a
    uÆAjz  ã                   @   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edkršeƒ  dS )a‡  
Do Kalshi and Poly find the SAME bets or DIFFERENT ones?  Quantify overlap.

poly_backfill rows carry BOTH kalshi_{side}_mid/ask AND poly_{side}_price, so each
book's [0.05,0.12) multiplicative-de-vig strategy runs on identical fixtures. For
each fixture (game_date,league,home,away) decide whether Kalshi fired a bet, whether
Poly fired, and if both, whether they picked the SAME side.

Buckets:
  Kalshi-only / Poly-only / Both-same-side / Both-different-side / neither
Reports counts AND each bucket's WR/ROIturn, so we see if the UNIQUE bets (the ones
only one book finds) are real edge -> i.e. does running both books add independent n.

Two universes:
  (a) ALL backfill fixtures (Poly covers fewer leagues, so coverage gap shows up)
  (b) SHARED-PRICE fixtures only: both books quoted a price (fair overlap test)
Read-only. Multiplicative de-vig (live default), both-sides dedupe to higher CLV.
é    N)Údatetime)ÚdefaultdictzE:\soccer\poly_backfill)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\kalshi_poly_overlap.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  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 ]n\}}|\}}}	}
|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   5   s   "ÿzload.<locals>.<listcomp>c                 S   s   | d S ©Nr   r   ©Útr   r   r   Ú<lambda>7   r    zload.<locals>.<lambda>©Úkeyc                 S   s   g | ]\}}|‘qS r   r   )r   Ú_r   r   r   r   r   ;   r    )r0   Úgdr'   r   Úpre)r   ÚlistÚglobÚosÚpathÚjoinÚDIRÚopenÚcsvZ
DictReaderr   ÚappendÚitemsÚsortedr   Údict)Zfixturesr7   Zfhr   Úfxr0   r   r2   r'   r(   r)   r3   r   r   r   r   Úload*   s*    ÿÿ&þ
$rA   c                 C   sè  g }d}dD �]ž\}}| d D �]Š}t | d¡ƒt | d¡ƒt | d¡ƒ  }}}	d|||	fv s|dkr|dkr|	dkszq|d	kr°t | d
|› d�¡ƒ}
t | d
|› d�¡ƒ}nt | d|› d�¡ƒ}
|
}|
du s|du sd|
  k rîdk rn qd|  k �r
dk �sq qd}t|||	fƒ| }|�r6||
 | nd}|du std |  k�rbtd k �sfq q| d dk�r~|dk�p’| d dk�o’|dk}| ||||f¡  qqq|�s¼d|fS t|dd„ d�\}}}}t||||d�|fS )z�Return (side, price_for_settlement, won, clv) of the book's bet, or None.
       book='kalshi' (price=ask) or 'poly' (price=mid).F))r(   r   )r)   é   r3   Zpin_homeZpin_drawZpin_awayNé   ÚkalshiZkalshi_Z_midZ_askZpoly_Z_pricer   Tr   r   r(   r   r)   c                 S   s   | d S r+   r   r,   r   r   r   r.   S   r    zfire.<locals>.<lambda>r/   )ÚsideÚpxÚwonÚclv)r   r   r$   ÚBANDr<   Úmaxr?   )r@   ZbookZcandsZ
have_pricerE   Zsidxr   ZphZpd_ZpaZmidrF   ZpfrH   rG   r   r   r   Úfire>   s&    .(.D,.rK   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	|d
›d|| d d›d|| d d›d|d›�S )Nz(0)c                 s   s   | ]}|d  V  qdS )rG   Nr   ©r   Úbr   r   r   Ú	<genexpr>Y   r    zroi.<locals>.<genexpr>c                 s   s.   | ]&}|d  r"d|d  |d  ndV  qdS )rG   rC   rF   g      ð¿Nr   rL   r   r   r   rN   Z   r    c                 s   s   | ]}|d  V  qdS )rF   Nr   rL   r   r   r   rN   [   r    c                 s   s"   | ]}|d  d|d    V  qdS )rF   rC   Nr   rL   r   r   r   rN   [   r    r   g        zn=Z3dz WR=éd   z4.1fz
% ROIturn=z+6.1fz% z=z+.2f)Úlenr"   ÚmathZsqrt)ZbetsÚnZwinsZnetZmuÚvarÚzr   r   r   ÚroiV   s    $rU   c            	   
   C   sv   t ƒ } g }| D ]8}t|dƒ\}}t|dƒ\}}| t|||||d�¡ qdd„ }||dƒ dd„ |D ƒ}||d	ƒ d S )
NrD   Zpoly)r
   ÚkÚpÚk_hasÚp_hasc                 S   s€  dd„ | D ƒ}dd„ | D ƒ}dd„ | D ƒ}dd„ | D ƒ}dd„ | D ƒ}dd„ |D ƒ}dd„ |D ƒ}d	d„ | D ƒ}	t d
|› dt| ƒ› d�ƒ t dt|ƒd›�ƒ t dt|ƒd›�ƒ t dt|	ƒd›�ƒ t |	rödt|ƒd›ddt|ƒ t|	ƒ d›d�ndƒ t dt|ƒd›�ƒ t dt|ƒd›�ƒ t dt|ƒd›�ƒ t dt|ƒd›�ƒ |�rž|	�rht|ƒt|	ƒ nd}
t d|
d›�ƒ t ddt|ƒ t|ƒ d›d�ƒ |�rÆt d dt|ƒ t|ƒ d›d�ƒ t d!ƒ t d"td#d„ |D ƒƒ› �ƒ t d$td%d„ |D ƒƒ› �ƒ t d&td'd„ |D ƒƒ› �ƒ t d(td)d„ |D ƒƒ› �ƒ |�r|t d*td+d„ |D ƒƒ› �ƒ t d,td-d„ |D ƒƒ› �ƒ d S ).Nc                 S   s   g | ]}|d  r|‘qS ©rV   r   r*   r   r   r   r   h   r    z(main.<locals>.report.<locals>.<listcomp>c                 S   s   g | ]}|d  r|‘qS ©rW   r   r*   r   r   r   r   i   r    c                 S   s    g | ]}|d  r|d r|‘qS ©rV   rW   r   r*   r   r   r   r   j   r    c                 S   s    g | ]}|d  r|d s|‘qS r\   r   r*   r   r   r   r   k   r    c                 S   s    g | ]}|d  r|d s|‘qS )rW   rV   r   r*   r   r   r   r   l   r    c                 S   s(   g | ] }|d  d |d d kr|‘qS ©rV   rE   rW   r   r*   r   r   r   r   m   r    c                 S   s(   g | ] }|d  d |d d kr|‘qS r]   r   r*   r   r   r   r   n   r    c                 S   s    g | ]}|d  s|d r|‘qS r\   r   r*   r   r   r   r   o   r    z
=== z (fixtures=z) ===z  Kalshi fired:        Z4dz  Poly fired:          z  UNION (either):      z  Both fired:          z   (rO   z.0fz% of union)r   z    - same side:       z    - DIFFERENT side:  z  Kalshi-only:         z  Poly-only:           r   z   Jaccard overlap (both/union): z.2fz   Of Kalshi bets, also on Poly: ú%z   Of Poly bets, also on Kalshi: z
  Performance by bucket:z    Kalshi-only (Kalshi px):  c                 S   s   g | ]}|d  ‘qS rZ   r   r*   r   r   r   r   ‚   r    z    Poly-only   (Poly px):    c                 S   s   g | ]}|d  ‘qS r[   r   r*   r   r   r   r   ƒ   r    z     Both, Kalshi side==Poly:  K c                 S   s   g | ]}|d  ‘qS rZ   r   r*   r   r   r   r   „   r    z     Both, same: Poly side:    P c                 S   s   g | ]}|d  ‘qS r[   r   r*   r   r   r   r   …   r    z     Both, DIFFERENT side:     K c                 S   s   g | ]}|d  ‘qS rZ   r   r*   r   r   r   r   ‡   r    z                               P c                 S   s   g | ]}|d  ‘qS r[   r   r*   r   r   r   r   ˆ   r    )ÚprintrP   rU   )ZuniverseZlabelÚKÚPZbothZkonlyZponlyZsameZdiffÚunionZjacr   r   r   Úreportg   sJ    ÿÿÿ""zmain.<locals>.reportz(a) ALL backfill fixturesc                 S   s    g | ]}|d  r|d r|‘qS )rX   rY   r   r*   r   r   r   r   ‹   r    zmain.<locals>.<listcomp>z-(b) SHARED-PRICE fixtures (both books quoted))rA   rK   r<   r?   )	r@   r   r
   rV   rX   rW   rY   rc   Zsharedr   r   r   Úmain_   s    #
rd   Ú__main__)Ú__doc__r;   r5   r6   rQ   r   Úcollectionsr   r9   rI   r   r   r   r   r$   rA   rK   rU   rd   Ú__name__r   r   r   r   Ú<module>   s     	/