Files
eth_hedge_sim/backend/app/sim/pricing.py
T
2026-07-26 16:08:44 +08:00

126 lines
3.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""成交价与手续费:滑点 = 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(SK,0)put=max(KS,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 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)。
紧急 bypassmax(买一, 标记, 内在价值)。
到期请用 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)