""" strategy/mtf.py ─────────────── Multi-timeframe (MTF) structure merging. Merges a higher-timeframe (HTF) market_structure column onto a lower-timeframe (LTF) DataFrame with strict no-lookahead-bias: At LTF candle timestamp T, only the most recent HTF candle that CLOSED at or before T is used (merge_asof direction='backward'). This means: - 1h signal at 14:00 gets the 4h structure from the 12:00 4h candle (the 16:00 4h candle hasn't closed yet — not used) - 4h signal at 20:00 gets the 1d structure from yesterday's daily close (today's daily candle is still open — not used) """ import pandas as pd def merge_htf_structure(ltf_df: pd.DataFrame, htf_df: pd.DataFrame) -> pd.DataFrame: """ Attach the HTF market_structure to every LTF candle. Parameters ---------- ltf_df : DataFrame with DatetimeIndex — the signal timeframe htf_df : DataFrame with DatetimeIndex — the higher timeframe, must already have a 'market_structure' column Returns ------- ltf_df with an added 'htf_structure' column ('bullish'|'bearish'|'neutral') """ htf_col = htf_df[['market_structure']].copy() htf_col = htf_col.rename(columns={'market_structure': 'htf_structure'}) htf_col = htf_col.reset_index() # timestamp becomes a column ltf_reset = ltf_df.reset_index() merged = pd.merge_asof( ltf_reset, htf_col, on='timestamp', direction='backward', # never look forward ) merged = merged.set_index('timestamp') merged['htf_structure'] = merged['htf_structure'].fillna('neutral') return merged