feat: review entry reason picker uses dropdown instead of prompt

Add modal select for trade record review, expand options to two-level labels (反转/启动A), and accept legacy short labels on save.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-07 00:38:16 +08:00
parent f580e4542d
commit 1092816359
10 changed files with 188 additions and 34 deletions
+41 -11
View File
@@ -48,13 +48,7 @@ ENTRY_CATEGORY_LABELS: dict[str, str] = {
ENTRY_CATEGORY_SWING: "波段",
}
TREND_DIV_ENTRY_REASON_LABELS: Tuple[str, ...] = (
"启动A",
"启动B",
"大分歧A",
"大分歧B",
"小分歧",
)
TRADE_STYLE_FALLBACK_ENTRY_REASONS: Tuple[str, ...] = ("趋势单", "波段单")
INTRADAY_LEGACY_TREND_ENTRY_REASONS: Tuple[str, ...] = (
"趋势多头:4h大结构突破前进场,确认条件:三次探顶,5m收敛不创新低",
@@ -281,23 +275,55 @@ def trade_style_label_zh(trade_style: str) -> str:
return "波段单" if (trade_style or "").strip().lower() == "swing" else "趋势单"
def trend_div_entry_reason_display_options() -> Tuple[str, ...]:
return tuple(entry_model_display_label(code) for code, _, _, _, _ in _ENTRY_SPECS)
def intraday_entry_reason_display_options() -> Tuple[str, ...]:
return tuple(entry_model_display_label(code) for code, _, _, _, _ in _INTRADAY_ENTRY_SPECS)
def normalize_review_entry_reason(raw: Optional[str], allowed: Sequence[str]) -> str:
"""复盘/核对开仓类型:允许两级展示名,兼容旧短标签。"""
s = (raw or "").strip()
if not s:
return ""
allowed_set = frozenset(allowed)
if s in allowed_set:
return s
disp = format_entry_type_display(s)
if disp in allowed_set:
return disp
code = normalize_entry_model_code(s)
if code:
disp2 = entry_model_display_label(code)
if disp2 in allowed_set:
return disp2
return ""
def trend_manual_entry_reason_count(policy: TradePolicy) -> int:
if is_intraday_trading_profile(policy):
return len(INTRADAY_LEGACY_TREND_ENTRY_REASONS)
return len(TREND_DIV_ENTRY_REASON_LABELS)
return len(INTRADAY_LEGACY_TREND_ENTRY_REASONS) + len(intraday_entry_reason_display_options())
return len(trend_div_entry_reason_display_options()) + len(TRADE_STYLE_FALLBACK_ENTRY_REASONS)
def build_trend_div_entry_reason_options(
strategy_options: Sequence[str],
) -> Tuple[str, ...]:
return TREND_DIV_ENTRY_REASON_LABELS + tuple(strategy_options)
return trend_div_entry_reason_display_options() + TRADE_STYLE_FALLBACK_ENTRY_REASONS + tuple(strategy_options)
def build_intraday_entry_reason_options(
key_options: Sequence[str],
strategy_options: Sequence[str],
) -> Tuple[str, ...]:
return INTRADAY_LEGACY_TREND_ENTRY_REASONS + tuple(key_options) + tuple(strategy_options)
return (
INTRADAY_LEGACY_TREND_ENTRY_REASONS
+ intraday_entry_reason_display_options()
+ tuple(key_options)
+ tuple(strategy_options)
)
def entry_reason_options_for_policy(
@@ -468,3 +494,7 @@ def migrate_entry_model_columns(conn) -> None:
conn.execute(f"ALTER TABLE {table} ADD COLUMN entry_model TEXT")
except Exception:
pass
# 兼容旧引用:现为两级展示文案
TREND_DIV_ENTRY_REASON_LABELS = trend_div_entry_reason_display_options()