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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„ Zdd„ Zddd„Zdd„ Zedkr®eƒ  dS )a�  
Re-run the live CLV strategy with an HONEST (power) de-vig for pin_fair, and
compare to the current MULTIPLICATIVE de-vig the pipeline ships.

The calibration study (research/devig_calibration.py) showed multiplicative
over-states longshot pin_fair by ~4% relative, which inflates measured CLV
(= (pin_fair - kalshi_mid)/pin_fair). So the live [5,12)% band is really ~[1,8)%
of honest edge. Question: does a genuinely +EV band SURVIVE de-biasing, or was
the apparent edge mostly this artifact?

Mirrors the frozen forward-test selection (forward_test_drift_momentum.build_signals
baseline path): one bet per fixture, enter at the FIRST pre-KO snapshot whose
clv_kalshi (mid-based) is in BAND, both-sides dedupe to the higher-CLV side, bet
at that snapshot's ASK, settle by ftr. NON-look-ahead. Computes both de-vig
selections from the SAME raw Pinnacle odds in the snapshots (pin_home/draw/away),
so it's an apples-to-apples swap of the fair-value model only.

Reports, for each de-vig: n, win rate, flat-stake ROI-on-turnover, and the
one-sided win-rate-vs-implied(ask) z (Poisson-binomial). Plus the cumulative-z
trajectory so we can see if the honest edge holds up as n grows.
é    N)Údatetime)ÚdefaultdictzE:\soccer\live_data)gš™™™™™©?g¸…ëQ¸¾?)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_live_rerun.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 ]8}|| d ‰ t‡ fdd„|D ƒƒ‰ˆdkrRˆ }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"   0   r#   zfair_power.<locals>.<listcomp>)ç      à?g      $@é<   é   c                 3   s   | ]}|ˆ  V  qd S r   r   r$   ©Úkr   r   Ú	<genexpr>4   r#   zfair_power.<locals>.<genexpr>r   c                    s   g | ]}|ˆ  ‘qS r   r   r$   r-   r   r   r"   8   r#   c                    s   g | ]}|ˆ  ‘qS r   r   )r!   Zpir%   r   r   r"   9   r#   )Úranger'   )r(   r   ÚloÚhiÚ_Úpr   )r.   r	   r   Ú
fair_power/   s    r5   )ÚmultiplicativeÚpowerc                 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 �]\\}}}}	}
|s²qštd
d„ |
D ƒdd„ d�}t|ƒdk rÚqšt|
ƒ}|d	u rìqšg }dD �]¢\}}d|› d�}d|› d�}d	}|D �]$\}}t| 
d¡ƒt| 
d¡ƒt| 
d¡ƒ  }}}t| 
|¡ƒ}d	|||fv �s|d	u �r‚�q|dk�r|dk�r|dk�s¤�q| |||fƒ| }|�rÈ|| | nd	}|d	u �std |  k�rötd k �sün �qt| 
|¡ƒ}|d	u �sd|  k �r,dk �s2n �q|||f} �qF�q|rô|dk�r^|dk�pn|dk�on|dk}| t||||d |d |d |d�¡ qô|rš| t|dd„ d�¡ qš|jdd„ d� |S )zBReturn list of bets (sorted by game_date) under one de-vig method.z*.csvr   zutf-8)ÚnewlineÚencodingZ	game_dateÚleagueÚhomeÚawayNc                 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"   I   s   "ÿzbuild.<locals>.<listcomp>c                 S   s   | d S )Nr   r   )Útr   r   r   Ú<lambda>K   r#   zbuild.<locals>.<lambda>)Úkeyr,   ))r;   r   )r<   r,   Zkalshi_Z_midZ_askZpin_homeZpin_drawZpin_awayé   r   r   r   )Úgdr:   ÚsideÚclvÚaskÚpfÚwonc                 S   s   | d S )NrC   r   )Údr   r   r   r>   d   r#   c                 S   s   | d S )NrA   r   ©Úbr   r   r   r>   e   r#   )r   ÚlistÚglobÚosÚpathÚjoinÚLIVE_DIRÚopenÚcsvZ
DictReaderr   ÚappendÚitemsÚsortedÚlenr   r   ÚBANDÚdictÚmaxÚsort)Zdevig_fnZfixturesrM   Zfhr   ÚbetsrA   r:   r;   r<   r   Zprer   ZcandsrB   ZsidxZmidkZaskkZentZtsZphZpd_ZpaZmidrE   rC   rD   rF   r   r   r   Úbuild=   sT    ÿÿ&þ
."0(&ÿ
r[   c           
      C   sþ   t |ƒ}|s td| › d�ƒ d S tdd„ |D ƒƒ}tdd„ |D ƒƒ}|| d }tdd„ |D ƒƒ}tdd„ |D ƒƒ}|d	krŽ|| t |¡ nd
}dt |t d¡ ¡ }	td| d›d|d›d|| d d›d|| d d›d|d›d|d›d|	d›�ƒ d S )Nú  z	: no betsc                 s   s   | ]}|d  V  qdS ©rF   Nr   ©r!   rI   r   r   r   r/   l   r#   zsummarize.<locals>.<genexpr>c                 s   s.   | ]&}|d  r"d|d  |d  ndV  qdS )rF   r@   rD   g      ð¿Nr   r^   r   r   r   r/   n   r#   éd   c                 s   s   | ]}|d  V  qdS ©rD   Nr   r^   r   r   r   r/   q   r#   c                 s   s"   | ]}|d  d|d    V  qdS ©rD   r@   Nr   r^   r   r   r   r/   r   r#   r   g        r*   r,   Z14sz n=Z4dz  WR=z4.1fz%  impliedWR=z%  ROIturn=z+6.1fz%  z=ú+.2fz  p=z.3f)rU   Úprintr'   ÚmathÚsqrtZerfc)
ÚnamerZ   ÚnÚwinsZnetZroiÚmuÚvarÚzr4   r   r   r   Ú	summarizeh   s"    4ÿÿÿrl   ©
é2   r_   é–   éÈ   éú   i,  i^  i�  iÂ  iô  c           
      C   sÞ   t d| › d�ƒ g }|D ]Œ}|t|ƒkr, q¦|d |… }tdd„ |D ƒƒ}tdd„ |D ƒƒ}tdd„ |D ƒƒ}|dkrˆ|| t |¡ nd}	| d|› d	|	d
›�¡ q| dt|ƒ› d�dd„ |ƒ ¡ t dd |¡ ƒ d S )Nr\   z" cumulative win-rate-vs-implied z:c                 s   s   | ]}|d  V  qdS r]   r   r^   r   r   r   r/   ~   r#   zztraj.<locals>.<genexpr>c                 s   s   | ]}|d  V  qdS r`   r   r^   r   r   r   r/      r#   c                 s   s"   | ]}|d  d|d    V  qdS ra   r   r^   r   r   r   r/      r#   r   zn=z:z=rb   z(all):z=c                 S   s:   dd„ t dd„ | D ƒƒt dd„ | D ƒƒt dd„ | D ƒƒƒS )Nc                 S   s"   |dkr| | t  |¡ d›S dS )Nr   rb   Ú0)rd   re   )ÚwÚmr   r   r   r   r>   ‚   r#   z)ztraj.<locals>.<lambda>.<locals>.<lambda>c                 s   s   | ]}|d  V  qdS r]   r   r    r   r   r   r/   ƒ   r#   z*ztraj.<locals>.<lambda>.<locals>.<genexpr>c                 s   s   | ]}|d  V  qdS r`   r   r    r   r   r   r/   ƒ   r#   c                 s   s"   | ]}|d  d|d    V  qdS ra   r   r    r   r   r   r/   ƒ   r#   r&   rH   r   r   r   r>   ‚   s   0ÿzztraj.<locals>.<lambda>z     )rc   rU   r'   rd   re   rR   rN   )
rf   rZ   ZstepsÚoutr.   Úsubrh   ri   rj   rk   r   r   r   Úztrajx   s    $ÿrw   c                  C   sÌ   t dƒ i } t ¡ D ]\}}t|ƒ| |< qtD ]}t|| | ƒ q.t ƒ  tD ]}t|| | ƒ qLdd„ }|| d ƒ|| d ƒ }}t dt|ƒ› dt|ƒ› dt||@ ƒ› d	t|| ƒ› d
t|| ƒ› �
ƒ d S )NzMRe-running live CLV selection under each de-vig (mid-based CLV, bet at ask):
c                 S   s   dd„ | D ƒS )Nc                 S   s"   h | ]}|d  |d |d f’qS )rA   r:   rB   r   r^   r   r   r   Ú	<setcomp>‘   r#   z'main.<locals>.keyset.<locals>.<setcomp>r   )rZ   r   r   r   Úkeyset‘   r#   zmain.<locals>.keysetr6   r7   z
  bet-set overlap: mult=z  power=z	  shared=z  mult-only=z  power-only=)rc   ÚDEVIGSrS   r[   rl   rw   rU   )Zselsrf   Úfnry   ÚarI   r   r   r   Úmain†   s     &
ÿ
ÿr}   Ú__main__)rm   )Ú__doc__rQ   rK   rL   rd   r   Úcollectionsr   rO   rV   r   r   r   r   r)   r5   rz   r[   rl   rw   r}   Ú__name__r   r   r   r   Ú<module>   s$    
+
