Fix LIVE open/close double-book and security audit findings.

Prevent expiry dual-close from re-booking option cash, abandon ledger rejection, margin-mode mismatch, and manual close races; harden fill wait and refuse default AUTH_SECRET on LIVE.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-29 20:11:29 +08:00
parent c6e8f6fe1e
commit ec87cf2104
10 changed files with 229 additions and 80 deletions
+32 -25
View File
@@ -103,16 +103,20 @@ async def sim_open_group(
db.fetchall("SELECT group_id FROM groups WHERE group_id LIKE ?", (f"G-{wkey}-%",))
)
gid = next_group_id(count)
r = ex.open_group(
group_id=gid,
bias=bias,
option_side=option_side,
perp_side=perp_side,
option_inst_id=option_inst,
entry_index_px=float(pick.underlying_px),
strike=pick.pair.strike,
expiry_ymd=pick.pair.expiry_ymd,
)
engine = get_engine()
async with engine._lock:
if ex.has_open_position():
raise HTTPException(status_code=409, detail="有未平仓,禁止开下一组")
r = ex.open_group(
group_id=gid,
bias=bias,
option_side=option_side,
perp_side=perp_side,
option_inst_id=option_inst,
entry_index_px=float(pick.underlying_px),
strike=pick.pair.strike,
expiry_ymd=pick.pair.expiry_ymd,
)
if not r.ok:
raise HTTPException(status_code=400, detail=r.detail)
try:
@@ -151,22 +155,25 @@ async def sim_close_group(_user: Annotated[str, Depends(require_user)]) -> dict:
)
from ..strategy import get_engine
r = get_executor().close_group(reason="manual")
if not r.ok and not r.liquidity_wait:
raise HTTPException(status_code=400, detail=r.detail)
if r.ok:
# 与自动/紧急全平一致:成功全平后进入组间休息
get_engine().enter_rest_after_close()
try:
from ..notify import wecom
engine = get_engine()
# 与策略引擎共用锁,避免与自动平仓/开仓竞态
async with engine._lock:
r = get_executor().close_group(reason="manual")
if not r.ok and not r.liquidity_wait:
raise HTTPException(status_code=400, detail=r.detail)
if r.ok:
# 与自动/紧急全平一致:成功全平后进入组间休息
engine.enter_rest_after_close()
try:
from ..notify import wecom
wecom.notify_close(
reason="manual",
detail=r.detail,
data=r.data or {},
)
except Exception:
pass
wecom.notify_close(
reason="manual",
detail=r.detail,
data=r.data or {},
)
except Exception:
pass
return {
"ok": r.ok,
"liquidity_wait": r.liquidity_wait,