修改okx挂单
This commit is contained in:
+60
-13
@@ -2481,21 +2481,44 @@ def cancel_okx_swap_open_orders(exchange_symbol):
|
|||||||
|
|
||||||
|
|
||||||
def _okx_place_tp_sl_orders(exchange_symbol, direction, amount, stop_loss, take_profit):
|
def _okx_place_tp_sl_orders(exchange_symbol, direction, amount, stop_loss, take_profit):
|
||||||
|
"""
|
||||||
|
为已有持仓挂条件止盈/止损(算法单)。
|
||||||
|
勿在同一笔 reduce-only 市价单上同时带 stopLoss+takeProfit,OKX/ccxt 可能当成立即全平。
|
||||||
|
"""
|
||||||
ensure_markets_loaded()
|
ensure_markets_loaded()
|
||||||
close_side = "sell" if direction == "long" else "buy"
|
close_side = "sell" if direction == "long" else "buy"
|
||||||
amt = float(exchange.amount_to_precision(exchange_symbol, float(amount)))
|
amt = float(exchange.amount_to_precision(exchange_symbol, float(amount)))
|
||||||
if amt <= 0:
|
if amt <= 0:
|
||||||
raise RuntimeError("止盈止损:可平数量经精度舍入后为 0")
|
raise RuntimeError("止盈止损:可平数量经精度舍入后为 0")
|
||||||
params = build_okx_order_params(direction, reduce_only=True)
|
base = build_okx_order_params(direction, reduce_only=True)
|
||||||
params["stopLoss"] = {
|
sl_px = float(stop_loss)
|
||||||
"triggerPrice": _okx_algo_trigger_price_str(exchange_symbol, stop_loss),
|
tp_px = float(take_profit)
|
||||||
"type": "market",
|
last_err = None
|
||||||
}
|
for attempt in range(6):
|
||||||
params["takeProfit"] = {
|
try:
|
||||||
"triggerPrice": _okx_algo_trigger_price_str(exchange_symbol, take_profit),
|
exchange.create_order(
|
||||||
"type": "market",
|
exchange_symbol,
|
||||||
}
|
"market",
|
||||||
exchange.create_order(exchange_symbol, "market", close_side, amt, None, params)
|
close_side,
|
||||||
|
amt,
|
||||||
|
None,
|
||||||
|
{**base, "stopLossPrice": sl_px},
|
||||||
|
)
|
||||||
|
time.sleep(0.05)
|
||||||
|
exchange.create_order(
|
||||||
|
exchange_symbol,
|
||||||
|
"market",
|
||||||
|
close_side,
|
||||||
|
amt,
|
||||||
|
None,
|
||||||
|
{**base, "takeProfitPrice": tp_px},
|
||||||
|
)
|
||||||
|
return
|
||||||
|
except Exception as e:
|
||||||
|
last_err = e
|
||||||
|
cancel_okx_swap_open_orders(exchange_symbol)
|
||||||
|
time.sleep(0.2 * (attempt + 1))
|
||||||
|
raise RuntimeError(f"OKX 未接受止盈/止损条件单:{last_err}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -3756,7 +3779,15 @@ def fib_limit_order_status(exchange_symbol, order_id):
|
|||||||
return "unknown"
|
return "unknown"
|
||||||
|
|
||||||
|
|
||||||
def place_fib_limit_order(exchange_symbol, direction, amount, leverage, limit_price):
|
def place_fib_limit_order(
|
||||||
|
exchange_symbol,
|
||||||
|
direction,
|
||||||
|
amount,
|
||||||
|
leverage,
|
||||||
|
limit_price,
|
||||||
|
stop_loss=None,
|
||||||
|
take_profit=None,
|
||||||
|
):
|
||||||
ensure_markets_loaded()
|
ensure_markets_loaded()
|
||||||
exchange.set_leverage(leverage, exchange_symbol)
|
exchange.set_leverage(leverage, exchange_symbol)
|
||||||
side = "buy" if direction == "long" else "sell"
|
side = "buy" if direction == "long" else "sell"
|
||||||
@@ -3764,6 +3795,15 @@ def place_fib_limit_order(exchange_symbol, direction, amount, leverage, limit_pr
|
|||||||
if price is None or price <= 0:
|
if price is None or price <= 0:
|
||||||
raise ValueError("挂单价无效")
|
raise ValueError("挂单价无效")
|
||||||
params = build_okx_order_params(direction, reduce_only=False)
|
params = build_okx_order_params(direction, reduce_only=False)
|
||||||
|
if stop_loss and take_profit:
|
||||||
|
params["attachAlgoOrds"] = [
|
||||||
|
{
|
||||||
|
"tpTriggerPx": _okx_algo_trigger_price_str(exchange_symbol, take_profit),
|
||||||
|
"tpOrdPx": "-1",
|
||||||
|
"slTriggerPx": _okx_algo_trigger_price_str(exchange_symbol, stop_loss),
|
||||||
|
"slOrdPx": "-1",
|
||||||
|
}
|
||||||
|
]
|
||||||
return exchange.create_order(exchange_symbol, "limit", side, amount, price, params)
|
return exchange.create_order(exchange_symbol, "limit", side, amount, price, params)
|
||||||
|
|
||||||
|
|
||||||
@@ -3933,8 +3973,13 @@ def _finalize_fib_key_fill(conn, row):
|
|||||||
return
|
return
|
||||||
tpsl_attached = False
|
tpsl_attached = False
|
||||||
try:
|
try:
|
||||||
_okx_place_tp_sl_orders(ex_sym, direction, amount, sl, tp)
|
slots = fetch_exchange_tpsl_slots(ex_sym, direction, plan_sl=sl, plan_tp=tp)
|
||||||
|
if slots.get("sl") and slots.get("tp"):
|
||||||
tpsl_attached = True
|
tpsl_attached = True
|
||||||
|
else:
|
||||||
|
_okx_place_tp_sl_orders(ex_sym, direction, amount, sl, tp)
|
||||||
|
slots2 = fetch_exchange_tpsl_slots(ex_sym, direction, plan_sl=sl, plan_tp=tp)
|
||||||
|
tpsl_attached = bool(slots2.get("sl") and slots2.get("tp"))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = (
|
msg = (
|
||||||
f"# ❌ {symbol} 斐波成交后挂 TP/SL 失败\n"
|
f"# ❌ {symbol} 斐波成交后挂 TP/SL 失败\n"
|
||||||
@@ -4079,7 +4124,9 @@ def _add_fib_key_monitor(conn, symbol, direction_sel, mt, upper_px, lower_px, br
|
|||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
amount, _ = prepare_order_amount(ex_sym, margin_capital, leverage, entry)
|
amount, _ = prepare_order_amount(ex_sym, margin_capital, leverage, entry)
|
||||||
order_resp = place_fib_limit_order(ex_sym, direction_sel, amount, leverage, entry)
|
order_resp = place_fib_limit_order(
|
||||||
|
ex_sym, direction_sel, amount, leverage, entry, stop_loss=sl, take_profit=tp
|
||||||
|
)
|
||||||
oid = str(order_resp.get("id") or "")
|
oid = str(order_resp.get("id") or "")
|
||||||
if not oid:
|
if not oid:
|
||||||
return False, "交易所未返回限价单 ID"
|
return False, "交易所未返回限价单 ID"
|
||||||
|
|||||||
@@ -514,12 +514,35 @@ def _okx_place_tp_sl(
|
|||||||
amt = float(ex.amount_to_precision(symbol, float(amount)))
|
amt = float(ex.amount_to_precision(symbol, float(amount)))
|
||||||
if amt <= 0:
|
if amt <= 0:
|
||||||
raise RuntimeError("止盈止损:可平数量经精度舍入后为 0")
|
raise RuntimeError("止盈止损:可平数量经精度舍入后为 0")
|
||||||
params = _okx_order_params(direction, reduce_only=True, pos_mode=pos_mode, td_mode=td_mode)
|
base = _okx_order_params(direction, reduce_only=True, pos_mode=pos_mode, td_mode=td_mode)
|
||||||
sl_s = ex.price_to_precision(symbol, float(stop_loss))
|
sl_px = float(stop_loss)
|
||||||
tp_s = ex.price_to_precision(symbol, float(take_profit))
|
tp_px = float(take_profit)
|
||||||
params["stopLoss"] = {"triggerPrice": sl_s, "type": "market"}
|
last_err: Exception | None = None
|
||||||
params["takeProfit"] = {"triggerPrice": tp_s, "type": "market"}
|
for attempt in range(6):
|
||||||
ex.create_order(symbol, "market", close_side, amt, None, params)
|
try:
|
||||||
|
ex.create_order(
|
||||||
|
symbol,
|
||||||
|
"market",
|
||||||
|
close_side,
|
||||||
|
amt,
|
||||||
|
None,
|
||||||
|
{**base, "stopLossPrice": sl_px},
|
||||||
|
)
|
||||||
|
time.sleep(0.05)
|
||||||
|
ex.create_order(
|
||||||
|
symbol,
|
||||||
|
"market",
|
||||||
|
close_side,
|
||||||
|
amt,
|
||||||
|
None,
|
||||||
|
{**base, "takeProfitPrice": tp_px},
|
||||||
|
)
|
||||||
|
return
|
||||||
|
except Exception as e:
|
||||||
|
last_err = e
|
||||||
|
cancel_orders_for_symbol(ex, "okx", symbol, scope="conditional")
|
||||||
|
time.sleep(0.2 * (attempt + 1))
|
||||||
|
raise RuntimeError(f"OKX 未接受止盈/止损条件单:{last_err}")
|
||||||
|
|
||||||
|
|
||||||
def _gate_tpsl_env() -> tuple[bool, int, int, str]:
|
def _gate_tpsl_env() -> tuple[bool, int, int, str]:
|
||||||
|
|||||||
Reference in New Issue
Block a user