Skip to content

Commit 21dcef8

Browse files
Pigbibiclaude
andauthored
fix: i18n defaults, strategy name differentiation, TypeError-safe translator, panic reversal constant (#118)
- Add EN i18n keys: strategy_plugin_recommendation_default, strategy_plugin_situation_default - Differentiate qqq_tech_enhancement from tech_communication_pullback_enhancement in ZH - Add PLUGIN_PANIC_REVERSAL_SHADOW constant - Wrap translator calls in try/except TypeError for kwargs safety Co-authored-by: Claude <noreply@anthropic.com>
1 parent f8c24a1 commit 21dcef8

2 files changed

Lines changed: 24 additions & 11 deletions

File tree

src/quant_platform_kit/common/notification_localization.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@
200200
"strategy_plugin_situation_delever_delever": "De-lever: a de-lever signal is active and risk exposure should be reduced under strategy rules.",
201201
"strategy_plugin_situation_notify_manual_review": "Manual review: the plugin found a market state that needs human judgment.",
202202
"strategy_plugin_situation_default": "State notice: the plugin found a market state that needs attention.",
203+
"strategy_plugin_recommendation_default": "Review manually first, then decide whether the action belongs to strategy rules or a manual process; do not treat the plugin notice as a trade instruction.",
203204
"strategy_plugin_recommendation_market_regime_control_watch_watch_only": "Check the trigger, recent volatility, and current leverage; this watch notice does not change allocations automatically, and any position change should come from the strategy run or an explicit manual decision.",
204205
"strategy_plugin_recommendation_market_regime_control_risk_reduced_delever": "Check the strategy run, account constraints, and de-lever thresholds; if the strategy-side automatic rule fired, execution belongs to the strategy notification and position adapter.",
205206
"strategy_plugin_recommendation_market_regime_control_risk_off_defend": "Pause opportunity adds and confirm whether defensive exposure matches strategy rules; wait for the risk-off state to clear before resuming offensive signals.",
@@ -243,7 +244,7 @@
243244
("global_etf_rotation", "全球 ETF 轮动"),
244245
("russell_1000_multi_factor_defensive", "罗素1000多因子"),
245246
("tech_communication_pullback_enhancement", "科技通信回调增强"),
246-
("qqq_tech_enhancement", "科技通信回调增强"),
247+
("qqq_tech_enhancement", "QQQ 科技增强"),
247248
("mega_cap_leader_rotation_top50_balanced", "美股超大盘50强平衡龙头轮动"),
248249
("outside_monthly_execution_window", "当前不在月度执行窗口"),
249250
("no_execution_window_after_snapshot", "快照后没有可用执行窗口"),

src/quant_platform_kit/common/strategy_plugins.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@
1313

1414
from quant_platform_kit.common.strategy_plugin_artifacts import (
1515
cache_path_for_remote_artifact,
16-
download_gcs_object,
17-
materialize_local_or_gcs_artifact,
18-
parse_gcs_uri,
16+
download_remote_object,
17+
materialize_local_or_remote_artifact,
18+
parse_cloud_uri,
1919
)
2020

2121
PLUGIN_CRISIS_RESPONSE_SHADOW = "crisis_response_shadow"
2222
PLUGIN_MARKET_REGIME_CONTROL = "market_regime_control"
2323
PLUGIN_MACRO_RISK_GOVERNOR = "macro_risk_governor"
2424
PLUGIN_TACO_REBOUND_SHADOW = "taco_rebound_shadow"
25+
PLUGIN_PANIC_REVERSAL_SHADOW = "panic_reversal_shadow"
2526
GENERAL_MARKET_REGIME_NOTIFICATION_TARGET = "market_regime_notification"
2627
PLUGIN_MODE_SHADOW = "shadow"
2728
STRATEGY_PLUGIN_ALERT_CHANNEL_EMAIL = "email"
@@ -1310,7 +1311,10 @@ def _translate_first_formatted(
13101311
if translator is None:
13111312
return None
13121313
for key in keys:
1313-
translated = translator(key, **kwargs)
1314+
try:
1315+
translated = translator(key, **kwargs)
1316+
except TypeError:
1317+
translated = translator(key)
13141318
if translated != key:
13151319
text = str(translated).strip()
13161320
if text:
@@ -1695,19 +1699,24 @@ def _sanitize_key_part(value: Any) -> str:
16951699

16961700

16971701
def _materialize_artifact_path(reference: str, *, client_factory: Any = None) -> tuple[Path, dict[str, str | None]]:
1698-
return materialize_local_or_gcs_artifact(
1702+
return materialize_local_or_remote_artifact(
16991703
reference,
17001704
cache_dir=DEFAULT_PLUGIN_ARTIFACT_CACHE_DIR,
17011705
client_factory=client_factory,
17021706
)
17031707

17041708

1705-
def _download_gcs_object(uri: str, destination: Path, *, client_factory: Any = None) -> None:
1706-
download_gcs_object(uri, destination, client_factory=client_factory)
1709+
def _download_remote_object(uri: str, destination: Path, *, client_factory: Any = None) -> None:
1710+
download_remote_object(uri, destination, client_factory=client_factory)
1711+
1712+
1713+
def _parse_cloud_uri(uri: str) -> tuple[str, str]:
1714+
return parse_cloud_uri(uri)
17071715

17081716

1709-
def _parse_gcs_uri(uri: str) -> tuple[str, str]:
1710-
return parse_gcs_uri(uri)
1717+
# Backward-compatible aliases (used internally by notification modules)
1718+
_download_gcs_object = _download_remote_object
1719+
_parse_gcs_uri = _parse_cloud_uri
17111720

17121721

17131722
def _cache_path_for_remote_artifact(reference: str) -> Path:
@@ -1742,7 +1751,10 @@ def _translate(
17421751
) -> str:
17431752
if translator is None:
17441753
return fallback.format(**kwargs)
1745-
translated = translator(key, **kwargs)
1754+
try:
1755+
translated = translator(key, **kwargs)
1756+
except TypeError:
1757+
translated = translator(key)
17461758
return translated if translated != key else fallback.format(**kwargs)
17471759

17481760

0 commit comments

Comments
 (0)