"""成交价与手续费:滑点 = 1×f。""" from __future__ import annotations from dataclasses import asdict, dataclass @dataclass(slots=True) class PriceResult: base_px: float fill_px: float fee: float slip: float notional: float def to_dict(self) -> dict[str, float]: return asdict(self) def option_intrinsic(*, option_side: str, strike: float, spot: float) -> float: """多头期权内在价值(USDT/ETH)。call=max(S−K,0),put=max(K−S,0)。""" s = float(spot) k = float(strike) side = str(option_side).lower().strip() if side in ("call", "c"): return max(s - k, 0.0) if side in ("put", "p"): return max(k - s, 0.0) return 0.0 def is_deep_otm( *, option_side: str, strike: float, spot: float, max_intrinsic: float = 0.01, ) -> bool: """ 远虚:内在价值≈0(多头期权已无行权价值)。 100×杠杆 ATM 在标的波动约1%后常落入此状态。 """ return option_intrinsic( option_side=option_side, strike=strike, spot=spot ) <= float(max_intrinsic) def option_expiry_settle( *, intrinsic: float, qty_eth: float, fee_rate: float, ) -> PriceResult: """到期结算:按内在价值入账(对齐实盘),无买卖价差滑点,仅扣手续费。""" base = max(float(intrinsic), 0.0) fill = base f = float(fee_rate) notional = abs(fill * float(qty_eth)) fee = notional * f return PriceResult(base_px=base, fill_px=fill, fee=fee, slip=0.0, notional=notional) def resolve_option_close_bid( *, bid: float | None, mark: float | None, intrinsic: float | None, bypass_liquidity: bool, ) -> float | None: """ 非到期平仓用买一价;多头卖出不得低于内在价值(SIM)。 紧急 bypass:max(买一, 标记, 内在价值)。 到期请用 option_expiry_settle,不要走本函数。 """ candidates: list[float] = [] if bid is not None and bid >= 0: candidates.append(float(bid)) if bypass_liquidity and mark is not None and mark >= 0: candidates.append(float(mark)) if intrinsic is not None and intrinsic >= 0: candidates.append(float(intrinsic)) if not candidates: return None if bypass_liquidity: return max(candidates) if bid is None: return None if intrinsic is not None and intrinsic >= 0: return max(float(bid), float(intrinsic)) return float(bid) def perp_fill( *, side: str, action: str, bid: float, ask: float, qty_eth: float, fee_rate: float, ) -> PriceResult: """ side: long|short(持仓方向意图:开仓要建立的方向 / 平仓时原持仓方向) action: open|close 开多/平空: 吃卖一 ×(1+f) 开空/平多: 吃买一 ×(1-f) """ f = float(fee_rate) buying = (action == "open" and side == "long") or (action == "close" and side == "short") if buying: base = float(ask) fill = base * (1.0 + f) else: base = float(bid) fill = base * (1.0 - f) notional = abs(fill * qty_eth) fee = notional * f slip = abs(fill - base) * qty_eth return PriceResult(base_px=base, fill_px=fill, fee=fee, slip=slip, notional=notional) def option_fill( *, action: str, bid: float, ask: float, qty_eth: float, fee_rate: float, ) -> PriceResult: """开仓买入吃卖一;平仓卖出吃买一。""" f = float(fee_rate) if action == "open": base = float(ask) fill = base * (1.0 + f) else: base = float(bid) fill = base * (1.0 - f) notional = abs(fill * qty_eth) fee = notional * f slip = abs(fill - base) * qty_eth return PriceResult(base_px=base, fill_px=fill, fee=fee, slip=slip, notional=notional)