
    ԀiU                        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mZm	Z	 ddl
mZmZmZmZmZ ddlZg dZ G d de      Z G d d	e      Z G d
 de      Z G d de      Z G d d      Zd Zedk(  r e        yy)z
Universal Sports Backtesting Engine
Supports NBA, NFL, MLB, NHL, CFB, CBB, Soccer, MMA, Golf, NASCAR, Tennis

This platform focuses EXCLUSIVELY on sports betting backtesting.
Financial markets (forex, crypto, stocks) are NOT supported.
    N)datetime	timedelta)DictListAnyOptionalCallablenbanflmlbnhlcfbcbbsoccermmagolfnascartennisc                       e Zd ZdZy)BacktestingErrorz%Base exception for backtesting errorsN__name__
__module____qualname____doc__     2/var/www/html/eventheodds/universal_backtesting.pyr   r      s    /r   r   c                       e Zd ZdZy)DataLoadingErrorzError loading game dataNr   r   r   r   r!   r!   !   s    !r   r!   c                       e Zd ZdZy)StrategyExecutionErrorzError executing user strategyNr   r   r   r   r#   r#   &       'r   r#   c                       e Zd ZdZy)InvalidMarketErrorzInvalid or unsupported marketNr   r   r   r   r&   r&   +   r$   r   r&   c                   h   e Zd ZdZdZd Z	 	 	 	 	 dOdededeeef   ded	e	d
edeeef   deeef   de
dedeeef   fdZdefdZd Zd Z	 dPdee   dedee   deeef   fdZdedededefdZdee   defdZdee   dedee   fd Zd! Zd" Zd#ee   dedee   fd$Zd#ee   dedee   fd%Zd#ee   dedee   fd&Zd' Zd#ee   dedee   fd(Zd#ee   dedee   fd)Zd#ee   dedee   fd*Zd#ee   dedee   fd+Zd#ee   dedee   fd,Zd- Z d#ee   dedee   fd.Z!d#ee   dedee   fd/Z"d#ee   dedee   fd0Z#d#ee   dedee   fd1Z$d#ee   dedee   fd2Z%d#ee   dedee   fd3Z&d#ee   dedee   fd4Z'd#ee   dedee   fd5Z(d6ee   dedeeef   fd7Z)d6ee   d8edefd9Z*d6ee   de+jX                  dedeeef   fd:Z-d6ee   deeef   fd;Z.d<eeef   dedefd=Z/d6ee   d>edeeef   fd?Z0d6ee   defd@Z1d#ee   dededeeef   dAeeef   d
edeeef   fdBZ2d#ee   dededeeef   dee   f
dCZ3d6ee   deeef   fdDZ4dEedFedeeef   fdGZ5dHee   deeef   fdIZ6dHee   defdJZ7dKedee   fdLZ8dededeeef   fdMZ9dedeeef   dedefdNZ:y)QUniversalBacktestingEnginez9Universal sports backtesting engine - Sports betting only順 c                    t        j                  d      | _        | j                  j                  t         j                         | j                  j
                  sUt        j                         }t        j                  d      }|j                  |       | j                  j                  |       | j                  d      | j                  d      | j                  d      | j                  d      | j                  d      | j                  d      | j                  d	      | j                  d
      | j                  d      | j                  d      | j                  d      d| _        y )Nr(   z4%(asctime)s - %(name)s - %(levelname)s - %(message)sr   r   r   r   r   r   r   r   r   r   r   r
   )logging	getLoggerloggersetLevelINFOhandlersStreamHandler	FormattersetFormatter
addHandler_get_sports_enginemarket_engines)selfconsole_handler	formatters      r   __init__z#UniversalBacktestingEngine.__init__6   s#   ''(DEW\\* {{##%335O))*`aI((3KK""?3
 **51**51**51**51 **51**51 --h7**51++F3--h7--h7!
r   Nmarketstrategy_name
parametersdata_source
min_trades	timeframewalk_forward_periodsoptimization_configuse_intrabar_ticksstrategy_codereturnc                    | j                   j                  d| d|        g d}|j                         |v rdd| dddd	t        d
S || j                  vr%dd| dddj                  t               t        dS | j                  |   }|dk(  rH| j                   j                  d|        |
sddiS |dk(  r:	 | j                         } |d   |
|      }|d   }|d   }| j                  |||      S d| j                  vr| j                         | j                  d<   |d   }|j                  dd      }| j                   j                  d| d |         |||      }| j                   j                  d!|rt        |      nd d"       |sdd#| d$iS t!        |t"              r$t        |      dkD  rt%        j&                  |      }n1t!        |t$        j&                        r|}nt%        j&                         }	 | j                  d   } |d   ||
|      }| j)                  ||      }d|v r|S | j+                  |||      }d&|||t        |      ||d'd || j-                  ||      | j/                  |      d(| || j1                  |      ||j3                          d)t        |       d*d+d,t        t$        j4                  j7                               d-d.S ||d/   vr%d0| d1| t#        |d/   j9                               d2S 	 |d   } ||j                  dd      |      }|sdd#| d$iS t!        |t"              r$t        |      dkD  rt%        j&                  |      }n1t!        |t$        j&                        r|}nt%        j&                         }|d/   |   } |||      }t        |      |k  rd4t        |       d5| d6t        |      d7S | j)                  ||      }| j;                  ||      }| j1                  |      }d}|r<|dk7  r7dd8lm}  |       } | jA                  ||      }!| jC                  ||||!|||9      }d}"|r,t        |      dkD  r|}#|dk(  rn| jE                  ||||||      }"| j+                  |||      }d|v r(|d   jG                  d:      rg g i d;|t        |      d<d=}d&|||t        |      ||d'd || j-                  ||      | j/                  |      | jI                  |||      ||||j3                          d)t        |       d*|	rd>nd?z   d@d,t        t$        j4                  j7                               d-d.}$|r	d|vr||$dA<   |"r|"|$dB<   |$S # t        $ r-}ddl
}dt        |       |j                         dcY d}~S d}~ww xY w# t        $ r$}d%t        |       t        |      dcY d}~S d}~ww xY w# t        $ r}dd3t        |       icY d}~S d}~ww xY w)Cz,Run a backtest for sports betting strategieszBacktest request: market=z, strategy=)forexcryptostocksstockcryptocurrencyfxFzFinancial market "z" is not supportedFINANCIAL_MARKET_NOT_SUPPORTEDzYThis platform focuses exclusively on sports betting. Financial markets are not supported.zfPlease choose a sports market like NBA, NFL, MLB, NHL, CFB, CBB, Soccer, MMA, Golf, NASCAR, or Tennis.)successerror
error_codemessage
suggestionavailable_marketszUnknown market: INVALID_MARKETzPlease choose from: z, )rN   rO   rP   rR   rS   dynamic_customz(Taking dynamic strategy path for market=rO   z.Dynamic strategy selected but no code providedr   executebetsgamesr   Nz'NBA dynamic strategy execution failed: )rO   detailsdynamicdata_loader	data_filez#Calling data_loader with data_file=, timeframe=zData loader returned z recordszNo data available for z backtesting#Dynamic strategy execution failed: TizDynamic strategy on z OHLC data (z trades)zDynamic strategy executionz4Verified - All results calculated from actual trades)r>   calculation_methodverification_status	timestamp)rN   r;   r<   r=   total_tradesresultstrades
all_tradesperformance_summaryrisk_metricsequation_summarydetailed_statistics	trade_logchart_visualizationverification_data
strategieszUnknown strategy for : )rO   available_strategieszStrategy execution failed: zInsufficient data: Only z trades generated, minimum z	 required)rO   trades_generated)ParameterOptimizer)r;   r<   base_parametersparameter_rangesrB   r\   r@   zVisualization errorzChart visualization unavailable)noter;   trades_count
price_datard   
indicatorssummaryz with intrabar ticks zReal trade-by-trade analysisoptimization_resultswalk_forward_analysis)%r-   infolowerSUPPORTED_SPORTSr6   joindebug_get_nba_dynamic_engine_calculate_nba_backtest_results	Exception	tracebackstr
format_exc_get_dynamic_enginegetlen
isinstancelistpd	DataFrame_calculate_backtest_results"_generate_trade_visualization_data_generate_performance_summary_calculate_risk_metrics_generate_detailed_trade_logupper	Timestampnowkeys_calculate_detailed_statisticsparameter_optimizerrq   _get_default_parameter_rangesoptimize_strategy_run_walk_forward_analysis
startswith_generate_equation_summary)%r7   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   financial_marketsmarket_enginenba_dynamic_engineresultrW   rX   er   r[   data_file_paramdatadata_dfdynamic_enginerd   rc   
chart_datastrategy_funcdetailed_statsrj   r{   rq   	optimizerrs   walk_forward_resultswf_strategy_nameresponses%                                        r   run_backtestz'UniversalBacktestingEngine.run_backtestW   s	    	4VHKWX [<<>.. -fX5GH>v G%5  ,,, +F84. 4TYY?O5P4QR%5  ++F3 ,,KK HQR !QRR )-)E)E)G&:/	:=*UF!&>D"7OE??jRWXX D$7$77595M5M5OD''	2 ,M:",..d"C!!$GGXXdendo"pq"?I>!!$9t#d)QR9SS["\]#'=fX\%RSS dD)c$i!m ll40Gbll3"G llnG%)%8%8%CN6^I6t]JWF ::6:Ng%"N "DDVWV\]
  $$%2",$'K&$STl"(+/+M+MgW]+^$($@$@$H*>vh(G+2!%!B!B6!J+5*0,,.)9c&k]RZ'[.J/e%()9)9);%<	* . -"==0=/J(,]<-H-M-M-O(P I+M:":>>+t#DiP#'=fX\%RSS dD)c$i!m ll40Gbll3"G llnG !.l ;M J&tZ8 v;#3CK=@[\f[ggpq$'K  226:F <<VWM55f=	  $=4D#D>*,I  $AA-QWX#,#>#>+ *!1$7%# $? $   $CIM, 00 '+'F'F&-()($ <<VWfU
j Z%8%C%CDY%Z ! =$$'K		J *$KSTl #'#E#Egv#V 88@ $ ? ?z[a b#1"#-"(,,.!1c&k](S  rDWm  JL   M&D'] !1!1!34	"
0  G3G$G/CH+,  0DH,-A ! $#J3q6(!S#,#7#7#9 B ! #Fs1vh!O#&q6 ~  I#>s1vh!GHHIsa   ;8U$ <V 'W .A6W $	V-"VVV	W
&W?W
W
	W0W+%W0+W0sportc                 D    ddl ddldfd	}fd}|d|idS )zGGeneric sports engine that uses BallDontLie API data for real game datar   Nc                    d}| r5dt        |       v r(	 t        t        |       j                  d      d         }n| r	 t        |       }d}j                  j                  |d d	      }j                  j                  |      r	 t        |d
      5 } j                  |      }ddd       |r$D cg c]  }|j                  d      |k(  s| }}D cg c]:  }|j                  d      s%|j                  di       j                  d      dk(  s9|< }	}|	r?g }
|	D ]  }|j                  di       j                  dd      }|j                  di       j                  dd      }|
j                  |j                  dd      |j                  dd      |j                  dd      ||||z   |j                  di       j                  dd      |j                  di       j                  dd      |j                  di       |j                  d      dd        ddl}ddl}|j"                  j%                  dt'        |
       dj)                          d       |
S |r+g }
|D ]  }|j                  di       j                  dd      }|j                  di       j                  dd      }|
j                  |j                  dd      |j                  dd      |j                  dd      ||||z   |j                  di       j                  dd      |j                  di       j                  dd      |j                  di       |j                  d      dd        ddl}t+        d t'        |
       dj)                          d!       |
S 	 j                  j                  |d#      }j                  j                  |d$      }j                  j                  |      r	 t        |d
      5 } j                  |      }ddd       i }j                  j                  |      rt        |d
      5 } j                  |      }|D ][  }|j                  d%      }|s||vri ||<   |j                  d&d      j/                         }|d'k(  r	|||   d(<   N|d)k(  sT|||   d)<   ] 	 ddd       g }
D ]  }|j                  d*      d+k7  r|j                  d,      s*|j                  d,d      xs d}|j                  d-d      xs d}|dk(  r|dk(  ra|r|j                  d      |k7  rx|j                  d.i       }|j                  d/i       }|j                  d0      }|j                  |i       }i }|rd|j                  d(i       }|j                  d)i       }|r(|j                  d1      |d2<   |j                  d3      |d4<   |r|j                  d5      |d6<   |
j                  |j                  d      xs ddd7 |j                  d8      xs |j                  d9d      |j                  d8      xs |j                  d9d      ||||z   ||kD  rd:n||kD  rd;nd||z
  ||j                  d      dd        |
rCddl}ddl}|j"                  j%                  dt'        |
       dj)                          d<       |
S 	 ddl}t+        d> d?       t1        d@ dA      # t        t        t
        f$ r5}t        j                  d      j                  d|  d|        Y d}~d}~ww xY w# t        t
        f$ r5}t        j                  d      j                  d|  d|        Y d}~"d}~ww xY w# 1 sw Y   xY wc c}w c c}w # t,        $ r}t+        d"|        Y d}~d}~ww xY w# 1 sw Y   xY w# 1 sw Y   xY w# t,        $ r}t+        d=|        Y d}~(d}~ww xY w)Ba$  Load real game data for the specified sport from BallDontLie.
            
            Data sources (in priority order):
            1. betting/{sport}_historical.json - Best for backtesting (deduplicated, with real odds)
            2. {sport}/games.json - Raw BallDontLie games
            N-r   r(   zFailed to parse season from rn   ./databetting_historical.jsonrseasonhasRealOddsoddssourcelivescores	homeScore	awayScoredaterz   homeTeamawayTeamr   winnerdrawmarginballdontlie)r   	home_team	away_team
home_score
away_scoretotalr   r   r   r   r      ✅ Loaded  z& games with REAL odds from BallDontLieu   ⚠️ Loaded z6 games from BallDontLie (some may have estimated odds)z(Error loading BallDontLie betting data: z
games.jsonz	odds.jsongame_idtype2way	moneylinespreadstatusFinalhome_team_scorevisitor_team_scorer   visitor_teamidodds_american_homemoneylineHomeodds_american_visitormoneylineAwayaway_spread
spreadAway
   	full_namenamehomeawayz  games from BallDontLie raw dataz$Error loading BallDontLie raw data: u)   ⚠️ No BallDontLie data available for .zNo game data available for zY. Please ensure BallDontLie data has been fetched using scripts/fetch_balldontlie_data.py)r   intsplit
ValueError
IndexError	TypeErrorr+   r,   warningpathr   existsopenloadr   appendsysstderrwriter   r   printr   r~   r!   )r\   r@   r   r   	data_basebetting_filefr   greal_odds_datarX   r   r   r   bdl_games_filebdl_odds_file	raw_gamesodds_by_game	odds_dataor   	odds_typer   r   	game_oddsr   mlr   jsonosr   s                               r   sports_data_loaderzIUniversalBacktestingEngine._get_sports_engine.<locals>.sports_data_loaderM  s    FSC	N2} Y!5!5c!:1!=>F } ^F !I 77<<	9GW>XYLww~~l+6JlC0 ,A(tyy|, +/Ma155?f3LMM 26%{A}9MQRQVQVW]_aQbQfQfgoQptzQza%{N%{% "!/ A)*x)<)@)@a)PJ)*x)<)@)@a)PJ!LL()fb(9-.UU:r-B-.UU:r-B.8.8)3j)@*+%%"*=*A*A(F*S*+%%"*=*A*A(A*N()fb(9*+%%/*7*   #J

0@0@;sSXzlZ[\a\g\g\i[j  kQ  BR  1S$ "!% A)*x)<)@)@a)PJ)*x)<)@)@a)PJ!LL()fb(9-.UU:r-B-.UU:r-B.8.8)3j)@*+%%"*=*A*A(F*S*+%%"*=*A*A(A*N()fb(9*+%%/*7*   #EN3u:,a  WM  +N  %O$) 2  WW\\)ULINGGLLE;GMww~~n-DFnc2 1a$-DIIaL	1 $&Lww~~m4!-5 L(1		!I%. 	L*+%%	*:#*'.l'B@BW(=01fb0A0G0G0II'0F':MNW(=k(J)2h)>JKW(=h(G	LL E& (55?g5aeeDU>V$%&UU+<a%@%EA
%&UU+?%C%Hq
%?zQ$!aeeHo&?$$%EE+r$:	$%EE."$=	"#%%+$0$4$4Wb$A	!$!*{B!?B%.]]8R%@F!8:?S8T_ 58:?V8W_ 5%5;ZZ5N\ 2%&UU6]%8b#2$>)2{)C)`y}}U[]_G`)2{)C)`y}}U[]_G`*4*4%/*%<0:Z0GfXbeoXofu{&0:&=$(&'eeHo&3& 9(T "J

0@0@;sSXzlZ[\a\g\g\i[j  kK  BL  1M$   I%PQRS"-eW 5j k c #J	: }%%&BCKKNjktjuuwxywzL{||}
 #I. }%%&BCKKNjktjuuwxywzL{||}, ,
  N &|X ! JDQCHIIJ1 1L Lx ! F@DEEFs   &[  \, ^
 ]3'^
 5^ ^ ^
 :^^E^
 D-^
 "_	 .^/1_	 2+^<<^<
^<&H_	  \)4*\$$\),]0;*]++]03]=8^
 
	^,^''^,/^94_	 <__	 		_+_&&_+c                     ddl m}  |       }g }g }j                  j                  t        d      }j                  j                  t        d      }	 j                  j                  |      r't        |d      5 }	 j                  |	      }ddd       j                  j                  |      r't        |d      5 }	 j                  |	      }ddd       |j                  || |||      }
|
S # 1 sw Y   bxY w# 1 sw Y   ,xY w#  Y 3xY w)z+Execute user-generated strategy code safelyr   SafeExecutor
teams.jsonplayers.jsonr   N)	safe_executorr  r   r   r   r   r   r   execute_strategy)r   codeparamsr  executorteamsplayers
teams_fileplayers_filer   rW   r  r  r   s              r   dynamic_strategy_executorzPUniversalBacktestingEngine._get_sports_engine.<locals>.dynamic_strategy_executor  s    2#~H EGiEJ77<<	5.IL77>>*-j#. -! )		!-77>>,/lC0 /A"+$))A,/ ,,T4%PDK- -/ /s<   'D	 =C1/D	 ?C=D	 1C:6D	 =DD	 	DrU   r[   rm   N1hour)r  r  )r7   r   r  r  r  r  s    `  @@r   r5   z-UniversalBacktestingEngine._get_sports_engineH  s/    `	D	6 . ";
 	
r   c           	      p    ddl m dt        t           dt        dt        dt        t           ffd}d|iS )	zDDynamic strategy engine for custom code execution using SafeExecutorr   r  r   r  r  rE   c                 0           }| }g }g }	 |j                  |||||      }t        |t              r|j                  dg       n|}g }	t	        |j                  dd            }
|D ]  }|j                  d      t        fd|D        d      }|s-|j                  dd      }t	        |j                  d	d
            }|j                         dv r|
|d
z
  z  dz  }n|
d
|z
  z  dz  }|	j                  dt        |	       t        |j                  d      xs |j                  dd            d|j                         |dkD  rdndt	        |      t	        |
      || d| d	        |	S # t        $ r}t        dt        |             d}~ww xY w)z
            Execute dynamic strategy code in a sandboxed environment.
            Uses SafeExecutor for security with timeout and memory limits.
            rW   stake  r   c              3   p   K   | ]-  }t        |j                  d             t              k(  s*| / yw)r   N)r   r   ).0r   r   s     r   	<genexpr>zcUniversalBacktestingEngine._get_dynamic_engine.<locals>.execute_dynamic_strategy.<locals>.<genexpr>-  s+      [qSy9I5JcRYl5Z [s   +66N
predictionlong
confidence      ?)r  r   over   dynamic_	game_dater   rz   rU   r   winlossz at confidence )	r   r   strategyactionoutcomeprofitr  r   signalr^   )r  r   dictr   floatnextr~   r   r   r   r   r   )r   r  r  r  rX   r  r  r   rW   rd   r  betgamer  r   r+  r   r   r  s                    @r   execute_dynamic_strategyzPUniversalBacktestingEngine._get_dynamic_engine.<locals>.execute_dynamic_strategy  s   
 $~H EGE(P!224PVW1;FD1Ivzz&"-v fjj$78 C!ggi0G [E []abD%(WW\6%B
%*377<+E%F
 &++-1II%*j3.>%?!%CF%*cJ.>%?!%CF$,S[M":$'(=(U&RTAU$V(8&0&6&6&806
u&+Fm%*5\*4)3OJ<&P
' 
!8  P"Ec!fX NOOPs   BE0 CE0 0	F9FFrV   )r
  r  r   r   r   )r7   r2  r  s     @r   r   z.UniversalBacktestingEngine._get_dynamic_engine  sJ    .5	P4: 5	PS 5	P$ 5	PSWX\S] 5	Pp /
 	
r   c                 V    ddl m dt        dt        dt        t           ffd}d|iS )zLNBA dynamic strategy engine for custom betting strategies using SafeExecutorr   r  r  r  rE   c                    ddl }ddl}        }|j                  dd      }|j                  dd      }t        |t              r%d|v r!t        |j                  d      d         dz   }n"t        |t              rt        |      }n|xs d	}d
}g }	g }
g }|j                  j                  |d| d      }|j                  j                  |      r	 t        |d      5 } |j                  |      }ddd       D ]  }|r|j                  d      |k7  r|j                  di       j                  dd      }|j                  di       j                  dd      }|	j                  |j                  dd      |j                  dd      |j                  dd      ||||z   |j                  di       j                  dd      |j                  di       |j                  d      d	        	 |j                  j                  ||d      }|j                  j                  ||d      }	 |j                  j                  |      r't        |d      5 } |j                  |      }
ddd       |j                  j                  |      r't        |d      5 } |j                  |      }ddd       |	st        d| d| d      t        d t        |	       d|j!                          d!t"        j$                  "       |j'                  | |	||
|      }t        |t(              r|j                  d#g       n|}t        |t*              st        d$      d%g}|D ]$  t-        fd&|D              rt        d'|        ||	d(S # 1 sw Y   xY w# t        $ r}t        d|        Y d}~d}~ww xY w# 1 sw Y   PxY w# 1 sw Y   xY w#  Y #xY w))z
            Execute NBA betting strategy code in a sandboxed environment.
            Uses real game data from BallDontLie and SafeExecutor for security.
            r   Nr   2024r   r   r        r   r   r   r   r   r   r   r   rz   r   r   r   r   r   r   )	r   r   r   r   r   r   r   r   r   z Error loading BallDontLie data: r  r	  z"No BallDontLie data available for r   z.. Run scripts/fetch_balldontlie_data.py first.r   z' games from BallDontLie for backtesting)filerW   z&Strategy output must be a list of betsr   c              3   &   K   | ]  }|v  
 y wNr   )r  fieldr0  s     r   r  zkUniversalBacktestingEngine._get_nba_dynamic_engine.<locals>.execute_nba_dynamic_strategy.<locals>.<genexpr>  s     EE5C<Es   zEach bet must contain: )rW   rX   )r  r  r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r-  r   all)r  r  r  r  r  r   r   
season_intr   rX   r  r  r   r   r   r   r   r   r   r  r  r   rW   required_fieldsr0  r  s                           @r   execute_nba_dynamic_strategyzXUniversalBacktestingEngine._get_nba_dynamic_engine.<locals>.execute_nba_dynamic_strategyS  s   
 #~H ZZ&1FJJw.E &#&3&= c!21!56:
FC( [
#^t
 IEEG 77<<	9GW>XYLww~~l+BlC0 ,A(tyy|, " %!%%/Z*G$%&UU8R%8%<%<[!%L
%&UU8R%8%<%<[!%L
$%EE&"$5)*z2)>)*z2)>*4*4%/*%<&'eeHb&9&=&=h&O$%EE&"$5&'eeHo
& 
( iEJ77<<	5.IL77>>*-j#. -! )		!-77>>,/lC0 /A"+$))A,/
 "DUG1VH  UC  !D  E  EKE
|1U[[]O;bcjmjtjtu ..tUGUFSF-7-E6::fb)6D dD) HII  )kO QE_EE#&=o=N$OPPQ !511q, ,( ! B<QC@AAB- -/ /sm   N M:1C7N $'O N,/O N9 O :N?N 	N)N$$N),N61O 9O>O OrV   )r
  r  r   r   r   )r7   r?  r  s     @r   r   z2UniversalBacktestingEngine._get_nba_dynamic_engineO  s;    .W	2s W	2D W	2T$Z W	2t 3
 	
r   rW   r  
games_datac                 :   |sddddddS |ddl }ddl}|j                  dd      }|j                  dd      }d	t        |      v r t	        |j                  d	      d         d
z   n%t        |      j                         rt	        |      nd}d| d}	|j                  j                  |	      rLt        |	d      5 }
 |j                  |
      }ddd       D cg c]  }|j                  d      |k(  s| }}ng }|D ci c].  }t        |j                  d|j                  dd                  |0 }}d}d}d}|j                  dd      }g }|D ]k  }|d   }|j                  |      }|s| j                  |||      }|j                  |       |d   dk(  r|d
z  }||d   z  }V|d   dk(  s_|d
z  }||d   z  }m t        |      }|dkD  r||z  nd}t        d |D              }t        t        d |D                    }|dkD  r||z  }n|dkD  rt!        d      }nd}|dkD  r||z  nd}|dkD  r||z  nd}| j#                  |      }d||||||||||dd dddt        |      t        |      dkD  r|t        |      z  nddd S # 1 sw Y   xY wc c}w c c}w )!z3Calculate backtest results for NBA betting strategyzNo bets generated by strategyr   )rO   
total_betstotal_profitwin_rateprofit_factorNr   r   r   r5  r   r6  r7  z./data/betting/r   r   r   r   rz   r  d   r*  r&  r+  r'  c              3   8   K   | ]  }|d    dkD  s|d      ywr+  r   Nr   r  bs     r   r  zMUniversalBacktestingEngine._calculate_nba_backtest_results.<locals>.<genexpr>  s     P(a8P   
c              3   8   K   | ]  }|d    dk  s|d      ywrH  r   rI  s     r   r  zMUniversalBacktestingEngine._calculate_nba_backtest_results.<locals>.<genexpr>  s     VqakTUoq{VrK  infTzNBA Dynamic BettingNBA2023-24)strategy_typer;   r   total_games_analyzedbets_per_game)rN   rB  winning_betslosing_betsrD  rC  rE  avg_winavg_lossmax_drawdownrW   ry   )r  r  r   r   r   r   isdigitr   r   r   r   _evaluate_nba_betr   r   sumabsr.  _calculate_max_drawdown)r7   rW   r  r@  r  r  r   r   r=  r   r   r   r   r1  games_lookuprC  rS  rT  r  processed_betsr0  r   
bet_resultrB  rD  
total_winstotal_lossesrE  rU  rV  rW  s                                  r   r   z:UniversalBacktestingEngine._calculate_nba_backtest_results  s    8 !!"  JJw.EZZ&1F:=V:LV\\#.q12Q6adekalatatavRUV\R]  }AJ,UG3CDLww~~l+,, ($499Q<D()-OAxJ1NaO
O
 XbbtDHHYr0BCDdJbb 

7C( 	5C)nG##G,D//T5AJ!!*-)$-!
8 44I&&0q 
8 44	5" (
0:Q<*,A PnPP
3VNVVW!&5M!^!%LMM 0<a/?*|+Q1<q<+-a33NC $(& (* ("4C(!6#(+JADZSTATc*o!=Z[
 	
k( (O
 cs   9JJ2J?3JJr0  r1  r  c                 J   |d   j                         }|d   }|j                  dd      }|j                  dd      }|j                  dd      }d}	d	}
|d
k(  r:|j                         dk(  r	||kD  rd}	nB|j                         dk(  r.||kD  r(d}	n$|dk(  r|j                  d      }|I|j                  di       }|j                         dk(  r|j                  dd      n|j                  dd      }|rt        |      nd}|j                         dk(  r	||z   |kD  }	n|j                         dk(  r|r| nd}||z   |kD  }	nu|dk(  s|dk(  ri||z   }|j                  d|j                  di       j                  dd            }|j                         dk(  r||kD  }	n|j                         dk(  r||k  }	nd}	|	r||
dz
  z  }d}n| }d}d|d    |d   |j                  dd      |||j                  d d!       d"| d#| d"|j                  d$d%       |t        |d&      ||||d'S )(z"Evaluate the outcome of an NBA betbet_typer  r   r!  r   r   r   Fg(\?r   r   Tr   r   r   
spreadHomer   
over_underr   line	totalLine   r"  underr6  r&  r'  nba_bet_r   r   rz   r   Homer   r   r   Awayr#  )r   r   r   rc  r  game_resultr*  r+  r  r   r   r   )r~   r   r.  round)r7   r0  r1  r  rc  r  r   r   r   wonpayout_multiplierr   r   spread_awaytotal_pointsrf  r+  r*  s                     r   rY  z,UniversalBacktestingEngine._evaluate_nba_bet  s    z?((*&
WW\3/
 XXlA.
XXlA.
 {"!V+
Z0G!!#v-*z2I!WWX&F~xx+6@6F6F6HF6R,2X\X`X`amopXq&,U6]!F!V+!F*j8!!#v-)/vgQ!K/:=%W)<%
2L776488FB#7#;#;K#MND!V+"T)!!#w."T) C /!34FGVFG S^,-9~HHVR( $"hh{F;<Aj\:,VWX\X`X`alntXuWvwFA&$$$
 	
r   c                 ^    |syd}d}d}|D ]  }||d   z  }||kD  r|}||z
  }||kD  s|}  |S )z/Calculate maximum drawdown from betting resultsr   r+  r   )r7   rW   cumulative_profitpeakrW  r0  drawdowns          r   r\  z2UniversalBacktestingEngine._calculate_max_drawdownZ  sc     	(CX. 4'(//H,&'	( r   rX   time_periodc                    ddl m } |s|S g }|D ]  }|j                  dd      }|s	  |j                  |j                  dd            }|j                  d      }|dk(  r_|j                  d	      }	|j                  d
      }
|	rQ|
rN ||	dd      } ||
dd      }||cxk  r|k  r.n n*|j	                  |       n|dk(  rP|j                  d	      }	|j                  d
      }
|	r|
r|	|j
                  cxk  r|
k  rn n|j	                  |       n|dk(  r4|j                  d      }|r|j
                  |k(  r|j	                  |       n|dk(  r|j                  dd      j                         }|j                  d      }ddddddddddddd}|j                  |      }|r1|r/|j
                  |k(  r |j                  |k(  r|j	                  |        |S # t        $ r}Y d}~d}~ww xY w)z)Filter NBA games by specified time periodr   )r   r%  rz   Zz+00:00r   r   
start_yearend_yearr   r6        
year_rangeyear
month_yearmonthr#                 	         )januaryfebruarymarchaprilmayjunejulyaugust	septemberoctobernovemberdecemberN)	r   r   fromisoformatreplacer   r  r~   r  r   )r7   rX   rw  r   filtered_gamesr1  game_date_strr%  period_typerz  r{  season_start
season_endr  
month_name	month_maptarget_monthr   s                     r   _filter_games_by_time_periodz7UniversalBacktestingEngine._filter_games_by_time_periodm  s   %L 4	D HH["5M /2H22=3H3Hh3WX	)oof5(*!,!>J*z:H!h'/
B'B%-h2%>
'9B
B*11$7 L0!,!>J*z:H!h%C8C*11$7 F*&??62D	$ 6&--d3 L0!,"!=!C!C!EJ&??62D $%!a! !Q!%&22SU!I $-==#<L#41GIOO_kLk&--d3a4	l 	  s   F.G	G0+G0c                 H    ddl m}  |       dfd	}|j                  dS )zNBA market enginer   )NBABacktestingEnginec                 &    j                  d      S )NrO  )_get_games_data)r\   r@   
nba_engines     r   nba_data_loaderzCUniversalBacktestingEngine._get_nba_engine.<locals>.nba_data_loader  s    --i88r   r  r  )nba_backtestingr  ro   )r7   r  r  r  s      @r   _get_nba_enginez*UniversalBacktestingEngine._get_nba_engine  s+    8)+
	9
 +$99
 	
r   c                     dd}d }|| j                   | j                  | j                  | j                  | j                  ddS )zForex market enginec                 r	   t        d|  d|        t        dt        j                                 | r=t        j                  j	                  |       s| j                         }d| d| d}t        d| dt        j                  j	                  |              t        j                  j	                  |      rI	 t        j                  |      }d	d
l}t        d| d| dt        |       d       |j                  d      S d| d}t        j                  j	                  |      rI	 t        j                  |      }d	d
l}t        d| d| dt        |       d       |j                  d      S | rt        j                  j	                  |       r| j                  dd| d      }t        j                  j	                  |      rF	 t        j                  |      }d	d
l}t        d| dt        |       d       |j                  d      S 	 t        j                  |       }d	d
l}t        d|  dt        |       d       |j                  d      S d	d
l}	d| d}
|	j                  |
      }|D cg c]  t        fddD              s }}|rL	 t        j                  |d	         }d	d
l}t        d|d	    dt        |       d       |j                  d      S d	d
l}t        d| d       g d }g }t        j                          t#        d!"      z
  }t%        d!      D ]  }|t#        |"      z   }|D ]  }d#d$d%d&d'd |   }t&        j(                  j+                  d	d(      }|d)|z   z  }|d)t&        j(                  j+                  d	d*      z   z  }|j-                  |j/                  d+      |t1        |d,      t1        |d,      t3        t(        j5                  d-d.            d/         |S # t        $ r}t        d| d|        Y d
}~d
}~ww xY w# t        $ r}t        d| d|        Y d
}~d
}~ww xY w# t        $ r}t        d|        Y d
}~Sd
}~ww xY w# t        $ r}t        d|        Y d
}~2d
}~ww xY wc c}w # t        $ r}t        d|        Y d
}~d
}~ww xY w)0z*Load forex CSV data with timeframe supportz/DEBUG: forex_data_loader called with data_file=r]   z"DEBUG: Current working directory: 	data/csv/_	_ohlc.csvzDEBUG: Looking for OHLC file: z
, exists: r   Nu    📊 Loaded forex OHLC data for rn    ( bars)recordsz"Error loading OHLC forex data for .csvu   📊 Loaded raw forex data for  rows)z!Error loading raw forex data for u   📊 Loaded forex OHLC data: zError loading OHLC forex data: u   📊 Loaded raw forex data: zError loading forex data: 
data/csv/*c              3   B   K   | ]  }|j                         v   y wr:  r~   r  termr   s     r   r  zZUniversalBacktestingEngine._get_forex_engine.<locals>.forex_data_loader.<locals>.<genexpr>  s"       9^t9J  9^   )rG   xauusdeurusdgbpusdusdjpyaudusdusdcadu   📊 Auto-loaded forex data: z(Error loading auto-detected forex data: u&   📊 Generating sample forex data for 
 timeframeEURUSDGBPUSDUSDJPYAUDUSDUSDCADm  daysHzG?RQ?     b@q=
ףp?皙?{Gzt?r6  Mb`?%Y-%m-%dr  '  r)   )r   pairr   closevolume)r   r  getcwdr   r   r   r   read_csvr   r   to_dictr   r  globanyr   r   r   rangenprandomnormalr   strftimern  r   randint)r\   r@   include_intrabar_tickssymbol	ohlc_filedfr   r   raw_filer  forex_patternforex_filesr   pairsr   	base_dateicurrent_dater  
base_priceprice_change
open_priceclose_prices               `          r   forex_data_loaderzGUniversalBacktestingEngine._get_forex_engine.<locals>.forex_data_loader  s   CI;l[dZefg6ryy{mDE 	!:"*'xq9E	6ykBGGNN[dLeKfgh77>>),R[[3"E,LVHTVW`Vaacdghjdkcllr*s$t!zz)44
 'vhd377>>(+Q[[2"E,KF8SUV^U__abefhbiajjp*q$r!zz)44
 RWW^^I6%--f)I6NO	77>>),E[[3"E,I)TVWZ[]W^V__e*f$g!zz)44
<Y/B(DYKrRUVXRYQZZ`&a b::i00
 (9=M))M2K&1  _S  9^  X]  9^  6^1  _K  _J[^4B(EkRSnEUUWX[\^X_W``f&g h::i00
  FykQ[\]FED )<<I3Z (9!+<<! D"&$%"&$" "J $&99#3#3Au#=L!+q</?!@J",BII4D4DQ4N0N"OKKK , 5 5j A4 %j! 4u[RS?T"%fnnUF&C"D!  KE % R B6("QCPQQR % Q A&A3OPPQ % E ?sCDDE ! <6qc:;;< _ ! JDQCHIIJs   =AO5 +AP 
AQ AQ* 5RRA
R 5	P>PP	Q&P==Q	Q'Q""Q'*	R3RR	R6R11R6c                     g d} g }t        j                         t        d      z
  }t        d      D ]O  }|t        |      z   }| D ]7  }dddddd|   }t        j
                  j                  d	d
      }|d|z   z  }|dt        j
                  j                  d	d      z   z  }	|j                  |j                  d      |t        |d      t        t        ||	      dt        t        j
                  j                  d	d            z   z  d      t        t        ||	      dt        t        j
                  j                  d	d            z
  z  d      t        |	d      t        t
        j                  dd            d       : R |S )z&Generate sample forex data for testingr  r  r  r  r  r  r  r  r   r  r6  r  r  r  gMbP?r  r)   )r   r  r   highlowr  r  r   r   r   r  r  r  r  r   r  rn  maxr[  minr   r  )
r  r   r  r  r  r  r  r  r  r  s
             r   !_generate_sample_forex_data_localzWUniversalBacktestingEngine._get_forex_engine.<locals>._generate_sample_forex_data_local  ss   FED )<<I3Z (9!+<<! D #'"&"'"&"&" "J $&99#3#3Au#=L!+q</?!@J",BII4D4DQ4N0N"OKKK , 5 5j A $ %j! 4 %c*k&Ba#biiN^N^_`bgNhJiFi&jlm n$S[%AQRYYM]M]^_afMgIhEh%iklm!&{A!6"%fnnUF&C"D! 6 Kr   )trend_followingrange_tradingbreakout_tradingcarry_trademean_reversionr  )Nr  F)_forex_trend_following_forex_range_trading_forex_breakout_trading_forex_carry_trade_forex_mean_reversion)r7   r  r  s      r   _get_forex_enginez,UniversalBacktestingEngine._get_forex_engine  sP    S	j!	H -#'#>#>!%!:!:$($@$@#66"&"<"<	
 		
r   r   c                    g }|j                  dd      }|j                  dd      }|D cg c]  }|j                  d      |k(  s| }}t        dt        |            D ]  }||dz
  | }	t        d |	D              }
t	        d |	D              }||   d   }||   d	   }||
kD  rJ|||   d
   kD  rdnd}|j                  dt        |       ||   d   d|d|
||dk(  r|n| |d|
dd
       ||   d   |k  s|||   d
   k  rdnd}|j                  dt        |       ||   d   d|d|||dk(  r|n| |d|dd
        |S c c}w )zForex breakout trading strategyr  r  r  r     c              3   &   K   | ]	  }|d      ywr  Nr   r  ds     r   r  zEUniversalBacktestingEngine._forex_breakout_trading.<locals>.<genexpr>O  s     8Aai8   c              3   &   K   | ]	  }|d      ywr  Nr   r  s     r   r  zEUniversalBacktestingEngine._forex_breakout_trading.<locals>.<genexpr>P  s     6!QuX6r  r  r  r   r&  r'  forex_breakout_r   r  BUYzBreakout above .5f)
r   r   r(  r  r)  breakout_levelr*  r+  r  r,  r  SELLzBreakout below )r   r  r   r  r  r   )r7   r   r  rd   r  r  r  	pair_datar  windowrecent_high
recent_lowcurrent_highcurrent_closer*  s                  r   r  z2UniversalBacktestingEngine._forex_breakout_tradingC  s   zz&(+

7D) $>1f(=Q>	>r3y>* (	AqtA&F 888K6v66J$Q</L%aL1M k)#09Q<3G#G%V+CK=9%aL0 2 #&1&'.%'7eeV" /C/@A  1e$z1#09Q<3G#G%V+CK=9%aL0 2 $&0&'.%'7eeV" /
3/?@ ;(	T Y ?s   EEc                     g }|j                  dd      }ddg}|D ]Z  }|d   |v st        j                         dkD  rdnd}|j                  d	t        |       |d
   d|d   d||dk(  r|n| |dd	       \ |S )zForex carry trade strategyr  r  r  NZDUSDr  皙?r&  r'  forex_carry_r   r  r  z&Carry trade - long high yield currency)	r   r   r(  r  r)  r*  r+  r  r,  )r   r  r   r   )r7   r   r  rd   r  high_yield_pairsr  r*  s           r   r  z-UniversalBacktestingEngine._forex_carry_tradew  s    

7D) %h/ 	I $44#)==?S#8%f(V6%f- -%f-#&'.%'7eeV"F
 
		  r   c                 N   g }|j                  dd      }|j                  dd      }|j                  dd      }|D cg c]  }|j                  d      |k(  s| }}t        dt        |            D ]%  }	||	dz
  |	 }
|
D cg c]  }|d   	 }}t        j                  |      }t        j
                  |      }||	   d   }|d	kD  r||z
  |z  nd	}|| k  r^||kD  rd
nd}|j                  dt        |       ||	   d   d|dt        |d      t        |d      ||d
k(  r|n| |d|dd|ddd       ||kD  s||k  rd
nd}|j                  dt        |       ||	   d   d|dt        |d      t        |d      ||d
k(  r|n| |d|dd|ddd       ( |S c c}w c c}w )zForex mean reversion strategyr  r  r  r  deviation_thresholdg       @r  r  r   r&  r'  forex_reversion_r   r  r  r#  r  zMean reversion buy at r  z (Z: .2f))r   r   r(  r  r)  z_score
mean_pricer*  r+  r  r,  r  zMean reversion sell at r   r  r   r  meanstdr   rn  )r7   r   r  rd   r  r  r  r  r  r  r  pricesr!  	std_pricecurrent_pricer   r*  s                    r   r   z0UniversalBacktestingEngine._forex_mean_reversion  s   zz&(+

7D)$jj)>D $>1f(=Q>	>r3y>* +	AqtA&F*01Qaj1F1 JvI%aL1MBKa-}z1Y>UVG ---#0:#=%6,S[M:%aL0 0 #$Wa0"'
A"6&'.%'7eeV" 6}S6IwWZm[\]  ..#0:#=%6,S[M:%aL0 0 $$Wa0"'
A"6&'.%'7eeV" 7c7J%PWX[}\]^ ?+	Z _ ? 2s   FFF"c                     dd}d }|| j                   | j                  | j                  | j                  | j                  | j
                  ddS )zCrypto market enginec                    | rt         j                  j                  |       s| j                         }d| d| d}t         j                  j                  |      rI	 t	        j
                  |      }ddl}t        d| d| dt        |       d	       |j                  d
      S d| d}t         j                  j                  |      rI	 t	        j
                  |      }ddl}t        d| d| dt        |       d       |j                  d
      S | rt         j                  j                  |       r| j                  dd| d      }t         j                  j                  |      rF	 t	        j
                  |      }ddl}t        d| dt        |       d	       |j                  d
      S 	 t	        j
                  |       }ddl}t        d|  dt        |       d       |j                  d
      S ddl}d| d}	|j                  |	      }
|
D cg c]  t        fddD              s }
}|
rL	 t	        j
                  |
d         }ddl}t        d|
d    dt        |       d	       |j                  d
      S ddl}t        d| d       g d}g }t        j                         t!        d      z
  }t#        d      D ]  }|t!        |      z   }|D ]  }ddd d!d"d|   }t$        j&                  j)                  dd#      }|d$|z   z  }|d$t$        j&                  j)                  dd%      z   z  }|j+                  |j-                  d&      |t/        |d'      t/        |d'      t1        t&        j3                  d(d)            d*         |S # t        $ r}t        d| d|        Y d}~d}~ww xY w# t        $ r}t        d| d|        Y d}~d}~ww xY w# t        $ r}t        d|        Y d}~Sd}~ww xY w# t        $ r}t        d|        Y d}~2d}~ww xY wc c}w # t        $ r}t        d|        Y d}~d}~ww xY w)+z+Load crypto CSV data with timeframe supportr  r  r  r   Nu!   📊 Loaded crypto OHLC data for rn   r  r  r  z#Error loading OHLC crypto data for r  u    📊 Loaded raw crypto data for r  z"Error loading raw crypto data for u   📊 Loaded crypto OHLC data: z Error loading OHLC crypto data: u   📊 Loaded raw crypto data: zError loading crypto data: r  c              3   B   K   | ]  }|j                         v   y wr:  r  r  s     r   r  z\UniversalBacktestingEngine._get_crypto_engine.<locals>.crypto_data_loader.<locals>.<genexpr>  s#       ;RQU41779;L  ;Rr  )rH   btcusdethadasoldotbtcu   📊 Auto-loaded crypto data: z)Error loading auto-detected crypto data: u'   📊 Generating sample crypto data for r  BTCETHADASOLDOTr  r  ȯ  
  ?_   @Q?r6  {Gz?r  r#  @B 逖 r   r  r   r  r  )r  r   r   r   r   r  r   r   r   r  r   r  r  r  r   r   r   r  r  r  r  r   r  rn  r   r  )r\   r@   r  r  r  r   r   r  r  crypto_patterncrypto_filesr   cryptosr   r  r  r  rH   r  r  r  r  s              `          r   crypto_data_loaderzIUniversalBacktestingEngine._get_crypto_engine.<locals>.crypto_data_loader  sb    	!:"*'xq9E	77>>),S[[3"E,MfXUWXaWbbdehikeldmms*t$u!zz)44
 'vhd377>>(+R[[2"E,LVHTVW_V``bcfgicjbkkq*r$s!zz)44
 RWW^^I6%--f)I6NO	77>>),F[[3"E,J9+UWX[\^X_W``f*g$h!zz)44
=Y/B(Ei[PRSVWYSZR[[a&b c::i00
 ))I>N99^4L'3  S!s  ;R  ZQ  ;R  8RA  SL  SK\!_5B(F|TUFWWYZ]^`ZaYbbh&i j::i00
  G	{R\]^9GD )<<I3Z (9!+<<% 	F).tDQS\`!abh!iJ#%99#3#3At#<L!+q</?!@J",BII4D4DQ4M0M"NKKK , 5 5j AV %j! 4u[RS?T"%fnnWh&G"H! 	 K % S CF82aSQRRS % R B6("QCPQQR % F @DEEF ! =7s;<<= S ! KEaSIJJKs   AN AN= *AO% 0AP
 P//P/8A
P4 	N:N55N:=	O"OO"%	P.PP
	P,P''P,4	Q=QQc                     g d} g }t        j                         t        d      z
  }t        d      D ]O  }|t        |      z   }| D ]7  }dddddd|   }t        j
                  j                  d	d
      }|d|z   z  }|dt        j
                  j                  d	d      z   z  }	|j                  |j                  d      |t        |d      t        t        ||	      dt        t        j
                  j                  d	d            z   z  d      t        t        ||	      dt        t        j
                  j                  d	d            z
  z  d      t        |	d      t        t
        j                  dd            d       : R |S )z'Generate sample crypto data for testingr1  r  r  r7  r8  r9  r:  r;  r   r<  r6  r=  r  r#  r>  r?  )r   r  r   r  r  r  r  r  )
rC  r   r  r  r  rH   r  r  r  r  s
             r   "_generate_sample_crypto_data_localzYUniversalBacktestingEngine._get_crypto_engine.<locals>._generate_sample_crypto_data_local  ss   9GD )<<I3Z (9!+<<% F  %##!#" "J $&99#3#3At#<L!+q</?!@J",BII4D4DQ4M0M"NKKK , 5 5j A"( %j! 4 %c*k&Ba#biiN^N^_`bfNgJhFh&ikl m$S[%AQRYYM]M]^_aeMfIgEg%hjkl!&{A!6"%fnnWh&G"H! 6 Kr   )momentum_tradingr  r  volume_analysisrsi_divergencer  r  r  )_crypto_momentum_trading_crypto_mean_reversion_crypto_breakout_trading_crypto_volume_analysis_crypto_rsi_divergence_crypto_trend_following)r7   rD  rF  s      r   _get_crypto_enginez-UniversalBacktestingEngine._get_crypto_engine  sY    L	\!	H .$($A$A"&"="=$($A$A#'#?#?"&"="=#'#?#?

 
	
r   c                    g }|j                  dd      }|j                  dd      }|D cg c]  }|j                  d      |k(  s| }}t        dt        |            D ]e  }t        j                  ||dz
  | D cg c]  }|d   	 c}      }	t        j                  ||dz
  | D cg c]  }|d   	 c}      }
||   d   }|	|
kD  r{||dz
     d   ||dz
     d	   k  rd|||   d	   kD  rd
nd}|j                  dt        |       ||   d   d|dt        |	d      t        |
d      ||d
k(  r|n| |d|	dd|
ddd       |	|
k  s||dz
     d   ||dz
     d	   k\  s|||   d	   k  rd
nd}|j                  dt        |       ||   d   d|dt        |	d      t        |
d      ||d
k(  r|n| |d|	dd|
ddd       h |S c c}w c c}w c c}w )z5Crypto trend following strategy - simple MA crossoverr  r2  r  r  r   r  r  r6  r   r&  r'  crypto_trend_r   r  r  r#  MA crossover buy ($r   > $r  r   r   r(  r  r)  short_malong_mar*  r+  r  r,  r  MA crossover sell ($ < $r   r  r   r  r#  r   rn  )r7   r   r  rd   r  r  r  symbol_datar  rV  rW  r'  r*  s                r   rO  z2UniversalBacktestingEngine._crypto_trend_followingI  sN   He,

7D)"&DQ!%%/V*CqDDr3{+, '	AwwK!A4FGq'
GHHgg;qtA3FGaqzGHG'N73M '!k!A#&6w&?;qQRsCSTZC[&[#0;q>&3I#I%v)#f+7'N62 1$# %h 2$Wa0&'.%'7eeV" 3HS>gc]RST  G#AaC(8(A[QRSTQTEUV\E](]#0;q>&3I#I%v)#f+7'N62 1$$ %h 2$Wa0&'.%'7eeV" 4XcN$wsmSTU 7'	R W E  HGs   GG=G
)G
c                 
   g }|j                  dd      }|j                  dd      }|D cg c]  }|j                  d      |k(  s| }}t        dt        |            D ]  }||dz
  | }	|	D cg c]  }|d   	 }
}t        j                  |
      }t        j
                  |
      }||   d   }|dkD  r||z
  |z  nd}t        |      dkD  sn|d	k  rO||kD  rd
nd}|j                  dt        |       ||   d   d|dt        |d      ||d
k(  r|n| |d|ddd
       |dkD  s||k  rd
nd}|j                  dt        |       ||   d   d|dt        |d      ||d
k(  r|n| |d|ddd
        |S c c}w c c}w )zCrypto mean reversion strategyr  r2  r  r     r  r   r#  r&  r'  crypto_reversion_r   r  r  zMean reversion buy (Z: r  r  
r   r   r(  r  r)  r   r*  r+  r  r,  r  zMean reversion sell (Z: )	r   r  r   r  r#  r$  r[  r   rn  r7   r   r  rd   r  r  r  r[  r  r  r%  r!  r&  r'  r   r*  s                   r   rK  z1UniversalBacktestingEngine._crypto_mean_reversion|  s   He,

7D)"&DQ!%%/V*CqDDr3{+, &	A 2a(F*01Qaj1F1JvI'N73MBKa-}z1Y>UVG7|aR<'4z'AevGMM 1#f+? +Av 6$4"("'#(!#4#*+2e+;%%!&$;GC="J#  q['4z'AevGMM 1#f+? +Av 6$4"("(#(!#4#*+2e+;%%!&$<WSM"K# 7&	P U E 2s   E;E;0F c                    g }|j                  dd      }|j                  dd      }|D cg c]  }|j                  d      |k(  s| }}t        dt        |            D ]  }||dz
  | }	t        d |	D              }
t	        d |	D              }|
|z
  }||   d   }||   d	   }||
|d
z  z   kD  rVt
        j                         dkD  rdnd}|j                  dt        |       ||   d   d|d|
||dk(  r|n| |d|
dd
       |||d
z  z
  k  st
        j                         dkD  rdnd}|j                  dt        |       ||   d   d|d|||dk(  r|n| |d|dd
       	 |S c c}w )z Crypto breakout trading strategyr  r2  r  r  r  c              3   &   K   | ]	  }|d      ywr  r   r  s     r   r  zFUniversalBacktestingEngine._crypto_breakout_trading.<locals>.<genexpr>  s     71QvY7r  c              3   &   K   | ]	  }|d      ywr
  r   r  s     r   r  zFUniversalBacktestingEngine._crypto_breakout_trading.<locals>.<genexpr>  s     5AeH5r  r  r  皙?r  r&  r'  crypto_breakout_r   r  r  zBreakout above $r  )
r   r   r(  r  r)  r  r*  r+  r  r,  r  zBreakout below $)r   r  r   r  r  r  r   )r7   r   r  rd   r  r  r  r[  r  r  
high_range	low_range
range_sizer  current_lowr*  s                   r   rL  z3UniversalBacktestingEngine._crypto_breakout_trading  s   He,

7D)"&DQ!%%/V*CqDDr3{+, '	A 2a(F 777J5f55I#i/J&q>&1L%a./K jJ,<==#)==?S#8%f,S[M:'N62 2$#&0&'.%'7eeV" 0C0@A  yJ,<==#)==?S#8%f,S[M:'N62 2$$&/&'.%'7eeV" 03@ 9'	R W Es   E,E,c                 t   g }|j                  dd      }|j                  dd      }|D cg c]  }|j                  d      |k(  s| }}t        dt        |            D ]J  }||dz
  | }	t        j                  |	D cg c]  }|d   	 c}      }
||   d   }||
dz  kD  sC||   d   ||   d	   z
  ||   d	   z  }|d
kD  rrt
        j                         dkD  rdnd}|j                  dt        |       ||   d   d|dt        ||
z  d      t        |d      ||dk(  r|n| |d| d|
ddd       |dk  st
        j                         dkD  rdnd}|j                  dt        |       ||   d   d|dt        ||
z  d      t        |d      ||dk(  r|n| |d| d|
ddd       M |S c c}w c c}w )zCrypto volume analysis strategyr  r2  r  r  r   r        ?r  r   r=  r9  r&  r'  crypto_volume_r   rH  r  r#  r  zHigh volume buy ( vs avg z.0fr  )r   r   r(  r  r)  volume_ratior  r*  r+  r  r,  {Gzr  zHigh volume sell (r   r  r   r  r#  r  r   rn  r7   r   r  rd   r  r  r  r[  r  r  
avg_volumecurrent_volumer  r*  s                 r   rM  z2UniversalBacktestingEngine._crypto_volume_analysis  s   He,

7D)"&DQ!%%/V*CqDDr3{+, &	A 2a(Fv!>!!H+!>?J(^H5N 
S 00 +Aw 7+a.:P PT_`aTbciTjj$&'-}}'=e6GMM .s6{m< +Av 6$5"("'(-nz.I1(M(-lA(>#*+2e+;%%!&$5n5EXjY\M]]^"_#  "E)'-}}'=e6GMM .s6{m< +Av 6$5"("((-nz.I1(M(-lA(>#*+2e+;%%!&$6~6FhzZ]N^^_"`# 5&	P U E "?s   F0F0?F5
c                 X   g }|j                  dd      }|j                  dd      }|D cg c]  }|j                  d      |k(  s| }}t        dt        |            D ]  }||dz
  | }	|	D cg c]  }|d   	 }
}g }g }t        dt        |
            D ]c  }|
|   |
|dz
     z
  }|dkD  r#|j                  |       |j                  d       9|j                  d       |j                  t	        |             e |rt        j                  |      nd}|rt        j                  |      nd}|dkD  r||z  }d	d	d|z   z  z
  }nd	}||   d   }|d
k  rbt        j                         dkD  rdnd}|j                  dt        |       ||   d   d|dt        |d      ||dk(  r|n| |d|ddd
       V|dkD  s]t        j                         dkD  rdnd}|j                  dt        |       ||   d   d|dt        |d      ||dk(  r|n| |d|ddd
        |S c c}w c c}w )zCrypto RSI divergence strategyr  r2  r  r  r]  r  r6  r   rF  r}  r  r&  r'  crypto_rsi_r   rI  r  r#  zRSI oversold (.1fr  )
r   r   r(  r  r)  rsir*  r+  r  r,  F   r  zRSI overbought ()	r   r  r   r   r[  r  r#  r  rn  )r7   r   r  rd   r  r  r  r[  r  r  r%  gainslossesjchangeavg_gainrV  rsrx  r'  r*  s                        r   rN  z1UniversalBacktestingEngine._crypto_rsi_divergence  sh   He,

7D)"&DQ!%%/V*CqDDr3{+, 8	A 2a(F +11Qaj1F1EF1c&k* /VAaC[0A:LL(MM!$LLOMM#f+./ */rwwu~AH*0rwwvaH!|(SAF^,'N73M Rx#)==?S#8%f'F}5'N62 0$# a=&'.%'7eeV" .s3iq9  r#)==?S#8%f'F}5'N62 0$$ a=&'.%'7eeV" 0S	; [8	t y E 2s   H"H"0H'c                     dd}d }|| j                   | j                  | j                  | j                  | j                  ddS )zStocks market enginec                   	 | rt         j                  j                  |       r| j                  dd| d      }t         j                  j                  |      rF	 t	        j
                  |      }ddl}t        d| dt        |       d       |j                  d	      S 	 t	        j
                  |       }ddl}t        d|  dt        |       d       |j                  d	      S ddl}d| d}|j                  |      }|D 		cg c]  	t        	fddD              s	 }}	|rL	 t	        j
                  |d         }ddl}t        d|d    dt        |       d       |j                  d	      S ddl}t        d| d       g d}
g }t        j                         t        d      z
  }t!        d      D ]  }|t        |      z   }|
D ]  }dddddd|   }t"        j$                  j'                  dd      }|d|z   z  }|dt"        j$                  j'                  dd      z   z  }|j)                  |j+                  d       |t-        |d!      t-        |d!      t/        t$        j1                  d"d#            d$         |S # t        $ r}t        d
|        Y d}~d}~ww xY w# t        $ r}t        d|        Y d}~d}~ww xY wc c}	w # t        $ r}t        d|        Y d}~~d}~ww xY w)%z+Load stocks CSV data with timeframe supportr  r  r  r   Nu   📊 Loaded stocks OHLC data: r  r  r  z Error loading OHLC stocks data: u   📊 Loaded raw stocks data: r  zError loading stocks data: r  c              3   B   K   | ]  }|j                         v   y wr:  r  r  s     r   r  z\UniversalBacktestingEngine._get_stocks_engine.<locals>.stocks_data_loader.<locals>.<genexpr>s  s#       ;MQU41779;L  ;Mr  )rJ   aaplgooglmsfttslanvdau   📊 Auto-loaded stocks data: z)Error loading auto-detected stocks data: u'   📊 Generating sample stocks data for r  AAPLGOOGLMSFTTSLANVDAr  r        |       r=  r6  Q?r  r#  r?   r@  )r  r   r   r  r   r  r   r   r   r  r   r  r  r   r   r   r  r  r  r  r   r  rn  r   r  )r\   r@   r  r  r   r   r  stocks_patternstocks_filesr   rI   r   r  r  r  rJ   r  r  r  r  s            `          r   stocks_data_loaderzIUniversalBacktestingEngine._get_stocks_engine.<locals>.stocks_data_loaderZ  s    RWW^^I6%--f)I6NO	77>>),F[[3"E,J9+UWX[\^X_W``f*g$h!zz)44
=Y/B(Ei[PRSVWYSZR[[a&b c::i00
 ))I>N99^4L'3  N!s  ;M  ZL  ;M  8MA  NL  NK\!_5B(F|TUFWWYZ]^`ZaYbbh&i j::i00
  G	{R\]^>FD )<<I3Z (9!+<<# 	E*-SRU_b!cdi!jJ#%99#3#3At#<L!+q</?!@J",BII4D4DQ4N0N"OKKK , 5 5j AU %j! 4u[RS?T"%fnnXy&I"J! 	 KU % F @DEEF ! =7s;<<= N ! KEaSIJJKsW   AJ AJ) KK'A
K 	J&J!!J&)	K2KK	K5K00K5c                  n   g d} g }t        j                         t        d      z
  }t        d      D ]~  }|t        |      z   }| D ]f  }dddddd|   }t        j
                  j                  d	d
      }|d|z   z  }|dt        j
                  j                  d	d      z   z  }	|j                  |j                  d      |t        |d      t        t        ||	      dt        t        j
                  j                  d	d            z   z  d      t        t        ||	      dt        t        j
                  j                  d	d            z
  z  d      t        |	d      t        t
        j                  dd            t        |	dt        j
                  j                  d	d      z   z  d      d       i  |S )z'Generate sample stocks data for testingr  r  r  r  r  r  r  r  r   r=  r6  r  r  r#  {Gz?r?  r  r  )r   r  r   r  r  r  r  	adj_closer  )
rI   r   r  r  r  rJ   r  r  r  r  s
             r   "_generate_sample_stocks_data_localzYUniversalBacktestingEngine._get_stocks_engine.<locals>._generate_sample_stocks_data_local  s   >FD )<<I3Z (9!+<<# E !$!$ # # #" "J $&99#3#3At#<L!+q</?!@J",BII4D4DQ4N0N"OKKK , 5 5j A"' %j! 4 %c*k&Ba#biiN^N^_`bfNgJhFh&ikl m$S[%AQRYYM]M]^_aeMfIgEg%hjkl!&{A!6"%fnnXy&I"J%*;!bii>N>NqRW>X:X+Y[\%]	! 	6 Kr   )earnings_momentumvolume_breakoutr  r  gap_tradingr  )N1day)_stocks_earnings_momentum_stocks_volume_breakout_stocks_mean_reversion_stocks_trend_following_stocks_gap_trading)r7   r  r  s      r   _get_stocks_enginez-UniversalBacktestingEngine._get_stocks_engineW  sO    4	l!	H .%)%C%C#'#?#?"&"="=#'#?#?#77	
 		
r   c                 L   g }|j                  dd      }|j                  dd      }|D cg c]  }|j                  d      |k(  s| }}t        dt        |            D ]6  }||dz
  | }	t        j                  |	D cg c]  }|d   	 c}      }
||   d   }||
dz  kD  sC||   d   ||   d	   z
  ||   d	   z  }|d
kD  rht
        j                         dkD  rdnd}|j                  dt        |       ||   d   d|dt        ||
z  d      ||dk(  r|n| |d|dd|
ddd
       |dk  st
        j                         dkD  rdnd}|j                  dt        |       ||   d   d|dt        ||
z  d      ||dk(  r|n| |d|dd|
ddd
       9 |S c c}w c c}w )zStocks volume breakout strategyr  r  r  r  r  r  r#  r  r   r=  r9  r&  r'  stocks_volume_r   r  r  zVolume breakout buy (,rn  z,.0fr  )
r   r   r(  r  r)  ro  r*  r+  r  r,  rp  r  zVolume breakout sell (rq  rr  s                 r   r  z2UniversalBacktestingEngine._stocks_volume_breakout  s   Hf-

7D)"&DQ!%%/V*CqDDr3{+, #	A 2a(Fv!>!!H+!>?J(^H5N
Q. +Aw 7+a.:P PT_`aTbciTjj$&'-}}'=e6GMM .s6{m< +Av 6$5"("'(-nz.I1(M#*+2e+;%%!&$9.9K8T^_cSdde"f#  "E)'-}}'=e6GMM .s6{m< +Av 6$5"("((-nz.I1(M#*+2e+;%%!&$:>!:LHU_`dTeef"g# 1#	J O E "?s   FF?F!
c                    g }|j                  dd      }|j                  dd      }|D cg c]  }|j                  d      |k(  s| }}t        dt        |            D ]  }||dz
  | }	|	D cg c]  }|d   	 }
}t        j                  |
      }t        j
                  |
      }||   d   }|dkD  r||z
  |z  nd}|dk  rN||kD  rd	nd
}|j                  dt        |       ||   d   d|dt        |d      ||d	k(  r|n| |d|dd
       |dkD  s||k  rd	nd
}|j                  dt        |       ||   d   d|dt        |d      ||d	k(  r|n| |d|dd
        |S c c}w c c}w )zStocks mean reversion strategyr  r  r  r  r  r  r   r^  r&  r'  stocks_reversion_r   r  r  r#  zMean reversion buy at $r  r`  r  zMean reversion sell at $r"  ra  s                   r   r  z1UniversalBacktestingEngine._stocks_mean_reversion  s   Hf-

7D)"&DQ!%%/V*CqDDr3{+, %	A 2a(F*01Qaj1F1JvI'N73MBKa-}z1Y>UVG|#0:#=%6-c&k];'N62 0$#$Wa0&'.%'7eeV" 7c7JK  1#0:#=%6-c&k];'N62 0$$$Wa0&'.%'7eeV" 8s8KL 5%	N S E 2s   E*E*0E/c                    g }|j                  dd      }|j                  dd      }|D cg c]  }|j                  d      |k(  s| }}t        dt        |            D ]R  }t        j                  ||dz
  | D cg c]  }|d   	 c}      }	t        j                  ||dz
  | D cg c]  }|d   	 c}      }
||   d   }|
|	kD  rr||dz
     d   |	k  rd|||   d	   kD  rd
nd}|j                  dt        |       ||   d   d|dt        |
d      t        |	d      ||d
k(  r|n| |d|
dd|	ddd       |
|	k  s||dz
     d   |	k\  s|||   d	   k  rd
nd}|j                  dt        |       ||   d   d|dt        |
d      t        |	d      ||d
k(  r|n| |d|
dd|	ddd       U |S c c}w c c}w c c}w )zStocks trend following strategyr  r  r  r  2   r  r  r6  r   r&  r'  stocks_trend_r   r  r  r#  rS  r  rT  r  rU  r  rX  rY  rZ  )r7   r   r  rd   r  r  r  r[  r  rW  rV  r'  r*  s                r   r  z2UniversalBacktestingEngine._stocks_trend_following  s*   Hf-

7D)"&DQ!%%/V*CqDDr3{+, &	Agg;qtA3FGaqzGHGwwK"Q4GHq'
HIH'N73M'!k!A#&6w&?7&J#0;q>&3I#I%v)#f+7'N62 1$# %h 2$Wa0&'.%'7eeV" 3HS>gc]RST  G#AaC(8(AW(L#0;q>&3I#I%v)#f+7'N62 1$$ %h 2$Wa0&'.%'7eeV" 4XcN$wsmSTU 5&	P U E HHs   F8F8=F=
)G
c                    g }|j                  dd      }|j                  dd      }|D cg c]  }|j                  d      |k(  s| }}t        dt        |            D ]  }||dz
     d   }	||   d   }
|
|	z
  |	z  }t        |      dkD  s-|dkD  rX||   d   |
k  rd	nd
}|j	                  dt        |       ||   d   d|dt        |dz  d      ||d	k(  r|n| |d|ddd
       |dk  s||   d   |
kD  rd	nd
}|j	                  dt        |       ||   d   d|dt        |dz  d      ||d	k(  r|n| |d|ddd
        |S c c}w )zStocks gap trading strategyr  r  r  r  r6  r  r   r<  r&  r'  stocks_gap_r   r  r  rF  r#  zGap up fade (.1%r  )
r   r   r(  r  r)  gap_percentr*  r+  r  r,  gQr  zGap down bounce ()r   r  r   r[  r   rn  )r7   r   r  rd   r  r  r  r[  r  
prev_closecurrent_opengap_pctr*  s                r   r  z.UniversalBacktestingEngine._stocks_gap_tradingP  s   Hf-

7D)"&DQ!%%/V*CqDDq#k*+ #	A$QqS)'2J&q>&1L $j0J>G7|d"T>'21~g'>'MeSYGMM +CK=9 +Av 6$1"("(',Ws]A'>#*+2e+;%%!&$1'#a"@#  u_'21~g'>'MeSYGMM +CK=9 +Av 6$1"("'',Ws]A'>#*+2e+;%%!&$5gc]!"D# 1#	J O Es   EEc                    g }|j                  dd      }|j                  dd      }|D cg c]  }|j                  d      |k(  s| }}t        dt        |            D ]  }||dz
  | }	|	D cg c]  }|d   	 }
}t        j                  |
dd       }t        j                  |
d	d       }||   d   }||kD  r[||d
z
     d   |k  rM|||   d   kD  rdnd}|j                  dt        |       ||   d   d|d||   d   |||dk(  r|n| |dd       ||k  s||d
z
     d   |k\  s|||   d   k  rdnd}|j                  dt        |       ||   d   d|d||   d   |||dk(  r|n| |dd        |S c c}w c c}w )zForex trend following strategyr  r  r  r  r  r  Nir6  r   r&  r'  forex_trend_r   r  r  zMA crossover upr   r   r(  r  r)  entry_price
exit_pricer*  r+  r  r,  r  zMA crossover down)r   r  r   r  r#  r   )r7   r   r  rd   r  r  r  r  r  r  r%  ma_shortma_longr'  r*  s                  r   r  z1UniversalBacktestingEngine._forex_trend_following  s   zz&(+

7D) !%>1f(=Q>	>r3y>* )	AqtA&F +11Qaj1F1wwvbc{+HggfSTl+G%aL1M'!i!nW&=&H#09Q<3G#G%V(V6%aL0 1 ##,Q<#7"/&'.%'7eeV"/  G#	!A#w(?7(J#09Q<3G#G%V(V6%aL0 1 $#,Q<#7"/&'.%'7eeV"1 ;)	V [ ? 2s   E<E<0Fc                 t   g }|j                  dd      }|j                  dd      }|j                  dd      }|D cg c]  }|j                  d      |k(  s| }}t        |t        |            D ]3  }	||	|z
  |	 }
|
D cg c]  }|d   	 c}|
D cg c]  }|d   	 c}z   }t        j                  |d	      }t        j                  |d      }||	   d   }||	   d   }||	   d
   }||k  rY||	dz
     d
   |kD  rK|||z   dz  kD  rdnd}|j                  dt        |       ||	   d   d|d||||dk(  r|n| |d|dd       ||k\  s||	dz
     d
   |k  s|||z   dz  k  rdnd}|j                  dt        |       ||	   d   d|d||||dk(  r|n| |d|dd       6 |S c c}w c c}w c c}w )zForex range trading strategyr  r  r  r  range_periodr  r  r  P   r  r6  r#  r&  r'  forex_range_r   r  r  zRange support at r  r  r  zRange resistance at )r   r  r   r  
percentiler   )r7   r   r  rd   r  r  r  r  r  r  r  r%  rg  rh  r  rj  r  r*  s                     r   r  z/UniversalBacktestingEngine._forex_range_trading  s1   zz&(+

7D)zz."5 $>1f(=Q>	>|S^4 ,	Aq~a0F)/0Aai0f3MAeH3MMF vr2Jfb1I$Q</L#A,u-K%aL1M i'IacN7,Ci,O#0I
4Ja3O#O%U[(V6%aL0 / ##,"/&'.%'7eeV" 1)CA  +	!A#w0G*0T#0I
4Ja3O#O%U[(V6%aL0 / $#-"/&'.%'7eeV" 4Z4DE A,	\ a ? 13Ms   F+F+F0F5c                 z   g }|j                  dd      }|j                  dd      }|j                  dd      }|D cg c]  }|j                  d      |k(  s| }}t        |t        |            D ]  }	||	|z
  |	 }
|
D cg c]  }|d   |d   z
  |d   z   }}t        j                  |      }||	   d   ||	   d   z
  ||	   d   z  }|d	kD  s^|d
kD  sd||	   d   ||	   d   kD  rdnd}|j                  dt        |       ||	   d   d|dt        |d      ||dk(  r|n| |d|dd
        |S c c}w c c}w )z Crypto momentum trading strategyr  r2  r  r  momentum_periodr  r  r   r=  r   r&  r'  crypto_momentum_r   rG  r  r  zHigh momentum: z.2%)
r   r   r(  r  r)  momentumr*  r+  r  r,  rZ  )r7   r   r  rd   r  r  r  r  r[  r  r  returnsavg_momentumcurrent_returnr*  s                  r   rJ  z3UniversalBacktestingEngine._crypto_momentum_trading  s   He,

7D) **%6:"&DQ!%%/V*CqDDK(89 	A ?!215FEKL'
QvY.!F);LGL777+L)!nW5Av8NNR]^_R`agRhhNd"~'9#.q>'#:[^F=S#S%Y_,S[M:'N62 2$# %lA 6&'.%'7eeV" /S/AB 	, 1 E Ms   D3D3D8c                    g }|j                  dd      }|j                  dd      }|D cg c]  }|j                  d      |k(  s| }}t        dt        |            D ]  }t        j                  j                  dd      }	|	dkD  s)||   d	   ||   d
   kD  rdnd}
|j                  dt        |       ||   d   d|t        |	d      |
|
dk(  r|n| |d|	dd	        |S c c}w )z!Stocks earnings momentum strategyr  r  r  r  r  r   re  皙?r  r   r&  r'  stocks_earnings_r   r  r  zEarnings beat by r  )	r   r   r(  r  earnings_surpriser*  r+  r  r,  )r   r  r   r  r  r  r   rn  )r7   r   r  rd   r  r  r  r[  r  r  r*  s              r   r  z4UniversalBacktestingEngine._stocks_earnings_momentum  s   Hf-

7D)"&DQ!%%/V*CqDDq#k*+ 	A "		 0 0C 8 4'#.q>'#:[^F=S#S%Y_,S[M:'N62 3$)./@!)D&'.%'7eeV" 12CC1HI
 
	& + Es   C%C%rd   c                 L   |sddiS t        j                  |D cg c]  }|j                          c}      }t        |      }t        ||d   dk(           }t        ||d   dk(           }|dkD  r||z  nd}|d   j	                         }	|d   j                         }
|dkD  r||d   dk(     d   j                         nd}|dkD  r||d   dk(     d   j                         nd}||d   dk(     d   j	                         }t        ||d   dk(     d   j	                               }|dkD  r||z  }n|dkD  rt        d      }nd}|d   }t        |      d	kD  rK|j                         dkD  r8|j                         |j                         z  t        j                  d
      z  }nd}|d   j                         }|j                         j                         }||z
  }|j                         }|dkD  r8|dkD  r3|dk  r.|d	|z
  |t        |      z  z  z
  }t        dt        |d            }nd}|||t        |dz  d      t        |	d      t        |
d      t        |d      t        |d      |t        d      k7  rt        |d      ndt        |d      t        |d      t        |d      |d   j	                         |d   j	                         dkD  r#t        |	|d   j	                         z  dz  d      nd| j!                  ||j#                  d|d   j	                                     dS c c}w )z(Calculate comprehensive backtest resultsrO   zNo trades to analyzer*  r&  r'  r   r+  rM  r6           ?rF  r#     ∞r  r  initial_capital)rb   winning_tradeslosing_tradesrD  rC  avg_profit_per_traderU  rV  rE  sharpe_ratiorW  kelly_fractiontotal_stakereturn_percentagecagr)r   r   copyr   rZ  r#  r[  r.  r$  r  sqrtcumsum	expandingr  r  rn  _calculate_cagrr   )r7   rd   r  tr  rb   r  r  rD  rC  
avg_profitrU  rV  r`  ra  rE  r  r  
cumulativerunning_maxrv  rW  r  s                          r   r   z6UniversalBacktestingEngine._calculate_backtest_results0  s:   344 \\V4166845 2wR9 678Br)}6784@14D>L0! (|'')\&&(
AORSAS"R	]e+,X6;;=YZCPSTCT2bmv-.x8==?Z[ 9./9==?
2bmv56x@DDFG!&5M!^!%LMM X,w<! 1"<<>GKKM9BGGCLHLL \((*
 **,002+||~ a<GaKHqL%!h,7S];R)STN C$=>NN ),*hna0!,2$)*a$8Wa(h*8Eu8UU=!4[`!,2!,2#NA6g;??,WYZaWbWfWfWhklWlr'{7H(HC'OQR!Srs((<MrRY{O`1ab
 	
Y 5s   L!r  c                 v   |r|dk  ry	 t        j                  |d   j                  dd            }t        j                  |d   j                  dd            }||z
  j                  dz  }|dk  ryt	        d |D              }||z   }|dk  ry||z  d	|z  z  d	z
  d
z  }t        |d      S # t        $ r Y yw xY w)z%Calculate Compound Annual Growth Rater           r   rz   g     v@c              3   @   K   | ]  }|j                  d d        ywrH  )r   )r  r  s     r   r  z=UniversalBacktestingEngine._calculate_cagr.<locals>.<genexpr>  s     BaquuXq1Bs   g      Yr6  rF  r#  )r   to_datetimer   r  rZ  rn  r   )	r7   rd   r  
first_date	last_dateyearsrC  final_capitalr  s	            r   r  z*UniversalBacktestingEngine._calculate_cagrt  s    A-	q	fb(ABJvbz~~fb'ABI+11F:EzB6BBL+l:M!"_4!e)DqHCODq>! 		s   A'B, 2B, B, ,	B87B8c                    |r||j                   rddiS 	 g g i i d}t        dt        |            }|j                  |      j	                  d      }|j                         D ]&  \  }}	 |t        |j                  d|j                  d	|                  t        j                  |d
         rt        |d
         ndt        j                  |d         rt        |d         ndt        j                  |d         rt        |d         ndt        j                  |d         rt        |d         ndt        j                  |j                  dd            rt        |j                  dd            ndd}	|d   j                  |	       ) t        j                  |      }|j                   rBdt        |d         |dt        |      dkD  rt        |j                   d   d         ndd|d<   |S t        j"                  |d	   dd      |d<   |j%                  dg      }|d   j&                  j)                  d      |d<   |j+                  d      }|j-                         }d}dD ]  }||j.                  v s|} n |Lt        |      t        |d         |dt        |      dkD  rt        |j                   d   d         nddd|d<   |S t        j"                  ||   dd      |d<   |j%                  dg      }|d   j&                  j)                  d      |d<   |j+                  d      }|j                   s|j                   rKt        |      t        |d         |dt        |      dkD  rt        |j                   d   d         ndd|d<   |S g d}g d}g d}|D ]"  }||j.                  v s|j                  |       $ 	 |dk(  rdnd }t        j0                  |||   dd!t        j2                  |"      #      }|j%                  d
g      }|j                         D ]	  \  }}t        |j                  d&d'            j?                         }t        |j                  d(d)            }t        |j                  d*d            }t        |j                  d+d,            }t        |j                  d-|j                  dd                  }|dk(  rt        |d         }|d   }d}|j                         D ]Y  \  }}t        j"                  |j                  d|j                  d	            dd      }|@|j)                  d      }||k(  sW|} n |6d.}d/} |d'k(  r|d0|z
  z  }!|d0| z   z  }"|||z  |z  z   }#n|d0|z   z  }!|d0| z
  z  }"|||z  |z  z
  }#d)}$|d1k(  r#|d'k(  r|#|"d2z  k\  rd3}$n:|d4k(  r|#|"d5z  k  rd3}$n*d6}$n'|d7k(  r"|d'k(  r|#|!d5z  k  rd8}$n|d4k(  r|#|!d2z  k\  rd8}$nd8}$	 |}%d}&d9|v r4t        j                  |d9         rt        j"                  |d9   dd      }&nd:|v r4t        j                  |d:         rt        j"                  |d:   dd      }&nnd	|v rjt        j                  |d	         rRt        j"                  |d	   dd      }'|'5|d;v rt        j2                  d0<      nt        j2                  d0=      }(|'|(z   }&|&}|&j)                  d      }&|j                         D ]Y  \  }}t        j"                  |j                  d|j                  d	            dd      }|@|j)                  d      }||&k\  sW|}% n tA        |%|d0z         }%t        |%t        |      d0z
        }%t        |j                  d@dA|             tC        |      ||||tC        |      |t        |j                  d	dB            dCtC        |%      |#t        |j                  d9|j                  d	dB                  |$dD|!|"dE|j                  dFi       |%|z
  dG})|dH   j                  |)        t        |      t        |d         |dt        |      dkD  rt        |j                   d   d         ndd|d<   |S # t        t        t        f$ r}
Y d}
~
2d}
~
ww xY w# t4        $ rW}
ddl}t9        d$|
 d%       |j-                         }|D ]$  }||j.                  vst:        j<                  ||<   & Y d}
~
d}
~
ww xY w# t4        $ rY}
|tA        d0tC        t        |      d>z              z   }%t        |%t        |      d0z
        }%ddl}t9        d?|
        Y d}
~
d}
~
ww xY w# t4        $ r]}
t9        dI| dJt        |
              ddl"}*|*jG                          dKt        |
       g g i dL||rt        |      nddMdNcY d}
~
S d}
~
ww xY w)OzJGenerate comprehensive chart data with trade annotations for visualizationNrO   z,No trade or data available for visualizationrv      Tdropra   r   r   r   r  r  r  r  )indexra   r   r  r  r  r  rw   r  r  )rb   
price_barsr;   r@   
last_pricery   coerce)utcerrors)subset)ra   r   Datetimez'No timestamp column found in price data)rb   r  r;   r@   r  rO   )ra   r   r  )r  r  r  rI   iQ i   backward)seconds)on	direction	toleranceu   ⚠️ merge_asof failed: z!, falling back to simple matchingr)  r  r*  unknownr+  r  rF  r  r=  {Gz?r6  r&  g\(\?take_profitr  gRQ?profit_targetr'  	stop_loss	exit_dateexit_timestamp)rG   rH   )hoursr  re  u1   ⚠️ Exit bar matching failed, using fallback: r   trade_rz   )	bar_indexpricera   )r  r  ra   reason)r  r   context)r   r  r)  r*  r+  r  entryexitlevelsr
  duration_barsrd   zVisualization error in rn   zVisualization error: zChart generation failed)rO   r;   ru   )rO   rw   rd   rx   ry   )$emptyr  r   tailreset_indexiterrowsr   r   r   notnar.  r   KeyErrorr   r   r   ilocr  dropnadttz_localizesort_valuesr  columns
merge_asof	Timedeltar   r   r   r  nanr   r  r   r   	print_exc)+r7   rd   r>   r;   r   
chart_barsprice_dfidxrowbar_datar   	trades_dfprice_df_copytimestamp_colcolrequired_colsoptional_cols
merge_colstolerance_seconds	merged_dfr   	trade_idxr)  r*  r+  r  r  entry_timestampentry_bar_idxp_rowbar_tsstop_loss_pcttake_profit_pctstop_loss_pricetake_profit_pricer  exit_reasonexit_bar_idxr  trade_entry_timemin_duration	trade_vizr   s+                                              r   r   z=UniversalBacktestingEngine._generate_trade_visualization_data  sQ
   ,0A0AKLLQ	  	J S#k"23J"''
3??T?JH %--/ S!$%(cggfc>R)S%T68hhs6{6Kc&k 2QR68hhs6{6Kc&k 2QR46HHSZ4HuSZ0a8:W8Ns7|!4TUAC#''RZ\]J^A_%!(<"=ef H |,33H=( V,I$%"%j&>"?$!(GJ8}WXGX%b(9'(B"C^_)
9% "! &(^^If4E4X`%aIk"!(((>I%.{%;%>%>%J%J4%PIk"!--k:I %MMOM !M< -///$'M
 $ %(	N"%j&>"?$!(GJ8}WXGX%b(9'(B"C^_F)
9% "!)+m,$x*M+& *000FM)6{)C)F)F)R)RSW)XM+&)55kBM""ioo$'	N"%j&>"?$!(GJ8}WXGX%b(9'(B"C^_)
9% "! ;M5M7J$ +-///%%c*+0-3x-?ET!MM!*-"( ll3DE	  "(((9I #,"4"4"6 y7	3SWWXu56<<>cggi;<swwx34cgggs34 $CGGM3777A;N$OP!#"'G"5K #&k"2 $"*"3"3"5 "JC^^EIIk599VCT,U[_hpqF)!'!3!3D!9!_4,/M!" !( !%"&U?&1Q5F&GO(3q?7J(K%!,+/M!MJ&1Q5F&GO(3q?7J(K%!,+/M!MJ (e#:9JT9Q+Q&36)j<MPT<T.T&3&5&:49O+O&16)jOd<R.R&1&1%_#0L &*N"c)bhhs;7G.H)+K8Hd[c)d)S0RXXcBR>S5T)+<L8MSW`h)i3288CK+@+->>#f+4X`+a(+7DJNaDa2<<a+@gigsgsyzg{L-=-LN%1)7)C)CD)I +3*;*;*= *JC%'^^EIIk599U[K\4]cgpx%yF%1)/););D)A#)^#;36L$)* $'|]Q5F#GL#&|S]Q5F#GL cggdfYK,@AB ^$&$"%(%7!,%()<%= &)%6!+%(cggfb>Q)R%S"-	 &5'8  #wwy"5%1M%A/	2 8$++I6sy7z !$F!*\":; $CFx=STCTeHMM"$5g$>?Z[%Jy! K !*i8 j  0E$>qcAb"cd%NN,	% 0C)"3"33)+	#0	0L ! _#03q#c(mc>Q:R3S#SL#&|S]Q5F#GL(YZ[Y\&] ^ ^	_X  	+F82c!fX>?! 1Q9  6$39CKq
 
	s   Ae% +Da;
A%e% 0Be% 9Ae% Ce% e% 2e% :b  D8e% 9e% Be% +Ed 0d ,d 3De% ;be% be% 	c=&6c8c82e% 8c==e%  	e"	Aee% e""e% %	g.Ag ggc                    |si S t        j                  |      }|d   }t        |      dkD  rt        j                  |d      }nd}||dk     }t        |      dkD  r-t        |||k           dkD  r|||k     j                         n|}nd}d}|||k     }t        |      dkD  r\t        j                  t        j
                  |dz              }	|	dkD  r)|j                         |	z  t        j                  d      z  nd}
nd}
|d   j                         }|j                         j                         }||z
  }t        |j                               }|dkD  r$|j                  d   t        |      z  dz  }||z  }nd}g }d}d}|d   D ]*  }||k(  r|d	z  }|dkD  r|j                  ||d
       d	}|}, |dkD  r|j                  ||d
       |D cg c]  }|d   dk(  s| }}|D cg c]  }|d   dk(  s| }}t        |d      t        |d      t        |
d      t        |d      |rt        |D cg c]  }|d   	 c}      nd|rt        |D cg c]  }|d   	 c}      nd|r0t        t        j
                  |D cg c]  }|d   	 c}      d	      nd|r0t        t        j
                  |D cg c]  }|d   	 c}      d	      ndt        |d   j                         d      t        |d   j!                         d      t        |d   j#                         d      dS c c}w c c}w c c}w c c}w c c}w c c}w )zCalculate detailed risk metricsr+  r   r  r#  r  r  Nr*  r6  r   lengthr   r&  r'  r=  )value_at_risk_95conditional_var_95sortino_ratiocalmar_ratiomax_win_streakmax_loss_streakavg_win_streakavg_loss_streak
volatilityskewnesskurtosis)r   r   r   r  r  r#  r  r  r  r  r[  r  r  r   rn  r$  skewrH  )r7   rd   r  r  var_95r{  cvar_95target_returndownside_returnsdownside_deviationr@  r  r  rv  rW  annual_returnrA  streakscurrent_streakcurrent_typer*  swin_streaksloss_streakss                           r   r   z2UniversalBacktestingEngine._calculate_risk_metrics	  sH   I\\&! X,w<!]]7A.FF 1%v;?9<VFfDT=U9VYZ9ZfVv-.335`fGG "7]#:; 1$!#1AQ1F)G!HRdghRhGLLN-??"''#,NnoMM \((*
 **,002+8<<>*!'__R03z?BcIM(<7LL )} 	'G,&!#!A%NNLN#ST!"&	' ANNLNKL")@QQvY%-?q@@#*Baai6.ABB !&fa 0"'"3"=!4!,2ITc"D11X;"DEZ[KWs#FAAhK#FG]^WbeBGG+,NQQx[,N$OQRShiYeuRWW<-Paak-P%QSTUkl8 0 0 2A6bl//115bl335q9
 	
 AB #E#F,N-Ps0   L#L#(L(6L(3L-L2 L73L<rc   c                    |d   }|d   }|d   }|d   }|d   }dddd	d
j                  ||j                               }d| d| d| d|d    d| d| d| d|d    d|d   dz   d|d    d|d    d|d    d|d    d }		 t        |      }
|d"k\  r|
d#k\  rd$}n|d%k\  r|
d&k\  rd'}n|d(k\  r|
d)k\  rd*}nd+}|	d | z  }	|	j                         S # t        t        f$ r d!}
Y Tw xY w),z+Generate human-readable performance summaryrD  rC  rE  r  rW  rN  ForexCryptocurrencyStocks)r   rG   rH   rI   u   
🏀 **u=    BACKTEST RESULTS**

📊 **Overall Results:**
• Win Rate: u   %
• Total Profit: $u   
• Total Trades: rb   u5   

💰 **Profitability Metrics:**
• Profit Factor: u   
• Sharpe Ratio: u   
• Max Drawdown: $u0   

📈 **Risk-Adjusted Returns:**
• Return %: r  u   %
• Kelly Fraction: r  rF  u*   %

🎲 **Trade Analysis:**
• Avg Win: $rU  u   
• Avg Loss: $rV  u   
• Winning Trades: r  u   
• Losing Trades: r  
r  <   rl  u6   🏆 EXCELLENT - This strategy shows strong potential!7   g333333?u7   ✅ GOOD - Solid performance with room for optimizationr  g      ?u3   🤔 FAIR - Breakeven performance, needs refinementu4   ⚠️ POOR - Strategy needs significant improvement)r   r   r.  r   r   strip)r7   rc   r;   rD  rC  rE  r  rW  market_namery   pf_valratings               r   r   z8UniversalBacktestingEngine._generate_performance_summary	  s   :&~.0~.~. &	

 #fflln
% 	}  j  > ">*+ , "? #. ! > " *+, --.s23 4 y!" #
#$ %-./ 0O,- .+2	=)F r>fmMF^#NF^#JFKFRx= }} I& 	F	s   C C"!C"basic_resultsc                 B   |si S t        j                  |      }t        |      }t        ||d   dk(           }t        ||d   dk(           }|dkD  r||z  nd}|d   }||d   dk(     d   }	||d   dk(     d   }
t        |	      dkD  r|	j                         nd}t        |
      dkD  r|
j	                         nd}t        |	      dkD  r|	j	                         nd}t        |
      dkD  r|
j                         nd}t        |	      dkD  r|	j                         nd}t        |
      dkD  r|
j                         nd}t        |	      dkD  r|	j                         nd}t        |
      dkD  r|
j                         nd}|	j                         }t        |
j                               }|dkD  r||z  nd}|}t        |      dkD  r|j                         dkD  r|j                         |j                         z  t        j                  d      z  }||dk     }t        |      dkD  rK|j                         dkD  r8|j                         |j                         z  t        j                  d      z  }nd}nd}d}|j                         }|j                         j                         }||z
  }|j	                         }t        ||dk           dkD  r||dk     j                         nd}|dk  rt        |j                  d	   |z        nd}g } d}!d
}"|d   D ]*  }#|#|"k(  r|!dz  }!|!dkD  r| j                  |"|!d       d}!|#}", |!dkD  r| j                  |"|!d       | D $cg c]  }$|$d   dk(  s|$ }%}$| D $cg c]  }$|$d   dk(  s|$ }&}$|dkD  r d|z
  dkD  r||z  d|z
  t        |      z  z
  }'nd}'|dkD  r8|dkD  r3|dk  r.|d|z
  |t        |      z  z  z
  }(t        dt	        |(d            }(nd}(|j                         })|j!                         }*|j#                         }+|||t%        |dz  d      t%        |d      dt%        |j                         d      t%        |d      t%        |d      t%        |d      t%        |d      t%        |d      t%        |d      t%        |d      t%        |d      t%        |d      t%        |d      d|t'        d      k7  rt%        |d      nd||dk7  rt%        |t        |      z  d      nd|t'        d      k7  rt%        |d      ndt%        |'d      t%        |(dz  d      dt%        |d      t%        |d      t%        |d      t%        |d      t%        |)d      t%        |*d      t%        |+d      d|%rt        |%D $cg c]  }$|$d   	 c}$      nd|&rt        |&D $cg c]  }$|$d   	 c}$      nd|%r0t%        t        j
                  |%D $cg c]  }$|$d   	 c}$      d      nd|&r0t%        t        j
                  |&D $cg c]  }$|$d   	 c}$      d      nd|"|!dt%        |j)                  d      d      t%        |j)                  d      d      t%        |j                         d      t%        |j)                  d      d      t%        |j)                  d      d      dt        |	      dkD  rt%        |	j)                  d      d      ndt        |	      dkD  rt%        |	j)                  d      d      ndt        |	      dkD  rt%        |	j)                  d      d      ndt        |	      dkD  rt%        |	j)                  d      d      nddt        |
      dkD  rt%        |
j)                  d      d      ndt        |
      dkD  rt%        |
j)                  d      d      ndt        |
      dkD  rt%        |
j)                  d      d      ndt        |
      dkD  rt%        |
j)                  d      d      nddddS c c}$w c c}$w c c}$w c c}$w c c}$w c c}$w ) z>Calculate comprehensive detailed statistics from actual tradesr*  r&  r'  r   r+  gR?@r6  r  r  Nr<  r   r  rF  r#  r  )rb   r  r  win_rate_percentwin_rate_decimal)rC  total_wins_amounttotal_losses_amountbiggest_winbiggest_losssmallest_winsmallest_lossaverage_winaverage_loss
median_winmedian_lossrM  r  )rE  profit_factor_numericwin_loss_ratiorecovery_factorexpectancy_per_tradekelly_fraction_percent)r  r@  rW  average_drawdownprofit_volatilityprofit_skewnessprofit_kurtosisr=  )rB  rC  rD  rE  current_streak_typecurrent_streak_lengthre  g      ??)p10p25
p50_medianp75p90)r{  r|  r~  r  )profit_percentileswin_amount_percentilesloss_amount_percentiles)trade_analysisprofit_loss_analysisratios_and_factorsrg   streak_analysisdistribution_analysis)r   r   r   r  r  r#  medianrZ  r[  r$  r  r  r  r  r  r   rI  rH  rn  r.  quantile),r7   rd   ra  r  rb   r  r  rD  profitswinning_profitslosing_profitsrg  rh  ri  rj  avg_win_amountavg_loss_amountrm  rn  r`  ra  rE  r  r  negative_returnsr@  r  r  rv  rW  avg_drawdownrq  rP  rQ  rR  r*  rS  rT  rU  
expectancyr  
profit_stdrv  rw  s,                                               r   r   z9UniversalBacktestingEngine._calculate_detailed_statistics+
  s   I\\&! 2wR9 678Br)}6784@14D>L0! X,R	]e34X>ByMV34X> 03?/Ca/Go))+Q/2>/BQ/F~))+A03O0Dq0H**,a03N0Ca0G**,Q 473G!3K--/QR36~3F3J.--/PQ14_1E1I_++-q
14^1Dq1Hn++-a %((*
>--/05AA5E
\16 w<! 1"<<>GKKM9BGGCLHL&w{3#$q(-=-A-A-Ca-G '1A1E1E1G G"''RU, V !LM ^^%
 **,002+||~8;HXPQ\<R8SVW8Wx1-224]^ FRTUEU#joob1L@A[a )} 	'G,&!#!A%NNLN#ST!"&	' ANNLNKL")@QQvY%-?q@@#*Baai6.ABB a<Q\Q."^3X_I]8]^JJ a<NQ.?Q3F%!h,>CP_L`;`)abN C$=>NN [[]
!,,.!**, !-"0!.$)(S.!$<$)(A$6 !&gkkmQ 7%*:q%9',\1'=$[!4 %lA 6 %lA 6!&}a!8$^Q7 %oq 9#J2$[!4% =JUSX\<Y}a!8_d)6UdhiUi%_9M(Mq"Qou@OSXY^S_@_5!#<ej(-j!(<*/0Da*H# !&lA 6!&}a!8 %lA 6$),$:%*:q%9#(!#<#(!#< NY#K&Hqq{&H"I^_O[3\'J('J#Kab[f%k0R80R(SUV"Wlm]i5|1T!!H+1T)UWX#Yop'3)7  !!1!1#!6: !1!1$!7;"'(8!"< !1!1$!7; !1!1#!6:' GJ/FZ]^F^5!9!9#!>BdeGJ?G[^_G_5!9!9$!?CefGJ?G[^_G_5!9!9$!?CefFI/FZ]^F^5!9!9#!>Bde	+ FIEX[\E\5!8!8!=qAbcFI.FY\]F]5!8!8!>BcdFI.FY\]F]5!8!8!>BcdEHEX[\E\5!8!8!=qAbc	,&]C
 C	
+ ABv 'I'J0R1Ts0   `%`/`=`
`)``
`c                 $   |syg }|j                  d       |j                  d       |j                  d       |j                  d       d}t        |d      D ]a  \  }}||d   z  }|j                  dd	      }|j                  d
d|       }|j                  dd      }|j                  dd      }	|j                  dd      }
|j                  dd      }|j                  dd      }|	dk(  rdn|	dk(  rdnd}|j                  d       |j                  d|        |j                  d|        |j                  d| d|	j                                 |j                  d|
d       |j                  d|d        |j                  d!|        |j                  d"|d       |j                  d#       d |j                  d       |j                  d$|dd%t	        |       d&       |j                  d       d'j                  |      S )(z=Generate a detailed log of all trades with timestamps and P&LzNo trades to log.zP================================================================================z-DETAILED TRADE LOG - ALL TRADES CHRONOLOGICALrz   r   r6  r+  r   zN/Ar   Trade_r)  UNKNOWNr*  r  r  r,  z	No signalr&  u   ✅r'  u   ❌u   ⚪2dzDate: zAction: z	Outcome: r   zProfit/Loss: $z+.2fzStake: $r  zSignal: zCumulative P&L: $z(----------------------------------------zFINAL RESULT: $z total P&L from  tradesrZ  )r   	enumerater   r   r   r   )r7   rd   	log_linescumulative_pnlr  trade
trade_datetrade_idr)  r*  r+  r  r,  outcome_symbols                 r   r   z7UniversalBacktestingEngine._generate_detailed_trade_log
  s!   &	"HI"!&!, 	'HAueHo-N 651Jyys|4HYYx3Fii	95GYYx+FIIgq)EYYx5F '.&6UWPVEVE\aNT"vj\23xx01y(8'--/9JKL~fT];<xc{34xx0100EFGX&/	'2 	?>$*??OPSTZP[}\cde"yy##r   walk_forward_configc           
      v   	 t        j                  |      }d|j                  vrFd|j                  v rt        j                  |d         |d<   n| j                  j                  d       yt        j                  |d         |d<   |j                  d      j                  d      }|j                  dd      }|j                  d	d
      }	|j                  d      }
|j                  d      }|j                  d|	      }|
rt        j                  |
      }
n|d   j                         }
|rt        j                  |      }n|d   j                         }||d   |
k\  |d   |k  z     }t        |      dk  rddt        |      dS g }|
}d}d}||k  r||k  r|t        j                  |      z   }|}|t        j                  |	      z   }||d   |k\  |d   |k  z     }t        |      dk  rn||d   |k\  |d   |k  z     }||d   |k\  |d   |k  z     }t        |      dk  st        |      dk  rnI| j                  |j                  d      |||      }| j                  |j                  d      |||      }| j                  |      }| j                  |      }| j!                  ||      }|j#                  |dz   t%        |j'                               t%        |j'                               t        |      t        |      |dt%        |j'                               t%        |j'                               t        |      t        |      |d|d       |t        j                  |      z   }|dz  }||k  r||k  r| j)                  |      }||	|t%        |
j'                               t%        |j'                               t        |      d||| j+                  |      | j-                  |      dS # t.        $ r9}| j                  j                  d|        dt%        |       |dcY d}~S d}~ww xY w) a  
        Perform walk forward analysis to prevent overfitting

        Parameters:
        - in_sample_months: Months for training/optimization
        - out_of_sample_months: Months for testing
        - start_date: Optional start date (YYYY-MM-DD)
        - end_date: Optional end date (YYYY-MM-DD)
        - step_months: Months to advance each period (default = out_of_sample_months)
        ra   r   z;No timestamp or date column found for walk forward analysisNTr  in_sample_monthsr  out_of_sample_monthsr  
start_dateend_datestep_monthsrF  z+Insufficient data for walk forward analysis)rO   required_minimumavailable_datar   r  )monthsr  r}  r   r  r6  )r  r  data_pointsrd   metrics)period_numberin_sample_periodout_of_sample_periodoverfitting_analysis)r  r  r  r  r  total_periods)configurationperiodsoverall_statisticsoverfitting_summaryrecommendationsz Error in walk forward analysis: zWalk forward analysis failed: )rO   r  )r   r   r  r  r-   rO   r  r  r   r  r  r   
DateOffset_run_strategy_on_datar  _calculate_walk_forward_metrics_calculate_overfitting_metricsr   r   r   %_calculate_overall_walk_forward_stats_generate_overfitting_summary&_generate_walk_forward_recommendationsr   )r7   r   r;   r<   r=   r  r@   r  r  r  r  r  r  rA   current_startperiod_countmax_periodsin_sample_endout_sample_startout_sample_endperiod_datain_sample_dataout_sample_datain_sample_tradesout_sample_tradesin_sample_metricsout_sample_metricsoverfitting_metricsoverall_statsr   s                                 r   r   z5UniversalBacktestingEngine._run_walk_forward_analysis
  s   F	d#B "**,RZZ'&(nnRZ&@B{OKK%%&cd nnR_=B{O,88d8CB  3667I2N#6#:#:;QST#U ,00>J*..z:H-11-AUVK ^^J7
_002
>>(3k?..0 R_
2r+(7RSTB2w}J(+&)"g  $& &MLK(*|k/I -EU0V V $1 !1BMMI]4^!^ !"[/]"Br+YgGg!hi{#b( "$R_%E"[/\iJi$j!k"$bo9I&IbQ\o`nNn%o"p~&+s?/Cb/H $(#=#="**95v}j$ 
 %)$>$>#++I6z%!
 %)$H$HIY$Z!%)%I%IJ[%\" '+&I&I%'9'# %++%1A%5&)-*<*<*>&?$'(:(:(<$='*>':"%&6"7#4) '**:*?*?*A&B$'(;(;(=$>'*?';"%&7"8#5- -@!- ( !.[0Q Q!y  (*|k/I~ !FFG[\M )9,@#."%joo&7"8 #HMMO 4%()=%>" 0&3'+'I'IJ^'_#'#N#N}#]   	KK @DE9#a&B!4 	s3   A(O6 +DO6 G9O6 A4O6 6	P8?.P3-P83P8c                     	  t        | d| d             }|sg S |d   j                  |      }|sg S  |||      }|r|S g S # t        $ r*}| j                  j	                  d|        g cY d}~S d}~ww xY w)z@Run a strategy on specific data subset for walk forward analysis_get__enginerm   )r  z'Error running strategy on data subset: N)getattrr   r   r-   rO   )	r7   r   r;   r<   r=   r   r   rd   r   s	            r   r  z0UniversalBacktestingEngine._run_strategy_on_data  s    	BGDE&*ABDM 	 *,7;;MJM 	 #4
;F#6++ 	KK GsKLI	s-   A A A A 	A6A1+A61A6c           	         |s	dddddddS t        j                  |      }|d   }t        ||d   dk(           }t        |      }|dkD  r||z  nd}|j                         }|j	                         }|j                         }	|	j                         j                         }
|	|
z
  }t        |      dkD  rt        |j                               nd}t        |      dkD  rK|j                         dkD  r8|j	                         |j                         z  t        j                  d      z  }nd}|t        |dz  d	      t        |d	      t        |d	      t        |d	      t        |d	      dS )
z-Calculate key metrics for walk forward periodr   )rb   rD  	total_pnl	avg_traderW  r  r+  r*  r&  r6  r  rF  r#  )r   r   r   rZ  r#  r  r  r  r[  r  r$  r  r  rn  )r7   rd   r  r  r  rb   rD  r  r  r  r  rv  rW  r  s                 r   r  z:UniversalBacktestingEngine._calculate_walk_forward_metrics  sX    ! ! !  \\&!X,R9 6782w4@14D>L0!KKM	LLN	 ^^%
 **,002+.1(ma.?s8<<>*Q w<! 1"<<>GKKM9BGGCLHLL )hna0y!,y!,!,2!,2
 	
r   	in_sample
out_samplec                    	 |j                  dd      }|j                  dd      }|dk7  r||z
  t        |      z  dz  }nd}|j                  dd      }|j                  dd      }||z
  }|j                  dd      }	|j                  dd      }
|
|	z
  }t        |      t        |      z   t        |      z   }|dk  rd}d}n|d	k  rd
}d}n|dk  rd}d}nd}d}t        |d      t        |d      t        |d      t        |d      |||dk7  rt        ||z  d      nd|dk7  rt        ||z  d      nd|	dk7  rt        |
|	z  d      ndddS # t        $ r7}| j                  j                  d|        t        |      dddcY d}~S d}~ww xY w)zMCalculate overfitting metrics between in-sample and out-of-sample performancer  r   rF  rD  r  r  LOWz+Strategy shows good out-of-sample stabilityr  MODERATEz1Some performance decay detected - monitor closelyHIGHz?Significant overfitting detected - strategy may need adjustmentCRITICALz1Severe overfitting - strategy likely curve-fittedr#  )	pnl_ratiowin_rate_ratior  )performance_decay_percentwin_rate_decay_percentsharpe_decayoverfitting_scoreoverfitting_risk_leveloverfitting_descriptionin_sample_vs_out_samplez'Error calculating overfitting metrics: r  )rO   r  r  N)r   r[  rn  r   r-   rO   r   )r7   r  r  in_pnlout_pnlperformance_decayin_win_rateout_win_ratewin_rate_decay	in_sharpe
out_sharper  r  
risk_levelrisk_descriptionr   s                   r   r  z9UniversalBacktestingEngine._calculate_overfitting_metrics  s   9	]];2F nn[!4G{&-&6#f+%E$L!$%! $--
A6K%>>*a8L)K7N "na8I#:J%	1L !$$5 6^9L LsS_O` ` !2%"
#P "R''
#V "S(#
#d '
#V  .33Da-H*/*B %lA 6%*+<a%@*4+;?E{w'7!;PQNY]^N^eL;,F&JdeHQUVE*y*@!$D\],   	KK GsKLQ%&*3 	s   EE 	F,F FFr  c                    |si S |D cg c]  }|d   d   d   dkD  s|d   d    }}|sddiS |D cg c]  }|d   	 }}|D cg c]  }|d   	 }}|D cg c]  }|d	   	 }}t        |      d
kD  rt        j                  |      nd}t        |      d
kD  rt        j                  |      nd}	t        |D cg c]
  }|dkD  s	| c}      }
|r|
t        |      z  nd}t        |      t        t        j                  |      d      t        t        j                  |      d      t        t        |      d      t        t        j                  |      d      t        |d      t        |	d      t        |dz  d
      t        t        |      d      t        t        |      d      |r!t        t        j                  |      d      dS ddS c c}w c c}w c c}w c c}w c c}w )z<Calculate overall statistics across all walk forward periodsr  r  rb   r   rO   zNo valid out-of-sample periodsrD  r  r  r6  r#  rF  )r  average_win_rateaverage_monthly_pnlr  average_sharpewin_rate_consistencypnl_consistencyprofitable_periods_percentbest_period_pnlworst_period_pnloverall_sharpe)r   r  r$  rn  r#  rZ  r  r  )r7   r  pout_sample_resultsr   	win_ratespnlssharpe_ratioswin_rate_stdpnl_stdprofitable_periodsprofitability_rates               r   r  z@UniversalBacktestingEngine._calculate_overall_walk_forward_stats  s   I MT  QqWXYoWpqzW{  }K  XL  OP  XPa 67	B  Q  Q!=>> -??qQz]?	?(:;1+;;4FGq>*GG -0	NQ,>rvvi(A"%d)a-"&&,Q !T!;QU!!;<?C/#d); !!34 %bggi&8! <#(#:s4y!,#BGGM$:A>$),$:$Wa0*/0BS0H!*L$SY2 %c$i 3BOeBGGM$:A>
 	
 VW
 	
% Q @;G "<s'   G
GGGG8
GGc           
         |syg }|j                  d       |j                  d       |D cg c]
  }|d   d    }}|D cg c]
  }|d   d    }}t        j                  |      }|j                  d      |j                  d      |j                  d	      |j                  d
      d}|j                  d|d       |j                  d|        |j                  d       |j                  d       |j                  d       |D ]b  }|d   }	|d   }
|
d   }|j                  d|	 d| d|
d   dd       |j                  d|
d   dd       |j                  d|
d   dd       d dj	                  |      S c c}w c c}w )z*Generate a summary of overfitting analysisz"No walk forward periods to analyzeu&   🎯 WALK FORWARD OVERFITTING ANALYSIS2==================================================r  r  r  r  r  r  r  )r  r  r  r  zAverage Overfitting Score: rw  zRisk Level Distribution: rz   zPERIOD-BY-PERIOD OVERFITTING:z------------------------------r  zPeriod rn   z risk (z score)z  P&L Decay: r  z+.1f%z  Win Rate Decay: r  rZ  )r   r  r#  countr   )r7   r  linesr  overfitting_scoresrisk_levelsavg_overfittingrisk_distributionperiodp_numanalysisrisks               r   r  z8UniversalBacktestingEngine._generate_overfitting_summary4  s   7=>X W^^QRa 678KL^^T[\qq/01IJ\\''"45$$U+#))*5%%f-#))*5	
 	2?32GHI01B0CDER 	45X 	ZF?+E45H45DLL75'D6BU9VWZ8[[bcdLL=2M)Nt(TTUVWLL-h7O.PQU-VVWXY	Z yy9 _\s   E>Fr  c                    g }|rd|v rdgS |j                  dd      }|dk\  r|j                  d       n(|dk\  r|j                  d       n|j                  d	       |j                  d
d      }||j                  dd      dz  k  r|j                  d       n|j                  d       |j                  dd      }|j                  dd      }|dkD  r|dk  r|j                  d       n(|dkD  r|j                  d       n|j                  d       |j                  dd      }|dk\  r|j                  d       |S |dk\  r|j                  d       |S |j                  d       |S )z7Generate recommendations based on walk forward analysisrO   z;Unable to generate recommendations due to insufficient datar  r   ry  uK   ✅ Excellent consistency - strategy shows strong out-of-sample performancer  uS   ⚠️ Moderate consistency - strategy performs in most periods but monitor closelyuC   ❌ Poor consistency - strategy fails in most out-of-sample periodsr  r  r!  u%   ✅ Good P&L stability across periodsuA   ⚠️ High P&L volatility - consider risk management adjustmentsr  r  r\  r   u1   ✅ Strong and consistent win rate across periodsuC   ⚠️ Decent win rate but inconsistent - may need parameter tuningu9   ❌ Weak win rate - strategy may need fundamental changesr  r  u9   ✅ Sufficient walk forward periods for reliable analysisr  u=   ⚠️ Moderate number of periods - consider adding more datauG   ❌ Insufficient periods - add more historical data for better analysis)r   r   )r7   r  r  profitabilityr  avg_win_rater  r  s           r   r  zAUniversalBacktestingEngine._generate_walk_forward_recommendations\  s   = 8QRR &))*FJB""#pqb ""#xy""#hi (++,=qA]../DaH3NN""#JK""#fg %(();Q?,001GK"!5!:""#VWB""#hi""#^_ &))/1=A""#^_  a""#bc  ""#lmr   c                 *   i }|dk(  rg dg dg dg dd}|S |dk(  rg dg d	g d
g dd}|S |dk(  rg dg dg dg dd}|S |dk(  rg dg dg dg dd}|S |dk(  rg dg dg dg dd}|S |dk(  rg dg dg dg dd}|S g dg dg d
d}|S ) z?Get default parameter ranges for optimization based on strategyr  )r  r  r6  )r  r  r  )r  r  r  )r=  re  r=  )short_ma_periodlong_ma_periodr2  r3  r  )r   r}  r  )rl  g      @r!  )r  r  r  )r  r<  r  )r  std_dev_multipliermax_holding_periodr2  r  )r6  r  r6  )r  r  r  )lookback_periodbreakout_thresholdconfirmation_periodr2  rG  )r     r6  )rp  r  r  )r  r   r6  )r  momentum_thresholdexit_thresholdr  r  )gffffff?rz  re  )r  r=  r  )r  range_multiplierr2  r3  r  )r}  Z   r  )r=  g{Gz?r=  )re  r!  re  )interest_diff_thresholdr  r2  position_size_pct)r2  r3  r  r   )r7   r<   r;   rangess       r   r   z8UniversalBacktestingEngine._get_default_parameter_ranges  s    --#-"-!3#5	Fb W ..%&5&0!5	FT I 00#.&:'0!3	FF ; 00#-&8"4&0	F8 - o- +$3!5#5	F*  m++=&2!3%4	F  "4#5&0F r   c                    d|j                          d|j                  dd      j                          d}|dk(  rx|dk(  rB|d|j                  d	d
       dz  }|d|j                  dd      j                          dz  }n)|dk(  r|d|j                  dd       dz  }n	|dk(  r|dz  }n|dz  }n|dk(  rX|j                  dd      }|dk(  r
|d| dz  }n|dk(  r
|d| dz  }n|d k(  r
|d!| dz  }n|d"k(  r
|d#| d$z  }n|d%| dz  }n|d&k(  rI|j                  d'd(      }|d)k(  r
|d*| dz  }nu|d"k(  r
|d#| d+z  }nf|d,k(  r
|d-| dz  }nW|d.| dz  }nM|d/k(  rH|j                  d'd0      }|d1k(  r
|d2| dz  }n'|d3k(  r
|d4| dz  }n|d5k(  r
|d6| dz  }n	|d%| dz  }|d7|j                  d8d9       d:z  }|S );z4Generate a concise equation summary for the strategyz**z Strategy:** r  r   z

r   player_points_overz!**Equation:** If Player_Points > points_threshold   z, WIN
z**Player:** player_nameUnknownrZ  team_win_streaku    **Equation:** If Win_Streak ≥ 
min_streakr  z, bet on team
home_away_performancez8**Equation:** Bet on home teams with >60% home win rate
z=**Equation:** Moneyline prediction with >55% win probability
rG   r  r  r  z%**Equation:** If SMA(5) > SMA(20) on z, BUY
r  zA**Equation:** Buy at 20th percentile, Sell at 80th percentile on r  u=   **Equation:** Enter on ±10% breakout beyond 20-day range on r  z(**Equation:** If Z-Score < -2 or > 2 on z, trade mean reversion
z!**Equation:** Trend following on rH   r  r2  rG  uA   **Equation:** If 5-day return > 2% AND volume > 1.5× average on z, mean reversion trade
rH  z'**Equation:** High volume breakouts on z"**Equation:** Momentum signals on rI   r  r  z+**Equation:** If earnings surprise > 5% on r  uA   **Equation:** If volume > 2× average AND price > 20-day high on r  u    **Equation:** Fade ±3% gaps on z**Stake:** $r  r  z per trade
)r   r  titler   )r7   r<   r=   r;   ry   r  r  s          r   r   z5UniversalBacktestingEngine._generate_equation_summary  s   v||~&mM4I4I#s4S4Y4Y4[3\\`aU? 44>z~~N`bd?e>ffmnn\*..	*R*X*X*Z)[[]^^"33=jnn\[\>]=^^mnn"99VW[\w>>&(3D 11B4&PP/1^_c^ddfgg"44Z[_Z``bcc"22EdVKcdd>tfBGGx^^He4F 22^_e^ffmnn"22EfXMeff"33DVHBOO?xrJJx^^Hf5F 33HPWXX"33^_e^ffmnn-/=fXRHH>vhbII\*..$"?!@MMr   )Nr   r  NNFNr:  );r   r   r   r   MAX_ITERATIONSr:   r   r   r   r   boolr   r5   r   r   r   r   r.  rY  r\  r  r  r  r  r  r   rP  rO  rK  rL  rM  rN  r  r  r  r  r  r  r  rJ  r  r   r  r   r   r   r   r   r   r   r   r  r  r  r  r  r  r   r   r   r   r   r(   r(   0   sn   C N
D U\;?:>/4)-o3 os oSRUX o!$o9<oNQo*.sCx.o *.c3ho )-	o
 $'o
 37sCx.obF
 F
P=
~_
D BF_
DJ _
 _
48J_
JNsTWx._
BF
T F
 F
e F
 F
RDJ 5 &?$t* ?4 ?TXY]T^ ?B
D
L2DJ 2 2d 2htDz 4 DJ 46$t* 6d 6tDz 6p~
@1DJ 1 1d 1f04: 0t 0T
 0d1T$Z 1 1$t* 1f0DJ 0 0d 0dB4: Bt BT
 BHe
N-DJ - -d -^/4: /t /T
 /b0DJ 0 0d 0d-T
 -D -T$Z -`44: 4t 4T
 4l7d 7T 7d4j 7tT$Z  $t* Dd4j $ 4PT: <B
$t* B
d B
tTWY\T\~ B
Hd4j 5 U 2Vd VRTR^R^ Vhk Vptuxz}u}p~ VpJ
d4j J
T#s(^ J
X8T#s(^ 8S 8UX 8tc
T$Z c
PT c
Y]^acf^fYg c
J)$4: )$# )$VStDz S3 SWZ S-1#s(^SRVWZ\_W_R`S,/S48cNSj$t* c RU )-c3h<@J,)
d4j )
T#s(^ )
V; ;$ ;SWX[]`X`Sa ;z$
T$Z $
DQTVYQYN $
L& T$Z & C & P+D +TRUY +Z73 7 7PTUXZ^U^P_ 7r3 3cSVh 3ad 3il 3r   r(   c                     ddl } t        | j                        dkD  rt               }| j                  d   }t        | j                        dkD  r"t	        j
                  | j                  d         ni }	 |dk(  rm|j                  |d   |d   |j                  di       |j                  d	      |j                  d
d      |j                  dd      |j                  d            }ndd| i}fdt        t	        j                   |                   yt               }t        d       t        d       t        d       |j                  dddddd      }|j                  d      rDddl } t        d|d    d        ddl } t        d!|d"   d#    d$       t        d%|d"   d&           nt        d'|j                  dd(              t        d)       |j                  d*d+d,dd-d      }|j                  d      rDddl } t        d.|d    d        ddl } t        d!|d"   d#    d$       t        d%|d"   d&           nt        d/|j                  dd(              t        d0       y# t        $ rE}t        t	        j                  dt        |      i              | j                  d       Y d}~yd}~ww xY w)1z:Main function for testing the universal backtesting enginer   Nr6  r#  r   r;   r<   r=   r\   r?   r   r@   r  rD   )rD   rO   zUnknown command: c                    t        | t        j                        rt        |       S t        | t        j                        rt        |       S t        | t        j                        r| j                         S t        | t              r*| j                         D ci c]  \  }}| |       c}}S t        | t              r| D cg c]
  } |       c}S | S c c}}w c c}w r:  )r   r  integerr   floatingr.  ndarraytolistr-  itemsr   )objkeyvalueitemconvert_numpy_typess       r   r6  z!main.<locals>.convert_numpy_types  s    c2::.s8OR[[1 :%RZZ0::<'T*NQiikZ
UC!4U!;;ZZT*BEF$/5FFJ	 [Fs   CCu&   🌍 Universal Backtesting Engine Testr   u$   
💱 Testing Forex Trend Following:rG   r  r  r  )r  r  r  )r?   rN   u   ✅ Forex backtest completed: rb   r  u   📊 Win Rate: rc   rD  r  u   💰 Total Profit: $rC  u   ❌ Forex backtest failed: zUnknown erroru   
₿ Testing Crypto Momentum:rH   rG  r2  )r  r  u   ✅ Crypto backtest completed: u   ❌ Crypto backtest failed: u1   
✅ Universal backtesting engine test completed!)r   r   argvr(   r  loadsr   r   r   dumpsr   r   r  )r   enginecommandr  r   r   result2r6  s          @r   mainr=    s   
388}q+-((1+,/MA,=CHHQK(2"	.(,,8$?+JJ|R0JJ{+JJ|R0JJ{G4"(**_"= -  "%6wi#@A $**089: ,-67h 	56$$-	 % 
 ::i  >vn?U>VV]^_y0A*0M/NaPQ(	):>)J(KLM/

7O0T/UVW 	./%%t,	 & 
 ;;y! ?@W?XX_`a	0B:0N/OqQR();N)K(LMN0Wo1V0WXYBCW  	$**gs1v./0CHHQKK	s   4B"I/ /	J=8;J88J=__main__)r   r  r   r  pandasr   numpyr  r   r   typingr   r   r   r   r	   r+   r   r   r   r!   r#   r&   r(   r=  r   r   r   r   <module>rB     s    
 
    ( 6 6  	y 	
	' 	
	- 	
	) 	
E3 E3NfUDn zF r   