diff --git a/application/rebalance_service.py b/application/rebalance_service.py index 84fca18..78f679f 100644 --- a/application/rebalance_service.py +++ b/application/rebalance_service.py @@ -24,6 +24,41 @@ ("feature_snapshot_config_name_mismatch", "快照配置名不匹配"), ("feature_snapshot_config_path_mismatch", "快照配置路径不匹配"), ("feature_snapshot_contract_version_mismatch", "快照契约版本不匹配"), + ("soxl_soxx_trend_income", "SOXL/SOXX 半导体趋势收益"), + ("tqqq_growth_income", "TQQQ 增长收益"), + ("global_etf_rotation", "全球 ETF 轮动"), + ("russell_1000_multi_factor_defensive", "罗素1000多因子"), + ("tech_communication_pullback_enhancement", "科技通信回调增强"), + ("qqq_tech_enhancement", "科技通信回调增强"), + ("mega_cap_leader_rotation_aggressive", "Mega Cap 激进龙头轮动"), + ("mega_cap_leader_rotation_dynamic_top20", "Mega Cap 动态 Top20 龙头轮动"), + ("mega_cap_leader_rotation_top50_balanced", "Mega Cap Top50 平衡龙头轮动"), + ("dynamic_mega_leveraged_pullback", "Mega Cap 2x 回调策略"), + ("outside_monthly_execution_window", "当前不在月度执行窗口"), + ("no_execution_window_after_snapshot", "快照后没有可用执行窗口"), + ("no-op", "不执行"), + ("monthly snapshot cadence", "月度快照节奏"), + ("waiting inside execution window", "等待进入执行窗口"), + ("small_account_warning=true", "小账户提示=是"), + ("portfolio_equity=", "净值="), + ("min_recommended_equity=", "建议最低净值="), + ( + "integer_shares_min_position_value_may_prevent_backtest_replication", + "整数股和最小仓位限制可能导致实盘无法完全复现回测", + ), + ( + "integer-share minimum position sizing may prevent backtest replication", + "整数股和最小仓位限制可能导致实盘无法完全复现回测", + ), + ("small account warning: portfolio equity", "小账户提示:净值"), + ("small account warning", "小账户提示"), + ("is below the recommended", "低于建议"), + ("is below recommended", "低于建议"), + ("snapshot_as_of=", "快照日期="), + ("snapshot=", "快照日期="), + ("allowed=", "允许日期="), + ("", "未知"), + ("", "无"), ("RISK-ON", "风险开启"), ("DE-LEVER", "降杠杆"), ("regime=hard_defense", "市场阶段=强防御"), @@ -191,7 +226,7 @@ def _build_notification_trade_lines( lines.extend(_build_order_batch_lines(execution_summary, translator=translator)) for raw_line in trade_logs or (): - text = str(raw_line).strip() + text = _localize_notification_text(str(raw_line).strip(), translator=translator) if not text: continue if text.startswith(("目标差异 ", "target_diff ", "DRY_RUN buy ", "DRY_RUN sell ")): diff --git a/tests/test_rebalance_service.py b/tests/test_rebalance_service.py index d4fe37c..fdf47fa 100644 --- a/tests/test_rebalance_service.py +++ b/tests/test_rebalance_service.py @@ -1,6 +1,7 @@ import json from application.rebalance_service import build_dashboard, run_strategy_core +from application.rebalance_service import _build_notification_trade_lines from notifications.telegram import build_translator @@ -136,6 +137,26 @@ def test_build_dashboard_localizes_qqq_tech_diagnostics_for_zh(): assert "入选标的数=8 前排标的=CIEN(0.92)" in dashboard +def test_notification_trade_lines_localize_runtime_diagnostic_tail_for_zh(): + lines = _build_notification_trade_lines( + [ + ( + "执行配置=soxl_soxx_trend_income | 市场阶段= | 宽度=0.0% | " + "目标股票仓位=0.0% | 实际股票仓位=0.0% | 快照日期= | 交易日=" + ) + ], + execution_summary={}, + translator=build_translator("zh"), + ) + + assert lines == [ + ( + "执行配置=SOXL/SOXX 半导体趋势收益 | 市场阶段=无 | 宽度=0.0% | " + "目标股票仓位=0.0% | 实际股票仓位=0.0% | 快照日期=无 | 交易日=无" + ) + ] + + def test_run_strategy_core_passes_signal_metadata_to_execution(): observed = {"messages": [], "strategy_symbols": None}