策略基础与创建

策略基础与创建

要创建一个新的交易策略,可以使用 new-strategy 命令。运行 freqtrade new-strategy --strategy MyNewStrategy 会在 user_data/strategies/ 目录下生成一个名为 MyNewStrategy.py 的 Python 文件模板。该模板包含策略类的基本结构,如 populate_indicatorspopulate_entry_trendpopulate_exit_trend 等必需函数,以及注释说明每个函数的作用。你可以基于此模板编写自己的技术指标组合和交易逻辑,是开发自定义策略的起点。

在使用 freqtrade new-strategy 命令时,通过 -s--strategy 参数指定策略的名称。例如,运行 freqtrade new-strategy -s MyFirstStrategy 会在用户数据目录中创建一个名为 MyFirstStrategy.py 的策略文件。策略名称必须是有效的 Python 类名(通常使用大驼峰命名法),且不能与现有策略重复,否则会提示冲突。

Freqtrade 提供三种策略模板:minimalfulladvanced。默认使用 full 模板。

  • minimal 模板生成一个最简化的策略骨架,只包含必需的导入、类定义和最基本的 populate_indicatorsenter_longexit_long 方法,适合希望从零开始完全自定义的开发者。
  • full 模板包含完整的策略结构,附带多个常用技术指标(如 RSI、MACD、BBands)的示例计算逻辑和基于这些指标的买卖条件,适合初学者快速理解策略结构并进行修改。
  • advanced 模板在 full 的基础上增加了更复杂的逻辑,例如多时间框架分析、自定义止损逻辑、动态仓位管理等,适合有经验的开发者快速构建高级策略原型。

如果你在运行 freqtrade new-strategy 命令时没有指定 --template 参数,系统将默认使用 full 模板。这意味着生成的策略文件将包含一套完整的、经过精心设计的技术指标示例和买卖逻辑,适合大多数初学者和中级用户快速开始策略开发。该模板提供了良好的起点,你可以在其基础上删减或扩展功能,而无需从空白文件开始。

一个完整的Freqtrade策略文件包含以下核心部分:

  • OHLCV数据:来自交易所的蜡烛图数据(开盘价、最高价、最低价、收盘价、成交量)。
  • 指标计算:通过 populate_indicators() 方法添加技术指标,如RSI、MACD、布林带等。
  • 入场逻辑:在 populate_entry_trend() 中定义买入信号(enter_longenter_short),通常基于指标交叉或阈值条件。
  • 出场逻辑:在 populate_exit_trend() 中定义卖出信号(exit_longexit_short)。
  • 最小收益率(Minimal ROI):定义交易在不同时间点后必须达到的最低盈利百分比,强制提前平仓。
  • 止损设置:通过 stoploss 属性设置固定止损或追踪止损(trailing stoploss)。
  • 可选功能:包括定价调整(pricing)、仓位调整(position adjustment)以及自定义回调函数(custom functions)。

所有策略都必须返回完整的DataFrame,不能删除或修改原始的 open, high, low, close, volume 列,否则会导致策略失效。

INTERFACE_VERSION 是策略文件中定义的一个属性,用于指定该策略所兼容的Freqtrade策略接口版本。当前版本为3,也是默认值。如果未显式设置,系统会自动使用版本3。旧版策略可能设置为版本2,但未来版本的Freqtrade将要求所有策略必须明确声明为版本3,否则可能无法加载。因此,为了确保策略在未来版本中仍能正常运行,建议在策略文件顶部显式声明 INTERFACE_VERSION = 3,避免因版本不匹配导致的兼容性问题。

Freqtrade只使用已完成的蜡烛数据(即已收盘的K线)来生成交易信号,这是为了避免‘重绘’(repainting)问题。重绘是指策略在蜡烛未完成时使用部分数据做出决策,然后在蜡烛收盘后因新数据而改变信号,这在实盘中会导致策略表现与回测严重不符。例如,若策略在当前5分钟蜡烛的第3分钟就基于部分数据发出买入信号,但收盘时价格反转,该信号就无效了。Freqtrade通过只使用完整蜡烛确保信号的稳定性与可复现性,使回测结果更贴近实盘表现。因此,你无法在策略中访问当前未完成的蜡烛数据,所有分析都基于历史完整数据。

startup_candle_count 是策略中的一个属性,用于指定策略在计算稳定指标前所需的最少历史蜡烛数量。某些指标(如EMA100)需要大量历史数据才能收敛到稳定值,在初始阶段会产生NaN或错误值。如果未设置该属性,Freqtrade会使用所有可用数据,可能导致回测早期信号无效或策略在实盘中因数据不足而无法交易。

例如,若策略使用了EMA100(需要至少100根K线),但为了确保计算精确,你发现需要400根K线才能稳定,那么应设置 startup_candle_count = 400。这样,回测时Freqtrade会自动向前加载额外的400根K线用于指标计算,然后剔除这部分‘不稳定’数据,仅对有效时间段进行回测。在实盘中,该值也决定了Bot启动时需要下载多少历史数据。建议使用 recursive-analysis 命令辅助确定最优值,确保指标方差为0%。

在Freqtrade策略中,不能像普通Python变量那样直接对pandas Series进行布尔比较,例如 if dataframe['rsi'] > 30: 会导致错误,因为Series包含多个值,其真值是模糊的。正确的做法是使用pandas的向量化操作,例如:

dataframe.loc[(dataframe['rsi'] > 30), 'enter_long'] = 1

这会在所有满足条件的行中,将 enter_long 列设为1,表示买入信号。loc 方法允许你基于条件筛选行,并同时指定要修改的列。这种写法是向量化的,能高效处理整个数据集,而不是逐行循环,从而大幅提升性能。所有信号列(如 enter_long, exit_long)都必须以这种方式批量赋值,而不是使用循环或单行判断。

你可以在策略文件的 populate_indicators() 方法中添加自定义技术指标。该方法接收一个pandas DataFrame和元数据字典作为参数,并返回修改后的DataFrame。你只需使用技术指标库(如TA-Lib、pandas-ta)的函数,将计算结果赋值给DataFrame的新列即可。例如:

dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
dataframe['bb_lower'] = ta.BBANDS(dataframe, nbdevup=2, nbdevdn=2)['lowerband']

注意:只添加在 populate_entry_trend()populate_exit_trend() 或其他指标计算中实际使用的指标,避免添加无用指标以节省内存和计算资源。同时,必须始终返回完整的DataFrame,不得删除或修改原始的 open, high, low, close, volume 列。Freqtrade默认安装了TA-Lib、pandas-ta和technical三个技术库,你也可以安装其他库或编写自定义指标函数。

最小收益率(minimal_roi)是一个字典,键为交易开始后经过的分钟数,值为对应的最低盈利百分比。Freqtrade会在达到任一阈值时自动平仓。例如:

minimal_roi = {
    "0": 0.04,   # 盈利4%时立即退出
    "20": 0.02,  # 20分钟后盈利2%即可退出
    "30": 0.01,  # 30分钟后盈利1%即可退出
    "40": 0.0    # 40分钟后保本即可退出
}

这意味着,如果一笔交易在15分钟时盈利3%,它不会退出(因为未达到20分钟2%的阈值),但一旦满20分钟且盈利超过2%,就会自动平仓。你也可以设置为空字典 {} 来完全禁用此功能。为适应不同时间周期,可以使用 timeframe_to_minutes() 动态计算:

from freqtrade.exchange import timeframe_to_minutes

timeframe = "1d"
timeframe_mins = timeframe_to_minutes(timeframe)
minimal_roi = {
    str(timeframe_mins * 3): 0.02,  # 3根日线后退出,盈利2%
}

注意:ROI计算包含交易手续费,且时间基准是交易首次下单时间(trade.open_date),即使订单未立即成交也以此为准。

在策略中设置止损是保护资金的关键。你可以通过定义 stoploss 属性来设置固定止损比例,例如:

stoploss = -0.10  # 设置10%的止损

这表示当交易亏损达到10%时,系统会自动平仓。除了固定止损,你还可以使用追踪止损(trailing stoploss),它会随着价格上涨动态调整止损位,锁定利润。完整的止损配置(包括追踪止损参数)请参考官方的 stoploss.md 文档。重要的是,止损设置必须合理,过紧容易被市场噪音触发,过松则可能造成重大亏损。建议结合历史波动率和交易品种特性进行测试调整。

informative_pairs 是策略中的一个方法,用于指定额外的、非交易的参考数据对(如更高时间周期的K线)。例如,你的主策略运行在5分钟周期,但你想参考1小时或1天的RSI趋势,就可以通过 informative_pairs() 返回这些参考对:

def informative_pairs(self):
    return [
        ("ETH/USDT", "5m"),
        ("BTC/TUSD", "15m"),
        ("BTC/USDT", "1h")
    ]

这些对会被Freqtrade自动下载并缓存,其数据会合并到主策略的DataFrame中,列名自动添加时间周期后缀(如 rsi_1h)。这让你可以在5分钟策略中使用日线级别的趋势判断,提高信号质量。但要注意:这些对不会被交易,除非它们也出现在交易白名单中。为避免频繁请求交易所,应尽量减少列表长度,并优先使用更高时间周期而非多个低周期对。