修复读取历史仓位
This commit is contained in:
+26
-22
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user