Fix Ichimoku look-ahead bias: lag Senkou Spans by 26 bars
Senkou Span A and B are plotted 26 periods ahead of calculation. Comparing current price to iloc[-1] cloud means comparing against the cloud 26 bars in the future — a textbook look-ahead bias that inflates signal grades in backtests. Now uses iloc[-(kijun+1)] so the cloud boundaries reflect where the cloud actually is at the current candle. TK cross (tenkan_val/kijun_val) stays at iloc[-1] — that is a current condition, not a projected one. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -544,11 +544,17 @@ class TechnicalEngine:
|
||||
tenkan_val = tenkan.iloc[-1]
|
||||
kijun_val = kijun.iloc[-1]
|
||||
|
||||
# Current (unshifted) cloud
|
||||
sa = (tenkan.iloc[-1] + kijun.iloc[-1]) / 2
|
||||
# Senkou Spans are plotted 26 bars ahead of their calculation date, so
|
||||
# the cloud boundaries at the *current* bar are the values computed 26
|
||||
# bars ago. Using iloc[-1] would compare price to the future cloud
|
||||
# (look-ahead bias). iloc[-27] gives the correctly lagged cloud.
|
||||
lag = c.ichimoku_kijun # 26 by default
|
||||
sb_raw = (high.rolling(c.ichimoku_senkou_b).max() +
|
||||
low.rolling(c.ichimoku_senkou_b).min()) / 2
|
||||
sb = sb_raw.iloc[-1]
|
||||
if len(sb_raw) < lag + 1:
|
||||
return
|
||||
sa = (tenkan.iloc[-(lag + 1)] + kijun.iloc[-(lag + 1)]) / 2
|
||||
sb = sb_raw.iloc[-(lag + 1)]
|
||||
|
||||
if pd.isna(sa) or pd.isna(sb) or pd.isna(tenkan_val) or pd.isna(kijun_val):
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user