Skip to content

Commit aa12958

Browse files
committed
Localize LongBridge notification guard text
1 parent 149f5da commit aa12958

2 files changed

Lines changed: 54 additions & 2 deletions

File tree

application/rebalance_service.py

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,28 @@
66
import traceback
77
from datetime import datetime
88

9+
_ZH_REASON_REPLACEMENTS = (
10+
("feature snapshot guard blocked execution", "特征快照校验阻止执行"),
11+
("feature snapshot required", "需要特征快照"),
12+
("feature snapshot compute failed", "特征快照计算失败"),
13+
("feature_snapshot_download_failed", "特征快照下载失败"),
14+
("feature_snapshot_compute_failed", "特征快照计算失败"),
15+
("feature_snapshot_path_missing", "缺少特征快照路径"),
16+
("feature_snapshot_missing", "特征快照不存在"),
17+
("feature_snapshot_stale", "特征快照过旧"),
18+
("feature_snapshot_manifest_missing", "缺少快照清单"),
19+
("feature_snapshot_profile_mismatch", "快照策略名不匹配"),
20+
("feature_snapshot_config_name_mismatch", "快照配置名不匹配"),
21+
("feature_snapshot_config_path_mismatch", "快照配置路径不匹配"),
22+
("feature_snapshot_contract_version_mismatch", "快照契约版本不匹配"),
23+
("outside_execution_window", "当前不在执行窗口"),
24+
("insufficient_buying_power", "购买力不足"),
25+
("missing_price", "缺少报价"),
26+
("no_equity", "无净值"),
27+
("fail_closed", "关闭执行"),
28+
("reason=", "原因="),
29+
)
30+
931

1032
def _plan_portfolio(plan):
1133
return dict(plan.get("portfolio") or {})
@@ -23,6 +45,21 @@ def _has_text(value):
2345
return bool(str(value or "").strip())
2446

2547

48+
def _translator_uses_zh(translator) -> bool:
49+
sample = str(translator("no_trades"))
50+
return any("\u4e00" <= ch <= "\u9fff" for ch in sample)
51+
52+
53+
def _localize_notification_text(text, *, translator):
54+
value = str(text or "").strip()
55+
if not value or not _translator_uses_zh(translator):
56+
return value
57+
localized = value
58+
for source, target in _ZH_REASON_REPLACEMENTS:
59+
localized = localized.replace(source, target)
60+
return localized
61+
62+
2663
def _has_benchmark_context(execution):
2764
return any(
2865
float(execution.get(key) or 0.0) > 0.0
@@ -44,7 +81,7 @@ def _build_benchmark_line(execution):
4481

4582

4683
def _append_status_lines(lines, *, execution, translator, signal_key):
47-
status_display = str(execution.get("status_display") or "").strip()
84+
status_display = _localize_notification_text(execution.get("status_display"), translator=translator)
4885
if status_display:
4986
lines.append(translator("market_status", status=status_display))
5087

@@ -60,7 +97,7 @@ def _append_status_lines(lines, *, execution, translator, signal_key):
6097
if income_locked_ratio_text:
6198
lines.append(translator("income_locked", ratio=income_locked_ratio_text))
6299

63-
signal_display = str(execution.get("signal_display") or "").strip()
100+
signal_display = _localize_notification_text(execution.get("signal_display"), translator=translator)
64101
if signal_display:
65102
lines.append(translator(signal_key, msg=signal_display))
66103

tests/test_rebalance_service.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,21 @@ def _build_plan(
9191

9292

9393
class RebalanceServiceNotificationTests(unittest.TestCase):
94+
def test_append_status_lines_localizes_snapshot_guard_text_for_zh(self):
95+
lines = []
96+
rebalance_service._append_status_lines(
97+
lines,
98+
execution={
99+
"status_display": "fail_closed | reason=feature_snapshot_path_missing",
100+
"signal_display": "feature snapshot guard blocked execution",
101+
},
102+
translator=build_translator("zh"),
103+
signal_key="heartbeat_signal",
104+
)
105+
106+
self.assertIn("📊 市场状态: 关闭执行 | 原因=缺少特征快照路径", lines)
107+
self.assertIn("🎯 信号: 特征快照校验阻止执行", lines)
108+
94109
def _run_strategy(
95110
self,
96111
plan,

0 commit comments

Comments
 (0)