
这几年我身边越来越多朋友开始问同一句话普通人还能不能做量化交易说实话放在五年前我的答案很犹豫。数据接口要钱、服务器要钱、写策略还要会C机构里一个量化团队动辄四五个人光是数据清洗和回测平台就够折腾几个月。但最近半年我把AI工具引入个人策略开发流程后最直观的感受是个人做量化的门槛已经从“会不会写代码”变成了“能不能把交易逻辑想清楚”。这篇文章是我最近一次完整实操的记录用AI辅助开发了一套偏中低频的“均线趋势布林回归”混合策略从数据获取、因子定义、回测到参数优化全部走了一遍。如果你手里有Python基础或者哪怕只是会一点Excel只要愿意花两周时间跟完这条流程大概率也能开发出第一套适合自己的量化策略。它能帮你直接跳过大半年的试错期把精力留给策略逻辑本身。1. 为什么AI让个人量化从“高门槛”变成“落地项”1.1 个人做量化的真实痛点先说一个很多人不信的事实大部分个人量化爱好者死在第一步不是死在策略构思而是死在看不懂数据和写不出代码。我以前第一次跑通回测的时候踩过一个大坑。从下载历史日线数据开始没有处理除权除息结果一只票分红除权后价格从20元掉到15元回测图像上直接出现了一个“大坑”策略以为发生了暴跌疯狂触发买入信号。我当时还以为发现了什么“稳定盈利信号”后来才知道这叫“复权没处理”整个回测全是废的。这种细节机构有专门的数据组帮你避开个人只能自己踩。类似的问题还有停牌期间的缺失值怎么填、涨跌停时根本无法成交、数据源接口今天能调明天就改版。这些杂活占掉一个个人开发者60%以上的时间。所以很多人的量化项目最后不是输在策略而是输在工程量。1.2 AI到底帮你省了哪些事现在AI工具已经把工程量大幅压下来了。我跟身边朋友讲AI在个人量化里的价值可以分成四层。第一层是写代码。以前你想实现“20日均线上穿60日均线买入”先要自己查pandas的rolling函数怎么写、交叉信号怎么判断。现在只要把这句话用大白话告诉AI它能直接给你一个能跑的Python函数还会解释每一行在干什么。第二层是因子灵感。你不知道该用什么因子来构建策略就让AI给你列一份常见因子清单动量类、均值回归类、波动率类、量价配合类。它会告诉你每个因子背后的逻辑是什么适合什么行情然后你再从中挑一两个做原型。第三层是回测结果解释。回测跑出来收益很高但回撤很大你可以把指标贴给AI让它帮你诊断可能的问题并给出改进方向。它虽然不能替你做投资决策但能节省大量查资料、翻代码的时间。第四层是代码和数据的查错。比如未来函数、索引对齐问题AI往往一眼就能看出隐患并给出修正建议。但要记住一点AI是整个流水线上的“熟练工”不是“决策者”。它帮你把“怎么实现”的活儿干完而“到底为什么这么做、风险边界在哪里”这件事还是要你亲自想清楚。这也是我下面要从策略设计讲起的根本原因。2. 动手前先想清楚策略类型与技术选型2.1 先决定做什么类型的策略很多新人一上来就问“能不能直接给我一套稳赚的策略代码”这种心态最容易亏钱。策略类型决定了你的精力投入、资金容量和心态承受能力必须先想清楚。按交易逻辑分个人最容易上手的策略类型有三类趋势跟踪、均值回归、套利。趋势跟踪的核心是“顺势而为”价格突破均线或创出阶段新高就买入跌破就卖出。它的特点是胜率不高可能十笔只有三笔赚钱但赚的那几笔盈亏比很高一波趋势能覆盖之前多次小亏。用冲浪来类比趋势策略是等浪来了再上板平时就在沙滩上等着所以交易频率低、对人的盯盘要求也低。均值回归的核心是“价格围绕价值波动”超跌了就买超涨了就卖。它像钓鱼在固定的鱼塘里反复下竿胜率高、单笔利润薄但最怕单边行情——如果价格一路下跌你一路抄底可能亏得怀疑人生。套利则是同时做多一个品种、做空另一个关联品种吃价差回归的钱。它风险相对中性但通常需要两个以上标的同时操作资金要求高逻辑也更复杂不是个人新手的第一选择。我自己选的是“趋势为主、均值回归为辅”的混合逻辑后面实操部分会详细展示。原因很简单我资金量不大交易频率不能太高否则手续费和滑点会吃掉利润平时还要上班没法每分钟盯盘中低频策略一天看一两次盘就够了。个人做量化首先要选择适合自己“生活状态”的策略而不只是适合市场的策略。2.2 技术栈选型本地Python还是在线平台选完策略类型接下来必须解决“在哪儿跑”的问题。我见过有人花了几千块买服务器最后发现自己一个月只跑几十次回测纯属浪费。个人量化的基础设施够用就行。目前主流方案有两个方向本地Python方案和在线量化平台方案。本地Python方案我推荐用Python 3加pandas、numpy处理数据回测框架用backtrader数据源用公开的akshare、tushare、baostock。好处是灵活什么策略都能自己改数据掌握在自己手里缺点是要自己解决数据更新、环境配置、回测bug这些问题。适合有一定Python基础、想搞清楚每个细节的人。在线平台方案比如聚宽、米筐、掘金这类好处是数据、回测、模拟盘都给你打包好了不用自己维护数据源写策略时只要按照平台API调整格式。适合把精力集中在策略逻辑、不想碰工程细节的人。缺点是平台数据可能有更新延迟深度定制时不如本地方便。我的建议是从本地Python开始。因为个人量化最重要的不是跑得快而是“没跑通之前不亏钱”。本地免费工具足够你验证一个策略从想法到落地是否可行。逻辑验证通过后再搬到在线平台做模拟盘和实盘会顺畅很多。下面给出一个我当时的选型对比表方便你对照自己的情况做决策方案优点缺点适合人群本地Python backtrader灵活可控、免费、数据自持需要自己处理数据和环境想深入理解量化流程的人在线平台聚宽/米筐等数据与回测一体化、上手快定制受限、数据延迟可能更关注策略逻辑、不想碰工程细节的人自建数据库云服务器扩展性强、可做高频成本高、维护量大资金和精力都比较充足的进阶玩家我早先用在线平台后来发现本地Python更适合我这种喜欢折腾的人。工具没有绝对好坏关键是你愿不愿意为自己的选择承担维护成本。3. 实操用AI开发一套“双均线布林回归”策略3.1 数据获取与清洗别让脏数据毁掉你的回测动手写策略之前先把数据搞定。我用akshare获取A股日线数据免费、接口比较稳定缺点是偶尔会有数据缺失正好可以用来练数据清洗。下面这段代码获取某只股票近五年的前复权日线数据并做基本清洗。注意看处理缺失值和停牌时的思路。import akshare as ak import pandas as pd # 获取日线数据adjustqfq 表示前复权 df ak.stock_zh_a_hist( symbol600519, perioddaily, adjustqfq ) # 简单清洗列名统一日期转成时间索引 df.rename(columns{日期: date, 开盘: open, 收盘: close, 最高: high, 最低: low, 成交量: volume}, inplaceTrue) df[date] pd.to_datetime(df[date]) df.set_index(date, inplaceTrue) df df[[open, high, low, close, volume]] # 去除缺失值并只保留正常交易区间 df df.dropna() print(df.head())这里有一个很重要的细节前复权数据是以当前价格为基准倒推历史价格所以每次行情更新后历史价格会跟着变。如果你做的是中低频策略这个变化会轻微影响历史信号所以更稳妥的做法是回测时用“后复权”数据保证历史价格不随最新行情漂移看图表时再用前复权更贴近真实盘感。想省事的话也可以用不复权数据但必须在除权除息日做事件过滤否则回测中会出现虚假的价格跳空。数据清洗是量化里最无聊但最重要的一环。我的经验是这个步骤宁可慢一点也要搞清楚每一列数据从哪来、有没有复权、缺失值代不代表停牌。否则后面所有漂亮的收益曲线都可能是垃圾进垃圾出。3.2 因子定义与信号生成让AI帮你写逻辑骨架数据准备好之后开始定义策略信号。我的这套策略包含两个信号趋势信号和回归信号。趋势信号用双均线5日均线上穿20日均线时产生买入信号下穿时产生卖出信号。这用来跟随中期趋势过滤掉部分震荡噪音。回归信号用布林带收盘价低于20日均线两个标准差时说明短期超跌产生反向买入信号收盘价高于两个标准差时说明短期超涨产生反向卖出信号。为什么要把趋势和回归拼在一起我直接用一个例子解释。如果只做双均线趋势遇到横盘震荡价格会在均线上下反复穿插信号频繁闪烁手续费就能亏掉不少。如果只做布林带回归遇到单边上涨行情价格会长期贴着布林带上轨运行你反复做空利润全变成亏损。两个信号组合虽然不能完全避免这些问题但能互相约束让策略在不同行情下都有一定的适应力。让AI写这段代码只需要给它一句话“用pandas计算5日和20日均线计算布林带上中下轨生成趋势信号和回归信号并把信号合并成最终的买卖信号。”你注意到没有这句话里面已经包含了所有关键参数和逻辑AI做的只是翻译成代码。import numpy as np df[ma_fast] df[close].rolling(5).mean() df[ma_slow] df[close].rolling(20).mean() df[std_20] df[close].rolling(20).std() df[upper] df[ma_slow] 2 * df[std_20] df[lower] df[ma_slow] - 2 * df[std_20] # 趋势信号快线上穿慢线为1下穿为-1 df[trend_signal] np.where(df[ma_fast] df[ma_slow], 1, -1) # 回归信号超跌为1超涨为-1 df[mean_signal] np.where(df[close] df[lower], 1, np.where(df[close] df[upper], -1, 0)) # 合并趋势为主回归信号在趋势反向时覆盖 df[signal] np.where(df[mean_signal] ! 0, df[mean_signal], df[trend_signal]) # 只保留信号发生变化的位置用于回测时减少无效交易 df[trade_signal] df[signal].diff().fillna(0)这段代码有几个坑值得展开说。df[signal]是持仓状态不是每次变化都交易trade_signal才是真正的开平仓动作。很多人直接把signal1当天就买入结果同一个信号连续出现好几天重复买入导致仓位混乱。所以我才加了一行.diff()来捕捉变化点。还有一点布林带参数2个标准差是常规用法但在不同标的上未必最优。这就要靠后面的参数优化环节来解决了。AI生成代码速度快但你必须能看懂每一行在算什么这就是信任边界。3.3 回测框架搭建自己写一个最简单的回测循环如果不想引入backtrader这类复杂框架手写一个最简回测循环反而更容易理解交易流程。我把回测拆成四个动作状态、买入、卖出、结算。下面的代码模拟一个简单的单标的、全仓进出的回测。每次买入用收盘价成交卖出同样用收盘价但各自扣掉手续费和滑点。不要小看这两项成本A股佣金加印花税加滑点一次完整买卖大约要吃掉0.2%到0.5%高频策略甚至会吃更多。def backtest(df, signal_col, initial_cash100000, fee_rate0.0003, slippage0.0002): cash initial_cash position 0 shares 0 equity_curve [] for date, row in df.iterrows(): action row[signal_col] price row[close] exec_price price * (1 slippage) # 买入时多付一点滑点 if position 0 and action 1: # 全仓买入 shares int(cash // (exec_price * 100)) * 100 if shares 0: cost shares * exec_price fee cost * fee_rate cash - (cost fee) position 1 elif position 1 and action -1: # 全仓卖出 income shares * price * (1 - slippage) fee income * fee_rate cash income - fee shares 0 position 0 equity cash shares * price equity_curve.append({date: date, equity: equity}) result pd.DataFrame(equity_curve).set_index(date) result[daily_ret] result[equity].pct_change().fillna(0) result[drawdown] result[equity] / result[equity].cummax() - 1 total_return result[equity].iloc[-1] / initial_cash - 1 annual_return (1 total_return) ** (250 / len(result)) - 1 max_drawdown result[drawdown].min() sharpe result[daily_ret].mean() / result[daily_ret].std() * np.sqrt(250) print(f累计收益率: {total_return:.2%}) print(f年化收益率: {annual_return:.2%}) print(f最大回撤: {max_drawdown:.2%}) print(f夏普比率: {sharpe:.2f}) return result这段代码里的“100股”整手买入是A股实际交易的基本规则不处理会引入仓位误差。滑点按0.0002估算对中低频策略来说偏乐观但可以先跑通流程后面再调。回测指标里我最看重最大回撤和夏普比率。最大回撤代表你实盘中要承受的心理底线夏普比率衡量的是每承担一分波动能换来多少收益。很多人只看累计收益率这是新手最常见的误区。一个年化30%但回撤40%的策略实盘里根本拿不住迟早会在低位割肉最后反而亏钱。3.4 参数优化用AI辅助但不被AI带偏策略有了参数还是手调的5日均线、20日均线、2倍标准差这些数值凭什么用默认值于是我又把AI拉进来让它生成一组参数搜索代码用网格搜索遍历合理的参数区间。from itertools import product best_params None best_sharpe -999 for fast, slow, mult in product(range(3, 11), range(15, 41, 5), np.arange(1.5, 3.1, 0.5)): if fast slow: continue df[ma_fast] df[close].rolling(fast).mean() df[ma_slow] df[close].rolling(slow).mean() df[std_20] df[close].rolling(int(slow)).std() df[upper] df[ma_slow] mult * df[std_20] df[lower] df[ma_slow] - mult * df[std_20] df[trend_signal] np.where(df[ma_fast] df[ma_slow], 1, -1) df[mean_signal] np.where(df[close] df[lower], 1, np.where(df[close] df[upper], -1, 0)) df[signal] np.where(df[mean_signal] ! 0, df[mean_signal], df[trend_signal]) df[trade_signal] df[signal].diff().fillna(0) result backtest(df, trade_signal, fee_rate0.0003, slippage0.0002) if result[equity].pct_change().std() 0: sharpe result[daily_ret].mean() / result[daily_ret].std() * np.sqrt(250) else: sharpe 0 if sharpe best_sharpe: best_sharpe sharpe best_params (fast, slow, mult) print(最优参数:, best_params, 夏普:, best_sharpe)这里我要强烈提醒一个事情网格搜索到的“最优参数”往往会过拟合历史数据。一个稳健的策略参数变化一点收益应该变化不大如果某个参数组合收益特别高旁边参数收益却非常差说明你找到的是“数据挖掘的巧合”。我的经验是不要只看全样本最优那一组而是把数据切成训练段和验证段。比如2018年到2022年用来找参数2023年到2025年用来验证参数。只有两段表现都稳定的参数才值得进模拟盘。AI可以把这段逻辑封装成函数但“要不要相信最优参数”这个判断必须由你来拍板。4. 常见问题与排查技巧实录4.1 回测高收益、实盘却亏钱的排查表我在这套策略从回测走向模拟盘的过程中踩了不少坑也总结了一个排查清单。每次策略表现不对先对着这个表格逐一排查现象可能原因排查方法回测收益极高但曲线平滑到离谱未来函数 / 数据泄漏检查信号是否用了当日收盘后才知道的数据模拟盘成交价和回测差距大滑点、开盘跳空回测里把滑点调高到0.1%重新跑参数一变收益就暴跌过拟合切分训练段和验证段看两段表现是否一致连续小亏但偶尔大赚胜率低的趋势策略检查盈亏比别只看胜率回测曲线前高后低策略逻辑可能失效查看标的市场风格变化考虑加入过滤器其中未来函数是个人量化里最隐蔽的坑。我早期犯过的一个错是用当天收盘价突破均线作为买入信号却在生成信号时用到了当日全量收盘后的均值统计相当于提前“偷看”了收盘结果。这样的回测当然好看实盘却不可能复现。排查未来函数有一个笨办法把信号生成和交易执行分成两条时间线只允许用t日及之前的数据生成t1日的信号t1日开盘或收盘才执行。把信号延迟一天如果收益依然不错说明策略可能接近真实可交易。4.2 数据与代码层面的经验坑除了上面这些宏观问题实际操作中还有一批细节坑。我每个都亲自踩过写出来帮你们省点时间。复权选择一定要前后一致。如果你用前复权数据做回测历史价格会随最新股价变动每次更新数据后回测结果可能变化。建议回测用后复权信号稳定实盘对照时再看前复权。停牌处理不能只靠dropna。停牌期间缺失的行情如果你直接删除会导致交易信号跨过停牌期默认停牌期间可以交易。实际停牌根本卖不出去。解决办法是在回测循环里判断“当日无行情则跳过交易动作”同时保留持仓不动。涨跌停无法成交。A股的涨停板买不进去跌停板卖不出去。如果策略总是在涨停时触发买入、跌停时触发卖出回测收益会虚高。严格一点的做法是开盘涨停时禁止买入开盘跌停时禁止卖出回测里加个涨跌停过滤条件。手续费和滑点不能省。回测时把费率设为零等于自己骗自己。A股手续费、印花税、滑点加在一起会让一个原本年化30%的策略变成年化18%这个差距足以改变你的仓位决策。4.3 AI协作的信任边界审代码比写代码更重要最后想聊聊AI协作中最容易被忽略的一点AI生成的代码一定要人工审查而且审查的重点不是语法错误而是逻辑合理性和数据泄漏。我知道有人直接用AI从头到尾生成一套策略连信号怎么定义、交易怎么执行都没看就丢进回测看到高收益就准备实盘。这跟闭眼开车没区别。AI擅长把模糊需求变成代码但模糊本身可能就是错的。比如它会很自然地用整段数据计算标准化因子这在前瞻性检验里就是严重的数据泄漏。我现在的协作模式是第一步自己在纸上画清楚策略逻辑写清信号、仓位、止损三个环节第二步让AI生成代码或逻辑片段第三步逐行审查AI代码重点检查有没有用到未来数据、有没有漏掉交易成本第四步小步快跑地做回测和参数优化第五步放到模拟盘验证至少三到四个星期再考虑小额实盘。这套流程下来AI帮我把开发周期从两个月压缩到一两周但我始终没有把“决策权”交给它。策略的生命力来自你对市场的理解AI只是把这份理解变成可执行工具。这一点想清楚个人量化就不会被工具牵着走。5. 从回测到模拟盘的临门一脚5.1 模拟盘与真实环境的差距参数优化后我在本地跑出了不错的曲线但我知道这距离真实交易还很远。模拟盘是连接回测和实盘之间的桥梁。模拟盘和回测最大的区别是回测是“事后看”模拟盘是“事前等”。回测里你知道这一刻是买入信号下一天行情是涨是跌都已经写进历史数据而模拟盘里你必须每天真正去看信号、下订单这才接近真实交易的心理压力。我身边有人跳过模拟盘直接上实盘结果第一天就遇到开盘跳空买入价比回测高了不少心态直接崩了。所以我强烈建议策略至少要跑满三到四周模拟盘覆盖不同类型的行情哪怕只是手工记录模拟信号也行。5.2 资金管理与仓位控制再好的策略没有合理的资金管理都会翻车。我个人用了最简单的模式单标的、单策略、初始仓位固定。每次买入只用总资金的固定比例比如30%盈利后逐步加仓但单标的不超过总资金的一半。原因很简单个人量化样本量小再稳妥的策略也可能遇到连续亏损。如果你全仓进出一次20%的回撤就需要25%的盈利才能回本心理压力会非常大。固定比例仓位连续亏损时亏损金额也在缩小你才有足够的时间去判断策略是否失效而不是被一次极端行情直接打出场。这里有一个常见的误区把仓位和胜率混为一谈。一个胜率70%的均值回归策略遇到单边行情可能连续止损一个胜率40%的趋势策略反而可能在几次大赚中覆盖亏损。仓位管理不是为了提高胜率而是为了保证你在概率不利阶段依然活着。5.3 策略日志与迭代节奏最后分享一个我坚持了大半年的习惯给每个策略单独建一个策略日志记录每一次改动。日志里包含日期、改动原因、改动前后参数、回测结果变化、模拟盘表现。这个习惯一开始看起来浪费时间但当你同时维护两三个策略时它的价值就体现出来了。很多次我改了参数跑出更好的回测兴奋地准备实盘结果翻日志才发现类似参数组合以前就试过最终在模拟盘表现很差。没有日志你就等于在同一个坑里反复横跳。迭代节奏上我的原则是“一次只改一个变量”。如果同时改参数和信号逻辑回测变好了你不知道是谁的贡献。一次只改一处才能建立清晰的因果链条。这个节奏听起来慢但长远看反而是最快的。我这半年最大的体会是AI不会让你躺着赚钱但它把“从想法到代码”这一段最磨人的路变得非常短。剩下的路比如怎么理解市场、怎么控制风险、怎么在连续亏损时保持冷静依然是人的功课。如果让我给新手一个最朴素的建议我会说先跑通一条最简单的策略再讨论优化。全程都不要把“回测高收益”当作实盘盈利的证据永远留足仓位去面对意外。