Skip to content

Commit bbcdcca

Browse files
Pigbibicodex
andcommitted
fix(ci): align drift baseline store and workflow pin
Co-Authored-By: Codex <noreply@openai.com>
1 parent c4163db commit bbcdcca

4 files changed

Lines changed: 44 additions & 19 deletions

File tree

.github/workflows/drift-check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ permissions:
1414

1515
jobs:
1616
drift:
17-
uses: QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@6ad21ccbaf176f9526a417f7df0716ba27eb43b6
17+
uses: QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@335c7a22bc3f570bd5705427ccc40172eda6b289
1818
with:
1919
strategy_domain: crypto
2020
caller_event_name: ${{ github.event_name }}

scripts/run_walk_forward_backtest.py

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
import argparse
77
import copy
8-
import json
98
import hashlib
9+
import json
10+
import re
1011
from datetime import date
1112
from pathlib import Path
1213
from typing import Any
@@ -52,6 +53,26 @@ def _baseline_param_set_id(profile: str, params: dict[str, Any]) -> str:
5253
return f"{profile}_baseline_{fingerprint}"
5354

5455

56+
def _current_qpk_pin() -> str:
57+
text = (Path(__file__).resolve().parents[1] / "qsl.toml").read_text(encoding="utf-8")
58+
match = re.search(r"QuantPlatformKit\.git@([0-9a-f]{40})", text)
59+
return match.group(1) if match else "unknown"
60+
61+
62+
def _baseline_identity_params(
63+
params: dict[str, Any],
64+
*,
65+
synthetic_days: int,
66+
baseline_result: Any,
67+
) -> dict[str, Any]:
68+
identity = copy.deepcopy(params)
69+
identity["_baseline_start_date"] = baseline_result.start_date.isoformat() if baseline_result.start_date else None
70+
identity["_baseline_end_date"] = baseline_result.end_date.isoformat() if baseline_result.end_date else None
71+
identity["_qpk_pin"] = _current_qpk_pin()
72+
identity["_synthetic_days"] = synthetic_days
73+
return identity
74+
75+
5576
def _build_runner(*, profile: str, synthetic_days: int, panel: Any = None, market_history: Any = None):
5677
return build_backtest_runner(
5778
profile,
@@ -77,37 +98,38 @@ def run_walk_forward(
7798
raise ValueError(f"unsupported profile={profile!r}; supported={sorted(SUPPORTED_PROFILES)}")
7899

79100
params = dict(PROFILE_DEFAULTS.get(profile, {"min_history_days": DEFAULT_MIN_HISTORY_DAYS}))
80-
store = PerformanceStore(local_root=store_root or Path("/tmp/crypto_wf_store"))
101+
store = PerformanceStore(local_root=store_root) if store_root is not None else PerformanceStore.from_env()
81102
orchestrator = BacktestOrchestrator(store=store)
82103

83104
baseline_params = copy.deepcopy(params)
84-
baseline_store_params = copy.deepcopy(baseline_params)
85-
baseline_runner = _build_runner(
105+
runner = _build_runner(
86106
profile=profile,
87107
panel=panel,
88108
market_history=market_history,
89109
synthetic_days=synthetic_days,
90110
)
91-
baseline_raw = baseline_runner.run(
111+
orchestrator.register_runner("crypto", runner)
112+
baseline_probe = orchestrator.run(
92113
profile,
93-
baseline_params,
114+
domain="crypto",
115+
params=copy.deepcopy(baseline_params),
116+
param_set_id="__discarded__",
94117
start_date=None,
95118
end_date=None,
96119
)
97-
baseline = orchestrator.persist_result(
98-
baseline_raw,
99-
strategy_profile=profile,
120+
baseline_store_params = _baseline_identity_params(
121+
baseline_params,
122+
synthetic_days=synthetic_days,
123+
baseline_result=baseline_probe,
124+
)
125+
baseline = orchestrator.run(
126+
profile,
100127
domain="crypto",
101128
params=baseline_store_params,
102129
param_set_id=_baseline_param_set_id(profile, baseline_store_params),
130+
start_date=None,
131+
end_date=None,
103132
)
104-
runner = _build_runner(
105-
profile=profile,
106-
panel=panel,
107-
market_history=market_history,
108-
synthetic_days=synthetic_days,
109-
)
110-
orchestrator.register_runner("crypto", runner)
111133
wf_params = copy.deepcopy(params)
112134
wf_results = orchestrator.walk_forward(
113135
profile,

tests/test_drift_workflow_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
def test_drift_workflow_wires_pipeline_repo_and_lifecycle_env() -> None:
55
workflow = (Path(__file__).resolve().parents[1] / ".github" / "workflows" / "drift-check.yml").read_text(encoding="utf-8")
66

7-
assert "uses: QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@6ad21ccbaf176f9526a417f7df0716ba27eb43b6" in workflow
7+
assert "uses: QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@335c7a22bc3f570bd5705427ccc40172eda6b289" in workflow
88
assert "strategy_domain: crypto" in workflow
99
assert "caller_event_name: ${{ github.event_name }}" in workflow
1010
assert "caller_pr_head_repository: ${{ github.event.pull_request.head.repo.full_name || '' }}" in workflow

tests/test_run_walk_forward_backtest.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,8 @@ def test_run_walk_forward_persists_lifecycle_baseline(tmp_path: Path) -> None:
2828
]
2929

3030
assert payload["baseline"]["sharpe_ratio"] is not None
31-
assert any("_baseline_" in record["param_set_id"] for record in records)
31+
baseline_records = [record for record in records if "_baseline_" in record["param_set_id"]]
32+
assert baseline_records
33+
assert baseline_records[-1]["params"]["_qpk_pin"]
34+
assert baseline_records[-1]["params"]["_baseline_end_date"]
3235
assert any("_wf" in record["param_set_id"] for record in records)

0 commit comments

Comments
 (0)