mcpField
B
backtrader

backtrader

github.com/agiprolabs数据与数据库456507 次安装8 周前更新
代码仓库

关于 backtrader

backtrader 是面向 Python 量化开发者的事件驱动回测框架,逐根处理行情数据并模拟订单与持仓。它内置经纪商、复杂订单管理和多时间周期数据处理,适用于依赖成交状态的策略逻辑。

主要功能

  1. 01逐根行情事件驱动回测
  2. 02支持市价、限价、止损及括号订单
  3. 03模拟佣金、滑点与保证金
  4. 04多时间周期数据重采样
  5. 05内置仓位 sizing 与绩效分析器
  6. 06支持自定义指标和绘图

适用场景

  1. 01回测依赖订单成交状态的策略
  2. 02测试入场、止损与止盈括号订单
  3. 03模拟多时间周期的交易逻辑
  4. 04分析策略收益、回撤和交易记录

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/agiprolabs/claude-trading-skills --skill backtrader

安装后在 Claude Code 中输入/backtrader确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
api_guide.md
strategy_patterns.md
scripts/
backtest_strategy.py
bracket_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

评论

支持 Markdown