diff --git a/application/rebalance_service.py b/application/rebalance_service.py index f76142a..8f8c8d7 100644 --- a/application/rebalance_service.py +++ b/application/rebalance_service.py @@ -240,6 +240,14 @@ def publish_log(text: str) -> None: return True +def _should_publish_cycle_notification(result: Mapping[str, Any]) -> bool: + if result.get("submitted_orders"): + return True + if result.get("error") or result.get("ok") is False: + return True + return False + + def load_strategy_plugin_signals( raw_mounts, *, @@ -705,7 +713,7 @@ def log_message(message: str) -> None: except Exception as exc: result["strategy_run_persisted"] = False result["strategy_run_persistence_error"] = f"{type(exc).__name__}: {exc}" - if send_cycle_notification: + if send_cycle_notification and _should_publish_cycle_notification(result): try: result["notification_sent"] = _publish_cycle_notification( result, @@ -715,6 +723,10 @@ def log_message(message: str) -> None: except Exception as exc: result["notification_sent"] = False result["notification_error"] = f"{type(exc).__name__}: {exc}" + elif send_cycle_notification: + result["notification_sent"] = False + result["notification_suppressed"] = True + result["notification_suppressed_reason"] = "no_trade_or_error" else: result["notification_sent"] = False result["notification_suppressed"] = True diff --git a/constraints.txt b/constraints.txt index 5fcff72..fefe067 100644 --- a/constraints.txt +++ b/constraints.txt @@ -3,7 +3,7 @@ # Generated: 2026-07-01 # Auto-updated by update-qpk-pin.yml on every push to QPK main. -quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@b0eacd2fe4884f7f2447b704a232e9a121f396c4 +quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@b9a7df85cfc848cebcc3aa6e1d77ec34ca7611ab us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@6568c315ce3be6f7ae5b799374cf7fb44232c170 hk-equity-strategies @ git+https://github.com/QuantStrategyLab/HkEquityStrategies.git@e9e3058c1eaf3f43b25d50df5eb14442816e568e cn-equity-strategies @ git+https://github.com/QuantStrategyLab/CnEquityStrategies.git@f6c735c33047d7613a23d5df018ed32f394e6001 diff --git a/requirements.txt b/requirements.txt index 08d3957..50e487a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,5 +7,5 @@ pandas_market_calendars pytest pytz requests -quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@b0eacd2fe4884f7f2447b704a232e9a121f396c4 +quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@b9a7df85cfc848cebcc3aa6e1d77ec34ca7611ab us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@6568c315ce3be6f7ae5b799374cf7fb44232c170 diff --git a/tests/test_rebalance_service.py b/tests/test_rebalance_service.py index 6d4a145..668a184 100644 --- a/tests/test_rebalance_service.py +++ b/tests/test_rebalance_service.py @@ -294,6 +294,8 @@ def evaluate(self, **inputs): def test_run_strategy_cycle_no_executes_weight_targets_when_total_equity_zero(monkeypatch): + messages = [] + class ZeroEquityClient(FakeFirstradeClient): def get_balances(self, _account): return {"total_value": "$0.00", "cash_balance": "$0.00", "buying_power": "$0.00"} @@ -326,6 +328,7 @@ def evaluate(self, **inputs): ), credentials=FirstradeCredentials(username="user", password="pass"), client_factory=ZeroEquityClient, + notification_sender=messages.append, env_reader=lambda _name, default=None: default, ) @@ -336,6 +339,10 @@ def evaluate(self, **inputs): assert result["skipped_orders"] == [ {"symbol": "AAA", "reason": "below_trade_threshold", "delta_value": 0.0} ] + assert result["notification_sent"] is False + assert result["notification_suppressed"] is True + assert result["notification_suppressed_reason"] == "no_trade_or_error" + assert messages == [] def test_run_strategy_cycle_loads_strategy_plugin_report_and_sends_email(