概述
Backtrader 是一个 Python 事件驱动型回测框架,逐根 K 线处理数据,通过内置券商、订单管理与持仓跟踪来模拟真实执行。与向量化框架(vectorbt、pandas)不同,backtrader 一次沿历史推进一根 K 线,触发回调,从而可以实现依赖此前成交、部分成交和条件性括号单的复杂订单逻辑。
事件驱动 vs 向量化
资料给出的对比要点:
- 执行模型:backtrader 为逐根 K 线回调;vectorbt 为整体数组运算。
- 速度:backtrader 较慢(Python 循环);vectorbt 快(NumPy/Numba)。
- 订单类型:backtrader 支持市价、限价、止损、止损限价、括号单、OCO;vectorbt 原生仅支持市价。
- 真实度:backtrader 内置含手续费、滑点、保证金的券商;vectorbt 需手动建模滑点。
- 多时间框架:backtrader 原生 resampledata;vectorbt 需手动对齐。
适用场景:
需要 backtrader 的情形包括:括号单(入场 + 止损 + 止盈作为一个单元)、止损限价或移动止损订单、依赖订单状态的逻辑(首次成交后加仓、N 根 K 线内未成交则撤单)、多时间框架策略(日线信号、小时级执行)、真实的手续费与滑点建模。
需要 vectorbt 的情形包括:对上千种组合进行快速参数优化、无复杂订单管理的简单多空信号、快速原型与结果的统计分析。
核心概念
backtrader 有五个核心对象,通过事件循环交互:
-
Cerebro(引擎):中央协调器。向 Cerebro 添加策略、数据源、分析器和 Sizer,然后调用 run()。示例中演示了 addstrategy、adddata、setcash、setcommission、addanalyzer 等调用。
-
Strategy(你的逻辑):Strategy 子类包含全部交易逻辑。关键方法:init() 定义指标,回测开始前运行一次;next() 每根 K 线调用,在此下单;notify_order(order) 在订单状态变化时调用(submitted、accepted、completed、canceled、margin、expired);notify_trade(trade) 在交易开仓或平仓时调用,可在此获取盈亏。资料给出 EMA 交叉策略示例,包含 params 定义、bt.ind.EMA、bt.ind.CrossOver 以及在 next() 中的买卖逻辑。
-
Data Feed(数据源):提供 OHLCV 数据线。最常见的方式是从 pandas DataFrame 加载(bt.feeds.PandasData),也可用于 CSV(bt.feeds.GenericCSVData,可设置 dtformat、openinterest 等)。
-
Broker(券商):内置券商模拟订单执行,可配置现金、手续费与滑点。示例中包含 setcash、setcommission,以及 cheat-on-open(set_coo(True),在信号所在 K 线的开盘价执行,以避免前视偏差)。
-
Analyzers(分析器):回测完成后计算绩效指标。示例中配置了 SharpeRatio、DrawDown、TradeAnalyzer、Returns,并通过 strat.analyzers.<name>.get_analysis() 获取结果。
订单类型
资料列出 backtrader 支持的关键订单类型:
- 市价单:self.buy()、self.sell()、self.close()。
- 限价单:self.buy(exectype=bt.Order.Limit, price=95.0) 等。
- 止损单:价格达到止损位时触发市价单,如 self.sell(exectype=bt.Order.Stop, price=90.0)。
- 止损限价单:价格达到止损位时触发限价单,如 self.buy(exectype=bt.Order.StopLimit, price=100.0, plimit=101.0)。
- 括号单:入场 + 止损 + 止盈作为一个原子单元;止损成交则止盈取消(反之亦然)。示例使用 self.buy_bracket(price=..., stopprice=..., limitprice=..., exectype=..., stopexec=..., limitexec=...)。资料提示 ATR 止损的括号单模式见 references/strategy_patterns.md。
仓位管理(Sizers)
Sizer 决定每笔订单买卖多少单位。示例包含:
- 固定数量:bt.sizers.FixedSize, stake=100
- 组合百分比:bt.sizers.PercentSizer, percents=95
- 全部可用现金:bt.sizers.AllInSizer, percents=95
- 自定义 Sizer:通过继承 bt.Sizer 并实现 _getsizing(self, comminfo, cash, data, isbuy) 方法,示例演示了基于风险比例与 ATR 计算仓位的方式。
加密货币相关注意事项
资料专门列出加密货币场景的注意点:
- 24/7 市场:加密货币全天候交易。使用日线时没有需要跳过的周末;若分析特定时间窗口,可设置会话时间或 sessionstart/sessionend。
- 高手续费:Solana 上的 DEX 兑换通常每笔 0.25–0.30%;据此设置手续费,示例为 setcommission(commission=0.003),注释为每边 0.3%。
- 分数化下单:加密货币允许小数单位,backtrader 原生支持,无需特殊配置。
- 滑点:为更真实模拟,可启用 cheat-on-open 并添加滑点,如 set_coo(True) 与 set_slippage_perc(0.001)。
- 波动性数据:加密货币 OHLCV 数据常有极端影线,建议使用基于 ATR 的止损而非固定百分比止损。
多时间框架
backtrader 可在单个策略内把数据重采样到多个时间框架,例如向 Cerebro 添加 1 小时数据后用 cerebro.resampledata(data_1h, timeframe=bt.TimeFrame.Days, compression=1) 重采样为日线,在策略中通过 self.datas[0]、self.datas[1] 分别访问小时线与日线指标。
自定义指标
可通过继承 bt.Indicator 定义,使用 lines 声明输出线(如 spread、zscore),在 init 中计算并赋值给 self.lines。资料给出基于 SMA 与 StdDev 的价差与 z-score 指标示例。
绘图
backtrader 内置基于 matplotlib 的绘图,例如 cerebro.plot(style="candlestick", volume=True)。在无头环境中可先设置 matplotlib.use("Agg"),再将返回的图形保存为文件。
与其他技能的集成
资料提及可与以下技能配合:
- pandas-ta:在外部计算指标,作为数据源列加入;添加额外数据线见 references/api_guide.md。
- trading-visualization:从 notify_trade 导出交易日志并用可视化技能绘图。
- position-sizing:使用该技能实现 Kelly 或波动率目标型 Sizer。
- risk-management:将组合层面的防护规则作为策略过滤器。
- slippage-modeling:使用该技能的滑点估计来配置 set_slippage_perc。
文件结构
参考资料:
- references/api_guide.md — Cerebro、Strategy、Broker、Analyzer、Data Feed API 参考
- references/strategy_patterns.md — 可复用策略模式:交叉、均值回归、多时间框架、自定义指标
脚本:
- scripts/backtest_strategy.py — 完整 EMA 交叉回测,含分析器与合成数据
- scripts/bracket_orders.py — 括号单演示,使用 RSI 入场与基于 ATR 的止损
快速开始
安装与运行命令如下(保留原文):
uv pip install backtrader pandas numpy matplotlib
python scripts/backtest_strategy.py --demo
python scripts/bracket_orders.py --demo
限制
资料未提供关于收费、价格、平台限制或性能基准的完整信息;除已述内容外,其余细节暂未提供。