修改移动止损

This commit is contained in:
dekun
2026-05-19 14:45:28 +08:00
parent 07b85ae9f2
commit 5af1251687
5 changed files with 141 additions and 28 deletions
+73 -9
View File
@@ -1656,6 +1656,24 @@ def resolve_monitor_exchange_symbol(row):
return normalize_exchange_symbol(raw) if raw else ""
def round_price_to_exchange(exchange_symbol, price):
"""与交易所 tick 对齐后的 float,供入库与计算;失败时退回 float(price)。"""
if price in (None, ""):
return None
try:
v = float(price)
except (TypeError, ValueError):
return None
if not exchange_symbol:
return v
try:
ensure_markets_loaded()
s = exchange.price_to_precision(exchange_symbol, v)
return float(s)
except Exception:
return v
def _position_contract_symbol_match(position_symbol, wanted_exchange_symbol):
if not position_symbol or not wanted_exchange_symbol:
return False
@@ -3093,6 +3111,28 @@ def cancel_all_open_orders_for_symbol(exchange_symbol):
pass
def replace_active_monitor_tpsl_on_exchange(order_row, stop_loss, take_profit):
"""移动保本/手动改价:先撤该合约 TP/SL 条件单,再按新价重挂。"""
ok, reason = ensure_exchange_live_ready()
if not ok:
raise RuntimeError(reason or "实盘未就绪")
ex_sym = resolve_monitor_exchange_symbol(order_row)
direction = order_row["direction"]
cancel_gate_swap_trigger_orders(ex_sym)
contracts = get_live_position_contracts(ex_sym, direction)
if contracts is None or float(contracts) <= 0:
raise ValueError("交易所当前无该方向持仓,无法挂止盈止损")
amt = float(contracts)
if amt <= 0:
try:
amt = float(order_row["order_amount"] or 0)
except Exception:
amt = 0
if amt <= 0:
raise ValueError("无法确定平仓数量")
_gate_place_tp_sl_orders(ex_sym, direction, amt, float(stop_loss), float(take_profit))
def extract_trade_price_from_order(order):
if not order:
return None
@@ -4491,14 +4531,36 @@ def check_order_monitors():
direction == "long" and new_sl > float(stop_loss)
)
if should_move:
conn.execute(
"UPDATE order_monitors SET stop_loss=?, breakeven_armed=1, breakeven_price=? WHERE id=?",
(new_sl, new_sl, pid),
)
stop_loss = new_sl
arm_txt = "保本止盈" if not breakeven_armed else "移动止盈"
send_wechat_msg(
build_wechat_breakeven_message(
ex_sym = resolve_monitor_exchange_symbol(r)
new_sl = round_price_to_exchange(ex_sym, new_sl)
tp_ex = float(take_profit or 0)
ok_live, _live_reason = ensure_exchange_live_ready()
synced_ex = not ok_live
if ok_live and tp_ex > 0:
try:
replace_active_monitor_tpsl_on_exchange(r, new_sl, tp_ex)
synced_ex = True
except Exception as e:
print(
f"[breakeven] exchange tpsl replace failed order={pid} {sym}: {e}",
flush=True,
)
send_wechat_msg(
f"⚠️ {sym} 移动保本止损未同步交易所:{friendly_exchange_error(e)}"
)
elif ok_live:
print(
f"[breakeven] skip exchange order={pid} {sym}: invalid take_profit",
flush=True,
)
if synced_ex:
conn.execute(
"UPDATE order_monitors SET stop_loss=?, breakeven_armed=1, breakeven_price=? WHERE id=?",
(new_sl, new_sl, pid),
)
stop_loss = new_sl
arm_txt = "保本止盈" if not breakeven_armed else "移动止盈"
be_msg = build_wechat_breakeven_message(
sym,
direction,
arm_txt,
@@ -4506,7 +4568,9 @@ def check_order_monitors():
locked_r,
new_sl,
)
)
if ok_live:
be_msg += "\n- 交易所:已先撤后挂止盈止损"
send_wechat_msg(be_msg)
res = None
# 做多