a
    ½ûÛiQ=  ã                   @   sP  d Z ddlZddlZddlZddlZe d¡ ddlm	Z
 ddlmZ ej d¡ dZdZg d¢Zd	Zd
ZdZdZdZdZg d¢Zddddddddddddddddd d!d"d#d$d%d&œZd'd(„ Zed)ƒ g Ze ¡ D ]²\ZZeD ]¤Z d*e› d+e › d,�Z!z€ej"e!d-d.�Z#e$e#ƒd/k �s(d0e#j%v�s(d1e#j%v�r,W qÜe#j&g d2¢d3�Z#e$e#ƒd/k �rNW qÜe e#d4< ee#d5< ee#d6< e 'e#¡ W qÜ   Y qÜ0 qÜqÐej(ed7d8�Z)ej*e)d9 d7d:d;�e)d9< e)j&d9gd3� +d9¡j,d7d<�Z)e-e)j.d=d>„ d?d@�Ž \Z/Z0Z1e) 2¡ Z)ej3e/e)j4dA�e)dB< ej3e0e)j4dA�e)dC< ej3e1e)j4dA�e)dD< d?e)dB  e)dE< d?e)dC  e)dF< d?e)dD  e)dG< e)d1 e)dG  e)dG  e)dH< e)dI e)dE  e)dE  e)dJ< e)dK e)dF  e)dF  e)dL< edMe$e)ƒdN›dOe)d6  5¡ › dP�ƒ edQd… Z6edRƒ edSe6› dT�ƒ g Z7g Z8g dU¢Z9e6D �]Z:ede 4e:¡… Z;e)e)d4  <e;¡ Z=e)e)d4 e:k Z>i Z?e$e;ƒZ@dVdW„ eAe;ƒD ƒZBe)d6  C¡ D �]âZDdXZEdZFe=e=d6 eDk ZGe9D �]`\ZHZIZJZKZLeGeGeI ek ZMe$eMƒek �r¾�qŒdYZNdYZOeM P¡ D ]L\ZQZReB SeRd4 dZ¡ZTeRd0 eLk�r eReJ d? nd[ZUeNeUeT 7 ZNeOeT7 ZO�qÎeOdk�r2eNeO d\ ndXZVg ZWe;D ]LZ eMeMd4 e k ZXe$eXƒek �rd�q>eYd]d^„ eX P¡ D ƒƒZZeW 'eZdk¡ �q>e$eWƒdk�rž�qŒeYeWƒe$eWƒ Z[eVdk�rŒe[ek�rŒeVeEk�rŒeVZEeHeJeKeLe$eMƒeVe[e$eWƒfZF�qŒeF�rjeF\ZHZJZKZLZ\ZVZ]Z^eHeJeKeLe\eVfe?eD< e8 'e:dN _e;¡eDeHe\e`eVdQƒe`e]dQƒe^d_œ¡ �qje? ¡ D ]¾\ZD\ZHZJZKZLZQZQe>e>d6 eDke>d`eL› � ek@  Zaea P¡ D ]|\ZQZReReJ d? ZbeReK Zcebdk�rÖedeceb d?ec  eb dƒndZeeedk�r–e7 'eRd9 e:eDeHeReJ eeeceRd0 eLkdaœ¡ �q–�qX�qe fe7¡ +d9¡j,d7d<�Zgegd9 jh idb¡egdc< edde$egƒdN›deegd9  j¡  k¡ › dfegd9  d¡  k¡ › dg�ƒ edhegdi  l¡ d\ dj›dk�ƒ edlegdm  l¡ d\ dj›dk�ƒ egjmdndodA� e fe8¡Znedpe6d[ › dq�ƒ enendr e6d[ k j+dsdodt�ZoedMdudv›dwdxdy›dwdzd{›dMd|d}›dMd~d›dMd€d}›�ƒ ed�ƒ eo P¡ D ]f\ZQZpedMepdu dv›dwepdx dy›dweqepd‚ ƒd{›dMepds dƒ›d„epd… d\ d†›d„eqepd‡ ƒd}›�ƒ �qPedˆƒ edMd4dy›dwd‰dŠ›dMd‹d}›dMdŒd›dMd�d{›�
ƒ edŽƒ e6D ]ŒZ egegd4 e k ZMeMjr�r�qüeMd� d?  seMdi d[¡Ztet l¡ d\ ZuedMe dy›dwe$eMƒdŠ›dMet Y¡ d�›dMeud‘›d„eMdi  l¡ d\ d’›dk�ƒ �qüegd� d?  segdi d[¡Zved“d”dy›dwe$egƒdŠ›dMev Y¡ d�›dMev l¡ d\ d‘›d„egdi  l¡ d\ d’›dk�ƒ ed•ƒ ed–ƒ ed—ƒ edMd˜d™›dwdšd››dMdœd›dMd�d›�ƒ edžƒ edZg D ]ÆZweZxeZydYZzeg P¡ D ]x\ZQZ{eje{dŸ ew d ƒZ|exe| Z}exe{di �	r˜e}e{d� d?  ne} 7 Zxexdk�	r´dZx �	qÔedeyexƒZyedezeyex ey ƒZz�	qZedMewd¡›d¢exd£›dMexe dƒ›d¤ezd\ d¥›dk�	ƒ �	qBed•ƒ ed¦edN›d§�ƒ ed—ƒ e$egƒZ~egd� jZ€egdm jZ�egdŸ jZ‚i Zƒd¨Z„eD �]¤Zwe …e‚ew d ¡Z†e ‡e¡Zˆe ‡e¡Z‰e ‡e„e~d? f¡ZŠeeŠdd…df< e‹eƒD ]äZŒej e~¡e�k Z�eZxeZydYZze‹e~ƒD ]€ZŽexe†eŽ  Z exe�eŽ �re e€eŽ d?  ne  7 Zxexdk�r"dZx �q\edeyexƒZyedezeyex ey ƒZzeŒe„k �
rÚexeŠeŒeŽd? f< �
qÚexeˆeŒ< eze‰eŒ< eŒe„k �
r²exdk�
r²deŠeŒeŽd? d…f< �
q²eˆe‰eŠd©œeƒew< ed“ewd¡›dª�ƒ ed«e �eˆ¡d¬›dee �eˆ¡e dj›d­�ƒ ed®e �eˆd/¡d¬›�ƒ ed¯e �eˆd°¡d¬›�ƒ ed±e �eˆd²¡d¬›�ƒ ed³e �eˆd´¡d¬›�ƒ edµeˆek l¡ d\ dj›dk�ƒ ed¶eˆed k l¡ d\ dj›dk�ƒ ed·eˆed/ k l¡ d\ dj›dk�ƒ ed¸eˆed k  l¡ d\ dj›dk�ƒ ed¹e �e‰¡d\ dj›dk�ƒ edºe �e‰d»¡d\ dj›dk�ƒ �
q^ed¼ƒ edMd½dv›�d¾d¿� eD ]ZwedMewd¡›dÀ�d¾d¿� �q&eƒ  edÁƒ dÂdÃd>„ fdÄdÅd>„ fdÆdÇd>„ fdÈdÉd>„ fdÊdËd>„ fdÌdÍd>„ fdÎdÏd>„ fdÐdÑd>„ fdÒdÓd>„ ff	D ]N\ZHZ‘edMeHdv›�d¾d¿� eD ]$ZwedMe‘eƒew dÔ ƒ› �d¾d¿� �qÐeƒ  �q°edMdÕdv›�d¾d¿� eD ].ZwedMe �eƒew dÖ ¡d\ d×›dk�d¾d¿� �qeƒ  dØdÙdÚdœZ’e$e6ƒZ“e
j”d?dÛdÜdÝ�\Z•Z–e•j—dÞe6d › dfe6d[ › dße$egƒdN›dàedN›dá�	dâdãdä� e–d Z˜eD ]pZweƒew dÔ Z™e �e™d»¡Zše˜j›e …e™eš¡d\dåe’ew ewd¡›dæe �e™¡dç›�dèdé� e˜jœe �e™¡e’ew dQdêdë� �q¼e˜jœedìd?dídîdï� e˜ �dð¡ e˜ ždñ¡ e˜jŸdòdó� e˜j  ¡edôd>„ ƒ¡ e–d? Z˜e ¢e~d? ¡Z£eD ]zZweƒew dõ Z¤ej�e¤ddd@�Z¥ej�e¤dödd@�Z¦ej�e¤d»dd@�Z§e˜j¨e£e¥e§d÷e’ew dø� e˜j©e£e¦e’ew dQewd¡›dÀ�dù� �q�e˜jªedìdúdídë� e˜ �dû¡ e˜ «dü¡ e˜ ždý¡ e˜jŸdòdó� e˜ ¬dþ¡ e˜j­ ¡edÿd>„ ƒ¡ e–dQ Z˜eD ]fZweƒew dÖ d\ Z®e˜j›e®�d dåe’ew ewd¡›dæe �e®¡�d›dk�dèdé� e˜jœe �e®¡e’ew dQdêdë� �qre˜ ��d¡ e˜ ž�d¡ e˜jŸdòdó� e˜j  ¡e�dd>„ ƒ¡ e
 ¯¡  e
j°e�d�d�d� e�de› �ƒ e�d	ƒ dS (
  ai  
Walk-forward Kelly backtest with Monte Carlo.

For each test season, training uses all prior seasons to:
  1. Identify which outcome (H/D/A) has CLV edge >5% per league
  2. Only bet outcomes that were profitable in training (ROI > 0, min 20 bets)

Test seasons are then compounded sequentially with Kelly staking.
MC runs 10,000 sims on the OOS bet sequence.
é    NZAgg)ÚFuncFormatteré*   i'  g     @�@)gš™™™™™¹?ç      Ð?ç      à?gš™™™™™©?é   g      è?é   r   zE:\soccer\walkforward_kelly.png)Z1920Z2021Z2122Z2223Z2324Z2425Z2526ZEPLZChampionshipz
League Onez
League TwoZ
ConferencezLa LigaZSegundazSerie AzSerie BZ
Bundesligaz2.BundesligazLigue 1zLigue 2Z
EredivisiezBelgian Pro LeaguezPrimeira Ligaz	Super LigzGreek SLzScottish PremzScottish ChampzScottish L1zScottish L2)ZE0ZE1ZE2ZE3ZECZSP1ZSP2ZI1ZI2ZD1ZD2ZF1ZF2ZN1ZB1ZP1ZT1ZG1ZSC0ZSC1ZSC2ZSC3c                 C   s:   d|  d|  d|  }d|  | d| | d| | fS )Né   © )ÚhÚdÚaZoverr	   r	   ú+E:\soccer\misc\archive\walkforward_kelly.pyÚremove_margin.   s    r   zLoading data...zE:/soccer/league_data/Ú_z.csvz	utf-8-sig)Úencodingé
   ÚFTRÚB365A)r   r   ÚB365HÚB365DÚPSCHÚPSCDÚPSCA)ZsubsetÚSeasonZ
LeagueCodeZ
LeagueNameT)Zignore_indexÚDateZcoerce)ZdayfirstÚerrors)Zdropc                 C   s   t | d | d | d ƒS )Nr   r   r   )r   )Úrr	   r	   r   Ú<lambda>I   ó    r   r   )Zaxis)ÚindexÚp_HÚp_DÚp_AZ
PSC_fair_HZ
PSC_fair_DZ
PSC_fair_AÚedge_Ar   Úedge_Hr   Úedge_Dz  ú,z matches across z leaguesé   z>
Walk-forward: train on all prior seasons, test on each seasonzTest seasons: Ú
))ZAwayr#   r   r"   ÚA)ZHomer$   r   r    ÚH)ZDrawr%   r   r!   ÚDc                 C   s"   i | ]\}}|t td  |  “qS )r   )ÚRECENCY_DECAYÚn_train)Ú.0ÚiÚsr	   r	   r   Ú
<dictcomp>r   s   ÿr1   iüÿÿg        g      ð?éÿÿÿÿéd   c                 c   s.   | ]&\}}|d  t kr"|t d ndV  qdS )r   r   r2   N)ÚresultÚodds_col)r.   r   r   r	   r	   r   Ú	<genexpr>Ž   s   ÿr6   )Ú
TestSeasonZTrainSeasonsÚLeagueÚOutcomeÚTrainNÚWeightedROIÚProfitableFracÚSeasonsCheckedZedge_)r   r   r8   r9   ÚOddsÚKellyÚp_winÚWonÚWZWeekz
OOS bets: z  (z to ú)zOverall OOS win rate:   rA   z.1fú%zAvg Pinnacle fair prob: r@   zE:\soccer\walkforward_bets.csvFz-
Training rules selected (last test season = z):r7   r;   )Z	ascendingr8   z<22ú r9   z<8ÚNz>6ZWtdROIz>8zProf%z>7ZSeasonszC  -----------------------------------------------------------------r:   z>7.1fz%  r<   z>6.0fr=   z$
OOS results by season (flat stake):ZBetsz>5zP&LZROIZWRz,  ------------------------------------------r>   z>+8.2fz>+6.2fz>5.1fz
  ZTOTALzB
=================================================================z*DETERMINISTIC KELLY COMPOUNDING (OOS only)zA=================================================================z
Kelly multz<15ÚFinalz>12ÚxZMaxDDz4  --------------------------------------------------r?   r   z.2fzx Kelly    z>12,.2fzx  z>6.1fzMONTE CARLO (z simulations, OOS bets only)iô  )ÚterminalÚmax_ddsÚpathszx Kelly:z    Median:       z>12,.0fzx)z    P10:          z    P25:          é   z    P75:          éK   z    P90:          éZ   z    P(profit):     z    P(> 5x):       z    P(> 10x):      z    P(ruin <50%):  z    Median MaxDD:  z    95th pct DD:   é_   zG
======================================================================ZMetricÚ )Úendzx KellyzF  --------------------------------------------------------------------ZMedianc                 C   s   t  | ¡d›S )Nú>11,.0f)ÚnpÚmedian©Útr	   r	   r   r   *  r   ZP10c                 C   s   t  | d¡d›S )Nr   rR   ©rS   Ú
percentilerU   r	   r	   r   r   +  r   ZP25c                 C   s   t  | d¡d›S )NrL   rR   rW   rU   r	   r	   r   r   ,  r   ZP75c                 C   s   t  | d¡d›S )NrM   rR   rW   rU   r	   r	   r   r   -  r   ZP90c                 C   s   t  | d¡d›S )NrN   rR   rW   rU   r	   r	   r   r   .  r   z	P(profit)c                 C   s   | t k ¡ d d›d�S )Nr3   ú>10.1frD   ©ÚSTARTÚmeanrU   r	   r	   r   r   /  r   zP(> 5x)c                 C   s   | t d k ¡ d d›d�S )Nr   r3   rY   rD   rZ   rU   r	   r	   r   r   0  r   zP(> 10x)c                 C   s   | t d k ¡ d d›d�S )Nr   r3   rY   rD   rZ   rU   r	   r	   r   r   1  r   zP(ruin)c                 C   s   | t d k  ¡ d d›d�S )Nr   r3   rY   rD   rZ   rU   r	   r	   r   r   2  r   rI   z	Med MaxDDrJ   rY   Z	steelblueZseagreenZ
darkorangeé   )é   é   )Zfigsizeu`   Walk-Forward Kelly MC â€” CLV Best Outcome Per League (OOS only)
Train: prior seasons  |  Test: z  |  z OOS bets  |  z simulationsé   Zbold)ÚfontsizeZ
fontweightgÍÌÌÌÌÌÜ?zx Kelly  med=ú,.0fZnone)ZbinsÚalphaÚcolorÚlabelZ	edgecolorz--)rd   Ú	linewidthÚ	linestyleZgrayú:zStart 1,000)rd   rf   rg   re   zTerminal bankrollz3Terminal bankroll distribution
(capped at 95th pct)é   )ra   c                 C   s   | d›S ©Nrb   r	   ©rH   r   r	   r	   r   r   T  r   rK   é2   g¸…ëQ¸¾?)rc   rd   )rd   rf   re   gš™™™™™é?zBet number (OOS)ZBankrollz#Median path (shaded = 5th-95th pct)Úlogc                 C   s   | d›S rj   r	   rk   r	   r	   r   r   e  r   éP   ú.0fzMax drawdown (%)zMax drawdown distributionc                 C   s   | d›d�S )Nro   rD   r	   rk   r	   r	   r   r   p  r   é–   Ztight)ZdpiZbbox_inchesz
Chart saved to zDone.)±Ú__doc__ZpandasZpdZnumpyrS   ÚosZ
matplotlibZuseZmatplotlib.pyplotZpyplotZpltZmatplotlib.tickerr   ZrandomZseedZN_SIMSr[   ZKELLY_MULTSZEDGE_THRESHZMIN_BETSr,   ZMIN_SEASON_BETSZMIN_PROFITABLE_FRACZPLOT_OUTZseasonsZleague_namesr   ÚprintZall_dfsÚitemsÚcodeÚnamer0   ÚpathZread_csvr   ÚlenÚcolumnsZdropnaÚappendÚconcatZdfZto_datetimeZsort_valuesZreset_indexÚzipZapplyZtHZtDZtAÚcopyZSeriesr   ZnuniqueZtest_seasonsZall_oos_betsZtraining_logZoutcomes_cfgZtest_sZtrain_seasonsZisinZtrain_dfZtest_dfZrulesr-   Ú	enumerateZseason_weightsÚuniqueZleagueZbest_weighted_roiZbestZtrre   Zedge_colr5   Zp_colr4   ÚsubZweighted_plZ
weighted_nZiterrowsr   r   ÚgetÚwZplZw_roiZseason_resultsZs_subÚsumZs_plZprofitable_fracÚnZpfracZ	n_seasonsÚjoinÚroundZteÚbÚpÚmaxZkelly_fZ	DataFrameZbets_dfZdtZ	to_periodÚminÚdater\   Zto_csvZtlogZlastÚrowÚintÚemptyÚwhereZprofitsZroiZtotal_profitsZkmZbkZpeakZmax_ddZbetÚfZstakerF   ÚvaluesZoddsr@   ZkellyZ
mc_resultsZN_PLOTZminimumZstakesZzerosrI   rJ   rK   ÚrangeZsimZoutcomesr/   rT   rX   ÚfnZcolorsZ
n_test_yrsZsubplotsZfigZaxesZsuptitleZaxrV   ZcapZhistZaxvlineZ
set_xlabelZ	set_titleZlegendZxaxisZset_major_formatterZarangerH   ZpthsZp5Zp50Zp95Zfill_betweenZplotZaxhlineZ
set_ylabelZ
set_yscaleZyaxisZddZtight_layoutZsavefigr	   r	   r	   r   Ú<module>   sp  


õ&
$
ÿÿÿø"(

ø:
8,ÿÿþ0JN($
6





$

*""""








÷"
,ÿÿþþüÿ 

$



ÿ 