Close residual options when premium recovers above configurable threshold.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-02 14:19:21 +08:00
parent 60b3743e8d
commit 62c91d4bd0
12 changed files with 603 additions and 11 deletions
+63
View File
@@ -1149,6 +1149,69 @@ class BinanceLiveExecutor(Matcher):
},
)
def try_close_one_residual(self, row: dict) -> dict | None:
"""LIVE-BN:权利金达标后交易所市价卖出归档期权。"""
err = self._guard_live()
if err:
logger.warning("residual premium close blocked: %s", err)
return None
skip, close_bid, _oq = self._evaluate_residual_premium_close(row)
if skip or close_bid is None:
if skip:
logger.debug(
"residual premium close skip %s: %s",
row.get("group_id"),
skip,
)
return None
option_inst_id = str(row.get("option_inst_id") or "")
opt_contracts = float(row.get("option_qty_contracts") or 0)
opt_qty = float(row.get("option_qty_eth") or 0)
if opt_contracts <= 0:
ct = self._ct_mult(option_inst_id)
opt_contracts = float(contracts_for_eth(opt_qty, ct) or 0)
if opt_contracts <= 0:
logger.warning(
"residual premium close skip %s: bad contracts", row.get("group_id")
)
return None
client = self._client()
try:
opt_live = client.place_option_market(
symbol=option_inst_id,
side="SELL",
quantity=max(1.0, opt_contracts),
reduce_only=True,
)
except Exception as e:
logger.warning(
"residual premium close exchange sell failed %s: %s",
row.get("group_id"),
e,
)
return None
of_px = float(opt_live.avg_px)
of_fee = float(opt_live.fee)
filled_c = (
float(opt_live.sz)
if opt_live.sz and float(opt_live.sz) > 0
else opt_contracts
)
opt_qty = eth_from_contracts(filled_c, self._ct_mult(option_inst_id))
row = {**row, "option_qty_eth": opt_qty, "option_qty_contracts": filled_c}
of_notional = of_px * opt_qty
now_ms = int(time.time() * 1000)
return self._book_residual_market_close(
row,
fill_px=of_px,
fee=of_fee,
notional=of_notional,
slip=0.0,
now_ms=now_ms,
note="LIVE-BN residual mid-close by premium recovery",
exec_mode="LIVE",
)
def close_perp_abandon_option(
self, *, reason: str = "target_perp_only", require_deep_otm: bool = True
) -> CloseResult:
+64
View File
@@ -1192,6 +1192,70 @@ class OkxLiveExecutor(Matcher):
},
)
def try_close_one_residual(self, row: dict) -> dict | None:
"""LIVE:权利金达标后交易所市价卖出归档期权。"""
err = self._guard_live()
if err:
logger.warning("residual premium close blocked: %s", err)
return None
skip, close_bid, _oq = self._evaluate_residual_premium_close(row)
if skip or close_bid is None:
if skip:
logger.debug(
"residual premium close skip %s: %s",
row.get("group_id"),
skip,
)
return None
option_inst_id = str(row.get("option_inst_id") or "")
opt_contracts = float(row.get("option_qty_contracts") or 0)
opt_qty = float(row.get("option_qty_eth") or 0)
if opt_contracts <= 0:
ct = self._ct_mult(option_inst_id)
opt_contracts = float(contracts_for_eth(opt_qty, ct) or 0)
if opt_contracts <= 0:
logger.warning(
"residual premium close skip %s: bad contracts", row.get("group_id")
)
return None
client = self._client()
try:
opt_live = client.place_market(
inst_id=option_inst_id,
side="sell",
sz=str(max(1, int(round(opt_contracts)))),
td_mode="cash",
reduce_only=True,
)
except Exception as e:
logger.warning(
"residual premium close exchange sell failed %s: %s",
row.get("group_id"),
e,
)
return None
of_px = float(opt_live.avg_px)
of_fee = float(opt_live.fee)
filled_c = (
float(opt_live.sz)
if opt_live.sz and float(opt_live.sz) > 0
else opt_contracts
)
opt_qty = eth_from_contracts(filled_c, self._ct_mult(option_inst_id))
row = {**row, "option_qty_eth": opt_qty, "option_qty_contracts": filled_c}
of_notional = of_px * opt_qty
now_ms = int(time.time() * 1000)
return self._book_residual_market_close(
row,
fill_px=of_px,
fee=of_fee,
notional=of_notional,
slip=0.0,
now_ms=now_ms,
note="LIVE residual mid-close by premium recovery",
exec_mode="LIVE",
)
def close_perp_abandon_option(
self, *, reason: str = "target_perp_only", require_deep_otm: bool = True
) -> CloseResult: