修复读取历史仓位

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"))
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 ""
reviewed_pnl = get_effective_trade_field(row, "reviewed_pnl_amount", "pnl_amount", None)
has_reviewed_pnl = reviewed_pnl is not None and str(reviewed_pnl).strip() != ""
try:
_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")
if not has_reviewed_pnl and ex_pnl is not None and str(ex_pnl).strip() != "":
try:
@@ -4508,25 +4512,21 @@ def _coerce_ts_ms(val):
if v > 1e12:
return int(v)
if v > 1e9:
return int(v)
return int(v * 1000.0)
return int(v * 1000.0)
def _unified_symbol_for_match(symbol_str):
if not symbol_str:
return ""
s = str(symbol_str).strip()
s = (symbol_str or "").strip().upper()
if not s:
return ""
try:
return normalize_exchange_symbol(s).split(":")[0]
except Exception:
x = s.upper().replace(" ", "")
if "/" in x:
return x.split(":")[0]
if x.endswith("USDT") and len(x) > 4:
return f"{x[:-4]}/USDT"
return x
if ":" in s:
s = s.split(":")[0]
if "_" in s and "/" not in s:
s = s.replace("_", "/")
if s.endswith("USDT") and "/" not in s and len(s) > 4:
s = f"{s[:-4]}/USDT"
return s
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"))
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 ""
reviewed_pnl = get_effective_trade_field(row, "reviewed_pnl_amount", "pnl_amount", None)
has_reviewed_pnl = reviewed_pnl is not None and str(reviewed_pnl).strip() != ""
try:
_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")
if not has_reviewed_pnl and ex_pnl is not None and str(ex_pnl).strip() != "":
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):
if not opened_at_str:
return None
try:
dt = datetime.strptime(str(opened_at_str).strip()[:19], "%Y-%m-%d %H:%M:%S")
except ValueError:
dt = parse_dt_for_trading_day(opened_at_str)
if dt is None:
return None
try:
aware = dt.replace(tzinfo=APP_TZ)
@@ -4651,25 +4654,22 @@ def _coerce_ts_ms(val):
if v > 1e12:
return int(v)
if v > 1e9:
return int(v)
return int(v * 1000.0)
return int(v * 1000.0)
def _unified_symbol_for_match(symbol_str):
if not symbol_str:
return ""
s = str(symbol_str).strip()
"""统一 ETH/USDT:USDT、ETH_USDT、ETH/USDT 便于与 trade_records 比对。"""
s = (symbol_str or "").strip().upper()
if not s:
return ""
try:
return normalize_exchange_symbol(s).split(":")[0]
except Exception:
x = s.upper().replace(" ", "")
if "/" in x:
return x.split(":")[0]
if x.endswith("USDT") and len(x) > 4:
return f"{x[:-4]}/USDT"
return x
if ":" in s:
s = s.split(":")[0]
if "_" in s and "/" not in s:
s = s.replace("_", "/")
if s.endswith("USDT") and "/" not in s and len(s) > 4:
s = f"{s[:-4]}/USDT"
return s
def exchange_position_sync_since_ms():
@@ -4696,7 +4696,11 @@ def _normalize_gate_position_history_entry(p):
return None
info = p.get("info") 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"):
sz = info.get("accum_size") if info.get("accum_size") is not None else info.get("size")
try:
@@ -4780,11 +4784,11 @@ def sync_trade_records_from_exchange(conn):
return
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
WHERE (exchange_sync_key IS NULL OR TRIM(exchange_sync_key) = '')
ORDER BY id DESC
LIMIT 120
LIMIT 200
"""
).fetchall()
if not candidates:
@@ -4825,7 +4829,7 @@ def sync_trade_records_from_exchange(conn):
if best_d is None or d < best_d:
best_d = d
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
sk = best["sync_key"]
if sk in used: