a
    Î?jN  ã                   @   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dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zedkr²eƒ  dS )a¶  
Is Poly's apparent edge over Kalshi just a LEAGUE-MIX artifact (Poly not listing the
leagues where Kalshi loses)?  Control by comparing the two books on the SAME fixtures.

The poly_backfill/*.csv rows carry BOTH kalshi_{side}_mid/ask AND poly_{side}_price, so
we can run each book's [0.05,0.12) strategy on identical fixtures. Kalshi bets at its real
ask (executable); Poly bets at mid and at mid+1x near-term half-spread (estimated ask).
Multiplicative de-vig throughout (the live default), home/away only, both-sides dedupe.

Reports:
  A. each book on its OWN full fixture set (the headline, uncontrolled comparison)
  B. MATCHED set: fixtures where BOTH books quoted -> Kalshi vs Poly head-to-head
  C. Kalshi restricted to Poly-COVERED LEAGUES (does dropping non-Poly leagues fix Kalshi?)
  D. per-league on matched fixtures: n, Kalshi ROI, Poly ROI side by side
If Poly still beats Kalshi on the MATCHED set, it is NOT a league-mix artifact.
é    N)Údatetime)ÚdefaultdictzE:\soccer\poly_backfill)çš™™™™™©?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\poly_kalshi_matched.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 )g      ð?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                 C   s@   | dk rdS | dk rdS | dk r$dS | dk r0dS | dk r<dS d	S )
Nr   gú~j¼t“h?gš™™™™™¹?g{®Gázt?g333333Ã?g      Ð?gffffffÖ?gš™™™™™™?g{®Gáz”?r   )Úmidr   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 ]h\\}}}}}	|s°qštd	d
„ |	D ƒdd„ d�}
|
sÐqšt|	ƒ}|d u râqš| t|||dd
„ |
D ƒd�¡ qš|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    9   s   "ÿz!load_fixtures.<locals>.<listcomp>c                 S   s   | d S ©Nr   r   ©Útr   r   r   Ú<lambda>;   r!   zload_fixtures.<locals>.<lambda>©Úkeyc                 S   s   g | ]\}}|‘qS r   r   )r   Ú_r   r   r   r   r    ?   r!   )Úgdr*   r   Úpre)r   ÚlistÚglobÚosÚpathÚjoinÚDIRÚopenÚcsvZ
DictReaderr   ÚappendÚitemsÚsortedr   Údict)Zfixturesr9   Zfhr   Úpreppedr4   r*   r+   r,   r   r5   r   r   r   r   Úload_fixtures/   s(    ÿÿ&þ
"rC   c                 C   s   dS )zºFirst in-band [pin_fair-price]/pin_fair bet for a book; both-sides dedupe to higher CLV.
       Returns (clv, price_used_for_bet_dict). price columns: f'{book}'. Generic via pricecol fn.Nr   )ÚfxZpricecolZsidx_mapr   r   r   ÚpickB   s    rE   c                 C   s  g }| D �]}g }dD �]¶\}}|d D �]¢}t | d¡ƒt | d¡ƒt | d¡ƒ  }}	}
d||	|
fv s(|dkr(|	dkr(|
dks„q(|dkrºt | d	|› d
�¡ƒ}t | d	|› d�¡ƒ}n6t | d|› d�¡ƒ}|dkrÜ|n|rì|t|ƒ nd}|du s(|du s(d|  k �rdk r(n q(d|  k �r2dk �s6q( q(t||	|
fƒ| }|�rZ|| | nd}|du s(td |  k�r†td k �sŠq( q(|d dk�r¢|dk�p¶|d dk�o¶|dk}| |||f¡  qq(q|rt|dd„ d�\}}}| t|d |d |||d |d fd�¡ q|S )zTbook='kalshi' (bet at ask) or 'poly_mid'/'poly_ask'. Returns list of bets w/ league.))r+   r   )r,   é   r5   Zpin_homeZpin_drawZpin_awayNé   ÚkalshiZkalshi_Z_midZ_askZpoly_Z_priceÚpoly_midr   r   r   r+   r   r,   c                 S   s   | d S r-   r   r.   r   r   r   r0   \   r!   zselect.<locals>.<lambda>r1   r4   r*   )r4   r*   ÚpxÚwonr2   )r   r   r'   r%   ÚBANDr>   ÚmaxrA   )rB   ZbookÚbetsrD   ZcandsZsideZsidxr   ZphZpd_Zpar&   rJ   ZpfZclvrK   r   r   r   ÚselectG   s.    
.(. F,.ÿ
rO   c                 C   s°   t | ƒ}|sd S tdd„ | D ƒƒ}tdd„ | D ƒƒ}tdd„ | D ƒƒ}tdd„ | D ƒƒ}|dkrr|| t |¡ nd}dt |t d	¡ ¡ }t||| d
 || d
 ||d�S )Nc                 s   s   | ]}|d  V  qdS )rK   Nr   ©r   Úbr   r   r   Ú	<genexpr>d   r!   zstat.<locals>.<genexpr>c                 s   s.   | ]&}|d  r"d|d  |d  ndV  qdS )rK   rG   rJ   g      ð¿Nr   rP   r   r   r   rR   e   r!   c                 s   s   | ]}|d  V  qdS )rJ   Nr   rP   r   r   r   rR   f   r!   c                 s   s"   | ]}|d  d|d    V  qdS )rJ   rG   Nr   rP   r   r   r   rR   f   r!   r   g        g      à?rF   éd   )ÚnÚwrÚroiÚzÚp)Úlenr#   ÚmathZsqrtZerfcrA   )rN   rT   ZwinsZnetZmuÚvarrW   rX   r   r   r   Ústata   s    $r\   c                 C   sj   |st d| d›d�ƒ d S t d| d›d|d d›d|d d	›d
|d d›d|d d›d|d d›�ƒ d S )Nú  Z34sz
 (no bets)z n=rT   Ú4dz  WR=rU   z4.1fz%  ROIturn=rV   z+6.1fz%  z=rW   z+.2fz  p=rX   z.3f)Úprint)Útagr
   r   r   r   Úlinek   s    ra   c                     sà  t ƒ } t| dƒ}t| dƒ}t| dƒ}tdt| ƒ› d�ƒ tdƒ tdt|ƒƒ tdt|ƒƒ td	t|ƒƒ d
d„ |D ƒ}d
d„ |D ƒ}||@ ‰tdtˆƒ› d�ƒ tdt‡fdd„|D ƒƒƒ tdt‡fdd„|D ƒƒƒ tdt‡fdd„|D ƒƒƒ dd„ |D ƒ‰tdtˆƒ› d�ƒ tdt‡fdd„|D ƒƒƒ tdt‡fdd„|D ƒƒƒ tdƒ tddd›d d!d"›d#d$d%›d d&d'›d#d(d%›d d)d'›�ƒ ttƒ‰ ttƒ}|D ]&}|d* ˆv �r¤ˆ |d+   |¡ �q¤|D ]&}|d* ˆv �rÐ||d+   |¡ �qÐt	t
ˆ ƒt
|ƒB ‡ fd,d-„d.�D ]Â}tˆ  |g ¡ƒt| |g ¡ƒ }	}
|	�rL|	d! nd/}|	�rb|	d0 d1›nd2}|	�rx|	d3 d4›nd5}|
�rŽ|
d0 d1›nd2}|
�r¤|
d3 d4›nd5}td|d›d |d6›d#|› d |› d#|› d |› �ƒ �qd S )7NrH   rI   Zpoly_askzfixtures total=Ú
z0A. Each book on its OWN fixtures (uncontrolled):zKalshi (at ask)zPoly (at mid)zPoly (at est ask)c                 S   s   h | ]}|d  ’qS r1   r   rP   r   r   r   Ú	<setcomp>|   r!   zmain.<locals>.<setcomp>z>
B. MATCHED fixtures where BOTH books fired a bet (n_fixtures=z):zKalshi (at ask)  | matchedc                    s   g | ]}|d  ˆ v r|‘qS r1   r   rP   ©Úmatchedr   r   r       r!   zmain.<locals>.<listcomp>zPoly (at mid)    | matchedc                    s   g | ]}|d  ˆ v r|‘qS r1   r   rP   rd   r   r   r    €   r!   zPoly (at est ask)| matchedc                    s   g | ]}|d  ˆ v r|‘qS r1   r   rP   rd   r   r   r    �   r!   c                 S   s   h | ]}|d  ’qS ©r*   r   rP   r   r   r   rc   „   r!   z/
C. Kalshi restricted to Poly-COVERED leagues (z
 leagues):zKalshi (at ask) | poly-leaguesc                    s   g | ]}|d  ˆ v r|‘qS rf   r   rP   ©Úpoly_leaguesr   r   r    †   r!   zKalshi (at ask) | NON-poly-lgc                    s   g | ]}|d  ˆ vr|‘qS rf   r   rP   rg   r   r   r    ‡   r!   z@
D. Per-league on MATCHED fixtures (Kalshi ask vs Poly est-ask):r]   ÚlgZ6sú rT   z>4z | zK_ROI%z>8ZK_zz>6zP_ROI%ZP_zr2   r*   c                    s   t ˆ  | g ¡ƒ S r   )rY   r   )Úl)ÚKbyr   r   r0   ‘   r!   zmain.<locals>.<lambda>r1   r   rV   z+8.1fz      --rW   z+6.2fz    --r^   )rC   rO   r_   rY   ra   r\   r   r6   r>   r@   Úsetr   )rB   ÚKZPmZPaZkkeysZpkeysZPbyrQ   ri   ZksZpsrT   ZkroiZkzZproiZpzr   )rl   re   rh   r   Úmaino   sD    


8$$$"ro   Ú__main__)Ú__doc__r=   r7   r8   rZ   r   Úcollectionsr   r;   rL   r   r   r   r   r%   r'   rC   rE   rO   r\   ra   ro   Ú__name__r   r   r   r   Ú<module>   s&    
+