修复okx止盈止损
This commit is contained in:
@@ -21,6 +21,22 @@ def _coerce_float(*values) -> float | None:
|
||||
return None
|
||||
|
||||
|
||||
def _symbol_base_coin(symbol: str) -> str:
|
||||
"""ZEC/USDT:USDT、ZEC-USDT-SWAP 等统一为标的币 ZEC。"""
|
||||
s = (symbol or "").strip().upper()
|
||||
if not s:
|
||||
return ""
|
||||
if "-SWAP" in s:
|
||||
s = s.replace("-SWAP", "")
|
||||
if "-" in s:
|
||||
return s.split("-", 1)[0]
|
||||
if "/" in s:
|
||||
return s.split("/", 1)[0]
|
||||
if ":" in s:
|
||||
return s.split(":", 1)[0]
|
||||
return s
|
||||
|
||||
|
||||
def symbols_match(position_symbol: str, order_symbol: str) -> bool:
|
||||
a = (position_symbol or "").strip().upper()
|
||||
b = (order_symbol or "").strip().upper()
|
||||
@@ -28,6 +44,9 @@ def symbols_match(position_symbol: str, order_symbol: str) -> bool:
|
||||
return False
|
||||
if a == b:
|
||||
return True
|
||||
ba, bb = _symbol_base_coin(a), _symbol_base_coin(b)
|
||||
if ba and bb and ba == bb:
|
||||
return True
|
||||
for suf in (":USDT", "/USDT:USDT", "/USDT"):
|
||||
a2 = a.replace(suf, "")
|
||||
b2 = b.replace(suf, "")
|
||||
@@ -54,7 +73,7 @@ def _is_conditional_type(typ: str) -> bool:
|
||||
t = (typ or "").upper()
|
||||
if not t:
|
||||
return False
|
||||
keys = ("STOP", "TAKE_PROFIT", "TRAIL", "TRIGGER", "CONDITIONAL")
|
||||
keys = ("STOP", "TAKE_PROFIT", "TRAIL", "TRIGGER", "CONDITIONAL", "OCO")
|
||||
return any(k in t for k in keys)
|
||||
|
||||
|
||||
@@ -90,7 +109,7 @@ def _normalize_raw_order(order: dict, *, channel: str) -> dict[str, Any] | None:
|
||||
oid = order.get("id") or info.get("algoId") or info.get("orderId") or info.get("ordId")
|
||||
if oid is None:
|
||||
return None
|
||||
sym = str(order.get("symbol") or info.get("symbol") or "")
|
||||
sym = str(order.get("symbol") or info.get("symbol") or info.get("instId") or "")
|
||||
typ = _order_type_str(order)
|
||||
side = str(order.get("side") or info.get("side") or "").lower()
|
||||
reduce_only = order.get("reduceOnly")
|
||||
@@ -137,6 +156,42 @@ def _normalize_raw_order(order: dict, *, channel: str) -> dict[str, Any] | None:
|
||||
}
|
||||
|
||||
|
||||
def _okx_normalize_orders(raw: dict, channel: str) -> list[dict[str, Any]]:
|
||||
"""OKX 算法单常一笔同时含 SL+TP,拆成两条供中控「交易所止盈止损」展示。"""
|
||||
n = _normalize_raw_order(dict(raw), channel=channel)
|
||||
if not n:
|
||||
return []
|
||||
info = raw.get("info") or {}
|
||||
if not isinstance(info, dict):
|
||||
info = {}
|
||||
sl_trig = _coerce_float(info.get("slTriggerPx"), raw.get("stopLossPrice"))
|
||||
tp_trig = _coerce_float(info.get("tpTriggerPx"), raw.get("takeProfitPrice"))
|
||||
if sl_trig is None or tp_trig is None:
|
||||
return [n]
|
||||
base_id = n["id"]
|
||||
rows: list[dict[str, Any]] = []
|
||||
for role, px, lbl in (
|
||||
("sl", sl_trig, f"止损 {sl_trig:g}"),
|
||||
("tp", tp_trig, f"止盈 {tp_trig:g}"),
|
||||
):
|
||||
row = dict(n)
|
||||
row["id"] = f"{base_id}:{role}"
|
||||
row["algo_id"] = base_id
|
||||
row["label"] = lbl
|
||||
row["trigger_price"] = px
|
||||
row["category"] = "conditional"
|
||||
row["channel"] = channel
|
||||
rows.append(row)
|
||||
return rows
|
||||
|
||||
|
||||
def _okx_algo_order_id(order_id: str) -> str:
|
||||
oid = str(order_id or "")
|
||||
if ":" in oid:
|
||||
return oid.split(":", 1)[0]
|
||||
return oid
|
||||
|
||||
|
||||
def _binance_list(ex: Any, symbol: str | None) -> list[dict]:
|
||||
ex.load_markets()
|
||||
out: list[dict] = []
|
||||
@@ -227,14 +282,12 @@ def _okx_list(ex: Any, symbol: str | None) -> list[dict]:
|
||||
try:
|
||||
for o in fetch_okx_all_open_orders(ex, sym):
|
||||
ch = "algo" if _is_conditional_type(_order_type_str(o)) else "regular"
|
||||
n = _normalize_raw_order(dict(o), channel=ch)
|
||||
if not n:
|
||||
continue
|
||||
key = (n["id"], n.get("channel") or ch)
|
||||
if key in seen:
|
||||
continue
|
||||
seen.add(key)
|
||||
out.append(n)
|
||||
for n in _okx_normalize_orders(dict(o), channel=ch):
|
||||
key = (n["id"], n.get("channel") or ch)
|
||||
if key in seen:
|
||||
continue
|
||||
seen.add(key)
|
||||
out.append(n)
|
||||
except Exception:
|
||||
pass
|
||||
return out
|
||||
@@ -345,7 +398,8 @@ def cancel_order(
|
||||
params = None
|
||||
if kind == "gate" and ch == "algo":
|
||||
params = _gate_trigger_params(ex)
|
||||
ex.cancel_order(str(order_id), unified, params)
|
||||
oid = _okx_algo_order_id(order_id) if kind == "okx" else str(order_id)
|
||||
ex.cancel_order(oid, unified, params)
|
||||
|
||||
|
||||
def cancel_orders_for_symbol(
|
||||
|
||||
Reference in New Issue
Block a user