a
    Í?jï  ã                   @   s¶   d Z ddlZddlZddlZddlZddlmZ ddlmZ dZg d¢Z	dd„ Z
d	d
„ Zdd„ Zdd„ Zdd„ ZeedœZddd„Zdd„ Zdd„ Zdd„ Zdd„ Zedkr²eƒ  dS )aÜ  
Poly edge NET OF SPREAD: re-price the mid-only backfill bets at an estimated ASK.

The live spread sample (research/poly_spread_sample.py, 2026-06-27) gave median
half-spreads on open longshot markets (mid 0.05-0.35) of ~0.7-3 cents. Apply that
bucketed half-spread to the backfill mids to estimate ask = mid + half, then settle
the [0.05,0.12) bets at the ask instead of the mid. Shows how much of Poly's +18-19%
mid ROI survives crossing the spread. Selection still fires on the mid-CLV signal (as
the live pipeline defines it); only the execution price changes.

Also reports an OPTIMISTIC (half the sampled spread) and PESSIMISTIC (2x) band so the
answer is a range, since the live sample is small/noisy and date-contaminated.
é    N)Údatetime)ÚdefaultdictzE:\soccer\poly_backfill)z%Y-%m-%d %H:%M:%Sz%m/%d/%Y %H:%Mz%m/%d/%Y %H:%M:%Sz%Y-%m-%d %H:%Mc              
   C   s8   t D ].}zt | |¡W   S  ttfy0   Y q0 qd S ©N)Ú_FMTSr   ÚstrptimeÚ
ValueErrorÚ	TypeError)ÚsÚf© r   ú$E:\soccer\research\devig_poly_ask.pyÚ_pts   s    r   c              	   C   s(   z
t | ƒW S  ttfy"   Y d S 0 d S r   )Úfloatr   r   ©Úxr   r   r   Ú_f   s    r   c                 C   s8   t | ƒD ]*}| d¡pd ¡  ¡ }|dv r|  S qd S )NÚftrÚ )ÚHÚDÚA)ÚreversedÚgetÚupperÚstrip)ÚrowsÚrÚvr   r   r   Ú_result   s    r   c                    s(   dd„ | D ƒ}t |ƒ‰ ‡ fdd„|D ƒS )Nc                 S   s   g | ]}d | ‘qS ©ç      ð?r   ©Ú.0r   r   r   r   Ú
<listcomp>"   ó    zfair_mult.<locals>.<listcomp>c                    s   g | ]}|ˆ  ‘qS r   r   ©r"   Zri©r	   r   r   r#   "   r$   )Úsum)Úor   r   r&   r   Ú	fair_mult!   s    r)   c                    sŒ   dd„ | D ƒ}d\}}t dƒD ]4}|| d ‰ t‡ fdd„|D ƒƒdkrNˆ }qˆ }q|| d ‰ ‡ fd	d„|D ƒ}t|ƒ‰‡fd
d„|D ƒS )Nc                 S   s   g | ]}d | ‘qS r   r   r!   r   r   r   r#   $   r$   zfair_power.<locals>.<listcomp>)ç      à?g      $@é<   é   c                 3   s   | ]}|ˆ  V  qd S r   r   r%   ©Úkr   r   Ú	<genexpr>'   r$   zfair_power.<locals>.<genexpr>r    c                    s   g | ]}|ˆ  ‘qS r   r   r%   r-   r   r   r#   )   r$   c                    s   g | ]}|ˆ  ‘qS r   r   )r"   Zpir&   r   r   r#   )   r$   )Úranger'   )r(   r   ÚloÚhiÚ_Úpr   )r.   r	   r   Ú
fair_power#   s     r5   ©ÚmultZpowerr    c                 C   sR   | dk rd}n<| dk rd}n.| dk r*d}n | dk r8d}n| dk rFd}nd	}|| S )
Nçš™™™™™©?gú~j¼t“h?gš™™™™™¹?g{®Gázt?g333333Ã?g      Ð?gffffffÖ?gš™™™™™™?g{®Gáz”?r   )Úmidr7   Úhr   r   r   Úhalf_spread.   s    r;   c               
   C   s  t tƒ} t tj td¡¡D ]p}t|ddd��N}t 	|¡D ]2}| | 
d¡| 
d¡| 
d¡| 
d¡f  |¡ q:W d   ƒ q1 s‚0    Y  qg }|  ¡ D ]f\\}}}}}	|s°qštd	d
„ |	D ƒdd„ d�}
|
sÐqšt|	ƒ}|d u râqš| t||dd
„ |
D ƒd�¡ qš|jdd„ d� |S )Nz*_polybackfill.csvr   zutf-8)ÚnewlineÚencodingZ	game_dateÚleagueÚhomeÚawayc                 S   s>   g | ]6}|  d ¡pd ¡ dkrt|d ƒrt|d ƒ|f‘qS )Zstatusr   ZPREZ	timestamp)r   r   r   )r"   r   r   r   r   r#   A   s   "ÿz!load_fixtures.<locals>.<listcomp>c                 S   s   | d S ©Nr   r   ©Útr   r   r   Ú<lambda>C   r$   zload_fixtures.<locals>.<lambda>©Úkeyc                 S   s   g | ]\}}|‘qS r   r   )r"   r3   r   r   r   r   r#   G   r$   )Úgdr   Úprec                 S   s   | d S )NrG   r   r   r   r   r   rD   H   r$   )r   ÚlistÚglobÚosÚpathÚjoinÚDIRÚopenÚcsvZ
DictReaderr   ÚappendÚitemsÚsortedr   ÚdictÚsort)ZfixturesrL   Zfhr   ÚpreppedrG   r>   r?   r@   r   rH   r   r   r   r   Úload_fixtures7   s*    ÿÿ&þ
 rW   c              	   C   s„  t | }g }| D �]l}g }dD �]0\}}	|d D �]}
t|
 d¡ƒt|
 d¡ƒt|
 d¡ƒ  }}}d |||fv s0|dkr0|dkr0|dksŒq0t|
 d|› d�¡ƒ}|d u s0d	|  k r¾dk sÂq0 q0||||fƒ|	 }|rä|| | nd }|d u s0||  k�r|k �sq0 q0|d
 dk�r$|dk�p8|d
 dk�o8|dk}| |||f¡  qq0q|rt|dd„ d�\}}}| t||d�¡ q|S )N))r?   r   )r@   r,   rH   Zpin_homeZpin_drawZpin_awayé   Zpoly_Z_pricer   r   r   r?   r   r@   c                 S   s   | d S rA   r   rB   r   r   r   rD   [   r$   zselect.<locals>.<lambda>rE   )r9   Úwon)Ú_DEVIGr   r   rQ   ÚmaxrT   )rV   Zdevigr1   r2   ÚfnÚbetsZfxZcandsZsideZsidxr   ZphZpd_Zpar9   ZpfZclvrY   r   r   r   ÚselectK   s$    
.( $.r^   c                 C   s  t | ƒ}|sd S tdd„ | D ƒƒ}d } }}d}| D ]d}||d ƒ}	d|	  k rZdk sfn |d7 }q6||d r|d|	 |	 nd7 }||	7 }||	d|	  7 }q6|| }
|
r´||
 d	 nd}|dkrÒ|| t |¡ nd}d
t |t d¡ ¡ }t|
|
�r||
 d	 nd|||d�S )Nc                 s   s   | ]}|d  V  qdS )rY   Nr   )r"   Úbr   r   r   r/   b   r$   zscore.<locals>.<genexpr>g        r   r9   rX   rY   g      ð¿éd   r*   r,   )ÚnÚwrÚroiÚzr4   )Úlenr'   ÚmathZsqrtZerfcrT   )r]   Zprice_fnra   ZwinsZnetZmuÚvarZskippedr_   ZpxÚmrc   rd   r4   r   r   r   Úscore_   s     ri   c                  C   s  t ƒ } dD ]ø}t| |ddƒ}td|› dt|ƒ› d�ƒ ddd	„ fd
dd	„ fddd	„ fddd	„ fg}tddd›ddd›ddd›ddd›ddd›ddd›�ƒ |D ]b\}}t||ƒ}|ržtd|d›d|d d›d|d d›d|d  d!›d|d d"›d|d d#›�ƒ qžq
d S )$Nr6   r8   g¸…ëQ¸¾?z
=== z de-vig, band [0.05,0.12), n=z ===zat MID (no spread)c                 S   s   | S r   r   ©rh   r   r   r   rD   t   r$   zmain.<locals>.<lambda>zask = mid + 0.5x halfc                 S   s   | t | dƒ S )Nr*   ©r;   rj   r   r   r   rD   u   r$   zask = mid + 1x halfc                 S   s   | t | dƒ S )Nr    rk   rj   r   r   r   rD   v   r$   zask = mid + 2x halfc                 S   s   | t | dƒ S )Ng       @rk   rj   r   r   r   rD   w   r$   z  ZpricingZ22sú ra   z>4zWR%z>5zROIturn%z>9rd   z>6r4   Z4drb   z5.1frc   z+9.1fz+6.2fz6.3f)rW   r^   Úprintre   ri   )rV   Zdvr]   r   Zlabelr\   r	   r   r   r   Úmaino   s$    



ý8
0ÿÿrn   Ú__main__)r    )Ú__doc__rP   rJ   rK   rf   r   Úcollectionsr   rN   r   r   r   r   r)   r5   rZ   r;   rW   r^   ri   rn   Ú__name__r   r   r   r   Ú<module>   s$    

	