Fix coin-margin expiry breakeven to use coin premium formula.
Use K/(1-p) and K/(1+p) for coin calls/puts instead of adding ETH premium to USD strike; align T-view straddle band with coin quotes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -438,10 +438,16 @@ def expiry_breakeven_from_ask(
|
||||
strike: float | None,
|
||||
ask_px: float | None,
|
||||
mark_px: float | None = None,
|
||||
quote_in_coin: bool = False,
|
||||
) -> float | None:
|
||||
"""买入前预估到期平衡:权利金按卖一;无卖一时回退标记价."""
|
||||
prem = ask_px if ask_px is not None and ask_px > 0 else mark_px
|
||||
return expiry_breakeven_px(opt_type=opt_type, strike=strike, avg_px=prem)
|
||||
return expiry_breakeven_px(
|
||||
opt_type=opt_type,
|
||||
strike=strike,
|
||||
avg_px=prem,
|
||||
quote_in_coin=quote_in_coin,
|
||||
)
|
||||
|
||||
|
||||
def expiry_breakeven_px(
|
||||
@@ -450,17 +456,37 @@ def expiry_breakeven_px(
|
||||
strike: float | None,
|
||||
avg_px: float | None,
|
||||
be_px_api: float | None = None,
|
||||
quote_in_coin: bool = False,
|
||||
) -> float | None:
|
||||
"""到期平衡点:持有至到期时标的指数盈亏为 0 的价格.优先 OKX bePx."""
|
||||
"""到期平衡点:持有至到期时标的指数盈亏为 0 的价格.优先 OKX bePx.
|
||||
|
||||
USDC: Call K+p / Put K-p (p 为美元报价).
|
||||
币本位: Call K/(1-p) / Put K/(1+p) (p 为币报价,与卖一同单位).
|
||||
"""
|
||||
if be_px_api is not None and be_px_api > 0:
|
||||
return round(float(be_px_api), 2)
|
||||
if strike is None or avg_px is None:
|
||||
return None
|
||||
try:
|
||||
k = float(strike)
|
||||
p = float(avg_px)
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
if p <= 0:
|
||||
return round(k, 2)
|
||||
o = (opt_type or "").upper()
|
||||
if quote_in_coin:
|
||||
if o == "C":
|
||||
if p >= 1:
|
||||
return None
|
||||
return round(k / (1.0 - p), 2)
|
||||
if o == "P":
|
||||
return round(k / (1.0 + p), 2)
|
||||
return None
|
||||
if o == "C":
|
||||
return round(strike + avg_px, 2)
|
||||
return round(k + p, 2)
|
||||
if o == "P":
|
||||
return round(strike - avg_px, 2)
|
||||
return round(k - p, 2)
|
||||
return None
|
||||
|
||||
|
||||
@@ -618,20 +644,30 @@ def straddle_premium_total(
|
||||
def straddle_breakeven_band(
|
||||
strike: float | None,
|
||||
combined_ask_per_unit: float | None,
|
||||
*,
|
||||
quote_in_coin: bool = False,
|
||||
) -> tuple[float | None, float | None]:
|
||||
"""跨式到期平衡带:下平衡 ~ 上平衡(按双卖一报价和)."""
|
||||
if strike is None or combined_ask_per_unit is None:
|
||||
return None, None
|
||||
k = float(strike)
|
||||
d = float(combined_ask_per_unit)
|
||||
if d <= 0:
|
||||
return None, None
|
||||
if quote_in_coin:
|
||||
if d >= 1:
|
||||
return None, None
|
||||
return round(k / (1.0 + d), 2), round(k / (1.0 - d), 2)
|
||||
return round(k - d, 2), round(k + d, 2)
|
||||
|
||||
|
||||
def format_straddle_band(
|
||||
strike: float | None,
|
||||
combined_ask_per_unit: float | None,
|
||||
*,
|
||||
quote_in_coin: bool = False,
|
||||
) -> str:
|
||||
lo, hi = straddle_breakeven_band(strike, combined_ask_per_unit)
|
||||
lo, hi = straddle_breakeven_band(strike, combined_ask_per_unit, quote_in_coin=quote_in_coin)
|
||||
if lo is None or hi is None:
|
||||
return ""
|
||||
return f"{lo:.0f} ~ {hi:.0f}"
|
||||
|
||||
Reference in New Issue
Block a user