a
    Gf¨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ZddlZdZ	dZ
ej ej e¡¡Zej ed¡Zej ed¡Zd\ZZdZdd
d„Zdd„ Zdd„ Zdd„ Zdd„ ZedkrÆe eƒ ¡ dS )a  What do the SUCCESSFUL Polymarket soccer makers actually do differently?

(read-only; touches no account and places nothing)

The coarse cuts came back empty: among genuine two-sided makers, winners and
losers are indistinguishable on legs quoted (2.08 vs 2.16), full-book rate
(42% vs 44%), two-sidedness (0.73 vs 0.72) and inventory discipline (0.17 vs
0.13). The only separator was SIZE, and in the wrong direction -- losers traded
2.3x the volume.

So this looks at the things a maker actually controls, per fill:

  ADVERSE SELECTION -- the core maker risk and the one our own xlow verdict is
  built on. For each fill, where did the price go afterwards? Signed by side:
  a maker who SOLD at 0.40 and sees 0.30 ten minutes later was right; one who
  sees 0.55 was picked off. Mid is estimated as the volume-weighted price of
  trades in a window around each timestamp, since the resting book is not
  public.

  TIMING -- share of volume in the first vs last third of the market's life.
  Our own decile study says the money is in a market's first ~30% of volume,
  so if that transfers, winners should be early.

  PRICE BUCKET -- do they make on favourites, longshots, or the draw? The draw
  is the leg our maker strands on.

  HOLD vs FLATTEN -- what fraction of their peak position is still open at
  settlement. This is the strand question in the only form this data can
  answer.

EVERYTHING IS FILLS, NEVER QUOTES: Polymarket's CLOB is off-chain, so resting
orders are public nowhere. A maker who quoted and was not hit is invisible.
é    Nz https://gamma-api.polymarket.comzhttps://data-api.polymarket.comz_pm_trades_cache.jsonzpm_maker_behaviour.csv)iô  i'  )iX  i  i   é   c              	   C   sˆ   t |ƒD ]z}ztj| |dd�}W n( tyH   t d|d  ¡ Y qY n0 |jdkr`| ¡   S |jdkrp d S t d|d  ¡ qd S )Né   )ÚparamsZtimeoutg333333ó?é   éÈ   é�  )ÚrangeÚrequestsÚgetÚ	ExceptionÚtimeÚsleepZstatus_codeÚjson)Zurlr   ZtriesÚiÚr© r   úresearch/pm_maker_behaviour.pyÚ_get5   s    

r   c                 C   sr   g d }}|t k rn| t|dœ}|s*d|d< tt› d�|ƒ}|s@qn||7 }|t|ƒ7 }t|ƒtk rbqnt d¡ q
|S )Nr   )ÚmarketÚlimitÚoffsetÚfalseÚ	takerOnlyú/tradesg{®Gáz´?)Ú
OFFSET_CAPÚPAGEr   ÚDATAÚlenr   r   )ÚcidZ
taker_onlyÚrowsÚoffÚpÚdr   r   r   ÚtradesC   s    
r#   c              
   C   s¾   g }dD ]°}t t› d�d|dddddœƒ}|s2 qº|D ]€}| d	¡pFg }t|ƒd
ks6d| d¡pbd ¡ vrlq6tdd„ |D ƒƒs€q6tdd„ |D ƒƒr”q6| |¡ t|ƒ| kr6|    S q6q|S )N)r   éd   r   i,  r   z/eventsr$   ZsoccerÚtrueZvolumer   )r   r   Ztag_slugÚclosedÚorderZ	ascendingÚmarketsé   z vsÚtitleÚ c                 s   s   | ]}|  d ¡V  qdS )ÚoutcomePricesN©r
   ©Ú.0Úmr   r   r   Ú	<genexpr>_   ó    z#complete_matches.<locals>.<genexpr>c                 s   s2   | ]*}t t› d �| d¡dtd ddœƒV  qdS )r   ÚconditionIdr   r   r   )r   r   r   r   N)r   r   r
   r   r.   r   r   r   r1   a   s   ý

ÿÿ)r   ÚGAMMAr
   r   ÚlowerÚallÚanyÚappend)ÚnÚoutr    ÚevsÚeZmsr   r   r   Úcomplete_matchesS   s.    
ÿÿ"ý
r=   c              
   C   sÂ  t j t¡r~ttdd��}t |¡}W d   ƒ n1 s80    Y  | d¡| kr~tdt	dd„ |d  
¡ D ƒƒ› d�ƒ |d S t| ƒ}i }|D ]ì}| d	¡pžd
 dd¡ ¡ }td|d d… d›�d
dd� d}|d D ]�}| d¡}	t|	dƒ}
dd„ t|	dƒD ƒ}zdd„ t | d¡¡D ƒ}W n t�y8   g }Y n0 |
||| d¡| d¡dœ||	< |t|
ƒ7 }qÖtd|d›d�ƒ qŽttd dd��"}t | |d!œ|¡ W d   ƒ n1 �s´0    Y  |S )"Núutf-8)Úencodingr9   zusing cached tape (c                 s   s   | ]}t |d  ƒV  qdS )r6   N)r   ©r/   Úvr   r   r   r1   q   r2   zload.<locals>.<genexpr>Úmkz rows)r*   r+   ÚasciiÚreplacez  é2   z<50T)ÚendÚflushr   r(   r3   Fc                 S   s"   g | ]}|d  › d|d › �‘qS )ÚtransactionHashú|ÚproxyWalletr   ©r/   Úxr   r   r   Ú
<listcomp>|   r2   zload.<locals>.<listcomp>c                 S   s   g | ]}t |ƒ‘qS r   )ÚfloatrK   r   r   r   rM   ~   r2   r,   ÚslugZquestion)r6   ÚtakersÚpricesrO   Úqú z>6z rowsÚw)r9   rB   )ÚosÚpathÚexistsÚCACHEÚopenr   Úloadr
   ÚprintÚsumÚvaluesr=   ÚencodeÚdecoder#   Úloadsr   r   Údump)Ú	n_matchesÚfhr"   r;   rB   r<   ÚtZnrr0   r   ÚallrZtkZprr   r   r   rZ   l   s8    (&


ÿ
2rZ   c            +         sØ  t tjƒdkrttjd ƒnd} t| ƒ}t dd„ ¡}| ¡ D �]\}}|d t|d ƒ }}|d }t t	¡‰|D ]Z}z>ˆt| 
d¡pŠd	ƒ  t|d
 ƒt|d ƒt|d ƒf¡ W qt ttfyÌ   Y qt0 qtˆD ]}	ˆ|	  ¡  qÔdd„ ˆ ¡ D ƒ‰ˆ�s q>tdd„ ˆ ¡ D ƒƒ}
tdd„ ˆ ¡ D ƒƒ}t||
 dƒ}‡‡fdd„}|D �]}|d }|d › d|› �|v �rv�qLz<t|d
 ƒ}t|d ƒ}t|d ƒ}t| 
d¡�p¬d	ƒ}W n ttf�yÐ   Y �qLY n0 || ‰ ˆ d  d7  < ˆ d  |¡ ˆ d  ||
 | ¡ | 
d¡�pd ¡ }|dk�r0dnd}ˆ d  || | 7  < ˆ d  ||f  |dk�rj|n| 7  < tˆ d! ||f tˆ d  ||f ƒƒˆ d! ||f< |t |ƒk �r¼|| nd"ˆ d# ||f< |dk�rÞˆ d$ nˆ d% ||f  |7  < tD ]X}||||d&  ||d&  ƒ}|d u �r(�qúˆ d' |  || |dk�rHdnd ¡ �qú�qLq>g }| ¡ D �]>\}‰ ˆ d d(k �r‚�qftˆ d$ ƒtˆ d% ƒB }g }d"}|D ]^}	ˆ d$  
|	d"¡ˆ d%  
|	d"¡ }}||| 7 }| t||ƒ�rüt||ƒt||ƒ nd"¡ �q¦|�rt|ƒt |ƒ nd"}|�r@t‡ fd)d„|D ƒƒ| nd}|d*k �sf|d+k�r\�qft‡ fd,d„ˆ d   ¡ D ƒƒ}td-d„ ˆ d   ¡ D ƒƒ} tˆ d!  ¡ ƒ�p¨d}!|tˆ d | d&ƒˆ d t|d.ƒt|d.ƒt|ƒttˆ d ƒt ˆ d ƒ d.ƒttd/d„ ˆ d D ƒƒt ˆ d ƒ d.ƒttd0d„ ˆ d D ƒƒt ˆ d ƒ d.ƒt| |! d.ƒd1œ
}"tD ]B}ˆ d' | }#|#�r‚tt|#ƒt |#ƒ d2ƒnd |"d3|d4 › d5�< �qV| |"¡ �qf|jd6d„ d7� ttd8dd9d:��<}$tj|$t	|d	  ¡ ƒd;�}%|% ¡  |% |¡ W d   ƒ n1 �s0    Y  td<t |ƒ› d=t› d>�ƒ d?d@„ |D ƒ}&dAd@„ |D ƒ}'dBdC„ }(tdDƒ tdEddFt |&ƒ dGt |'ƒ f ƒ dHD ]P\}	})|(|&|	ƒ|(|'|	ƒ }*}|	  d'¡�r¾|*d( |d(  }*}tdI|)|*|f ƒ �q‚d	S )JNr   é
   c                   S   s<   dd„ t D ƒg dt t¡t t¡i g dt t¡t t¡dœ
S )Nc                 S   s   i | ]
}|g “qS r   r   )r/   Úhr   r   r   Ú
<dictcomp>�   r2   z*main.<locals>.<lambda>.<locals>.<dictcomp>ç        r   )
ÚdriftÚpxÚcashÚposÚpeakÚsettleÚ	life_fracr9   ÚbuyÚsell)ÚHORIZONSÚcollectionsÚdefaultdictrN   r   r   r   r   Ú<lambda>Ž   s
    üzmain.<locals>.<lambda>r6   rP   rQ   ZoutcomeIndexr   Z	timestampZpriceÚsizec                 S   s    i | ]\}}|d d„ |D ƒ“qS )c                 S   s   g | ]}|d  ‘qS )r   r   rK   r   r   r   rM   ¡   r2   z#main.<locals>.<dictcomp>.<listcomp>r   )r/   ÚkrA   r   r   r   rh   ¡   r2   zmain.<locals>.<dictcomp>c                 s   s   | ]}|rt |ƒV  qd S ©N)Úminr@   r   r   r   r1   ¤   r2   zmain.<locals>.<genexpr>c                 s   s   | ]}|rt |ƒV  qd S ry   )Úmaxr@   r   r   r   r1   ¥   r2   c           
         sr   ˆ |  }ˆ|  }t  ||¡t  ||¡ }}|||… }|s>d S tdd„ |D ƒƒ}tdd„ |D ƒƒ}	|	rn||	 S d S )Nc                 s   s   | ]\}}}|| V  qd S ry   r   )r/   Ú_r!   Úsr   r   r   r1   ®   r2   z%main.<locals>.vwap.<locals>.<genexpr>c                 s   s   | ]\}}}|V  qd S ry   r   )r/   r|   r}   r   r   r   r1   ®   r2   )ÚbisectZbisect_leftZbisect_rightr\   )
ÚoiZt0Út1rA   Ztsr   ÚjZsegZnumZden)ÚtapeÚtimesr   r   Úvwap¨   s    $zmain.<locals>.vwaprJ   rH   rI   r9   rk   rp   Úsider+   ZBUYg      ð¿g      ð?rl   rm   rn   ri   ro   rq   rr   é   rj   r$   c                 3   s2   | ]*}t ˆ d   |d¡ˆ d  |d¡ ƒV  qdS )rq   r   rr   N)Úabsr
   )r/   rx   ©r}   r   r   r1   Ø   r2   g333333Ó?g333333ã?c                 3   s&   | ]\}}|ˆ d    |d¡ V  qdS )ro   ri   Nr-   )r/   rx   rR   rˆ   r   r   r1   Û   r2   c                 s   s   | ]}t |ƒV  qd S ry   )r‡   )r/   rR   r   r   r   r1   Ü   r2   r)   c                 s   s   | ]}|d k rdV  qdS )g…ëQ¸Õ?r   Nr   ©r/   Úfr   r   r   r1   â   r2   c                 s   s   | ]}|d krdV  qdS )gq=
×£på?r   Nr   r‰   r   r   r   r1   ã   r2   )
ZwalletÚpnlZfillsÚflipÚnet_exposureÚgross_volumeÚmean_fill_pxÚearly_shareÚ
late_shareÚheld_to_settleé   Zdrift_é<   r0   c                 S   s
   | d  S )Nr‹   r   )r   r   r   r   rv   ê   r2   )ÚkeyrT   r>   )Únewliner?   )Z
fieldnamesz
wrote z true makers -> Ú
c                 S   s   g | ]}|d  dkr|‘qS ©r‹   r   r   ©r/   r   r   r   r   rM   ð   r2   zmain.<locals>.<listcomp>c                 S   s   g | ]}|d  dkr|‘qS r˜   r   r™   r   r   r   rM   ñ   r2   c                    s.   ‡ fdd„| D ƒ}|r&t |ƒt|ƒ S tdƒS )Nc                    s"   g | ]}|  ˆ ¡d ur|ˆ  ‘qS ry   r-   r™   ©rx   r   r   rM   ó   r2   z%main.<locals>.avg.<locals>.<listcomp>Únan)r\   r   rN   )Zrsrx   rA   r   rš   r   Úavgò   s    zmain.<locals>.avgz7BEHAVIOUR OF WINNERS vs LOSERS  (true two-sided makers)z  %-22s %12s %12szWINNERS n=%dzLOSERS n=%d)
)Z	drift_10mzdrift +10m (c))Z	drift_30mzdrift +30m (c))Z
drift_120mzdrift +120m (c))r�   zmean fill price)r�   zshare filled early)r‘   zshare filled late)r’   zheld to settlement)rŒ   ztwo-sidedness)r�   znet exposure)rŽ   zgross volumez  %-22s %12.3f %12.3f)!r   ÚsysÚargvÚintrZ   rt   ru   ÚitemsÚsetÚlistr
   r8   rN   Ú	TypeErrorÚ
ValueErrorÚsortrz   r]   r{   Úupperr‡   rs   r\   ÚroundrY   ÚOUTÚcsvZ
DictWriterÚkeysZwriteheaderZ	writerowsr[   Ú
startswith)+rb   rB   ÚWr   r"   re   ZtsetrQ   rd   rx   Zt_loZt_hiÚspanr„   rT   Zts_rk   Zszr   r…   Zsignrg   Zfutr   rª   ZflipsZgrossÚbZslrŒ   Znetexpro   Zheldrn   r   rA   rc   ZwtrÚwinZlosrœ   ZlabÚar   )r}   r‚   rƒ   r   ÚmainŠ   s¾     
 ÿ	
$(ÿ&*
2".$&&ú42"r±   Ú__main__)r   )Ú__doc__r~   rt   r©   r   rU   r�   r   r	   r4   r   rV   ÚdirnameÚabspathÚ__file__ZHEREÚjoinrX   r¨   r   r   rs   r   r#   r=   rZ   r±   Ú__name__Úexitr   r   r   r   Ú<module>   s,   !
y