a
    Éu€j�  ã                   @   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	 ddl
mZ ej dd¡ ddlZedƒZedƒZg d¢Zd	d
„ Zdd„ Zdd„ Zedkr eƒ  dS )a¿  What premium over the touch maximises EXPECTED BOOK VALUE?

The maker's payoff is not per leg. A book pays only when all three legs sell,
and it then collects the overround plus whatever premium each leg was sold
above the touch. So the quantity to maximise is

    E[book] = P(all three fill at premium d) x (overround + 3d)

Quoting higher raises the second term and destroys the first. The live ladder
picks d by decaying it with time-to-kickoff; nothing has ever measured the
curve it is walking down.

MEASURED FROM THE TRADE TAPE, not from our own fills. For each leg we fetch
every print between posting and kickoff and take the maximum. A resting ask at
price P would have been lifted iff some print landed at or above P, so one tape
read gives the fill/no-fill answer at EVERY premium at once -- the actual arm
the quoter happened to choose is irrelevant.

THE CEILING CAVEAT STILL APPLIES: a print at or above our price means we could
have been hit, not that we would have been. Queue priority is assumed, exactly
as mm_settle assumes it. Read the SHAPE of the curve, not its level.

Tape reads are cached to research/.tape_cache.json, so re-runs are free.

Usage:  python research\touch_premium_curve.py
é    N)Údefaultdict)ÚPathzE:\soccer\mainz&E:\soccer\research\mm_paper_quotes.csvz#E:\soccer\research\.tape_cache.json)r   é   é   é   é   é   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\touch_premium_curve.pyÚ_f,   s    
r   c                  C   s�   t t ¡ ƒd } t t| ¡ i }| jdddd��L}t |¡D ]0}| 	d¡}|r<||vr<| 	d¡s<ds<|||< q<W d  ƒ n1 s‚0    Y  |S )	z;First genuine quote per leg (action rows carry a `reason`).zmm_paper_quotes.snap.csvÚ zutf-8Úreplace)ÚnewlineÚencodingÚerrorsZ
leg_tickerÚreasonN)
r   ÚtempfileZ
gettempdirÚshutilZcopyfileÚQUOTESÚopenÚcsvZ
DictReaderÚget)ÚtmpÚfirstZfhÚrÚtr   r   r   Ú
first_rows3   s    
(r    c                     st  t  ¡ rt t  ¡ ¡ni } tƒ }tt|ƒ› dt| ƒ› d�ƒ i d }}tt	| 
¡ ƒdƒD �]f\}\}}t | d¡¡t | d¡¡ }‰t| d¡ƒt| d¡ƒ }}	|d u sXˆd u sX|d u sX|	d u rÈqXd|  k rÜdk rXn qXdˆ|  ¡ d	   k �rd
k�sqX qX|| v �r| | }
n~t ||¡}‡fdd„|D ƒ}|�rHt|ƒnd}
|
| |< |d7 }|d dk�ršt  t | ¡¡ td|› d|› dt|ƒ› d�ƒ | d¡||
|	| d¡�p¶ddœ||< qXt  t | ¡¡ tt|ƒ› d|› d�ƒ ttƒ}| ¡ D ]}||d   |¡ �qúdd„ | 
¡ D ƒ}tt|ƒ› d�ƒ |�sBd S tdd›ddd ›dd!d"›dd#d$›dd%d ›�	ƒ tD ]ê‰ t‡ fd&d'„| ¡ D ƒƒ}d(\}}| 
¡ D ]T\}}t‡ fd)d'„|D ƒƒ�r¢|d7 }td*d'„ |D ƒƒd+ d, }||d-ˆ   7 }�q¢t|ƒ}|| }tˆ d.›d/d,| t|ƒ d0›d1|d.›d2|d3›dd,| | d4›d1|d5›d/|d6›d7�ƒ �qttd8ƒ td9ƒ d S ):Nz legs; z tape reads cachedr   r   ÚtsZkickoffZk_askZover_askg      ¬@é   c                    s   g | ]\}}|ˆ kr|‘qS r   r   )Ú.0r   Úp)Úkor   r   Ú
<listcomp>Q   ó    zmain.<locals>.<listcomp>ç        é   z  ... z new tape reads (ú/ú)ÚeventÚregimeú?)r,   ÚtouchÚmaxÚoverr-   z legs usable, z new reads
c                 S   s"   i | ]\}}t |ƒd kr||“qS )r   )Úlen)r#   ÚeÚvr   r   r   Ú
<dictcomp>`   r'   zmain.<locals>.<dictcomp>z three-leg books
Zpremiumz>8ú zleg fillz>9zbooks completez>15Z	collectedz>10zE[book]c                 3   s*   | ]"}|d  |d ˆ d  krdV  qdS )r0   r/   ç      Y@r   Nr   )r#   r4   ©Údr   r   Ú	<genexpr>h   r'   zmain.<locals>.<genexpr>)r   r(   c                 3   s&   | ]}|d  |d ˆ d  kV  qdS )r0   r/   r7   Nr   ©r#   r   r8   r   r   r:   k   r'   c                 s   s   | ]}|d  V  qdS )r/   Nr   r;   r   r   r   r:   m   r'   g      ð?r7   r   z>7zc z>8.0fz% z / z<5z>3.0fz>9.0fz>8.2fÚczC
E[book] is per book QUOTED, not per book completed -- the number azEquoting policy actually earns. Fills assume queue priority (CEILING).)ÚCACHEÚexistsÚjsonÚloadsÚ	read_textr    Úprintr2   Ú	enumerateÚsortedÚitemsÚMSZ_ptr   r   Ztotal_secondsZtrades_tuplesr0   Z
write_textÚdumpsr   ÚlistÚvaluesÚappendÚPREMIUMSÚsumÚall)Úcacher   ZlegsZn_newÚiZtkrr   r!   Zkar1   ZmxZtradesZpreZbooksr4   ZfullZlegfillZcompÚvalr3   Zv3Zover_cÚnZevr   )r9   r%   r   Úmain@   sz    
 " >

 ÿÿÿÿÿÿþþrR   Ú__main__)Ú__doc__r   ZdatetimeZdtr?   r   Úsysr   Úcollectionsr   Úpathlibr   ÚpathÚinsertZ	mm_settlerF   r   r=   rK   r   r    rR   Ú__name__r   r   r   r   Ú<module>   s$   8