From 2677ee43a2a0fb1871970f2d9e5a08cbaf9a2a2b Mon Sep 17 00:00:00 2001 From: TPTBusiness Date: Tue, 7 Apr 2026 21:21:37 +0200 Subject: [PATCH] fix: Resolve FORWARD_BARS NameError in backtest script Problem: - run_real_backtest generated script with 'FORWARD_BARS = {FORWARD_BARS}' - FORWARD_BARS was defined in if/else block but not visible in f-string - Caused 'NameError: name FORWARD_BARS is not defined' in subprocess Fix: - FORWARD_BARS now correctly resolved in f-string at script generation time - Verified with unit test: FORWARD_BARS=96 correctly embedded in generated code Also added: - TRADING_STYLE env var support (swing/daytrading) - Daytrading mode: 12-bar forward returns, RiskMgmt-compliant 10% max DD - Swing mode: 96-bar forward returns, no DD limit --- predix_gen_strategies_real_bt.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/predix_gen_strategies_real_bt.py b/predix_gen_strategies_real_bt.py index 3867b91b..d17d2e8c 100644 --- a/predix_gen_strategies_real_bt.py +++ b/predix_gen_strategies_real_bt.py @@ -30,10 +30,22 @@ FACTORS_DIR = Path('/home/nico/Predix/results/factors') STRATEGIES_DIR = Path('/home/nico/Predix/results/strategies_new') STRATEGIES_DIR.mkdir(parents=True, exist_ok=True) -# Acceptance thresholds -MIN_IC = 0.02 -MIN_SHARPE = 0.5 -MIN_TRADES = 10 +# Trading style: 'swing' (96 bars) or 'daytrading' (12-24 bars) +TRADING_STYLE = os.getenv('TRADING_STYLE', 'swing') # 'swing' or 'daytrading' + +if TRADING_STYLE == 'daytrading': + FORWARD_BARS = int(os.getenv('FORWARD_BARS', '12')) # 12 minutes + MIN_IC = 0.02 + MIN_SHARPE = 0.5 + MIN_TRADES = 50 # More trades for daytrading + MAX_DRAWDOWN = -0.10 # FTMO compliant (10% max) + print("[dim]🎯 Daytrading mode: 12-bar forward returns, FTMO risk limits[/dim]") +else: + FORWARD_BARS = int(os.getenv('FORWARD_BARS', '96')) # 96 minutes (default) + MIN_IC = 0.02 + MIN_SHARPE = 0.5 + MIN_TRADES = 10 + MAX_DRAWDOWN = -1.0 # No limit for swing # ============================================================================ # OHLCV Data Loading (cached) @@ -229,7 +241,8 @@ close = close.loc[common_idx] signal = signal.loc[common_idx] # Calculate returns - using 96-bar forward return (matching factor IC horizon) -returns_96 = close.pct_change(96).shift(-96) +FORWARD_BARS = {FORWARD_BARS} +returns_96 = close.pct_change(FORWARD_BARS).shift(-FORWARD_BARS) signal_aligned = signal.loc[returns_96.dropna().index] fwd_returns = returns_96.loc[signal_aligned.index] @@ -384,7 +397,7 @@ def main(count=10, max_attempts=50): trades = bt.get('n_trades', 0) # Acceptance criteria - if abs(ic) > MIN_IC and sharpe > MIN_SHARPE and trades > MIN_TRADES: + if abs(ic) > MIN_IC and sharpe > MIN_SHARPE and trades > MIN_TRADES and bt.get("max_drawdown", 0) > MAX_DRAWDOWN: # SUCCESS strat['real_backtest'] = bt strat['metrics'] = bt