From 9fd386ebf8f0b8fd54a57e8b249c7b13b385550e Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Thu, 27 Aug 2026 20:22:56 +0800 Subject: [PATCH] feat(risk): represent split-adjusted price basis Co-Authored-By: Codex --- docs/qsl_long_horizon_risk_observation_v2.zh-CN.md | 2 +- python/scripts/long_horizon_risk_composer_v2.py | 4 ++++ python/tests/test_long_horizon_risk_observation_v2.py | 11 +++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/qsl_long_horizon_risk_observation_v2.zh-CN.md b/docs/qsl_long_horizon_risk_observation_v2.zh-CN.md index e8d9319..2abe257 100644 --- a/docs/qsl_long_horizon_risk_observation_v2.zh-CN.md +++ b/docs/qsl_long_horizon_risk_observation_v2.zh-CN.md @@ -72,7 +72,7 @@ v2 复用已验证的 v1 计算器,**仅**在以下范围输出 `ADVISORY_RECO | 多策略组合 | `PORTFOLIO_COMPOSER_REQUIRED` | 必须重算相关性、边际风险贡献和组合净收益 | | DCA 或外部现金流 | `CASHFLOW_COMPOSER_REQUIRED` | 必须使用现金流匹配、时间一致的路径 | | 混合、现金或绝对收益基准 | `BENCHMARK_POLICY_COMPOSER_REQUIRED` | 不能伪装为权益无杠杆基准 | -| 非净成本总收益基准口径 | `BENCHMARK_RETURN_BASIS_COMPOSER_REQUIRED` | 当前回撤比较不具可比性 | +| 非净成本总收益基准口径(包括 `SPLIT_ADJUSTED_PRICE_RETURN`) | `BENCHMARK_RETURN_BASIS_COMPOSER_REQUIRED` | 当前回撤比较不具可比性;拆分复权收盘价不得伪称总收益 | `PARKED` 没有尺度、最大回撤或前沿;它不是失败后的默认继续运行,更不能触发实盘动作。 diff --git a/python/scripts/long_horizon_risk_composer_v2.py b/python/scripts/long_horizon_risk_composer_v2.py index 09fc622..2a6ab6a 100644 --- a/python/scripts/long_horizon_risk_composer_v2.py +++ b/python/scripts/long_horizon_risk_composer_v2.py @@ -105,6 +105,10 @@ _RETURN_BASES = { "TOTAL_RETURN_NET_OF_COST", "TIME_WEIGHTED_TOTAL_RETURN", + # Some verified research lanes intentionally retain only split-adjusted + # closes. They must be representable without being mislabeled as a total + # return series; the generic v1-compatible composer still parks them. + "SPLIT_ADJUSTED_PRICE_RETURN", "CASHFLOW_MATCHED_RETURN", } _RISK_FACTORS = { diff --git a/python/tests/test_long_horizon_risk_observation_v2.py b/python/tests/test_long_horizon_risk_observation_v2.py index cc89081..ce420a9 100644 --- a/python/tests/test_long_horizon_risk_observation_v2.py +++ b/python/tests/test_long_horizon_risk_observation_v2.py @@ -168,6 +168,17 @@ def test_cashflow_matched_strategies_cannot_be_coerced_to_time_weighted_linear_m with self.assertRaisesRegex(composer.LongHorizonRiskComposerError, "requires CASHFLOW_MATCHED_RETURN"): composer_v2.validate_long_horizon_risk_observation_v2(invalid) + def test_split_adjusted_price_benchmark_is_represented_but_not_mislabeled_as_total_return(self): + observation = self._observation() + observation["benchmark_policy"]["return_basis"] = "SPLIT_ADJUSTED_PRICE_RETURN" + observation["observation_sha256"] = composer_v2.calculate_risk_observation_v2_sha256(observation) + + recommendation = composer_v2.compose_long_horizon_risk_recommendation_v2(observation, self._profile()) + + self.assertEqual(recommendation["status"], "PARKED") + self.assertEqual(recommendation["reason_codes"], ["BENCHMARK_RETURN_BASIS_COMPOSER_REQUIRED"]) + self.assertIsNone(recommendation["recommended_scale_bps"]) + if __name__ == "__main__": unittest.main()