a
    È3ej©  ã                   @   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 g d¢Z	ddddd	d
ddddddœZ
eejƒdkrxeejd ƒnd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"d#„Zd$d%„ Zed&krÜeƒ  dS )(a€  
Is the 20-25% price bucket -- where xlow actually bets -- mis-calibrated?
(read-only, trades nothing, downloads public CSVs)

WHY: sa_history_calibration.py refuted the South America anomaly on 11.7k games,
but turned up something more relevant on the way. Bucketing outcomes by implied
probability, the 0.20-0.25 bucket came in ~7% below implied (z-3.72) while its
neighbours were clean. xlow's average bet sits at 23.7% implied -- dead centre of
that bucket. If the effect is real it eats the bottom half of the [5%,12%) CLV
band and would explain a forward test sitting at zero.

That first pass only covered Brazil/Argentina/Mexico/USA. This one covers OUR
league universe -- the divisions xlow actually trades, dominated by the European
leagues that were 78% of the backtest.

TWO DEVIGS, because the first pass showed it matters: proportional (what our
pipeline uses) systematically overstates longshots, so part of any apparent
longshot bias is our own arithmetic rather than the market's. Power devig is the
control. If the dip survives power devig, it is not a devig artifact.

Usage:  python research\price_bucket_calibration.py [n_seasons]
é    N)Údefaultdict)ZE0ZE1ZE2ZE3ZECZSC0ZSC1ZSC2ZSC3ZD1ZD2ZI1ZI2ZSP1ZSP2ZF1ZF2ZN1ZB1ZP1ZT1ZG1zBSA/BR2ZAR1ZMX1ZMLSZSE1ZNO1ZDK1ZPL1ZRO1ZCN1ZJP1)ZBRAZARGZMEXZUSAZSWEZNORZDNKZPOLZROUZCHNZJPNé   é
   )ZPSCHZPSCDZPSCA)ZAvgCHZAvgCDZAvgCA))gš™™™™™©?çš™™™™™¹?)r   ç333333Ã?)r   çš™™™™™É?)r   ç      Ð?)r   ç333333Ó?)r	   çš™™™™™Ù?)r
   çš™™™™™á?)r   gffffffî?c              	   C   s8   zt | ƒ}|dkr|nd W S  ttfy2   Y d S 0 d S )Nç      ð?)ÚfloatÚ	TypeErrorÚ
ValueError)ÚxÚv© r   ú.E:\soccer\research\price_bucket_calibration.pyÚ_f,   s
    r   c                 C   sH   g }t d|  dƒD ]0}|d |d d  }}| |d›|d›�¡ q|S )Né   éd   r   Z02d)ÚrangeÚappend)ÚnÚoutÚstartÚaÚbr   r   r   Úseasons4   s
    r   c                 C   s8   zt jj| dd� ¡  dd¡W S  ty2   Y d S 0 d S )Né-   )Ztimeoutz	utf-8-sigÚreplace)ÚurllibZrequestZurlopenÚreadÚdecodeÚ	Exception)Zurlr   r   r   Úgrab<   s    r%   c                    s~   g }| s|S t  t | ¡¡D ]\‰ ˆ  |¡p,d ¡  ¡ }|dvr@q|D ]2}‡ fdd„|D ƒ}t|ƒrD| |||f¡  qqDq|S )NÚ )ÚHÚDÚAc                    s   g | ]}t ˆ  |¡ƒ‘qS r   )r   Úget)Ú.0Úc©Úrr   r   Ú
<listcomp>L   ó    zparse.<locals>.<listcomp>)	ÚcsvZ
DictReaderÚioÚStringIOr*   ÚstripÚupperÚallr   )ZtxtZres_keyZ	cols_setsÚtagr   ÚresZcolsr   r   r-   r   ÚparseC   s    r9   c                    s(   dd„ | D ƒ}t |ƒ‰ ‡ fdd„|D ƒS )Nc                 S   s   g | ]}d | ‘qS ©r   r   ©r+   r   r   r   r   r/   T   r0   zprop.<locals>.<listcomp>c                    s   g | ]}|ˆ  ‘qS r   r   ©r+   Úi©Úsr   r   r/   V   r0   )Úsum)ÚoÚimpr   r>   r   ÚpropS   s    rC   c                    sr   dd„ | D ƒ}d\}}t dƒD ]4}|| d ‰ t‡ fdd„|D ƒƒdkrNˆ }qˆ }q|| d ‰ ‡ fd	d„|D ƒS )
zMSolve sum(p_i^k)=1. Flattens longshots; standard fix for proportional's bias.c                 S   s   g | ]}d | ‘qS r:   r   r;   r   r   r   r/   [   r0   zpower.<locals>.<listcomp>)g      à?g      ø?é<   é   c                 3   s   | ]}|ˆ  V  qd S ©Nr   r<   ©Úkr   r   Ú	<genexpr>_   r0   zpower.<locals>.<genexpr>r   c                    s   g | ]}|ˆ  ‘qS r   r   r<   rG   r   r   r/   d   r0   )r   r@   )rA   rB   ÚloÚhiÚ_r   rG   r   ÚpowerY   s    rM   c                    sž  g }| D ]H\}}}|r ||vr q||ƒ}t dƒD ]\}	}
| ||	 ||
kf¡ q0qtd|› dt|ƒ› d�ƒ tddd›dd	d
›ddd›ddd›ddd›ddd
›�ƒ tD ]ð\‰‰ ‡ ‡fdd„|D ƒ}t|ƒ}|dk rÖq¨tdd„ |D ƒƒ}tdd„ |D ƒƒ}tdd„ |D ƒƒ}|| ||  d }ˆdk�r.dnd}tdˆd›dˆ d›d|d›d|| d d ›d!|| d d ›d!|d d"›d!|| t |¡ d#›|› �ƒ q¨d S )$NZHDAÚ
ú   (z outcome observations)ú  ZbucketZ12sú r   z>7sZimpliedz>8sZactualÚrelÚzc                    s,   g | ]$}ˆ|d    kr ˆ k rn q|‘qS )r   r   r;   ©rK   rJ   r   r   r/   r   r0   ztable.<locals>.<listcomp>éÈ   c                 s   s   | ]\}}|V  qd S rF   r   ©r+   ÚprL   r   r   r   rI   v   r0   ztable.<locals>.<genexpr>c                 s   s   | ]\}}|rd V  qdS ©r   Nr   )r+   rL   Úwr   r   r   rI   w   r0   c                 s   s   | ]\}}|d |  V  qdS rX   r   rV   r   r   r   rI   x   r0   r   r   z  <-- xlow bets herer&   z.2fú-z   Z7dr   z7.2fz% z+7.1fz+7.2f)Ú	enumerater   ÚprintÚlenÚBUCKETSr@   ÚmathZsqrt)ÚgamesZdevigZlabelÚonlyZobsrA   r8   r7   rW   r=   Zletterr?   r   ZexpZactÚvarrR   Úflagr   rT   r   Útableg   s4    8<ÿÿÿrd   c               	   C   sN  g } t tƒ}tdttƒ› dt|ƒ› dttƒ› d�ƒ tD ]b}d}|D ]<}ttd|› d|› d�ƒd	tt	fd
ƒ}| |7 } |t|ƒ7 }qDtd|d›d|d›�ƒ q8tD ]R}ttd|› d�ƒdtt	fdƒ}| |7 } td|d›dt|ƒd›dt| › d�ƒ q tdt| ƒ› d�ƒ t
| tdƒ t
| tdƒ t
| tdd
hd� tdƒ tdƒ tdƒ d S )Nz	fetching z European divisions x z seasons + z country feeds ...r   z(https://www.football-data.co.uk/mmz4281/ú/z.csvZFTRZeurorP   Z4srQ   Z6dz$https://www.football-data.co.uk/new/ZResÚnewrO   ú)z
TOTAL z! games with Pinnacle closing oddsz,PROPORTIONAL DEVIG  (what our pipeline uses)z=POWER DEVIG  (control for proportional overstating longshots)z2EUROPEAN ONLY, proportional  (78% of the backtest))ra   zF
If the 0.20-0.25 dip survives POWER devig it is a real market effect;zEif it vanishes, our proportional devig was inflating CLV on longshotsz5-- which would be OUR bug, and equally worth knowing.)r   Ú	N_SEASONSr\   r]   Ú	EURO_DIVSÚ	NEW_FEEDSr9   r%   ÚODDSÚFALLBACKrd   rC   rM   )r`   ZssZdivZgotr?   ÚgÚcoder   r   r   Úmain   s6    ÿ

ÿ
ÿ*ro   Ú__main__)N)Ú__doc__ÚsysZurllib.requestr!   r2   r1   r_   Úcollectionsr   ri   rj   r]   ÚargvÚintrh   rk   rl   r^   r   r   r%   r9   rC   rM   rd   ro   Ú__name__r   r   r   r   Ú<module>   s2   þ 
