Skip to content

Commit e4aa520

Browse files
committed
Register market regime control plugin
1 parent 77d439f commit e4aa520

3 files changed

Lines changed: 170 additions & 0 deletions

File tree

src/quant_platform_kit/common/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
CRISIS_RESPONSE_SHADOW_SUPPORTED_STRATEGIES,
4343
DEFAULT_STRATEGY_PLUGIN_DEFINITIONS,
4444
PLUGIN_CRISIS_RESPONSE_SHADOW,
45+
PLUGIN_MARKET_REGIME_CONTROL,
46+
PLUGIN_MACRO_RISK_GOVERNOR,
4547
PLUGIN_TACO_REBOUND_SHADOW,
4648
PLUGIN_MODE_SHADOW,
4749
STRATEGY_PLUGIN_ALERT_CHANNEL_EMAIL,
@@ -51,6 +53,8 @@
5153
STRATEGY_PLUGIN_ALERT_ACTIONS,
5254
STRATEGY_PLUGIN_NON_ALERT_ROUTES,
5355
SUPPORTED_STRATEGY_PLUGIN_MODES,
56+
MACRO_RISK_GOVERNOR_SUPPORTED_STRATEGIES,
57+
MARKET_REGIME_CONTROL_SUPPORTED_STRATEGIES,
5458
TACO_REBOUND_SHADOW_SUPPORTED_STRATEGIES,
5559
StrategyPluginAlertMessage,
5660
StrategyPluginDefinition,
@@ -81,6 +85,8 @@
8185
"DEFAULT_TERMINAL_FUNDING_BLOCK_SKIP_REASONS",
8286
"DEFAULT_TERMINAL_STRATEGY_RUN_STAGES",
8387
"PLUGIN_CRISIS_RESPONSE_SHADOW",
88+
"PLUGIN_MARKET_REGIME_CONTROL",
89+
"PLUGIN_MACRO_RISK_GOVERNOR",
8490
"PLUGIN_TACO_REBOUND_SHADOW",
8591
"PLUGIN_MODE_SHADOW",
8692
"STAGE_COMPLETED",
@@ -99,6 +105,8 @@
99105
"STRATEGY_PLUGIN_ALERT_ACTIONS",
100106
"STRATEGY_PLUGIN_NON_ALERT_ROUTES",
101107
"SUPPORTED_STRATEGY_PLUGIN_MODES",
108+
"MACRO_RISK_GOVERNOR_SUPPORTED_STRATEGIES",
109+
"MARKET_REGIME_CONTROL_SUPPORTED_STRATEGIES",
102110
"TACO_REBOUND_SHADOW_SUPPORTED_STRATEGIES",
103111
"filter_execution_blocking_skips",
104112
"is_terminal_funding_block",

src/quant_platform_kit/common/strategy_plugins.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
from typing import Any, Callable
1313

1414
PLUGIN_CRISIS_RESPONSE_SHADOW = "crisis_response_shadow"
15+
PLUGIN_MARKET_REGIME_CONTROL = "market_regime_control"
16+
PLUGIN_MACRO_RISK_GOVERNOR = "macro_risk_governor"
1517
PLUGIN_TACO_REBOUND_SHADOW = "taco_rebound_shadow"
1618
PLUGIN_MODE_SHADOW = "shadow"
1719
STRATEGY_PLUGIN_ALERT_CHANNEL_EMAIL = "email"
@@ -29,6 +31,8 @@
2931
}
3032
)
3133
TACO_REBOUND_SHADOW_SUPPORTED_STRATEGIES = frozenset({"tqqq_growth_income"})
34+
MACRO_RISK_GOVERNOR_SUPPORTED_STRATEGIES = frozenset({"tqqq_growth_income"})
35+
MARKET_REGIME_CONTROL_SUPPORTED_STRATEGIES = frozenset({"tqqq_growth_income"})
3236
_DEFAULT_STRATEGY_PLUGIN_ALERT_GUIDANCE: Mapping[tuple[str, str, str], str] = {
3337
(
3438
PLUGIN_CRISIS_RESPONSE_SHADOW,
@@ -46,6 +50,54 @@
4650
"The crisis route was blocked by a guard; review data freshness and context before "
4751
"acting on the signal."
4852
),
53+
(
54+
PLUGIN_MACRO_RISK_GOVERNOR,
55+
"delever",
56+
"delever",
57+
): (
58+
"Deterministic macro risk governor suggests reducing leveraged exposure while preserving "
59+
"unlevered risk exposure when the strategy opts in."
60+
),
61+
(
62+
PLUGIN_MACRO_RISK_GOVERNOR,
63+
"crisis",
64+
"defend",
65+
): (
66+
"Deterministic macro risk governor suggests moving the risk sleeve toward defensive or "
67+
"cash-like exposure until macro stress de-escalates."
68+
),
69+
(
70+
PLUGIN_MARKET_REGIME_CONTROL,
71+
"risk_off",
72+
"defend",
73+
): (
74+
"Unified market regime control blocks opportunity overlays and suggests moving risk exposure "
75+
"toward defensive or cash-like positions until the deterministic arbiter de-escalates."
76+
),
77+
(
78+
PLUGIN_MARKET_REGIME_CONTROL,
79+
"risk_reduced",
80+
"delever",
81+
): (
82+
"Unified market regime control suggests reducing leveraged exposure while preserving only the "
83+
"risk budget allowed by the strategy policy adapter."
84+
),
85+
(
86+
PLUGIN_MARKET_REGIME_CONTROL,
87+
"opportunity_watch",
88+
"notify_manual_review",
89+
): (
90+
"Manual review only: the unified arbiter allows the bounded TACO opportunity context, but it "
91+
"does not authorize broker orders or live allocation mutation."
92+
),
93+
(
94+
PLUGIN_MARKET_REGIME_CONTROL,
95+
"blocked",
96+
"blocked",
97+
): (
98+
"Unified market regime control was blocked by data-quality or freshness guards; review source "
99+
"artifacts before relying on the signal."
100+
),
49101
(
50102
PLUGIN_TACO_REBOUND_SHADOW,
51103
"taco_rebound",
@@ -120,6 +172,28 @@ def supports_strategy(self, strategy: str) -> bool:
120172
STRATEGY_PLUGIN_ALERT_CHANNEL_TELEGRAM,
121173
),
122174
),
175+
PLUGIN_MARKET_REGIME_CONTROL: StrategyPluginDefinition(
176+
plugin=PLUGIN_MARKET_REGIME_CONTROL,
177+
supported_strategies=MARKET_REGIME_CONTROL_SUPPORTED_STRATEGIES,
178+
supported_modes=SUPPORTED_STRATEGY_PLUGIN_MODES,
179+
alert_channels=(
180+
STRATEGY_PLUGIN_ALERT_CHANNEL_EMAIL,
181+
STRATEGY_PLUGIN_ALERT_CHANNEL_SMS,
182+
STRATEGY_PLUGIN_ALERT_CHANNEL_PUSH,
183+
STRATEGY_PLUGIN_ALERT_CHANNEL_TELEGRAM,
184+
),
185+
),
186+
PLUGIN_MACRO_RISK_GOVERNOR: StrategyPluginDefinition(
187+
plugin=PLUGIN_MACRO_RISK_GOVERNOR,
188+
supported_strategies=MACRO_RISK_GOVERNOR_SUPPORTED_STRATEGIES,
189+
supported_modes=SUPPORTED_STRATEGY_PLUGIN_MODES,
190+
alert_channels=(
191+
STRATEGY_PLUGIN_ALERT_CHANNEL_EMAIL,
192+
STRATEGY_PLUGIN_ALERT_CHANNEL_SMS,
193+
STRATEGY_PLUGIN_ALERT_CHANNEL_PUSH,
194+
STRATEGY_PLUGIN_ALERT_CHANNEL_TELEGRAM,
195+
),
196+
),
123197
}
124198

125199

tests/test_strategy_plugins.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@
88
from quant_platform_kit.common.strategy_plugins import (
99
CRISIS_RESPONSE_SHADOW_SUPPORTED_STRATEGIES,
1010
DEFAULT_STRATEGY_PLUGIN_DEFINITIONS,
11+
MACRO_RISK_GOVERNOR_SUPPORTED_STRATEGIES,
1112
PLUGIN_CRISIS_RESPONSE_SHADOW,
13+
PLUGIN_MARKET_REGIME_CONTROL,
14+
PLUGIN_MACRO_RISK_GOVERNOR,
1215
PLUGIN_TACO_REBOUND_SHADOW,
1316
PLUGIN_MODE_SHADOW,
1417
STRATEGY_PLUGIN_ALERT_CHANNEL_EMAIL,
1518
STRATEGY_PLUGIN_ALERT_CHANNEL_PUSH,
1619
STRATEGY_PLUGIN_ALERT_CHANNEL_SMS,
1720
STRATEGY_PLUGIN_ALERT_CHANNEL_TELEGRAM,
21+
MARKET_REGIME_CONTROL_SUPPORTED_STRATEGIES,
1822
TACO_REBOUND_SHADOW_SUPPORTED_STRATEGIES,
1923
StrategyPluginDefinition,
2024
attach_strategy_plugin_metadata,
@@ -145,6 +149,62 @@ def test_default_plugin_definition_limits_taco_rebound_to_tqqq_notifications(sel
145149
mode=PLUGIN_MODE_SHADOW,
146150
)
147151

152+
def test_default_plugin_definition_limits_macro_risk_governor_to_tqqq(self):
153+
definition = DEFAULT_STRATEGY_PLUGIN_DEFINITIONS[PLUGIN_MACRO_RISK_GOVERNOR]
154+
155+
self.assertEqual(definition.supported_strategies, MACRO_RISK_GOVERNOR_SUPPORTED_STRATEGIES)
156+
self.assertEqual(
157+
definition.alert_channels,
158+
(
159+
STRATEGY_PLUGIN_ALERT_CHANNEL_EMAIL,
160+
STRATEGY_PLUGIN_ALERT_CHANNEL_SMS,
161+
STRATEGY_PLUGIN_ALERT_CHANNEL_PUSH,
162+
STRATEGY_PLUGIN_ALERT_CHANNEL_TELEGRAM,
163+
),
164+
)
165+
validate_strategy_plugin_compatibility(
166+
strategy="tqqq_growth_income",
167+
plugin=PLUGIN_MACRO_RISK_GOVERNOR,
168+
mode=PLUGIN_MODE_SHADOW,
169+
)
170+
with self.assertRaisesRegex(
171+
ValueError,
172+
"macro_risk_governor does not support strategy soxl_soxx_trend_income",
173+
):
174+
validate_strategy_plugin_compatibility(
175+
strategy="soxl_soxx_trend_income",
176+
plugin=PLUGIN_MACRO_RISK_GOVERNOR,
177+
mode=PLUGIN_MODE_SHADOW,
178+
)
179+
180+
def test_default_plugin_definition_limits_market_regime_control_to_tqqq(self):
181+
definition = DEFAULT_STRATEGY_PLUGIN_DEFINITIONS[PLUGIN_MARKET_REGIME_CONTROL]
182+
183+
self.assertEqual(definition.supported_strategies, MARKET_REGIME_CONTROL_SUPPORTED_STRATEGIES)
184+
self.assertEqual(
185+
definition.alert_channels,
186+
(
187+
STRATEGY_PLUGIN_ALERT_CHANNEL_EMAIL,
188+
STRATEGY_PLUGIN_ALERT_CHANNEL_SMS,
189+
STRATEGY_PLUGIN_ALERT_CHANNEL_PUSH,
190+
STRATEGY_PLUGIN_ALERT_CHANNEL_TELEGRAM,
191+
),
192+
)
193+
validate_strategy_plugin_compatibility(
194+
strategy="tqqq_growth_income",
195+
plugin=PLUGIN_MARKET_REGIME_CONTROL,
196+
mode=PLUGIN_MODE_SHADOW,
197+
)
198+
with self.assertRaisesRegex(
199+
ValueError,
200+
"market_regime_control does not support strategy soxl_soxx_trend_income",
201+
):
202+
validate_strategy_plugin_compatibility(
203+
strategy="soxl_soxx_trend_income",
204+
plugin=PLUGIN_MARKET_REGIME_CONTROL,
205+
mode=PLUGIN_MODE_SHADOW,
206+
)
207+
148208
def test_parse_strategy_plugin_mounts_rejects_unsupported_crisis_response_strategy(self):
149209
raw = [
150210
{
@@ -174,6 +234,34 @@ def test_parse_strategy_plugin_mounts_accepts_taco_rebound_tqqq_notification(sel
174234
self.assertEqual(mounts[0].strategy, "tqqq_growth_income")
175235
self.assertEqual(mounts[0].plugin, PLUGIN_TACO_REBOUND_SHADOW)
176236

237+
def test_parse_strategy_plugin_mounts_accepts_macro_risk_governor_tqqq(self):
238+
mounts = parse_strategy_plugin_mounts(
239+
[
240+
{
241+
"strategy": "tqqq_growth_income",
242+
"plugin": PLUGIN_MACRO_RISK_GOVERNOR,
243+
"signal_path": "gs://bucket/macro/latest_signal.json",
244+
}
245+
]
246+
)
247+
248+
self.assertEqual(mounts[0].strategy, "tqqq_growth_income")
249+
self.assertEqual(mounts[0].plugin, PLUGIN_MACRO_RISK_GOVERNOR)
250+
251+
def test_parse_strategy_plugin_mounts_accepts_market_regime_control_tqqq(self):
252+
mounts = parse_strategy_plugin_mounts(
253+
[
254+
{
255+
"strategy": "tqqq_growth_income",
256+
"plugin": PLUGIN_MARKET_REGIME_CONTROL,
257+
"signal_path": "gs://bucket/market_regime/latest_signal.json",
258+
}
259+
]
260+
)
261+
262+
self.assertEqual(mounts[0].strategy, "tqqq_growth_income")
263+
self.assertEqual(mounts[0].plugin, PLUGIN_MARKET_REGIME_CONTROL)
264+
177265
def test_plugin_definition_can_extend_future_strategy_support(self):
178266
raw = [
179267
{

0 commit comments

Comments
 (0)