Fix post-close auto sell: restore missing spot min-size helpers used by sim sell.

Sell was silently failing on ImportError; surface sell result in close alert notes.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-14 16:58:09 +08:00
parent d54bbdfcb3
commit be00991568
5 changed files with 83 additions and 8 deletions
+31 -6
View File
@@ -1681,18 +1681,36 @@ def execute_manual_close_plan(cfg: dict[str, Any], conn: Any, plan_id: int) -> d
notes.append(f"永续已平 {symbol}")
_release_db_write(conn)
# 3) 卖币回 USDT
sell_r: dict[str, Any] = {"ok": True, "skipped": True}
# 3) 卖币回 USDT(期权平仓后交易账户应有标的币)
sell_r: dict[str, Any] = {"ok": False, "msg": "未执行卖币"}
try:
_release_db_write(conn)
sell_ex = cfg.get("exchange_options") or cfg.get("exchange")
if sell_ex is not None:
if callable(sell_ex):
sell_ex = sell_ex()
if sell_ex is None:
sell_r = {"ok": False, "msg": "无交易所实例,无法卖币"}
else:
sell_r = spot_market_sell_coin_to_usdt(sell_ex, underlying=uly)
# 无可用币视为已无需卖(非失败),其它失败要暴露
if not sell_r.get("ok"):
msg_l = str(sell_r.get("msg") or "")
if "无可用" in msg_l or "可卖数量过小" in msg_l:
sell_r = {**sell_r, "ok": True, "skipped": True, "soft": True}
except Exception as e:
sell_r = {"ok": False, "msg": str(e)}
close_detail["sell_coin"] = sell_r
if sell_r.get("ok"):
notes.append("已卖币回 USDT" if not sell_r.get("skipped") else "卖币跳过")
if sell_r.get("ok") and not sell_r.get("skipped"):
notes.append(
"已卖币回 USDT"
+ (
f" {sell_r.get('coin_sold')}→{sell_r.get('usdt_recovered')}U"
if sell_r.get("coin_sold") is not None
else ""
)
)
elif sell_r.get("skipped"):
notes.append("卖币跳过: " + str(sell_r.get("msg") or "无可用币"))
else:
notes.append("卖币失败: " + str(sell_r.get("msg") or ""))
@@ -1730,11 +1748,18 @@ def execute_manual_close_plan(cfg: dict[str, Any], conn: Any, plan_id: int) -> d
notify_plan_end(cfg, conn, plan2)
except Exception:
pass
sell_ok = bool(sell_r.get("ok"))
msg = "已平仓并结束计划"
if sell_ok and not sell_r.get("skipped"):
msg = "已平仓并卖币回 USDT"
elif not sell_ok:
msg = "已平仓,但卖币失败: " + str(sell_r.get("msg") or "")
return {
"ok": True,
"plan_id": int(plan_id),
"msg": "已平仓并结束计划",
"msg": msg,
"notes": notes,
"close": close_detail,
"sell_coin": sell_r,
"realized_pnl_total": plan2.get("realized_pnl_total") if plan2 else total,
}