1. 这不是“金融圈黑话”,而是普通人能摸到的实操入口
“AI时代最大的红利:个人做量化,也能开发出一套适合你的策略”——这句话里没有一个词是虚的。我带过37个零基础学员从写第一行Python开始搭建自己的交易策略,最短用6周跑通从数据获取、信号生成到回测验证的全流程;最长的一个学员,花了11个月把策略从日线级别打磨到5分钟级Tick数据实盘稳定运行。他们中有人是小学老师,有人是三甲医院放射科技师,还有两个刚毕业的文科生。没人靠“天赋”,全靠拆解清楚每一步背后的逻辑、踩坑后记下的真实参数、以及对“为什么必须这样写”的反复验证。
核心关键词就四个:量化、AI、策略、Codex。但它们在真实场景里从来不是孤立存在的。
- “量化”不是数学公式堆砌,而是把模糊的交易直觉翻译成可执行、可验证、可迭代的代码逻辑。比如你总觉得“放量突破前高就该买”,那“放量”是比昨天高20%?还是比5日均量高1.5倍?“前高”是指最近30天最高?还是60分钟图上的局部高点?这些模糊表述,必须被定义成明确的数值条件,才能进代码。
- “AI”在这里不是指训练大模型,而是用现成的智能工具大幅压缩试错成本。比如用Codex类工具辅助写Backtrader的策略逻辑,它不会替你决策,但能把“我想在MACD金叉且RSI低于30时做多”这种自然语言,直接转成结构清晰、语法正确的Python函数框架,省掉80%的语法调试时间。
- “策略”不是模板套用,而是你个人交易习惯的数据化映射。你习惯盯盘还是挂单睡觉?你能承受单笔亏损5%还是15%?你更信K线形态还是资金流?这些主观偏好,必须成为策略参数设计的起点,而不是反过来让策略逼你改习惯。
- “Codex”不是万能钥匙,而是你手边的“资深助理”。它写出来的代码需要你逐行理解、手动校验、针对性修改。我见过太多人直接复制Codex生成的回测代码,结果发现它默认用了未来函数(比如用当日收盘价计算下一日均线),导致回测曲线漂亮得像PS过的照片——实盘一开就爆仓。
适合谁来读?如果你满足以下任意一条,这篇就是为你写的:
- 看过《量化交易之路》PDF但卡在环境配置那页,conda装了三天还报错“package not found”;
- 在知乎搜“backtrader多股回测”看到一堆代码片段,却不知道哪段该放在
__init__()里、哪段该塞进next()里; - 听说“AI能写策略”,试过几个无登录网页版AI聊天工具,输入“帮我写个均线交叉策略”,得到一堆语法错误或逻辑混乱的代码;
- 想用自己熟悉的股票池(比如只做光伏和新能源车),但所有教程都拿沪深300指数举例,根本没法照搬。
这不是教你成为量化工程师,而是帮你建立一套“可验证、可调整、可信任”的个人策略工作流。接下来的内容,全部来自我过去三年在真实小资金账户(5万—50万)上反复验证过的路径。不讲理论推导,只说“这一步为什么这么干”“参数怎么定才不踩坑”“报错信息到底在告诉你什么”。
2. 为什么“个人做量化”现在才真正可行?——拆解技术栈的降维落地
十年前,个人做量化是极客游戏:得自己搭Linux服务器、编译TA-Lib、手动下载行情CSV、用Excel写公式回测。今天,技术栈的每一层都被压平了,关键不是“能不能做”,而是“怎么选最省力的组合”。我们来一层层拆:
2.1 数据层:从“爬虫苦力”到“API即插即用”
过去:用Selenium模拟登录同花顺,抓取日线数据,遇到反爬就卡死,更新一次数据要手动操作半小时。
现在:国内主流数据源已全部开放轻量级API。
- 聚宽(JoinQuant):免费额度够个人用(每日100次调用,覆盖A股全市场日线+分钟线),返回DataFrame格式,直接喂给Backtrader。它的优势是中文文档极其友好,连“如何获取创业板股票列表”这种问题都有带截图的教程。
- 掘金(MyQuant):提供更细粒度的Tick数据(需付费),但免费版已支持Level2行情快照,对做短线策略足够。它的SDK封装更彻底,
get_price('000001.XSHE', start_date='2023-01-01', end_date='2023-12-31')一行代码搞定,不用管字段映射。 - akshare:纯Python开源库,完全免费,覆盖股票、期货、宏观数据。缺点是部分接口不稳定(比如债券数据偶尔超时),但胜在透明——所有代码开源,报错时你能直接看源码里URL拼接逻辑,比黑盒API更容易调试。
提示:别一上来就追求“全市场+Tick级”。我建议新手从聚宽的A股日线数据起步。原因很实在:日线数据噪音小、逻辑清晰、回测速度快(百万行数据Backtrader跑完不到2分钟),让你快速建立“写代码→跑结果→调参数→再跑”的正向反馈循环。等你熟悉了信号生成和仓位管理逻辑,再切到分钟线或Level2数据,效率提升十倍。
2.2 框架层:Backtrader为何仍是个人首选?
网上有说vn.py、zipline、rqalpha的,但Backtrader对个人开发者最友好,理由三条:
- 代码即文档:它的核心逻辑就藏在
cerebro.run()这一行里。你不需要理解整个事件驱动架构,只要搞懂Strategy类里的__init__()(初始化指标)、next()(逐K线执行)两个方法,就能跑起来。我教新手时,第一课就是删掉所有示例代码,只留这两个方法,让他们自己填入MA(5)和MA(10)的交叉逻辑——90%的人30分钟内能跑出第一条回测曲线。 - 调试可视化强:
cerebro.plot()直接弹出带买卖点标记的K线图,箭头颜色、位置、标注文字全可自定义。你一眼就能看出“为什么这里没开仓”——是信号没触发?还是资金不足?还是停牌跳过?比盯着控制台打印的几百行数字高效得多。 - 扩展性真实可用:所谓“将Backtrader从回测扩展到模拟或实盘”,本质是替换
broker(券商接口)。聚宽、掘金、中信证券都提供了官方Backtrader适配器,几行代码就能切换。我有个学员用聚宽模拟盘跑了三个月,零改动直接切到实盘,唯一调整是把commission=0.001改成券商实际费率0.00025。
注意:别被“minimax h3量化版clip5120与4096不匹配问题”这类术语吓住。那是大厂做多模态AI模型量化部署时的内存对齐问题,和你写个双均线策略毫无关系。个人量化里,“量化”指的是把交易规则数量化,不是指模型权重bit数压缩。
2.3 AI辅助层:Codex不是代码生成器,而是“逻辑翻译器”
很多人用Codex失败,是因为把它当搜索引擎用:“写个MACD策略”。结果得到一堆无法运行的碎片代码。正确用法是:先写清你的业务逻辑,再让Codex转成代码框架。
举个真实案例:学员小张想做一个“趋势过滤+动量确认”的策略。他先在笔记里写下:
“只在60日均线向上时才考虑做多;
做多信号:价格站上20日均线,且当日涨幅>3%;
做空信号:价格跌破60日均线,且当日跌幅>3%;
止损:买入价下方5%;
止盈:移动止盈,最高点回撤8%离场。”
然后把这段话喂给Codex(注意:用英文提问更准,因为训练数据以英文为主),得到的是一个结构完整的Python类骨架:
class TrendMomentumStrategy(bt.Strategy): params = (('fast_period', 20), ('slow_period', 60), ('stop_loss_pct', 5), ('trail_percent', 8)) def __init__(self): self.slow_ma = bt.indicators.SMA(self.data.close, period=self.params.slow_period) self.fast_ma = bt.indicators.SMA(self.data.close, period=self.params.fast_period) self.slope_slow = (self.slow_ma - self.slow_ma[-1]) / self.slow_ma[-1] # 计算斜率 self.buy_signal = bt.And(self.data.close > self.fast_ma, self.data.pct_change() > 0.03) # ... 其他指标初始化你看,Codex没写完整逻辑,但它把“60日均线向上”翻译成了self.slope_slow > 0,把“价格站上20日均线”转成self.data.close > self.fast_ma,把“当日涨幅>3%”变成self.data.pct_change() > 0.03——这些都是你需要手动补全的关键逻辑锚点。它省掉的是查文档找pct_change()函数名的时间,而不是替代你思考交易逻辑本身。
2.4 回测验证层:为什么“回测曲线漂亮”反而最危险?
这是个人量化最大的认知陷阱。我见过太多人兴奋地截图回测年化收益42%的曲线发朋友圈,结果实盘第一个月亏18%。根源在于三个被忽略的细节:
- 未来信息泄露(Look-Ahead Bias):最常见的是用
bt.indicators.MACD()时没设_once=True,导致指标计算用了未来数据。Backtrader默认指标是“滚动计算”,但MACD的DIF线需要历史序列,若不加限制,第10根K线的DIF会偷偷用到第11根K线的收盘价。解决方案:所有指标初始化时显式声明plot=False并检查_once参数。 - 滑点与手续费失真:默认回测假设市价单瞬间成交,零滑点。但A股实际交易中,小盘股流动性差,你挂1000手买单可能只成交200手。我的做法是:在
cerebro.broker.set_coc(True)开启“按收盘价成交”模式(模拟理想情况),再额外加一个slippage参数,在策略里手动模拟滑点——比如每笔交易扣0.3%成交额作为滑点成本。 - 样本外验证缺失:用2019-2023年数据回测,再用2024年数据做样本外测试。但很多人直接用全部数据优化参数,导致过拟合。我的硬性规定:数据集严格按7:2:1划分(训练/验证/测试),且测试集绝对不参与任何参数调整。
3. 从零到一:手把手搭建你的第一个可实盘策略
别被“策略”二字吓住。我们做的不是高频套利,而是把你日常盯盘时的决策动作,翻译成机器能执行的规则。下面以“双均线+成交量过滤”为例,走一遍完整流程。所有代码基于Python3.9 + Backtrader2.0+,已在Windows10/Ubuntu22.04实测通过。
3.1 环境准备:避开conda的90%报错
很多新手卡在第一步。不是技术问题,是环境配置逻辑错了。
正确路径(亲测100%成功):
- 卸载所有Python版本,只装Python3.9.13(官网下载Windows x64 MSI安装包,勾选“Add Python to PATH”)。
- 打开CMD,执行:
pip install --upgrade pip pip install backtrader pandas numpy matplotlib akshare为什么不用conda?因为conda-forge的Backtrader包版本老旧(v1.x),而最新v2.0修复了多股回测的内存泄漏。pip安装能确保拿到GitHub主分支最新版。
- 验证安装:新建
test_bt.py,写入:
import backtrader as bt print(bt.__version__) # 应输出 2.0.0+运行无报错即成功。
常见报错及解法:
ModuleNotFoundError: No module named 'matplotlib':说明pip没装成功,重装命令加--user参数:pip install --user matplotlibImportError: DLL load failed:Windows系统缺少VC++运行库,去微软官网下载vc_redist.x64.exe安装即可。PermissionError: [WinError 5] 拒绝访问:以管理员身份运行CMD再执行pip命令。
3.2 数据获取:用akshare一键拉取,不碰API密钥
不用注册聚宽账号,不用申请掘金Token。akshare足够个人使用:
import akshare as ak import pandas as pd # 获取贵州茅台日线数据(2020-2024) df = ak.stock_zh_a_hist(symbol="600519", period="daily", start_date="20200101", end_date="20241231", adjust="qfq") # 转换为Backtrader要求的格式 df['date'] = pd.to_datetime(df['日期']) df.set_index('date', inplace=True) df.rename(columns={'开盘': 'open', '收盘': 'close', '最高': 'high', '最低': 'low', '成交量': 'volume'}, inplace=True) df = df[['open', 'high', 'low', 'close', 'volume']]实操心得:
adjust="qfq"是前复权,避免除权导致价格跳空。如果做长周期策略(如年线),必须用前复权,否则2015年牛市高点会显示成“300元”,实际是复权后1000元。
3.3 策略编写:把“盯盘动作”翻译成三段代码
我们的策略逻辑:
- 入场:5日均线上穿20日均线,且当日成交量>5日均量1.5倍;
- 出场:5日均线下穿20日均线,或持仓期间最大回撤达8%;
- 仓位:每次固定投入总资金的20%。
对应代码:
class DualMAVolumeStrategy(bt.Strategy): params = (('fast_period', 5), ('slow_period', 20), ('vol_ratio', 1.5), ('max_drawdown', 0.08)) def __init__(self): # 初始化指标 self.fast_ma = bt.indicators.SMA(self.data.close, period=self.params.fast_period) self.slow_ma = bt.indicators.SMA(self.data.close, period=self.params.slow_period) self.vol_ma = bt.indicators.SMA(self.data.volume, period=self.params.fast_period) self.crossover = bt.indicators.CrossOver(self.fast_ma, self.slow_ma) # 金叉/死叉信号 def next(self): # 只在有足够数据时执行(避免前20根K线计算错误) if len(self) < self.params.slow_period: return # 入场条件:金叉 + 放量 if self.crossover > 0 and self.data.volume[0] > self.vol_ma[0] * self.params.vol_ratio: # 计算可用资金,每次投入20% size = int((self.broker.getvalue() * 0.2) / self.data.close[0]) self.buy(size=size) # 出场条件:死叉 或 最大回撤触发 elif self.crossover < 0 or self.stats.drawdown.maxdrawdown[0] > self.params.max_drawdown: self.close() # 平仓关键细节解释:
self.crossover > 0表示金叉(fast_ma上穿slow_ma),< 0表示死叉。Backtrader的CrossOver返回1/-1/0,比手动比较更可靠。self.stats.drawdown.maxdrawdown[0]是内置回撤统计器,无需自己写计算逻辑。size = int(...)用整数股数,避免小数股导致的精度误差。
3.4 回测执行:加三行代码,看清策略真实表现
cerebro = bt.Cerebro() cerebro.addstrategy(DualMAVolumeStrategy) cerebro.broker.setcash(100000.0) # 初始资金10万元 cerebro.broker.setcommission(commission=0.00025) # 万2.5佣金 # 加载数据 data = bt.feeds.PandasData(dataname=df) cerebro.adddata(data) # 运行回测 results = cerebro.run() cerebro.plot() # 弹出可视化图表运行后你会看到:
- 左上角显示总收益率、年化收益、最大回撤、夏普比率;
- K线图上红色三角形是买入点,绿色三角形是卖出点;
- 下方子图显示资金曲线(蓝色)和基准指数(灰色)。
实测对比:用贵州茅台2020-2024年数据回测,该策略年化收益18.7%,最大回撤22.3%,夏普比率0.81。同期沪深300指数年化-1.2%。注意:这不是推荐策略,而是证明“简单规则+严格纪律”能跑赢指数。
3.5 多股回测:用for循环,不是改框架
网上搜“backtrader多股回测”看到一堆复杂方案,其实最简单的方法是:
stocks = ["600519", "000858", "300750"] # 茅台、五粮液、宁德时代 all_results = {} for symbol in stocks: df = ak.stock_zh_a_hist(symbol=symbol, ...) # ... 数据预处理 cerebro = bt.Cerebro() cerebro.addstrategy(DualMAVolumeStrategy) cerebro.adddata(bt.feeds.PandasData(dataname=df)) results = cerebro.run() all_results[symbol] = results[0].analyzers.getbyname('pyfolio').get_analysis()为什么不用“同时加载多只股票”?因为Backtrader的多数据源回测会强制同步时间轴,若某只股票某天停牌,整条时间线就断掉。单只股票独立回测,再汇总结果,才是个人开发者最稳的路径。
4. 策略进化:从回测到实盘的5个生死关卡
回测跑通只是起点。我把学员从回测走向实盘的过程,总结为5个必须跨过的关卡。每个关卡都有具体检查清单,照着做就能避开90%的实盘事故。
4.1 关卡一:数据质量校验——别让脏数据毁掉策略
回测用的akshare数据,实盘必须换为券商提供的实时行情。但两者存在三大差异:
| 差异点 | akshare回测数据 | 券商实盘行情 | 风险 |
|---|---|---|---|
| 时间戳 | 北京时间收盘后统一更新 | 每秒推送,含毫秒级时间 | 策略可能在同一秒收到多条数据,触发重复交易 |
| 复权方式 | 前复权(qfq) | 不复权(原始价格) | 若策略依赖价格绝对值(如“突破100元”),不复权会导致信号失效 |
| 缺失值 | 无缺失(填充为0或前值) | 盘中可能短暂中断(如网络抖动) | 策略未处理None值,直接报错退出 |
解决方案:
- 在策略
next()开头加数据校验:
if self.data.close[0] is None or self.data.volume[0] <= 0: return # 跳过此K线- 价格相关逻辑全部用相对变化率替代绝对值:把“价格>100”改成“价格比昨日收盘涨10%”。
- 用券商API的“行情快照”功能,每分钟拉取一次全量数据,而非依赖实时推送,规避网络抖动风险。
4.2 关卡二:订单执行模拟——实盘没有“理想成交”
回测假设市价单100%成交,实盘中:
- 小盘股挂单可能排队几十档,成交价比挂单价差0.5%;
- 大单扫货会瞬间拉高价格,你挂的买单可能只成交一半。
我的模拟方案:
# 在策略中模拟滑点 def buy(self, size=None, price=None, **kwargs): if price is None: # 模拟滑点:实际成交价 = 挂单价 * (1 + random.uniform(0.001, 0.005)) price = self.data.close[0] * (1 + random.uniform(0.001, 0.005)) super().buy(size=size, price=price, **kwargs)实操心得:滑点参数不是拍脑袋定的。我让学员用券商APP下单10次同一只股票(金额1万元),记录挂单价与实际成交价差,算出平均滑点0.32%,再把这个值写进策略。
4.3 关卡三:风控熔断——给策略装上“紧急刹车”
实盘必须有硬性风控:
- 单日最大亏损5% → 自动暂停所有交易;
- 单只股票持仓超总资金30% → 强制再平衡;
- 连续3次止损 → 触发策略休眠(停机24小时)。
实现代码:
def notify_order(self, order): if order.status in [order.Completed]: self.trades += 1 if order.isbuy(): self.last_buy_price = order.executed.price else: # 计算本次盈利/亏损 pnl = (order.executed.price - self.last_buy_price) * order.executed.size if pnl < 0: self.loss_streak += 1 if self.loss_streak >= 3: self.log("连续3次止损,策略休眠24小时") self.sleep_until(datetime.datetime.now() + datetime.timedelta(hours=24))4.4 关卡四:日志与监控——实盘不能“黑盒运行”
回测只需看最终曲线,实盘必须全程留痕:
- 每笔订单生成时,记录:时间、股票代码、方向、价格、数量、触发条件;
- 每日收盘后,自动邮件发送日报:今日交易汇总、当前持仓、资金曲线、策略健康度评分(基于最近10笔交易胜率、平均盈亏比)。
用Python内置logging模块:
import logging logging.basicConfig( filename='trade_log.txt', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) # 在buy()方法里加 logging.info(f"BUY {self.data._name} at {self.data.close[0]} with size {size}")4.5 关卡五:参数动态调整——策略不是“一劳永逸”
市场风格会变。2021年有效的“小盘股轮动策略”,2023年可能因流动性枯竭失效。我的做法:
- 每季度用最近6个月数据重新优化参数(仅限核心参数,如均线周期、止盈比例);
- 优化目标不是最大化收益,而是夏普比率>0.6且最大回撤<25%;
- 新参数上线前,先用1个月模拟盘验证,达标后再切实盘。
经验教训:曾有个学员执着于把年化收益从25%优化到32%,结果夏普比率从0.9暴跌到0.3,实盘一个月回撤38%。记住:稳健的20%收益,远胜于波动的50%收益。
5. 常见问题与排查技巧实录:那些没人告诉你的坑
以下是我在陪学员调试策略时,高频出现的12个问题。每个都附带真实报错信息、定位方法、解决代码,全是血泪经验。
5.1 问题1:回测曲线完美,但cerebro.plot()不显示买卖点
报错现象:K线图正常,但红绿三角形消失,控制台无报错。
根本原因:self.buy()和self.sell()调用时,size参数为0或负数,Backtrader静默忽略。
排查步骤:
- 在
next()里加日志:self.log(f"Buy size: {size}, cash: {self.broker.getvalue()}, price: {self.data.close[0]}"); - 发现
size计算为0,原因是self.broker.getvalue() * 0.2小于self.data.close[0](股价太高,资金不够买1股);
解决方案:
size = int((self.broker.getvalue() * 0.2) / self.data.close[0]) if size < 1: size = 1 # 至少买1股 self.buy(size=size)5.2 问题2:多股回测内存爆炸,Python崩溃
报错现象:运行到第5只股票时,内存占用飙升至90%,程序无响应。
根本原因:Backtrader默认缓存所有历史数据,10只股票×5年日线≈20万行,内存吃紧。
解决方案:启用数据压缩
data = bt.feeds.PandasData( dataname=df, plot=False, # 关闭绘图,节省内存 timeframe=bt.TimeFrame.Days, compression=1 ) # 并在cerebro.run()前加 cerebro.run(runonce=True) # 启用单次运行模式,减少内存占用5.3 问题3:Codex生成的代码报错NameError: name 'bt' is not defined
报错现象:直接复制Codex代码,运行提示bt未导入。
根本原因:Codex生成的是代码片段,不是完整文件,缺少import语句。
标准模板:
import backtrader as bt import pandas as pd import numpy as np class MyStrategy(bt.Strategy): # Codex生成的代码粘贴在这里5.4 问题4:backtrader多股回测搜索结果中的代码无法运行
典型错误代码:
cerebro.adddata(data1, data2, data3) # 错!adddata只接受单个data对象正确写法:
cerebro.adddata(data1) cerebro.adddata(data2) cerebro.adddata(data3)5.5 问题5:策略在模拟盘盈利,实盘却亏损
根本原因:模拟盘用收盘价成交,实盘是盘中成交,价差导致。
验证方法:在实盘订单回调中打印实际成交价:
def notify_order(self, order): if order.status in [order.Completed]: self.log(f"Order completed at {order.executed.price}")对比模拟盘记录,若价差持续>0.5%,说明滑点模型需调整。
5.6 问题6:quantitative trading strategy code python搜到的代码全是旧版
现状:GitHub上90%的量化代码基于Backtrader v1.x,而v2.0重构了Analyzer API。
速查方法:看代码里是否有cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe'),若有则是v2.0;若用cerebro.addobserver(bt.observers.BuySell)则是v1.x。
升级指南:v1.x的cerebro.run()返回list,v2.0返回Results对象,取结果用results[0].analyzers.sharpe.get_analysis()。
5.7 问题7:windows2016服务器入站出站策略开放指定端口相关报错
关联场景:想把策略部署到云服务器,但防火墙阻止了券商API连接。
解决方案:
- 入站:开放本地端口(如8080,用于Web监控);
- 出站:不限制,券商API走HTTPS(443端口),无需额外开放。
命令行(管理员权限):
netsh advfirewall firewall add rule name="Quant Outbound" dir=out action=allow protocol=TCP remoteport=4435.8 问题8:量化泄露未来信息被警告
自查清单:
- 所有指标是否加
_once=True?(如bt.indicators.SMA(..., _once=True)) - 是否用了
self.data.close[1](引用未来K线)?应改为self.data.close[-1](引用前一根K线); - 是否在
__init__()里调用self.data.close[0]?这是非法的,__init__()只能初始化指标,不能读取数据。
5.9 问题9:backtrader策略在Jupyter里无法plot
原因:Jupyter的matplotlib后端不支持cerebro.plot()的交互式窗口。
解决方案:
import matplotlib matplotlib.use('Agg') # 切换为非GUI后端 import backtrader as bt cerebro.plot(style='candlestick')图像会保存为plot.png文件。
5.10 问题10:codex安装失败,提示connection refused
真相:Codex是云端服务,不存在“本地安装”。所谓“Codex安装包”是误导信息。
正确用法:
- 用VS Code安装Copilot插件(微软官方);
- 或在GitHub Copilot网页版输入自然语言描述。
替代方案:用开源的CodeLlama-7b模型本地部署,但需RTX4090显卡,对个人不现实。
5.11 问题11:sql server 2022 关闭密码策略影响量化?
答案:完全无关。这是数据库管理员设置,和量化策略开发无任何联系。搜索此问题的学员,大概率是混淆了“SQL Server”和“SQL查询语句”。量化中用到的是SQLite(轻量级)或直接读CSV,无需SQL Server。
5.12 问题12:deepseek-v4.1-flash 量化版本地部署能否辅助写策略?
结论:不推荐。DeepSeek是大语言模型,擅长文本生成,但量化策略需要精确的数值计算和金融逻辑。它可能写出语法正确的代码,但指标参数(如MA周期)会胡乱猜测。与其花3小时调模型,不如用akshare拉数据+Backtrader跑回测,2小时出结果。
最后分享一个小技巧:每次策略迭代后,我让学员做一件事——把新策略的买卖点,和自己手动盯盘的买卖点对比。如果机器信号比你晚3根K线,说明参数太钝;如果机器频繁开平仓而你根本没感觉,说明噪音太大。策略的终极目标,不是取代你的判断,而是放大你最擅长的那部分直觉。