ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

10 分钟跑通 Python 量化回测:backtrader 回测框架实战与避坑指南

10 分钟跑通 Python 量化回测:backtrader 回测框架实战与避坑指南 10 分钟跑通 Python 量化回测backtrader 回测框架实战与避坑指南【免费下载链接】backtraderPython Backtesting library for trading strategies项目地址: https://gitcode.com/gh_mirrors/ba/backtraderbacktrader 是一个 Python 量化策略回测框架它让你把刚想出来的交易策略放进完整的历史 K 线里跑一遍输出每一笔成交价、盈亏和回撤在你花真金白银之前看清策略到底行不行。这篇文章不按安装→入门→进阶线性讲而是围绕你做回测时最常问的三个问题来组织策略去哪验证、仓位风险怎么控制、结果可不可信。策略上线前没地方验证backtrader 直接解决的 3 个痛点想法只能靠拍脑袋——策略上线前没地方验证手动在 Excel 里拉 K 线推演花几天还不敢信。backtrader 把历史数据逐根 K 线播放每笔成交、佣金、仓位全程留痕想法当天就能验。手写回测逻辑慢且容易错——订单撮合、滑点、仓位跟踪自己写坑多到怀疑人生。backtrader 内置模拟券商支持 Market / Limit / Stop / StopTrail 等 7 种订单类型撮合逻辑不用你操心。回测结果不敢信——年化 300%多半是没算成本。backtrader 一行加佣金、一行加滑点再配夏普比率、最大回撤、胜率等分析器交叉验证虚高的数字当场现形。从 0 到看见第一个回测结果10 分钟装一个包就够无外部依赖只有画图时才需要 matplotlibpip install backtrader官方samples/下有 60 多个示例但不少依赖在线数据。这里用仓库自带的本地 CSV 数据写一个最小脚本保存为myfirst.py直接跑import backtrader as bt import datetime class SmaCross(bt.Strategy): params dict(fast10, slow30) def __init__(self): fast bt.ind.SMA(self.data.close, periodself.p.fast) slow bt.ind.SMA(self.data.close, periodself.p.slow) self.cross bt.ind.CrossOver(fast, slow) def next(self): if not self.position and self.cross 0: self.buy() # 空仓且金叉 → 买入 elif self.position and self.cross 0: self.close() # 持仓且死叉 → 平仓 cerebro bt.Cerebro() cerebro.addstrategy(SmaCross) data bt.feeds.BacktraderCSVData(datanamedatas/2005-2006-day-001.txt) cerebro.adddata(data) cerebro.broker.setcash(100000.0) # 初始资金 10 万 cerebro.run() print(f最终资金: {cerebro.broker.getvalue():.2f})你会看到一行最终资金数字跟 100000 一对比就知道赚没赚。脚本末尾再加cerebro.plot()会弹出一张带均线、买卖点标记和资金曲线的 K 线图——这是策略行不行最直观的形态。数据文件datas/2005-2006-day-001.txt的格式是Date,Open,High,Low,Close,Volume,OpenInterest正好是BacktraderCSVData的默认格式拿来即用不用清洗。核心概念速览3 个就够你上手Cerebro回测的中央厨房一句话定义Cerebro是回测引擎负责组装数据、策略、资金和分析器然后统一启动。类比像餐厅的中央厨房厨师策略、食材数据、菜单资金设置都挂在它身上厨房一开火菜就端出来了。引擎源码在backtrader/cerebro.py本文所有代码都围着它转。Strategy 与 next()策略的做菜节奏一句话定义策略类继承bt.Strategy__init__只声明指标next()每根 K 线调用一次做决策。类比__init__是写菜谱用什么料、拿什么工具next()是每天开火炒一道self.data.close[0]是今天的收盘价、[-1]是昨天的。模块见 backtrader/strategy.py同文件还定义了notify_order订单状态和notify_trade成交回报回调。Indicator122 个内置指标全部惰性计算一句话定义bt.ind.SMA / EMA / RSI / MACD等指标吃进数据、吐出一条新的时间序列。类比温度计——数据不够时不显示读数预热后才开始输出SMA(30) 前 29 根 K 线拿不到值。模块在 backtrader/indicators/共 122 个内置指标支持close sma这类自由组合运算。场景实战用 backtrader 达成 3 个目标 双均线策略 10 分钟跑通还要加止损想法是金叉买入、死叉平仓再挂个 2% 跟踪止损防止利润回吐。在最小脚本基础上买入后给持仓挂一笔StopTrail订单class StopTrailCross(bt.Strategy): params dict(fast10, slow30, trail0.02) def __init__(self): fast bt.ind.EMA(self.data.close, periodself.p.fast) slow bt.ind.EMA(self.data.close, periodself.p.slow) self.crup bt.ind.CrossUp(fast, slow) # 金叉信号 self.order None def next(self): if not self.position and self.crup 0: self.buy() # 金叉买入 self.order None elif self.position and self.order is None: # 跟踪止损从最高点回落 2% 触发卖出 self.order self.sell(exectypebt.Order.StopTrail, trailpercentself.p.trail)cerebro 的组装部分和最小脚本完全一致。跑完看图表有些卖出点附近并没有死叉那就是止损在干活。常见的坑市价单在下一根 K 线开盘价成交金叉次日如果跳空低开成交价会比预期差——这是贴近现实的设定不是 bug。仓位风险怎么设才合理Sizer 一行搞定backtrader 默认每次买 100 股FixedSize——10 万本金买 3000 块一股的东西一笔就占用三成仓位显然不合理。Sizer专门负责计算这次买多少继承bt.Sizer写_getsizing即可class RiskSizer(bt.Sizer): params dict(risk0.02) # 单笔最多亏总资金的 2% def _getsizing(self, comminfo, cash, data, isbuy): stop_dist data.close[0] * 0.02 # 假设止损距离 2% return int(cash * self.p.risk / stop_dist) cerebro.addsizer(RiskSizer)逻辑我能承受亏的钱 资金 × 2%除以每股止损金额就是能买的股数——风险预算固定仓位随价格自动伸缩。内置的PercentSizerInt按可用现金百分比等也都在backtrader/sizers/里可直接用。坑返回值必须取整股票按整数股交易忘了int()订单会被拒。回测结果靠不靠谱3 个分析器交叉验证赚了钱只是第一步赚得靠谱才是问题。给同一个 cerebro 加成本和三个分析器cerebro.broker.setcommission(commission0.001) # 0.1% 佣金 cerebro.broker.set_slippage_perc(perc0.001) # 0.1% 滑点 cerebro.addanalyzer(bt.analyzers.SharpeRatio, _namesharpe, timeframebt.TimeFrame.Days, annualizeTrue) cerebro.addanalyzer(bt.analyzers.DrawDown, _namedd) cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _nametrades) # ... 运行后取结果 strat cerebro.run()[0][0] print(strat.analyzers.sharpe.get_analysis()[sharperatio]) print(strat.analyzers.dd.get_analysis()[max][drawdown])输出怎么读夏普比率年化后 1 尚可、2 不错drawdown是最大回撤百分比超过 30% 得问问自己真拿得住吗TradeAnalyzer给总笔数、胜率trades[won][total] / trades[total][total]和盈亏分布用来判断是运气好还是真有边际。坑忘了annualizeTrue算出来的是日频夏普差一个约 16 倍的年化因子跟别人的数字没法比。回测结果不对先查这 3 处 ⚠️现象 1日志出现 Order Rejected一笔单都没开出来根因默认FixedSize买 100 股股价一高现金不够订单直接被拒。修复cerebro.addsizer(bt.sizers.PercentSizerInt, percents95) # 用 95% 现金现象 2回测收益高得离谱和实盘完全两回事根因没设佣金和滑点每笔交易都是零成本成交。修复cerebro.broker.setcommission(commission0.001) cerebro.broker.set_slippage_perc(perc0.001)现象 3成交价不是我看到的那根 K 线价格根因不是 bug——市价单在下一根 K 线开盘执行当前这根的收盘价只是信号时点。如果你确实要按收盘价成交更理想化显式指定self.buy(exectypebt.Order.Close) # 按当前 K 线收盘价执行下一步行动清单改最小脚本里的两个数字fast5, slow15再跑一遍——预期交易次数明显变多最终资金因成本增加而缩水直观感受过拟合。跑一次参数网格进入samples/optimization/目录执行python optimization.py --ma_low 5 --ma_high 15——预期逐组输出各参数组合的指标看哪个区间稳定而不是单点最优。看一个单元测试执行python tests/test_ind_rsi.py——预期RSI 指标测试通过顺便学它喂数据→比数值的验证姿势以后写自定义指标可以照搬。跑一个带图的完整示例python samples/sigsmacross/sigsmacross2.py需联网拉 Yahoo 数据——预期看到均线、买卖标记和资金曲线齐全的图表。资源入口官方示例目录 samples/60 个可直接运行的脚本、测试用例 tests/83 个文件的正确用法参考、指标库backtrader/indicators/、changelog.txt版本变更记录。写在最后记不住也没关系就记一条把 20 行最小脚本跑起来改两个数字再跑一遍。看到数字随参数动起来你就上路了——仓库里的示例脚本现在就能跑挑一个动手试试。【免费下载链接】backtraderPython Backtesting library for trading strategies项目地址: https://gitcode.com/gh_mirrors/ba/backtrader创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表