diff --git a/crypto_monitor_binance/app.py b/crypto_monitor_binance/app.py index 25a25cc..ed57e72 100644 --- a/crypto_monitor_binance/app.py +++ b/crypto_monitor_binance/app.py @@ -76,7 +76,7 @@ from lib.strategy.strategy_trade_labels import ( trade_record_monitor_type as resolve_trade_record_monitor_type, trend_plan_id_from_monitor_row, ) -from lib.instance.journal_form_lib import normalize_journal_entry_reason +from lib.instance.journal_form_lib import normalize_journal_direction, normalize_journal_entry_reason from lib.instance.journal_images_lib import ( collect_journal_slot_images, enrich_journal_api_item, @@ -1434,6 +1434,9 @@ def init_db(): try: c.execute("ALTER TABLE journal_entries ADD COLUMN order_type TEXT") except: pass + try: + c.execute("ALTER TABLE journal_entries ADD COLUMN direction TEXT") + except: pass try: c.execute("ALTER TABLE key_monitors ADD COLUMN direction TEXT DEFAULT 'long'") except: pass @@ -9281,6 +9284,10 @@ def add_journal(): if not order_type_norm: flash("请选择下单类型") return _redirect_records() + direction_norm = normalize_journal_direction(d.get("direction") or d.get("direction_hint")) + if not direction_norm: + flash("请选择方向") + return _redirect_records() entry_reason_norm = normalize_journal_entry_reason( d.get("entry_reason"), ENTRY_REASON_OPTIONS, allow_legacy=False ) @@ -9376,11 +9383,11 @@ def add_journal(): conn = get_db() conn.execute( """INSERT INTO journal_entries - (id, open_datetime, close_datetime, hold_duration, coin, tf, pnl, order_type, entry_reason, exit_reason, + (id, open_datetime, close_datetime, hold_duration, coin, tf, direction, pnl, order_type, entry_reason, exit_reason, expect_rr, real_rr, early_exit, early_exit_reason, early_exit_trigger, early_exit_note, mood_score, mood_ai_score, mood_ai_comment, mood_issues, post_breakeven_stare, new_trade_while_occupied, note, image, images_json) - VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", + VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", ( entry_id, normalize_bj_datetime_storage(d.get("open_datetime")), @@ -9388,6 +9395,7 @@ def add_journal(): hold_duration, d.get("coin"), d.get("tf"), + direction_norm, d.get("pnl"), order_type_norm, entry_reason_norm, exit_reason_stored, d.get("expect_rr"), real_rr_text, early_exit_raw, early_exit_reason_saved, early_exit_trigger, early_exit_note, None, None, None, mood_issues, diff --git a/crypto_monitor_gate/app.py b/crypto_monitor_gate/app.py index 735a0c1..e9ae24d 100644 --- a/crypto_monitor_gate/app.py +++ b/crypto_monitor_gate/app.py @@ -78,7 +78,7 @@ from lib.strategy.strategy_trade_labels import ( trade_record_monitor_type as resolve_trade_record_monitor_type, trend_plan_id_from_monitor_row, ) -from lib.instance.journal_form_lib import normalize_journal_entry_reason +from lib.instance.journal_form_lib import normalize_journal_direction, normalize_journal_entry_reason from lib.instance.journal_images_lib import ( collect_journal_slot_images, enrich_journal_api_item, @@ -1430,6 +1430,9 @@ def init_db(): try: c.execute("ALTER TABLE journal_entries ADD COLUMN order_type TEXT") except: pass + try: + c.execute("ALTER TABLE journal_entries ADD COLUMN direction TEXT") + except: pass try: c.execute("ALTER TABLE key_monitors ADD COLUMN direction TEXT DEFAULT 'long'") except: pass @@ -9148,6 +9151,10 @@ def add_journal(): if not order_type_norm: flash("请选择下单类型") return _redirect_records() + direction_norm = normalize_journal_direction(d.get("direction") or d.get("direction_hint")) + if not direction_norm: + flash("请选择方向") + return _redirect_records() entry_reason_norm = normalize_journal_entry_reason( d.get("entry_reason"), ENTRY_REASON_OPTIONS, allow_legacy=False ) @@ -9243,11 +9250,11 @@ def add_journal(): conn = get_db() conn.execute( """INSERT INTO journal_entries - (id, open_datetime, close_datetime, hold_duration, coin, tf, pnl, order_type, entry_reason, exit_reason, + (id, open_datetime, close_datetime, hold_duration, coin, tf, direction, pnl, order_type, entry_reason, exit_reason, expect_rr, real_rr, early_exit, early_exit_reason, early_exit_trigger, early_exit_note, mood_score, mood_ai_score, mood_ai_comment, mood_issues, post_breakeven_stare, new_trade_while_occupied, note, image, images_json) - VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", + VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", ( entry_id, normalize_bj_datetime_storage(d.get("open_datetime")), @@ -9255,6 +9262,7 @@ def add_journal(): hold_duration, d.get("coin"), d.get("tf"), + direction_norm, d.get("pnl"), order_type_norm, entry_reason_norm, exit_reason_stored, d.get("expect_rr"), real_rr_text, early_exit_raw, early_exit_reason_saved, early_exit_trigger, early_exit_note, None, None, None, mood_issues, diff --git a/crypto_monitor_okx/app.py b/crypto_monitor_okx/app.py index 3c114e1..cdba7fb 100644 --- a/crypto_monitor_okx/app.py +++ b/crypto_monitor_okx/app.py @@ -76,7 +76,7 @@ from lib.strategy.strategy_trade_labels import ( trade_record_monitor_type as resolve_trade_record_monitor_type, trend_plan_id_from_monitor_row, ) -from lib.instance.journal_form_lib import normalize_journal_entry_reason +from lib.instance.journal_form_lib import normalize_journal_direction, normalize_journal_entry_reason from lib.exchange.okx_orders_lib import cancel_okx_all_open_orders, fetch_okx_all_open_orders from lib.instance.journal_images_lib import ( collect_journal_slot_images, @@ -1435,6 +1435,9 @@ def init_db(): try: c.execute("ALTER TABLE journal_entries ADD COLUMN order_type TEXT") except: pass + try: + c.execute("ALTER TABLE journal_entries ADD COLUMN direction TEXT") + except: pass try: c.execute("ALTER TABLE key_monitors ADD COLUMN direction TEXT DEFAULT 'long'") except: pass @@ -8836,6 +8839,10 @@ def add_journal(): if not order_type_norm: flash("请选择下单类型") return _redirect_records() + direction_norm = normalize_journal_direction(d.get("direction") or d.get("direction_hint")) + if not direction_norm: + flash("请选择方向") + return _redirect_records() entry_reason_norm = normalize_journal_entry_reason( d.get("entry_reason"), ENTRY_REASON_OPTIONS, allow_legacy=False ) @@ -8931,11 +8938,11 @@ def add_journal(): conn = get_db() conn.execute( """INSERT INTO journal_entries - (id, open_datetime, close_datetime, hold_duration, coin, tf, pnl, order_type, entry_reason, exit_reason, + (id, open_datetime, close_datetime, hold_duration, coin, tf, direction, pnl, order_type, entry_reason, exit_reason, expect_rr, real_rr, early_exit, early_exit_reason, early_exit_trigger, early_exit_note, mood_score, mood_ai_score, mood_ai_comment, mood_issues, post_breakeven_stare, new_trade_while_occupied, note, image, images_json) - VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", + VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", ( entry_id, normalize_bj_datetime_storage(d.get("open_datetime")), @@ -8943,6 +8950,7 @@ def add_journal(): hold_duration, d.get("coin"), d.get("tf"), + direction_norm, d.get("pnl"), order_type_norm, entry_reason_norm, exit_reason_stored, d.get("expect_rr"), real_rr_text, early_exit_raw, early_exit_reason_saved, early_exit_trigger, early_exit_note, None, None, None, mood_issues, diff --git a/lib/common/static/instance_ui.js b/lib/common/static/instance_ui.js index ca8a73a..158078e 100644 --- a/lib/common/static/instance_ui.js +++ b/lib/common/static/instance_ui.js @@ -34,6 +34,7 @@ typeof formatExitLine === "function" ? formatExitLine(o) : o.exit_reason || "无"; const lines = [ `币种/周期:${escapeHtml(o.coin || "-")} ${escapeHtml(o.tf || "-")}`, + `方向:${escapeHtml((function(){ const d = inferJournalDirection(o); return d ? d.text : "-"; })())}`, `开仓时间:${escapeHtml(o.open_datetime || "-")}`, `平仓时间:${escapeHtml(o.close_datetime || "-")}`, `持仓时长:${escapeHtml(o.hold_duration || "-")}`, diff --git a/lib/instance/journal_form_lib.py b/lib/instance/journal_form_lib.py index de373f8..1aed0a6 100644 --- a/lib/instance/journal_form_lib.py +++ b/lib/instance/journal_form_lib.py @@ -42,3 +42,13 @@ def journal_entry_reason_valid(raw: Optional[str], allowed: Sequence[str]) -> bo def journal_order_type_valid(raw: Optional[str]) -> bool: return bool(normalize_journal_order_type(raw)) + + +def normalize_journal_direction(raw: Optional[str]) -> str: + s = (raw or "").strip().lower() + if s in ("long", "buy", "多", "做多"): + return "long" + if s in ("short", "sell", "空", "做空"): + return "short" + # 兼容旧隐藏字段 direction_hint + return "" diff --git a/lib/instance/templates/embed_boot_scripts.html b/lib/instance/templates/embed_boot_scripts.html index b8fd8f5..9a32dd2 100644 --- a/lib/instance/templates/embed_boot_scripts.html +++ b/lib/instance/templates/embed_boot_scripts.html @@ -545,6 +545,8 @@ function fillJournalFromTrade(t){ if(stopHint){ stopHint.value = slPx; } const dirHint = document.getElementById("direction-hint"); if(dirHint){ dirHint.value = t.direction || "long"; } + const dirNorm = String(t.direction || "long").toLowerCase() === "short" ? "short" : "long"; + setJournalField("direction", dirNorm); setJournalField("early_exit_trigger", ""); setJournalField("early_exit_note", ""); const kst = String(t.key_signal_type || "").trim(); diff --git a/lib/instance/templates/embed_shell.html b/lib/instance/templates/embed_shell.html index ef78a50..a067834 100644 --- a/lib/instance/templates/embed_shell.html +++ b/lib/instance/templates/embed_shell.html @@ -90,7 +90,7 @@ - + diff --git a/lib/instance/templates/index.html b/lib/instance/templates/index.html index c4a816d..0a6ce30 100644 --- a/lib/instance/templates/index.html +++ b/lib/instance/templates/index.html @@ -447,7 +447,7 @@ - + @@ -1002,6 +1002,8 @@ function fillJournalFromTrade(t){ if(stopHint){ stopHint.value = slPx; } const dirHint = document.getElementById("direction-hint"); if(dirHint){ dirHint.value = t.direction || "long"; } + const dirNorm = String(t.direction || "long").toLowerCase() === "short" ? "short" : "long"; + setJournalField("direction", dirNorm); setJournalField("early_exit_trigger", ""); setJournalField("early_exit_note", ""); const kst = String(t.key_signal_type || "").trim(); diff --git a/lib/strategy/templates/journal_form_fields.html b/lib/strategy/templates/journal_form_fields.html index 18ab4b6..a0746a0 100644 --- a/lib/strategy/templates/journal_form_fields.html +++ b/lib/strategy/templates/journal_form_fields.html @@ -10,6 +10,11 @@
+