77 CRISIS_RESPONSE_SHADOW_SUPPORTED_STRATEGIES ,
88 DEFAULT_STRATEGY_PLUGIN_DEFINITIONS ,
99 PLUGIN_CRISIS_RESPONSE_SHADOW ,
10+ PLUGIN_TACO_REBOUND_SHADOW ,
1011 PLUGIN_MODE_SHADOW ,
1112 STRATEGY_PLUGIN_ALERT_CHANNEL_EMAIL ,
1213 STRATEGY_PLUGIN_ALERT_CHANNEL_PUSH ,
1314 STRATEGY_PLUGIN_ALERT_CHANNEL_SMS ,
1415 STRATEGY_PLUGIN_ALERT_CHANNEL_TELEGRAM ,
16+ TACO_REBOUND_SHADOW_SUPPORTED_STRATEGIES ,
1517 StrategyPluginDefinition ,
1618 build_strategy_plugin_alert_messages ,
1719 build_strategy_plugin_notification_lines ,
@@ -111,6 +113,34 @@ def test_default_plugin_definition_limits_crisis_response_to_supported_strategie
111113 mode = PLUGIN_MODE_SHADOW ,
112114 )
113115
116+ def test_default_plugin_definition_limits_taco_rebound_to_tqqq_notifications (self ):
117+ definition = DEFAULT_STRATEGY_PLUGIN_DEFINITIONS [PLUGIN_TACO_REBOUND_SHADOW ]
118+
119+ self .assertEqual (definition .supported_strategies , TACO_REBOUND_SHADOW_SUPPORTED_STRATEGIES )
120+ self .assertEqual (
121+ definition .alert_channels ,
122+ (
123+ STRATEGY_PLUGIN_ALERT_CHANNEL_EMAIL ,
124+ STRATEGY_PLUGIN_ALERT_CHANNEL_SMS ,
125+ STRATEGY_PLUGIN_ALERT_CHANNEL_PUSH ,
126+ STRATEGY_PLUGIN_ALERT_CHANNEL_TELEGRAM ,
127+ ),
128+ )
129+ validate_strategy_plugin_compatibility (
130+ strategy = "tqqq_growth_income" ,
131+ plugin = PLUGIN_TACO_REBOUND_SHADOW ,
132+ mode = PLUGIN_MODE_SHADOW ,
133+ )
134+ with self .assertRaisesRegex (
135+ ValueError ,
136+ "taco_rebound_shadow does not support strategy soxl_soxx_trend_income" ,
137+ ):
138+ validate_strategy_plugin_compatibility (
139+ strategy = "soxl_soxx_trend_income" ,
140+ plugin = PLUGIN_TACO_REBOUND_SHADOW ,
141+ mode = PLUGIN_MODE_SHADOW ,
142+ )
143+
114144 def test_parse_strategy_plugin_mounts_rejects_unsupported_crisis_response_strategy (self ):
115145 raw = [
116146 {
@@ -126,6 +156,20 @@ def test_parse_strategy_plugin_mounts_rejects_unsupported_crisis_response_strate
126156 ):
127157 parse_strategy_plugin_mounts (raw )
128158
159+ def test_parse_strategy_plugin_mounts_accepts_taco_rebound_tqqq_notification (self ):
160+ mounts = parse_strategy_plugin_mounts (
161+ [
162+ {
163+ "strategy" : "tqqq_growth_income" ,
164+ "plugin" : PLUGIN_TACO_REBOUND_SHADOW ,
165+ "signal_path" : "gs://bucket/taco/latest_signal.json" ,
166+ }
167+ ]
168+ )
169+
170+ self .assertEqual (mounts [0 ].strategy , "tqqq_growth_income" )
171+ self .assertEqual (mounts [0 ].plugin , PLUGIN_TACO_REBOUND_SHADOW )
172+
129173 def test_plugin_definition_can_extend_future_strategy_support (self ):
130174 raw = [
131175 {
@@ -315,6 +359,26 @@ def test_strategy_plugin_true_crisis_builds_generic_alert_message(self):
315359 self .assertNotIn ("source=" , alerts [0 ].body )
316360 self .assertTrue (alerts [0 ].metadata ["would_trade_if_enabled" ])
317361
362+ def test_taco_rebound_notification_alerts_without_trade_flag (self ):
363+ signal = validate_strategy_plugin_signal_payload (
364+ {
365+ ** _signal_payload (plugin = PLUGIN_TACO_REBOUND_SHADOW ),
366+ "schema_version" : "taco_rebound_shadow.v2" ,
367+ "canonical_route" : "taco_rebound" ,
368+ "suggested_action" : "notify_manual_review" ,
369+ "would_trade_if_enabled" : False ,
370+ "manual_review_required" : True ,
371+ },
372+ source_uri = "gs://bucket/taco/latest_signal.json" ,
373+ )
374+
375+ self .assertTrue (should_alert_strategy_plugin_signal (signal ))
376+ alerts = build_strategy_plugin_alert_messages ([signal ], strategy_label = "TQQQ Growth Income" )
377+
378+ self .assertEqual (len (alerts ), 1 )
379+ self .assertIn ("taco_rebound_shadow" , alerts [0 ].subject )
380+ self .assertFalse (alerts [0 ].metadata ["would_trade_if_enabled" ])
381+
318382
319383if __name__ == "__main__" :
320384 unittest .main ()
0 commit comments