backtrader
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBacktrader
Backtrader
Backtrader is a Python event-driven backtesting framework that processes data bar-by-bar, simulating realistic execution with a built-in broker, order management, and position tracking. Unlike vectorized frameworks (vectorbt, pandas), backtrader walks through history one bar at a time, firing callbacks that let you implement complex order logic that depends on previous fills, partial executions, and conditional brackets.
Backtrader是一款基于Python的事件驱动回测框架,它逐K线处理数据,通过内置的经纪商、订单管理和仓位跟踪功能模拟真实交易执行。与向量化框架(vectorbt、pandas)不同,Backtrader会逐根遍历历史K线,触发回调函数,让你能够实现依赖于之前成交、部分执行和条件括号单的复杂订单逻辑。
Event-Driven vs Vectorized
事件驱动 vs 向量化
| Aspect | Backtrader (event-driven) | vectorbt (vectorized) |
|---|---|---|
| Execution model | Bar-by-bar callbacks | Whole-array operations |
| Speed | Slower (Python loop) | Fast (NumPy/Numba) |
| Order types | Market, limit, stop, stop-limit, bracket, OCO | Market only (native) |
| Realism | Built-in broker with commission, slippage, margin | Manual slippage modeling |
| Multi-timeframe | Native resampledata | Manual alignment |
| Best for | Complex strategies, bracket orders, portfolio | Fast parameter sweeps, simple signals |
Use backtrader when you need:
- Bracket orders (entry + stop loss + take profit as a unit)
- Stop-limit or trailing stop orders
- Order-dependent logic (scale in after first fill, cancel if not filled in N bars)
- Multi-timeframe strategies (daily signals, hourly execution)
- Realistic commission and slippage modeling
Use vectorbt when you need:
- Fast parameter optimization over thousands of combinations
- Simple long/short signals without complex order management
- Quick prototyping and statistical analysis of results
| 维度 | Backtrader(事件驱动) | vectorbt(向量化) |
|---|---|---|
| 执行模型 | 逐K线回调 | 全数组运算 |
| 速度 | 较慢(Python循环) | 较快(NumPy/Numba) |
| 订单类型 | 市价单、限价单、止损单、止损限价单、括号单、OCO单 | 仅支持市价单(原生) |
| 真实性 | 内置经纪商,支持佣金、滑点、保证金模拟 | 需手动模拟滑点 |
| 多时间框架 | 原生支持数据重采样 | 需手动对齐数据 |
| 适用场景 | 复杂策略、括号单、组合投资 | 快速参数扫描、简单信号策略 |
当你需要以下功能时选择Backtrader:
- 括号单(入场+止损+止盈为一个整体单元)
- 止损限价单或追踪止损单
- 依赖订单状态的逻辑(首次成交后加仓、N根K线未成交则取消订单)
- 多时间框架策略(日线信号、小时线执行)
- 真实的佣金与滑点模拟
当你需要以下功能时选择vectorbt:
- 针对数千种组合的快速参数优化
- 无需复杂订单管理的简单多空信号
- 快速原型开发与结果统计分析
Core Concepts
核心概念
Backtrader has five core objects that interact through an event loop:
Backtrader包含五个核心对象,它们通过事件循环交互:
1. Cerebro (the engine)
1. Cerebro(引擎)
The central orchestrator. You add strategies, data feeds, analyzers, and sizers to Cerebro, then call .
run()python
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()核心协调器。你可以向Cerebro添加策略、数据馈源、分析器和仓位计算器,然后调用启动回测。
run()python
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 (your logic)
2. Strategy(策略逻辑)
A Strategy subclass contains all trading logic. Key methods:
- — Define indicators. Runs once before backtesting starts.
__init__() - — Called on every bar. Place orders here.
next() - — Called when order status changes (submitted, accepted, completed, canceled, margin, expired).
notify_order(order) - — Called when a trade opens or closes. Access P&L here.
notify_trade(trade)
python
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()Strategy子类包含所有交易逻辑。关键方法:
- — 定义指标,在回测开始前运行一次。
__init__() - — 每根K线都会被调用,在此处下达订单。
next() - — 订单状态变化时调用(已提交、已接受、已完成、已取消、保证金不足、已过期)。
notify_order(order) - — 交易开仓或平仓时调用,在此处获取盈亏数据。
notify_trade(trade)
python
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
3. Data Feed(数据馈源)
Backtrader data feeds provide OHLCV lines. The most common approach is loading from a pandas DataFrame:
python
import pandas as pd
df = pd.DataFrame({
"open": [...], "high": [...], "low": [...],
"close": [...], "volume": [...],
}, index=pd.DatetimeIndex([...]))
data = bt.feeds.PandasData(dataname=df)
cerebro.adddata(data)For CSV files:
python
data = bt.feeds.GenericCSVData(
dataname="ohlcv.csv",
dtformat="%Y-%m-%d",
openinterest=-1, # no open interest column
)Backtrader的数据馈源提供OHLCV数据。最常用的方式是从pandas DataFrame加载:
python
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文件:
python
data = bt.feeds.GenericCSVData(
dataname="ohlcv.csv",
dtformat="%Y-%m-%d",
openinterest=-1, # 无持仓兴趣列
)4. Broker
4. Broker(经纪商)
The built-in broker simulates order execution with configurable cash, commission, and slippage.
python
cerebro.broker.setcash(100_000)
cerebro.broker.setcommission(commission=0.003) # 0.3% per trade内置经纪商可模拟订单执行,支持配置初始资金、佣金和滑点。
python
cerebro.broker.setcash(100_000)
cerebro.broker.setcommission(commission=0.003) # 每笔交易0.3%Cheat-on-open: execute at the open of the signal bar (avoids lookahead)
开盘价成交:在信号K线的开盘价执行订单(避免前瞻偏差)
cerebro.broker.set_coo(True)
undefinedcerebro.broker.set_coo(True)
undefined5. Analyzers
5. Analyzers(分析器)
Analyzers compute performance metrics after the backtest completes.
python
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()分析器在回测完成后计算绩效指标。
python
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()Order Types
订单类型
Backtrader supports complex order types critical for realistic crypto backtesting.
Backtrader支持对真实加密货币回测至关重要的复杂订单类型。
Market Order
市价单
python
self.buy() # market buy
self.sell() # market sell
self.close() # close current positionpython
self.buy() # 市价买入
self.sell() # 市价卖出
self.close() # 平仓Limit Order
限价单
python
self.buy(exectype=bt.Order.Limit, price=95.0)
self.sell(exectype=bt.Order.Limit, price=105.0)python
self.buy(exectype=bt.Order.Limit, price=95.0)
self.sell(exectype=bt.Order.Limit, price=105.0)Stop Order
止损单
Triggers a market order when price reaches the stop level:
python
self.sell(exectype=bt.Order.Stop, price=90.0) # stop loss价格达到止损位时触发市价单:
python
self.sell(exectype=bt.Order.Stop, price=90.0) # 止损Stop-Limit Order
止损限价单
Triggers a limit order when price reaches the stop level:
python
self.buy(exectype=bt.Order.StopLimit, price=100.0, plimit=101.0)价格达到止损位时触发限价单:
python
self.buy(exectype=bt.Order.StopLimit, price=100.0, plimit=101.0)Bracket Order
括号单
Entry + stop loss + take profit as an atomic unit. If the stop fills, the take profit is canceled (and vice versa).
python
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,
)See for bracket order patterns with ATR-based stops.
references/strategy_patterns.md入场+止损+止盈为一个原子单元。如果止损单成交,止盈单会被取消(反之亦然)。
python
self.buy_bracket(
price=100.0, # 入场限价
stopprice=95.0, # 止损
limitprice=110.0, # 止盈
exectype=bt.Order.Limit,
stopexec=bt.Order.Stop,
limitexec=bt.Order.Limit,
)如需基于ATR止损的括号单模式,请查看。
references/strategy_patterns.mdPosition Sizing (Sizers)
仓位管理(Sizers)
Sizers determine how many units to buy/sell per order.
python
undefined仓位计算器决定每笔订单的买卖数量。
python
undefinedFixed size
固定数量
cerebro.addsizer(bt.sizers.FixedSize, stake=100)
cerebro.addsizer(bt.sizers.FixedSize, stake=100)
Percent of portfolio
占组合比例
cerebro.addsizer(bt.sizers.PercentSizer, percents=95)
cerebro.addsizer(bt.sizers.PercentSizer, percents=95)
All available cash
全仓买入
cerebro.addsizer(bt.sizers.AllInSizer, percents=95)
Custom sizer:
```python
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)cerebro.addsizer(bt.sizers.AllInSizer, percents=95)
自定义仓位计算器:
```python
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)Crypto Considerations
加密货币适配要点
24/7 Markets
7×24小时市场
Crypto trades around the clock. When using daily bars, there are no weekends to skip. Set the session times or use / if analyzing specific windows.
sessionstartsessionend加密货币全天候交易。使用日线数据时无需跳过周末。如需分析特定时段,可设置交易时段或使用/。
sessionstartsessionendHigh Fees
高额手续费
DEX swaps on Solana typically cost 0.25-0.30% per trade. Set commission accordingly:
python
cerebro.broker.setcommission(commission=0.003) # 0.3% round trip per sideSolana上的DEX交易手续费通常为每笔0.25-0.30%,需相应设置佣金:
python
cerebro.broker.setcommission(commission=0.003) # 单边0.3%,往返合计0.6%Fractional Sizing
fractional仓位
Crypto allows fractional units. Backtrader supports this natively -- no special config needed.
加密货币支持小数仓位,Backtrader原生支持此功能,无需额外配置。
Slippage
滑点
For realistic simulation, enable cheat-on-open and add slippage:
python
cerebro.broker.set_coo(True)
cerebro.broker.set_slippage_perc(0.001) # 0.1% slippage为实现真实模拟,启用开盘价成交并添加滑点:
python
cerebro.broker.set_coo(True)
cerebro.broker.set_slippage_perc(0.001) # 0.1%滑点Volatile Data
高波动数据
Crypto OHLCV data often has extreme wicks. Use ATR-based stops rather than fixed percentage stops to adapt to volatility.
加密货币OHLCV数据通常带有极端影线,建议使用基于ATR的止损而非固定百分比止损,以适应波动率变化。
Multi-Timeframe
多时间框架
Backtrader can resample data to multiple timeframes within a single strategy:
python
data_1h = bt.feeds.PandasData(dataname=df_1h)
cerebro.adddata(data_1h)Backtrader可在单个策略内将数据重采样至多个时间框架:
python
data_1h = bt.feeds.PandasData(dataname=df_1h)
cerebro.adddata(data_1h)Resample 1h to daily
将1小时数据重采样为日线数据
cerebro.resampledata(data_1h, timeframe=bt.TimeFrame.Days, compression=1)
Access in strategy:
```python
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) # dailycerebro.resampledata(data_1h, timeframe=bt.TimeFrame.Days, compression=1)
在策略中调用:
```python
def __init__(self):
self.ema_1h = bt.ind.EMA(self.datas[0], period=20) # 小时线EMA
self.ema_daily = bt.ind.EMA(self.datas[1], period=20) # 日线EMACustom Indicators
自定义指标
python
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 / stdpython
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 / stdPlotting
绘图
Backtrader includes matplotlib-based plotting:
python
cerebro.plot(style="candlestick", volume=True)For headless environments, save to file:
python
import matplotlib
matplotlib.use("Agg")
figs = cerebro.plot(style="candlestick")
figs[0][0].savefig("backtest_result.png", dpi=150)Backtrader包含基于matplotlib的绘图功能:
python
cerebro.plot(style="candlestick", volume=True)在无图形界面环境中,可保存为文件:
python
import matplotlib
matplotlib.use("Agg")
figs = cerebro.plot(style="candlestick")
figs[0][0].savefig("backtest_result.png", dpi=150)Integration with Other Skills
与其他工具集成
- pandas-ta: Compute indicators externally, add as data feed columns. See for adding extra lines.
references/api_guide.md - trading-visualization: Export trade log from and plot with the visualization skill.
notify_trade - position-sizing: Use the skill for Kelly or volatility-targeting sizers.
position-sizing - risk-management: Apply portfolio-level guardrails from the skill as strategy filters.
risk-management - slippage-modeling: Use slippage estimates from the skill to configure
slippage-modeling.set_slippage_perc
- pandas-ta: 外部计算指标,添加为数据馈源列。如需添加额外数据列,请查看。
references/api_guide.md - trading-visualization: 从导出交易日志,使用可视化工具绘图。
notify_trade - position-sizing: 使用工具实现凯利公式或波动率目标仓位管理。
position-sizing - risk-management: 应用工具中的组合级风控规则作为策略过滤器。
risk-management - slippage-modeling: 使用工具的滑点估算结果配置
slippage-modeling。set_slippage_perc
Files
文件说明
References
参考文档
- — Cerebro, Strategy, Broker, Analyzer, Data Feed API reference
references/api_guide.md - — Reusable strategy patterns: crossover, mean reversion, multi-timeframe, custom indicators
references/strategy_patterns.md
- — Cerebro、Strategy、Broker、Analyzer、Data Feed的API参考
references/api_guide.md - — 可复用策略模式:交叉策略、均值回归、多时间框架、自定义指标
references/strategy_patterns.md
Scripts
脚本
- — Complete EMA crossover backtest with analyzers and synthetic data
scripts/backtest_strategy.py - — Bracket order demonstration with RSI entry and ATR-based stops
scripts/bracket_orders.py
- — 完整的EMA交叉回测脚本,包含分析器和合成数据
scripts/backtest_strategy.py - — 括号单演示脚本,基于RSI入场和ATR止损
scripts/bracket_orders.py
Quick Start
快速开始
bash
uv pip install backtrader pandas numpy matplotlib
python scripts/backtest_strategy.py --demo
python scripts/bracket_orders.py --demobash
uv pip install backtrader pandas numpy matplotlib
python scripts/backtest_strategy.py --demo
python scripts/bracket_orders.py --demo