8ea05e7064
Co-authored-by: Cursor <cursoragent@cursor.com>
69 lines
1.6 KiB
Python
69 lines
1.6 KiB
Python
"""成交价与手续费:滑点 = 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 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)
|