a
    ©hjL  ã                   @   sŽ   d Z ddlZddlZddlZddlmZ ddlmZ ej dd¡ ej dd¡ ddl	Z
ddlZddlZdZdd	„ Zd
d„ ZedkrŠeƒ  dS )a¬  Does Pinnacle price COLD-START fixtures worse than settled ones?

This is a pre-test for the SoFIFA question, run BEFORE spending any effort
acquiring squad-rating data.

THE LOGIC. Every strength feature we have tested (Elo, rolling form) is derived
from RESULTS, so it is blind at cold start: a newly promoted team, a season
opener, a squad rebuilt in the transfer window. Scout-assessed player ratings
(SoFIFA / EA) are genuinely different in provenance -- they carry information
about a squad that has not played yet. That is the one real gap in what we have
tested.

But squad ratings can only help if THE MARKET is also weak there. Pinnacle reads
the same team sheets. So the question that decides whether to scrape anything is
not "are ratings informative" but "is the closing line measurably worse on cold-
start fixtures than on settled ones?"

  - If the line is equally sharp at cold start -> no room. Do not scrape.
  - If the line degrades materially -> a gap exists, and squad ratings are the
    obvious candidate to fill it.

COLD START is measured as matches played by BOTH teams in the current season
(season = calendar year boundary is wrong for European leagues, so we use a
rolling "matches since a >60-day gap for that team", which detects a real
off-season break in any calendar).

Metric is LOG LOSS of the devigged closing line against the realised result.
Lower is better. The comparison is like-for-like on the same leagues.
é    N)Údefaultdict)ÚdatetimezE:\soccer\researchzE:\soccer\mainé<   c                    s(   dd„ | D ƒ}t |ƒ‰ ‡ fdd„|D ƒS )Nc                 S   s   g | ]}d | ‘qS )g      ð?© ©Ú.0Úxr   r   ú+E:\soccer\research\coldstart_market_test.pyÚ
<listcomp>.   ó    zdevig.<locals>.<listcomp>c                    s   g | ]}|ˆ  ‘qS r   r   r   ©Úsr   r	   r
   0   r   )Úsum)ÚoÚrr   r   r	   Údevig-   s    r   c               	      sà  t  ¡ } tt| ƒ› d�ƒ i ttƒ }}| D ]’}dD ]>}|| }||v rf|d ||  jtkrfd||< |d ||< q4||d  ||d   |d< |d< ||d   d	7  < ||d   d	7  < q,t 	¡ }g }| D ]š}|d t 
t |d ¡¡t 
t |d ¡¡f}| |¡}	|	�sqÐ|	\}
}tj |¡}|d u �r4qÐ| t t|
| d
ƒ¡ t|d |d ƒ|d dœ¡ qÐtt|ƒ› d�ƒ dd„ }tdƒ tdƒ tdƒ g d¢}i }|D ]4\‰‰ }||‡ ‡fdd„|D ƒƒ}|�r®|||< �q®dd„ |D ƒ}dd„ |D ƒ}t|ƒdk�rÜt|ƒdk�rÜtdd„ |D ƒƒt|ƒ ‰tdd„ |D ƒƒt|ƒ ‰t‡fdd„|D ƒƒt|ƒd	  t|ƒ t‡fdd„|D ƒƒt|ƒd	  t|ƒ  d }ˆˆ }td|d ›d!|d"›d#|| d$›�ƒ td%ƒ d S )&Nz fixtures with results)ÚhomeÚawayÚdater   r   r   Zmp_hZmp_aé   gê-�™—q=Údiv)ÚllÚmpr   z" matched to Pinnacle closing odds
c              
      s°   t |ƒdk r.td| d›dt |ƒd›d�ƒ d S tdd„ |D ƒƒt |ƒ ‰ t‡ fd	d„|D ƒƒt |ƒd
  t |ƒ d }td| d›dt |ƒd›dˆ d›d|d›�ƒ ˆ |t |ƒfS )Né2   z  Z26sz n=Z5dz  (too few)c                 s   s   | ]}|d  V  qdS ©r   Nr   r   r   r   r	   Ú	<genexpr>V   r   z$main.<locals>.blk.<locals>.<genexpr>c                 3   s   | ]}|d  ˆ  d V  qdS ©r   é   Nr   r   ©r   r   r	   r   W   r   r   ç      à?z  log loss ú.5fz  +/- )ÚlenÚprintr   )ÚnameÚsubÚser   r   r	   ÚblkR   s    .,zmain.<locals>.blkz5PINNACLE CLOSING LINE ACCURACY BY MATCHES-INTO-SEASONzD(lower log loss = sharper. If cold start is NOT worse, squad ratingsz0 cannot help, because the market already knows.)))r   r   zseason opener (0))r   é   zmatches 1-2)r'   é   zmatches 3-5)r(   é   zmatches 6-11)r)   iç  zmatches 12+ (settled)c                    s,   g | ]$}ˆ|d    kr ˆ k rn q|‘qS )r   r   r   )ÚhiÚlor   r	   r
   c   r   zmain.<locals>.<listcomp>c                 S   s   g | ]}|d  dk r|‘qS )r   r'   r   r   r   r   r	   r
   g   r   c                 S   s   g | ]}|d  dkr|‘qS )r   r)   r   r   r   r   r	   r
   h   r   r   c                 s   s   | ]}|d  V  qdS r   r   r   r   r   r	   r   j   r   zmain.<locals>.<genexpr>c                 s   s   | ]}|d  V  qdS r   r   r   r   r   r	   r   k   r   c                 3   s   | ]}|d  ˆ  d V  qdS r   r   r   )Úler   r	   r   l   r   c                 3   s   | ]}|d  ˆ  d V  qdS r   r   r   )Úll_r   r	   r   m   r   r   z/
  cold start (<3 played) minus settled (12+): z+.5fz +/- r    z	  -> t = z+.2fz9  positive t means the line IS worse when teams are cold.)ÚEZload_fixturesr"   r!   r   ÚintZdaysÚOFFSEASON_GAP_DAYSÚTZ	load_oddsZnormÚDSZ	fdco_nameÚgetZIDXÚappendÚmathÚlogÚmaxÚminr   )ZfxZlastZcntÚfZsideÚtZoddsZrowsÚkeyZhitÚpÚresÚir&   ZbucketsZnmr   ZearlyZlater%   Údr   )r*   r,   r-   r+   r	   Úmain3   sl    ".

ÿ
	((ÿÿÿÿr@   Ú__main__)Ú__doc__Zcsvr5   ÚsysÚcollectionsr   r   ÚpathÚinsertZelo_model_testr.   Znonprice_edge_testr1   Zdaily_signalsr2   r0   r   r@   Ú__name__r   r   r   r	   Ú<module>   s   A