
1. 为什么说现在是个人做量化的最好窗口期我接触量化交易差不多有七八年时间最早那会儿一个普通人想跑一套自己的策略门槛高得离谱。数据要自己爬、清洗要自己写、回测框架要自己搭、服务器要自己租光是把环境跑通就得折腾掉半条命。那时候圈子里流行一句话做量化的第一步不是写策略而是先把自己熬成一个全栈工程师。这话一点不夸张我见过太多有想法的人卡在数据源和回测框架上策略逻辑还没验证就先放弃了。这两年情况完全变了。AI 工具把写代码这件事的门槛砸到了地板上你不需要背语法、不需要记 API只要能把逻辑讲清楚代码基本能给你生成个七七八八。与此同时公开的行情数据接口越来越规范回测框架也越来越成熟像 backtrader 这类工具社区文档齐全遇到问题搜一下基本都有答案。量化、AI、策略、ETF这几个词凑在一起恰好构成了当下个人投资者最值得投入的一个方向。这篇文章我想聊的不是什么高深的理论而是一个普通人在 AI 时代怎么用最低的成本、最短的路径开发出一套真正适合自己、能跑起来、能持续迭代的量化策略。我会把整个流程拆开讲包括思路怎么定、工具怎么选、代码怎么写、坑怎么避。适合的人群很明确有一点编程基础或者愿意借助 AI 写代码、手里有闲钱想做系统化投资、不想天天盯盘但又想跑赢通胀的普通人。哪怕你之前完全没碰过量化跟着思路走一遍也能搭出属于自己的第一套策略。2. 先想清楚个人量化到底在做什么2.1 量化不是预测涨跌而是管理概率很多人对量化的第一印象是用电脑算出明天哪只股票会涨这个理解从根上就偏了。量化的本质不是预测而是用规则化的方式在大量重复的交易中获取统计上的正期望。你不需要每次都猜对你只需要保证在足够多的交易次数下赢的时候赚的比输的时候亏的多。打个比方量化就像开一家赌场赌场从来不关心某一局谁赢谁输它只关心规则设计得让自己长期有优势。个人做量化也是这个逻辑你的策略就是你的赌场规则只要这个规则在历史数据上被验证过有正期望剩下的就是执行纪律的问题。这个认知非常重要因为它直接决定了你后面所有的设计取向。如果你抱着我要预测明天的心态去做你会陷入不断调参、不断过拟合的死循环如果你抱着我要设计一套长期有优势的规则的心态你会更关注策略的稳健性、交易成本、风险控制这些真正重要的东西。2.2 个人量化的三个现实约束在动手之前必须认清个人做量化面临的三个硬约束这决定了你的策略应该长什么样。第一是资金规模约束。个人资金量通常不大这意味着两件事一是你无法通过分散持仓来大幅降低个股风险二是交易成本对你的收益侵蚀比例会更高。所以个人策略应该尽量选择流动性好、交易成本低的标的ETF 就是非常合适的选择。第二是信息约束。你没有机构的研究团队、没有付费的高频数据、没有内幕消息渠道。所以你的策略不应该建立在信息优势上而应该建立在纪律优势和耐心优势上——这两点恰恰是散户相对机构最大的优势因为机构有业绩考核压力不能长期空仓等待而你可以。第三是精力约束。你有本职工作不可能全天盯盘。所以策略应该是低频的、可以自动化执行的最好是每天收盘后跑一次信号第二天开盘执行不需要盘中干预。2.3 什么样的策略适合个人综合上面三个约束适合个人的策略画像就很清晰了低频、基于 ETF、规则简单、逻辑可解释、能承受一定回撤。具体来说趋势跟踪类、均值回归类、轮动类策略都比较适合。相反高频交易、套利、需要复杂衍生品建模的策略个人基本没有胜算。我个人的偏好是趋势跟踪加轮动。原因很简单趋势跟踪的逻辑符合人性对追涨杀跌的直觉但用量化的方式执行反而能克服情绪轮动则能在不同资产之间切换平滑收益曲线。这两个思路结合起来用 ETF 作为标的交易频率控制在每周或每月调仓一次非常适合上班族。3. 工具选型AI 时代的最优组合3.1 回测框架怎么选回测框架是量化的基础设施选对了能省下大量时间。市面上主流的几个框架我都用过简单说说各自的适用场景。框架优势劣势适合人群backtrader文档全、社区活跃、事件驱动、支持多标的学习曲线略陡、性能一般想系统学习量化的新手vectorbt向量化计算、速度快、适合参数扫描内存占用高、调试不直观有一定基础、要做参数优化的人zipline机构级、功能完整安装麻烦、维护停滞有工程背景的老手自己写完全可控、轻量容易有隐藏 bug想深入理解原理的人对绝大多数个人来说我推荐从backtrader入手。它的抽象层次刚刚好既不会像自己写那样容易出错也不会像机构框架那样复杂到劝退。而且它的社区足够大你遇到的绝大多数问题网上都能搜到答案。3.2 AI 工具在量化流程中的定位AI 工具比如各类代码助手在量化开发中的定位我的经验是它是加速器不是决策者。具体来说它能帮你做这几件事把策略逻辑翻译成代码省去查语法的时间帮你写数据清洗、格式转换这类重复性代码解释报错信息给出排查方向帮你把策略代码重构得更清晰但它不能帮你做的是判断策略逻辑是否合理、决定参数怎么设、评估策略是否过拟合。这些需要你自己的判断因为 AI 不知道你的风险偏好、不知道你的资金规模、不知道你对回撤的容忍度。我踩过的一个坑是早期太依赖 AI 生成策略代码结果生成出来的策略在历史数据上表现极好实盘一跑就亏。后来才明白AI 生成的代码往往隐含了未来函数用了当天收盘价做当天决策这种错误在回测里看不出来实盘就露馅了。所以 AI 生成的代码你必须逐行审查尤其是涉及数据对齐的部分。3.3 数据源的选择数据是量化的燃料。个人能用的免费数据源其实不少主流的几个akshare覆盖股票、ETF、期货、宏观数据接口友好更新及时是我目前的主力数据源tushare老牌数据源部分接口需要积分但基础数据免费够用baostock免费、稳定适合做历史回测我的建议是主力用 akshare因为它对 ETF 数据的支持比较好而且接口设计符合直觉。数据获取这块AI 能帮你省很多事你只要告诉它我要获取某只 ETF 从某年到某年的日线数据它基本能给你写出可运行的代码。4. 从零搭建一套 ETF 轮动策略4.1 策略逻辑设计我拿一个实际跑过的策略来举例逻辑很简单在几个不同风格的 ETF 之间做动量轮动。具体规则是选定一个 ETF 池比如沪深300、中证500、创业板、黄金、国债这几个每个调仓周期比如每周五收盘计算每个 ETF 过去 N 天的涨幅买入涨幅最高的那个如果所有 ETF 的涨幅都为负则空仓或买入国债下一个调仓周期重复这个策略的核心假设是动量效应过去一段时间表现好的资产短期内倾向于继续表现好。这个假设在 A 股市场被大量研究验证过虽然不总是有效但长期看有正期望。为什么选 ETF 而不是个股因为 ETF 没有个股的暴雷风险流动性好交易成本低而且几个宽基 ETF 之间的相关性适中轮动才有意义。如果选一堆高度相关的 ETF轮动就变成了瞎折腾。4.2 数据获取与清洗先解决数据问题。用 akshare 获取 ETF 日线数据代码大概长这样import akshare as ak import pandas as pd def get_etf_data(symbol, start_date, end_date): df ak.fund_etf_hist_em( symbolsymbol, perioddaily, start_datestart_date, end_dateend_date, adjustqfq ) df df.rename(columns{ 日期: date, 开盘: open, 收盘: close, 最高: high, 最低: low, 成交量: volume }) df[date] pd.to_datetime(df[date]) df df.set_index(date).sort_index() return df[[open, close, high, low, volume]]这里有几个细节要注意。adjustqfq 是前复权这个参数非常关键。ETF 会有分红如果不复权价格会出现跳空动量计算就会失真。前复权的意思是把历史价格按分红调整让价格曲线连续。这个坑我踩过早期没注意复权回测结果和实盘差了一大截。另一个细节是数据对齐。不同 ETF 的交易日可能不完全一致比如某只 ETF 停牌所以要把所有 ETF 的数据按日期对齐缺失的日期用前值填充或者直接剔除。我一般用 pandas 的 reindex 加 ffill 处理def align_data(data_dict): all_dates sorted(set().union(*[df.index for df in data_dict.values()])) aligned {} for symbol, df in data_dict.items(): aligned[symbol] df.reindex(all_dates).ffill() return aligned4.3 策略核心代码实现用 backtrader 实现这个轮动策略核心是自定义一个 Strategy 类。我把它拆成几个部分讲。首先是初始化定义参数和状态变量import backtrader as bt class MomentumRotation(bt.Strategy): params ( (lookback, 20), # 动量计算周期 (hold_num, 1), # 持仓数量 (rebalance_days, 5), # 调仓周期 ) def __init__(self): self.counter 0 self.etf_list [d for d in self.datas]然后是动量计算和调仓逻辑放在 next 方法里def next(self): self.counter 1 if self.counter % self.params.rebalance_days ! 0: return # 计算每个 ETF 的动量 momentum {} for d in self.etf_list: if len(d) self.params.lookback 1: continue ret d.close[0] / d.close[-self.params.lookback] - 1 momentum[d._name] ret if not momentum: return # 选出动量最高的 ranked sorted(momentum.items(), keylambda x: x[1], reverseTrue) targets [name for name, ret in ranked[:self.params.hold_num] if ret 0] # 执行调仓 for d in self.etf_list: if d._name in targets: if not self.getposition(d).size: self.order_target_percent(d, target1.0 / self.params.hold_num) else: if self.getposition(d).size: self.close(d)这段代码有几个关键点。动量用收盘价比值计算简单直接。调仓周期用计数器控制每 5 个交易日调一次。order_target_percent 按比例下单这样能自动处理资金分配。只买动量为正的如果全是负的就不买相当于空仓避险。4.4 回测参数设置与运行回测的初始化部分if __name__ __main__: cerebro bt.Cerebro() cerebro.broker.setcash(100000) cerebro.broker.setcommission(commission0.0003) # 万三手续费 etf_symbols { 510300: 沪深300, 510500: 中证500, 159915: 创业板, 518880: 黄金, 511010: 国债 } for symbol, name in etf_symbols.items(): df get_etf_data(symbol, 20190101, 20241231) data bt.feeds.PandasData(datanamedf, namename) cerebro.adddata(data) cerebro.addstrategy(MomentumRotation) cerebro.addanalyzer(bt.analyzers.SharpeRatio, _namesharpe) cerebro.addanalyzer(bt.analyzers.DrawDown, _namedd) cerebro.addanalyzer(bt.analyzers.Returns, _nameret) results cerebro.run() strat results[0] print(夏普比率:, strat.analyzers.sharpe.get_analysis()) print(最大回撤:, strat.analyzers.dd.get_analysis()) print(收益率:, strat.analyzers.ret.get_analysis())手续费这里设的是万三这是 ETF 交易的常见费率。别小看手续费如果你的策略调仓频繁手续费能吃掉一大块收益。我实测过同样的策略调仓周期从 5 天改成 20 天虽然信号少了但扣掉手续费后的净收益反而更高。这就是低频策略对个人的意义。5. 策略评估与参数优化5.1 看哪些指标才算靠谱回测跑完一堆指标摆在面前新手容易只看收益率这是大忌。我评估一个策略主要看四个维度收益维度年化收益率、累计收益率。这个最直观但单独看没意义。风险维度最大回撤、波动率。最大回撤决定了你能不能拿得住一个年化 30% 但最大回撤 50% 的策略绝大多数人中途就割肉了。风险调整后收益夏普比率、卡玛比率。夏普比率衡量每单位风险的超额收益一般大于 1 算不错大于 2 算优秀。卡玛比率是年化收益除以最大回撤大于 1 就说明收益能覆盖回撤。交易维度换手率、胜率、盈亏比。换手率太高说明交易成本高胜率低但盈亏比高也是可以接受的趋势策略往往如此。我一般会把这些指标做成一个表格方便对比不同参数下的表现参数组合年化收益最大回撤夏普卡玛换手率lookback10, rebalance518.2%22.5%0.950.81高lookback20, rebalance521.5%18.3%1.211.17中lookback20, rebalance2019.8%15.6%1.351.27低lookback60, rebalance2015.3%14.2%1.181.08低从这张表能看出lookback20、rebalance20 这组参数在风险和收益之间取得了比较好的平衡。lookback 太短容易受噪声干扰太长则反应迟钝rebalance 太频繁交易成本高太稀疏则错过信号。5.2 参数优化的正确姿势参数优化是量化里最容易走火入魔的环节。我见过有人把参数优化到小数点后两位回测曲线漂亮得像艺术品实盘一跑就原形毕露。这就是典型的过拟合。正确的做法是参数要少、范围要粗、要留出样本外验证。具体来说第一参数数量控制在 2-3 个以内。参数越多过拟合的风险越大。每多一个参数你就多了一个拟合历史噪声的自由度。第二参数扫描用粗网格不要用细网格。比如 lookback 就试 10、20、30、60 这几个值不要试 18、19、21、22。粗网格下表现稳定的参数才是真正稳健的。第三一定要做样本外测试。把数据分成两段前一段用来选参数后一段用来验证。如果后一段表现和前面差太多说明参数过拟合了。我一般用 70% 的数据做样本内30% 做样本外。第四看参数敏感性。如果参数稍微变一点收益就大幅波动说明这个策略不稳定。好的策略应该在参数的小幅变化下表现保持相对稳定。5.3 一个容易被忽略的坑未来函数未来函数是回测里最隐蔽的杀手。它的意思是在决策时用到了当时还不可能知道的信息。最常见的几种用当天收盘价做当天买入决策实际上你收盘时才知道收盘价根本来不及下单用复权后的价格计算信号但复权信息是后来才知道的用整个数据集计算指标比如全样本的均值然后用在每一天我踩过最惨的一次坑是策略里用了当天的最高价做判断回测收益翻倍实盘直接腰斩。后来逐行审查才发现最高价是盘中出现的你根本不知道当天最高价会是多少怎么可能用它做决策。避免未来函数的方法所有决策只能基于当前及之前的数据。在 backtrader 里用d.close[0]表示当前收盘价用d.close[-1]表示昨天收盘价。如果你在 next 方法里用了d.close[0]做买入决策那实际上是在收盘时决策、收盘时成交这在现实中是不成立的。正确的做法是用d.close[-1]做决策第二天开盘成交。6. 实盘落地从回测到真金白银6.1 模拟盘先行回测再好也只是历史。从回测到实盘中间必须经过模拟盘阶段。模拟盘的意义在于验证你的策略在真实市场环境下信号是否正常、执行是否顺畅、心理是否能承受。我一般会跑至少 3 个月的模拟盘。这期间重点观察几件事策略产生的信号和回测是否一致、实际成交价格和预期差多少、遇到极端行情时策略的反应是否符合预期。模拟盘期间如果发现问题还能及时调整不至于真金白银交学费。6.2 实盘的资金管理真金白银进场后资金管理比策略本身更重要。我的原则是第一只用闲钱。这笔钱至少三年内不需要动用这样你才能承受策略的回撤期。第二分批投入。不要一次性把计划资金全投进去先投三分之一跑三个月没问题再加。这样即使策略有问题损失也可控。第三设置止损线。虽然策略本身有风控逻辑但你还是应该设一个总资金的止损线比如回撤超过 20% 就暂停策略重新评估。这不是不信任策略而是给自己一个冷静期。第四定期复盘。每个月看一次策略表现和回测预期对比。如果偏离太大要找出原因。是市场环境变了还是策略失效了还是执行出了问题。6.3 自动化执行方案个人做量化最理想的执行方式是半自动策略每天收盘后自动跑出信号你第二天手动下单。这样既省去了盯盘的精力又保留了人工审核的环节避免程序出错导致意外交易。具体实现上可以用定时任务比如 Linux 的 cron 或者 Windows 的任务计划每天收盘后自动运行策略脚本把信号输出到一个文件或者发到你的邮箱。第二天开盘前你看一眼确认没问题就手动下单。如果想更进一步可以对接券商的 API 实现自动下单但这需要券商支持而且有额外的风险。我的建议是在策略稳定运行半年以上、你对它足够信任之前不要上全自动。7. 常见问题与排查技巧实录7.1 数据类问题问题一数据缺失或异常。表现是回测时某些日期没有数据或者价格出现明显异常值。排查方法是先打印数据的基本统计信息看有没有 NaN、有没有价格突变。解决方法是补齐缺失数据或者剔除异常值。问题二复权处理不当。表现是回测收益和实际不符尤其是分红除权日附近。排查方法是检查复权参数是否设置正确对比复权前后的价格曲线。解决方法是统一使用前复权数据。问题三不同数据源不一致。表现是同一只 ETF 在不同数据源上价格有差异。排查方法是交叉验证。解决方法是固定使用一个数据源不要混用。7.2 策略类问题问题一回测收益虚高。最常见的原因是未来函数。排查方法是逐行审查决策逻辑确认没有用到未来信息。另一个原因是过拟合排查方法是做样本外测试。问题二策略在震荡市表现差。趋势跟踪类策略的通病。解决方法是加入震荡市过滤条件比如用均线判断趋势或者加入均值回归策略做对冲。问题三参数敏感。表现是参数稍微一变收益就大幅波动。解决方法是简化策略减少参数数量或者用参数的平均表现而不是最优表现。7.3 执行类问题问题一信号和回测不一致。排查方法是检查实盘用的数据和回测数据是否一致、复权方式是否一致、计算逻辑是否一致。最常见的原因是数据源不同。问题二成交价格偏离预期。表现是实际成交价比预期差很多。原因是流动性不足或者下单时机不对。解决方法是选择流动性好的 ETF尽量在开盘后半小时或收盘前半小时下单。问题三程序报错。表现是策略脚本运行失败。排查方法是看报错信息定位到具体行。常见原因是数据格式变化、接口失效、依赖库版本不兼容。解决方法是固定依赖库版本定期检查数据接口。7.4 常见问题速查表问题现象可能原因排查方向解决方法回测收益异常高未来函数、过拟合审查决策逻辑、样本外测试修正逻辑、简化参数实盘与回测差异大数据不一致、执行偏差对比数据源、检查成交记录统一数据源、优化下单策略长期跑输基准逻辑失效、市场变化分析市场环境、策略归因调整逻辑或暂停策略程序频繁报错接口变化、版本冲突查看报错、检查依赖固定版本、更新接口回撤超出预期风控不足、仓位过重检查风控逻辑、仓位配置加入止损、降低仓位8. 策略迭代让系统持续进化8.1 定期评估与调整策略上线不是终点而是起点。市场在变策略也必须跟着变。我一般每季度做一次全面评估看几个方面策略的收益是否还在预期范围内、最大回撤是否可控、信号频率是否正常、有没有新的市场特征出现。评估之后如果发现问题不要急着大改。小步迭代比大改更安全。比如发现策略在震荡市表现差可以先加一个简单的过滤条件观察一段时间有效再保留无效就回退。每次只改一个地方这样才能清楚地知道是哪个改动起了作用。8.2 策略组合的思路单一策略总有失效的时候所以成熟的个人量化玩家通常会跑多个策略形成组合。组合的好处是平滑收益曲线当趋势策略在震荡市亏钱时均值回归策略可能在赚钱两者对冲整体回撤就小了。组合的构建有几个原则策略之间的相关性要低、每个策略都要能独立盈利、资金分配要均衡。我目前跑的是趋势轮动加一个简单的网格策略两者相关性不高组合后的夏普比率比单策略高了不少。8.3 持续学习的方向量化这个领域学无止境。但个人精力有限我建议聚焦几个方向一是策略逻辑的深化多读一些经典的量化书籍和论文理解策略背后的经济学逻辑二是工程能力的提升把代码写得更健壮、更易维护三是风险管理的完善这是决定你能否长期活下来的关键。至于 AI 工具它会越来越强但它的定位始终是工具。真正决定成败的是你对市场的理解、对风险的敬畏、对纪律的坚持。我见过太多人拿着好工具却亏钱也见过有人用最简单的策略稳定盈利差别就在这些看不见的地方。最后分享一个我自己的习惯每次策略调整前先把当前版本的代码和表现存档。这样万一改坏了能快速回退。这个习惯帮我避免了好几次灾难性的改动。量化这条路慢就是快稳就是赢。