fix: OKX manual orders save entry_model for trade record 开仓类型

OKX add_order omitted entry_model on insert; align with Binance/Gate and add trade_style fallback when resolving entry_reason for close and display.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-07 00:15:22 +08:00
parent d3753f1aee
commit d520ba6904
5 changed files with 86 additions and 8 deletions
+16 -2
View File
@@ -183,6 +183,7 @@ from lib.trade.entry_model_lib import (
order_entry_template_context,
open_position_button_label,
parse_manual_order_style_fields,
resolve_effective_trade_entry_reason,
resolve_trade_record_entry_reason,
trend_manual_entry_reason_count,
)
@@ -2105,8 +2106,20 @@ def to_effective_trade_dict(row):
item["effective_pnl_amount"] = get_effective_trade_field(row, "reviewed_pnl_amount", "pnl_amount", item.get("pnl_amount"))
item["effective_hold_minutes"] = get_effective_trade_field(row, "reviewed_hold_minutes", "hold_minutes", item.get("hold_minutes"))
item["effective_hold_seconds"] = get_effective_trade_field(row, "reviewed_hold_seconds", "hold_seconds", item.get("hold_seconds"))
er_eff = get_effective_trade_field(row, "reviewed_entry_reason", "entry_reason", item.get("entry_reason"))
item["effective_entry_reason"] = (str(er_eff).strip() if er_eff is not None else "") or ""
try:
_er_keys = row.keys() if hasattr(row, "keys") else []
except Exception:
_er_keys = []
reviewed_er = row["reviewed_entry_reason"] if "reviewed_entry_reason" in _er_keys else None
item["effective_entry_reason"] = resolve_effective_trade_entry_reason(
reviewed_entry_reason=reviewed_er,
entry_reason=item.get("entry_reason"),
key_signal_type=(item.get("key_signal_type") or "").strip() or None,
monitor_type=item.get("monitor_type"),
trade_style=item.get("trade_style"),
entry_reason_from_key_signal=entry_reason_from_key_signal,
entry_reason_for_monitor_type=entry_reason_for_monitor_type,
)
try:
_keys = row.keys() if hasattr(row, "keys") else []
except Exception:
@@ -2642,6 +2655,7 @@ def insert_trade_record(
entry_model=entry_model,
key_signal_type=kst,
monitor_type=monitor_type,
trade_style=trade_style,
entry_reason_from_key_signal=entry_reason_from_key_signal,
entry_reason_for_monitor_type=entry_reason_for_monitor_type,
)
+16 -2
View File
@@ -182,6 +182,7 @@ from lib.trade.entry_model_lib import (
order_entry_template_context,
open_position_button_label,
parse_manual_order_style_fields,
resolve_effective_trade_entry_reason,
resolve_trade_record_entry_reason,
trend_manual_entry_reason_count,
)
@@ -2064,8 +2065,20 @@ def to_effective_trade_dict(row):
item["effective_pnl_amount"] = get_effective_trade_field(row, "reviewed_pnl_amount", "pnl_amount", item.get("pnl_amount"))
item["effective_hold_minutes"] = get_effective_trade_field(row, "reviewed_hold_minutes", "hold_minutes", item.get("hold_minutes"))
item["effective_hold_seconds"] = get_effective_trade_field(row, "reviewed_hold_seconds", "hold_seconds", item.get("hold_seconds"))
er_eff = get_effective_trade_field(row, "reviewed_entry_reason", "entry_reason", item.get("entry_reason"))
item["effective_entry_reason"] = (str(er_eff).strip() if er_eff is not None else "") or ""
try:
_er_keys = row.keys() if hasattr(row, "keys") else []
except Exception:
_er_keys = []
reviewed_er = row["reviewed_entry_reason"] if "reviewed_entry_reason" in _er_keys else None
item["effective_entry_reason"] = resolve_effective_trade_entry_reason(
reviewed_entry_reason=reviewed_er,
entry_reason=item.get("entry_reason"),
key_signal_type=(item.get("key_signal_type") or "").strip() or None,
monitor_type=item.get("monitor_type"),
trade_style=item.get("trade_style"),
entry_reason_from_key_signal=entry_reason_from_key_signal,
entry_reason_for_monitor_type=entry_reason_for_monitor_type,
)
try:
_keys = row.keys() if hasattr(row, "keys") else []
except Exception:
@@ -2358,6 +2371,7 @@ def insert_trade_record(
entry_model=entry_model,
key_signal_type=kst,
monitor_type=monitor_type,
trade_style=trade_style,
entry_reason_from_key_signal=entry_reason_from_key_signal,
entry_reason_for_monitor_type=entry_reason_for_monitor_type,
)
+18 -4
View File
@@ -181,6 +181,7 @@ from lib.trade.entry_model_lib import (
order_entry_template_context,
open_position_button_label,
parse_manual_order_style_fields,
resolve_effective_trade_entry_reason,
resolve_trade_record_entry_reason,
trend_manual_entry_reason_count,
)
@@ -2012,8 +2013,20 @@ def to_effective_trade_dict(row):
item["effective_pnl_amount"] = get_effective_trade_field(row, "reviewed_pnl_amount", "pnl_amount", item.get("pnl_amount"))
item["effective_hold_minutes"] = get_effective_trade_field(row, "reviewed_hold_minutes", "hold_minutes", item.get("hold_minutes"))
item["effective_hold_seconds"] = get_effective_trade_field(row, "reviewed_hold_seconds", "hold_seconds", item.get("hold_seconds"))
er_eff = get_effective_trade_field(row, "reviewed_entry_reason", "entry_reason", item.get("entry_reason"))
item["effective_entry_reason"] = (str(er_eff).strip() if er_eff is not None else "") or ""
try:
_er_keys = row.keys() if hasattr(row, "keys") else []
except Exception:
_er_keys = []
reviewed_er = row["reviewed_entry_reason"] if "reviewed_entry_reason" in _er_keys else None
item["effective_entry_reason"] = resolve_effective_trade_entry_reason(
reviewed_entry_reason=reviewed_er,
entry_reason=item.get("entry_reason"),
key_signal_type=(item.get("key_signal_type") or "").strip() or None,
monitor_type=item.get("monitor_type"),
trade_style=item.get("trade_style"),
entry_reason_from_key_signal=entry_reason_from_key_signal,
entry_reason_for_monitor_type=entry_reason_for_monitor_type,
)
try:
_keys = row.keys() if hasattr(row, "keys") else []
except Exception:
@@ -2253,6 +2266,7 @@ def insert_trade_record(
entry_model=entry_model,
key_signal_type=kst,
monitor_type=monitor_type,
trade_style=trade_style,
entry_reason_from_key_signal=entry_reason_from_key_signal,
entry_reason_for_monitor_type=entry_reason_for_monitor_type,
)
@@ -7984,10 +7998,10 @@ def add_order():
tc_en = 0
tc_en, tc_h, tc_at = time_close_insert_values(tc_en, tc_h, opened_at_ms)
conn.execute(
"INSERT INTO order_monitors (symbol, exchange_symbol, direction, trigger_price, stop_loss, initial_stop_loss, take_profit, margin_capital, leverage, trade_style, risk_percent, risk_amount, breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, breakeven_armed, breakeven_price, breakeven_enabled, notional_value, position_ratio, base_amount, order_amount, exchange_order_id, opened_at, opened_at_ms, session_date, monitor_type, time_close_enabled, time_close_hours, time_close_at_ms) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
"INSERT INTO order_monitors (symbol, exchange_symbol, direction, trigger_price, stop_loss, initial_stop_loss, take_profit, margin_capital, leverage, trade_style, entry_model, risk_percent, risk_amount, breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, breakeven_armed, breakeven_price, breakeven_enabled, notional_value, position_ratio, base_amount, order_amount, exchange_order_id, opened_at, opened_at_ms, session_date, monitor_type, time_close_enabled, time_close_hours, time_close_at_ms) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
(
symbol, exchange_symbol, direction, trigger_price, stop_loss, stop_loss, take_profit,
margin_capital, leverage, trade_style, risk_percent_db, risk_amount_final, breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, 0, breakeven_price,
margin_capital, leverage, trade_style, entry_model, risk_percent_db, risk_amount_final, breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, 0, breakeven_price,
breakeven_enabled,
notional_value, position_ratio, base_amount, amount, open_order_id, opened_at_bj, opened_at_ms, trading_day, "下单监控",
tc_en, tc_h, tc_at,
+30
View File
@@ -290,6 +290,7 @@ def resolve_trade_record_entry_reason(
entry_model: Optional[str] = None,
key_signal_type: Optional[str] = None,
monitor_type: Optional[str] = None,
trade_style: Optional[str] = None,
entry_reason_from_key_signal=None,
entry_reason_for_monitor_type=None,
) -> str:
@@ -308,9 +309,38 @@ def resolve_trade_record_entry_reason(
from_mt = (entry_reason_for_monitor_type(monitor_type) or "").strip()
if from_mt:
return from_mt
ts = (trade_style or "").strip().lower()
if ts in ("trend", "swing"):
return trade_style_label_zh(ts)
return ""
def resolve_effective_trade_entry_reason(
*,
reviewed_entry_reason: Optional[str] = None,
entry_reason: Optional[str] = None,
entry_model: Optional[str] = None,
key_signal_type: Optional[str] = None,
monitor_type: Optional[str] = None,
trade_style: Optional[str] = None,
entry_reason_from_key_signal=None,
entry_reason_for_monitor_type=None,
) -> str:
"""交易记录展示/导出用:复盘优先,再回落 entry_model / 关键位 / 策略 / trade_style。"""
for raw in (reviewed_entry_reason, entry_reason):
er = (raw or "").strip()
if er:
return er
return resolve_trade_record_entry_reason(
entry_model=entry_model,
key_signal_type=key_signal_type,
monitor_type=monitor_type,
trade_style=trade_style,
entry_reason_from_key_signal=entry_reason_from_key_signal,
entry_reason_for_monitor_type=entry_reason_for_monitor_type,
)
def enrich_entry_model_display(item: dict) -> dict:
code = normalize_entry_model_code(item.get("entry_model"))
if code:
+6
View File
@@ -127,6 +127,12 @@ class TestEntryModelLib(unittest.TestCase):
er2 = resolve_trade_record_entry_reason(entry_model=ENTRY_MODEL_LAUNCH_A)
self.assertEqual(er2, "启动A")
def test_resolve_entry_reason_trade_style_fallback(self):
er = resolve_trade_record_entry_reason(trade_style="swing")
self.assertEqual(er, "波段单")
er2 = resolve_trade_record_entry_reason(trade_style="trend")
self.assertEqual(er2, "趋势单")
def test_build_trend_div_journal_options(self):
opts = build_trend_div_entry_reason_options(("趋势回调",))
self.assertEqual(opts[:5], ("启动A", "启动B", "大分歧A", "大分歧B", "小分歧"))