a
    Ç�je  ã                   @   s¬   d Z ddlZddlZddlZddlZddlZej dd¡ ej dd¡ ddlZ	dZ
dZddd	d
œZ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µ  Can we predict, BEFORE kickoff, which games will swing in play?

In-play moves are 16x pre-match at the p99 (mm_inplay_swings.py). The question
is whether the swinging is foreseeable from things known before the ball is
kicked, since everything a strategy can act on has to be known by then.

Target:   in-play price movement per fixture -- mean absolute snapshot-to-
          snapshot move across its three legs, from live_data with elapsed > 0.
Features: all strictly pre-kickoff --
            expected goals, from API-Football rolling gf/ga over the last 5
            the favourite's price (a 75c favourite has less room to travel)
            how evenly matched the book is (spread between top and bottom leg)
            league
            recent shot volume, as a proxy for chaotic end-to-end games

A goal is what moves a soccer book, so if anything predicts the swinging it
ought to be how many goals the two teams have been involved in.
é    NzE:\soccer\mainzE:\soccer\researchzE:\soccer\live_dataz$E:\soccer\raw_api\match_features.csvZkalshi_home_midZkalshi_draw_midZkalshi_away_mid)ÚhomeÚdrawÚawayé   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\research\mm_predict_inplay_vol.pyÚ_f    s    
r   c                  C   s€  t dd„ t t¡D ƒƒt d… } t dd„ ¡}| D �]D}ttj 	t|¡ddd���}t
 |¡D ]ø}t | d	¡¡}| d
¡}|du s`|dv r�q`zt|ƒ}W n ty²   Y q`Y n0 | d¡| d¡| d¡| d¡f}t ¡ D ]v\}}	t| |	¡ƒ}
|
du sàd|
  k �rdk �sqà qà|dk�r@|| d |  ||
f¡ qà|| d |  |
¡ qàq`W d  ƒ q41 �sp0    Y  q4|S )zG{(gd, home, away): {'pre': {side: [mid]}, 'live': {side: [(ts, mid)]}}}c                 s   s   | ]}|  d ¡r|V  qdS )z.csvN)Úendswith)Ú.0Úfr   r   r   Ú	<genexpr>)   ó    zload_live.<locals>.<genexpr>Nc                   S   s   t  t¡t  t¡dœS )N)ÚpreÚlive)ÚcollectionsÚdefaultdictÚlistr   r   r   r   Ú<lambda>+   s   ÿzload_live.<locals>.<lambda>úutf-8Úreplace©ÚencodingÚerrorsZ	timestampÚelapsed)NÚ Z	game_dater   r   Úleaguer   é   r   r   )ÚsortedÚosÚlistdirÚLIVE_DIRÚDAYSr   r   ÚopenÚpathÚjoinÚcsvÚ
DictReaderÚSZ_ptÚgetr   r	   ÚSIDESÚitemsr   Úappend)ÚfilesÚoutÚfnÚfhÚrZtsZelÚkeyÚsideÚcolÚmr   r   r   Ú	load_live'   s:    "ÿ
ÿ

ÿ"
<r;   c                  C   s´   i } t j t¡s| S ttddd��~}t |¡D ]b}| d¡p>ddd… | d¡ }}|r.|s^q.t| d	¡ƒt| d
¡ƒt| d¡ƒdœ| ||f< q.W d  ƒ n1 s¦0    Y  | S )zF{(date, team): {gf5, ga5, shots5}} from API-Football rolling features.r   r   r   Údater    Né
   ZteamZ	api_gf_w5Z	api_ga_w5Zapi_total_shots_w5)ÚgfÚgaÚshots)	r$   r)   ÚexistsÚFEATSr(   r+   r,   r.   r   )r3   r5   r6   ÚdÚtr   r   r   Ú
load_featsF   s    "þ.rE   c                 C   sX   g }|   ¡ D ]0\}}t|ƒ}|dd„ t||dd … ƒD ƒ7 }qt|ƒdkrTt |¡S d S )Nc                 S   s(   g | ] \\}}\}}t || ƒd  ‘qS )éd   )Úabs)r   Ú_ÚaÚbr   r   r   Ú
<listcomp>Z   r   zinplay_move.<locals>.<listcomp>r"   r=   )r0   r#   ÚzipÚlenÚ
statisticsZmean)r   Úvalsr8   ZptsÚsr   r   r   Úinplay_moveV   s
    "rQ   é   c                    s‚  t ‡fdd„| D ƒƒ‰tˆƒdk r&d S ‡fdd„dD ƒ}g d¢}d|d	 f|d	 |d
 f|d
 |d f|d dfg}td|› d�ƒ g }t||ƒD ]x\\‰‰ }‡ ‡‡fdd„| D ƒ}	t|	ƒdk rÂq’t dd„ |	D ƒ¡}
| ||
f¡ td|d›dt|	ƒd›d|
d›d�ƒ q’t|ƒdk�r~td|d d	 › d|d	 d	 › d|d d
 |d	 d
  d›d|d d
 td|d	 d
 ƒ d ›d!�	ƒ d S )"Nc                 3   s$   | ]}|  ˆ ¡d ur|ˆ  V  qd S r   ©r.   ©r   r6   ©r7   r   r   r   _   r   zbucket.<locals>.<genexpr>é<   c                    s    g | ]}ˆ t tˆ ƒ| ƒ ‘qS r   )ÚintrM   )r   Úp)rO   r   r   rK   b   r   zbucket.<locals>.<listcomp>)g      Ð?g      à?g      è?)z
lowest 25%Z2ndZ3rdzhighest 25%g    eÍÍÁr   r"   é   g    eÍÍAz
  by ú:c                    s:   g | ]2}|  ˆ¡d urˆ|ˆ   kr.ˆ k rn q|‘qS r   rS   rT   )Úhir7   Úlor   r   rK   i   r   é   c                 s   s   | ]}|d  V  qdS ©ÚmoveNr   rT   r   r   r   r   l   r   ú    z>12ú ú>4z games   median in-play move ú>5.2fÚcú    -> éÿÿÿÿz vs z: z+.2fzc (ç{®Gáz„?ú.2fzx))r#   rM   ÚprintrL   rN   Úmedianr1   Úmax)Úrowsr7   ZlabelÚnZcutsÚnamesZedgesZgotZnmZselr:   r   )r[   r7   r\   rO   r   Úbucket^   s2    &
ÿÿ ÿþro   c                  C   s:  t ƒ } tƒ }tt| ƒ› dt|ƒd›d�ƒ g }|  ¡ D �]4\\}}}}}t|d ƒ}|d u r^q6dd„ |d  ¡ D ƒ}	t|	ƒdkr‚q6| ||f¡| ||f¡ }
}d }d }|
�r0|�r0td	d
„ |
d |
d |d |d fD ƒƒ�r0|
d |d  |d  |
d  d }|
d d u�r0|d d u�r0|
d |d  }| ||t	|	 
¡ ƒt	|	 
¡ ƒt|	 
¡ ƒ |	 d¡||dœ¡ q6tt|ƒ› dtdd
„ |D ƒƒ› d�ƒ t|ƒdk �r®tdƒ d S tdt dd
„ |D ƒ¡d›d�ƒ t|ddƒ t|ddƒ t|ddƒ dd „ |D ƒ}t|ƒd!k�r2t|d"d#ƒ td$d „ |D ƒdd%ƒ t t¡}|D ]}||d&   |d' ¡ �q@td(d
„ | ¡ D ƒd)d*„ d+�}|�r6td,ƒ |d d-… D ].\}}}td.|d/›d0|d1›d2|d3›d�ƒ �q–td4ƒ |d5d … D ].\}}}td.|d/›d0|d1›d2|d3›d�ƒ �qÚtd6|d7 d8 t	d9|d: d8 ƒ d;›d<�ƒ d S )=Nz fixtures in live_data, ú,z team-match feature rowsr   c                 S   s    i | ]\}}|r|t  |¡“qS r   )rN   rj   )r   rP   Úvr   r   r   Ú
<dictcomp>�   r   zmain.<locals>.<dictcomp>r   é   c                 s   s   | ]}|d uV  qd S r   r   )r   r   r   r   r   r   ‡   r   zmain.<locals>.<genexpr>r>   r?   g       @r@   r   )r_   r!   ÚfavÚspreadr   Ú	exp_goalsr@   z* fixtures with in-play movement measured, c                 s   s   | ]}|d  durdV  qdS )rv   Nr"   r   rT   r   r   r   r   “   r   z with API-Football features
éP   ztoo fewzmedian in-play move overall: c                 s   s   | ]}|d  V  qdS r^   r   rT   r   r   r   r   ™   r   rh   rd   rt   zthe favourite's pre-match priceru   z/how lopsided the book is (top leg - bottom leg)zthe draw pricec                 S   s   g | ]}|d  dur|‘qS )rv   Nr   rT   r   r   r   rK   ž   r   zmain.<locals>.<listcomp>rV   rv   z&expected goals (rolling gf/ga, last 5)c                 S   s   g | ]}|d  dur|‘qS )r@   Nr   rT   r   r   r   rK   ¡   r   z'recent shot volume (both teams, last 5)r!   r_   c                 s   s2   | ]*\}}t |ƒd kr|t |¡t |ƒfV  qdS )é   N)rM   rN   rj   )r   Úlgrq   r   r   r   r   §   s   ÿc                 S   s
   | d  S )Nr"   r   r
   r   r   r   r   ©   r   zmain.<locals>.<lambda>rU   z
  by league (top and bottom):rR   r`   z>8ra   rb   z	 games   rc   z    ...éýÿÿÿre   r   r"   rg   rf   z.1fzx across leagues)r;   rE   ri   rM   r0   rQ   r.   Úallr1   rk   ÚvaluesÚminÚsumrN   rj   ro   r   r   r   r#   )r   Zfeatsrl   Úgdr   r   ry   rC   Zmvr   Zfh_Zfa_rv   r@   ZfgZby_lgr6   Zlgsr:   Úkr   r   r   Úmainv   sx    ÿ
$
ü
ÿ
ÿ
ÿ
ÿþ&&r�   Ú__main__)rR   )Ú__doc__r+   r   r$   rN   Úsysr)   ÚinsertZ	mm_settler-   r&   rB   r/   r'   r   r;   rE   rQ   ro   r�   Ú__name__r   r   r   r   Ú<module>   s$   (ÿ
>