Skip to content

Commit 9b05f51

Browse files
authored
Use shared strategy plugin alert dispatcher (#84)
1 parent 3d94942 commit 9b05f51

3 files changed

Lines changed: 23 additions & 78 deletions

File tree

main.py

Lines changed: 12 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,10 @@
3131
load_configured_strategy_plugin_signals,
3232
parse_strategy_plugin_mounts,
3333
)
34-
from quant_platform_kit.notifications.strategy_plugin_email import (
35-
StrategyPluginEmailAlertMarkerStore,
36-
build_strategy_plugin_alert_context_label as build_email_alert_context_label,
37-
publish_strategy_plugin_email_alerts,
38-
)
39-
from quant_platform_kit.notifications.strategy_plugin_sms import (
40-
StrategyPluginSmsAlertMarkerStore,
41-
publish_strategy_plugin_sms_alerts,
34+
from quant_platform_kit.notifications.strategy_plugin_alerts import (
35+
StrategyPluginAlertStateSettings,
36+
build_strategy_plugin_alert_context_label as build_alert_context_label,
37+
publish_strategy_plugin_alerts as dispatch_strategy_plugin_alerts,
4238
)
4339
from quant_platform_kit.strategy_contracts import build_strategy_evaluation_inputs
4440
from runtime_logging import build_run_id, emit_runtime_log
@@ -221,24 +217,14 @@ def build_strategy_plugin_alert_messages(signals):
221217
return STRATEGY_ADAPTERS.build_strategy_plugin_alert_messages(signals)
222218

223219

224-
def build_strategy_plugin_alert_store():
225-
return StrategyPluginEmailAlertMarkerStore(
226-
local_dir=os.getenv("STRATEGY_PLUGIN_ALERT_STATE_DIR") or "/tmp/quant_strategy_plugin_alerts",
227-
gcs_prefix_uri=os.getenv("STRATEGY_PLUGIN_ALERT_STATE_GCS_URI") or os.getenv("EXECUTION_REPORT_GCS_URI"),
228-
gcp_project_id=PROJECT_ID,
229-
)
230-
231-
232-
def build_strategy_plugin_sms_alert_store():
233-
return StrategyPluginSmsAlertMarkerStore(
234-
local_dir=os.getenv("STRATEGY_PLUGIN_ALERT_STATE_DIR") or "/tmp/quant_strategy_plugin_alerts",
235-
gcs_prefix_uri=os.getenv("STRATEGY_PLUGIN_ALERT_STATE_GCS_URI") or os.getenv("EXECUTION_REPORT_GCS_URI"),
220+
def build_strategy_plugin_alert_state_settings():
221+
return StrategyPluginAlertStateSettings.from_env(
236222
gcp_project_id=PROJECT_ID,
237223
)
238224

239225

240226
def build_strategy_plugin_alert_context_label() -> str:
241-
return build_email_alert_context_label(
227+
return build_alert_context_label(
242228
platform_id="longbridge",
243229
strategy_profile=STRATEGY_PROFILE,
244230
account_scope=ACCOUNT_REGION,
@@ -247,39 +233,19 @@ def build_strategy_plugin_alert_context_label() -> str:
247233
)
248234

249235

250-
def attach_strategy_plugin_alert_email_result(report, result) -> None:
251-
report.setdefault("summary", {})["strategy_plugin_alert_email_sent_count"] = result.sent_count
252-
report.setdefault("diagnostics", {}).update(result.to_report_fields())
253-
254-
255-
def attach_strategy_plugin_alert_sms_result(report, result) -> None:
256-
report.setdefault("summary", {})["strategy_plugin_alert_sms_sent_count"] = result.sent_count
257-
report.setdefault("diagnostics", {}).update(result.to_report_fields())
258-
259-
260236
def publish_strategy_plugin_alerts(signals, *, report=None):
261-
email_result = publish_strategy_plugin_email_alerts(
262-
signals,
263-
email_settings=RUNTIME_SETTINGS,
264-
translator=t,
265-
strategy_label=STRATEGY_PROFILE,
266-
context_label=build_strategy_plugin_alert_context_label(),
267-
alert_store=build_strategy_plugin_alert_store(),
268-
log_message=print,
269-
)
270-
sms_result = publish_strategy_plugin_sms_alerts(
237+
result = dispatch_strategy_plugin_alerts(
271238
signals,
272-
sms_settings=RUNTIME_SETTINGS,
239+
notification_settings=RUNTIME_SETTINGS,
273240
translator=t,
274241
strategy_label=STRATEGY_PROFILE,
275242
context_label=build_strategy_plugin_alert_context_label(),
276-
alert_store=build_strategy_plugin_sms_alert_store(),
243+
state_settings=build_strategy_plugin_alert_state_settings(),
277244
log_message=print,
278245
)
279246
if report is not None:
280-
attach_strategy_plugin_alert_email_result(report, email_result)
281-
attach_strategy_plugin_alert_sms_result(report, sms_result)
282-
return email_result
247+
result.attach_to_report(report)
248+
return result
283249

284250

285251
def run_strategy(*, force_run: bool = False, validation_only: bool = False, validation_label: str = "backfill"):

requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
flask
22
gunicorn
3-
quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@d43800180aae1c7fe7051496a6af5d76f2c65879
4-
us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@9661d8bb74e33466fa0ec1efef168b1d1bae8875
3+
quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@532346b6e22d9f9c0a25c5e859f29084d7b27f6c
4+
us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@7ccc46038e6f0fe84a6910a6fa0515252bf15b79
55
pandas
66
requests
77
pytz

tests/test_request_handling.py

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -423,41 +423,20 @@ def build_rebalance_config(self, *, strategy_plugin_signals=()):
423423
module.is_market_open_now = lambda: True
424424
module.run_rebalance_cycle = lambda **_kwargs: None
425425

426-
def fake_email_publish(signals, **kwargs):
427-
observed["email_alerts"].append((tuple(signals), kwargs))
428-
return types.SimpleNamespace(
429-
sent_count=1,
430-
to_report_fields=lambda: {
431-
"strategy_plugin_alert_email_attempted_count": 1,
432-
"strategy_plugin_alert_email_sent_count": 1,
433-
"strategy_plugin_alert_email_skipped_count": 0,
434-
"strategy_plugin_alert_email_failed_count": 0,
435-
"strategy_plugin_alert_email_deliveries": [],
436-
},
437-
)
426+
observed["alerts"] = []
438427

439-
def fake_sms_publish(signals, **kwargs):
440-
observed["sms_alerts"].append((tuple(signals), kwargs))
441-
return types.SimpleNamespace(
442-
sent_count=1,
443-
to_report_fields=lambda: {
444-
"strategy_plugin_alert_sms_attempted_count": 1,
445-
"strategy_plugin_alert_sms_sent_count": 1,
446-
"strategy_plugin_alert_sms_skipped_count": 0,
447-
"strategy_plugin_alert_sms_failed_count": 0,
448-
"strategy_plugin_alert_sms_deliveries": [],
449-
},
450-
)
428+
def fake_dispatch(signals, **kwargs):
429+
observed["alerts"].append((tuple(signals), kwargs))
430+
return types.SimpleNamespace(attach_to_report=lambda _report: None)
451431

452-
module.publish_strategy_plugin_email_alerts = fake_email_publish
453-
module.publish_strategy_plugin_sms_alerts = fake_sms_publish
432+
module.dispatch_strategy_plugin_alerts = fake_dispatch
454433

455434
module.run_strategy()
456435

457-
self.assertEqual(observed["email_alerts"][0][0], (signal,))
458-
self.assertEqual(observed["sms_alerts"][0][0], (signal,))
459-
self.assertIn("longbridge", observed["email_alerts"][0][1]["context_label"])
460-
self.assertIn("longbridge", observed["sms_alerts"][0][1]["context_label"])
436+
self.assertEqual(observed["alerts"][0][0], (signal,))
437+
self.assertIn("longbridge", observed["alerts"][0][1]["context_label"])
438+
self.assertIs(observed["alerts"][0][1]["notification_settings"], module.RUNTIME_SETTINGS)
439+
self.assertIsNotNone(observed["alerts"][0][1]["state_settings"])
461440

462441
def test_run_strategy_force_runs_when_market_closed(self):
463442
module = load_module()

0 commit comments

Comments
 (0)