Riy777 commited on
Commit
1245491
·
verified ·
1 Parent(s): 6649776

Update backtest_engine.py

Browse files
Files changed (1) hide show
  1. backtest_engine.py +9 -4
backtest_engine.py CHANGED
@@ -1,5 +1,5 @@
1
  # ============================================================
2
- # 🧪 backtest_engine.py (V135.0 - GEM-Architect: Feature Parity + Full Diagnostics)
3
  # ============================================================
4
 
5
  import asyncio
@@ -46,7 +46,6 @@ def _z_roll(x, w=500):
46
  return ((x - r) / s).fillna(0)
47
 
48
  def _revive_score_distribution(scores):
49
- """Normalize flattened scores to 0-1 range if they are compressed"""
50
  scores = np.array(scores, dtype=np.float32)
51
  if len(scores) < 10: return scores
52
  std = np.std(scores)
@@ -84,7 +83,7 @@ class HeavyDutyBacktester:
84
  self.force_end_date = None
85
 
86
  if not os.path.exists(CACHE_DIR): os.makedirs(CACHE_DIR)
87
- print(f"🧪 [Backtest V135.0] Feature Parity + Full Diagnostics + Speed.")
88
 
89
  def set_date_range(self, start_str, end_str):
90
  self.force_start_date = start_str
@@ -155,11 +154,15 @@ class HeavyDutyBacktester:
155
  if adx is not None: df['ADX'] = adx.iloc[:, 0].fillna(0)
156
  else: df['ADX'] = 0.0
157
 
 
158
  for p in [9, 21, 50, 200]:
159
  ema = ta.ema(df['close'], length=p)
160
  df[f'EMA_{p}_dist'] = ((df['close'] / ema) - 1).fillna(0)
161
  df[f'ema{p}'] = ema
162
 
 
 
 
163
  bb = ta.bbands(df['close'], length=20, std=2.0)
164
  if bb is not None:
165
  df['BB_w'] = ((bb.iloc[:, 2] - bb.iloc[:, 0]) / bb.iloc[:, 1]).fillna(0)
@@ -228,7 +231,6 @@ class HeavyDutyBacktester:
228
  rv_gk = ((np.log(df['high'] / df['low'])**2) / 2) - ((2 * np.log(2) - 1) * (np.log(df['close'] / df['open'])**2))
229
  df['rv_gk'] = _z_roll(rv_gk)
230
 
231
- # L_Score approximation
232
  df['L_score'] = (df['vol_zscore_50'] - df['amihud'] - df['roll_spread'] - df['rv_gk'].abs() - df['vwap_dev'].abs() + df['ofi']).fillna(0)
233
 
234
  # ---------------------------------------------------------
@@ -246,6 +248,8 @@ class HeavyDutyBacktester:
246
  roll_min = df['low'].rolling(50).min()
247
  diff = (roll_max - roll_min).replace(0, 1e-9)
248
  df['fib_pos'] = ((df['close'] - roll_min) / diff).fillna(0.5)
 
 
249
  df['trend_slope'] = ((df['ema20'] - df['ema20'].shift(5)) / df['ema20'].shift(5)).fillna(0)
250
  df['volatility'] = (df['atr'] / df['close']).fillna(0)
251
 
@@ -481,6 +485,7 @@ class HeavyDutyBacktester:
481
  l2_arr = np.full(240, 0.7)
482
  tgt_arr = np.full(240, 3.0)
483
 
 
484
  X_H = np.column_stack([
485
  sl_st[:,0], sl_st[:,1], sl_st[:,2], sl_st[:,3], sl_st[:,4],
486
  zeros, atr_pct, norm_pnl, max_pnl_r,
 
1
  # ============================================================
2
+ # 🧪 backtest_engine.py (V135.1 - GEM-Architect: EMA20 Fix)
3
  # ============================================================
4
 
5
  import asyncio
 
46
  return ((x - r) / s).fillna(0)
47
 
48
  def _revive_score_distribution(scores):
 
49
  scores = np.array(scores, dtype=np.float32)
50
  if len(scores) < 10: return scores
51
  std = np.std(scores)
 
83
  self.force_end_date = None
84
 
85
  if not os.path.exists(CACHE_DIR): os.makedirs(CACHE_DIR)
86
+ print(f"🧪 [Backtest V135.1] Feature Parity + Full Diagnostics + Speed.")
87
 
88
  def set_date_range(self, start_str, end_str):
89
  self.force_start_date = start_str
 
154
  if adx is not None: df['ADX'] = adx.iloc[:, 0].fillna(0)
155
  else: df['ADX'] = 0.0
156
 
157
+ # Titan uses 9, 21, 50, 200
158
  for p in [9, 21, 50, 200]:
159
  ema = ta.ema(df['close'], length=p)
160
  df[f'EMA_{p}_dist'] = ((df['close'] / ema) - 1).fillna(0)
161
  df[f'ema{p}'] = ema
162
 
163
+ # ✅ [GEM-FIX] Explicitly calculate EMA20 for Legacy models
164
+ df['ema20'] = ta.ema(df['close'], length=20).fillna(df['close'])
165
+
166
  bb = ta.bbands(df['close'], length=20, std=2.0)
167
  if bb is not None:
168
  df['BB_w'] = ((bb.iloc[:, 2] - bb.iloc[:, 0]) / bb.iloc[:, 1]).fillna(0)
 
231
  rv_gk = ((np.log(df['high'] / df['low'])**2) / 2) - ((2 * np.log(2) - 1) * (np.log(df['close'] / df['open'])**2))
232
  df['rv_gk'] = _z_roll(rv_gk)
233
 
 
234
  df['L_score'] = (df['vol_zscore_50'] - df['amihud'] - df['roll_spread'] - df['rv_gk'].abs() - df['vwap_dev'].abs() + df['ofi']).fillna(0)
235
 
236
  # ---------------------------------------------------------
 
248
  roll_min = df['low'].rolling(50).min()
249
  diff = (roll_max - roll_min).replace(0, 1e-9)
250
  df['fib_pos'] = ((df['close'] - roll_min) / diff).fillna(0.5)
251
+
252
+ # ✅ Now 'ema20' exists!
253
  df['trend_slope'] = ((df['ema20'] - df['ema20'].shift(5)) / df['ema20'].shift(5)).fillna(0)
254
  df['volatility'] = (df['atr'] / df['close']).fillna(0)
255
 
 
485
  l2_arr = np.full(240, 0.7)
486
  tgt_arr = np.full(240, 3.0)
487
 
488
+ # [rsi1, rsi5, rsi15, bb, vol, dist_ema, atr_p, norm, max, dists, time, entry, oracle, l2, target]
489
  X_H = np.column_stack([
490
  sl_st[:,0], sl_st[:,1], sl_st[:,2], sl_st[:,3], sl_st[:,4],
491
  zeros, atr_pct, norm_pnl, max_pnl_r,