Skip to content

Commit 9609933

Browse files
authored
Merge pull request #61 from QuantStrategyLab/codex/crypto-lifecycle-gates-20260706
Align crypto strategy lifecycle gates
2 parents 8e8f054 + 91f69a1 commit 9609933

3 files changed

Lines changed: 27 additions & 51 deletions

File tree

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ These profiles depend on artifacts produced by `CryptoLivePoolPipelines` before
3737

3838
Research-only profiles may stay in code for reproducibility and future review, but they should not appear in current configurable live profiles.
3939

40+
| Profile | Name | Notes |
41+
| --- | --- | --- |
42+
| `crypto_btc_dca` | Crypto BTC DCA | Shadow candidate; allowed for monitoring and accumulation review, but still platform gated. |
43+
| `crypto_trend_rotation` | Crypto Trend Rotation | Research-only redesign candidate. |
44+
| `crypto_equity_combo` | Crypto Equity Combo | Research-only orchestrator candidate. |
45+
4046
No direct runtime strategies are exposed from this package.
4147

4248
## How this connects to execution

src/crypto_strategies/catalog.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@
267267
asset_scope="btc_only",
268268
benchmark="BTC",
269269
role="crypto_core_accumulation",
270-
status="runtime_enabled",
270+
status="shadow_candidate",
271271
),
272272
CRYPTO_TREND_ROTATION_PROFILE: StrategyMetadata(
273273
canonical_profile=CRYPTO_TREND_ROTATION_PROFILE,
@@ -279,7 +279,7 @@
279279
asset_scope="liquid_crypto_assets",
280280
benchmark="BTC",
281281
role="crypto_offensive_rotation",
282-
status="runtime_enabled",
282+
status="research_backtest_only",
283283
),
284284
CRYPTO_EQUITY_COMBO_PROFILE: StrategyMetadata(
285285
canonical_profile=CRYPTO_EQUITY_COMBO_PROFILE,
@@ -291,7 +291,7 @@
291291
asset_scope="crypto_equity",
292292
benchmark="BTC",
293293
role="crypto_combined",
294-
status="runtime_enabled",
294+
status="research_backtest_only",
295295
),
296296
}
297297

@@ -309,9 +309,13 @@ def get_runtime_enabled_profiles() -> frozenset[str]:
309309
"""Return the set of strategy profiles allowed to run on this platform.
310310
311311
This defines the rollout allowlist — the upper bound of what profiles
312-
may be enabled. By default all defined profiles are allowed.
312+
may be enabled.
313313
"""
314-
return frozenset(STRATEGY_DEFINITIONS)
314+
return frozenset(
315+
profile
316+
for profile, metadata in STRATEGY_METADATA.items()
317+
if str(metadata.status or "").strip().lower() == "runtime_enabled"
318+
)
315319

316320

317321
def get_strategy_catalog() -> StrategyCatalog:

tests/test_catalog.py

Lines changed: 12 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,21 @@
1-
import unittest
1+
from __future__ import annotations
22

3-
from quant_platform_kit.common.strategies import get_strategy_component_map
4-
from crypto_strategies import get_strategy_definitions
53
from crypto_strategies.catalog import (
6-
CRYPTO_CANONICAL_REQUIRED_INPUTS,
7-
CRYPTO_LEADER_ROTATION_PROFILE,
4+
CRYPTO_BTC_DCA_PROFILE,
5+
CRYPTO_EQUITY_COMBO_PROFILE,
86
CRYPTO_LIVE_POOL_ROTATION_PROFILE,
9-
get_strategy_definition,
7+
CRYPTO_TREND_ROTATION_PROFILE,
8+
get_runtime_enabled_profiles,
109
get_strategy_metadata,
1110
)
12-
from crypto_strategies.runtime_adapters import BINANCE_PLATFORM, get_platform_runtime_adapter
1311

1412

15-
class CatalogTest(unittest.TestCase):
16-
def test_catalog_contains_crypto_live_pool_rotation(self):
17-
catalog = get_strategy_definitions()
18-
self.assertIn(CRYPTO_LIVE_POOL_ROTATION_PROFILE, catalog)
19-
self.assertEqual(catalog[CRYPTO_LIVE_POOL_ROTATION_PROFILE].domain, "crypto")
20-
self.assertEqual(catalog[CRYPTO_LIVE_POOL_ROTATION_PROFILE].supported_platforms, frozenset({"binance"}))
21-
self.assertEqual(catalog[CRYPTO_LIVE_POOL_ROTATION_PROFILE].target_mode, "weight")
22-
self.assertEqual(catalog[CRYPTO_LIVE_POOL_ROTATION_PROFILE].required_inputs, CRYPTO_CANONICAL_REQUIRED_INPUTS)
13+
def test_only_live_pool_rotation_remains_runtime_enabled() -> None:
14+
assert get_runtime_enabled_profiles() == frozenset({CRYPTO_LIVE_POOL_ROTATION_PROFILE})
15+
assert get_strategy_metadata(CRYPTO_LIVE_POOL_ROTATION_PROFILE).status == "runtime_enabled"
2316

24-
def test_known_profile_resolves(self):
25-
definition = get_strategy_definition("crypto_live_pool_rotation")
26-
self.assertEqual(definition.profile, CRYPTO_LIVE_POOL_ROTATION_PROFILE)
27-
component_map = get_strategy_component_map(definition)
28-
core_module = component_map["core"]
29-
self.assertEqual(
30-
core_module.module_path,
31-
"crypto_strategies.strategies.crypto_live_pool_rotation.core",
32-
)
33-
rotation_module = component_map["rotation"]
34-
self.assertEqual(
35-
rotation_module.module_path,
36-
"crypto_strategies.strategies.crypto_live_pool_rotation.rotation",
37-
)
3817

39-
def test_legacy_leader_rotation_profile_resolves_to_live_pool_rotation(self):
40-
definition = get_strategy_definition(CRYPTO_LEADER_ROTATION_PROFILE)
41-
metadata = get_strategy_metadata(CRYPTO_LEADER_ROTATION_PROFILE)
42-
43-
self.assertEqual(definition.profile, CRYPTO_LIVE_POOL_ROTATION_PROFILE)
44-
self.assertEqual(metadata.canonical_profile, CRYPTO_LIVE_POOL_ROTATION_PROFILE)
45-
self.assertIn(CRYPTO_LEADER_ROTATION_PROFILE, metadata.aliases)
46-
47-
def test_runtime_adapter_covers_canonical_inputs(self):
48-
definition = get_strategy_definition(CRYPTO_LIVE_POOL_ROTATION_PROFILE)
49-
adapter = get_platform_runtime_adapter(CRYPTO_LIVE_POOL_ROTATION_PROFILE, platform_id=BINANCE_PLATFORM)
50-
self.assertLessEqual(definition.required_inputs, adapter.available_inputs)
51-
self.assertEqual(adapter.portfolio_input_name, "portfolio_snapshot")
52-
53-
54-
if __name__ == "__main__":
55-
unittest.main()
18+
def test_non_live_crypto_profiles_are_not_runtime_enabled() -> None:
19+
assert get_strategy_metadata(CRYPTO_BTC_DCA_PROFILE).status == "shadow_candidate"
20+
assert get_strategy_metadata(CRYPTO_TREND_ROTATION_PROFILE).status == "research_backtest_only"
21+
assert get_strategy_metadata(CRYPTO_EQUITY_COMBO_PROFILE).status == "research_backtest_only"

0 commit comments

Comments
 (0)