a
    ð/jË%  ã                   @   s¢  d Z ddl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
d\ZZdd	„ Zg d
¢Zdd„ Zdd„ ZeeƒZe ej e	d¡¡D ]tZeeddd��RZe e¡D ]6Ze d¡e d¡e d¡e d¡fZee  e¡ q®W d  ƒ q�1 sú0    Y  q�edd„ ƒZedd„ ƒZdd„ Ze ¡ D �]Ð\ZZ e\Z!Z"Z#Z$e%dd„ e D ƒdd„ d�Z&e'e&ƒd k �rp�q.d!D �]V\Z(Z)g g  Z*Z+d Z,Z-e&D ]z\Z.Zee e(¡ƒee e)¡ƒ Z/Z0e/du �sÎe0du �rÚd Z,Z-�q”e,du�re* e/e, ¡ e+ e0e- ¡ n e/e0 Z,Z-�q”ee" Z1e2e'e*ƒƒD ]¤Z3e1d" d  e*e3 ¡ e1d" d#  e+e3 ¡ e3d# e'e*ƒk �r$e1d$ d  e*e3 ¡ e1d$ d#  e+e3d#  ¡ e1d% d  e+e3 ¡ e1d% d#  e*e3d#  ¡ �q$�qtd&D �](\Z4Z5Z6dZ7e&D ]L\Z8Zee e5¡ƒZ9e9du�ræee9  k�rek �ræn ne8efZ7 �q4�qæe7�s>�qÒee7d#  e6¡ƒZ:dZ;e<e&ƒD ],\Z8Zee e6¡ƒZ=e=du�r\e=Z; �qŠ�q\e:du �sÒe;du �r¢�qÒe;e: Z>ee" d'  d#7  < ee" d(  e>dk�rØd#nd7  < ee" d)  e>7  <  �q.�qÒ�q.i Z?zÐee
dd*��Ze @e¡ZAW d  ƒ n1 �s60    Y  ed+d„ ƒZBeAD ]pZCeC d,¡eC d-¡ ZDZEeC d¡�p~eC d.¡ZFeD�rPeEdu�rPeF�rPeBeF d  eD7  < eBeF d#  eE7  < �qPd/d0„ eB ¡ D ƒZ?W n eG�yê   Y n0 eHd1ƒ eHd2ƒ eHd1ƒ eHd3d4›d5d6›d7d8›d9d8›d:d8›d;d8›d<d=›d>d=›d?d8›�	ƒ g ZIe%eƒD ]æZFeeF Z1ee1d" d e1d" d# ƒ\ZJZ.ee1d$ d e1d$ d# ƒ\ZKZLee1d% d e1d% d# ƒ\ZMZ.eKdu �sNeMdu �rÌ�qNeKeM ZNe eFddd@œ¡ZCeCd' �reCd( eCd'  dA ndZOe? eF¡ZPeI eFeLeJeKeMeNeCd' eOePf	¡ �qNe%eIdBd„ d�D ]~\	ZFZLZJZKZMZNZQZOZPeOdu�rneOdC›ndDZRePdu�r„ePdE›ndFZSeHeFd4›eLdG›eJdH›eKdH›eMdH›eNdH›eQdI›eR› eS› �	ƒ �qFdJdK„ ZTdcdNdO„ZUdPdQ„ ZVdRdS„ ZWeHdTƒ eHdUƒ dVD ]˜\ZXZYeUdWd„ dXd„ eYdY�\ZZZ[Z\eUdZd„ d[d„ eYdY�\Z]Z^Z_eHd\eX› �ƒ eHd]eVeZƒ› d^eWe\ƒ› d_e[› d`�ƒ eHdaeVe]ƒ› d^eWe_ƒ› d_e^› d`�ƒ �qüeHdbƒ dS )da!  
Read-only study: LEAD-LAG of Kalshi vs Pinnacle repricing, per league.

Motivation (stale-Pinnacle theory): our edge = pin_fair - kalshi. If Kalshi
reprices BEFORE our (delayed) Pinnacle feed, the measured edge is just
Pinnacle's lag catching up to a price Kalshi already found -> illusory, no
value to capture. If Pinnacle leads (or they move together), the edge reflects
a real mispricing that persists long enough to trade.

We need a per-league SPEED proxy better than raw Kalshi volume (volume only got
us to corr p~=0.12). This measures who-moves-first directly from the snapshot
series, with NO external data.

Method (cross-correlation of one-step price changes, per fixture, pooled/league):
  For consecutive PRE snapshots build:
     dK_t = kalshi_mid(t)   - kalshi_mid(t-1)
     dP_t = pin_fair(t)     - pin_fair(t-1)
  Both home and away sides used as independent repricing observations.
  Cross-correlations of the increment series:
     rho(+1) = corr(dK_t, dP_{t+1})   Kalshi change predicts NEXT Pin change  -> KALSHI LEADS
     rho(-1) = corr(dP_t, dK_{t+1})   Pin change predicts NEXT Kalshi change   -> PIN LEADS
     rho(0)  = corr(dK_t, dP_t)       contemporaneous (same snapshot)
  Lead-lag score  LL = rho(+1) - rho(-1).  LL > 0  => Kalshi leads (bad for us).

Then correlate league LL against:
  - beat-close% (reference-independent edge-quality screen, recomputed here)
  - realized Kalshi ROI from bet_history.json
Hypothesis: Kalshi-leads (high LL) -> weaker edge (lower beat-close, lower ROI).

NOTHING is traded. Reproducible / read-only.
é    N)Údatetime)ÚdefaultdictzE:\soccer\live_datazE:\soccer\data\bet_history.json)gš™™™™™©?g¸…ëQ¸¾?c              	   C   s(   z
t | ƒW S  ttfy"   Y d S 0 d S ©N)ÚfloatÚ	TypeErrorÚ
ValueError)Úx© r	   úE:\soccer\analyze_leadlag.pyÚf(   s    r   )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 r   )Ú_FMTSr   Ústrptimer   r   )ÚsÚfmtr	   r	   r
   Úparse_ts-   s    r   c                    sª   t | ƒ}|dk rd |fS t| ƒ| t|ƒ|  ‰ ‰t‡ ‡fdd„t| |ƒD ƒƒ}t‡ fdd„| D ƒƒ}t‡fdd„|D ƒƒ}|dksŒ|dkr”d |fS |t || ¡ |fS )Né   c                 3   s"   | ]\}}|ˆ  |ˆ  V  qd S r   r	   )Ú.0ÚaÚb©ÚmxÚmyr	   r
   Ú	<genexpr>7   ó    zpearson.<locals>.<genexpr>c                 3   s   | ]}|ˆ  d  V  qdS ©é   Nr	   )r   r   )r   r	   r
   r   8   r   c                 3   s   | ]}|ˆ  d  V  qdS r   r	   )r   r   )r   r	   r
   r   9   r   r   )ÚlenÚsumÚzipÚmathÚsqrt)ÚxsÚysÚnZsxyZsxxZsyyr	   r   r
   Úpearson3   s    r$   z*.csvÚ zutf-8)ÚnewlineÚencodingZ	game_dateÚleagueÚhomeÚawayc                   C   s   g g gg g gg g gdœS )N)Úp1Úm1Úc0r	   r	   r	   r	   r
   Ú<lambda>F   r   r.   c                   C   s   ddddœS )Nr   ç        )r#   ÚbeatÚmover	   r	   r	   r	   r
   r.   H   r   c                 C   s8   t | ƒD ]*}| d¡pd ¡  ¡ }|dv r|  S qd S )NÚftrr%   )ÚHÚDÚA)ÚreversedÚgetÚupperÚstrip)ÚrowsÚrr2   r	   r	   r
   ÚresultJ   s    r<   c                 C   sF   g | ]>}|  d ¡pd ¡ dkrt|  d¡ƒdurt|  d¡ƒ|f‘qS )Zstatusr%   ZPREZ	timestampN)r7   r8   r   )r   r;   r	   r	   r
   Ú
<listcomp>R   s   þr=   c                 C   s   | d S )Nr   r	   ©Útr	   r	   r
   r.   U   r   )Úkeyr   ))Úkalshi_home_midZpin_fair_home)Úkalshi_away_midZpin_fair_awayr-   é   r+   r,   ))r5   Zclv_kalshi_awayrB   )r3   Zclv_kalshi_homerA   r#   r0   r1   )r'   c                   C   s   ddgS )Nr/   r	   r	   r	   r	   r
   r.   ‹   r   Zkalshi_stakeZ
kalshi_pnlZdivc                 C   s2   i | ]*\}}||d  r*|d |d   d nd“qS )r   rC   éd   Nr	   )r   ÚlgÚvr	   r	   r
   Ú
<dictcomp>‘   r   rG   z\============================================================================================zYLEAD-LAG of Kalshi vs Pinnacle repricing  (LL>0 => Kalshi LEADS => edge may be stale-Pin)ZLeagueZ14ZincNz>6Zrho0z>8zrho+1zrho-1ÚLLZbeatNz>7zbeat%zROI%)r#   r0   rD   c                 C   s
   | d  S ©Né   r	   r>   r	   r	   r
   r.   ©   r   z6.1fz    naz+7.1fz     naZ6dz8.3fZ7dc              	   C   sô   |dkrdS ||| |    }|d d }}dd„ }t  |¡t  |¡ t  || ¡ }||d || d  k r¨t  |t  |¡ |t  d| ¡  | ¡||||ƒ | }nBdt  |t  |¡ |t  d| ¡  | ¡|d| ||ƒ |  }td|ƒS )	zKtwo-sided p-value from a t-stat via regularized incomplete beta (no scipy).r   Ng       @g      à?c                 S   sp  d\}}}|| |d |d   }}}d}	d||  |  }
t |
ƒ|k rJ|}
d|
 }
|
}td|ƒD �]}d| }|||  |  || ||   }d||
  }
t |
ƒ|k rª|}
d||	  }	t |	ƒ|k rÆ|}	d|
 }
||
|	 9 }||  ||  |  || ||   }d||
  }
t |
ƒ|k �r|}
d||	  }	t |	ƒ|k �r<|}	d|
 }
|
|	 }||9 }t |d ƒ|k r` �qlq`|S )N)éÈ   gßÄAfcŠ=gYóøÂn¥ç      ð?rC   r   )ÚabsÚrange)r   r   r   ZMAXITZEPSZFPMINZqabZqapZqamÚcÚdÚhÚmZm2ZaaZder	   r	   r
   Úbetacfµ   s*    
 &zt_to_p.<locals>.betacfrL   rC   )r   ZlgammaZexpÚlogÚmin)r?   Zdfr   r   r   rS   ZlbetaZibr	   r	   r
   Út_to_p¯   s    "<BrV   é   r	   c              
   C   sØ   g g  }}t D ]d}|\	}}}	}
}}}}}||k s||v r:q| |ƒ||ƒ }}|d u s|d u r^q| |¡ | |¡ qt||ƒ\}}d }|d urÎ|dkrÎt|ƒdk rÎ|t |d d||   ¡ }t||d ƒ}|||fS )Nr   rC   )ÚtableÚappendr$   rM   r   r    rV   )ZgetxZgetyZminnÚdropr!   r"   ÚrowrE   Únp_Úr0ÚrpÚrmrH   ÚbnÚbpctÚrvr   Úyr;   r#   Úpr?   r	   r	   r
   Ú
corr_pairsÒ   s    
,re   c                 C   s   | d ur| d›S dS )Nz+.3fz  nar	   )r;   r	   r	   r
   r   á   r   r   c                 C   s   | d ur| d›S dS )Nz.3fZnar	   )rd   r	   r	   r
   Úfpâ   r   rf   z]
--------------------------------------------------------------------------------------------zIDoes Kalshi-leading predict weaker edge?  (leagues with >=8 settled bets)))zALL leaguesr	   )zEXCL E0)ZE0c                 C   s   | d S rI   r	   r>   r	   r	   r
   r.   ç   r   c                 C   s   | d S )Né   r	   r>   r	   r	   r
   r.   ç   r   )rZ   c                 C   s   | d S rI   r	   r>   r	   r	   r
   r.   è   r   c                 C   s   | d S )NrW   r	   r>   r	   r	   r
   r.   è   r   z
 z  corr(LL, beat-close%)  r=z  p=z  n=z   (expect NEG)z  corr(LL, realized ROI) r=zS
E0 row is the acid test: if stale-Pin theory holds, E0 should have the HIGHEST LL.)rW   r	   )`Ú__doc__ZcsvZglobÚosZjsonr   r   Úcollectionsr   ZLIVE_DIRZHISTZ	THRESH_LOZ	THRESH_HIr   r   r   r$   ÚlistZfixturesÚpathÚjoinÚopenZfhZ
DictReaderr;   r7   r@   rY   ZlagpZbcr<   Úitemsr:   Úgdr(   r)   r*   ÚsortedZprer   ZkmidZpfairZdKZdPZprevkZprevpÚ_ZkvZpvZaccrN   ÚiZsideZclvkZmidkZentZtsZclvZm0Zmlastr6   Zmvr1   ZroiÚloadZhistZaggr   ÚstZplrE   Ú	ExceptionÚprintrX   r]   r^   r\   r_   rH   ra   rb   r`   ZbsZrsrV   re   r   rf   ZlabelrZ   Zr_bcZn_bcZp_bcZr_roiZn_roiZp_roir	   r	   r	   r
   Ú<module>   sâ   ($0ý

,08&
"*,&ÿÿÿ"
$&>#
$(