
这两年量化交易在国内已经从少数机构的秘密武器变成了不少个人开发者和投资者桌面上的常规工具。尤其是量化多因子选股这条路门槛没有想象中那么高但坑也绝对不少。我见过有人拿一套网上流传的选股公式跑回测年化收益曲线漂亮得不像话一上实盘就扛不住回撤也见过有人一口气丢进去二十个因子最后发现一半因子在逻辑上是重复的还有一小半偷偷用了未来数据。所以我想把多因子选股开发这件事完整地捋一遍从因子库搭建、数据预处理、有效性检验、多因子合成再到回测验证和实盘切换每一步都讲清楚为什么这么做而不是只丢一段能跑的代码。这篇东西更适合这样几类人想独立搭建第一套多因子选股框架的 Python 开发者已经会写单因子策略但不知道怎么扩展成体系的量化研究员以及被各种指标公式折腾过、想从看图形转向看数据的投资者。默认场景是 A 股市场但方法论可以平移到期货、港股甚至加密资产只需要把数据源、交易规则和成本参数替换掉。我不会给你兜售什么必胜公式只会把完整的开发链路和真实存在的问题讲透。1. 多因子选股从理念到可落地的开发框架1.1 为什么多因子模型能长期有效很多人第一次接触多因子模型时会被 CAPM、APT、Fama-French 这些名词劝退。换个角度看就没那么玄股价的涨跌不是由一个原因决定的估值便宜、业绩超预期、资金持续流入、技术形态突破、波动率处于低位每个原因都能解释一部分收益来源。单拿一个原因做选股运气成分很大行情风格一变就失效。多因子模型的本质是把多个相对独立的收益来源组合在一起让它们在统计上形成合力同时分散单一因子失效的风险。学术界管这些收益来源叫因子溢价业界叫 alpha 来源。它们之所以存在一般有三个解释一是承担了某些风险的补偿比如低波动因子长期有效的背后是投资者对高波动股票的过度偏好二是行为偏差比如散户追涨杀跌让动量因子和反转因子反复出现三是市场结构约束比如公募基金的持仓限制导致某些股票长期被系统性低估。理解这一点很重要因为当你手里的因子开始失效时你需要判断是因子本身失效了还是它的底层逻辑暂时不在风口上。1.2 一套完整的开发链路应该包含哪些模块做多因子选股不是写个函数算几个指标就完事。我习惯把整个系统拆成七个模块每个模块都有明确的输入输出模块之间用数据接口解耦。这样后面任何一个环节出问题都能快速定位。模块输入输出常用工具数据获取与存储交易标的、日历量价、财务、资金流数据akshare、tushare、Wind存 parquet/clickhouse因子计算原始数据因子值宽表pandas、numpy因子预处理因子值去极值、标准化、中性化后的因子pandas、statsmodels因子有效性检验因子值 后续收益IC、分层回测、相关性矩阵scipy、statsmodels、alphalens多因子合成通过检验的因子综合因子得分、选股名单自研打分模块组合构建与回测选股名单、交易规则净值曲线、绩效指标backtrader、自研事件驱动框架实盘执行目标持仓实际成交记录QMT、miniQMT、量化交易终端这里面最容易被新手忽略的是第一环——数据存储。很多人用 pandas 直接从接口拉数据写到一半发现数据没对齐、复权因子不对、财报发布日期缺失整个因子库都要推倒重来。我建议一开始就把原始数据落到本地文件或者数据库里按交易日 标的的主键组织保留一份不做任何处理的原始备份再基于原始备份做复权和衍生计算。这样每一步都可以追溯排查未来数据泄露时也会省力很多。2. 因子库搭建五类常用因子的构造逻辑与 Python 实现2.1 动量、反转与技术形态因子动量因子是最好理解也最容易构造的一类过去一段时间涨得好的股票未来一段时间倾向于继续涨这是横截面上的动量效应。但动量不能只看一个窗口学术研究里经典的 12-1 动量指的是过去 12 个月扣掉最近 1 个月的收益剔除近一个月是为了避开短期反转的干扰。A 股市场的特性是短期反转比中期动量更明显所以我在实际开发时通常同时保留 20 日动量、60 日动量和 5 日反转三个因子。def compute_momentum(close, window20, lag1): # 计算过去 window 日的累计收益率注意因子值本身要在 T 日收盘后才可得到 mom close / close.shift(window) - 1 # 使用 lag1 表示 T 日计算出的因子最早只能用于 T1 日开盘的交易决策 return mom.shift(lag) def compute_reversal(close, window5, lag1): rev close / close.shift(window) - 1 return -rev.shift(lag) # 反转因子取负值跌得多的得分高技术形态类因子也属于这个范畴。网上流传的各种选股指标公式比如破底翻、三倍量、趋势线共振本质上都是在用 K 线组合、量能变化和均线关系做规则化描述。多因子的做法不是否定这些规则而是把它们背后的逻辑拆成可计算的量突破 20 日高点的距离、放量倍数的滚动分位、均线多头发散的强度等等。这样拆出来的因子可以做统计检验而不是停留在图形对不对这种无法证伪的判断上。2.2 资金流因子资金流因子是 A 股市场最受关注的类别之一因为散户体量大、龙虎榜和 Level-2 数据普及度高主力资金的行为会明显影响短期股价。很多人熟悉的资金全景图、主力大单监控一类指标本质上就是把逐笔成交按单量大小切分成大单、中单、小单然后聚合出净流入。在自建因子库时最简单可靠的构造方式是主力净流入率 大单买入金额 - 大单卖出金额/ 当日成交额再用过去 N 日做滚动累加或滚动平均。def compute_money_flow(amount, buy_amount, sell_amount, window5): net_buy buy_amount - sell_amount net_buy_ratio net_buy / amount return net_buy_ratio.rolling(window).mean()要注意的是资金流因子的换手率天然偏高而且受算法单划分标准影响很大。不同数据商对大单的定义不一样同一个标的可能资金流方向完全相反。我的建议是先用日频的大单净流入做验证如果有效再考虑引入分钟级数据不要一上来就追求高频精度。2.3 波动率与流动性因子低波动异象是被实证反复验证过的现象过去波动率低的股票未来风险调整后收益反而更高。波动率因子不是让你去买死水股而是把它作为一个风险调整维度放进模型里让组合不会过于集中在高波动题材股上。流动性因子则对应 Amihud 非流动性指标成交额越低、价格冲击越大的股票需要更高的预期收益补偿。def compute_volatility(returns, window20): return returns.rolling(window).std() * np.sqrt(252) # 年化波动率 def compute_amihud(daily_return, amount, window20): illiquidity (daily_return.abs() / amount) return illiquidity.rolling(window).mean()流动性还有一个作用风控。如果选出来的股票日成交额不到两千万实盘一买就把价格打上去了回测里的收益根本吃不到。所以流动性因子除了用作 alpha也经常作为组合构建时的过滤条件。2.4 价值与质量因子价值因子和质量因子依赖财务数据逻辑上更偏中低频。价值因子常见的有市盈率、市净率、市现率、股息率质量因子常见的有 ROE、毛利率、资产负债率、经营现金流与净利润的比值。财务因子最大的坑不是计算而是数据对齐——你只能用财报实际发布日期之前公开的数据不能把后来披露的财报数据用在更早的决策点上。# 财报数据要对齐到 report_date 与 announce_date 之后才可用 def align_fundamental(fundamental_df, price_df): # 将基本面数据按公告日期映射到自然日再扩展到对应交易日 aligned fundamental_df.reindex(price_df.index, methodffill) return aligned.shift(1) # 确保不会用到当日收盘后才知道的信息质量因子和动量因子的相关性通常比较低把它们放在一起可以有效改善组合的稳定性。这也是多因子组合比单因子策略稳健的根本原因——不同逻辑的收益来源互相补位。2.5 复现指标公式时的常见坑从三倍量选股说起网上到处能看到胜率 98% 的选股公式黑马竞价选股器源码这类东西。作为开发人员我不建议直接照搬公式但很推荐去复现它们因为复现过程本身就是一次很好的因子开发训练。这些公式最常见的坑是未来函数有的公式里用了未来 N 日才确认的信号比如用当天的最高价去回看过去一段时间的最高价导致信号只有在未来数据出现后才会被触发有的公式直接在副图指标里引用了下一周期的值。回测里这些信号表现神勇实盘里永远迟半拍。复现任何指标公式时我建议先做一件事把 K 线数据按日期排序然后检查指标在每个时点的计算是否只依赖该时点及之前的数据。如果发现任何对未来的引用要么用滞后平移的方式修正要么直接放弃这个因子。这个习惯能帮你过滤掉大量虚假的策略信号。3. 因子预处理管道为什么去极值、标准化、中性化一步都不能少3.1 极端值如何毁掉一个因子刚算出因子值时很多人会直接拿去做相关性分析或者打分。这就容易出问题。举个例子某天有一批股票涨停或者跌停行情软件里的涨跌幅因子会出现离群值如果直接用原始值做标准化一个极端值就可能把整个截面的均值和标准差拉偏让 99% 的股票挤在一堆只剩一两只股票被当成极端优秀送进选股名单这就是典型的一颗老鼠屎坏了一锅汤。更隐蔽的是极值对 IC 计算的影响。Spearman 秩相关对极端值没那么敏感但如果你用的是 Pearson 相关或者用原始因子值做线性回归残差离群点就会主导结果。所以预处理管道的第一道工序必须是去极值。3.2 去极值MAD 与百分位法的选择去极值有两种主流做法MAD 法和百分位截尾法。MAD 法用中位数作为中心用绝对中位偏差衡量离散度一般取 5 倍 MAD 作为上下界超出边界就砍到边界值。百分位法更简单通常把 1% 和 99% 作为截断点超过的部分设置成边界值。def winsorize_mad(series, n5): median series.median() mad (series - median).abs().median() upper median n * 1.4826 * mad lower median - n * 1.4826 * mad return series.clip(lower, upper) def winsorize_percentile(series, lower0.01, upper0.99): lo series.quantile(lower) hi series.quantile(upper) return series.clip(lo, hi)其中 1.4826 是把 MAD 还原到与标准差同尺度所用的系数。两套方法在多数场景下结果差异不大我更倾向于 MAD 法因为它对偏态分布更稳健不需要假设数据是正态的。3.3 标准化Z-score 和 Rank 化的取舍去极值之后要标准化目的是让不同量纲的因子能加总比较。最常规的是 Z-score减去均值除以标准差。但金融数据离正态分布差得很远直接 Z-score 可能仍然受偏态影响。Rank 化是更稳妥的选择把因子值转换成它在截面上的百分位排名再映射到 [-1, 1] 区间相当于把任意分布都变成均匀分布。def zscore(series): return (series - series.mean()) / series.std() def rank_normalize(series): return series.rank(pctTrue) * 2 - 1Rank 化的代价是丢失了因子值之间的相对距离信息但选股本身就是横截面排序问题距离信息的作用没有想象中大。我的默认管线是去极值后用 rank 化只有在做收益率预测类模型时才保留 Z-score 后的原始值。3.4 行业与市值中性化用回归残差做因子中性化解决的是因子取值里混杂了你不想承担的风险这个问题。比如银行股市值普遍偏大、市盈率偏低如果你不做行业中性化价值因子选出来的股票大概率全是银行和地产组合完全暴露在单一行业风险里。市值中性化同样重要不然小市值因子会主导整个选股结果。做法并不复杂把因子值作为因变量把行业虚拟变量和对数市值作为自变量做回归取残差作为中性化后的因子。import statsmodels.api as sm def neutralize(factor, industry_dummies, log_mktcap): X sm.add_constant(pd.concat([industry_dummies, log_mktcap], axis1)) y factor model sm.OLS(y, X).fit() return model.resid需要提醒的是中性化也有副作用。如果某个因子大部分的 alpha 恰好来自行业配置比如低波动行业本身跑赢高波动行业那中性化之后这部分收益就被抹掉了。所以不要在预处理的第一个阶段盲目中性化先把原始因子做成一个版本再把中性化版本也做成一个版本回测对比之后再决定正式管线里保留谁。4. 因子有效性检验IC、分层回测与相关性筛查4.1 用 IC 和 ICIR 判断因子有没有用因子算完、预处理做完第一件要干的事就是检验这个因子和未来收益到底有没有关系。业界最常用的是 IC即信息系数定义为因子值与下一期收益的 Spearman 秩相关。IC 通常在每个调仓日计算一次比如每周算一个截面 IC。指标含义经验参考值IC因子与下一期收益的秩相关绝对值大于 0.03 算有效大于 0.05 算优秀ICIRIC 均值除以 IC 标准差大于 0.5 说明稳定大于 1.0 非常稳定IC 胜率IC 大于 0 的期数占比高于 60% 说明正收益方向较稳定def calc_ic_series(factor_panel, ret_panel): # factor_panel 与 ret_panel 均为 DataFrame行是调仓日列是股票 ic_series factor_panel.corrwith(ret_panel, axis1, methodspearman) return ic_series def summarize_ic(ic_series): return { ic_mean: ic_series.mean(), ic_std: ic_series.std(), icir: ic_series.mean() / ic_series.std(), ic_positive_ratio: (ic_series 0).mean() }单看 IC 不够还要看 ICIR。一个因子可能平均 IC 还可以但时正时负波动极大这样的因子没办法稳定使用。ICIR 可以理解为因子的信噪比它衡量的是因子预测能力的稳定性。4.2 分层回测看单调性而不是只看多头IC 是一个统计量但它不能告诉你在实际操作中选出来的股票具体表现如何。分层回测是更直观的检验每个调仓日按因子值从小到大把股票分成 10 组分别计算每组未来一段时间的平均收益然后看组别收益有没有单调性。判断标准有三个层次第一多头组第 10 组是否显著跑赢市场第二组别之间的收益是否单调递增或递减第三多空组合做多第 10 组、做空第 1 组是否有稳定的超额收益。在 A 股做空受限的情况下多空收益更多是参考真正重要的是多头组的超额收益和单调性。def layer_backtest(factor, forward_ret, layers10): grouped pd.qcut(factor.rank(methodfirst), layers, labelsFalse) 1 stats pd.DataFrame({layer: grouped, fwd_ret: forward_ret}).groupby(layer)[fwd_ret].mean() return stats很多因子在分层回测里会出现两头翘的非线性形态比如多头组收益高、空头组收益也高。这种因子通常不是线性 alpha而是代表了某个风险溢价。直接用出多头反而是更稳妥的做法。4.3 因子相关性筛查避免重复下注多因子的多不是越多越好而是相关性越低越好。20 个动量类因子可能本质上是一件事加在一起等于把单一风险放大了 20 倍。所以做完单因子检验后要算因子之间的相关系数矩阵把相关性超过 0.7 的因子放到一个池子里做进一步筛选。我一般会观察两个维度一是同期截面相关系数看因子值本身的重复度二是 IC 序列相关系数看因子预测能力的时间路径是否雷同。后者更有意义因为两个因子截面相关系数虽然不高但它们的有效时期高度重叠也说明它们在吃同一份收益。处理高相关因子的办法很简单优先保留 ICIR 更高、逻辑更直接的那个或者把一组高相关因子做因子合成提取公共成分。不要依赖任何黑箱的特征选择算法来做这件事因为你必须在逻辑上能解释为什么要留下这个因子。4.4 因子衰减速度决定调仓频率因子不是每时每刻都有效。有的因子对未来 5 天的收益预测能力很强但 20 天之后就完全失效有的因子钝一点预测 1 个月甚至 3 个月的趋势更稳定。通过计算不同持有期5 日、10 日、20 日、60 日下的 IC可以画出因子衰减曲线。衰减曲线直接决定调仓频率。衰减快的因子适合周频调仓但对交易成本和冲击成本极为敏感衰减慢的因子适合月频调仓容量更大但超额收益通常更薄。我看很多实盘失败案例问题不在因子本身而是调仓频率和因子衰减速度不匹配用月度调仓去跑 5 日衰减的因子收益早被磨损了。5. 多因子合成三种实用打分方案与组合构建5.1 等权打分法直观但容易被强因子主导通过了单因子检验和相关性筛查之后剩下的因子要合成一个综合得分。最简单的就是等权打分每个因子标准化的值直接等权重相加得分最高的前 N 只股票组成买入名单。优点是没有过度拟合的空间逻辑透明回测结果不容易被参数美化。缺点是所有因子一视同仁如果某个因子的 IC 明显比其他因子高它在等权体系里就出力不足拉低整体效率。等权打分适合刚起步的阶段也适合作为其他方法的基准。我建议无论最后用多复杂的权重方案都先跑一版等权组合当锚点。5.2 IC 加权法让历史有效的因子多出力比等权稍微进阶一点的是 IC 加权。思路很简单用每个因子过去一段时间的滚动 ICIR 作为权重ICIR 高的因子多分一点权重负的因子反向使用。注意负 IC 不是丢弃而是取因子值负号之后纳入打分因为有效的负向因子同样是 alpha 来源比如短期反转因子本身就是负向动量。def ic_weighted_score(factor_panel, icir_series): weights icir_series / icir_series.abs().sum() score factor_panel.mul(weights, axis1).sum(axis1) return scoreIC 加权比等权更细致代价是有轻微过拟合风险。滚动窗口越长权重越稳定但对近期风格变化的适应就越慢窗口越短反应越灵敏但也容易被噪声带偏。我个人常用 24 个月滚动窗口、每季度更新一次权重不搞高频权重调整。5.3 回归与机器学习合成高收益高风险的博弈再进一步就是直接用横截面回归甚至机器学习模型来预测收益因子作为特征下期收益作为标签。线性回归相对可控但要注意多重共线性。树模型和神经网络能捕捉非线性关系也容易把噪声拟合进去尤其是因子数量不多、样本量有限的情况下回测里的提升很可能只是过拟合。我对机器学习合成多因子的态度是可以用但要设严格的护栏。第一因子数量控制在 15 个以内第二必须做时间序列交叉验证按年份滚动训练和测试不能用随机打乱第三模型输出的预测值在进入组合构建之前仍然要做标准化和换手率控制。否则你得到的只是一堆漂亮的回测绩效不是可实盘的策略。5.4 从综合因子到目标组合行业约束与权重上限选股名单定下来之后还有一步很多人会忽略个股和行业权重约束。我见过最典型的失误是模型选出的前 20 只股票里有 8 只属于同一个行业表面上是多因子选股实际变成了押注某一个行业赛道。为了避免这个问题组合构建阶段至少要加三道约束单只股票权重不超过 5% 或 10%单一行业权重不超过 20%-30%总持仓数量不低于 30 只。权重分配上等权重比市值权重在中小盘策略里更常见因为市值加权会让组合被少数大市值股票主导。如果你有更精细的需求可以用风险平价或者带约束的最优化但不建议一开始就上复杂的优化器——参数多一点就多一个出 bug 的地方。6. 回测框架搭建与未来函数陷阱数据泄露的把关6.1 事件驱动回测与向量化回测怎么选策略逻辑写清楚、因子合成完成之后最关键也最容易犯错的就是回测。回测框架有两类向量化回测和事件驱动回测。向量化回测直接用整段历史数据一次性计算持仓与收益速度快适合因子研究和初步筛选事件驱动回测模拟真实交易流程按时间逐笔推进能精确控制什么时候能拿到数据、什么时候能成交更适合接近实盘的验证。我的选择是因子研究阶段用向量化策略冻结之后的验证阶段必须用事件驱动。很多回测神器为了性能做了大量向量化优化代价是对数据对齐做了隐式假设比如盘中信号当日收盘价成交、财报数据当日可用这些假设在实盘里全都不成立。6.2 五种常见的未来数据泄露场景网上经常看到量化泄露未来信息的说法翻译成工程语言就是未来函数、前视偏差、数据泄露。我在别人的策略和复盘文章里见过的典型场景有五种第一财务数据对齐错误。使用了财报的完整数值但在财报实际披露日之前就把它当作已知信息放进了因子计算。第二复权因子使用不当。用后复权价格计算历史收益率时未考虑复权因子本身是事后确定的导致历史收益被修正成未来才知道的数值。第三全样本标准化。在计算因子的 zscore 时用了整段历史区间的均值和标准差而不是只用截至决策日的数据。第四价格对齐错误。把 T 日收盘才能计算出的因子直接和 T 日收盘价计算的未来收益对齐造成用同一天的收益去验证同一天的因子的幻觉。第五幸存者偏差。股票池选用了当前仍然上市交易的股票退市股在回测的早期阶段被自动剔除放大了收益。要防止这五类泄露没有魔法方案只能在代码层面严格要求所有因子值使用前统一 shift 一期所有财务数据必须带公告日期过滤所有标准化参数必须用滚动窗口内样本估计股票池必须是 Point-in-Time 的历史成分股列表。6.3 自查清单如何确认回测没有偷偷看未来与其相信代码写的时候没问题不如主动做防泄露压力测试。我常用的三个验证手段一是随机因子测试。把因子值随机打乱重新跑整套回测流程如果随机因子也能产生显著收益说明数据管道里有未来信息或者逻辑漏洞。这套方法成本最低但非常有效。二是样本外测试。把前 70% 时间作为因子筛选和参数训练区间后 30% 完全不碰等全部流程固定后一次性验证。三是逐代码审查。重点看三处因子计算函数里有没有使用shift(-1)或未来窗口函数、数据合并时有没有 forward fill 到未来、收益对齐时有没有把 T 日和 T1 日搞混。def leakage_check(df): checks {} # 检查因子列是否包含未来信息当前行的值如果引用了未来行就会造成泄露 checks[future_shift] any( col for col in df.columns if df[col].isna().sum() ! df[col].diff().isna().sum() ) return checks这个方法不是万能的但至少能拦住大部分低级错误。6.4 交易成本建模换手率才是收益杀手回测里最容易被低估的是交易成本。股票交易的综合成本包括佣金、印花税和滑点散户和小资金的常规假设是双边千分之二到千分之三高频调仓策略需要把滑点放大到千分之五以上。成本对收益的侵蚀在换手率高的因子里会被放大到惊人的程度一个年化 20% 的因子策略如果月换手率超过 100%双边千分之三的成本一年就能吃掉 7% 左右。所以在回测框架里交易成本不能做成一个静态参数而要和持仓变化绑定每次调仓时计算目标持仓与当前持仓的差异按差异金额收取成本并且结合实际成交量的比例估算可成交量和滑点。没有这个模块你优化的方向很可能是换手越猛收益越高最后得到一份实盘绝对跑不出来的绩效。7. 夏普比率优化与实盘切换经验7.1 提升夏普比率的三条路径网上很多人问怎么把策略夏普从 1 做到 3各种指标公式满天飞。我自己做下来的体会是夏普比率的提升路径就三条提高分子端的超额收益均值降低分母端的收益波动以及减少不必要的换手损耗。提高超额收益主要靠因子选得更准、更分散。当两个因子的 ICIR 相当但相关性很低时组合在一起的夏普提升最明显这就是分散化的数学价值。降低波动主要靠组合构建时的行业中性化和个股权重上限以及仓位波动管理——用已实现波动率动态调整总仓位。减少换手损耗则是用调仓缓冲带只有股票的因子得分排名变化超过一定阈值才换仓避免因为微小排名波动产生频繁交易。7.2 我曾踩过的三个实盘偏差第一个偏差是回测用收盘价成交实盘里信号 T 日收盘产生、T1 日开盘买入开盘价经常比收盘价高不少尤其选中的股票有人提前抢筹时。这个问题在中小市值股票上特别严重收益可能被吃掉一大截。后来我强制在回测里用 T1 日开盘价加上滑点来模拟成交绩效立刻打了折扣但也真实了很多。第二个偏差是涨跌停导致的成交假设失效。回测假设所有股票都能以目标权重成交但 A 股有涨跌停限制选出的股票一字板买不进是常事。现在我的回测会做一个可成交性判断如果开盘一字涨停视为无法买入如果一字跌停视为无法卖出。第三个偏差是停牌。持有股票突然停牌资金被锁死无法按照目标组合重新平衡。这在低频多因子策略里危害更大因为你可能眼睁睁看着组合在一只停牌股上暴露 10% 的风险。处理办法是回测里模拟停牌持仓不参与调仓复牌后再按原计划处理。7.3 控制换手与波动率的一个实用框架最后分享一个我现在还在用的组合管理框架。选股信号出来之后不直接全量调仓而是分两步。第一步计算目标持仓与当前持仓的差异把换手率限制在单次 20% 以内超出的部分顺延到下一期。第二步总仓位按 5 日已实现波动率的倒数调整波动率高的时期自动降低仓位波动率低的时期自动提高仓位。这两步都不涉及复杂的优化求解但能非常有效地改善实际净值曲线的平滑度。做多因子开发这几年我最大的体会是模型和因子的重要性并没有传说中那么高真正决定长期表现的是数据管道的干净程度、回测假设的诚实程度和组合层面的风险控制。把这三件事做好哪怕因子库只有五六个扎实的因子也能做出能实盘的策略这三件事里任何一件偷懒再豪华的因子库都会在实盘面前现出原形。一开始做的时候别急着追求因子的数量先把一条从数据到下单的完整链路打通让它足够诚实、足够经得起压力测试后面的事情会顺很多。