个人 A 股量化系统机构级 60 分 Baseline 技术选型设计:从聚宽研究到 QMT 实盘(2026-07-22)
本文把LEAN 60 行骨架继续向前推进:不再只解释模块,而是为一个个人、A 股、日频、先聚宽回测与模拟、后迁移 QMT 实盘、预计持续演进 3—5 年的系统,做一套可以验收的 Baseline 技术选型。
需求来自这次完整讨论。资料与交易规则核验日为 2026-07-22。
[!warning] 使用边界 “机构级 60 分”描述的是研究与生产链条的完整度,不是收益率,不表示已获得机构数据、私有 Alpha、席位、低延迟基础设施或风控审批,也不构成投资建议。纸面设计只有在每一项验收证据出现后才真正得分。
一页结论
最合适的答案不是挑一个“最强平台”,而是建立一个小而完整的组合栈:
| 角色 | V1.0 选型 | 为什么 |
|---|---|---|
| 架构语言 | LEAN 式稳定接口 | 把预测、目标仓位、订单、成交明确分开;以后替换模型或券商时不重写全系统 |
| 数据底座 | 授权的聚宽/JQData 数据适配器 + Parquet + DuckDB | 当前 A 股适配最好,同时避免策略永久锁死在平台内部 |
| 研究与模型 | Qlib 工作流 + LightGBM 主模型 + Ridge 线性挑战者 | 适合中等规模表格因子;训练、记录和组合实验链成熟;保留简单模型作为过拟合警报 |
| 标的池 | 按当时成分还原的中证 500 + 可交易性过滤 | 在横截面宽度、流动性和个人执行难度之间取中间值 |
| 风险 | 行业 + 透明风格因子模型,协方差收缩,特异风险 | 比“只看止损”完整,也比直接购买或复制商业 Barra 更可审计 |
| 成本 | 日期版本化显性费率 + 半价差 + 参与率/波动冲击 | 成本同时进入回测、优化与成交后校准,不再用一个固定滑点掩盖容量问题 |
| 组合 | CVXPY 连续受约束优化 + 取整/离散 repair | 显式权衡 Alpha、风险、换手与成本;持股数、最低佣金和交易单位不伪装成连续凸约束 |
| 执行 | QMT/XtTrader 适配器 + Guarded TWAP/POV 状态机 | 日频不需要追求微秒,但必须正确处理异步回报、部分成交、撤单重报和对账 |
| 评估与追踪 | Qlib Records + 自有账本 + 本地 MLflow + Git/data manifest | 一次结果能追溯到代码、配置、数据、模型、订单和成交 |
| 当前平台分工 | 本地为事实源;聚宽做独立回测/模拟;QMT 做实盘 | 研究、验证和实盘各用其所长,业务核心不依赖平台专有回调 |
可以把它浓缩成一句话:
LEAN 定合约,Qlib 做研究,聚宽做第二引擎验证,QMT 做真实订单;本地的版本化数据、组合决策和账本才是系统事实源。
V1.0 的目标设计分约为 66/100。它刚好高于 60,而不是假装达到 90:数据供应仍非双源,成本冲击主要靠代理变量,风险模型尚未经过多年实盘校准,执行也没有交易所级逐笔队列模型。
一、先把“60 分”定义清楚
1. 60 分不是平均分,而是“分数 + 硬门”
系统总分由七个维度加权,但必须同时通过十道硬门。这样不能靠一个漂亮的回测 Sharpe 抵消数据泄漏,也不能靠代码整洁抵消实盘无法对账。
| 评分维度 | 权重 | 60 分层级应有的证据 |
|---|---|---|
| 数据与时点正确性 | 15% | PIT 数据、成分股历史、退市样本、公司行动、字段可用时间、版本与质量报告 |
| 研究与样本外验证 | 15% | 时间顺序切分、标签重叠 purge/embargo、walk-forward、成本后结果、多市场状态 |
| 风险与组合构建 | 15% | 预测与仓位分离,相关性/暴露/流动性进入优化,约束可解释且有不可行降级 |
| 成本与执行现实性 | 15% | 日期化费率、价差/冲击、成交量约束、部分成交、撤改、异步回报 |
| 工程与可复现性 | 15% | 代码/配置/数据/环境/模型版本齐全,同一输入可重放同一决策 |
| 运行、对账与监控 | 15% | 决策—订单—成交三账、日终券商对账、告警、断线恢复、kill switch |
| 合规与平台迁移 | 10% | 程序化交易报告已确认;核心逻辑与聚宽/QMT API 解耦;规则按日期版本化 |
定义为:
总分 = Σ(维度得分 × 权重占比),且 Σ权重占比 = 1
达到 Baseline 60 ⇔ 总分 ≥ 60
且 G1…G10 全部通过
十道硬门如下:
| Gate | 不可妥协的验收条件 | 失败意味着什么 |
|---|---|---|
| G1 数据时点 | 任意一次预测都能回答“当时实际知道什么”;财报按公告可得时间进入 | 有未来函数,整份回测作废 |
| G2 样本外 | 禁止随机打乱时间;有隔离的验证、测试和向前滚动评估 | 只有拟合,没有证据 |
| G3 A 股现实 | 停复牌、涨跌幅制度、交易单位、T+1 可卖量、费用与公司行动按证券和日期处理 | 回测订单在现实中不存在 |
| G4 稳定合约 | Forecast → Target → Order → Fill 是不同对象并落盘 |
无法定位误差来自哪一层 |
| G5 事前风险 | 仓位生成前检查集中度、行业/风格暴露、波动、流动性和换手 | “止损”无法替代组合风控 |
| G6 订单状态 | 支持提交、确认、部分成交、全成、撤单中、已撤、拒单与未知状态 | 实盘仓位会漂移 |
| G7 可复现 | 每个 run 绑定 Git commit、环境锁、配置 hash、数据快照与随机种子 | 结果无法复核 |
| G8 对账与停机 | 每日与券商资产/持仓/订单/成交对账;异常时能阻止新单 | 小故障可以累积成资金事故 |
| G9 双引擎一致性 | 同一信号/目标在本地与聚宽的差异有解释;QMT 影子运行通过 | 迁移风险未知 |
| G10 合规 | 已向实际券商确认报告、权限、频率和软件信息要求,并完成“先报告、后交易” | 不得上线实盘 |
2. 每一层的 0—90 分语义
| 层级 | 含义 |
|---|---|
| 0 | 缺失 |
| 20 | Notebook/Demo 能跑;大量理想化假设 |
| 40 | 回测可用;尚不能可靠模拟或实盘 |
| 60 | 职责、输入、输出、失败模式和验收测试齐全,并已有连续模拟/影子运行证据;系统级通过后才有资格进入受控小资金 canary |
| 80 | 多数据源、压力测试、自动恢复、持续监控和实盘校准较成熟 |
| 90+ | 机构私有数据、容量与成交模型、治理、权限、审计和生产基础设施长期验证 |
因此,本文所说的“机构级”准确含义是:采用机构常见的完整责任链与控制思想,但用个人能维护的复杂度实现其 60 分版本。
3. 本文的固定边界
V1.0 先主动放弃一些问题,否则工程面会无限膨胀:
- 市场:沪深 A 股,暂不含港股、美股、期权、期货和跨境资产。
- 账户:个人现金股票账户,长仓,不融资融券。
- 频率:日频生成 Alpha,默认周度再平衡;日内数据只服务可交易性、成本和执行。
- 目标:相对中证 500 的成本后超额收益,不把最高绝对收益当唯一目标。
- 平台:当前在聚宽回测与模拟;本地保存研究事实;未来以实际券商可用的 QMT/XtQuant 接口实盘。
- 非目标:高频、盘口预测、做市、深度学习端到端下单、分布式微服务、Kubernetes。
如果将来改做分钟高频、期权组合或多券商交易,本设计的接口仍可保留,但执行、风控和数据模型必须升级,不能把本文参数原样平移。
二、目标架构:研究平面与交易平面分开
LEAN 官方的 Algorithm Framework 把 Universe、Alpha、Portfolio Construction、Risk Management 和 Execution 分开。本文保留这套责任边界,但加上现实系统不可缺少的数据、成本、账本、监控与反馈。

可编辑源图:个人 A 股量化 Baseline:研究、交易与证据反馈闭环
核心不是目录名,而是九种稳定对象:
| 对象 | 最少字段 | 生产含义 |
|---|---|---|
SecurityMaster |
内部 ID、交易所代码、上市/退市日、板块、交易单位、规则版本 | 证券身份与规则不能靠字符串猜 |
UniverseSnapshot |
as_of、成员、纳入/排除原因、数据版本 |
标的池可重放,杜绝当前成分回填历史 |
FeatureSnapshot |
instrument、event_time、available_time、值、版本 |
区分事件发生与研究者可得时间 |
AlphaForecast |
标的、生成时点、持有期、分数/预期超额、置信度、模型版本 | 只表达预测,不偷偷决定股数 |
RiskForecast |
暴露矩阵、因子协方差、特异风险、流动性、场景 | 描述一起跌、暴露过大和难退出的风险 |
CostForecast |
方向、数量、显性费率、价差、冲击、置信区间 | 成本是数量的函数,不是一条常数 |
TargetPortfolio |
决策时点、目标权重/数量、约束状态、优化器状态 | 想持有什么,与如何成交分离 |
ExecutionPlan |
父单、子单节奏、限价边界、参与率、截止时间、退出政策 | 把目标差额翻译成可控的执行意图 |
OrderEvent/Fill |
client ID、broker ID、状态、成交量价费、事件时间 | 券商回报是事实,必须可幂等重放 |
稳定边界建议固定成:
alpha.predict(feature_snapshot) -> AlphaForecast
risk.estimate(market_snapshot, positions) -> RiskForecast
cost.estimate(trade_list, market_snapshot) -> CostForecast
portfolio.build(alpha, risk, cost, current_positions) -> TargetPortfolio
pretrade.check(target, broker_snapshot, rules) -> PreTradeDecision
execution.plan(decision, market_snapshot) -> ExecutionPlan
broker.submit(plan) -> stream[OrderEvent]
ledger.reconcile(order_events, broker_snapshot) -> ReconciliationReport
聚宽、Qlib 和 QMT 只能实现这些接口,不能反过来侵入领域对象。平台切换时替换 adapter;Alpha、风险、组合与验收逻辑保持不动。
三、总框架候选:为什么不选一个“大一统平台”
| 候选 | 优点 | 主要缺口 | 复杂度 | 生产成熟度 | 当前适配 / 学习 ROI | 结论 |
|---|---|---|---|---|---|---|
| 聚宽全包 | A 股数据、API、回测、模拟接近当前习惯 | 平台锁定;本地实验、实盘订单语义与券商状态难成为统一事实源 | 低 | 中 | 很高 / 高 | 保留为验证环境,不作内核 |
| Microsoft Qlib 全包 | 数据处理、模型训练、记录与 A 股示例完整;论文与源码公开 | 默认策略与执行不是 QMT 生产 OMS;公开样例数据不应当作生产源 | 中 | 研究高、交易低 | 高 / 很高 | 选作研究工作流,不包办实盘 |
| QuantConnect LEAN | 五层接口、事件、现实模型与订单生命周期成熟 | 中国本地数据、规则和 QMT 接入成本较高 | 高 | 高 | 中 / 很高 | 选其架构思想,不把整引擎搬进 V1 |
| vn.py / NautilusTrader 类事件引擎 | 事件驱动、网关、订单状态适合交易工程学习 | 日频 A 股横截面研究和当前 QMT 路线仍需大量适配 | 中高 | 中高 | 中 / 中高 | 80 分阶段参考,不作 V1 主干 |
| 小型本地 Python 内核 + 适配器 | 接口、数据和账本完全受控,最容易跨聚宽/QMT | 自己必须承担测试、状态、监控和文档 | 中 | 取决于实现 | 很高 / 很高 | V1 主干;只自建薄层,复用成熟库 |
最终不是“全自研”。自建的仅是对个人系统最有长期价值的部分:领域对象、平台 adapter、约束配置、决策账本和验收测试;矩阵运算、模型、求解器、存储和追踪全部复用成熟项目。
四、数据与证券主数据层
职责:回答“在时点 ,系统对证券 真正知道什么、能否交易、适用什么规则”。
- 输入:行情、财务与公司行动、指数成分、证券状态、交易日历、交易规则、数据商元数据。
- 输出:
SecurityMaster、不可变原始分区、PIT 标准表、数据质量报告和data_version。 - 60 分失败模式:当前指数成分回填历史、使用修订后财报、只保存后复权价、退市证券消失、不同平台代码混用、规则硬编码。
候选比较
| 候选 | 优点 | 缺点 / 风险 | 复杂度 | 生产成熟度 | 当前适配 / 学习 ROI | 决策 |
|---|---|---|---|---|---|---|
| 只用聚宽平台内数据 | 上手最快,A 股字段和回测环境统一 | 被平台对象与权限绑定;难做独立数据快照和 QMT 重放 | 低 | 中 | 很高 / 中 | 仅做交叉验证 |
| 聚宽/JQData 授权源 + 本地标准层 | 延续当前数据经验,又能固定 PIT 快照与跨平台代码 | 需处理授权范围、增量更新、字段语义和质量测试 | 中 | 中高 | 很高 / 很高 | V1 Baseline |
| Qlib 示例/公开数据 | 快速跑通官方 workflow | Qlib 仓库明确提醒公开数据可能不完善;不适合作为资金决策事实源 | 低 | 低 | 中 / 高 | 只做 smoke test |
| Wind / Choice 等商业数据 | 财务、公司行动、行业与一致预期覆盖较强 | 费用、许可和供应商绑定;个人阶段投入较大 | 中 | 高 | 中 / 中 | 80 分升级 |
| 自抓交易所/网站并拼接 | 可控、费用低 | 复权、修订、历史状态和长期运维成本被严重低估 | 很高 | 低至中 | 低 / 中 | 不作主源 |
聚宽的入门指南适合完成回测—模拟闭环;JQData 文档适合本地访问。但“API 能返回数据”不等于 PIT 正确。聚宽技术支持说明 set_option("avoid_future_data", True) 需要显式开启且默认关闭(未来数据说明),股票数据页也对全证券与历史指数成分的未来函数风险作了提示(股票数据说明);V1 仍要自己做字段可用时间测试。数据能否落本地、保存多久和用于何处,应以账户实际授权条款为准。
V1.0 实现
data/
├── raw/provider=jq/table=bars/trade_date=YYYY-MM-DD/*.parquet
├── raw/provider=jq/table=fundamentals/announce_date=YYYY-MM-DD/*.parquet
├── canonical/bars/...
├── canonical/fundamentals_pit/...
├── canonical/security_master/...
├── canonical/index_membership_pit/...
├── canonical/trading_rules/...
├── snapshots/<data_version>/manifest.json
└── quality/<run_date>/report.json
选 Parquet + DuckDB,原因不是它们“更量化”,而是个人单机上列式分区、SQL 审计和 Python 互操作足够强,又没有数据库服务运维负担。Qlib 只读取 canonical view,不拥有原始数据。
必须保留以下语义:
- 原始价、复权因子和公司行动分开保存,禁止只存一条会随查询日变化的后复权序列。
- 每条基本面记录同时保存
period_end、announce_time、available_time和供应商抓取版本;模型按available_time连接。 - 指数成分、ST/风险警示、停复牌、上市退市和证券板块均为带生效区间的慢变表。
- 交易日历、交易单位、涨跌幅与有效申报规则按市场、板块、证券、日期取值,不散落在策略
if中。 - 每次实验锁定
data_version = hash(manifest + schema + source partitions);供应商历史修订后旧实验仍能重放。 - 每日质量门检查重复键、缺口、极值、价格关系、成交额一致性、复权跳变、成分数量和供应商延迟;失败时不产生新目标仓位。
上海、深圳交易规则在 2026 年又有修订,整体自 2026-07-06 起施行(上交所规则、深交所规则);上交所页面同时单列了暂缓实施条文。规则表因此不仅要保存 effective_from/effective_to,还要保存 active/deferred 状态,不能把“已发布”直接等同于“所有条款均已执行”。
数据层验收
- 任抽 30 个历史决策日,可以还原当日指数成员、证券状态、财报可得值和规则。
- 在数据表中人为注入未来公告,PIT join 测试必须拒绝它。
- 代码不改、固定
data_version重跑,特征 hash 和目标权重在数值容差内相同。 - 退市、长期停牌、代码变更、分红送转和跨年费率至少各有一个回归测试样本。
五、Universe 层:先决定“研究谁”,再判断“今天能不能动”
职责:在每个 as_of 生成可研究集合,同时把“可持有、可开仓、可卖出”拆成不同状态。
- 输入:PIT 指数成分、Security Master、成交额/停牌/风险警示/上市年龄、现有持仓。
- 输出:
UniverseSnapshot,包括成员、状态与逐项原因码。
候选比较
| 候选 | 优点 | 缺点 / 风险 | 复杂度 | 成熟度 | 当前适配 / 学习 ROI | 决策 |
|---|---|---|---|---|---|---|
| 固定股票清单 | 最容易复现 | 生存者偏差、容量与风格集中严重 | 低 | 低 | 低 / 低 | 拒绝 |
| 用今天的指数成分回测历史 | 写法简单 | 直接泄漏未来成分;回测无效 | 低 | 低 | 低 / 低 | 硬门拒绝 |
| PIT 中证 300 | 流动性最好、成本较易控制 | 横截面较窄,大盘风格集中 | 低中 | 高 | 高 / 高 | 挑战者 |
| PIT 中证 500 + 可交易性 | 宽度、流动性与个人维护成本平衡 | 仍有成分调整和中盘风格偏置 | 中 | 高 | 很高 / 很高 | V1 Baseline |
| 中证 1000 / 全 A 流动性池 | Alpha 空间更宽 | 微盘、涨跌停、冲击与数据质量难度明显上升 | 中高 | 中 | 中 / 高 | 80 分升级 |
V1.0 规则
以当时有效的中证 500 成分作为 benchmark-native 初始池,默认:
- 新股观察期先设为 120 个交易日;这是待验证的保守起点,不是市场真理。
- 风险警示证券、已知退市整理状态禁止新开仓;退出服从真实可卖性。
- 用过去 20 日中位成交额和停牌比例做流动性门;阈值由计划资金和容量测试反推,不先拍一个绝对金额。
- 当日停牌、触及价格限制或无有效报价时标为
frozen,不能因为“不合格”就在回测里假装卖掉。 - 昨日买入数量进入
unsettled_buy,当日不得卖出;系统使用券商返回的available_to_sell,不自行乐观推算。 - 现有持仓即使不再允许开仓,也必须继续出现在优化问题中,直到真实退出完成。
建议状态机:
researchable ──┬── openable
├── hold_only
├── sell_only
└── frozen
这比一个布尔字段 tradable=True/False 多一点代码,却能消除大量“回测能卖、实盘卖不掉”的错误。
六、特征、Alpha 与验证层
职责:用决策时点以前的信息,为固定持有期输出横截面预期超额收益或排序;它不决定仓位。
- 输入:PIT 特征快照、标签定义、训练窗口、Universe 快照。
- 输出:
AlphaForecast(score, expected_excess_return, horizon, uncertainty, model_version)。 - 60 分失败模式:随机交叉验证、预处理全样本拟合、标签与交易时点错位、只报告最优回测、模型升级没有挑战者。
候选比较
| 候选 | 优点 | 缺点 / 风险 | 复杂度 | 生产成熟度 | 当前适配 / 学习 ROI | 决策 |
|---|---|---|---|---|---|---|
| 单均线/单规则 | 透明,适合验证数据—下单链路 | 信息维度太少,无法验证横截面研究与组合体系 | 低 | 中 | 低 / 中 | 只作管线 smoke test |
| OLS / Ridge / Elastic Net | 快、稳定、可解释,能暴露泄漏和过拟合 | 难表达非线性与交互 | 低 | 高 | 很高 / 很高 | 强制挑战者 |
| LightGBM | 表格因子、缺失与非线性交互适配;训练快;Qlib 有成熟 Alpha158 配置 | 仍会过拟合;分数未天然校准为预期收益 | 中 | 高 | 很高 / 很高 | V1 主模型 |
| XGBoost / CatBoost | 同属成熟 GBDT,可做模型多样性 | V1 同时维护三套树模型收益有限,调参空间扩大 | 中 | 高 | 高 / 高 | 二级挑战者 |
| LSTM / Transformer / GNN / RL | 能表示序列、关系或策略决策 | 有效样本、非平稳、泄漏、可解释、推理与监控成本都更高 | 高至很高 | 场景依赖 | 低 / 中 | 先拒绝,80 分后再立项 |
Qlib 的官方 benchmark同时列出线性、GBDT 和多种深度模型;它最有价值的结论不是“某模型永远第一”,而是提供统一工作流去做可比实验。LightGBM 的原始设计强调高效梯度提升(项目与论文入口),很适合做个人 A 股结构化因子的第一个非线性 Baseline,但不保证产生超额收益。
V1.0 特征与标签
先使用 5 类、约 80—160 个透明特征,而不是一次堆数千个表达式:
- 动量与反转:5/20/60/120 日收益、近期反转、距高点等。
- 波动与下行风险:不同窗口 realized vol、下行波动、跳空、偏度代理。
- 流动性与交易活跃:换手、成交额、Amihud 类价格冲击代理、量价背离。
- 估值与质量:按真实公告时点接入的估值、盈利质量、成长、杠杆和现金流。
- 市场与行业相对量:相对行业/基准的动量、Beta、残差收益与拥挤度代理。
价格量特征可复用 Alpha158 的组织方式;财务因子必须额外遵守公告时点。每天横截面处理按以下顺序执行,并且所有需要拟合的参数只在训练集学习:
原始 PIT 值
→ 缺失原因标记
→ 温莎化/稳健截尾
→ 行业内或全市场标准化
→ 可选的行业、规模中性化
→ 缺失填补 + missing indicator
→ FeatureSnapshot
基准标签先定义为:在 日收盘数据完整到达后产生预测,以固定执行窗口的 VWAP 为起点、同一窗口的 VWAP 为终点,计算 5 个持有区间的个股收益,再减同期中证 500 收益。研究标签使用固定、事先声明的 VWAP 代理;模拟/实盘绩效再用真实成交替换。不能用 日收盘价生成信号后又假设自己在同一收盘价满额成交。
构造 日样本时,不能用事后看到的 停牌、封板或成交量反过来筛掉股票。若 没有可执行 VWAP,记录 label_status=non_executable/censored,在样本覆盖和执行机会成本里单列;不能静默删除后只训练“第二天恰好能成交”的幸存样本。 盘前实际可交易状态只属于 PreTrade/Execution 层。
V1.0 验证协议
普通随机 CV 不适合有时间顺序的数据,scikit-learn 的 TimeSeriesSplit 文档也明确指出普通交叉验证会出现“用未来训练、在过去评估”的问题。本系统再向前一步处理横截面标签重叠:
- 初始研究窗:滚动 4 年训练、1 年验证,随后 3—6 个月纯样本外;每月重训,周度出分。
- 在相邻集合之间 purge 至少一个标签持有期,并保留 embargo;禁止重叠未来收益跨越边界。
- 预处理器、特征选择、模型和分数—收益校准器全部只在训练/验证区间拟合。
- 超参数先在少量预注册网格中选择;测试期只打开一次,之后进入新的向前窗口。
- 同时保留 Ridge、LightGBM 与无 Alpha 的 benchmark;LightGBM 只有在多段样本外、成本后、稳定性和风险暴露上整体胜过 Ridge,才获得生产资格。
- 用 IC、RankIC、ICIR、分层收益、衰减、换手和按行业/规模分组稳定性评估预测;不用单一 Sharpe 选模型。
- 对标签、特征滞后、成分股历史、复权和费用分别做刻意破坏测试,确保测试能抓到泄漏。
模型最终输出不是“买入前 50 名”,而是一个带版本与持有期的预测。是否买、买多少,由风险和成本共同决定。
七、风险模型与风险管理层
职责:风险模型在交易前描述组合可能怎样一起亏;风险管理根据这些估计修改或拒绝目标。两者都不是“跌到某价卖出”的同义词。
- 输入:持仓、候选权重、行业与风格暴露、协方差、特异风险、流动性、市场状态。
- 输出:
RiskForecast、约束与限额、压力测试、RiskDecision。 - 60 分失败模式:只设单股止损、只看历史波动、直接使用高维样本协方差、停牌仓位在风险报告里消失。
候选比较
| 候选 | 优点 | 缺点 / 风险 | 复杂度 | 生产成熟度 | 当前适配 / 学习 ROI | 决策 |
|---|---|---|---|---|---|---|
| 单股止损/组合回撤线 | 易懂,适合作为事后保护 | 不描述集中度、相关性、Beta、流动性与隔夜跳空 | 低 | 低至中 | 中 / 低 | 只能作最后保险丝 |
| 历史波动 + 样本协方差 | 实现直接 | 股票数接近或超过样本数时病态、优化权重极不稳定 | 低中 | 中 | 中 / 高 | 仅作对照 |
| Ledoit–Wolf 收缩协方差 | 数值稳定、实现成熟 | 仍难直接解释行业和风格风险 | 中 | 高 | 高 / 高 | 协方差挑战者 |
| 行业 + 风格因子模型,协方差收缩 | 可解释、可设暴露约束、适合横截面股票组合 | 因子定义、收益估计和特异风险要自己验证 | 中高 | 高 | 很高 / 很高 | V1 Baseline |
| 商业 Barra/供应商风险模型 | 数据、分类与生产流程成熟 | 昂贵、许可限制、内部逻辑与个人策略未必透明 | 中 | 很高 | 低 / 中 | 80—90 分升级 |
Ledoit 与 Wolf 对组合问题的核心提醒是:高维样本协方差往往不适合直接优化,收缩能改善估计稳定性(论文入口、scikit-learn 实现)。MSCI 的权益因子模型说明则体现了行业、风格与特异风险的机构化表达。V1 借用思想,不复制商业模型名称或参数。
V1.0 透明因子风险模型
对股票收益使用:
- :在收益 发生前已经可得的行业与风格暴露;不能拿 日收盘后才知道的数据解释同一天收益。
- :决策时点 已经可得的行业 one-hot、规模、市场 Beta、动量、波动、流动性、价值/杠杆等少量透明风格暴露。
- :用稳健加权横截面回归估计的因子收益;行业哑变量与截距需固定基准或施加和为零约束,避免不可识别。
- :截至 的因子收益 EWMA 协方差,再做收缩与特征值下限处理。
- :截至 的个股残差方差稳健估计,设样本不足和极低方差 floor。
- :交给组合优化器的事前股票协方差预测。
Qlib 的 EnhancedIndexingStrategy 已展示风险暴露、因子协方差、特异风险、blacklist 与不可交易持仓如何进入增强指数优化(策略文档、实现源码)。V1 可先用它做研究参照,生产内核保留自有 RiskForecast 格式。
风险约束分三类:
- 组合构建前:单股、行业相对 benchmark、市场 Beta、风格暴露、预测波动、跟踪误差、换手、ADV 容量、持仓数和现金缓冲。
- 交易前:目标是否超限、可卖量、价格/行情新鲜度、重复订单、预计现金、单日成交与申报频率。
- 运行中:数据停止、券商断线、订单拒绝激增、成交价偏离、持仓对账差异、组合日损失/回撤状态。
压力测试至少覆盖:市场单日下跌、最大行业冲击、波动率翻倍、相关性向 1 收敛、交易成本 2 倍、预期成交只有 50%、若干大持仓连续不可卖。压力场景的结果是减仓、延后交易或停机规则,而不是报告里的一张装饰图。
风险层验收
- 把两个高度相关股票同时放大,组合风险必须明显高于分散持仓。
- 因子数据缺失或协方差非正定时,系统使用保守 fallback 并告警,不能静默输出 NaN 权重。
- 停牌持仓以冻结权重进入总风险;无法交易不等于没有风险。
- 所有硬限额在优化前、优化后和下单前各检查一次;三次使用同一规则版本。
- 止损仅保留为极端保护,不参与“风险模型已经完成”的评分。
八、费用、滑点与容量层
职责:估计从当前持仓走到目标持仓所需付出的显性费用、价差、冲击和机会成本,并在交易后用真实成交校准。
- 输入:方向、计划数量、报价/分钟量价、ADV、波动、费率版本、券商佣金、执行窗口。
- 输出:逐股票、逐订单的
CostForecast(low, base, high)和容量报告。 - 60 分失败模式:零成本、永远固定一个滑点、假设目标数量全部成交、只在绩效报表末尾扣费而不影响权重。
候选比较
| 候选 | 优点 | 缺点 / 风险 | 复杂度 | 生产成熟度 | 当前适配 / 学习 ROI | 决策 |
|---|---|---|---|---|---|---|
| 零成本 | 方便检查代码 | 对可交易性没有任何意义 | 低 | 无 | 无 / 低 | 拒绝 |
| 固定费率 + 固定滑点 | 能跑,参数少 | 不随方向、流动性、规模和波动变化 | 低 | 低至中 | 中 / 中 | smoke test |
| 日期化费率 + 半价差 + 参与率/波动冲击 | 可解释,能进入优化和容量分析 | 冲击系数需真实成交持续校准 | 中 | 高 | 很高 / 很高 | V1 Baseline |
| Almgren–Chriss / 多期凸成本模型 | 风险—冲击权衡清楚,可做动态计划 | 参数估计与模型假设要求更高 | 中高 | 高 | 中 / 高 | 80 分升级 |
| 盘口/队列仿真或学习型执行成本 | 对高频限价单更细 | 数据、撮合细节和运维成本远超日频 V1 需求 | 很高 | 场景依赖 | 低 / 中 | 暂拒绝 |
组合决策的成熟表达不是“先求权重、最后再扣手续费”。Boyd 等人的多期交易优化把预期收益、风险、交易成本、持有成本和约束放进同一个问题;Almgren–Chriss 则系统讨论执行风险与市场冲击的权衡(论文 DOI)。V1 使用其思想的简化、可校准版本。
V1.0 成本函数
对计划交易 估计:
其中:
fee:印花税、经手/监管/过户等费用和券商佣金/最低佣金,全部按日期与账户配置。spread:优先用可得的盘口或分钟数据估计;没有可靠报价时使用保守高低价代理,并标记较低置信度。impact:以波动和参与率为主的平方根代理。它不是自然定律, 必须用实盘成交拟合并做 0.5×/1×/2× 压力测试。
需要区分“账本里的真实费用”与“凸优化器里的成本代理”。单笔最低佣金在零交易与非零交易之间存在离散跳变,不能在纯连续凸问题里被精确表达。V1 的连续优化器只使用比例税费、价差、凸冲击和换手惩罚,并设置最小交易金额;取整后删除不覆盖最低佣金的碎单,执行 repair,再用账户真实最低佣金重算现金、回测与 TCA。若以后必须联合决定“是否交易”并精确计入每笔最低佣金,应升级为混合整数问题,而不是继续把它称为纯凸优化。
财政部规定证券交易印花税自 2023-08-28 起减半征收(官方公告);交易所收费项目也有各自的现行标准(上交所收费指引、深交所收费页)。这些链接用于核验,不应把今天的数字永久写死在代码里。券商佣金和最低收费以实际账户交割单反推。
V1 初始容量政策:
- 优化器同时看单笔参与率、组合一天总成交额、单只股票清仓天数和全组合容量。
- 先把
order / ADV ≤ 5%作为保守研究上限,并测试 1%、3%、5% 三档;上线阈值必须由分钟量和真实成交重新校准。 - 如果策略只有在零成本或极小资金下成立,结论应是“无当前容量”,不是继续调模型。
- 回测输出低/基准/高三条成本后净值;选型看最差合理情形是否仍可接受。
成本层验收
- 买卖方向、最低佣金和日期切换有单元测试,并能与实际交割单逐项对上。
- 将计划交易放大 10 倍,单位成本和成交时间不得保持不变。
- 组合优化前的预测成本与成交后的 implementation shortfall 可逐订单关联。
- 无分钟/盘口数据时明确降低置信度并提高冲击假设,不能悄悄回退到零滑点。
九、组合构建层:把 Alpha、风险和成本真正放在一起
职责:把预测转换成满足风险、成本、容量与真实持仓约束的目标组合。
- 输入:
AlphaForecast、RiskForecast、CostForecast、当前持仓与可交易边界。 - 输出:
TargetPortfolio、预计风险/成本、约束余量、优化诊断和不可行原因。 - 60 分失败模式:Alpha 排名直接等于仓位、优化器报错就静默等权、停牌股从归一化分母消失、求出小数股后粗暴取整导致越界。
候选比较
| 候选 | 优点 | 缺点 / 风险 | 复杂度 | 生产成熟度 | 当前适配 / 学习 ROI | 决策 |
|---|---|---|---|---|---|---|
| 等权 | 透明、稳健、参数极少 | 忽略预测强弱、相关性、风险、成本和容量 | 低 | 高(作为朴素规则) | 中 / 高 | 必备 benchmark,不作最终 Baseline |
| Top-k / TopkDrop | Qlib 样例成熟,换手逻辑直观 | 风险和成本通常没有在权重生成中被完整联合处理 | 低中 | 中 | 高 / 很高 | 研究挑战者 |
| 分数比例 / softmax | 保留预测强弱 | 对分数尺度敏感,仍不处理协方差和约束 | 低 | 中 | 中 / 中 | 不选 |
| 风险平价 | 不依赖 Alpha 尺度,资产配置中有价值 | 股票横截面 Alpha 目标被弱化;行业与风格仍需约束 | 中 | 高 | 中 / 高 | Beta 层候选,不作本层主模型 |
| 成本感知的受约束凸优化 | 风险、Alpha、换手、冻结仓位和容量统一;诊断可审计 | 需要校准参数、稳定风险模型和不可行处理 | 中高 | 高 | 很高 / 很高 | V1 Baseline |
V1.0 优化问题
使用 CVXPY 解一个长仓凸优化问题。这里的 特指上一节的连续凸成本代理,不假装精确包含每笔最低佣金。概念形式为:
四项必须先统一量纲: 是校准后的 5 日预期超额收益,不是原始 LightGBM rank; 与同一持有期对齐; 以 NAV 比例表示;换手也是权重比例。年化波动和跟踪误差只用于展示/限额换算,不能把日频协方差、5 日 Alpha 和人民币成本未经缩放直接相加。
约束至少包括:
另外将真实交易边界转成数量约束:停牌证券数量固定;卖出量不得超过券商可卖量;禁止开仓的证券只能不增仓;风险退出也不能假装穿越涨跌停。权重优化后进行交易单位取整,再用一个小型 repair pass 恢复现金、单股和行业约束。
精确持股数、最小非零仓位和“是否产生一笔订单”都是离散决策,也不属于纯连续凸问题。V1 先用当前/冻结持仓 + Alpha 预筛候选形成 60/100/150 只候选池,再做连续凸优化;取整后删除尘埃仓位并 repair,把 30—80 只作为目标带和诊断指标,而不是求解器硬约束。若未来必须严格持有恰好 50 只或精确联合最小佣金,应明确升级为混合整数优化。
V1 的初始研究网格而非永久参数:
| 参数 | 起始搜索范围 | 目的 |
|---|---|---|
| 候选池规模 | 60 / 100 / 150 | 预筛后进入连续优化;比较宽度、稳定性与计算量 |
| 目标持仓带 | 30—80 | 取整/repair 后的诊断范围,不是凸优化硬约束 |
| 单股上限 | 1%—3% | 防止模型把不稳定分数集中成大仓位 |
| 现金缓冲 | 3%—8%,初始 5% | 吸收费用、价格变化和异步成交 |
| 行业相对偏离 | ±3%—5% | 让超额主要来自选股而非押行业 |
| 单次单边换手 | 10%—20% | 与周频信号、成本和容量共同验证 |
| ADV 上限 | 1% / 3% / 5% 三档 | 输出容量敏感性,不只看一个假设 |
数值最终由风险预算与成本后样本外结果确定。不能先挑让回测最好看的组合,再称它为“风险参数”。
不可行和求解失败政策
这是 60 分系统与 Demo 的重要分界:
- 约束分为绝不放松的硬约束与允许有限 slack 的软约束。
- 证券规则、可卖量、现金非负、合规黑名单是硬约束。
- 行业偏离和换手可按预先定义的顺序小幅放松,并完整记录 slack 成本;候选池与目标持仓带在求解器外按已发布配置处理。
- 求解器超时、非最优或解在容差外时,先尝试上一组已验证参数;仍失败则输出
NO_TRADE或只执行明确的风险降低单。 - 禁止“优化失败 → 自动等权 → 继续下单”。这会把系统错误伪装成投资决策。
为什么不是等权
等权不是坏方法:它应当永久保留为基准,因为稳定、易解释,常常能揭穿复杂模型。但它不能作为这套系统的最终 60 分答案,因为它对“两个高度相关股票是否各买 2%”“预期 Alpha 能否覆盖冲击”“某行业是否已过载”“一只股票是否根本卖不掉”都没有答案。
验收要求:每一个目标权重都能分解为 Alpha 贡献、风险惩罚、成本惩罚和活跃约束;对 Alpha 加微小扰动时,权重不能大幅跳变;rounding 后重新过全部硬约束。
十、执行与 OMS 层:目标仓位不等于订单,订单也不等于成交
职责:把目标—当前差额转成一组受限父单/子单,维护券商异步状态,最后给账本真实成交。
- 输入:
TargetPortfolio、实时持仓/现金/可卖量、行情、交易规则、成本与执行窗口。 - 输出:
ExecutionPlan、订单命令、OrderEvent、Fill、执行异常和残余目标。 - 60 分失败模式:回测默认瞬间全成;撤单后立即重报却未确认旧单;重启后重复下单;用本地预期仓位覆盖券商事实。
候选比较
| 候选 | 优点 | 缺点 / 风险 | 复杂度 | 生产成熟度 | 当前适配 / 学习 ROI | 决策 |
|---|---|---|---|---|---|---|
| 立即市价/假设全成 | 代码最少 | A 股订单、部分成交、容量、异步和价格限制全部被抹掉 | 低 | 低 | 低 / 低 | 拒绝 |
| 次日开盘一次性订单 | 与日频信号容易对齐 | 开盘波动、冲击和失败集中;大单不稳 | 低 | 中 | 中 / 中 | 仅小单挑战者 |
| 固定 TWAP | 可解释、实现简单 | 不看当时成交量,冷清时段可能过度参与 | 中 | 高 | 高 / 高 | 组成部分 |
| 历史 VWAP | 跟随典型量能曲线 | 当日量能偏离历史时失真;无法保证成交 | 中 | 高 | 高 / 高 | 组成部分 |
| 带限价边界的 TWAP/POV 混合 | 时间节奏、参与率、价格保护和剩余量能统一 | 状态机与参数校准工作较多 | 中高 | 高 | 很高 / 很高 | V1 Baseline |
| 盘口最优执行 / RL | 可能适应微观结构 | 逐笔数据、队列建模与安全验证远超日频需求 | 很高 | 场景依赖 | 低 / 低 | 暂拒绝 |
QMT 的 XtQuant 快速开始把行情与交易接口分开;XtTrader 文档提供委托、撤单、资产/持仓/订单/成交查询,以及断线、委托、成交、撤单错误和异步委托回调。这些接口形态本身就说明:实盘必须是状态机,而不是一行 order_target_percent。LEAN 的实盘订单文档同样强调实盘订单异步、可部分成交且修改不保证成功。
V1.0 Guarded TWAP/POV
默认决策—执行时序:
T 日收盘后
数据完整性通过 → 特征/预测 → 风险/成本 → 目标仓位 → 决策签名
T+1 开盘前
查询券商资产、持仓、可卖量、未结订单 → 三账预对账 → PreTrade Gate
T+1 09:35 以后
风险降低单 / 资金受限时的卖单优先
→ 在预定窗口按时间桶与参与率拆分
→ 限价保护、超时撤单、确认后再重报
→ 回调驱动剩余量更新
窗口结束
按预设残余政策放弃、延后或有限追价;不得为了“完成回测目标”无界追单
→ 日终券商对账 → TCA
初版执行器要有以下机制:
- 父单身份:
decision_id + instrument + side形成幂等 key;同一决策重放不会产生第二个父单。 - 订单状态机:
CREATED → SENT → ACKED → PARTIAL → FILLED,并允许CANCEL_PENDING → CANCELED、REJECTED、UNKNOWN;只有确认旧单结束才能替换。 - 数量真相:剩余量由成交回报累计,不由“已提交量”推断;启动时先从券商拉取未结订单和成交恢复。
- 价格保护:限价同时受最新有效报价、可接受滑点、当日规则和策略放弃阈值约束;行情过期时停止新单。
- 参与率保护:子单和时间桶成交量不超过预定比例;量能不足时减少而不是假设全成。
- 现金与 T+1:买单只使用已确认可用资金;卖单只使用券商
available_to_sell;所有费用留缓冲。 - 节流:每秒报撤单数、每日总订单、单标的撤改次数和异常拒单率均有上限,且低于券商/交易所允许范围。
- Kill switch:断线、行情陈旧、对账不平、重复回报异常、资产变化超阈值或拒单爆发时,禁止新开仓;是否撤掉已有安全订单由场景配置。
回测成交模型必须与执行器同源
至少使用分钟数据做次日执行回放:
- 订单价格被该分钟高低价触及只是成交的必要条件,不是充分条件;仍受可成交方向、成交量和参与率限制。
- 单分钟成交量受 bar volume × participation cap 限制,因此允许部分成交和残单。
- 成交价加入方向相关的价差与冲击,费用由同一个版本化 cost engine 计算。
- 停牌、无有效报价、T+1、价格限制、交易单位、公司行动和未成交残余都真实进入仓位。
- 对一字涨跌停或单边封板,分钟 OHLC/成交量不能证明自己的队列能成交;V1 默认不成交,除非更细数据能证明对手方可成交量,并另做乐观/基准/悲观敏感性。
- 回测记录的是
OrderEvent序列,不只在持仓表里瞬间改一个数字。
回测不可能完整复原队列位置,因此应偏保守,并用聚宽模拟和 QMT 影子盘校准。它的目标是排除明显不可交易策略,不是证明未来一定按模拟价格成交。
十一、评价、归因与反馈层
职责:判断预测是否有效、组合是否按预期承担风险、执行损失在哪里、实盘是否偏离研究,并把证据反馈到各层。
- 输入:特征/预测、目标仓位、风险/成本预估、订单事件、成交、每日持仓现金、benchmark。
- 输出:研究报告、组合归因、TCA、模型/数据漂移、运行 SLO 与升级/回滚决定。
- 60 分失败模式:只有收益率、只看全样本 Sharpe、隐藏失败订单、每次实验无法追到代码与数据。
候选比较
| 候选 | 优点 | 缺点 / 风险 | 复杂度 | 生产成熟度 | 当前适配 / 学习 ROI | 决策 |
|---|---|---|---|---|---|---|
| 累计收益 + Sharpe | 快速 | 无法区分 Alpha、Beta、成本、风险和执行问题 | 低 | 低 | 低 / 低 | 拒绝 |
| QuantStats/pyfolio 类 tear sheet | 图表丰富,诊断方便 | 主要处理净值结果,不拥有决策—订单—成交链 | 低 | 中 | 中 / 中 | 辅助输出 |
Qlib SigAnaRecord / PortAnaRecord |
信号和组合分析接入 workflow,复现实验方便 | 对真实 QMT 订单、成交和对账不够 | 中 | 研究高 | 高 / 很高 | 研究 Baseline |
| 自有事件账本 + TCA + MLflow | 能贯通研究与实盘,所有差异可追溯 | 需要定义 schema、监控与日常纪律 | 中高 | 高 | 很高 / 很高 | 生产 Baseline |
| 商业 PMS/风险/TCA 平台 | 功能与治理成熟 | 成本和个人系统集成不匹配 | 高 | 很高 | 低 / 低 | 90 分选项 |
Qlib 提供 SigAnaRecord 和 PortAnaRecord 等记录模板(官方 API)。MLflow Tracking则能记录参数、代码版本、指标和模型/文件 artifacts,本地运行已经足够个人 V1 使用。二者都不替代真实交易账本:研究记录回答“这个实验是什么”,账本回答“资金实际上发生了什么”。
五组必须同时看的指标
| 视角 | 核心指标 | 它回答什么 |
|---|---|---|
| Alpha | IC、RankIC、ICIR、分层单调性、衰减、覆盖率、分行业/规模稳定性 | 预测本身有没有横截面信息 |
| 组合 | 成本前后超额、IR、Sharpe/Sortino、最大回撤、Calmar、跟踪误差、换手、持仓集中度 | 信息是否被稳定地变成组合 |
| 风险 | 行业/风格/Beta 暴露、预测与实现波动、风险贡献、压力损失、限额触发 | 赚的钱是否来自意外押注 |
| 执行 / TCA | arrival shortfall、VWAP/close 偏离、填单率、撤单/拒单率、完成时长、机会成本、参与率 | 纸面 Alpha 在哪里损失 |
| 运行 | 数据延迟/缺口、job 成功率、订单状态未知数、对账差异、恢复时间、告警确认 | 系统是否可靠运转 |
对收盘后决策的策略,TCA 要把隔夜跳空与日内执行分开:隔夜段从 收盘到 首个可执行基准价;implementation shortfall 的 arrival benchmark 使用 PreTrade Gate 通过后的首个有效报价/预先声明的执行窗基准。否则会把无法在夜间成交的价格变化错误归因给执行器。
每次再平衡至少保存四条净值或 P&L 轨迹:
理想 Alpha 组合(无约束、无成本)
→ 加风险/持仓约束后的目标组合
→ 使用回测成交模型后的模拟组合
→ 使用券商真实成交后的实盘组合
相邻两条之间的差异分别对应组合约束损失、模拟执行损失和研究—实盘偏差。只有一条最终净值时,任何层都能把错误推给别的层。
Champion / Challenger 与升级纪律
- Champion 固定运行;Ridge、等权/Top-k、旧风险模型和旧成本模型保持为 challengers。
- 新模型必须在预注册的样本外窗口、成本压力、多随机种子/参数邻域和暴露约束下胜出。
- 不以一次显著性或一个市场状态升级;先 shadow,再小资金 canary,最后逐级放量。
- 模型性能下降时先定位数据、Universe、风险、成本和执行,不默认“重新训练就会好”。
- 每次升级写 decision record:证据、预期改善、风险、回滚条件、负责人和生效时间。
十二、工程、运行与合规层
这层不产生 Alpha,却决定研究结果是否能安全变成资金行为。
- 职责:固化接口、版本、运行状态、权限、恢复、审计与平台适配,使研究和交易可以确定性重放。
- 输入:前述所有领域对象、配置、外部事件、部署包和凭据引用。
- 输出:可复现实验、已签名决策、部署 artifact、三本账、监控告警、对账与合规证据。
- 60 分失败模式:Notebook 隐式状态、生产机手改代码、凭据进入仓库、重启重复下单、出错后没有 runbook。
工程形态候选
| 候选 | 优点 | 缺点 / 风险 | 复杂度 | 生产成熟度 | 当前适配 / 学习 ROI | 决策 |
|---|---|---|---|---|---|---|
| Notebook + 平台脚本 | 探索最快 | 隐式状态、难测试、难重放、平台锁定 | 低 | 低 | 中 / 中 | 仅探索 |
| 模块化 Python monorepo | 一人可维护,接口与测试集中,部署简单 | 需要持续守住边界 | 中 | 高 | 很高 / 很高 | V1 Baseline |
| 多进程服务 + 消息队列 | 隔离与恢复能力更强 | 调试、部署和状态一致性成本上升 | 高 | 高 | 低 / 中 | 80 分按瓶颈引入 |
| 微服务/Kubernetes | 团队扩展与资源调度强 | 个人日频系统严重过度设计 | 很高 | 很高 | 很低 / 低 | 拒绝 |
V1.0 仓库布局
quant-os/
├── pyproject.toml # 锁定 Python 与依赖
├── configs/ # 经 schema 验证的研究/风险/执行配置
├── src/
│ ├── domain/ # 九种稳定对象,不导入任何平台 SDK
│ ├── data/ # provider adapters、PIT、质量与版本
│ ├── universe/
│ ├── features/
│ ├── alpha/
│ ├── risk/
│ ├── cost/
│ ├── portfolio/
│ ├── execution/ # planner、OMS 状态机
│ ├── ledger/ # 决策/订单/成交/持仓/现金
│ ├── evaluation/
│ └── adapters/
│ ├── qlib_research/
│ ├── joinquant/
│ └── qmt/
├── tests/
│ ├── unit/
│ ├── integration/
│ ├── replay/
│ └── parity/
├── migrations/ # schema 与规则迁移
├── runbooks/ # 断线、拒单、错账、数据失败处置
└── artifacts/ # 仅索引;大数据/模型由 manifest 指向
V1 不要求为了“像机构”而拆微服务。一个进程内也可以拥有严格接口、事件日志和恢复能力。只有观测到资源隔离、延迟或可靠性瓶颈后才拆服务。
三本账与重放
| 账本 | 写入时点 | 真相是什么 |
|---|---|---|
| 决策账 | 目标组合批准后 | 模型在何种数据、风险、成本和约束下想做什么 |
| 订单/成交账 | 每个券商回调到达时 | 实际提交、确认、撤改、拒绝、部分成交和费用 |
| 券商快照账 | 启动前、关键事件后、日终 | 券商认定的资产、持仓、可用量和未结订单 |
三账不得互相覆盖。对账输出差异及解释,只有白名单时间差允许自动清除;未知差异使次日系统进入 SAFE_MODE。所有外部事件保留原始 payload 的脱敏 hash 和解析结果,回放相同事件序列应得到相同订单状态。
测试金字塔
- 单元:费用日期切换、可卖量、交易单位、复权、PIT join、约束与 rounding。
- 属性测试:现金不为负、持仓数量守恒、成交累计不超过订单、重复事件不重复记账。
- 集成:固定小样本从数据到目标,再通过模拟 broker 产生部分成交/拒单/断线。
- Replay:保存一段 QMT 回调流,在无网络环境重建订单与持仓。
- Parity:本地与聚宽对齐收益口径、信号日、费用、目标权重;差异必须落报告。
- 故障注入:行情过期、数据缺列、回调乱序/重复、撤单超时、求解器失败、进程重启。
可观测性与操作
每次 run 至少记录:run_id、Git commit、dirty flag、配置 hash、数据版本、模型版本、规则版本、随机种子、依赖锁、启动人、环境和时间。日志使用结构化字段而非拼接长字符串;指标、告警和 runbook 一一对应。
实盘部署保留人工批准点:系统可以自动生成目标和执行计划,但从模拟切换到实盘、放大资金、改变最大申报频率或更换策略版本必须显式批准。密码、token、cookie 和券商凭据只放系统钥匙串/环境注入,不进入 Git、MLflow artifacts 或 OB。
合规不是上线后的补丁
证监会《证券市场程序化交易管理规定(试行)》自 2024-10-08 起施行,要求程序化交易投资者报告账户、资金、策略、软件等信息,并确立“先报告、后交易”(证监会原文)。沪深交易所实施细则自 2025-07-07 起施行(上交所、深交所)。
因此,个人账户不应把“金额不大”理解为自动豁免。上线前需要向实际开户券商书面确认:
- QMT/MiniQMT/XtQuant 到底开通哪种、模拟与实盘各有哪些 API 和频率限制。
- 程序化交易报告的字段、入口、审核状态和策略/软件重大变更后的更新义务。
- 最大报撤频率、每日委托数、异常行为控制和券商侧熔断。
- 实盘可用行情层级、数据授权、委托类型、回调保证和断线重连行为。
- 交割单费用、最低佣金、资产/订单/成交查询的最终一致时间。
这五项未确认,系统可以继续回测和模拟,但 G10 不通过,不能标记为实盘 Baseline。
十三、V1.0 冻结配置:第一版到底采用什么
前面的候选比较最终收敛为下面这一套。这里的默认值是第一轮验证起点,所有变化都通过配置和 decision record,而不是散落在代码里。
system:
market: CN_A_SHARE
mode: long_only_cash
research_engine: qlib_local
validation_engine: joinquant
live_adapter: qmt_xttrader
decision_timezone: Asia/Shanghai
data:
primary_provider: authorized_joinquant_or_jqdata
canonical_store: parquet_duckdb
point_in_time: strict
raw_immutable: true
version_by_manifest: true
universe:
benchmark: CSI500
membership: point_in_time
ipo_seasoning_days: 120 # 初始研究值
liquidity_window_days: 20
states: [openable, hold_only, sell_only, frozen]
alpha:
champion: lightgbm
mandatory_challenger: ridge
features: [momentum, reversal, volatility, liquidity, valuation, quality, relative]
label: next_executable_5d_excess_return
rebalance: weekly
retrain: monthly
validation: purged_walk_forward
risk:
model: transparent_industry_style_factor
covariance: ewma_shrinkage
specific_risk: robust_residual_with_floor
stress: [market_shock, industry_shock, vol_2x, corr_up, cost_2x, fill_50pct]
cost:
fee_schedule: versioned_account_specific
optimizer_model: continuous_convex_surrogate
exact_ticket_fees: post_rounding_backtest_and_tca
min_trade_notional: account_calibrated
spread_model: quote_or_conservative_proxy
impact_model: volatility_sqrt_participation
scenarios: [low, base, high]
portfolio:
solver: cvxpy_convex
objective: alpha_minus_risk_minus_cost_minus_turnover
cash_buffer: 0.05 # 初始研究值
candidate_count_grid: [60, 100, 150]
target_holdings_band: [30, 80] # 取整/repair 后的诊断带
exact_cardinality_constraint: false
single_name_cap_grid: [0.01, 0.02, 0.03]
industry_active_cap_grid: [0.03, 0.05]
one_way_turnover_grid: [0.10, 0.15, 0.20]
adv_cap_grid: [0.01, 0.03, 0.05]
solver_failure: no_trade_or_risk_reduction_only
execution:
algorithm: guarded_twap_pov
decision_time: T_after_close
trade_day: T_plus_1
start_after_open_minutes: 5
partial_fill: true
cancel_replace: ack_before_replace
stale_market_data: block_new_orders
reconciliation: startup_event_driven_eod
tracking:
research: qlib_records_and_mlflow_local
versions: [git_commit, env_lock, config_hash, data_version, model_version, rules_version]
ledgers: [decision, order_fill, broker_snapshot]
一次完整再平衡的可执行顺序
- 数据封版:确认 日所需数据到齐,写
data_version与质量报告。 - Universe:按 日状态生成研究、可开、只持、只卖和冻结集合。
- 预测:加载已批准 champion,对
FeatureSnapshot出 5 日 Alpha;Ridge 同步出挑战结果但不下单。 - 风险/成本:估计风险暴露、协方差、特异风险、三档成本和容量。
- 组合:优化目标,取整与 repair,再做独立 post-check;保存
decision_id。 - 发布一致性复核:在开发/发布 gate 中,用相同 fixture 在本地与聚宽检查规则、费用、信号和目标差异;超过容差则阻断该
release_id。实盘日不在线依赖聚宽。 - 开盘前对账:QMT 查询资产、持仓、可卖量、未结订单和昨日成交;不平则
SAFE_MODE。 - PreTrade Gate:重算现金、目标差额、当日规则、行情新鲜度、限额和申报预算。
- 执行:父单拆子单,回调更新状态;先处理必须降低风险的可卖单,再按现金和优先级安排其余交易。
- 反馈:窗口结束处理残余;日终对账,生成 P&L、暴露、TCA、异常和 champion 健康报告。
平台之间传什么,不传什么
| 边界 | 允许传递 | 禁止依赖 |
|---|---|---|
| Qlib → 核心 | 带时间、持有期、版本的预测表 | Qlib 内部 dataset/model 对象直接进入交易 |
| 核心 → 聚宽 | Universe、目标权重、费用/成交参数、run ID | 用聚宽隐式全局状态定义策略事实 |
| 核心 → QMT | 已批准的父单意图、限额和 idempotency key | 把模型代码塞进券商 callback |
| QMT → 核心 | 原始回报、标准化事件、券商快照 | 用本地预期覆盖券商持仓或订单状态 |
这使“聚宽先跑、以后迁移 QMT”不再等于重写策略。真正需要重写的是平台适配器和少量时序,不是 Alpha、风险、成本与组合定义。
十四、这套 V1.0 为什么是 66 分,而不是 40 或 90
各层目标成熟度
| 层 | 纸面目标分 | 超过 60 的理由 | 还没到 80 的原因 |
|---|---|---|---|
| 数据 / Security Master | 68 | PIT、原始/标准分层、规则版本、快照与质量门齐全 | 单主源,复杂公司行动和历史修订仍需长期校验 |
| Universe | 66 | PIT 成分、流动性、持有/买卖/冻结状态分离 | 尚无动态容量池和多 benchmark 稳定性 |
| Alpha / 验证 | 65 | LightGBM + Ridge、purged walk-forward、成本后多维指标 | 特征与标签仍是公开范式,尚无长期实盘证据 |
| 风险 | 64 | 透明多因子、收缩、特异风险、事前约束和压力测试 | 因子与协方差未用多年实盘/商业模型交叉验证 |
| 成本 / 容量 | 62 | 日期费率、价差、冲击、三档压力并进入优化 | 冲击参数尚无足量真实成交拟合 |
| 组合 | 68 | Alpha—风险—成本联合优化,真实交易边界和失败降级 | 单期、参数不确定性处理仍较基础 |
| 执行 / OMS | 62 | 异步状态、部分成交、幂等、节流、恢复与对账 | 没有精细量能预测、队列/盘口模型和多券商容灾 |
| 评价 / 反馈 | 65 | 预测—目标—成交四轨迹、归因、TCA、champion/challenger | 自动漂移诊断与决策治理仍较轻 |
| 工程 / 运行 / 合规 | 64 | 模块单体、测试、事件账本、runbook、报告 gate | 单机、人工值守、灾备与权限治理有限 |
总分计算
| 总评分维度 | 权重 | 目标得分 | 加权贡献 |
|---|---|---|---|
| 数据与时点正确性 | 15% | 68 | 10.20 |
| 研究与样本外验证 | 15% | 66 | 9.90 |
| 风险与组合构建 | 15% | 67 | 10.05 |
| 成本与执行现实性 | 15% | 62 | 9.30 |
| 工程与可复现性 | 15% | 68 | 10.20 |
| 运行、对账与监控 | 15% | 63 | 9.45 |
| 合规与平台迁移 | 10% | 68 | 6.80 |
| 合计 | 100% | 65.90 ≈ 66 |
[!important] 分数的正确读法 66 是这份设计在全部实现、测试、模拟和券商确认通过后的目标分。今天只有文档而没有证据,系统不能自称 66 分;每个 Gate 都应链接到测试报告、模拟记录或券商确认材料。
它不是 40 分,因为已经显式处理了数据时点、相关风险、成本容量、异步订单、对账与合规;它不是 90 分,因为没有私有数据优势、商业风险模型、长期成交数据库、多券商容灾、严格权限治理和多年资金验证。
十五、几条关键取舍:明确说“不选什么”
1. 不把等权当最终答案
等权保留为永远的 benchmark,但它没有使用预测强度、协方差、行业暴露、容量和交易成本。复杂优化器若长期不能成本后胜过等权,应下线复杂优化器,而不是删除等权对照。
2. 不用单均线代表 Alpha 层
单均线可以验证完整管线,也可能在趋势策略中有真实价值,但无法代表跨股票的特征、标签、排序、风险暴露和组合决策。它是测试信号,不是这篇 Baseline 的研究终点。
3. 不把止损叫风险系统
止损发生在价格已经移动以后,而且在停牌、跳空、跌停时未必能成交。它不处理相关性、行业集中、Beta、波动、流动性、容量和不可卖风险。V1 保留损失保护线,但把主要风险控制放在仓位生成以前。
4. 不假设订单瞬间全部成交
真实 API 是异步的,订单可能拒绝、部分成交、撤单失败或回报乱序。只要回测持仓能在一行代码里瞬间跳到目标,执行层就没有达到 60 分。
5. 不只看收益、Sharpe 和最大回撤
相同净值可能来自真正选股、行业押注、不可复制的成交价或数据泄漏。Alpha、风险、成本、执行和运行指标必须同时存在,并能沿 run_id/decision_id/order_id 下钻。
6. 不在 V1 先上 Transformer、GNN 或 RL
原因不是它们永远无效,而是当前主要误差更可能来自 PIT 数据、有效样本、风险暴露、费用和执行。深模型只有在稳定 Baseline 上作为 challenger,以相同信息集、相同验证协议、相同风险成本比较后才有意义。
7. 不追求一个框架包办一切
聚宽最懂当前 A 股研究体验,Qlib 最适合模型 workflow,LEAN 最值得学习架构,QMT 才连接实际券商。让一个框架承担不擅长的全部角色,会把便利变成锁定;稳定数据契约比统一 Logo 更重要。
8. 不用“最新”替代“可验证”
V1 优先成熟的树模型、收缩协方差、凸优化和确定性执行。新方法首先进入离线 challenger;只有它在净收益、稳定性、风险、运维和回滚五方面都证明增量价值,才进入生产。
9. 不用回测收益抵消代码质量,也不用漂亮架构掩盖无效 Alpha
上线采用双门:研究门要求样本外、成本后有稳定证据;工程门要求状态、测试、重放、对账和合规通过。任何一边失败都不能上线。
十六、从 60 到 80:按证据升级,不按功能堆砌
分阶段落地
| 阶段 | 目标 | 完成证据 | 禁止事项 |
|---|---|---|---|
| Phase 0:合同与夹具(1—2 周) | 九种对象、schema、规则表、固定小数据集 | 接口文档;PIT/费用/T+1/部分成交单测 | 先调模型找高收益 |
| Phase 1:研究闭环(3—6 周) | 本地 Qlib + Ridge/LightGBM + 风险/成本/优化 | purged walk-forward 报告;实验可重放;等权/Top-k 对照 | 只保存一条最佳净值 |
| Phase 2:双引擎与模拟(6—12 周) | 本地与聚宽口径对齐,模拟运行 | 差异报告;至少 60 个交易日连续模拟;故障演练 | 发现差异后手工改净值 |
| Phase 3:QMT 影子盘(4—8 周) | 不发真实单,但用实时行情、券商快照和完整状态机 | 至少 20 个交易日;断线/重启/乱序回放;每日零未知账差 | 用模拟回调替代券商验证 |
| Phase 4:小资金 canary | 有人工批准、严格限额的真实成交 | 至少 20 个交易日;真实费用与 TCA;无未解释对账差异 | 初期即满资金、自动放量 |
| Phase 5:受控放量 | 按容量与误差逐级扩大 | 每级预测—实现偏差和回滚审查 | 按回测收益直接决定资金量 |
这些天数是最低工程观察窗,不是统计显著性的保证。跨市场状态的策略有效性仍要靠更长样本与持续实盘证据。
各层 60 → 80 升级表
| 层 | 60 分 Baseline | 到 80 分最有价值的升级 | 何时才值得做 |
|---|---|---|---|
| 数据 | 单主源 PIT + 版本快照 | 第二独立源对账、自动修订差分、字段级 lineage、更多逐笔/公告数据 | 主源错误已成为主要残差 |
| Universe | PIT 中证 500 + 静态容量门 | 资金规模驱动的动态流动性池、多 benchmark、拥挤/退市概率 | CSI500 限制了容量或 Alpha |
| Alpha | LightGBM + Ridge | 稳健 ensemble、预测不确定性、正交新数据、因果/机制验证 | 简单模型已稳定且新数据有独立价值 |
| 风险 | 透明行业风格模型 | 动态相关、流动性/拥挤风险、商业模型交叉验证、模型风险 ensemble | 风险预测误差可被量化定位 |
| 成本 | 代理冲击 + 压力区间 | 用真实成交分层拟合、日内量能预测、多日 liquidation、机会成本模型 | 积累足量不同股票/规模成交 |
| 组合 | 单期凸优化 | 鲁棒/多期优化、参数不确定性、分层风险预算、现金/Beta 联合组合 | 单期决策的短视成本已显著 |
| 执行 | Guarded TWAP/POV | 自适应量能/波动、智能限价、多窗口/多日计划、灾备 broker adapter | TCA 证明执行损失是主要瓶颈 |
| 评价 | 四轨迹 + TCA + MLflow | 自动归因、漂移分型、champion/canary 编排、统计过程控制 | 实验与实盘数量足以自动化 |
| 工程/运维 | 单机模块化 + 三账 | 热备、强权限审计、不可变事件库、异地恢复、多账户隔离 | 资金规模与停机损失值得成本 |
升级原则只有一个:先修复当前最大且可测的误差源。如果净收益主要损失在冲击,先改执行;如果模型在不同行业失效,先修 Alpha/Universe;如果每天对账都不稳,暂停所有模型升级。
十七、最终验收清单
以下项目全部打勾,才可以把 V1 标记为“达到 60 分”;其中 G10 和实盘权限必须由实际券商确认。
数据与研究
- [ ] 历史指数成员、退市股、公司行动和财报公告时点可重放。
- [ ] 原始价/复权因子分离;JoinQuant 与本地价格/收益口径差异有报告。
- [ ] Random CV 已禁用;purge/embargo、walk-forward 和未触碰测试集写入代码。
- [ ] Ridge、等权/Top-k 和 benchmark 全程保留,不只展示 LightGBM 最优结果。
- [ ] 多时期、行业、规模和成本压力下结果无单点依赖。
风险、成本与组合
- [ ] 行业/风格暴露、协方差、特异风险和压力测试都有版本。
- [ ] 费率与券商交割单一致;冲击参数输出 low/base/high。
- [ ] Alpha、风险、成本和换手共同进入优化;所有权重可解释。
- [ ] 停牌、T+1、禁止开仓、现金和 ADV 是真实约束,不是事后修饰。
- [ ] 求解不可行、rounding 和模型缺失均有测试过的降级路径。
执行、账本与运行
- [ ] 分钟回放支持部分成交、残单、撤改、拒单和价格限制。
- [ ] QMT adapter 支持幂等、重启恢复、乱序/重复回调和未知状态处置。
- [ ] 启动前、运行中和日终三次对账;未知差异自动阻断新开仓。
- [ ] 数据陈旧、断线、拒单激增和超限均触发明确 kill switch/runbook。
- [ ] 每个实盘成交可追到
run_id → decision_id → parent_order → child_order → fill。
复现、迁移与合规
- [ ] Git、依赖、配置、数据、模型、规则版本和随机种子全记录。
- [ ] 本地/聚宽双引擎差异在约定容差内,且费用和成交假设同源。
- [ ] 聚宽策略不包含无法移植的核心业务逻辑;QMT callback 不包含模型逻辑。
- [ ] 已完成至少 60 个交易日模拟、20 个交易日 QMT 影子盘和故障演练。
- [ ] 已向国金等实际开户券商确认 QMT 权限、模拟/实盘差异、频率限制和程序化交易报告状态。
十八、现在只需要冻结的五个个人决策
技术栈可以先按本文实现,但以下五项最终来自你的资金目标,不应由框架替你决定:
| 决策 | 本文默认 | 改变它会影响什么 |
|---|---|---|
| benchmark / 标的池 | PIT 中证 500 | Alpha 标签、风险暴露、持仓数与容量 |
| 资金规模与未来放量目标 | 未填;必须输入 | ADV 门、单股上限、执行窗口和数据投入 |
| 风险预算 | 5% 现金缓冲;其余范围用网格 | 跟踪误差、行业偏离、回撤状态和仓位 |
| 调仓节奏 | 周频目标、次日执行 | 标签期限、换手、容量和执行模型 |
| 券商接口事实 | 待实际确认 QMT/MiniQMT | Adapter、回调、频率、报告与上线日程 |
在这些答案出现前,系统仍能完成研究和模拟;但参数必须标记 UNCONFIRMED,不能把通用默认包装成个性化最优值。
十九、最终判断
这套 Baseline 的真正价值不在 LightGBM、CVXPY 或 QMT 任一名词,而在四个不可逆的工程习惯:
- 当时知道的数据与后来修订的数据分开。
- 预测、目标、订单、成交分开。
- Alpha、风险、成本、可交易性在下单前相遇。
- 研究结论、实盘事实和反馈证据可以沿版本与账本闭环。
只要这四点成立,未来把 LightGBM 换成 ensemble、把透明风险模型换成商业模型、把聚宽换成本地引擎、把 QMT 换成另一家券商,都属于可控升级。反过来,如果四点没有成立,再复杂的深度模型或更快的柜台只会让错误更快发生。
所以,个人 A 股系统的第一个“机构级 60 分”不应追求像一个缩小版大机构,而应该成为一个边界清楚、假设可见、失败安全、结果可复核、能够真实迁移的小系统。这足以作为未来 3—5 年的地基。
主要资料
架构与开源系统
- QuantConnect LEAN Algorithm Framework
- LEAN Portfolio Construction 支持模型
- Qlib 论文、Qlib 官方仓库、官方 benchmarks
- Qlib Strategy 文档
- MLflow Tracking 官方文档
模型、风险、组合与执行
- LightGBM 项目与论文入口
- TimeSeriesSplit 官方文档
- Ledoit–Wolf Shrinkage Portfolio Selection
- MSCI Equity Factor Models
- Multi-Period Trading via Convex Optimization
- Optimal Execution of Portfolio Transactions / Almgren–Chriss
- XtQuant 快速开始、XtTrader API、XtData API
- LEAN Live Trading:Trading and Orders
A 股平台、规则与费用
- 聚宽入门指南、JQData 文档
- 证监会《证券市场程序化交易管理规定(试行)》
- 上交所程序化交易实施细则、深交所程序化交易实施细则
- 上交所 2026 年交易规则、深交所 2026 年交易规则
- 财政部证券交易印花税公告、上交所收费指引、深交所收费页
与 OB 现有路线的关系
- 架构入口:quants/foundations/LEAN 60 行量化系统骨架逐行解读:从标的、Alpha 到组合、风控与执行(2026-07-18)
- 开源代码地图:quants/机构级量化系统最小可运行模板选择指南:Top 5 开源仓库与学习路线(2026-07-15)
- 个人能力坐标:quants/foundations/个人量化能力全景图与当前坐标:从现金层、Beta 层、Alpha 层到优秀个人、小团队与幻方级机构(2026-07-17)
- 券商与接口现实:quants/个人量化券商系统选择、问询与开户指南:QMT、PTrade 与极速柜台(2026-07-01)