关于 backtrader
backtrader 是面向 Python 量化开发者的事件驱动回测框架,逐根处理行情数据并模拟订单与持仓。它内置经纪商、复杂订单管理和多时间周期数据处理,适用于依赖成交状态的策略逻辑。
主要功能
- 01逐根行情事件驱动回测
- 02支持市价、限价、止损及括号订单
- 03模拟佣金、滑点与保证金
- 04多时间周期数据重采样
- 05内置仓位 sizing 与绩效分析器
- 06支持自定义指标和绘图
适用场景
- 01回测依赖订单成交状态的策略
- 02测试入场、止损与止盈括号订单
- 03模拟多时间周期的交易逻辑
- 04分析策略收益、回撤和交易记录
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ agiprolabs/ claude-trading-skills --skill backtrader安装后在 Claude Code 中输入/backtrader确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api_guide.mdstrategy_patterns.mdscripts/backtest_strategy.pybracket_orders.py详细介绍
Backtrader
Backtrader 是一个基于 Python 的事件驱动回测框架,逐根处理数据 K 线,并通过内置的经纪商、订单管理和持仓跟踪模拟真实的执行情况。与向量化框架(vectorbt、pandas)不同,Backtrader 会逐根遍历历史数据并触发回调,让你能够实现依赖之前成交、部分执行和条件括号单的复杂订单逻辑。
事件驱动与向量化
| 方面 | Backtrader(事件驱动) | vectorbt(向量化) |
|---|---|---|
| 执行模型 | 逐根 K 线回调 | 整个数组运算 |
| 速度 | 较慢(Python 循环) | 快(NumPy/Numba) |
| 订单类型 | 市价单、限价单、止损单、止损限价单、括号单、OCO | 仅市价单(原生支持) |
| 真实性 | 内置经纪商,支持佣金、滑点和保证金 | 手动模拟滑点 |
| 多时间周期 | 原生 resampledata | 手动对齐 |
| 适用于 | 复杂策略、括号单、投资组合 | 快速参数扫描、简单信号 |
需要以下功能时使用 backtrader:
- 括号单(将入场单 + 止损单 + 止盈单作为一个整体)
- 止损限价单或追踪止损单
- 依赖订单状态的逻辑(首次成交后加仓,N 根 K 线内未成交则取消)
- 多时间周期策略(日线信号、小时线执行)
- 逼真的佣金和滑点模拟
需要以下功能时使用 vectorbt:
- 在数千种组合中快速优化参数
- 无需复杂订单管理的简单做多/做空信号
- 快速原型开发和结果统计分析
核心概念
Backtrader 有五个通过事件循环交互的核心对象:
1. Cerebro(引擎)
中央协调器。你可以向 Cerebro 添加策略、数据源、分析器和仓位管理器,然后调用 run()。
import backtrader as bt
cerebro = bt.Cerebro()
cerebro.addstrategy(MyStrategy, fast_period=10, slow_period=30)
cerebro.adddata(data_feed)
cerebro.broker.setcash(100_000)
cerebro.broker.setcommission(commission=0.003) # 0.3%
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name="sharpe")
cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown")
cerebro.run()
2. Strategy(你的逻辑)
Strategy 子类包含所有交易逻辑。关键方法:
__init__()— 定义指标。在回测开始前运行一次。next()— 在每根 K 线上调用。在此处下单。notify_order(order)— 订单状态变化时调用(已提交、已接受、已完成、已取消、保证金不足、已过期)。notify_trade(trade)— 交易开仓或平仓时调用。在此处获取盈亏。
class EMACrossover(bt.Strategy):
params = (
("fast_period", 10),
("slow_period", 30),
)
def __init__(self) -> None:
self.ema_fast = bt.ind.EMA(period=self.p.fast_period)
self.ema_slow = bt.ind.EMA(period=self.p.slow_period)
self.crossover = bt.ind.CrossOver(self.ema_fast, self.ema_slow)
def next(self) -> None:
if not self.position:
if self.crossover > 0:
self.buy()
elif self.crossover < 0:
self.close()
3. Data Feed
Backtrader 数据源提供 OHLCV 数据线。最常用的方法是从 pandas DataFrame 加载数据:
import pandas as pd
df = pd.DataFrame({
"open": [...], "high": [...], "low": [...],
"close": [...], "volume": [...],
}, index=pd.DatetimeIndex([...]))
data = bt.feeds.PandasData(dataname=df)
cerebro.adddata(data)
对于 CSV 文件:
data = bt.feeds.GenericCSVData(
dataname="ohlcv.csv",
dtformat="%Y-%m-%d",
openinterest=-1, # no open interest column
)
4. Broker
内置经纪商可通过配置现金、佣金和滑点来模拟订单执行。
cerebro.broker.setcash(100_000)
cerebro.broker.setcommission(commission=0.003) # 0.3% per trade
# Cheat-on-open: execute at the open of the signal bar (avoids lookahead)
cerebro.broker.set_coo(True)
5. Analyzers
回测完成后,分析器会计算绩效指标。
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name="sharpe",
riskfreerate=0.0, annualize=True, timeframe=bt.TimeFrame.Days)
cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown")
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="trades")
cerebro.addanalyzer(bt.analyzers.Returns, _name="returns")
results = cerebro.run()
strat = results[0]
sharpe = strat.analyzers.sharpe.get_analysis()
dd = strat.analyzers.drawdown.get_analysis()
trades = strat.analyzers.trades.get_analysis()
订单类型
Backtrader 支持复杂订单类型,这对于逼真的加密货币回测至关重要。
市价单
self.buy() # market buy
self.sell() # market sell
self.close() # close current position
限价单
self.buy(exectype=bt.Order.Limit, price=95.0)
self.sell(exectype=bt.Order.Limit, price=105.0)
止损单
当价格达到止损价位时触发市价单:
self.sell(exectype=bt.Order.Stop, price=90.0) # stop loss
止损限价单
当价格达到止损价位时触发限价单:
self.buy(exectype=bt.Order.StopLimit, price=100.0, plimit=101.0)
括号单
将入场单 + 止损单 + 止盈单作为一个整体。如果止损单成交,止盈单就会取消(反之亦然)。
self.buy_bracket(
price=100.0, # entry limit
stopprice=95.0, # stop loss
limitprice=110.0, # take profit
exectype=bt.Order.Limit,
stopexec=bt.Order.Stop,
limitexec=bt.Order.Limit,
)
有关基于 ATR 的止损括号单模式,请参阅 references/strategy_patterns.md。
仓位规模(Sizers)
仓位管理器决定每笔订单买入或卖出的单位数量。
# Fixed size
cerebro.addsizer(bt.sizers.FixedSize, stake=100)
# Percent of portfolio
cerebro.addsizer(bt.sizers.PercentSizer, percents=95)
# All available cash
cerebro.addsizer(bt.sizers.AllInSizer, percents=95)
自定义仓位管理器:
class RiskSizer(bt.Sizer):
params = (("risk_pct", 0.02),)
def _getsizing(self, comminfo, cash, data, isbuy):
risk_amount = cash * self.p.risk_pct
atr = self.strategy.atr[0]
if atr <= 0:
return 0
size = risk_amount / atr
return int(size)
加密货币注意事项
24/7 市场
加密货币全天候交易。使用日线数据时,无需跳过周末。如果要分析特定时段,请设置交易时段,或使用 sessionstart/sessionend。
高额手续费
Solana 上的 DEX 兑换通常每笔交易成本为 0.25-0.30%。请相应设置佣金:
cerebro.broker.setcommission(commission=0.003) # 0.3% round trip per side
小数仓位
加密货币支持以小数单位交易。Backtrader 原生支持此功能——无需特殊配置。
滑点
为了实现逼真的模拟,请启用开盘作弊并添加滑点:
cerebro.broker.set_coo(True)
cerebro.broker.set_slippage_perc(0.001) # 0.1% slippage
波动较大的数据
加密货币 OHLCV 数据通常会出现极端影线。请使用基于 ATR 的止损,而不是固定百分比止损,以适应波动性。
多时间框架
Backtrader 可以在单个策略中将数据重采样为多个时间框架:
data_1h = bt.feeds.PandasData(dataname=df_1h)
cerebro.adddata(data_1h)
# Resample 1h to daily
cerebro.resampledata(data_1h, timeframe=bt.TimeFrame.Days, compression=1)
在策略中访问:
def __init__(self):
self.ema_1h = bt.ind.EMA(self.datas[0], period=20) # hourly
self.ema_daily = bt.ind.EMA(self.datas[1], period=20) # daily
自定义指标
class SpreadIndicator(bt.Indicator):
lines = ("spread", "zscore",)
params = (("period", 20),)
def __init__(self):
mean = bt.ind.SMA(self.data, period=self.p.period)
std = bt.ind.StdDev(self.data, period=self.p.period)
self.lines.spread = self.data - mean
self.lines.zscore = self.lines.spread / std
绘图
Backtrader 内置了基于 matplotlib 的绘图功能:
cerebro.plot(style="candlestick", volume=True)
对于无头环境,可保存到文件:
import matplotlib
matplotlib.use("Agg")
figs = cerebro.plot(style="candlestick")
figs[0][0].savefig("backtest_result.png", dpi=150)
与其他技能集成
- pandas-ta:在外部计算指标,并将其作为数据馈送列添加。有关添加额外数据线的信息,请参阅
references/api_guide.md。 - trading-visualization:从
notify_trade导出交易日志,并使用可视化技能绘图。 - position-sizing:使用
position-sizing技能设置 Kelly 或波动率目标仓位计算器。 - risk-management:将
risk-management技能中的投资组合级防护措施用作策略筛选条件。 - slippage-modeling:使用
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