首页
/ Freqtrade Orderflow 订单流数据分析实战:公开成交数据配置、下载与策略列使用指南

Freqtrade Orderflow 订单流数据分析实战:公开成交数据配置、下载与策略列使用指南

2026-09-06 23:35:13作者:平淮齐Percy

本文基于 Freqtrade 官方文档 docs/advanced-orderflow.md 展开,讲解如何利用交易所公开逐笔成交数据(public trades)在回测与实盘中做订单流(orderflow)分析:如何开启 use_public_trades、如何配置 orderflow 参数、如何用 --dl-trades 下载历史成交数据、策略 dataframe 中新增的 11 个订单流列各代表什么,以及 footprint 图表(成交量分布)与失衡(imbalances)检测的底层算法。读完后你可以独立搭建一套基于买卖盘口不平衡、Delta 与堆叠失衡的订单流指标策略。

功能定位与适用限制

Freqtrade 的 orderflow 功能允许你把交易所的逐笔公开成交记录(public trades)聚合到每一根 K 线上,从而在策略中分析订单流动态。官方文档将其明确标注为实验性(beta)特性,使用前后需要注意三点限制:

  • 功能处于 beta 阶段:未来版本中配置项和列结构可能发生变化,遇到问题应向官方仓库反馈;
  • 尚未与 FreqAI 测试组合使用:把 orderflow 和 FreqAI 两个功能叠加目前不在支持范围内;
  • 性能开销显著:orderflow 需要原始逐笔成交数据,数据量远大于 OHLCV。首次启动时 Freqtrade 需要下载覆盖最近若干根 K 线的全部成交记录,导致启动变慢;开启后内存占用也会明显上升,需要预留足够的计算资源。

从源码结构看,该功能的所有计算集中在 freqtrade/data/converter/orderflow.py,新增列的完整清单定义在 freqtrade/constants.pyORDERFLOW_ADDED_COLUMNS 常量中(tradesorderflowimbalancesstacked_imbalances_bidstacked_imbalances_askmax_deltamin_deltabidaskdeltatotal_trades),与文档描述一一对应。

开启功能:在 exchange 段启用 use_public_trades

第一步是在 config.jsonexchange 段中将 use_public_trades 设为 true

"exchange": {
   ...
   "use_public_trades": true,
}

这一步不是"可选开关"那么简单。在配置校验层 freqtrade/configuration/config_validation.py 中,_validate_orderflow 会检查:一旦 exchange.use_public_tradestrue,而配置中缺少顶层 orderflow,会直接抛出 ConfigurationError("Orderflow is a required configuration key when using public trades.")。也就是说,开启公开成交数据后,orderflow 配置段是必填项,两个配置必须同时存在。

策略侧的入口在 freqtrade/strategy/interface.py_if_enabled_populate_trades 方法:当检测到 exchange.use_public_trades 为真时,它会以当前 dataframe 的日期范围构造 timerange,通过 self.dp.trades(...) 从 DataProvider 取成交记录,再调用 populate_dataframe_with_trades 把订单流列填充进你策略使用的 dataframe,并按交易对缓存已计算好的分组结果。由于该填充发生在 advise_indicators 阶段之前,你的 populate_indicators 中可以直接读取这些新列。

配置 orderflow 处理参数

orderflow 段共有 6 个参数,完整配置示例如下(来自官方文档):

"orderflow": {
    "cache_size": 1000,
    "max_candles": 1500,
    "scale": 0.5,
    "stacked_imbalance_range": 3, //  needs at least this amount of imbalance next to each other
    "imbalance_volume": 1, //  filters out below
    "imbalance_ratio": 3 //  filters out ratio lower than
}

各参数含义、schema 约束与源码中的作用如下表:

参数 作用 schema 约束(config_schema.py 源码中的行为
cache_size 多少根历史 orderflow K 线被缓存,而不是每根新 K 线重新计算 数值,最小 1,默认 1500 计算完成后取 dataframe.tail(cache_size) 整体缓存;下一轮若某根 K 线命中缓存则直接复制结果,跳过全部计算
max_candles 只为最近多少根 K 线获取并聚合成交数据 数值,最小 1,默认 1500 策略侧仅聚合晚于 dataframe.tail(max_candles).date.iat[0] 的成交;交易侧 needed_candle_for_trades_ms 用它决定从交易所拉取多少根 K 线量的成交
scale footprint 图表的价格分箱(bin)宽度 数值,最小 0.0 成交价按 round(price / scale) * scale 取整到 scale 的整数倍后分箱聚合
stacked_imbalance_range 连续失衡价格层的最小个数 数值,最小 0 用于 stacked_imbalance 函数,识别"堆叠失衡"区间的起始价格
imbalance_volume 失衡判定的最低总量阈值 数值,最小 0 价格层总成交量低于该值时,失衡直接判为 False
imbalance_ratio 失衡判定所需的 bid/ask 成交量比值下限 数值,最小 0.0 bid 失衡要求本层 bid 量 / 上一层 ask 量 > 该比值

在 schema 中,max_candlesscale 属于必填字段(required 数组),而 cache_size 缺省为 1500。注意 scale 是绝对价格单位而非百分比:例如 scale: 0.5 表示每 0.5 个价格单位聚合成一个价格层,选择时应与所交易品种的典型价差量级匹配,分箱过粗会丢失细节,过细则单箱成交量被摊薄,难以触发失衡阈值。

为回测下载历史成交数据

回测需要历史逐笔成交数据,通过 freqtrade download-data 命令的 --dl-trades 标志下载(定义于 freqtrade/commands/cli_options.pydownload_trades 选项,帮助文本为 "Download trades instead of OHLCV data")。官方文档给出的示例:

freqtrade download-data -p BTC/USDT:USDT --timerange 20230101- --trading-mode futures --timeframes 5m --dl-trades

该命令的执行链是:download-data 进入数据下载流程后,逐笔拉取由 freqtrade/data/history/history_utils.py 驱动——先读取本地已有成交文件,再调用 freqtrade/exchange/exchange.pyget_historic_trades(内部按交易对、since/until 时间窗,支持 time 或 id 两种游标分页方式)增量抓取新成交,去重后落盘。--trading-mode futures 决定成交数据归属现货还是合约交易模式,--timeframes 指定 K 线周期,因为 orderflow 列是按 K 线周期聚合的。

数据可用性提醒:并非所有交易所都提供历史公开成交数据。对于不支持的交易对/交易所,使用 --dl-trades 启动下载时 Freqtrade 会打印警告。此外同一目录下的 --convert 标志可以把已下载的成交数据转换为 OHLCV(主要用于没有历史 OHLCV 的交易所),这属于 download-data 文档 的范畴,与 orderflow 分析相互独立但共用同一份成交文件。

策略中自动生成的订单流列

启用后,populate_dataframe_with_tradesfreqtrade/data/converter/orderflow.py)会为 dataframe 的每根 K 线填充以下列(文档列表 + 源码常量一致):

dataframe["trades"]                 # 本根 K 线内每笔成交的明细列表
dataframe["orderflow"]              # footprint 图表 dict(见下文结构)
dataframe["imbalances"]             # 本根 K 线的买卖盘失衡 dict
dataframe["bid"]                    # 本根 K 线 bid 方向总成交量
dataframe["ask"]                    # 本根 K 线 ask 方向总成交量
dataframe["delta"]                  # ask 与 bid 成交量之差
dataframe["min_delta"]              # K 线内逐笔 delta 累计和的最小值
dataframe["max_delta"]              # K 线内逐笔 delta 累计和的最大值
dataframe["total_trades"]           # 成交笔数
dataframe["stacked_imbalances_bid"] # bid 侧堆叠失衡区间起始价格列表
dataframe["stacked_imbalances_ask"] # ask 侧堆叠失衡区间起始价格列表

在源码中可以确认这些列的计算细节:

  • bid/ask 归属约定side == "sell" 的成交计入 bid 方向,side == "buy" 的成交计入 ask 方向——即以主动卖盘(砸向买盘)为 bid 量、主动买盘(吃掉卖盘)为 ask 量,delta = ask - bid,正值表示主动买盘占优;
  • min/max_delta:对 K 线内逐笔 delta 做累计和(cumsum),取该曲线的最大值与最小值,反映 K 线内部主动买卖力量的最强峰值;
  • 计算窗口:只处理晚于最近 max_candles 根 K 线起始时间的成交,更早的历史不会参与聚合,这正是内存开销可控的关键;
  • 异常处理:整个填充过程若抛错会被包装为 DependencyException 并记录日志,而不是静默产出空列。

一个最小可用的策略集成示例(文档原版):

def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    # Calculating cumulative delta
    dataframe["cum_delta"] = cumulative_delta(dataframe["delta"])
    # Accessing total trades
    total_trades = dataframe["total_trades"]
    ...

def cumulative_delta(delta: Series):
    cumdelta = delta.cumsum()
    return cumdelta

累计 delta(cumulative delta)是订单流分析中最常用的基础指标:对 delta 列求累计和即可得到资金主动流向的累积曲线,可配合均线或背离逻辑构建信号。

Footprint 图表:dataframe["orderflow"]

orderflow 列保存的是每根 K 线的 footprint(足迹图):按 scale 分箱后,各价格层上主动买/卖成交量与笔数的分布。其结构为 {价格: 统计dict}

{
    "price": {
        "bid_amount": 0.0,
        "ask_amount": 0.0,
        "bid": 0,
        "ask": 0,
        "delta": 0.0,
        "total_volume": 0.0,
        "total_trades": 0
    }
}

各字段含义:

字段 含义
key(价格) 价格层,按 scale 间隔分箱(round(price/scale)*scale
bid_amount 该价格层上买方向(side=sell 主动卖盘)总成交量
ask_amount 该价格层上卖方向(side=buy 主动买盘)总成交量
bid / ask 该价格层的买/卖订单笔数
delta 该价格层 ask_amount 与 bid_amount 之差
total_volume 该价格层总量(ask_amount + bid_amount)
total_trades 该价格层总笔数(ask + bid)

对应实现是 freqtrade/data/converter/orderflow.py 中的 trades_to_volumeprofile_with_total_delta_bid_ask:先用 np.where 把 side 映射为 bid/ask 的量与笔数,把成交价取整到 scale 的倍数,再 groupby("price").sum() 完成分箱聚合。footprint 分布可以让你直接看到单根 K 线内资金在哪些价位激烈换手,例如高价位出现集中的 ask_amount 峰通常意味着买方在该位置持续吃单上攻。

原始成交明细:dataframe["trades"]

trades 列是一个列表,保存本根 K 线时间窗内发生的所有逐笔成交,用于比列级指标更细粒度的自定义分析。每条记录为 dict,包含(文档列出):

  • timestamp:成交时间戳(毫秒);
  • date:成交日期;
  • price:成交价格;
  • amount:成交数量;
  • side:买或卖;
  • id:交易所唯一成交标识;
  • cost:成交总价值(price × amount)。

从源码结构看,存储进 trades 列的记录来源于 freqtrade/constants.py 定义的 DEFAULT_TRADES_COLUMNStimestampidtypesidepriceamountcost)外加 date 列,因此在实际使用中每条记录还会出现 type(limit/market 等订单类型)字段,聚合时用于剔除的 candle_start/candle_end 辅助列不会写入该列。

失衡检测:imbalancesstacked_imbalances

imbalances 列提供每根 K 线的盘口失衡信息:当某一价格层的 ask 与 bid 成交量出现显著差异时即构成失衡。其结构为 {价格: {bid_imbalance: 布尔, ask_imbalance: 布尔}}

{
    "price": {
        "bid_imbalance": false,
        "ask_imbalance": false
    }
}

算法实现(trades_orderflow_to_imbalances)值得逐行理解,因为这里采用的是斜向对比而非同层对比:

  1. ask = df.ask.shift(-1)——把 ask 列向下平移一格,即用价格层 N 的 bid 量价格层 N+1 的 ask 量比较(footprint 分析中标准的对角比较);
  2. bid_imbalance = (bid / ask_above) > imbalance_ratio:本层 bid 量相对上一层 ask 量比值超过 imbalance_ratio 时判定为 bid 失衡;ask_imbalance 对称处理;
  3. 再按 total_volume < imbalance_volume 把低量级的价格层强制置 False,避免小盘噪音触发失衡。

stacked_imbalances_bid / stacked_imbalances_ask 列则进一步做堆叠失衡识别(stacked_imbalance 函数):把布尔失衡序列分组统计连续 True 段,凡是连续失衡层数达到 stacked_imbalance_range 的区间,就返回该区间起始价格层。多个这样的起始价列表即构成"堆叠失衡区"——在实盘语义上,连续多层买/卖盘压倒性占优的位置,常被视为短期支撑/阻力或流动性真空边界。注意列表记录的是"失衡区间的开始价格"而非全部失衡价格,策略中若需要区间端点,可用 scale 反推。

缓存机制与性能调优

orderflow 的计算成本决定了两个参数直接决定运行效率:

  • cache_sizepopulate_dataframe_with_trades 每次运行结束后保存 dataframe.tail(cache_size) 的副本作为缓存;下一根新 K 线到来时,凡是 date 命中缓存的 K 线,其 11 个订单流列直接从缓存复制,不再重算 footprint 和失衡。cache_size 越大,重算越少、内存越高——文档示例取 1000,schema 默认 1500,可按回测时长与内存权衡;
  • max_candles:双重作用——策略侧只聚合最近 max_candles 根 K 线的成交;交易侧 freqtrade/exchange/exchange.pyneeded_candle_for_trades_msmin(max_candles, 单次可拉取 K 线数) 决定从交易所预取的成交时间窗(并额外多取 1 根 K 线作为安全边界)。_now_is_time_to_refresh_trades 则在新 K 线形成后触发增量拉取,只抓自上一笔缓存成交 id 之后的新记录并合并去重,因此实盘运行期每个周期的增量成本很低,大头在首次冷启动

回测时如果观察到启动阶段耗时集中,可以优先调小 max_candles(以覆盖策略回看窗口为准);如果实盘中每周期延迟偏高,再考虑增大 cache_size

仓库中可深入阅读的参考文件

小结

Freqtrade 的 orderflow 功能把"逐笔成交 → K 线级订单流指标"这条链路完整地工程化了:--dl-trades 负责数据落盘,use_public_trades + orderflow 配置负责开关与分箱/失衡阈值,populate_dataframe_with_trades 负责带缓存的聚合计算,最终在 populate_indicators 前交付 deltacum_delta、footprint、imbalances 与堆叠失衡区等可直接建模的列。作为 beta 特性,建议先在回测环境验证信号逻辑与资源消耗,再谨慎投入实盘,并注意它当前不与 FreqAI 组合使用。

登录后查看全文
热门项目推荐
相关项目推荐