修复okx止盈止损
This commit is contained in:
+77
-46
@@ -45,6 +45,7 @@ from fib_key_monitor_lib import (
|
||||
key_signal_type_for_trade_record,
|
||||
stored_key_signal_type,
|
||||
)
|
||||
from okx_orders_lib import fetch_okx_all_open_orders
|
||||
from key_sl_tp_lib import (
|
||||
breakeven_enabled_from_row,
|
||||
normalize_sl_tp_mode,
|
||||
@@ -2467,7 +2468,7 @@ def cancel_okx_swap_open_orders(exchange_symbol):
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
for o in exchange.fetch_open_orders(exchange_symbol) or []:
|
||||
for o in fetch_okx_all_open_orders(exchange, exchange_symbol):
|
||||
oid = o.get("id")
|
||||
if oid is None:
|
||||
continue
|
||||
@@ -2616,26 +2617,52 @@ def _resolve_tpsl_prices_for_manual(direction, live_price, sltp_mode, data):
|
||||
return stop_loss, take_profit
|
||||
|
||||
|
||||
def _okx_tpsl_slot_from_order(order, exchange_symbol):
|
||||
def _okx_tpsl_slot_build(exchange_symbol, order_id, trigger_price, order_type=""):
|
||||
if trigger_price is None or order_id is None:
|
||||
return None
|
||||
sym = exchange_symbol.replace(":USDT", "").replace("/USDT:USDT", "")
|
||||
return {
|
||||
"order_id": str(order_id),
|
||||
"trigger_price": float(trigger_price),
|
||||
"trigger_display": format_price_for_symbol(sym, trigger_price),
|
||||
"type": str(order_type or ""),
|
||||
}
|
||||
|
||||
|
||||
def _okx_tpsl_slots_from_order(order, exchange_symbol):
|
||||
"""从单笔 OKX 订单解析 SL/TP(算法单常同时带 slTriggerPx 与 tpTriggerPx)。"""
|
||||
if not isinstance(order, dict):
|
||||
return None, None
|
||||
info = order.get("info") or {}
|
||||
if not isinstance(info, dict):
|
||||
info = {}
|
||||
oid = order.get("id") or info.get("algoId") or info.get("ordId")
|
||||
trig = _coerce_float(
|
||||
info.get("slTriggerPx"),
|
||||
info.get("tpTriggerPx"),
|
||||
if oid is None:
|
||||
return None, None
|
||||
ord_type = str(order.get("type") or info.get("ordType") or "")
|
||||
sl_px = _coerce_float(
|
||||
order.get("stopLossPrice"),
|
||||
info.get("slTriggerPx"),
|
||||
info.get("slOrdPx"),
|
||||
)
|
||||
tp_px = _coerce_float(
|
||||
order.get("takeProfitPrice"),
|
||||
info.get("tpTriggerPx"),
|
||||
info.get("tpOrdPx"),
|
||||
)
|
||||
sl_slot = _okx_tpsl_slot_build(exchange_symbol, oid, sl_px, ord_type) if sl_px is not None else None
|
||||
tp_slot = _okx_tpsl_slot_build(exchange_symbol, oid, tp_px, ord_type) if tp_px is not None else None
|
||||
if sl_slot or tp_slot:
|
||||
return sl_slot, tp_slot
|
||||
trig = _coerce_float(
|
||||
info.get("triggerPx"),
|
||||
order.get("triggerPrice"),
|
||||
order.get("stopPrice"),
|
||||
)
|
||||
if trig is None:
|
||||
return None
|
||||
return {
|
||||
"order_id": str(oid) if oid is not None else None,
|
||||
"trigger_price": float(trig),
|
||||
"trigger_display": format_price_for_symbol(
|
||||
exchange_symbol.replace(":USDT", "").replace("/USDT:USDT", ""),
|
||||
trig,
|
||||
),
|
||||
"type": str(order.get("type") or info.get("ordType") or ""),
|
||||
}
|
||||
return None, None
|
||||
one = _okx_tpsl_slot_build(exchange_symbol, oid, trig, ord_type)
|
||||
return one, None
|
||||
|
||||
|
||||
def fetch_exchange_tpsl_slots(exchange_symbol, direction, plan_sl=None, plan_tp=None):
|
||||
@@ -2647,35 +2674,18 @@ def fetch_exchange_tpsl_slots(exchange_symbol, direction, plan_sl=None, plan_tp=
|
||||
return slots
|
||||
try:
|
||||
ensure_markets_loaded()
|
||||
ambiguous = []
|
||||
for order in exchange.fetch_open_orders(exchange_symbol) or []:
|
||||
slot = _okx_tpsl_slot_from_order(order, exchange_symbol)
|
||||
if not slot or not slot.get("order_id"):
|
||||
continue
|
||||
trig = slot.get("trigger_price")
|
||||
if plan_sl is not None and plan_tp is not None:
|
||||
try:
|
||||
role = "sl" if abs(trig - float(plan_sl)) <= abs(trig - float(plan_tp)) else "tp"
|
||||
except Exception:
|
||||
role = None
|
||||
elif plan_sl is not None:
|
||||
role = "sl"
|
||||
elif plan_tp is not None:
|
||||
role = "tp"
|
||||
else:
|
||||
ambiguous.append(slot)
|
||||
continue
|
||||
if role in ("sl", "tp") and slots[role] is None:
|
||||
slots[role] = slot
|
||||
for slot in ambiguous:
|
||||
trig = slot.get("trigger_price")
|
||||
if trig is None:
|
||||
continue
|
||||
try:
|
||||
plan_sl_f = float(plan_sl) if plan_sl is not None else None
|
||||
plan_tp_f = float(plan_tp) if plan_tp is not None else None
|
||||
except Exception:
|
||||
plan_sl_f = plan_tp_f = None
|
||||
plan_sl_f = plan_tp_f = None
|
||||
try:
|
||||
if plan_sl is not None:
|
||||
plan_sl_f = float(plan_sl)
|
||||
if plan_tp is not None:
|
||||
plan_tp_f = float(plan_tp)
|
||||
except Exception:
|
||||
plan_sl_f = plan_tp_f = None
|
||||
|
||||
def assign_role(trig, slot):
|
||||
if trig is None or slot is None:
|
||||
return
|
||||
if plan_sl_f is not None and plan_tp_f is not None:
|
||||
role = "sl" if abs(trig - plan_sl_f) <= abs(trig - plan_tp_f) else "tp"
|
||||
elif plan_sl_f is not None:
|
||||
@@ -2683,9 +2693,30 @@ def fetch_exchange_tpsl_slots(exchange_symbol, direction, plan_sl=None, plan_tp=
|
||||
elif plan_tp_f is not None:
|
||||
role = "tp"
|
||||
else:
|
||||
continue
|
||||
return
|
||||
if slots[role] is None:
|
||||
slots[role] = slot
|
||||
|
||||
for order in fetch_okx_all_open_orders(exchange, exchange_symbol):
|
||||
sl_slot, tp_slot = _okx_tpsl_slots_from_order(order, exchange_symbol)
|
||||
if sl_slot and slots["sl"] is None:
|
||||
slots["sl"] = sl_slot
|
||||
if tp_slot and slots["tp"] is None:
|
||||
slots["tp"] = tp_slot
|
||||
if sl_slot or tp_slot:
|
||||
continue
|
||||
info = order.get("info") or {}
|
||||
oid = order.get("id") or info.get("algoId")
|
||||
trig = _coerce_float(info.get("triggerPx"), order.get("triggerPrice"))
|
||||
if oid is None or trig is None:
|
||||
continue
|
||||
slot = _okx_tpsl_slot_build(
|
||||
exchange_symbol,
|
||||
oid,
|
||||
trig,
|
||||
str(order.get("type") or info.get("ordType") or ""),
|
||||
)
|
||||
assign_role(trig, slot)
|
||||
except Exception:
|
||||
pass
|
||||
return slots
|
||||
@@ -3717,7 +3748,7 @@ def fib_limit_order_status(exchange_symbol, order_id):
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
for o in exchange.fetch_open_orders(exchange_symbol) or []:
|
||||
for o in fetch_okx_all_open_orders(exchange, exchange_symbol):
|
||||
if str(o.get("id")) == oid:
|
||||
return "open"
|
||||
except Exception:
|
||||
|
||||
Reference in New Issue
Block a user