教程 · 单套解锁 量化编程 · Python框架

BacktraderPro操作手册

使用手册 + 操作教程 共 22 章全部免费开放,一步一步把软件用起来;核心知识点 8 章,¥69 一次解锁讲透原理。

作者 枢汇安全课堂 更新 2026-10-12 阅读 37 收录 Python框架 · 30 章
本课程 · 单套解锁
¥69¥104
单品永久解锁 · 会员可阅 · 一次购买终身使用
✓使用手册 + 操作教程 共 22 章全文免费 ✓核心知识点 8 章,¥69 一次解锁 ✓支持电脑 / 手机 · 永久免费更新
注册后解锁核心知识点
免费学习区 使用手册 + 操作教程 共 22 章全部免费开放 · 核心知识点 8 章为付费内容 ¥69 解锁核心知识点
PART ONE

使用手册

功能在哪 · 是什么 · 怎么调出来

一、软件定位与适用场景

量化研究 / 交易框架(Python / 云 / 券商 API),用于数据、回测、实盘。本文只讲软件功能与界面含义,不涉及任何交易方向建议。

二、使用前准备

  1. 准备 Python 环境或平台账号
  2. 订阅数据源
  3. 配置 API 密钥
  4. 准备策略代码

三、界面结构总览

手机端通常分为三个主区域:

  • 行情页:看品种价格、分时、K 线、盘口
  • 交易页:下单、持仓、挂单、资金
  • 账户页:账户信息、安全设置、业务办理、通知

四、数据页字段含义

  • 标的 / 周期 / 复权方式
  • 字段:OHLCV、因子
  • 起止范围与频率
独到见解:复权方式选错,回测结论全盘反转。

五、回测页要素

  • 起止时间 / 初始资金
  • 手续费与滑点设置
  • 绩效指标:夏普、最大回撤
  • 参数优化区间

六、实盘页常用功能

  • API 连接状态
  • 订单管理
  • 风控阈值
  • 日志与告警
  • 部署(云 / 本地)

七、它是什么:回测框架,不是"赚钱系统"

1、准确定位

它是它不是
一个回测与策略开发框架不是自带策略的软件
执行引擎:驱动策略在历史数据上逐根 K 线运行不是数据源(数据要你自己喂)
记账器:模拟资金、手续费、持仓不是行情终端
一个可以安装到你自己机器上的 Python 库不是托管服务

2、一个关键的前提认知

Backtrader 能做的事:
  给你一套标准机制,让策略逻辑可以被执行、被记账、被统计

Backtrader 不能做的事:
   告诉你该买什么
   保证回测结果在未来有效
   替你判断数据好不好

这对我意味着什么: 很多人把「学会框架」当成「学会量化」。实际上框架解决的是执行,策略解决的是判断。这两件事的差距,比想象中大得多。

八、安装与环境准备

1、安装

pip install backtrader

如需绘图功能,通常需要额外安装绘图相关依赖:

pip install matplotlib

2、建议的项目结构

my_backtest/
├── data/
│   └── sample.csv         # 历史数据
├── strategies/
│   └── my_strategy.py     # 策略逻辑
├── run.py                 # 主运行脚本
└── utils/
    └── loaders.py         # 数据加载辅助

为什么建议分开: 随着策略变多,把所有东西塞进一个文件会让「改一行代码就跑不动」的风险大增。分离数据与策略是最基本的工程习惯。

3、环境注意事项

  • 强烈建议使用虚拟环境(venv / conda 均可)
  • 锁定依赖版本,避免升级后 API 不兼容导致旧脚本失效
  • Python 版本与依赖的兼容性以官方说明为准
PART TWO

操作教程

一步一步 · 跟着做完一件事

九、五个核心概念(理解这五个,就能用起来)

概念作用一句话理解
Cerebro总控制器/引擎大脑,负责把数据、策略、经纪商装配起来并运行
Strategy策略你的交易逻辑写在里面
Data Feed数据源被喂进去的历史数据
Broker经纪商模拟负责资金、手续费、撮合、持仓记账
Analyzer分析器跑完之后算绩效指标

此外还有两个常用配件:

配件作用
Indicator技术指标(内置一大堆,也可自定义)
Sizer仓位管理,决定每次买多少

1、一次完整回测的标准流程

① 创建 Cerebro 实例
② 准备数据(Data Feed)
③ 把数据加进 Cerebro
④ 把策略加进 Cerebro
⑤ 设置资金、手续费、滑点
⑥ (可选)添加分析器
⑦ 运行
⑧ 查看结果与绘图

十、第一个完整例子:双均线交叉

下面这段代码是 Backtrader 的最小可运行范式,务必逐行理解:

import backtrader as bt

## ---------- 1. 定义策略 ----------
class SmaCross(bt.Strategy):
    # 可调参数
    params = (
        ('pfast', 10),   # 快线周期
        ('pslow', 30),   # 慢线周期
    )

    def __init__(self):
        # 指标通常在 __init__ 中定义
        self.sma_fast = bt.indicators.SMA(self.data.close, period=self.p.pfast)
        self.sma_slow = bt.indicators.SMA(self.data.close, period=self.p.pslow)
        # 交叉信号
        self.crossover = bt.indicators.CrossOver(self.sma_fast, self.sma_slow)

    def next(self):
        # 每根 K 线都会调用 next()
        if not self.position:                 # 当前空仓
            if self.crossover > 0:            # 金叉
                self.buy()                    # 买入
        else:                                 # 已持仓
            if self.crossover < 0:            # 死叉
                self.close()                  # 平仓

## ---------- 2. 组装并运行 ----------
cerebro = bt.Cerebro()

data = bt.feeds.GenericCSVData(
    dataname='data/sample.csv',
    dtformat='%Y-%m-%d',
    timeframe=bt.TimeFrame.Days,
    datetime=0, open=1, high=2, low=3, close=4, volume=5, openinterest=-1,
)

cerebro.adddata(data)                 # 加数据
cerebro.addstrategy(SmaCross)         # 加策略
cerebro.broker.setcash(100000.0)      # 初始资金
cerebro.broker.setcommission(commission=0.001)  # 手续费

print('起始资金: %.2f' % cerebro.broker.getvalue())
cerebro.run()
print('结束资金: %.2f' % cerebro.broker.getvalue())

cerebro.plot()                        # 绘图

1、这段代码在做什么

环节发生了什么
__init__声明指标。框架会在这里一次性创建指标对象
next每根 K 线调用一次,你的买卖判断写在这里
self.buy()发出买单,由 Broker 模拟成交
self.position当前持仓,空仓时为空
cerebro.run()开始逐根 K 线推进,直到数据结束

2、__init__ 与 next 的区别极其重要

__init__:整个回测只执行一次,用于声明指标与预计算
next   :每根 K 线执行一次,用于写逻辑

常见错误:把指标计算写在 next 里
  → 每根 K 线重复计算,极慢,且容易出错

这对我意味着什么: 这是新手最容易写错的地方。指标声明放 __init__,交易判断放 next。 这个习惯会让你的代码高效且不易出错。

十一、Lines:Backtrader 的数据抽象

1、什么是 line

在 Backtrader 里,所有时间序列都叫 line。收盘价是一条 line,均线是一条 line,MACD 也是一条 line。

访问方式:

self.data.close        # 收盘价这条 line(当前对象)
self.data.close[0]     # 当前这根 K 线的值
self.data.close[-1]    # 上一根 K 线的值
self.data.close[-2]    # 上两根

索引是「时间倒序」的:0 = 当下,-1 = 上一根。

这一点与 Python 列表的正向索引习惯相反,是新手最常犯的错误之一。

2、访问多条数据

self.data.close[0]     # 当前收盘价
self.data.open[0]      # 当前开盘价
self.data.high[0]      # 当前最高价
self.data.volume[0]    # 当前成交量

3、为什么会存在「预热期」

一条 30 日均线,需要有 30 根数据才能算出第一个有效值。

第 1 根 K 线:SMA(30) 无值
第 30 根 K 线:SMA(30) 开始有值

在这之前,next() 仍会被调用,但指标还没有有效值。

这对我意味着什么: 回测开始时策略不会立刻交易,这不是 bug,是数学必然。如果你的策略在开头几根 K 线就产生信号,要检查是否误读了无效值。

十二、数据接入:三种常见方式

1、CSV 文件

data = bt.feeds.GenericCSVData(
    dataname='data.csv',
    dtformat='%Y-%m-%d',
    timeframe=bt.TimeFrame.Days,
    datetime=0, open=1, high=2, low=3,
    close=4, volume=5, openinterest=-1,
)
cerebro.adddata(data)

参数说明:

  • datetime/open/high/low/close/volume:这些字段在 CSV 中的列序号
  • openinterest=-1:表示没有持仓量列
  • dtformat:日期格式,必须与文件完全一致

2、Pandas DataFrame

import pandas as pd
import backtrader as bt

df = pd.read_csv('data.csv', index_col='date', parse_dates=True)
data = bt.feeds.PandasData(dataname=df)
cerebro.adddata(data)

注意: DataFrame 的索引通常应为日期时间索引,列名需符合框架约定或另行做映射。

3、多个数据源

cerebro.adddata(data_a, name='AAA')
cerebro.adddata(data_b, name='BBB')

## 在策略中按序号访问
self.datas[0]                 # AAA
self.datas[1]                 # BBB
self.getdatabyname('BBB')     # 按名称访问

适用场景: 跨品种配对、跨市场联动、多时间框架分析。

4、数据质量决定回测上限

检查项为什么重要
是否存在缺失日期缺数据会让指标错算
是否有重复行成交量会被重复计入
是否做过复权处理未复权会让除权日产生假信号
时间戳是否对齐多数据源时必须对齐
是否有异常极值脏数据会引发假信号

这对我意味着什么: 再漂亮的策略,喂进去脏数据就是 garbage out。在怀疑策略之前,先怀疑数据。

十三、指标:内置与自定义

1、内置指标

self.sma  = bt.indicators.SMA(self.data.close, period=20)
self.ema  = bt.indicators.EMA(self.data.close, period=20)
self.macd = bt.indicators.MACD(self.data.close)
self.rsi  = bt.indicators.RSI(self.data.close, period=14)
self.atr  = bt.indicators.ATR(self.data)
self.boll = bt.indicators.BollingerBands(self.data.close)

2、自定义指标

class DoubleSMA(bt.Indicator):
    lines = ('result',)              # 声明输出线
    params = (('period', 20),)

    def __init__(self):
        sma1 = bt.indicators.SMA(self.data.close, period=self.p.period)
        sma2 = bt.indicators.SMA(sma1, period=self.p.period)
        self.lines.result = sma2     # 赋值给自己声明的线

## 使用
self.myind = DoubleSMA(self.data.close, period=15)

3、关键提醒:不要用「未来」的计算方式

 错误:看到后一根 K 线的数据来决定前一根的操作
 正确:只用当前及之前可获得的信息

自查方法:
  在 next() 里,只能使用 [0] 及负索引(过去)的值。
  如果出现正索引(如 [1] 表示未来),那就是未来函数。

这对我意味着什么: 「偷看未来」是回测作假的头号方式,而且经常是无意的。一个看似无害的写法就可能引入未来函数。回测越漂亮,越要怀疑。

十四、下单、成交与持仓

1、基本下单

self.buy()                                # 买入
self.sell()                               # 卖出(含建立空头)
self.close()                              # 平掉当前持仓
self.order_target_percent(target=0.5)     # 调整到目标仓位比例

2、订单通知:把成交状况打印出来

def notify_order(self, order):
    if order.status in [order.Submitted, order.Accepted]:
        return                                  # 已提交/已接受,暂不处理

    if order.status == order.Completed:
        if order.isbuy():
            print('买入成交 价格%.2f 数量%.0f' % (order.executed.price,
                                                order.executed.size))
        elif order.issell():
            print('卖出成交 价格%.2f' % order.executed.price)

    elif order.status in [order.Canceled, order.Margin, order.Rejected]:
        print('订单未完成,原因:', order.getstatusname())

这对我意味着什么: 「发出去买指令」和「真的买到了」是两件事。Margin(资金不足)、Rejected(被拒)都是可能出现的正常状态,必须在代码里处理,而不是假设一定成交。

3、资金与持仓查询

self.broker.getcash()      # 可用现金
self.broker.getvalue()     # 账户总权益
self.position.size         # 当前持仓数量(正为多,负为空)
self.position.price        # 持仓均价

十五、把成本算进去:回测真实性的分水岭

1、设置手续费

cerebro.broker.setcommission(commission=0.001)     # 按比例,此处为千分之一示例

2、设置滑点

cerebro.broker.set_slippage_perc(perc=0.0005)      # 按百分比滑点

## cerebro.broker.set_slippage_fixed(fixed=0.02)

3、为什么这一步不能省

对成本量级的示意性理解(非具体品种费率):

某策略日均做 2 个往返,一个月约 20 个交易日
  → 每年约 480 个往返

若每个往返的滑点 + 手续费合计约为成交金额的 0.1%
  → 年度累计成本约 48%(相对单笔全额周转计)

即便实际数值远小于这个示意,频繁交易的成本也极其可观。
若策略本身毛收益不高,这些成本完全可以吃掉全部利润甚至转负。

这对我意味着什么: 不设手续费和滑点的回测,结果系统性偏乐观。 一个策略在零成本时赚 20%,加上真实成本后可能亏损——这是量化最常见的"希望破灭"时刻。

4、仓位管理

cerebro.addsizer(bt.sizers.FixedSize, stake=100)        # 固定 100 股/手
cerebro.addsizer(bt.sizers.PercentSizer, percents=20)   # 每次用约 20% 资金

也可以在策略内自行决定数量:

size = int((self.broker.getcash() * 0.2) / self.data.close[0])
self.buy(size=size)

十六、绩效评估:用 Analyzer

1、添加分析器

cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe')
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]

print(strat.analyzers.sharpe.get_analysis())
print(strat.analyzers.drawdown.get_analysis())
print(strat.analyzers.trades.get_analysis())

2、三个最值得看的指标

指标回答什么
最大回撤 DrawDown最惨的时候亏了多少(先看这个)
夏普比率 SharpeRatio每承担一单位波动换来多少超额收益
交易分析 TradeAnalyzer胜率、盈亏比、连续亏损笔数等

这对我意味着什么: 新手盯着「总收益率」,专业看「回撤」和「夏普」。一个回撤 60% 的高收益策略,实盘上大概率撑不到它兑现的那天——资金曲线会在中途被击穿,或者人的心理先崩了。

十七、参数优化:威力与陷阱

1、基本用法

cerebro.optstrategy(SmaCross, pfast=range(5, 20, 1), pslow=range(20, 60, 5))

results = cerebro.run()   # 每组参数跑一次

2、优化的三个陷阱

陷阱说明
过拟合参数记住了历史,换了数据就失效
参数越多越容易拟合参数空间越大,越容易找到"完美"组合
未做样本外检验只在调参所用的数据上好看,是自我欺骗

3、正确做法

① 把数据分成两段:样本内 / 样本外
② 只在样本内调参
③ 用样本外检验结果是否站得住
④ 检查参数敏感性:微调参数,结果是否剧烈变化
   - 剧烈变化 = 高过拟合风险
⑤ 加倍成本再看是否仍有正收益
关键认知:回测的作用是"证伪",不是"证明"。 正确用法是全力想办法让策略亏掉,如果怎么都亏不掉,再谈实盘。

十八、多周期处理:Resample 与 Replay

1、Resample(降频)

把细粒度数据合并成粗粒度,例如把分钟线合成日线:

cerebro.resampledata(
    data,
    timeframe=bt.TimeFrame.Days,
    compression=1,
)

2、Replay(回放)

把一根粗粒度 K 线内的细粒度数据逐步回放出来,用于更精细的成交模拟:

cerebro.replaydata(
    data,
    timeframe=bt.TimeFrame.Days,
)

3、两者的区别

ResampleReplay
粒度合成后只有一根 Bar一根 Bar 期间多次触发 next
用途多周期分析精细成交模拟
速度快慢

这对我意味着什么: 用日线数据回测出来的信号,在分钟级实盘中可能因为盘中路径不同而产生完全不同的结果。回测粒度决定结论的适用范围。

十九、绘图

cerebro.plot()

常用调整依赖绘图后端与样式设置,具体参数以版本文档为准。

绘图的价值在于目视检查:你会发现很多问题(比如信号堆积在某个时段、长期空仓、成交集中在异常价格),看图往往比看数字更快发现问题。

二十、从回测到实盘:边界要清楚

1、框架自带的实盘连接能力(概念层面)

开源 Backtrader 包含对部分对接方式的支持(例如面向某些经纪商的 Store / Data Feed / Broker 组件)。具体支持哪些、如何配置,以官方文档为准。

2、回测与实盘的差距清单

差距回测实盘
成交假设按规则成交排队、部分成交、拒单
延迟零延迟网络 + 柜台 + 撮合延迟
流动性影响不影响价格大单有冲击成本
数据历史静态实时可能有脏数据
连续性一次跑完需处理断线与重启
成本固定假设费率可能变化

3、转实盘的检查清单

  1. 是否已在样本外数据上验证
  2. 是否已建模手续费与滑点
  3. 是否已处理资金不足/拒单状态
  4. 是否有明确的仓位上限
  5. 是否有超时/断线处理
  6. 是否有日志
  7. 是否已小资金试运行
  8. 是否知道什么情况下应该停掉它

二十一、常见坑清单

坑表现处理
索引方向搞反用 [1] 表示过去记住 [0] 当前,[-1] 过去
指标写在 next 里极慢、结果异常移到 __init__
忘记设手续费滑点回测异常漂亮必须设置
数据未排序回测顺序错乱检查时间升序
数据有缺失指标跳变补齐或检查数据源
忽视预热期开头信号怪异检查指标是否已有值
参数过拟合样本外崩塌分段验证
用日线结论做分钟交易实盘不匹配回测粒度对齐实盘
未来函数回测完美只用 [0] 及负索引
不处理拒单实盘仓位错乱实现 notify_order

二十二、注意事项

  1. 框架不产生盈利能力。 它只负责执行与记账,策略有效性完全取决于使用者。
  2. 回测的作用是证伪,不是证明。 漂亮曲线应当引起怀疑,而非信心。
  3. 不设成本的回测没有意义。 手续费与滑点必须建模。
  4. 回测粒度必须与实盘一致。 用日线结论指导分钟级交易是常见错误。
  5. 适时承认失败。 需要反复微调参数才能成立的策略,通常是拟合出来的。
  6. 建议使用版本锁定与可复现环境。 把框架版本、依赖清单与随机种子一同记录,避免因版本升级导致回测结果不可复现。
  7. 先用模拟账户跑满一个完整周期。 至少覆盖一段震荡与一段趋势行情,再考虑是否进入实盘。
  8. 关于「Pro」: 如前所述,开源主干没有名为 Pro 的官方发行版。若使用第三方版本,请以该版本官方资料为准,并对其声称的能力保持审慎。
  9. 本文仅在介绍框架操作,不构成投资建议,不推荐任何产品。
金融产品有风险,交易决策请自行判断,据此操作风险自负。
付费专享 · 核心知识点 8 章

继续阅读:核心知识点,搞懂原理

BacktraderPro操作手册 — 共 30 章,已免费阅读 22 章,剩余 8 章核心知识点讲透「为什么这样、点了会怎样」。

二十三、数据源与频率
二十四、回测引擎原理
二十五、滑点与手续费建模
二十六、参数优化与过拟合
二十七、风险控制模块
二十八、绩效评价指标
…等共 8 章核心内容
✍️ 注册后扫码购买 🔐 已有账号,去登录 单套 ¥69 永久 · 会员可阅
SERVICE & PRICING
服务收费说明 · 明码标价,无隐藏收费
全部课程统一 ¥39-69,买一套永久使用。以下为购买与使用的完整流程。
01先免费试读

每套教程的「使用手册」部分均可免费阅读,先确认内容是否适合自己再决定,不必盲买。

02扫码付款

选定课程后点「立即解锁」,页面展示收款二维码与客服微信,扫码转账即可,无需注册海外支付。

03获取卡密

付款完成后客服第一时间发送卡密号与卡密密码,站内消息与微信同步通知。

04兑换解锁

在用户中心「兑换卡密」输入卡密号与密码,系统即时解锁全部章节,无需二次付款。

一次付费,终身可用 · 解锁后课程永久留在账号里,不限次数、不限时间阅读 持续免费更新 · 平台改版、规则变化时课程同步修订
RECOMMEND
相关教程推荐 · 同栏目更多上手机会

💬 用户评价 (0)

🔒 登录并成为会员后可发表评价
还没有评价 · 成为第一个评价的人吧 🎯