From 2fe1c734f078c9c07dc710ca907a5b003c6afebc Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Thu, 9 Jul 2026 03:45:52 +0800 Subject: [PATCH 1/2] feat(entrypoints): record per-run decisions via PerformanceMonitor Update qpk pin and persist StrategyDecision from entrypoints for roadmap 5a. Co-Authored-By: Claude Co-authored-by: Cursor --- pyproject.toml | 2 +- src/crypto_strategies/entrypoints/__init__.py | 38 ++++++++++++++++--- src/crypto_strategies/entrypoints/_common.py | 29 ++++++++++++++ 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e87ad50..a1c26d9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ description = "Shared crypto strategy catalog and implementations" readme = "README.md" requires-python = ">=3.11" dependencies = [ - "quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@37c81901160c5b31127a27dba1c63944933fb6bf", + "quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@0c69df08144872ccd1d8bf523738e80748d8d664", ] [tool.setuptools] diff --git a/src/crypto_strategies/entrypoints/__init__.py b/src/crypto_strategies/entrypoints/__init__.py index a3c65de..d5e29c0 100644 --- a/src/crypto_strategies/entrypoints/__init__.py +++ b/src/crypto_strategies/entrypoints/__init__.py @@ -18,7 +18,7 @@ crypto_trend_rotation_manifest, ) -from ._common import apply_risk_gate +from ._common import apply_risk_gate, record_strategy_decision """Unified crypto strategy entrypoints built on top of legacy core/rotation modules.""" @@ -261,7 +261,14 @@ def evaluate_crypto_live_pool_rotation(ctx: StrategyContext) -> StrategyDecision risk_flags=risk_flags, diagnostics=diagnostics, ) - return apply_risk_gate(decision) + decision = apply_risk_gate(decision) + record_strategy_decision( + ctx, + decision, + profile_id=crypto_live_pool_rotation_manifest.profile, + domain=crypto_live_pool_rotation_manifest.domain, + ) + return decision crypto_live_pool_rotation_entrypoint = CallableStrategyEntrypoint( @@ -343,7 +350,14 @@ def evaluate_crypto_btc_dca(ctx: StrategyContext) -> StrategyDecision: risk_flags=risk_flags, diagnostics=diagnostics, ) - return apply_risk_gate(decision, max_single_weight=0.50) + decision = apply_risk_gate(decision, max_single_weight=0.50) + record_strategy_decision( + ctx, + decision, + profile_id=crypto_btc_dca_manifest.profile, + domain=crypto_btc_dca_manifest.domain, + ) + return decision crypto_btc_dca_entrypoint = CallableStrategyEntrypoint( @@ -426,7 +440,14 @@ def evaluate_crypto_trend_rotation(ctx: StrategyContext) -> StrategyDecision: risk_flags=risk_flags, diagnostics=diagnostics, ) - return apply_risk_gate(decision, max_single_weight=0.30) + decision = apply_risk_gate(decision, max_single_weight=0.30) + record_strategy_decision( + ctx, + decision, + profile_id=crypto_trend_rotation_manifest.profile, + domain=crypto_trend_rotation_manifest.domain, + ) + return decision crypto_trend_rotation_entrypoint = CallableStrategyEntrypoint( @@ -615,7 +636,14 @@ def evaluate_crypto_equity_combo(ctx: StrategyContext) -> StrategyDecision: risk_flags=risk_flags, diagnostics=diagnostics, ) - return apply_risk_gate(decision, max_single_weight=0.30) + decision = apply_risk_gate(decision, max_single_weight=0.30) + record_strategy_decision( + ctx, + decision, + profile_id=crypto_equity_combo_manifest.profile, + domain=crypto_equity_combo_manifest.domain, + ) + return decision crypto_equity_combo_entrypoint = CallableStrategyEntrypoint( diff --git a/src/crypto_strategies/entrypoints/_common.py b/src/crypto_strategies/entrypoints/_common.py index 4101a85..144f78d 100644 --- a/src/crypto_strategies/entrypoints/_common.py +++ b/src/crypto_strategies/entrypoints/_common.py @@ -3,6 +3,7 @@ import logging from quant_platform_kit.strategy_contracts import PositionTarget, StrategyDecision +from quant_platform_kit.strategy_lifecycle.performance_monitor import PerformanceMonitor logger = logging.getLogger(__name__) @@ -10,6 +11,34 @@ # 风控硬门 — 每个 entrypoint 返回 StrategyDecision 前必须调用 # --------------------------------------------------------------------------- +_performance_monitor: PerformanceMonitor | None = None + + +def record_strategy_decision( + _ctx: object, + decision: StrategyDecision, + *, + profile_id: str, + domain: str, +) -> None: + """Record per-run decision for live monitoring (roadmap 5a). + + Crypto entrypoints don't consistently thread `StrategyContext` typing, so we + accept `ctx` as `object` and only use it for future extension. + """ + global _performance_monitor + try: + if _performance_monitor is None: + _performance_monitor = PerformanceMonitor() + _performance_monitor.record( + profile_id, + decision, + execution_result={}, + domain=domain, + ) + except Exception as exc: # pragma: no cover + logger.warning("PerformanceMonitor.record failed: %s", exc) + def _position_weight(position: PositionTarget) -> float | None: if position.target_weight is not None: From 0b7875b4faff6f2287d3ffb2e2236d5f454fa2d6 Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Thu, 9 Jul 2026 03:50:03 +0800 Subject: [PATCH 2/2] fix(ci): update QPK_HEALTH_COMMIT expectation for PerformanceMonitor record Keep contract governance tests aligned with the QuantPlatformKit commit required by roadmap 5a. Co-Authored-By: Claude Co-authored-by: Cursor --- tests/test_contract_governance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_contract_governance.py b/tests/test_contract_governance.py index 2791f9d..6d354a4 100644 --- a/tests/test_contract_governance.py +++ b/tests/test_contract_governance.py @@ -35,7 +35,7 @@ "binance", "BINANCE_", ) -QPK_HEALTH_COMMIT = "37c81901160c5b31127a27dba1c63944933fb6bf" +QPK_HEALTH_COMMIT = "0c69df08144872ccd1d8bf523738e80748d8d664" QPK_OLD_HEALTHLESS_COMMIT = "86f03fb8e83c0d372f4e1c64cccf3e6da50b8dd4"