Backtrader 策略实战:从一个想法到一份完整回测
学完基础概念后,最好的练习不是继续背 API,而是完整做一个小策略。
今天用“双均线交叉”演示一遍:
提出规则 → 写代码 → 加入成本 → 分析结果 → 检查问题一、先把策略说成人话
策略规则:
- 计算 10 日均线;
- 计算 30 日均线;
- 10 日均线上穿 30 日均线,买入;
- 10 日均线下穿 30 日均线,卖出;
- 一次只持有一个仓位。
注意:均线交叉是教学案例,不是投资建议。
二、用 Backtrader 表达规则
classSmaCross(bt.Strategy):params=dict(fast=10,slow=30)def__init__(self):fast=bt.indicators.SMA(self.data.close,period=self.p.fast)slow=bt.indicators.SMA(self.data.close,period=self.p.slow)self.cross=bt.indicators.CrossOver(fast,slow)self.order=Nonedefnext(self):ifself.order:returnifnotself.positionandself.cross>0:self.order=self.buy()elifself.positionandself.cross<0:self.order=self.close()这里最重要的是两点:
- 用 CrossOver 判断真正的上穿和下穿;
- 用 self.order 防止订单还没成交时重复下单。
三、补上订单和交易日志
defnotify_order(self,order):iforder.statusin[order.Submitted,order.Accepted]:returniforder.status==order.Completed:print("成交:",order.executed.price,"数量:",order.executed.size,"手续费:",order.executed.comm)else:print("订单未完成:",order.getstatusname())self.order=Nonedefnotify_trade(self,trade):iftrade.isclosed:print("净利润:",trade.pnlcomm,"持仓 K 线数:",trade.barlen)信号日志和成交日志要分开看。
信号出现,不代表订单一定成交。
四、加入手续费和滑点
cerebro.broker.setcash(100000)cerebro.broker.setcommission(commission=0.001)cerebro.broker.set_slippage_perc(perc=0.0005)先不加成本跑一次,再加成本跑一次,比较差异。
如果策略加入成本后完全失效,说明它的优势可能太小,或者换手太高。
五、加入分析器
cerebro.addanalyzer(bt.analyzers.Returns,_name="returns")cerebro.addanalyzer(bt.analyzers.DrawDown,_name="drawdown")cerebro.addanalyzer(bt.analyzers.TradeAnalyzer,_name="trades")运行后查看:
results=cerebro.run()strategy=results[0]print(strategy.analyzers.returns.get_analysis())print(strategy.analyzers.drawdown.get_analysis())print(strategy.analyzers.trades.get_analysis())不要只打印最终资金。
六、加一个买入并持有基准
双均线策略如果赚了 30%,但买入并持有赚了 50%,就不能简单说它更优秀。
比较时至少看:
- 累计收益;
- 最大回撤;
- 波动;
- 交易次数;
- 手续费;
- 在不同市场阶段的表现。
策略的价值通常是“风险收益比更好”,而不只是收益数字更大。
七、可以怎样升级这个策略?
基础版本跑通后,可以一次只增加一个功能:
1. RSI 过滤
只在趋势向上且 RSI 没有过热时买入。
2. ATR 止损
根据市场波动动态设置止损距离。
3. 百分比仓位
不同资金规模下保持相近的仓位比例。
4. 多资产轮动
每月比较多个资产,选择相对强势的品种。
5. 参数敏感性分析
比较快均线和慢均线在不同参数下是否稳定。
每次只增加一个功能,才能知道结果变化来自哪里。
八、策略实战的正确顺序
先写清规则 → 用最简单代码实现 → 用小数据手算 → 加入订单日志 → 加入手续费和滑点 → 加入分析器 → 和基准比较 → 做样本外验证不要一开始就同时加入十个指标。
九、实战中最容易犯的错误
- 策略规则没有写清楚就开始编程;
- 只看信号,不看实际成交;
- 没有买入并持有基准;
- 参数调到历史最优就停止;
- 一次加入太多过滤条件;
- 没有记录每笔交易;
- 忽略成本和样本外表现。
最后总结
策略实战的核心不是把代码写得很长,而是让每一步都能回答:
为什么买? 什么时候成交? 买了多少? 成本是多少? 为什么卖? 这套规则换一段历史还有效吗?把一个简单策略完整做对,比收藏十个复杂策略更有价值。