Treat exchange as LIVE SoT: expiry closes perp only, no invented option settles.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-08 15:44:15 +08:00
parent 4fe15c41fa
commit 99e58910d3
8 changed files with 1010 additions and 303 deletions
+14 -20
View File
@@ -209,12 +209,12 @@ def perp_close_contracts_okx(
perp_side: str,
perp_qty_eth: float,
ct_val: float,
allow_db_fallback: bool = True,
allow_db_fallback: bool = False,
) -> int | None:
"""平永续张数:优先交易所持仓。
"""平永续张数:交易所持仓为准
返回 >0 应下单;0=已确认空仓(仅 allow_db_fallback=False
None=查仓失败(调用方不得当空仓 finalize)
返回 >0 应下单;0=已确认空仓;None=查仓失败(调用方不得当空仓 finalize
交易所已确认空仓时绝不回退 DB。allow_db_fallback 仅在查仓失败时可用
"""
ps = "long" if perp_side == "long" else "short"
ex_sz = client.get_perp_pos_sz(perp_inst, pos_side=ps)
@@ -224,9 +224,7 @@ def perp_close_contracts_okx(
return max(1, int(round(perp_qty_eth / ct_val)))
if ex_sz > _PERP_EPS:
return max(1, int(round(ex_sz)))
if not allow_db_fallback:
return 0
return max(1, int(round(perp_qty_eth / ct_val)))
return 0
def perp_close_qty_eth_binance(
@@ -235,9 +233,9 @@ def perp_close_qty_eth_binance(
perp_inst: str,
perp_side: str,
perp_qty_eth: float,
allow_db_fallback: bool = True,
allow_db_fallback: bool = False,
) -> float | None:
"""平永续 ETH>0 下单;0=已确认空;None=查仓失败。"""
"""平永续 ETH>0 下单;0=已确认空;None=查仓失败。已空绝不回退 DB。"""
ps = "LONG" if perp_side == "long" else "SHORT"
ex_sz = client.get_perp_pos_sz(perp_inst, position_side=ps)
if ex_sz is None:
@@ -246,9 +244,7 @@ def perp_close_qty_eth_binance(
return float(perp_qty_eth)
if ex_sz > _PERP_EPS:
return float(ex_sz)
if not allow_db_fallback:
return 0.0
return float(perp_qty_eth)
return 0.0
def perp_open_contracts_okx(*, perp_qty_eth: float, ct_val: float) -> int:
@@ -327,17 +323,15 @@ def recover_stuck_opening(executor) -> CloseResult | None:
if not callable(persist):
return CloseResult(ok=False, detail="recover_opening: 无 half_open 落库")
of_px = float(pos.get("option_entry_px") or 0) or 0.0
# 数量以交易所为准
opt_contracts = float(opt_sz)
opt_qty = float(pos.get("option_qty_eth") or 0)
opt_contracts = float(pos.get("option_qty_contracts") or 0)
if opt_contracts <= 0 and hasattr(executor, "_ct_mult"):
from ..sim.liquidity import contracts_for_eth
ct = executor._ct_mult(option_inst)
opt_contracts = float(contracts_for_eth(opt_qty or opt_sz, ct)) if opt_qty else float(opt_sz)
if opt_qty <= 0 and hasattr(executor, "_ct_mult"):
if hasattr(executor, "_ct_mult"):
from ..sim.liquidity import eth_from_contracts
opt_qty = eth_from_contracts(opt_contracts or opt_sz, executor._ct_mult(option_inst))
opt_qty = eth_from_contracts(opt_contracts, executor._ct_mult(option_inst))
elif opt_qty <= 0:
opt_qty = float(opt_sz)
persist(
group_id=group_id or f"RCV-{option_inst[-12:]}",
bias="recover",