stock-ai-agent/backend/app/utils/signal_text.py
2026-04-28 15:02:13 +08:00

128 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
信号文本翻译工具
将内部策略枚举、setup/entry basis 等英文编码,转换为更适合通知展示的中文描述。
"""
from __future__ import annotations
from typing import Dict, Optional
SETUP_TYPE_LABELS: Dict[str, str] = {
"range_reversal": "区间反转",
"trend_reversal": "趋势反转",
"breakout_confirmation": "突破确认",
"breakout_pullback": "突破后回踩",
"trend_continuation_pullback": "趋势延续回踩",
"deep_pullback_continuation": "深度回踩延续",
"unknown": "未分类",
}
LOCATION_LABELS: Dict[str, str] = {
"near_long_zone": "临近做多区",
"near_short_zone": "临近做空区",
"near_range_support": "临近区间支撑",
"near_range_resistance": "临近区间阻力",
"middle_of_range": "位于区间中部",
"far_from_trade_zone": "远离优先交易区",
"between_trade_zones": "位于交易区之间",
"range_edge": "区间边缘",
"unknown": "未知位置",
}
FEATURE_VALUE_LABELS: Dict[str, str] = {
"bullish_acceptance": "多头承接有效",
"bearish_acceptance": "空头承接有效",
"bullish_rejection": "多头拒绝信号",
"bearish_rejection": "空头拒绝信号",
"bullish_continuation": "多头延续",
"bearish_continuation": "空头延续",
"pullback_on_light_volume": "缩量回调",
"counter_pressure_expanding": "逆向压力放大",
"acceptance_breakout_up": "向上突破并站稳",
"acceptance_breakout_down": "向下突破并站稳",
"weak_breakout_up": "向上弱突破",
"weak_breakout_down": "向下弱突破",
"healthy_pullback": "健康回调",
"heavy_sell_pullback": "放量下压回调",
"heavy_buy_pullback": "放量上冲回调",
"none": "",
"neutral": "中性",
"unknown": "未知",
"early": "趋势早期",
}
FIELD_LABELS: Dict[str, str] = {
"setup": "形态",
"location": "位置",
"volume_price_state": "量价状态",
"breakout_quality": "突破质量",
"pullback_quality": "回调质量",
"rejection_signal": "拒绝信号",
}
ENTRY_BASIS_LABELS: Dict[str, str] = {
"breakout_acceptance_follow_through": "突破站稳后顺势跟进",
"pullback_into_trade_zone": "回踩交易区后挂单介入",
"pullback_confirmed": "回调确认后介入",
"rejection_or_structure_shift": "出现拒绝信号或结构切换后介入",
"generic_entry": "按通用入场条件执行",
}
def humanize_setup_type(value: Optional[str]) -> str:
code = str(value or "").strip()
if not code:
return "-"
return SETUP_TYPE_LABELS.get(code, code)
def _humanize_value(raw: str) -> str:
text = str(raw or "").strip()
if not text:
return "-"
if text in SETUP_TYPE_LABELS:
return SETUP_TYPE_LABELS[text]
if text in LOCATION_LABELS:
return LOCATION_LABELS[text]
if text in FEATURE_VALUE_LABELS:
return FEATURE_VALUE_LABELS[text]
return text
def humanize_setup_basis(value: Optional[str]) -> str:
text = str(value or "").strip()
if not text:
return "-"
parts = []
for chunk in text.split("|"):
piece = chunk.strip()
if not piece:
continue
if "=" not in piece:
parts.append(piece)
continue
key, raw_value = [item.strip() for item in piece.split("=", 1)]
key_label = FIELD_LABELS.get(key, key)
value_label = _humanize_value(raw_value)
parts.append(f"{key_label}={value_label}")
return "".join(parts) if parts else text
def humanize_entry_basis(value: Optional[str]) -> str:
text = str(value or "").strip()
if not text:
return "-"
if text in ENTRY_BASIS_LABELS:
return ENTRY_BASIS_LABELS[text]
reversal_prefix = "reversal_from_"
if text.startswith(reversal_prefix):
location = text[len(reversal_prefix):]
return f"{LOCATION_LABELS.get(location, location)}出现反转信号后介入"
return text