From c12d08ce3cb9ecc3e49860cf40be94ffd2ac2ea1 Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Sat, 27 Jun 2026 05:19:30 +0800 Subject: [PATCH] Show full account in notifications and sync cash-only execution tests. Display full Firstrade account IDs in user-facing probe/rebalance messages and align test expectations with cash-only equity execution defaults from main. Co-authored-by: Cursor --- application/rebalance_service.py | 4 ++-- application/session_check_service.py | 6 +++--- tests/test_decision_mapper.py | 4 ++-- tests/test_execution_service.py | 2 +- tests/test_notifications_telegram.py | 2 +- tests/test_rebalance_service.py | 3 ++- tests/test_runtime_broker_adapters.py | 4 ++-- tests/test_session_check_service.py | 10 +++++----- 8 files changed, 18 insertions(+), 17 deletions(-) diff --git a/application/rebalance_service.py b/application/rebalance_service.py index a242811..10761c3 100644 --- a/application/rebalance_service.py +++ b/application/rebalance_service.py @@ -492,7 +492,7 @@ def log_message(message: str) -> None: result = { "ok": True, "api_kind": "unofficial-reverse-engineered", - "account": masked_account, + "account": account, "strategy_profile": strategy_runtime.profile, "strategy_display_name": strategy_runtime.display_name, "dry_run_only": settings.dry_run_only, @@ -594,7 +594,7 @@ def log_message(message: str) -> None: result = { "ok": not execution_blocked, "api_kind": "unofficial-reverse-engineered", - "account": mask_account_id(account), + "account": account, "strategy_profile": strategy_runtime.profile, "strategy_display_name": strategy_runtime.display_name, "dry_run_only": settings.dry_run_only, diff --git a/application/session_check_service.py b/application/session_check_service.py index 5572d6b..1696b36 100644 --- a/application/session_check_service.py +++ b/application/session_check_service.py @@ -291,7 +291,7 @@ def persist_session_check_maintenance( as_of = now or _utcnow() payload = { "checked_at": as_of.isoformat(), - "account": mask_account_id(account), + "account": account, "session_reused": session_reused, "strategy_profile": decision.strategy_profile, "strategy_cadence": decision.strategy_cadence, @@ -332,7 +332,7 @@ def build_account_funds_snapshot( as_of = now or _utcnow() snapshot: dict[str, Any] = { "as_of": as_of.isoformat(), - "account": mask_account_id(account), + "account": account, "session_reused": session_reused, "account_summaries": account_summaries, "balance_metrics": selected_numeric_metrics(balances, BALANCE_KEYWORDS), @@ -445,7 +445,7 @@ def run_session_check( result: dict[str, Any] = { "ok": True, "api_kind": "unofficial-reverse-engineered", - "account": mask_account_id(account), + "account": account, "session_reused": session_reused, "funds_snapshot": snapshot, "snapshot_persisted": snapshot_persisted, diff --git a/tests/test_decision_mapper.py b/tests/test_decision_mapper.py index 156a43c..a84c674 100644 --- a/tests/test_decision_mapper.py +++ b/tests/test_decision_mapper.py @@ -160,8 +160,8 @@ def test_value_decision_without_threshold_uses_platform_default(): strategy_profile="russell_top50_leader_rotation", ) - assert plan["execution"]["trade_threshold_value"] == 200.0 - assert plan["execution"]["current_min_trade"] == 200.0 + assert plan["execution"]["trade_threshold_value"] == 100.0 + assert plan["execution"]["current_min_trade"] == 100.0 assert plan["allocation"]["targets"]["AAA"] == 500.0 diff --git a/tests/test_execution_service.py b/tests/test_execution_service.py index 40fcb35..1146a08 100644 --- a/tests/test_execution_service.py +++ b/tests/test_execution_service.py @@ -265,7 +265,7 @@ def test_execute_value_target_plan_projects_unbuyable_value_target_to_zero(): assert result.action_done is True assert [(order.side, order.symbol, order.quantity) for order in execution_port.orders] == [ ("sell", "SOXX", 1.0), - ("buy", "SOXL", 1.0), + ("buy", "SOXL", 2.0), ] diff --git a/tests/test_notifications_telegram.py b/tests/test_notifications_telegram.py index 6156b2e..04efe9c 100644 --- a/tests/test_notifications_telegram.py +++ b/tests/test_notifications_telegram.py @@ -41,7 +41,7 @@ def test_render_cycle_summary_dashboard_text_does_not_hide_account_overview(): ) assert " - Total assets: $2,345.67" in message - assert " - Buying power: $456.78" in message + assert " - Available cash: $456.78" in message assert " - Reserved cash: $50.00" in message assert " - Investable cash: $406.78" in message assert " - SOXL: $1,000.00 / 5 shares" in message diff --git a/tests/test_rebalance_service.py b/tests/test_rebalance_service.py index 5b732b8..20e65e6 100644 --- a/tests/test_rebalance_service.py +++ b/tests/test_rebalance_service.py @@ -59,6 +59,7 @@ def test_runtime_metadata_uses_platform_execution_policy_over_strategy_metadata( "firstrade_execution_policy": { "reserved_cash_floor_usd": 250.0, "reserved_cash_ratio": 0.03, + "cash_only_execution": True, }, } @@ -242,7 +243,7 @@ def fake_client_factory(*args, **kwargs): assert result["notification_sent"] is True assert "🔔 【Rebalance Instruction】" in messages[0] assert "🧭 Strategy: TQQQ Growth Income" in messages[0] - assert "🆔 Account: ****5678" in messages[0] + assert "🆔 Account: 12345678" in messages[0] assert "📌 Strategy Account" in messages[0] assert "Target changes: AAA +50.00 USD" in messages[0] assert "🧾 Execution details" in messages[0] diff --git a/tests/test_runtime_broker_adapters.py b/tests/test_runtime_broker_adapters.py index 4a0bfae..f361929 100644 --- a/tests/test_runtime_broker_adapters.py +++ b/tests/test_runtime_broker_adapters.py @@ -61,9 +61,9 @@ def get_balances(self, _account): portfolio = adapters.build_portfolio_port().get_portfolio_snapshot() - assert portfolio.total_equity == 1234.56 + assert portfolio.total_equity == 221.0 assert portfolio.cash_balance == 200.0 - assert portfolio.metadata["total_equity_source"] == "balance_total" + assert portfolio.metadata["total_equity_source"] == "cash_plus_positions" def test_managed_portfolio_snapshot_ignores_full_account_value_balance_key(): diff --git a/tests/test_session_check_service.py b/tests/test_session_check_service.py index 165dcb5..1b3a0df 100644 --- a/tests/test_session_check_service.py +++ b/tests/test_session_check_service.py @@ -64,7 +64,7 @@ def _env(values): return lambda name, default=None: values.get(name, default) -def test_build_account_funds_snapshot_masks_account_and_compacts_values(): +def test_build_account_funds_snapshot_uses_full_account_and_compacts_values(): snapshot = build_account_funds_snapshot( account="12345678", account_summaries=[{"account": "****5678", "total_value": "100.00"}], @@ -74,7 +74,7 @@ def test_build_account_funds_snapshot_masks_account_and_compacts_values(): now=datetime(2026, 5, 23, 1, 2, 3, tzinfo=timezone.utc), ) - assert snapshot["account"] == "****5678" + assert snapshot["account"] == "12345678" assert snapshot["session_reused"] is True assert snapshot["balance_metrics"] == { "total_account_value": 100.0, @@ -104,8 +104,8 @@ def test_run_session_check_persists_funds_snapshot_when_enabled(): assert result["session_reused"] is True assert result["snapshot_persisted"] is True assert len(store.writes) == 2 - assert store.writes[0][0] == "accounts/____5678/funds/latest.json" - assert store.writes[1][0] == "accounts/____5678/funds/history/2026/05/23/20260523T010203Z.json" + assert store.writes[0][0] == "accounts/12345678/funds/latest.json" + assert store.writes[1][0] == "accounts/12345678/funds/history/2026/05/23/20260523T010203Z.json" assert store.writes[0][1]["positions"][0]["symbol"] == "SPY" @@ -162,7 +162,7 @@ def test_monthly_session_check_runs_and_persists_maintenance_state_when_due(): state_key, { "checked_at": "2026-06-03T01:02:03+00:00", - "account": "****5678", + "account": "12345678", "session_reused": True, "strategy_profile": "russell_top50_leader_rotation", "strategy_cadence": "monthly",