feat中控市价单:实例按第一档实值与杠杆立即全仓开仓。

EOF

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-11-03 18:50:46 +08:00
parent 4e14c92385
commit 8a29f2d51b
6 changed files with 947 additions and 1 deletions
+74 -1
View File
@@ -561,6 +561,22 @@ def band_bounds(trigger_px: float, deviation_pct: float) -> tuple[float, float]:
return lo, hi
def _chain_contract_leverage(c: dict[str, Any], *, index_px: float) -> float | None:
"""用链上报价估合约杠杆(币本位≈1/ask)."""
from lib.options.options_pricing_lib import equivalent_contract_leverage
ask = _safe_float(c.get("ask"))
ct_mult = _safe_float(c.get("ct_mult")) or 0.01
if ask is None or ask <= 0 or ct_mult <= 0:
return None
return equivalent_contract_leverage(
index_px=index_px,
eth_amount=float(ct_mult),
total_premium=float(ask) * float(ct_mult),
margin_mode="coin",
)
def pick_nearest_itm_contract(
cfg: dict[str, Any],
ex: Any,
@@ -569,8 +585,12 @@ def pick_nearest_itm_contract(
opt_type: str,
index_px: float,
min_expiry_hours: float,
target_leverage: float | None = None,
) -> dict[str, Any] | None:
"""按当前指数选最近一档实值;到期 ≥ min_expiry_hours."""
"""按当前指数选最近一档实值;到期 ≥ min_expiry_hours.
target_leverage 有值时:仅在第一档实值(最近行权距)内,选杠杆最接近目标的合约。
"""
from lib.exchange.okx_options_lib import build_option_chain, option_buy_liquidity_ok
from lib.options.options_pricing_lib import option_moneyness
@@ -614,6 +634,59 @@ def pick_nearest_itm_contract(
if not candidates:
return None
candidates.sort(key=lambda x: (x[0], str(x[1].get("inst_id") or "")))
want_lev = _safe_float(target_leverage)
if want_lev is not None and want_lev > 0:
min_dist = candidates[0][0]
rung = [c for d, c in candidates if abs(float(d) - float(min_dist)) <= 1e-9]
scored: list[tuple[float, int, dict[str, Any], dict[str, Any] | None]] = []
for c in rung:
inst = str(c.get("inst_id") or "")
if not inst:
continue
q: dict[str, Any] | None = None
try:
q = cfg["quote_option_contract"](ex, inst)
except Exception:
q = None
ask = (q or {}).get("ask") if q else c.get("ask")
ask_sz = (q or {}).get("ask_sz") if q else c.get("ask_sz")
ok_liq, _ = option_buy_liquidity_ok(ask, ask_sz)
lev = None
if q and ask is not None:
ct = _safe_float((q or {}).get("ct_mult")) or _safe_float(c.get("ct_mult")) or 0.01
from lib.options.options_pricing_lib import equivalent_contract_leverage
lev = equivalent_contract_leverage(
index_px=index_px,
eth_amount=float(ct),
total_premium=float(ask) * float(ct),
margin_mode="coin",
)
if lev is None:
lev = _chain_contract_leverage(c, index_px=index_px)
if lev is None:
continue
scored.append((abs(float(lev) - float(want_lev)), 0 if ok_liq else 1, c, q))
if scored:
scored.sort(key=lambda x: (x[0], x[1], str(x[2].get("inst_id") or "")))
best_c = dict(scored[0][2])
if scored[0][3]:
best_c["quote"] = scored[0][3]
best_c["picked_leverage"] = _chain_contract_leverage(best_c, index_px=index_px)
if scored[0][3] and scored[0][3].get("ask") is not None:
ct = _safe_float(scored[0][3].get("ct_mult")) or _safe_float(best_c.get("ct_mult")) or 0.01
from lib.options.options_pricing_lib import equivalent_contract_leverage
best_c["picked_leverage"] = equivalent_contract_leverage(
index_px=index_px,
eth_amount=float(ct),
total_premium=float(scored[0][3]["ask"]) * float(ct),
margin_mode="coin",
)
return best_c
# 杠杆估不出时退回第一档最近合约
# 优先有卖一深度的最近档
for _dist, c in candidates[:12]:
inst = str(c.get("inst_id") or "")