a
    ®6ejG  ã                   @   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Zddlm	Z	 ej
 dd¡ ddlZdZdZeejƒdkrzeejd ƒndZg d	¢Zd
d„ Zdd„ Zdd„ Zdd„ Zedkr´eƒ  dS )a™  
Backfill SETTLED Kalshi soccer markets with their pre-kickoff prices.

WHY: our live_data only holds ~976 fixtures with Kalshi quotes -- not enough to
resolve a ~5% relative calibration effect (it would need the effect to be ~22%
before it could see it). Kalshi's own API has every settled market we ever cared
about, so the sample is sitting there waiting to be pulled.

HOW:
  1. /markets?series_ticker=...&status=settled  (paginated) -> every finalised
     market for each of our leagues.
  2. Group the 3 markets of an event (home / away / tie) by event_ticker.
  3. For each market, /series/{s}/markets/{t}/candlesticks around kickoff and
     take the LAST candle that closes at or before kickoff and still has a live
     two-sided book (bid > 0, ask < 1). Settled markets report bid 0 / ask 1, so
     that filter is what keeps post-resolution prices out of the sample.
  4. Devig the three mids proportionally, record the result, write one row per
     fixture.

Output: research/kalshi_backfill.csv  (resumable -- reruns skip events already
written, so an interrupted pull can just be restarted).

Usage:  python research\kalshi_backfill.py [max_events_per_series]
é    N)ÚdefaultdictzE:\soccer\mainz&E:\soccer\research\kalshi_backfill.csvzE:\soccer\data\league_map.jsoné   i�  ©ÚdivÚseriesÚeventZkickoffÚhomeÚawayÚftrZ
k_home_bidZ
k_home_askZ
k_draw_bidZ
k_draw_askZ
k_away_bidZ
k_away_askZ	fair_homeZ	fair_drawZ	fair_awayc                  C   s$   t  ttdd�¡} dd„ |  ¡ D ƒS )Núutf-8)Úencodingc                 S   s0   g | ](\}}t |tƒr| d ¡r||d  f‘qS )Zkalshi_series)Ú
isinstanceÚdictÚget©Ú.0ÚkÚv© r   ú%E:\soccer\research\kalshi_backfill.pyÚ
<listcomp>.   s   ÿzseries_map.<locals>.<listcomp>)ÚjsonÚloadÚopenÚMAPÚitems)Úmr   r   r   Ú
series_map,   s    r   c              
   C   s¾   g d }}t |ƒ|k r²| dddœ}|r.||d< zt d|¡}W n> ty| } z&td|› �ƒ W Y d}~q²W Y d}~n
d}~0 0 | dg ¡}||7 }| d¡}|r²|s¦q²t d	¡ q
|d|… S )
z.All finalised markets for a series, paginated.NZsettledéÈ   )Zseries_tickerZstatusÚlimitÚcursorz/marketsz    list failed: Zmarketsg¸…ëQ¸¾?)ÚlenÚktÚ_getÚ	ExceptionÚprintr   ÚtimeÚsleep)r   ZcapÚoutr    ÚpÚrÚeÚmsr   r   r   Úsettled_markets2   s"    
"
r-   c           
      C   sì   dD ]â\}}z*t  d| › d|› d�|| ||dœ¡}W n tyL   Y  dS 0 d}| dg ¡D ]z}| dd	¡|krtq^z$t|d
 d ƒ}t|d d ƒ}	W n tttfy´   Y q^Y n0 |d	ks^|	dks^|	|krÐq^||	f}q^|r|  S qdS )zALast candle closing at/before kickoff with a live two-sided book.))i`T  é<   )i€Q r.   z/series/z	/markets/z/candlesticks)Zstart_tsZend_tsZperiod_intervalNZcandlesticksZend_period_tsr   Zyes_bidZclose_dollarsZyes_askr   )r"   r#   r$   r   ÚfloatÚKeyErrorÚ	TypeErrorÚ
ValueError)
r   ÚtickerÚko_tsZlookbackZintervalr*   ZbestÚcÚbÚar   r   r   Úpreko_quoteG   s0    ÿÿ



r8   c                     s   t ƒ } tj t¡rrttddd��.}t |¡D ]}|  |d ¡ q,W d   ƒ n1 sT0    Y  t	dt
| ƒ› d�ƒ ttdddd�}tj|td�}| sœ| ¡  tƒ D �]ä\}}t|tƒ}|sÔt	|d	›d
|d›d�ƒ q¢ttƒ}|D ]}|| d¡  |¡ qàd}	| ¡ D �]J\}
}|
| v �st
|ƒdk�r,�q|d  d¡�pH|d  d¡}|�sT�qz ttj | dd¡¡ ¡ ƒ}W n t�yŽ   Y �qY n0 i d  }}|D ]6}| d¡�p°d ¡ }| ¡ dv �rÊ|}n|||< �qž|�rt
|ƒdk�rî�q|d  dd¡}d|v�r�qdd„ | d¡d  d¡d d… D ƒ\‰‰ | ˆ¡�p\t ‡fdd„| ¡ D ƒd ƒ}| ˆ ¡�p„t ‡ fdd„| ¡ D ƒd ƒ}|�r|�r||u �r �q| d¡d k�r´d!n*| d¡d k�rÈd"n| d¡d k�rÜd#nd }|�sê�qi ‰d$}d%|fd&|fd'|ffD ]<\}}t!||d( |ƒ}t" #d)¡ |�s:d*} �qF|ˆ|< �q|�sP�q‡fd+d„d,D ƒ}t$|ƒ‰d-ˆ  k �r‚d.k �sˆn �q‡fd/d„|D ƒ}| %|||
|ˆˆ |ˆd% d ˆd% d0 ˆd& d ˆd& d0 ˆd' d ˆd' d0 t&|d d1ƒt&|d0 d1ƒt&|d d1ƒd2œ¡ |  |
¡ |	d07 }	|	d3 dk�r| '¡  t	d4|› d5|	› �ƒ �q| '¡  t	|d	›d
|d›d
t
|ƒd6›d7|	d6›d8�ƒ q¢| (¡  t	d9tƒ d S ):NÚ r   )Únewliner   r   z
resuming: z events already writtenr7   )Z
fieldnamesZ5sú Z26sz
 0 settledZevent_tickerr   é   Zoccurrence_datetimeZexpected_expiration_timeÚZz+00:00Zyes_sub_title)ÚtieÚdrawé   Útitlez vs c                 S   s   g | ]}|  ¡ ‘qS r   )Ústrip©r   Útr   r   r   r   �   ó    zmain.<locals>.<listcomp>z Winnerc                 3   s"   | ]\}}|r|ˆ v r|V  qd S ©Nr   r   )Úhome_nmr   r   Ú	<genexpr>“   rE   zmain.<locals>.<genexpr>c                 3   s"   | ]\}}|r|ˆ v r|V  qd S rF   r   r   )Úaway_nmr   r   rH   •   rE   ÚresultZyesÚHÚAÚDTr   r?   r	   r3   g¸…ëQ¸®?Fc                    s(   g | ] }ˆ | d  ˆ | d  d ‘qS )r   r   r@   r   rC   )Úqr   r   r   ¨   rE   )r   r?   r	   gš™™™™™é?gš™™™™™ù?c                    s   g | ]}|ˆ  ‘qS r   r   )r   r   )Úsr   r   r   ¬   rE   r   é   r   é   z    z ... Z4dz events -> z usablezdone ->))ÚsetÚosÚpathÚexistsÚOUTr   ÚcsvZ
DictReaderÚaddr%   r!   Z
DictWriterÚFIELDSZwriteheaderr   r-   ÚMAX_PER_SERIESr   Úlistr   Úappendr   ÚintÚdtÚdatetimeZfromisoformatÚreplaceZ	timestampr$   rB   ÚlowerÚsplitÚnextr8   r&   r'   ÚsumZwriterowÚroundÚflushÚclose)ZdoneZfhr*   Úwr   r   r,   Zbyr   ZwroteZevZmkZkor4   Zlegsr>   ÚsubrA   ZhmZamr
   ZokÚtagZpqZmidsZfairr   )rI   rG   rN   rO   r   Úmainb   sº    .

ÿ

ÿ
ÿÿþ
ù
.rk   Ú__main__)Ú__doc__ÚsysrS   rW   r   r&   r_   r^   Úcollectionsr   rT   ÚinsertZkalshi_traderr"   rV   r   r!   Úargvr]   rZ   rY   r   r-   r8   rk   Ú__name__r   r   r   r   Ú<module>   s&    ^