4.9 KiB
4.9 KiB
#交易 #量化交易 #策略研究 #freqtrade #DeepSeek
在 Freqtrade 策略中实现多时间框架指标计算(如 5 分钟主框架下计算 1 小时 ADX)需通过 K 线数据重采样(Resample) 实现。以下是具体方法和注意事项:
一、实现原理
- 默认时间框架
populate_indicators()中dataframe默认使用配置文件config.json的timeframe(如5m),所有计算基于此周期1,3。 - 多时间框架需求
若需计算更高周期指标(如 1 小时 ADX),需将原始数据重采样为目标周期(1h),再计算指标,最后对齐到原始时间戳6。
二、实现步骤(代码示例)
以下是在 5 分钟策略中计算 1 小时 ADX 的完整代码:
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# 1. 复制 DataFrame 避免污染原始数据
df = dataframe.copy()
# 2. 重采样为 1 小时数据 (聚合规则)
resample_rule = '1H'
df_resampled = df.resample(
resample_rule,
on='date', # 时间列
closed='right', # 右边界闭合
label='right' # 时间标签取右边界
).agg({
'open': 'first',
'high': 'max',
'low': 'min',
'close': 'last',
'volume': 'sum'
}).dropna()
# 3. 在重采样数据上计算 1 小时 ADX
df_resampled['adx_1h'] = ta.ADX(
df_resampled,
timeperiod=14 # ADX 周期
)
# 4. 将 1 小时 ADX 合并回原始 5 分钟数据
# 注意:使用前向填充 (ffill) 避免未来函数
dataframe['adx_1h'] = df_resampled['adx_1h'].reindex(
df.index,
method='ffill' # 用上一个有效的小时值填充
)
# 5. 可选:删除中间列避免内存占用
dataframe.drop(columns=['adx_1h_temp'], inplace=True, errors='ignore')
return dataframe
三、关键注意事项
-
避免未来函数
- **必须用
ffill而非bfill**:bfill会使用未来数据,导致回测失真6。 - 滞后处理:1 小时 ADX 在 5 分钟数据中需在整点后生效(如 10:00 的 ADX 在 10:05 才能使用)。
- **必须用
-
重采样规则
参数 值 说明 closedright确保当前 K 线数据属于前一个小时的统计区间,避免未来信息泄露 labelright时间戳标记为小时结束点(如 10:00 标签包含 09:05-10:00 的数据) volumesum成交量按小时累加 high/lowmax/min价格取区间极值 -
性能优化
- 仅重采样必要列:减少
agg()中不必要的列(如不用的trades列)6。 - 禁用未用指标:不在
populate_indicators中计算未参与信号逻辑的指标。
- 仅重采样必要列:减少
-
实盘适配
- 实时运行时,最后一根 K 线可能不完整(如当前小时未结束),需通过
dropna()排除3。
- 实时运行时,最后一根 K 线可能不完整(如当前小时未结束),需通过
四、替代方案:多时间框架数据注入
对高频策略,可通过配置文件直接加载多周期数据(需修改 config.json):
"dataframe_extra": {
"enabled": true,
"timeframes": ["1h", "4h"]
}
在策略中通过 self.dp 访问:
def populate_indicators(self, dataframe, metadata):
# 获取 1 小时数据
df_1h = self.dp.get_pair_dataframe(metadata["pair"], "1h")
dataframe["adx_1h"] = df_1h["adx"].reindex(dataframe.index, method="ffill")
return dataframe
优点:避免重复计算,适合高频策略4,5。
缺点:需提前下载多周期数据,配置文件更复杂。
五、典型错误及规避
-
未来函数陷阱
# 错误!直接合并会导致未来数据 dataframe['adx_1h'] = df_resampled['adx_1h'] # 未对齐时间戳修正:必须用
reindex(..., method='ffill')。 -
边界处理错误
# 错误!left 边界会导致当前小时数据污染 df_resampled = df.resample(..., closed='left', label='left')修正:始终用
closed='right', label='right'。
六、总结建议
- 震荡策略:优先使用
resample动态计算(节省数据下载时间)。 - 趋势策略:在
config.json中预加载多周期数据(减少实时计算负载)。 - 关键检查点:
✅ 验证回测时是否出现NaN(需dropna()或ffill)
✅ 对比实盘/回测中 1 小时 ADX 的值是否一致
✅ 监控策略内存占用(多周期数据易导致 OOM)
进阶参考:TA-Lib 的多周期协同策略案例可参考6中的 多周期RSI策略 实现。