a
    ˆªj‘2  ã                   @   s¼   d Z ddlZddlZddlZddlmZ ddlZdZdZd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d„Zd!dd„Zedkr¸ddlmZ ee ¡ edd� ƒ dS )"uº   
Kalshi live price checker â€” all supported European + MLS leagues.
At halftime, call check_halftime() to get the current away-win price
and whether there's edge to buy more contracts.
é    N)Údatez-https://api.elections.kalshi.com/trade-api/v2gÉv¾Ÿ/½?c                 C   s
   t  | ¡S )zMGet Kalshi abbreviation for a team. Reads from team_map.json via maps module.)ÚmapsZ
kalshi_abr)Z	team_name© r   úkalshi_live.pyÚget_abr   s    r   c                   C   s    t ttddd„ t ¡ D ƒƒƒƒS )zCReturn list of all unique Kalshi series tickers across all leagues.Nc                 S   s   g | ]}t  |¡‘qS r   ©r   Úleague_kalshi_series©Ú.0Údr   r   r   Ú
<listcomp>   ó    z&_all_kalshi_series.<locals>.<listcomp>)ÚlistÚsetÚfilterr   Úall_divsr   r   r   r   Ú_all_kalshi_series   s    r   c                   C   s   dd„ t  ¡ D ƒS )z2Return reverse mapping: series ticker -> div code.c                 S   s"   i | ]}t  |¡rt  |¡|“qS r   r   r	   r   r   r   Ú
<dictcomp>   r   z"_series_to_div.<locals>.<dictcomp>)r   r   r   r   r   r   Ú_series_to_div   s    r   c                 C   s@   |  d¡ ¡ }|  d¡}|  d¡}| › d|› |› |› |› |› �S )Nz%bz%dz%yú-)ÚstrftimeÚupper)ÚseriesÚ	game_dateÚhome_abrÚaway_abrZmonthZdayZyearr   r   r   Úbuild_event_ticker   s    

r   c              	   C   sT  | r|r|sdS t  dt  | ¡› d�¡}||f||fh}dD �]}zòd}tdƒD ]B}tjt› d�| d|dœd	d
�}|jdkr€ q”t 	d|d  ¡ qP|du s¦|jdkrªW q<| 
¡  dg ¡D ]v}| dd¡}	| |	¡}
|
sÚqº|
 d¡}tdt|ƒƒD ]<}|d|… ||d…  }}||f|v rò|	    W   S qòqºW q< t�yL   Y q<Y q<0 q<dS )aB  
    Search the entire series for an active event whose ticker ends with the two
    team abbreviations in either order, regardless of date.

    Useful when the game has been rescheduled in API-Football but Kalshi still
    has the event under its original date ticker.

    Returns the event_ticker string, or None.
    Nú^z-\d{2}[A-Z]{3}\d{2}([A-Z0-9]+)$)ÚopenZunopenedÚclosedé   ú/eventséÈ   ©Úseries_tickerÚlimitÚstatusé
   ©ÚparamsÚtimeoutg      ø?é   ÚeventsÚevent_tickerÚ )ÚreÚcompileÚescapeÚrangeÚrequestsÚgetÚBASEÚstatus_codeÚtimeÚsleepÚjsonÚmatchÚgroupÚlenÚ	Exception)r   r   r   ZpatÚtargetsr&   ÚrZattemptÚevZetÚmÚrestÚsplitÚaÚbr   r   r   Úfind_event_by_abrs$   s@    

ÿý


rF   c                 C   s@  t |ƒ}t |ƒ}d}|r’|r’t| |||ƒ}tjt› d|› d|› �dd�}|jdkrX|}n:t| |||ƒ}	tjt› d|	› d|› �dd�}|jdkr’|	}|s¢t| ||ƒ}|�s>tjt› d�| ddd	œdd
�}| ¡  dg ¡D ]f}
|
 dd¡}| ¡ | ¡ v rÖ| ¡ | ¡ v rÖ|
d }t	 
dt	 | ¡› d�|¡}|rÖ| d¡} �q>qÖ|�sHdS i }|df|dfdfD ]Ò\}}|› d|› �}tjt› d|› �dd�}|jdk�r^| ¡  d| ¡ ¡}
t|
 dd¡�p¾dƒ}t|
 dd¡�pÔdƒ}|dk�rî|| d n|}t|dƒ||› d�< t|dƒ||› d�< t|dƒ||› d�< �q^|�r<|S dS )zDFetch home, draw, and away prices from Kalshi. Returns dict or None.Nú	/markets/r   r'   ©r*   r"   ú/marketsr   r#   r(   ÚmarketsÚtitler.   Útickerú(z-\d+[A-Z]+\d+[A-Z]+)-[A-Z]+$r+   ÚawayÚhome)ÚTIEZdrawÚmarketÚyes_ask_dollarsr   Úyes_bid_dollarsé   é   Z_askZ_bidZ_mid)r   r   r3   r4   r5   r6   rF   r9   Úlowerr/   r:   r1   r;   ÚfloatÚround)r   r   Ú	home_teamÚ	away_teamr   r   ÚeventÚe1r?   Úe2rA   rK   Útr:   ÚresultZoutcomeZlabelrL   ZaskZbidÚmidr   r   r   Úget_all_pricesW   sN    

 
ra   c              	   C   s¸  t |ƒ}t |ƒ}|r|sÔtjt› d�| dddœdd�}| ¡  dg ¡D ]h}| dd	¡}| ¡ | ¡ v rF| ¡ | ¡ v rF|d
 }	t | › d�|	¡}
|
rF|
 d¡dkrFt	|	ƒ  S qFt
d|› d|› d|› d|› �ƒ d S t| |||ƒ}|› d|› �}tjt› d|› �dd�}|jdk�rHt| |||ƒ}|› d|› �}tjt› d|› �dd�}|jdk�rŒt| ||ƒ}|�rŒ|› d|› �}tjt› d|› �dd�}|jdk�rªt
d|› �ƒ d S t	|| ¡ ƒS )NrI   r"   r   r#   r'   r(   rJ   rK   r.   rL   z-\d+[A-Z]+\d+([A-Z]+)-([A-Z]+)$rT   rP   z  Could not find abbreviation: u   â†’z, r   rG   rH   i”  z  Market not found: )r   r3   r4   r5   r9   rV   r/   r:   r;   Ú_fetch_priceÚprintr   r6   rF   )r   r   rY   rZ   r   r   r?   rA   rK   rL   Zt_matchr[   Zaway_tickerZevent2Úfoundr   r   r   Úget_market_price�   s:      re   c              	   C   s–   |d u r(t jt› d| › �dd�}| ¡ }| d|¡}t| dd¡pDdƒ}t| dd¡pXdƒ}|dkrp|| d n|}| |||| d	d
¡| dd
¡dœS )NrG   r'   rH   rQ   rR   r   rS   rT   rK   r.   r&   )rL   Úyes_askÚyes_bidr`   rK   r&   )r3   r4   r5   r9   rW   )rL   Údatar?   rA   rf   rg   r`   r   r   r   rb   ´   s    ÿrb   ÚE0c                 C   s  || }t  | ¡ ¡pd}td|› d|› d|› d|› d|› d�ƒ |dkrbtdƒ d	d
d
d
d
dœS |dkr‚tdƒ dd
d
d
d
dœS t|| ||ƒ}|s˜d
S |d dkr¬|d n|d }	|	dkrÈtdƒ d
S t|	 }
|	tk }td|d › �ƒ td|	d d›d|d d d›d|d d d›d�ƒ tdt|ƒ› dtd d›d�ƒ td|
d d›d|�rZd nd!› �ƒ |�rÜd"|	 d" }tt| d"t  | d# dƒ}td$|d d›d%|	d d›d&td d›d'�ƒ td(|
|	 d d)›d*�ƒ |�ræd+nd,t|	d-ƒt|d d-ƒt|d d-ƒt|
d-ƒdœS ).zEPrints HT analysis and returns dict with kalshi price data (or None).Z	KXEPLGAMEz
[z] ú r   z at HTr   u/     Away team winning â€” HOLD. No action needed.ZHOLD_WINNINGN)ÚsignalZkalshi_priceZ
kalshi_bidZ
kalshi_askÚedgeu     Level at HT â€” HOLD.Z
HOLD_LEVELr`   rf   z1  No price available (market may not be live yet)z  Market:   rL   z  Price:    éd   z.1fz%  (bid rg   z% / ask z%)z!  Historical comeback rate (down z): ú%z  Edge:     z+.1fz%  ->  z
[BUY MORE]zNo edge - hold original onlyr+   g      à?z	  -> Add z% of bankroll at zc  (fair value zc)z  -> EV on additional bet: z.0fz% return on investmentZBUYZHOLDrU   )	r   r   r   rc   re   ÚCOMEBACK_RATEÚabsÚmaxrX   )r   rY   rZ   Zht_score_homeZht_score_awayZleague_codeZdeficitr   r_   Zpricerl   Zhas_edgerE   Úkr   r   r   Úcheck_halftime¿   sB    (6 $.ûrs   c              
   C   s´  t  ¡  | du rt ¡ } |  d¡ ¡ }tƒ }tƒ }tƒ }g }|D ]ô}d}t	dƒD ]â}|ddœ}	|rj||	d< t
jt› d�|	d	d
�}
|
 ¡ }| dg ¡p–g D ]p}| dd¡}||vr²q˜||v r¼q˜| |¡ t d| d¡pØd ¡ ¡}|r˜| || d¡ ¡ | d¡ ¡ f¡ q˜| d¡�pd}|�r*||k�r. q@|}qPq@td| › dt|ƒ› d�ƒ d}t|dd„ d�D ]J\}}}||k�r˜| ||¡}td|› d�ƒ |}td|› d|› �ƒ �qd|S )z4List all matches on a given date across all leagues.Nz%y%b%dr.   é   r"   )r$   r%   Úcursorr!   r'   r(   r,   r-   z(.+?) vs (.+)$rK   r+   rT   z
Matches on z (z games):c                 S   s   | d S )Nr   r   )Úxr   r   r   Ú<lambda>  r   zlist_matches.<locals>.<lambda>)Úkeyz
  [ú]z    z vs )r   Úreloadr   Útodayr   r   r   r   r   r2   r3   r4   r5   r9   Úaddr/   r:   ÚstripÚappendr;   rc   r<   Úsorted)Ztarget_dateZdate_strZ
all_seriesZ
series_divZseen_eventsZgamesr   ru   Ú_r)   r?   ZpayloadÚer@   r:   ZnxtZ
cur_seriesrO   rN   Zleaguer   r   r   Úlist_matchesí   sJ    




&
r‚   Ú__main__)Ú	timedeltar+   )Zdays)N)ri   )N)Ú__doc__r3   r/   r7   Zdatetimer   r   r5   ro   r   r   r   r   rF   ra   re   rb   rs   r‚   Ú__name__r„   r{   r   r   r   r   Ú<module>   s$   36'

.
4