Skip to content

Commit d307ca3

Browse files
Pigbibicodex
andcommitted
feat: gate Firstrade execution by live continuity state
Co-Authored-By: Codex <noreply@openai.com>
1 parent b82f2ac commit d307ca3

4 files changed

Lines changed: 38 additions & 6 deletions

File tree

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ dependencies = [
1818
"pytest",
1919
"pytz",
2020
"requests",
21-
"quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@2d572658df6e1e82ce822e782e4a717beda4cf83",
21+
"quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@d420441d0e96a020e333ec678ee88f5d964bbb43",
2222
"us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@26c9b908c486ca60123414eda42cd509c0f17c62",
2323
]
2424
license = "MIT"
@@ -82,5 +82,5 @@ show_missing = true
8282

8383
[tool.uv]
8484
override-dependencies = [
85-
"quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@2d572658df6e1e82ce822e782e4a717beda4cf83",
85+
"quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@d420441d0e96a020e333ec678ee88f5d964bbb43",
8686
]

runtime_config_support.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
build_runtime_target,
2828
resolve_runtime_target_from_env,
2929
)
30+
from quant_platform_kit.common.live_continuity import runtime_target_permits_standard_execution
3031
from strategy_registry import (
3132
FIRSTRADE_PLATFORM,
3233
resolve_strategy_definition,
@@ -189,7 +190,10 @@ def load_platform_runtime_settings(
189190
tg_token=_get_credential("firstrade-telegram-token", "TELEGRAM_TOKEN"),
190191
tg_chat_id=os.getenv("QSL_GLOBAL_TELEGRAM_CHAT_ID") or os.getenv("GLOBAL_TELEGRAM_CHAT_ID"),
191192
dry_run_only=dry_run_only,
192-
runtime_target_enabled=_runtime_target_enabled_env(),
193+
runtime_target_enabled=(
194+
_runtime_target_enabled_env()
195+
and runtime_target_permits_standard_execution(runtime_target)
196+
),
193197
cash_only_execution=resolve_cash_only_execution_env(
194198
os.environ,
195199
platform_env_prefix="FIRSTRADE",

tests/test_runtime_config_support.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
import json
4+
35
import pytest
46

57
from runtime_config_support import (
@@ -174,6 +176,32 @@ def test_runtime_target_enabled_loads_from_env(monkeypatch):
174176
assert settings.runtime_target_enabled is False
175177

176178

179+
def test_live_continuity_paused_state_disables_standard_execution(monkeypatch):
180+
runtime_target = {
181+
"platform_id": "firstrade",
182+
"strategy_profile": "ibit_smart_dca",
183+
"dry_run_only": False,
184+
"execution_mode": "live",
185+
"live_continuity": {
186+
"state": "PAUSED",
187+
"baseline_kind": "legacy_authorized",
188+
"baseline_id": "ibit-firstrade-lkg-20260830",
189+
"baseline_target_sha256": "a" * 64,
190+
"captured_at": "2026-08-30",
191+
},
192+
}
193+
from quant_platform_kit.common.live_continuity import runtime_target_fingerprint
194+
195+
runtime_target["live_continuity"]["baseline_target_sha256"] = runtime_target_fingerprint(runtime_target)
196+
monkeypatch.setenv("RUNTIME_TARGET_JSON", json.dumps(runtime_target))
197+
monkeypatch.setenv("FIRSTRADE_DRY_RUN_ONLY", "false")
198+
monkeypatch.setenv("RUNTIME_TARGET_ENABLED", "true")
199+
200+
settings = load_platform_runtime_settings(project_id_resolver=lambda: "project-1")
201+
202+
assert settings.runtime_target_enabled is False
203+
204+
177205
def test_invalid_runtime_target_enabled_is_rejected(monkeypatch):
178206
monkeypatch.setenv("RUNTIME_TARGET_JSON", _target_json())
179207
monkeypatch.setenv("RUNTIME_TARGET_ENABLED", "maybe")

uv.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)