Skip to content

第八章:让策略活着:监控、诊断、迭代

第七章你搭好了从回测到实盘的桥梁——订单生成、成交价压力测试、模拟交易、执行报告。策略终于跑起来了。

然后你开始每天看净值。

上个月赚了 3%,开心。这个月亏了 5%,慌了。盯着那条往下走的曲线,你脑子里全是问号——策略是不是坏了?要不要停?要不要改?还是再等等?

别慌。这一章教你三件事:怎么看(监控)、怎么查(诊断)、怎么改(迭代)。

飞轮转回起点了。 这一章你站在飞轮的“归因层”——但和第五章不同,第五章你“看”的是离线的回测;这一章你“看”的是活着的实盘。

本书口号“做要规则、看要指标、还要怀疑你的指标”——做(监控规则)、看(仪表盘指标)、疑(诊断三问),三个动作在这一章被你第二次走了一遍。

路线图

选什么标的(第二章)→ 每个买多少(第三章)→ 什么时候买卖(第四章)→ 怎么验证有效(第五章)→ 如何避免自欺欺人(第六章)→ 如何真正执行(第七章)→ 如何持续改进(第八章本章)

本章从“盯着净值焦虑”的状态出发,用三个步骤建立系统性的迭代能力,三个步骤的问题与方法对照如表 8-1 所示。

表 8-1 第八章三步迭代框架——问题与方法对照

步骤问题方法
第 1 步策略是不是坏了?监控仪表盘——用指标替代焦虑
第 2 步问题出在哪?诊断三问——由外到内定位原因
第 3 步怎么改?假设驱动的对照实验

(操作流程见前言“怎么使用这本书”。)


8.1 策略是不是坏了?

上个月赚了 3%,这个月亏了 5%。你盯着净值曲线,心里发慌。

但“净值在跌”这个信息太粗糙了——就像你身体不舒服,光说“不舒服”没用,得量体温、测血压、做检查。策略也一样,需要一个“仪表盘”,用具体的指标告诉你:现在到底是正常波动,还是真的出了问题。

我们用三个指标构成监控仪表盘,三者覆盖的角度如表 8-2 所示。

表 8-2 监控仪表盘的三个核心指标

指标含义类比
滚动夏普(最近 3 个月)最近 3 个月的风险调整收益体温计——正常在 0 以上,跌破 0 说明在“发烧”
滚动回撤从近期高点到现在跌了多少水位线——持续下降说明“水在退”
对比沪深 300 多赚了多少(你 - 沪深 300)同期你的策略和沪深 300 指数的差额跑步比赛——持续落后说明跑法有问题

动手实验 1:监控仪表盘

这是本章第一份“运营 spec”,和前七章那种“建一个新功能”不同——这里我们要写的是怎么周期性地看一个已经在跑的策略。我们一起把这份 spec 写出来。这次重点看两件新东西:心智切换——上下文段第一句话就要告诉 AI“这不是建造,是体检”;以及周期性运营 spec 的四要素——触发条件 / 频率 / 阈值 / 输出形态全部显式。

起草上下文 + 任务

上下文段开头那句“用具体指标替代焦虑”是整个第八章的总动机。运营章 spec 的上下文不必交代环境怎么搭,要交代学员现在的情绪状态和场景

上下文:学员跑完第七章,策略终于在实盘运行。但上个月赚了 3%,这个月亏了 5%——是正常波动还是策略出了问题?需要一个“仪表盘”,用具体指标替代焦虑。

任务:在 notebook 中跑基准回测后,用 StrategyMonitor 构建监控仪表盘,画三个滚动指标的时间序列图,并自动检测恶化时段。

📌 要点:运营 spec 的上下文要交代“心智切换”。前七章的 spec 是“建一个新功能”,这一章开始是“看一个已有功能的健康状态”。学员如果带着建造者的姿态去做运维,看了 30 个图也不知道在干嘛——上下文一句话点明“用指标替代焦虑”,就是给学员(也给 AI)定调子:这次的产出不是新代码,是健康判断。

起草要求:周期性运营 spec 的四要素

要求段是这份 spec 的主体——重点是把“什么时候触发监控、多久跑一次、什么数值算异常、异常了怎么输出”四件事全部显式写明

要求

  1. 跑基准回测(SimBroker + 风险平价 + 21 天调仓 + 10% 止损),拿到 result_base
  2. StrategyMonitor(result_base, benchmark="510300.SS", roll_window=63) 获取滚动指标
    • roll_window=63 ≈ 3 个月交易日(21 天/月 × 3),太短(<20)每天报警、太长(>120)警报来时已经亏了半年
  3. 画四行子图(figsize 14×16,共享 x 轴):净值曲线 / 滚动夏普(标零线和 1 线)/ 滚动回撤 / 相对沪深300超额收益,红色填充异常区域
  4. 自动检测恶化时段——告警规则显式声明:
    • 触发条件:滚动夏普 < 0 且持续 ≥ 20 个交易日
    • 频率:每月例行检查一次;第 1 步发现恶化时立即触发第 2 步诊断
    • 阈值sharpe_threshold=0.0, min_days=20(在 StrategyMonitor 构造时锁定)
    • 输出形态:遍历 monitor.bad_periods,每段一行打印起止日期、持续天数、平均夏普
  5. 打印结尾过渡句:“2022 年集中出现恶化,原因是什么?”——把读者推向第 2 步

📌 要点:周期性运营 spec 的告警四要素——触发条件 / 频率 / 阈值 / 输出形态——必须全部显式。建造类 spec 的“成功标志”是“代码跑通、图渲染出来”;运营类 spec 的“成功标志”是“在该报警的时候报了警、不该报的时候没报”。任何一个要素藏在 oxq 库默认参数里、没写进 spec,半年后阈值变了你也不知道——这是运营 spec 区别于 q1-q7 建造 spec 的核心方法点。

📌 要点:关键常量旁边要写“为什么是这个数”。roll_window=63 不是随便选的——它是行业惯例(约 3 个月交易日),理由也要进 spec。运营场景里的每一个数字都是阈值,阈值的合理性比数值本身更重要。

起草结果呈现

结果呈现:四行仪表盘图正常渲染 + 恶化时段列表非空(2022 年应有多个时段)+ equitydaily_retresult_basemonitor 变量已定义(后续 spec 接续使用)。

完整 spec 在 specs/spec-01-monitoring.md——复制给 AI,弹窗选「允许」。

AI 助手执行完毕后,你的 notebook 里应该出现了基准回测结果和一张四行的监控仪表盘图。

这个实验做了什么?先用 第四、七章 同款的风险平价策略(沪深300ETF + 纳指100ETF + 黄金ETF,21 天调仓 + 10% 止损)跑一次从 2021 年到现在的完整回测,拿到净值曲线。然后把净值喂给 StrategyMonitor——它就是那个“体检中心”,自动计算三个滚动健康指标(滚动夏普、滚动回撤、相对基准超额收益),并标注出指标持续恶化的时段。

运行结果

先看基准回测:累计收益 86.45%,年化 12.50%,最大回撤 -16.62%,夏普 1.17,共 184 笔交易。

监控仪表盘的整体效果如图 8-1 所示。

监控仪表盘——四个指标同时恶化的时段就是“危险区”

图 8-1 第一行是净值曲线,整体向上但中间有几段明显的下跌。第二行是滚动夏普——红色填充区域就是夏普跌破 0 的时段,说明最近 3 个月策略在亏钱。第三行是回撤,持续加深说明策略在“失血”。第四行是相对沪深300的超额收益,为负说明还不如直接买指数。

仪表盘自动检测到的恶化时段如表 8-3 所示。

表 8-3 监控仪表盘自动检测到的恶化时段

起始日期结束日期持续天数平均夏普
2022-02-072022-04-2958 天-1.78
2022-05-052022-08-1068 天-2.25
2022-08-292022-09-3023 天-1.13
2022-10-102022-12-0139 天-1.02
2023-10-182023-11-1420 天-0.84
2023-12-052024-01-0321 天-0.91

2022 年集中出现了 4 段恶化,最长的一段持续了 68 天,平均夏普 -2.25。

结果解读

仪表盘让你从“盯着净值焦虑”变成“看指标判断”。

滚动夏普跌破 0,说明最近 3 个月策略在亏钱——这是最直接的“发烧”信号。回撤持续加深说明策略在“失血”。相对沪深300的超额收益为负,说明你还不如直接买指数。

三个指标同时恶化的时段就是需要关注的“危险区”。2022 年出现了多段集中恶化——但发现问题不等于知道原因

是执行出了问题?市场变了?还是策略本身有缺陷?


8.2 问题出在哪?

第 1 步告诉你“最近不对劲”——但不对劲有很多种原因。

在开始诊断之前,先认识一个本节的关键概念:

市场状态(regime) ——市场不是一成不变的。有时候波动大、几乎所有资产一起剧烈起伏(“高波动”),有时候很平静(“低波动 / 正常”)。就像天气有晴天和台风天,同一件衣服在不同天气穿感受完全不同。策略也一样——一个在正常市场表现不错的策略,到了高波动状态可能完全失灵。诊断三步里有两步都和它相关——所以我们前置介绍它。

就像身体不舒服,你不会直接吃药。先量体温排除感冒,再查血排除感染,最后做 CT 看看有没有更深的问题。策略诊断也一样,我们由外到内排查三层:

  1. 是执行的问题吗? —— 回测和实盘之间的差距有没有异常放大
  2. 是市场状态(regime)变了吗? —— 市场的波动水平有没有发生大的变化
  3. 是策略本身的设计问题吗? —— 参数在不同时段的表现是否稳定

动手实验 2:诊断三问

我们一起把这份 spec 写出来。这次重点看两件新东西:一份 spec 包多步诊断的取舍——前七章每份 spec 只做一件事,这份一次塞进三步诊断;以及阈值事前锁定——什么样的数字算“通过”、什么样算“失败”,必须在跑诊断之前定好,不能跑完了再看图说话。

起草上下文 + 任务

接续型 spec 链的上下文要写明前置 spec 留下了哪些变量、本份 spec 在叙事里的位置:

上下文:在 q8-iteration.ipynb 中已有第 1 步监控仪表盘和恶化时段检测。第 1 步发现了多段恶化时段(2022 年集中出现),现在需要搞清楚原因。由外到内排查三层:执行 → 市场 → 策略。

任务:完成三步诊断——排查执行落差、检测市场状态变化、检查参数稳定性。这三步是不可拆分的方法论,必须按“由外到内”的顺序执行。

📌 要点:q1-q7 的写法是“一份 spec 一件事”,这份是“一份 spec 三件事”——叙事完整性优先于任务原子性。诊断方法论本身就是一个不可拆分的整体,拆成三份 spec 学员会丢掉“先排外因再查内因”的节奏。但代价是 spec 体积变大,所以必须在任务段第一句就明示“这三步必须按顺序”——给 AI 也给学员定下“这是一个流程,不是三个独立任务”的预期。

起草要求:阈值事前锁定

要求段是这份 spec 的主体——三步诊断每一步都要把“通过 / 失败”的判定阈值事前写明,绝不能“看图说话”:

要求

  1. 诊断 1——执行落差排查

    • 跑“理想回测”(收盘价 + 佣金,无滑点)和“模拟实盘”(次日开盘 + 佣金 + 千分之一滑点)
    • 计算两条净值曲线的滚动执行落差(63 日滚动均值)
    • 判定阈值:落差走势平稳(每 63 日变化标准差 < 0.5%)→ 排除执行问题;若突然放大则结论改为“需进一步检查滑点 / 佣金模型”
    • 把落差放到学员能理解的语境中:N 年赚了 X%,其中 Y% 被执行成本吃掉
  2. 诊断 2——市场状态检测

    • MarketStateDetector(result_base) 检测市场状态
    • 分状态打印策略表现(年化收益、夏普、天数)
    • 判定阈值:高波动状态下夏普 < 0 且与第 1 步恶化时段重叠 ≥ 70% → 结论“市场状态变了,不是策略 bug”
    • 画两行子图:净值曲线 + 高波动红色阴影 / 市场波动率 + 中位数线 + 高波动阈值线
    • detectorhigh_vol_maskmarket_volHIGH_VOL_LINE 变量必须已定义(第 3 步接续使用)
  3. 诊断 3——参数稳定性检查

    • 把数据分成前后两半(按交易日中点切分)
    • 对 5 种调仓频率(10/15/21/42/63 天)分别在两半上跑回测
    • 判定阈值:用 scipy.stats.kendalltau 计算前后两半夏普排序的 tau(Kendall tau 是衡量两组排序一致性的统计量,取值 -1 到 1,越接近 1 说明前后两段的最优参数排序越像);tau ≥ 0.7 → 排序稳定,参数没过拟合;tau < 0.7 → 参数对时段敏感
    • 打印对比表:频率、前半段年化、前半段夏普、后半段年化、后半段夏普

📌 要点:诊断 spec 的核心是“事前锁定阈值”——绝不能“看图说话”。建造类 spec 的失败长什么样很明显(代码报错、图渲染不出来);诊断类 spec 的失败是隐式的——你跑完看到一个图,凭直觉说“看起来没问题”。只要阈值不事前锁定,诊断就退化成 confirmation bias——你想看到什么结论就能从图里读出什么结论。每一步诊断都必须配一个“通过 X、失败 Y”的数字阈值。

📌 要点:spec 不能给 AI“二选一”。如果你写“用 Kendall tau 或简单比较都行”,AI 选哪种你就拿到哪种结果,下次重跑可能换一种实现,结果不可比。spec 是契约不是协商——能确定一种方案就锁死一种,留 AI 自由发挥的余地越小,诊断越可复现。

起草结果呈现

结果呈现:三步诊断各一组图 + 数字结论;detectorhigh_vol_maskmarket_vol 变量已定义供第 3 步使用。

完整 spec 在 specs/spec-02-diagnostics.md——复制给 AI,弹窗选「允许」。

AI 助手执行完毕后,你的 notebook 里应该出现了三步诊断的完整结果。

这个实验做了什么?由外到内排查三层原因:

  • 诊断 1(执行):跑两次回测——一次用“理想条件”(收盘价成交、只有佣金),一次用“模拟实盘”(次日开盘价 + 佣金 + 滑点),对比两条净值曲线的差距是否在正常范围内。
  • 诊断 2(市场):用 MarketStateDetector 自动检测市场的波动率水平,把每一天标记为“高波动”或“正常”,然后分别统计策略在两种状态下的表现。
  • 诊断 3(参数):把整段回测数据按时间中点切成前后两半(前半段大致覆盖 2021-2023 上半年的高波动市场,后半段覆盖 2023 下半年至今的恢复期),在两半上分别测试 5 种调仓频率,看最优参数在不同时段是否稳定。

运行结果

按“由外到内”的顺序看三步诊断的输出。

诊断 1 — 执行落差排查

理想回测收益 92.13%,模拟实盘收益 83.54%,执行落差累计 8.59%,每年约 1.72%。

换个方式理解:策略 5 年累计赚了 92%,其中 8.6% 被佣金、滑点等执行成本吃掉了。相当于每年的执行成本约 1.7%——对于月度调仓的策略来说,这是正常水平。

更重要的是执行落差的走势是平稳的,没有突然放大——说明执行层面没有异常。如果这条线突然变陡(落差加速扩大),才说明执行出了问题。

排除执行问题。

诊断 2 — 市场状态检测

回顾 8.2 节首讲过的市场状态(regime)——这一步我们用 MarketStateDetector 把每一天自动标记为高波动 / 正常 / 低波动,再看策略在不同状态下的表现差异。结果三档分得很开——表 8-4 一目了然。

策略在不同市场状态下的表现差异如表 8-4 所示。

表 8-4 策略在不同市场状态下的表现

市场状态年化收益夏普天数
高波动-1.44%-0.08260 天
正常16.62%1.80940 天
低波动34.72%6.3236 天

策略净值与高波动时段的叠加如图 8-2 所示。

策略净值 + 高波动时段——恶化和高波动高度吻合

图 8-2 的红色阴影区域就是高波动时段。和第 1 步检测到的恶化时段一对比,高度吻合——策略在高波动环境下年化收益 -1.44%,夏普 -0.08,在亏钱。而正常时段年化 16.62%,夏普 1.80,表现优秀。

恶化的原因是市场状态变了,不是策略的 bug。

诊断 3 — 参数稳定性检查

把数据按时间中点切成前后两半,对 5 种调仓频率分别跑回测,结果如表 8-5 所示。

表 8-5 5 种调仓频率在前后两半段的表现

频率前半段年化前半段夏普后半段年化后半段夏普
10 天+3.30%0.40+25.78%2.17
15 天+1.91%0.25+23.76%2.02
21 天+2.18%0.28+23.13%1.89
42 天+2.88%0.37+24.82%1.95
63 天+5.34%0.65+24.56%1.87

不同时段的年化收益差异很大(前半段 2-5%,后半段 23-26%),说明策略在不同市场环境下表现差异大。但参数排序有变化——前半段 63 天最优,后半段 10 天最优。这意味着:策略的框架是对的,但对某些市场状态没有应对方案。

结果解读

三步诊断的结论汇总如表 8-6 所示。

表 8-6 三步诊断的结论汇总

诊断问题结论
执行回测和实盘的差距有没有异常放大?没有。执行落差稳定,排除
市场市场波动水平有没有大的变化?有。恶化时段和高波动高度吻合
策略参数在不同时段是否稳定?排序有变化,但策略框架没问题,对某些市场状态没有应对方案

问题定位清楚了——不是执行的问题,不是参数过拟合,而是策略对高波动的市场状态没有应对方案

把这套诊断流程压成一句以后能脱口而出的口诀——

🔧 归因 SOP 口诀:先排执行落差(外),再查市场状态(中),最后看策略本身(内)。

这个由外到内的顺序不能反过来。先动策略本身,你大概率会“为了一个市场状态变化”而推翻整个框架,下一轮市场恢复正常你又要再推翻一次——这正是缺乏纪律的迭代最常见的死循环。三步走完之后再决定改什么、改哪一层,每一步都有数据支撑。

那怎么改?推翻重来?还是在现有策略上做小步改进?


8.3 怎么改?

诊断结果出来了——执行没问题,是市场状态变了,策略对高波动没有应对。

你可能想直接调参数试试。但改策略不是拍脑袋——你需要像做实验一样:先提出假设和判断标准,再做对照实验,最后看结果确认还是推翻假设。

就像医生看病——不是看到头疼就开止疼药,而是先做检查确认病因,再开药。

每次迭代都走这个闭环:

观察(看到了什么)—— 假设(猜原因)—— 验证标准(怎么判断对错)—— 实验(改一个变量)—— 结论(确认/推翻)

动手实验 3:假设驱动的对照实验

我们一起把这份 spec 写出来。这次重点看两件新东西:让“假设”跟着 Strategy 跑——open-xquant 的 Strategy 类在设计时就内置了 hypothesisobjectives 两个空,创建 Strategy 时填两个空(假设、判定标准),跑出来的 Strategy 自己背着这张假设卡;以及验证标准事前锁定具体数字——绝不写“看情况调整”这种橡皮条款。

起草上下文 + 任务

上下文:在 q8-iteration.ipynb 中已有第 1 步监控 + 第 2 步诊断的完整变量。诊断结论:策略对高波动的市场状态没有应对方案。

任务:完成两轮迭代实验(调仓频率 + 波动率过滤),用 Strategy 的 hypothesis/objectives 字段展示完整的实验工作流,最后用 ExperimentLog 记录迭代历史。

起草要求:假设跟着 strategy 跑 + 验证标准事前锁定

要求段是这份 spec 的灵魂——把“假设 → 验证标准 → 实验 → 结论”的方法论挂到 Strategy 自己身上的两个空(Strategy.hypothesisStrategy.objectives),让 strategy 跑到哪、假设卡跟到哪:

要求

  1. 迭代 1——调仓频率对照实验(注定被推翻的一轮):

    • 创建 Strategy 时填写 hypothesis="缩短调仓频率能改善高波动期表现"
    • 同时填写 objectives={"high_vol_sharpe": "above_baseline", "max_dd_limit": dd_limit}——验证标准事前锁定
    • 对 6 种频率(5/10/15/21/42/63 天)分别跑回测
    • 计算每种频率在高波动时段的夏普(用 high_vol_mask 筛选)
    • 假设验证:对比基准(21 天)和最优频率的高波动夏普,判断假设确认还是推翻
  2. 迭代 2——波动率过滤对照实验(注定被确认的一轮):

    • 创建 Strategy 时填写 hypothesis="高波动时降仓位能显著降低回撤"
    • 验证标准事前锁定:objectives={"dd_improvement": ">=30%", "sharpe": ">=1.0"}
    • VolFilteredOptimizer 包装 RiskParityOptimizer:高波动期权重缩放 0.5
    • 测试 4 种配置:无过滤、阈值 10% / 15% / 20%
    • “最佳配置”选择函数显式锁定best_label = argmax(dd_improvement)——不能让 AI 揣摩“最佳”的含义
    • 假设验证:检查最佳配置是否同时满足两个事前标准
  3. 迭代记录表

    • ExperimentLog(name="第八章迭代实验") 创建记录
    • log.add() 添加两轮迭代,每行字段值字符级显式:name / observation / hypothesis / criteria / result / conclusion / notes
    • log.to_dataframe().to_string(index=False) 打印记录表

📌 要点:让 hypothesis 跟着 strategy 跑——hypothesisobjectives 这两个空是 open-xquant 在 Strategy 类设计时就内置好的。spec 要求“创建 Strategy 时填写”这两个空,意思是把“假设驱动”从写在注释里、口头讲讲的方法论,挂到 Strategy 自己身上——跑出来的 Strategy 对象自带 .hypothesis 标签,ExperimentLog 自动取走填进表格。以前你的假设写在心里、写在备忘录里——现在 Strategy 自己背着这张假设卡。

📌 要点:验证标准必须事前锁定到具体数字。“高波动夏普优于基准”是数字、“回撤改善 ≥ 30% 且夏普 ≥ 1.0”是数字——绝不写“看情况调整”“效果好就采纳”这种橡皮条款。事后改标准就是过拟合——你跑完看到 25% 改善,临时把标准从 30% 改到 20%,那不是验证假设,是在为已有结果找说辞。事前锁定阈值是迭代 spec 区别于“调参 spec”的本质差异。

📌 要点:注意章节的节奏——迭代 1 故意安排成“假设被推翻”,迭代 2 是“假设被确认”。这是教学设计:先让学员体会“推翻不是失败、推翻是省下了实盘的学费”,再示范一个被确认的假设长什么样。spec 也要配合这个节奏——迭代 1 不要写得“温柔一点让它更容易通过”,要让结果如实推翻。

起草结果呈现

结果呈现:两轮指标表 + 净值对比图 + 假设验证结论 + 2 行迭代记录表(iter1 rejected + iter2 confirmed)+ Strategy 的 hypothesis / objectives 字段值在输出中可见。

完整 spec 在 specs/spec-03-iteration.md——复制给 AI,弹窗选「允许」。

AI 助手执行完毕后,你的 notebook 里应该出现了两轮对照实验的完整结果和迭代记录表。

这个实验做了什么?两轮对照实验,每轮都遵循“假设 —— 验证标准 —— 实验 —— 结论”的流程:

  • 迭代 1(调仓频率):假设“缩短调仓频率能改善高波动期表现”。保持策略逻辑不变,只改调仓周期——分别测试 5/10/15/21/42/63 天六种频率,重点比较各频率在高波动时段(第 2 步检测出的那些红色阴影区域)的夏普。
  • 迭代 2(波动率过滤):假设“高波动时降低仓位能显著减少回撤”。保持调仓频率不变,用 VolFilteredOptimizer 包装 RiskParityOptimizer——当市场波动率超过阈值时,自动将权重缩放 0.5(仓位减半)。分别测试无过滤、阈值 10%/15%/20% 四种配置,看回撤改善了多少、付出了多少收益代价。

open-xquant 的 Strategy 支持在创建时填写 hypothesis(假设)和 objectives(验证目标),让“假设驱动”从口号变成 Strategy 自己背着的两个标签。ExperimentLog 则帮你自动记录每次迭代的假设、标准、结果和结论。

运行结果

两轮迭代的产出按“先被推翻、后被确认”的节奏展开。

迭代 1 — 调仓频率

观察:高波动时段策略表现最差。假设:21 天调仓太慢,缩短频率能改善。验证标准:高波动时段夏普优于基准。

6 种调仓频率的全时段与高波动指标对比如表 8-7 所示。

表 8-7 迭代 1——6 种调仓频率的指标对比

频率年化收益最大回撤夏普比率高波动夏普
5 天+13.01%-14.47%1.250.22
10 天+14.55%-12.57%1.390.56
15 天+13.29%-14.14%1.260.09
21 天(基准)+12.50%-16.62%1.17-0.08
42 天+14.09%-15.98%1.290.44
63 天+14.71%-11.49%1.310.84

不同调仓频率的净值曲线对比如图 8-3 所示。

迭代 1:不同调仓频率的净值对比——图例中是高波动时段的夏普

注意看表 8-7 最后一列——“高波动夏普”,这才是我们验证假设的指标。全时段夏普最高的是 10 天(1.39),但那不是我们的验证目标。高波动时段表现最好的是 63 天(0.84)——更长而非更短

假设被推翻。 缩短调仓频率并没有改善高波动期表现。

这告诉我们什么?改“多久做一次决策”没有用——因为每次做的决策(风险平价满仓分配)没变。问题不在于你多久看一次天气预报,而在于看到暴雨预警后有没有带伞。

迭代 2 — 波动率过滤

观察:频率不是关键,真正的问题是高波动时策略依然满仓暴露在风险中。假设:高波动时降仓位,能显著降低回撤。验证标准:回撤改善 ≥ 30%,夏普 ≥ 1.0。

4 种波动率过滤配置的指标对比如表 8-8 所示。

表 8-8 迭代 2——4 种波动率过滤配置的指标对比

配置年化收益最大回撤夏普比率回撤改善
无过滤(基准)+12.50%-16.62%1.17
过滤>10%+6.57%-8.70%1.1847.6%
过滤>15%+10.44%-9.62%1.4342.1%
过滤>20%+12.89%-12.43%1.2825.2%

不同配置的净值曲线对比如图 8-4 所示。

迭代 2:波动率过滤的净值对比——高波动时仓位减半

最佳配置是“过滤>10%”:回撤从 -16.62% 改善到 -8.70%(改善 47.6%),夏普 1.18。两个验证标准都达标。

假设被确认。 波动率过滤有效。

但年化收益从 +12.50% 降到 +6.57%,代价 5.93%。你用 5.9% 的收益换来了 48% 的回撤改善——这就是取舍(trade-off)。没有“最好”的参数,只有“适合你风险承受能力”的选择。

结果解读

两轮迭代的关键认知汇总如表 8-9 所示。

表 8-9 两轮迭代的核心认知

改了什么学到了什么
迭代 1执行参数(多久做一次)问题不在频率——策略对市场状态没有反应
迭代 2策略逻辑(做什么)让策略感知市场状态并调整行为才有效

假设被推翻不是失败——这是最有价值的学习。如果你凭直觉觉得“调快点应该更好”,然后不做验证就上线,可能越改越差。对照实验的意义就在于此:用数据而不是直觉做决策。

“执行参数”和“策略逻辑”是两件事。 调仓频率是“多久行动一次”,但每次行动的内容(满仓风险平价)没变。如果问题出在行动的内容上,改频率没用——你需要改策略的行为本身。


8.4 回头看:你刚才做了什么?

三步实验,回答了同一个核心问题——策略跑起来之后怎么办?

第 1 步:建监控,发现“最近不对劲”(滚动夏普跌破 0)。第 2 步:做诊断,定位“是市场状态变了”(由外到内三层排查)。第 3 步:做迭代,改频率没用(推翻),改逻辑有效(确认)。

从今以后,策略出了问题你都可以套这套 SOP 应对,三步对照清单如表 8-10 所示。

表 8-10 监控/诊断/迭代 SOP 速查

步骤怎么做好的信号坏的信号
监控看滚动夏普、回撤、超额指标波动但整体健康多个指标同时持续恶化
诊断由外到内:执行、市场、策略能定位到具体原因三层都有问题(可能需要重新设计)
迭代假设、验证标准、实验、结论假设被确认或被有价值地推翻没有假设就开始改参数

8.5 本章总结

策略进化路径

第七章把策略推上了实盘,第八章把“上线之后怎么办”补完——三步进化路径如表 8-11 所示。

表 8-11 第八章三步进化路径

步骤做了什么关键发现
第 1 步 监控滚动指标 + 自动标恶化2022 年集中出现 4 段恶化
第 2 步 诊断由外到内三层排查不是 bug,是市场状态变了
第 3 步 迭代两轮假设驱动对照改频率没用,改逻辑才有效

第七章产出“从回测到实盘的完整闭环”,第八章在它之上多走一步——产出“策略迭代的完整方法论”加上“用数据做决策”的认知。

概念速查表

本章涉及的核心概念汇总如表 8-12 所示,方便随时回查。

表 8-12 第八章核心概念速查

概念含义类比
滚动夏普最近一段时间(如 3 个月)的风险调整收益,衡量策略“现在”的健康度体温计——数值正常说明没发烧
市场状态(regime)市场的波动水平和整体环境,不同时期差异很大天气——晴天和台风天出门穿的衣服不一样
假设驱动迭代先提出可验证的猜想和判断标准,再做实验,而不是凭感觉改医生看病——先检查确认病因,再开药
对照实验只改一个变量、其他不变,看效果同一道菜只改盐的量,尝尝区别
执行参数 vs 策略逻辑“多久做一次”和“做什么”是两件事多久看一次天气预报 vs 看到暴雨预警后是否带伞
迭代记录表每次改动的假设、标准、结果、结论,形成可追溯的改进历史病历本——记录每次看病的诊断和治疗

飞轮第一圈完整闭环

到这里,你完成了第一圈完整的飞轮——本章的结论会反过来喂给下一圈飞轮的“候选 → 组合 → 执行”。 候选层(第二章)→ 组合层(第三、四章)→ 执行层(第七章)→ 归因层(第五、六、八章)→ 反哺起点。三字要点(做 / 看 / 疑)也走了完整一遍:做 = 把每一层都写成可重复执行的规则;看 = 用指标判断好坏;疑 = 不止信回测,也质疑实盘的每一段。

下一圈飞轮要让它转得更快——这就是第九章的事。

本章核心认知

走完三步之后,本章最值得带走的九条认知如表 8-13 所示。

表 8-13 第八章核心认知

认知来源
策略亏钱不一定是坏了,可能是正常波动第 1 步
持续监控比偶尔看一眼净值重要得多第 1 步
诊断要由外到内——先排执行,再看市场,最后看策略第 2 步
市场状态会变,策略在不同状态下表现不同是正常的第 2 步
改策略前先定好验证标准,不能事后改规则第 3 步
改“多久行动”和改“怎么行动”是两件事第 3 步 迭代 1
假设被推翻是好事——省下了实盘亏钱的学费第 3 步 迭代 1
让策略感知市场状态并调整行为,才是有效的改进第 3 步 迭代 2
每次改进都是取舍——用收益换安全,或反过来第 3 步 迭代 2

带走的问题

我们已经走完了从选标的(第二章)到持续改进(第八章)的完整闭环。你现在掌握了监控、诊断和迭代的方法论。

但你可能已经感受到:每次迭代都要构造假设、改参数、跑回测、对比指标、记录结论……这个过程不算轻松。

策略不完美没关系,碰到问题也没关系——只要迭代得够快,从错误和失败中学习得够快,你就可以保持进化。迭代速度本身就是竞争力。

有没有办法让这个循环转得更快?—— 第九章

本章所有代码的可运行版本见 notebooks/q8-iteration.ipynb


8.6 拓展阅读

本章正文聚焦“监控 / 诊断 / 迭代”三个策略层面的动作。下面这段是动手之外的“软功”——读完正文后回头看,决定你能不能把这套方法长期跑下去。

迭代自己:耐心 / 纪律 / 记录

前面三步解决的是策略层面的问题,但还有一层问题藏在你自己身上。

耐心(对应第 1 步 监控)。 策略有波动是常态。不要每天盯着净值焦虑——你已经有了监控仪表盘,定期检查就够了。如果你发现自己每小时都在看净值,那不是在监控,是在焦虑。仪表盘的意义不只是发现问题,也是让你在没有问题的时候安心。

纪律(对应第 3 步 验证标准)。 定好了验证标准就不要改。如果实验结果不好就改标准,这和第六章讲的过拟合是一回事——你在“事后”调整规则来让结果看起来好,而不是真的在改进。假设被推翻了?接受它,记录下来,想下一个假设。

记录(对应第 3 步 迭代记录表)。 每次迭代都填迭代记录表。三个月后回头看,你会发现大部分假设都被推翻了——但你从每次推翻中学到的东西比确认更多。这些记录就是你的成长轨迹。

一句话: 策略层面的方法论你已经有了;接下来三年里能不能跑通,取决于你“耐心 / 纪律 / 记录”这三条软纪律守得有多严。这是带得走的“心态地图”。


反馈与读者群

如果你发现本章有错别字、概念不清或实验结果不一致,欢迎 提交 GitHub Issue

课程、正式书和后续更新见 xquant.shop/courses

添加作者微信 xquanter 进入读者群。请备注:XQuant 读者