a
    eâhjÌ  ã                   @   sh   d 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dd„ Zed	krdeƒ  dS )
aí  What if we had NEVER crossed early -- what would the paper maker have made?

FINDING THAT PROMPTED THIS (2026-07-28): complete_book() fires the instant a book
reaches 2-of-3 filled. In practice that was 8.6-10.1 HOURS before kickoff. We paid
~2c to cross while the third leg still had most of a twelve-hour window to sell at
our resting ask for free. The claim "9 of 9 books needed the completion rule" was
therefore never tested -- it was manufactured by our own trigger firing instantly.

THE COUNTERFACTUAL. For each leg we completed at the bid, ask the tape: did any
trade print at or above our ORIGINAL ask between the moment we crossed and
kickoff? If yes, a resting order would have been there to meet it, the leg fills
free, and the book earns its full gross with no fee. If no, we would still have
had to cross near kickoff, so we keep the cost we actually paid.

  net(delayed) = gross                      if the third leg would have sold
  net(delayed) = net(actual)                otherwise

KNOWN OPTIMISM, not buried: "a trade printed at our price" is not the same as
"we were filled". We join the queue behind existing size, so some of these would
not have been ours. This is the same ceiling assumption that made the earlier
historical replay predict 97.5% natural fills against a live 0-of-7 -- so treat
the output as an UPPER BOUND on the delayed rule, not an estimate. The live A/B
(cap arm filling 9/9) suggests our asks do get hit at the touch, which is why the
bound is worth computing at all.
é    N)ÚdefaultdictzE:\soccer\mainz&E:\soccer\research\mm_paper_quotes.csvé
   c                     sP  t t ttdd�¡ƒ} dd„ | D ƒ}tt|ƒ› d�ƒ tt ƒ}| D ]N‰ˆ d¡pRd 	d¡r\qBˆ d	¡rB|ˆd
 ˆd f  
ˆd tˆd	 ƒf¡ qBi }|D ]ž‰ˆd
 ˆd  }}‡fdd„| ||fg ¡D ƒ}|sÔqš|ˆd tˆd	 ƒ|d t ˆd ¡t ˆd ¡ˆd ˆd ˆd tt dˆd ¡ d¡ƒdœ
||< qš| ¡ D ]t\}‰ i }dD ]6}‡ fdd„| ||fg ¡D ƒ}|�rR|d ||< �qRt|ƒdk�r¬t| ¡ ƒd d nd ˆ d< �qBtddd›dd d!›dd"d#›dd$d%›dd&d#›dd'd#›�ƒ d( }	}
d)}t| ¡ d*d+„ d,�D ]ê\}‰ ˆ d d u �r*�qt ˆ d- ˆ d ¡}‡ fd.d„|D ƒ}t|ƒd)k}||7 }|�rrˆ d nˆ d/ }|	ˆ d/ t d 7 }	|
|t d 7 }
tdˆ d d d0… d›dˆ d d!›dˆ d1 d d2›d3t|ƒd4›dˆ d/ d5›d3|d5›d6�ƒ �qtd7|› d8t|ƒ› d9�ƒ td:|	d;›�ƒ td<|
d;›d=�ƒ td>|
|	 d;›�ƒ d S )?Nzutf-8)Úencodingc                 S   s$   g | ]}|  d ¡pd d¡r|‘qS )ÚreasonÚ ÚCOMPLETE_AT_BID)ÚgetÚ
startswith)Ú.0Úr© r   ú4E:\soccer\research\mm_delayed_completion_backtest.pyÚ
<listcomp>)   ó    zmain.<locals>.<listcomp>z$ completion events in the quote log
r   r   r   Zour_askZeventÚsideÚtsc                    s    g | ]\}}|ˆ d  k r|‘qS ©r   r   ©r
   ÚtÚa)r   r   r   r   7   r   Z
leg_tickeréÿÿÿÿZkickoffÚhomeÚawayÚdivz=> ([-+0-9.]+)cé   )
r   ÚtickerZbidÚorig_askr   Úkor   r   r   Ú
net_actual)r   Zdrawr   c                    s$   g | ]\}}|ˆ d    ¡ kr|‘qS r   )Z	isoformatr   ©Úbr   r   r   C   r   é   éd   Zgrossz  ZbookZ22sú ZlegZ5szour askz>8sztrades>=askz>12sZactualZdelayedg        r   c                 S   s   | d d S )Nr   r   r   )Zkvr   r   r   Ú<lambda>L   r   zmain.<locals>.<lambda>)Úkeyr   c                    sH   g | ]@}ˆ d  |d   k r(ˆ d k rn q|d ˆ d d kr|‘qS )r   r   r   r   r   g•Ö&è.>r   )r
   Úxr   r   r   r   P   r   r   é   r   z7.0fzc Z12dz+7.2fÚcz(
  third leg would have sold naturally: ú/z booksz"  ACTUAL   (cross immediately) : $z+.2fz"  DELAYED  (wait, cross late)  : $z   <- UPPER BOUNDz"  difference                   : $)ÚlistÚcsvZ
DictReaderÚopenÚQUOTESÚprintÚlenr   r   r	   ÚappendÚfloatÚSZ_ptÚreÚsearchÚgroupÚitemsÚsumÚvaluesÚsortedZtrades_tuplesÚSIZE)ZrowsZcompZhistZbooksZevr   ZpriorZlegsÚhZtot_aZtot_dZnatZtrZafterZwouldÚdr   )r    r   r   Úmain'   sn    
,ý.$ÿÿ4ÿÿÿr=   Ú__main__)Ú__doc__r+   ZdatetimeZdtr3   ÚsysÚcollectionsr   ÚpathÚinsertZ	mm_settler2   r-   r:   r=   Ú__name__r   r   r   r   Ú<module>   s   8