diff --git a/constraints.txt b/constraints.txt index 742aa4a..2522c89 100644 --- a/constraints.txt +++ b/constraints.txt @@ -4,7 +4,7 @@ # Auto-updated by update-qpk-pin.yml on every push to QPK main. quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@b0eacd2fe4884f7f2447b704a232e9a121f396c4 -us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@c8df5f9659340965bd7f53998892ed1018ed4254 +us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@c57fb20528d40f363ae149ae6e3f6b1a240ec237 hk-equity-strategies @ git+https://github.com/QuantStrategyLab/HkEquityStrategies.git@700c8b19c46336d3d8fcba687e58553afcf0235f cn-equity-strategies @ git+https://github.com/QuantStrategyLab/CnEquityStrategies.git@e09fd557c2bd9ae5f4d44228915c4e52c4b0dd21 crypto-strategies @ git+https://github.com/QuantStrategyLab/CryptoStrategies.git@565be005e4186fd6d750884e7b0bc59f779f9549 diff --git a/notifications/telegram.py b/notifications/telegram.py index 7a03363..e5380ec 100644 --- a/notifications/telegram.py +++ b/notifications/telegram.py @@ -185,6 +185,7 @@ def format_small_account_whole_share_bootstrap_notes( "account_overview_title": "📌 策略账户概览", "equity": "净值", "total_assets": "总资产(策略标的+现金)", + "total_assets_margin": "总资产(策略净值)", "buying_power": "可用现金", "buying_power_margin": "购买力", "reserved_cash": "预留现金", @@ -353,6 +354,7 @@ def format_small_account_whole_share_bootstrap_notes( "account_overview_title": "📌 Strategy Account", "equity": "Equity", "total_assets": "Total assets", + "total_assets_margin": "Total assets (strategy net liquidation)", "buying_power": "Available cash", "buying_power_margin": "Buying power", "reserved_cash": "Reserved cash", @@ -724,11 +726,15 @@ def _is_dashboard_account_metric_line(line: str, *, translator: Callable[..., st translator("investable_cash"), translator("equity"), "Total assets (strategy symbols + cash)", + "Total assets (strategy symbols + cash, ex-margin)", + "Total assets (strategy net liquidation)", "Buying power", "Reserved cash", "Investable cash", "Equity", "总资产(策略标的+现金)", + "总资产(策略标的+现金,不含融资额度)", + "总资产(策略净值)", "购买力", "预留现金", "可投资现金", @@ -744,14 +750,15 @@ def _format_generated_dashboard_lines( translator: Callable[..., str], ) -> list[str]: lines = [translator("account_overview_title")] + cash_only_execution = bool(execution.get("cash_only_execution", portfolio.get("cash_only_execution", True))) total_equity = _safe_float(portfolio.get("total_equity")) if total_equity is not None: - lines.append(f" - {translator('total_assets')}: {_format_money(total_equity)}") + total_assets_label = "total_assets" if cash_only_execution else "total_assets_margin" + lines.append(f" - {translator(total_assets_label)}: {_format_money(total_equity)}") buying_power = _safe_float(portfolio.get("liquid_cash")) if buying_power is None: buying_power = _safe_float(portfolio.get("buying_power")) if buying_power is not None: - cash_only_execution = bool(execution.get("cash_only_execution", portfolio.get("cash_only_execution", True))) buying_power_label = "buying_power" if cash_only_execution else "buying_power_margin" lines.append(f" - {translator(buying_power_label)}: {_format_money(buying_power)}") reserved_cash = _safe_float(execution.get("reserved_cash")) @@ -1224,8 +1231,6 @@ def render_cycle_summary(result: Mapping[str, Any], *, lang: str = "en") -> str: lines.append(SEPARATOR) lines.extend(dashboard_lines) lines.append(SEPARATOR) - lines.extend(_format_timing_lines(execution, translator=translator)) - lines.extend(_format_signal_lines(execution, translator=translator)) lines.extend(target_diff_lines) lines.extend( str(line).strip() diff --git a/requirements.txt b/requirements.txt index 5efb380..7add228 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,4 +8,4 @@ pytest pytz requests quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@b0eacd2fe4884f7f2447b704a232e9a121f396c4 -us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@c8df5f9659340965bd7f53998892ed1018ed4254 +us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@c57fb20528d40f363ae149ae6e3f6b1a240ec237 diff --git a/tests/test_notifications_telegram.py b/tests/test_notifications_telegram.py index 04efe9c..9489452 100644 --- a/tests/test_notifications_telegram.py +++ b/tests/test_notifications_telegram.py @@ -49,7 +49,7 @@ def test_render_cycle_summary_dashboard_text_does_not_hide_account_overview(): assert "Total assets (strategy symbols + cash): $2,000.00" not in message assert "Buying power: $100.00" not in message assert "📌 Strategy portfolio" not in message - assert message.count("🎯 Signal:") == 1 + assert "🎯 Signal:" not in message def test_render_cycle_summary_includes_tqqq_volatility_delever_risk_control(): @@ -94,8 +94,30 @@ def test_render_cycle_summary_includes_tqqq_volatility_delever_risk_control(): lang="en", ) - assert ( - "🛡️ Risk control: QQQ 5d annualized volatility 31.2% is above effective threshold 30.0% " - "(dynamic p90, 252d lookback, bounded 24.0%-36.0%, samples 252); TQQQ redirects to QQQM " - "(leveraged sleeve: TQQQ retained 0.0%, QQQM 100.0%)" - ) in message + assert "🛡️ Risk control:" not in message + + +def test_render_cycle_summary_relabels_total_assets_when_margin_is_enabled(): + message = render_cycle_summary( + { + "account": "****1234", + "strategy_profile": "tqqq_growth_income", + "dry_run_only": False, + "portfolio": { + "total_equity": 50000.0, + "liquid_cash": 75000.0, + "portfolio_rows": (("TQQQ",),), + "market_values": {"TQQQ": 8000.0}, + "quantities": {"TQQQ": 10}, + }, + "allocation": {"targets": {"TQQQ": 8000.0}}, + "execution": {"cash_only_execution": False}, + "submitted_orders": [], + "skipped_orders": [], + }, + lang="zh", + ) + + assert "总资产(策略净值): $50,000.00" in message + assert "购买力: $75,000.00" in message + assert "不含融资额度" not in message diff --git a/tests/test_rebalance_service.py b/tests/test_rebalance_service.py index 727b9f2..6d4a145 100644 --- a/tests/test_rebalance_service.py +++ b/tests/test_rebalance_service.py @@ -795,8 +795,8 @@ def test_render_cycle_summary_formats_skipped_orders_in_unified_chinese_template assert "🔔 【调仓指令】" in message assert "🆔 账户: ****1234" in message assert "📌 策略账户概览" in message - assert "⏱ 执行时点: 2026-05-20 -> 2026-05-21 (次一交易日执行)" in message - assert "🎯 信号: 入场信号" in message + assert "⏱ 执行时点:" not in message + assert "🎯 信号:" not in message assert "调仓变化: BOXX +7.89 USD, QQQ +44.39 USD, TQQQ +44.39 USD" in message assert "🧾 执行明细" in message assert "未下单: 原因=TQQQ,QQQ(整数股不足 1 股,无需下单), BOXX(低于调仓阈值)" in message @@ -842,10 +842,9 @@ def test_render_cycle_summary_localizes_strategy_signal_codes(): lang="zh", ) - assert "📊 市场状态: 🚀 风险开启(SOXX+SOXL)" in message - assert "🎯 信号: SOXX 站上 140 日门槛线,持有 SOXL 70.0% + SOXX 20.0%" in message - assert " - 小账户提示:净值 $0 低于建议 $1,000;整数股和最小仓位限制可能导致实盘无法完全复现回测" in message - assert message.count("🎯 信号:") == 1 + assert "📊 市场状态:" not in message + assert "🎯 信号:" not in message + assert "小账户提示" not in message assert "signal_blend_gate_risk_on" not in message assert "soxl_ratio" not in message assert "small_account_warning_note" not in message @@ -970,8 +969,8 @@ def test_render_cycle_summary_formats_skipped_orders_in_unified_english_template assert "🔔 【Rebalance Instruction】" in message assert "🆔 Account: ****1234" in message assert "📌 Strategy Account" in message - assert "⏱ Timing: 2026-05-20 -> 2026-05-21 (next trading day)" in message - assert "🎯 Signal: Entry Signal" in message + assert "⏱ Timing:" not in message + assert "🎯 Signal:" not in message assert "Target changes: BOXX +7.89 USD, QQQ +44.39 USD, TQQQ +44.39 USD" in message assert "🧾 Execution details" in message assert (