72f0090fb8
Gate build_gate_order_params returns {} which is falsy; params or None broke trend_market_add with NoneType is not iterable while first-leg place_exchange_order worked.
Co-authored-by: Cursor <cursoragent@cursor.com>
98 lines
4.2 KiB
Python
98 lines
4.2 KiB
Python
"""趋势回调:各交易所止损刷新、市价加/平仓(通过 app 模块能力探测)。"""
|
|
from __future__ import annotations
|
|
|
|
import time
|
|
from typing import Any
|
|
|
|
|
|
def _m(cfg: dict) -> Any:
|
|
return cfg["app_module"]
|
|
|
|
|
|
def trend_refresh_stop_only(cfg: dict, exchange_symbol: str, direction: str, stop_loss: float) -> None:
|
|
m = _m(cfg)
|
|
if hasattr(m, "_gate_place_stop_loss_only_position"):
|
|
if hasattr(m, "cancel_gate_swap_trigger_orders"):
|
|
m.cancel_gate_swap_trigger_orders(exchange_symbol)
|
|
m._gate_place_stop_loss_only_position(exchange_symbol, direction, stop_loss)
|
|
return
|
|
if hasattr(m, "_binance_place_stop_loss_only"):
|
|
m._binance_place_stop_loss_only(exchange_symbol, direction, stop_loss)
|
|
return
|
|
if hasattr(m, "_okx_place_stop_loss_only"):
|
|
m._okx_place_stop_loss_only(exchange_symbol, direction, stop_loss)
|
|
return
|
|
raise RuntimeError("当前实例未配置趋势回调止损挂单能力")
|
|
|
|
|
|
def trend_market_add(cfg: dict, exchange_symbol: str, direction: str, contracts: float, leverage: int):
|
|
m = _m(cfg)
|
|
ex = m.exchange
|
|
m.ensure_markets_loaded()
|
|
ex.set_leverage(int(leverage), exchange_symbol)
|
|
side = "buy" if direction == "long" else "sell"
|
|
if hasattr(m, "build_gate_order_params"):
|
|
params = m.build_gate_order_params(direction, reduce_only=False)
|
|
elif hasattr(m, "build_binance_order_params"):
|
|
params = m.build_binance_order_params(direction, reduce_only=False)
|
|
elif hasattr(m, "build_okx_order_params"):
|
|
params = m.build_okx_order_params(direction, reduce_only=False)
|
|
else:
|
|
params = {}
|
|
order_params = params if params is not None else {}
|
|
return ex.create_order(exchange_symbol, "market", side, float(contracts), None, order_params)
|
|
|
|
|
|
def trend_market_close(cfg: dict, exchange_symbol: str, direction: str, pos_qty: float, leverage: int):
|
|
m = _m(cfg)
|
|
ex = m.exchange
|
|
m.ensure_markets_loaded()
|
|
ex.set_leverage(int(leverage), exchange_symbol)
|
|
side = "sell" if direction == "long" else "buy"
|
|
amt = float(ex.amount_to_precision(exchange_symbol, float(pos_qty)))
|
|
if hasattr(m, "close_exchange_order"):
|
|
row = {
|
|
"exchange_symbol": exchange_symbol,
|
|
"symbol": exchange_symbol,
|
|
"direction": direction,
|
|
"order_amount": amt,
|
|
}
|
|
return m.close_exchange_order(row)
|
|
if hasattr(m, "build_gate_order_params"):
|
|
params = m.build_gate_order_params(direction, reduce_only=True)
|
|
return ex.create_order(exchange_symbol, "market", side, amt, None, params)
|
|
if hasattr(m, "build_binance_order_params"):
|
|
for params in m._binance_market_close_param_candidates(direction):
|
|
try:
|
|
return ex.create_order(exchange_symbol, "market", side, amt, None, params)
|
|
except Exception as e:
|
|
if not m._is_binance_close_param_retryable(str(e)):
|
|
raise
|
|
raise RuntimeError("平仓失败")
|
|
if hasattr(m, "build_okx_order_params"):
|
|
params = m.build_okx_order_params(direction, reduce_only=True)
|
|
return ex.create_order(exchange_symbol, "market", side, amt, None, params)
|
|
return ex.create_order(exchange_symbol, "market", side, amt, None, {"reduceOnly": True})
|
|
|
|
|
|
def trend_replace_tpsl(cfg: dict, order_row: dict, stop_loss: float, take_profit: float) -> None:
|
|
"""趋势保本移交:先撤条件单再挂保本止损 + 计划止盈(与下单监控一致)。"""
|
|
m = _m(cfg)
|
|
fn = getattr(m, "replace_active_monitor_tpsl_on_exchange", None)
|
|
if not callable(fn):
|
|
raise RuntimeError("当前实例未配置止盈止损同步能力")
|
|
fn(order_row, float(stop_loss), float(take_profit))
|
|
|
|
|
|
def cancel_symbol_orders(cfg: dict, exchange_symbol: str) -> None:
|
|
m = _m(cfg)
|
|
if hasattr(m, "cancel_all_open_orders_for_symbol"):
|
|
m.cancel_all_open_orders_for_symbol(exchange_symbol)
|
|
return
|
|
if hasattr(m, "cancel_gate_swap_trigger_orders"):
|
|
m.cancel_gate_swap_trigger_orders(exchange_symbol)
|
|
if hasattr(m, "cancel_binance_futures_open_orders"):
|
|
m.cancel_binance_futures_open_orders(exchange_symbol)
|
|
if hasattr(m, "cancel_okx_swap_open_orders"):
|
|
m.cancel_okx_swap_open_orders(exchange_symbol)
|