修复读取历史仓位

This commit is contained in:
dekun
2026-05-17 16:39:10 +08:00
parent 5a59246e18
commit 56f58c2b52
2 changed files with 41 additions and 37 deletions
+15 -15
View File
@@ -1732,8 +1732,12 @@ def to_effective_trade_dict(row):
item["effective_hold_seconds"] = get_effective_trade_field(row, "reviewed_hold_seconds", "hold_seconds", item.get("hold_seconds")) 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")) 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 "" item["effective_entry_reason"] = (str(er_eff).strip() if er_eff is not None else "") or ""
reviewed_pnl = get_effective_trade_field(row, "reviewed_pnl_amount", "pnl_amount", None) try:
has_reviewed_pnl = reviewed_pnl is not None and str(reviewed_pnl).strip() != "" _keys = row.keys() if hasattr(row, "keys") else []
except Exception:
_keys = []
_reviewed_pnl_raw = row["reviewed_pnl_amount"] if "reviewed_pnl_amount" in _keys else None
has_reviewed_pnl = _reviewed_pnl_raw is not None and str(_reviewed_pnl_raw).strip() != ""
ex_pnl = item.get("exchange_realized_pnl") ex_pnl = item.get("exchange_realized_pnl")
if not has_reviewed_pnl and ex_pnl is not None and str(ex_pnl).strip() != "": if not has_reviewed_pnl and ex_pnl is not None and str(ex_pnl).strip() != "":
try: try:
@@ -4508,25 +4512,21 @@ def _coerce_ts_ms(val):
if v > 1e12: if v > 1e12:
return int(v) return int(v)
if v > 1e9: if v > 1e9:
return int(v) return int(v * 1000.0)
return int(v * 1000.0) return int(v * 1000.0)
def _unified_symbol_for_match(symbol_str): def _unified_symbol_for_match(symbol_str):
if not symbol_str: s = (symbol_str or "").strip().upper()
return ""
s = str(symbol_str).strip()
if not s: if not s:
return "" return ""
try: if ":" in s:
return normalize_exchange_symbol(s).split(":")[0] s = s.split(":")[0]
except Exception: if "_" in s and "/" not in s:
x = s.upper().replace(" ", "") s = s.replace("_", "/")
if "/" in x: if s.endswith("USDT") and "/" not in s and len(s) > 4:
return x.split(":")[0] s = f"{s[:-4]}/USDT"
if x.endswith("USDT") and len(x) > 4: return s
return f"{x[:-4]}/USDT"
return x
def exchange_position_sync_since_ms(): def exchange_position_sync_since_ms():
+26 -22
View File
@@ -1691,8 +1691,12 @@ def to_effective_trade_dict(row):
item["effective_hold_seconds"] = get_effective_trade_field(row, "reviewed_hold_seconds", "hold_seconds", item.get("hold_seconds")) 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")) 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 "" item["effective_entry_reason"] = (str(er_eff).strip() if er_eff is not None else "") or ""
reviewed_pnl = get_effective_trade_field(row, "reviewed_pnl_amount", "pnl_amount", None) try:
has_reviewed_pnl = reviewed_pnl is not None and str(reviewed_pnl).strip() != "" _keys = row.keys() if hasattr(row, "keys") else []
except Exception:
_keys = []
_reviewed_pnl_raw = row["reviewed_pnl_amount"] if "reviewed_pnl_amount" in _keys else None
has_reviewed_pnl = _reviewed_pnl_raw is not None and str(_reviewed_pnl_raw).strip() != ""
ex_pnl = item.get("exchange_realized_pnl") ex_pnl = item.get("exchange_realized_pnl")
if not has_reviewed_pnl and ex_pnl is not None and str(ex_pnl).strip() != "": if not has_reviewed_pnl and ex_pnl is not None and str(ex_pnl).strip() != "":
try: try:
@@ -3246,9 +3250,8 @@ def try_persist_exchange_margin_for_order(conn, order_id, exchange_symbol, direc
def opened_at_str_to_ms(opened_at_str): def opened_at_str_to_ms(opened_at_str):
if not opened_at_str: if not opened_at_str:
return None return None
try: dt = parse_dt_for_trading_day(opened_at_str)
dt = datetime.strptime(str(opened_at_str).strip()[:19], "%Y-%m-%d %H:%M:%S") if dt is None:
except ValueError:
return None return None
try: try:
aware = dt.replace(tzinfo=APP_TZ) aware = dt.replace(tzinfo=APP_TZ)
@@ -4651,25 +4654,22 @@ def _coerce_ts_ms(val):
if v > 1e12: if v > 1e12:
return int(v) return int(v)
if v > 1e9: if v > 1e9:
return int(v) return int(v * 1000.0)
return int(v * 1000.0) return int(v * 1000.0)
def _unified_symbol_for_match(symbol_str): def _unified_symbol_for_match(symbol_str):
if not symbol_str: """统一 ETH/USDT:USDT、ETH_USDT、ETH/USDT 便于与 trade_records 比对。"""
return "" s = (symbol_str or "").strip().upper()
s = str(symbol_str).strip()
if not s: if not s:
return "" return ""
try: if ":" in s:
return normalize_exchange_symbol(s).split(":")[0] s = s.split(":")[0]
except Exception: if "_" in s and "/" not in s:
x = s.upper().replace(" ", "") s = s.replace("_", "/")
if "/" in x: if s.endswith("USDT") and "/" not in s and len(s) > 4:
return x.split(":")[0] s = f"{s[:-4]}/USDT"
if x.endswith("USDT") and len(x) > 4: return s
return f"{x[:-4]}/USDT"
return x
def exchange_position_sync_since_ms(): def exchange_position_sync_since_ms():
@@ -4696,7 +4696,11 @@ def _normalize_gate_position_history_entry(p):
return None return None
info = p.get("info") or {} info = p.get("info") or {}
sym = p.get("symbol") or "" sym = p.get("symbol") or ""
side = (p.get("side") or "").strip().lower() if not sym:
c_alt = str(info.get("contract") or "").strip()
if c_alt:
sym = c_alt.replace("_", "/")
side = (p.get("side") or info.get("side") or "").strip().lower()
if side not in ("long", "short"): if side not in ("long", "short"):
sz = info.get("accum_size") if info.get("accum_size") is not None else info.get("size") sz = info.get("accum_size") if info.get("accum_size") is not None else info.get("size")
try: try:
@@ -4780,11 +4784,11 @@ def sync_trade_records_from_exchange(conn):
return return
candidates = conn.execute( candidates = conn.execute(
""" """
SELECT id, symbol, direction, closed_at, opened_at, opened_at_ms SELECT id, symbol, direction, closed_at, closed_at_ms, opened_at, opened_at_ms
FROM trade_records FROM trade_records
WHERE (exchange_sync_key IS NULL OR TRIM(exchange_sync_key) = '') WHERE (exchange_sync_key IS NULL OR TRIM(exchange_sync_key) = '')
ORDER BY id DESC ORDER BY id DESC
LIMIT 120 LIMIT 200
""" """
).fetchall() ).fetchall()
if not candidates: if not candidates:
@@ -4825,7 +4829,7 @@ def sync_trade_records_from_exchange(conn):
if best_d is None or d < best_d: if best_d is None or d < best_d:
best_d = d best_d = d
best = h best = h
if best is None or best_d is None or best_d > 25 * 60 * 1000: if best is None or best_d is None or best_d > 90 * 60 * 1000:
continue continue
sk = best["sync_key"] sk = best["sync_key"]
if sk in used: if sk in used: