feat: options sheet sizing, ITM/OTM labels, and 14-day chain view

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-07 09:06:45 +08:00
parent d6d1ac5818
commit c1647822fb
8 changed files with 172 additions and 29 deletions
+25 -3
View File
@@ -50,16 +50,19 @@ def calc_order_size(
budget_usdc: float | None = None,
budget_buffer: float = 0.95,
eth_amount: float | None = None,
sheets: int | None = None,
budget_cap: float | None = None,
) -> dict[str, Any]:
"""
返回 sheets, eth_amount, total_premium。
mode: budget_full eth_amount。
mode: budget_full / eth_amount / sheets
"""
if quote_per_unit <= 0:
return {"ok": False, "msg": "卖一价无效", "sheets": 0, "eth_amount": 0.0, "total_premium": 0.0}
if eth_amount is not None and eth_amount > 0:
if sheets is not None and int(sheets) > 0:
sheets = int(sheets)
elif eth_amount is not None and eth_amount > 0:
sheets = sheets_from_eth_amount(eth_amount, ct_mult)
elif budget_usdc is not None and budget_usdc > 0:
eff = float(budget_usdc) * float(budget_buffer)
@@ -68,7 +71,7 @@ def calc_order_size(
return {"ok": False, "msg": "无法计算单张权利金", "sheets": 0, "eth_amount": 0.0, "total_premium": 0.0}
sheets = int(math.floor(eff / per_sheet))
else:
return {"ok": False, "msg": "请指定预算或 ETH 数量", "sheets": 0, "eth_amount": 0.0, "total_premium": 0.0}
return {"ok": False, "msg": "请指定预算、币数量或张数", "sheets": 0, "eth_amount": 0.0, "total_premium": 0.0}
if sheets < min_sz:
per = premium_per_sheet(quote_per_unit, ct_mult)
@@ -110,3 +113,22 @@ def is_shallow_itm(
return False
return (strike - index_px) <= max_dist_usd
return False
def option_moneyness(*, opt_type: str, strike: float, index_px: float) -> str:
"""返回 itm / otm / atm。"""
o = (opt_type or "").upper()
if strike is None or index_px is None or index_px <= 0:
return "unknown"
atm_band = max(index_px * 0.002, 2.0)
if abs(strike - index_px) <= atm_band:
return "atm"
if o == "C":
return "itm" if strike < index_px else "otm"
if o == "P":
return "itm" if strike > index_px else "otm"
return "unknown"
def option_moneyness_label(moneyness: str) -> str:
return {"itm": "实值", "otm": "虚值", "atm": "平值"}.get((moneyness or "").lower(), "")