FREQTRADE回测用trailing buy追踪买入代码无买单问题求助
Freqtrade追踪买入无买单问题排查
核心问题1:populate_indicators执行逻辑与预期不符
Freqtrade的populate_indicators是一次性传入完整的历史K线DataFrame,函数内的局部变量每次调用都会重置,你当前的写法存在两个致命错误:
- 只取了
dataframe['close'].tail(1)也就是最后一根K线的价格做判断,前面所有历史K线的trailbuy都被统一设为0,没有做逐行计算 trailing_buy_order_started这类状态变量是函数内的局部变量,每次执行函数都会被重置为False,所以if trailing_buy_order_started:的分支永远不会触发,永远不会生成买入信号
核心问题2:未确认入场信号配置
就算正确生成了trailbuy列的1值,还需要在populate_entry_trend函数中明确配置对应规则,否则Freqtrade不会识别这个信号作为买入触发条件。
修正方案
你需要在populate_indicators中逐行遍历K线,用变量保存跨K线的追踪状态,修正后的参考代码如下:
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # TRAILING BUY 配置参数 trailing_buy_offset = 0.005 trailing_buy_order_enabled = True # 初始化状态变量 trailing_buy_order_started = False trailing_buy_order_uplimit = 0.0 trailing_buy_order_downlimit = 0.0 # 初始化trailbuy列全为0 dataframe['trailbuy'] = 0 # 逐行遍历每一根K线计算信号 for i in range(len(dataframe)): current_price = dataframe['close'].iloc[i] if trailing_buy_order_enabled: if trailing_buy_order_started: if current_price < trailing_buy_order_downlimit: # 价格继续下跌,更新追踪上下限 trailing_buy_order_uplimit = current_price * (1 + trailing_buy_offset) trailing_buy_order_downlimit = current_price elif current_price >= trailing_buy_order_uplimit: # 价格反弹触发买入条件 dataframe.loc[i, 'trailbuy'] = 1 trailing_buy_order_started = False else: # 初始化追踪状态 trailing_buy_order_started = True trailing_buy_order_uplimit = current_price * (1 + trailing_buy_offset) trailing_buy_order_downlimit = current_price return dataframe # 补充populate_entry_trend配置示例 def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ (dataframe['trailbuy'] == 1) & (dataframe['volume'] > 0), # 额外加成交量过滤避免无交易K线触发 'enter_long' ] = 1 return dataframe
额外注意事项
- 逐行遍历的方式在K线量很大的时候运行效率会偏低,如果你需要优化性能,可以改用pandas的滚动窗口、shift函数向量化实现相同逻辑
- 回测时可以先输出
dataframe[['date','close','trailbuy']]查看trailbuy列是否有1值,确认信号生成正常后再跑完整回测
内容的提问来源于stack exchange,提问作者Jacques Buys
相关产品推荐
相关产品推荐

