feat中控市价单:实例按第一档实值与杠杆立即全仓开仓。
EOF Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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 "")
|
||||
|
||||
Reference in New Issue
Block a user