1. 为什么个人做量化这件事在AI时代突然变得可行了三年前如果有人跟我说一个散户能独立开发出一套稳定跑赢ETF定投的量化策略我大概率会笑笑不说话。那时候做量化是什么门槛你得有Wind终端一年几万块、得有聚宽或米筐的付费权限、得懂C写撮合回测引擎、还得有服务器跑数据清洗。光是数据这一关就把99%的个人投资者挡在门外了。但这两年情况变了而且变得很彻底。我身边至少有五六个非科班出身的朋友用Python加AI辅助真的跑出了自己的策略有的跑ETF轮动有的做可转债双低有的干脆就是简单的均线动量组合。他们不是天才也没有金融工程博士学位就是普通程序员或者对投资有点兴趣的上班族。这个变化的核心驱动力有三个我一个个说。第一个是数据获取成本趋近于零。以前你要买Level-2行情、要买财务数据、要买因子库现在akshare、tushare、yfinance这些开源库基本能覆盖个人策略需要的所有数据。ETF的日线、分钟线、成分股、溢价率全都是免费接口。你可能觉得免费数据质量不行但对于日频或小时频的策略来说完全够用。我实测过akshare的ETF数据和券商软件对比误差在可接受范围内。第二个是AI把写代码这件事的门槛打下来了。这里说的不是让AI帮你预测涨跌——那玩意儿不靠谱——而是让AI帮你写回测框架、写数据清洗逻辑、写参数优化脚本。以前你脑子里有个策略想法要花两周把它变成能跑的代码现在你跟Codex或者类似的AI编程助手描述清楚逻辑半天就能跑出第一版。这个效率提升是数量级的。第三个是回测框架的成熟。backtrader、vectorbt、qlib这些框架文档齐全、社区活跃你不需要从零造轮子。尤其是vectorbt向量化回测速度快得离谱跑几千组参数组合也就几分钟的事。注意我说个人能做量化不等于个人能轻松赚钱。量化策略的开发是一个迭代过程第一版大概率是亏钱的这很正常。关键是你能不能快速迭代、快速证伪。那具体怎么做下面我按实际开发流程一步步拆给你看。这套流程我自己跑过不下十遍也帮朋友搭过几套踩过的坑都会标出来。2. 策略想法的来源别一上来就搞机器学习很多人一提到量化第一反应是我要用LSTM预测股价或者我要搞强化学习。我劝你先把这个念头放下。不是说这些技术没用而是对个人开发者来说简单策略的可解释性和可维护性远比复杂度重要。2.1 从ETF轮动切入是最稳的起点为什么推荐ETF而不是个股三个原因。第一ETF没有个股的暴雷风险你不用担心财务造假、突然停牌这些破事。第二ETF的流动性好回测时的滑点假设更接近真实。第三ETF的策略逻辑通常更直观比如动量轮动、均值回归、行业轮动这些概念你一听就懂。我自己跑的第一个能用的策略就是ETF动量轮动。逻辑简单到令人发指每周最后一个交易日计算候选ETF池里每只ETF过去20个交易日的涨幅买入涨幅最高的那只如果所有ETF的涨幅都是负的就空仓或者买货币ETF。这个策略为什么有效背后是动量效应这个被学术界反复验证过的现象——过去涨得好的资产短期内倾向于继续涨。当然这个效应会衰减、会失效但作为入门策略它的逻辑清晰、参数少、容易验证。2.2 策略想法的三个可靠来源如果你不知道从哪里找策略想法我给你三个方向学术论文的简化版去SSRN或者知网搜momentum、mean reversion、factor investing找那些结论清晰的论文把它们的核心逻辑简化成可执行的规则。注意论文里的策略通常有很多约束条件你要做减法只保留最核心的信号。券商研报的因子复现很多券商会发布XX因子选股的研报里面会给出因子的计算公式。你可以把这些因子套用到ETF上或者用ETF成分股做加权。自己观察到的市场规律比如你发现每年春节前消费ETF都会涨一波或者美联储议息会议前后黄金ETF波动加大。这些观察可能不严谨但可以作为策略的起点然后用数据去验证。提示不要同时验证超过3个策略想法。个人精力有限聚焦才能出结果。2.3 用AI辅助策略构思的正确姿势现在你可以用AI来帮你扩展策略思路。比如你可以这样问我有一个ETF动量轮动的策略候选池是沪深300、中证500、创业板、黄金、国债请帮我设计5种不同的改进方向每种方向说明其金融逻辑和可能的参数。AI会给你一堆建议比如加入波动率过滤、加入相关性约束、改成风险平价权重等等。你要做的是筛选出逻辑上说得通的然后用回测去验证。记住AI给的建议大部分是平庸的但偶尔会有一两个让你眼前一亮的点。我自己的经验是AI在帮你把模糊想法结构化这件事上特别有用。你脑子里可能只有一个模糊的我想做轮动的念头跟AI聊几轮之后你就能得到一个清晰的规则描述调仓频率、候选池、排序指标、过滤条件、仓位管理。这个结构化过程以前要靠自己慢慢想现在几分钟就能搞定。3. 数据准备免费数据够不够用怎么清洗数据是量化的地基。地基不稳后面全是空中楼阁。但好消息是个人做ETF策略免费数据真的够用。3.1 akshare和tushare的实际使用对比我用得最多的是akshare偶尔用tushare。两个库各有优劣我列个表给你看对比项aksharetushare费用完全免费基础免费高级接口需积分数据覆盖ETF、股票、期货、宏观股票为主ETF数据较少接口稳定性偶尔抽风需重试相对稳定数据质量日线数据可靠分钟线一般日线数据可靠文档中文文档示例多中文文档需注册我的建议是主力用akshare关键数据用tushare交叉验证。比如ETF的复权净值两个库都拉一遍如果差异超过0.5%就要去查原因。3.2 数据清洗中最容易忽略的三个坑第一个坑复权处理。ETF有分红如果你用不复权的价格回测会在分红日出现虚假的暴跌。akshare的fund_etf_hist_em接口默认返回的是不复权价格你需要自己处理复权。最简单的办法是用adjustqfq参数前复权但要注意前复权会随着新分红不断调整历史数据导致回测结果不可复现。我的做法是用后复权数据做回测。后复权价格一旦确定就不会变回测结果可复现。akshare里可以通过fund_etf_hist_em(symbol510300, adjusthfq)获取。第二个坑停牌和流动性。ETF虽然很少停牌但某些冷门ETF的成交额可能只有几百万你的策略如果选中了这种ETF回测时按收盘价成交实盘时可能根本买不到量。解决办法是在候选池里加一个流动性过滤过去20日日均成交额低于5000万的ETF直接剔除。第三个坑数据对齐。不同ETF的交易日历可能略有差异比如某些跨境ETF在A股休市时仍然交易。如果你要做轮动必须把所有ETF的数据对齐到同一个交易日历上。我的做法是以沪深300ETF的交易日历为基准其他ETF缺失的交易日用前值填充。import akshare as ak import pandas as pd # 拉取ETF后复权数据 def get_etf_data(symbol, start_date, end_date): df ak.fund_etf_hist_em( symbolsymbol, perioddaily, start_datestart_date, end_dateend_date, adjusthfq ) df df.rename(columns{ 日期: date, 开盘: open, 收盘: close, 最高: high, 最低: low, 成交量: volume, 成交额: amount }) df[date] pd.to_datetime(df[date]) df df.set_index(date).sort_index() return df[[open, close, high, low, volume, amount]] # 以沪深300ETF的交易日历为基准对齐 def align_data(data_dict, base_symbol): base_dates data_dict[base_symbol].index aligned {} for symbol, df in data_dict.items(): aligned[symbol] df.reindex(base_dates).ffill() return aligned这段代码我用了很久基本没出过问题。注意ffill()是前向填充意味着如果某只ETF在某天没有数据就用前一天的数据代替。这在处理跨境ETF时特别有用。3.3 数据存储别用CSV用Parquet很多人习惯把数据存成CSV方便查看。但CSV有两个致命问题一是读取慢二是没有数据类型。当你需要频繁读取几十只ETF的历史数据时CSV的IO开销会让你抓狂。我的做法是用Parquet格式存储。Parquet是列式存储读取速度快5-10倍而且自带压缩文件体积只有CSV的1/3。pandas直接支持to_parquet和read_parquet用起来和CSV一样简单。# 存储 df.to_parquet(fdata/{symbol}.parquet) # 读取 df pd.read_parquet(fdata/{symbol}.parquet)如果你要做参数优化需要反复读取数据Parquet的优势会非常明显。我实测过读取50只ETF的10年日线数据CSV需要8秒左右Parquet只需要1.5秒。4. 回测框架选型backtrader还是vectorbt回测框架的选择直接决定了你的开发效率。我前后用过三个框架backtrader、vectorbt、qlib。qlib太重适合机构个人用起来累。backtrader和vectorbt各有千秋我详细说说。4.1 backtrader事件驱动适合复杂逻辑backtrader是事件驱动的回测框架它的核心概念是Strategy、Indicator、Analyzer。你定义一个策略类在next()方法里写每天的买卖逻辑。这种模式的好处是灵活你可以实现任何复杂的交易逻辑比如条件单、止损止盈、多品种对冲。但backtrader的缺点也很明显慢。因为它是一天一天循环的跑10年日线数据大概需要几秒到几十秒。如果你要做参数优化跑1000组参数那就是几个小时的事。backtrader适合什么场景适合策略逻辑复杂、需要精细控制交易细节的情况。比如你要做网格交易需要记录每一格的成交状态或者你要做期权策略需要处理行权、到期等事件。4.2 vectorbt向量化适合快速验证vectorbt是向量化回测框架它的核心思想是用矩阵运算代替循环。你把所有ETF的价格数据拼成一个DataFrame然后一次性计算所有信号和收益。这种模式的速度极快跑1000组参数可能只需要几秒钟。vectorbt的缺点是学习曲线陡峭。它的API设计比较抽象你需要理解Portfolio、Signal、Accessor这些概念。而且它的文档虽然全但示例代码不够多很多功能需要自己摸索。vectorbt适合什么场景适合策略逻辑简单、需要大量参数优化的情况。比如动量轮动、均值回归这类策略用vectorbt跑参数优化非常爽。4.3 我的实际选择两个都用我现在的做法是用vectorbt做快速验证和参数优化用backtrader做最终确认和实盘对接。具体流程是先用vectorbt跑一遍策略看看大致收益和回撤如果结果不错再用backtrader复现一遍确认交易细节比如滑点、手续费对收益的影响最后用backtrader的实盘接口对接券商。这样做的原因是vectorbt的参数优化结果可能过于乐观因为它忽略了一些交易细节需要用backtrader做二次验证。如果两个框架的结果差异很大说明策略对交易细节敏感实盘时要特别小心。import vectorbt as vbt import numpy as np # 假设close_df是N只ETF的收盘价DataFrame # 计算20日动量 momentum close_df.pct_change(20) # 每周最后一个交易日调仓 weekly_rebalance close_df.resample(W).last().index signal pd.DataFrame(0, indexclose_df.index, columnsclose_df.columns) for date in weekly_rebalance: if date in momentum.index: top_etf momentum.loc[date].idxmax() if momentum.loc[date, top_etf] 0: signal.loc[date, top_etf] 1 # 用vectorbt回测 portfolio vbt.Portfolio.from_signals( closeclose_df, entriessignal 1, exitssignal 0, init_cash100000, fees0.0003, slippage0.001, freqD ) print(portfolio.stats())这段代码跑一次大概2秒如果要做参数优化比如把20日改成10日、30日、60日用vectorbt的ParameterGrid可以一次性跑完。注意vectorbt的from_signals默认是当天收盘价成交但实际交易中你不可能在收盘价成交。我的做法是把信号延后一天即今天产生信号明天开盘成交。这个细节对回测结果影响很大尤其是高频策略。5. 策略开发的核心环节信号、仓位、风控策略开发不是写个买卖规则就完事了。一个完整的策略包含三个部分信号生成、仓位管理、风险控制。很多人只关注信号忽略了后两者结果回测很漂亮实盘一塌糊涂。5.1 信号生成从简单规则到多因子信号生成是策略的核心。最简单的信号是单因子比如20日动量最高的ETF。但单因子策略往往不稳定容易在特定市场环境下失效。我的做法是用2-3个因子做组合。比如动量因子过去20日涨幅波动率因子过去20日波动率取负值即低波动优先趋势因子价格是否在60日均线之上把这三个因子标准化后等权相加得到综合得分选得分最高的ETF。这样做的好处是降低单一因子的失效风险。当动量因子失效时波动率和趋势因子可能还在起作用。但要注意因子不是越多越好。因子之间如果高度相关加进去没有意义。我一般会计算因子之间的相关系数如果超过0.7就只保留其中一个。5.2 仓位管理别总是满仓很多人回测时习惯满仓操作即每次调仓都把全部资金买入选中的ETF。这种做法在牛市中收益很高但在熊市中回撤巨大。我的做法是根据市场状态动态调整仓位。具体来说用一个简单的择时指标来判断市场状态如果沪深300在60日均线之上且60日均线向上仓位100%如果沪深300在60日均线之上但60日均线向下仓位50%如果沪深300在60日均线之下仓位0%或买货币ETF这个规则很简单但能有效降低回撤。我回测过加入这个择时规则后策略的最大回撤从35%降到了20%左右年化收益只下降了2-3个百分点。这个交换是值得的。5.3 风险控制止损和止盈的量化处理止损止盈是风控的重要手段但很多人处理得过于随意。我的做法是用ATR平均真实波幅来设定止损位而不是固定的百分比。具体来说买入后如果价格跌破买入价 - 2倍ATR就止损卖出。ATR的计算周期用14天。这样做的好处是止损位会随着市场波动率自适应调整。波动大时止损位宽波动小时止损位窄避免被正常波动扫出去。止盈方面我一般不用固定止盈而是用移动止盈。即价格每创新高就把止盈位上移。具体规则是止盈位 最高价 - 2倍ATR。这样可以在趋势延续时让利润奔跑在趋势反转时及时锁定收益。def calculate_atr(df, period14): high df[high] low df[low] close df[close] tr1 high - low tr2 abs(high - close.shift(1)) tr3 abs(low - close.shift(1)) tr pd.concat([tr1, tr2, tr3], axis1).max(axis1) atr tr.rolling(period).mean() return atr # 止损逻辑 def check_stop_loss(entry_price, current_price, atr, multiplier2): stop_price entry_price - multiplier * atr if current_price stop_price: return True # 触发止损 return False这段代码我用了很久效果稳定。注意ATR的周期选择14天是经典参数但你可以根据策略的持仓周期调整。如果持仓周期是几天可以用7天如果持仓周期是几周可以用21天。6. 参数优化的陷阱过拟合是怎么发生的参数优化是量化策略开发中最容易出问题的地方。我见过太多人回测曲线漂亮得像艺术品实盘一跑就亏钱。原因几乎都是过拟合。6.1 过拟合的本质你在拟合噪声过拟合的本质是你的策略参数不仅拟合了市场中的真实规律还拟合了历史数据中的随机噪声。噪声是不可重复的所以实盘时策略就失效了。怎么判断是否过拟合一个简单的标准是如果参数微小变化导致收益剧烈变化说明过拟合了。比如你把动量周期从20天改成21天年化收益从15%掉到5%那这个策略大概率是拟合了噪声。健康的策略应该是参数在合理范围内变化时收益曲线是平滑的。比如动量周期从15天到25天年化收益在12%-15%之间波动这说明策略捕捉的是真实规律。6.2 避免过拟合的三个实用方法方法一样本外测试。把数据分成两段前70%做参数优化后30%做验证。如果策略在样本外也能保持不错的收益说明过拟合程度较低。注意样本外数据只能用一次如果你反复调整参数去适应样本外数据那样本外就变成样本内了。方法二参数稳健性检验。不要只选最优参数而是选参数平原上的中心点。具体做法是画出参数-收益的热力图找到收益较高且周围参数收益也较高的区域选这个区域的中心参数。这样即使市场环境变化导致最优参数偏移策略也不会立刻失效。方法三限制参数数量。每增加一个参数过拟合的风险就增加一分。我的原则是策略参数不超过3个。如果超过3个说明策略逻辑太复杂需要简化。6.3 用AI辅助参数优化小心AI的过度自信现在你可以用AI来帮你做参数优化。比如你可以把回测结果喂给AI让它分析哪些参数组合更稳健。但要注意AI倾向于给出确定性的答案它会告诉你最优参数是20天但不会告诉你这个参数在样本外可能失效。我的做法是用AI做初步筛选找出几个候选参数组合然后自己用样本外数据做验证。AI的建议可以参考但最终决策要靠自己的判断。提示参数优化的结果不要直接用于实盘。先用小资金跑一段时间确认策略在实盘环境下的表现和回测一致再逐步加大资金。7. 从回测到实盘那些回测不会告诉你的坑回测和实盘之间的差距是量化交易中最难跨越的鸿沟。我总结了四个最常见的坑每一个我都亲自踩过。7.1 滑点回测里的理想成交价不存在回测时我们通常假设按收盘价或开盘价成交。但实盘中你的买单会推高价格卖单会压低价格这就是滑点。对于流动性好的ETF滑点可能在0.1%左右对于流动性差的ETF滑点可能超过0.5%。我的做法是在回测中设置保守的滑点假设。对于日均成交额超过1亿的ETF滑点设0.1%对于日均成交额在5000万到1亿之间的ETF滑点设0.2%低于5000万的ETF直接不纳入候选池。7.2 手续费别忽略印花税和过户费ETF交易没有印花税但有券商佣金。目前主流券商的ETF佣金在万分之0.5到万分之3之间。如果你做高频调仓手续费会吃掉大量收益。我的做法是在回测中设置万分之1的手续费保守估计并且控制调仓频率。日频调仓的手续费成本太高周频或双周频更合理。我实测过把调仓频率从每天改成每周年化收益只下降了1-2个百分点但手续费节省了80%以上。7.3 流动性你的策略容量有多大流动性决定了策略的资金容量。如果你的策略选中了一只日均成交额只有2000万的ETF你最多只能投入几百万否则买卖就会显著影响价格。我的做法是计算策略的资金容量。具体方法是假设你每次调仓买入的金额不超过该ETF当日成交额的1%那么策略容量 候选池中最小成交额 × 1% × 持仓数量。比如候选池里最小的ETF日均成交额是5000万你持仓1只那策略容量就是50万。超过这个金额就要考虑分仓或换标的。7.4 实盘对接用券商API还是手动操作实盘对接有两种方式券商API自动交易和手动操作。券商API的好处是执行速度快、不受情绪影响。但缺点是大部分券商的API不对个人开放或者有资金门槛。我了解到的信息是目前只有少数券商提供个人量化接口而且需要申请。手动操作的好处是简单、不需要编程对接。但缺点是执行速度慢、容易受情绪影响。我的做法是用程序生成每日交易信号然后手动在券商APP下单。这样既保证了信号的一致性又避免了API对接的复杂性。注意手动操作时一定要在开盘前设置好条件单避免盘中临时决策。我吃过这个亏盘中看到大跌就慌了临时改了策略结果错过了后面的反弹。8. 策略迭代一个策略的生命周期有多长没有任何策略能永远有效。市场环境在变参与者在变策略的收益会逐渐衰减。所以策略迭代是量化交易的常态。8.1 策略失效的信号什么时候该放弃判断策略是否失效不能只看短期亏损。短期亏损可能是正常回撤也可能是策略失效。我的判断标准是如果策略连续3个月跑输基准且回撤超过历史最大回撤的1.5倍就要警惕了如果策略的信号逻辑所依赖的市场规律明显改变比如动量效应消失就要考虑放弃如果策略的参数在样本外持续恶化说明过拟合严重需要重新开发我的做法是每季度做一次策略体检。具体包括计算最近3个月的收益、回撤、夏普比率对比历史同期表现检查策略依赖的市场规律是否仍然存在。8.2 策略迭代的三个方向如果策略需要迭代可以从三个方向入手方向一更换候选池。比如原来用宽基ETF现在加入行业ETF或跨境ETF。候选池的变化会带来新的机会。方向二调整因子权重。比如原来动量和波动率等权现在根据市场环境动态调整权重。在趋势市场中加大动量权重在震荡市场中加大波动率权重。方向三加入新的过滤条件。比如加入宏观经济指标PMI、社融、市场情绪指标换手率、融资余额作为过滤条件。8.3 用AI辅助策略迭代的正确方式AI在策略迭代中能帮上什么忙我的经验是AI擅长帮你分析数据但不擅长帮你做决策。比如你可以把最近3个月的交易记录喂给AI让它分析哪些交易是盈利的、哪些是亏损的、亏损交易有什么共同特征。AI可能会告诉你亏损交易大多发生在市场波动率突然放大的时候这个洞察很有价值你可以据此加入波动率过滤条件。但AI不会告诉你这个策略应该放弃还是继续。这个决策需要你自己做因为只有你知道自己的风险承受能力、资金规模和投资目标。9. 个人量化的现实预期别指望暴富但可以跑赢定投最后说说预期管理。我见过太多人抱着一年翻倍的心态进入量化结果半年就放弃了。个人量化不是印钞机它的合理预期是跑赢ETF定投同时控制回撤。具体来说一个健康的个人量化策略年化收益在10%-20%之间最大回撤在15%-25%之间夏普比率在0.8-1.5之间。如果你能做到这个水平已经超过了90%的散户。我自己的策略过去三年的年化收益是14.7%最大回撤是18.3%夏普比率1.1。这个成绩不算惊艳但胜在稳定。我知道有些人的策略年化收益更高但回撤也更大实盘时很难拿住。提示不要用杠杆。个人量化的优势是灵活不是激进。杠杆会放大回撤让你在策略正常回撤时被迫平仓。另外不要把所有资金都投入量化策略。我的做法是量化策略的资金不超过总投资的30%剩下的配置在指数基金、债券和现金上。这样即使策略短期失效整体资产也不会受太大影响。说到底个人量化是一场马拉松不是百米冲刺。你需要的是持续学习、持续迭代、持续控制风险。AI时代给了我们工具但能不能用好还是看你自己。