Look-ahead bias occurs when a backtest uses information unavailable on its simulated decision date, making a signal appear stronger or more prescient than it could have been in real time. section 12.4 section 11.1.1
Prevent it by enforcing point-in-time access: filter each data series to values published by the decision date, accounting for its publication lag. Daily market indicators may have minimal delay; macroeconomic releases can arrive days or weeks later. section 12.4
Listing 12.5 Point-in-time macro extraction
def get_available_macro(target_date, macro_data):
"""Extract macro data respecting publication lags."""
target_dt = datetime.strptime(target_date, '%Y-%m-%d')
lags = {
'VIXCLS': 1, 'DGS10': 1, 'DGS2': 1, 'FEDFUNDS': 1, #1
'M2SL': 45, 'CPIAUCSL': 14, 'UNRATE': 7, 'UMCSENT': 14 #2
}
result = {}
for code, lag in lags.items():
if code in macro_data:
cutoff = target_dt - timedelta(days=lag)
filtered = macro_data[code][macro_data[code].index <= cutoff] #3
if len(filtered) > 0:
result[code] = round(filtered.iloc[-1], 2)
if 'DGS10' in result and 'DGS2' in result:
result['YIELD_CURVE'] = round(result['DGS10'] - result['DGS2'], 2) #4
return result
The extraction function applies per-series lags and excludes observations newer than each decision date’s cutoff. section 12.4
An apparently prescient LLM signal
An investment LLM may echo a post-event market narrative absorbed during pretraining, making its signal seem predictive. Retrieval grounding can reduce this temporal leakage but cannot eliminate information embedded in model weights. section 11.1.1
