SPB Git forge
1commits 1branches 0releases
189.0 KBsize
maindefault branch
5 h agolast push
Python 54.7% TypeScript 42.5% SQL 1.9%
1.8 KB · 41 lines python
Raw Blame History
1"""Execution cost & fill model shared by the backtester and the paper simulator."""23from __future__ import annotations45import math6from decimal import ROUND_DOWN, Decimal78from pydantic import BaseModel, Field91011class CostModel(BaseModel):12    taker_fee: float = Field(0.0040, description="Kraken spot taker fee at the lowest tier (verify with TradeVolume)")13    maker_fee: float = Field(0.0025)14    spread_bps: float = Field(5.0, description="Assumed quoted spread when no book data (bps of mid)")15    slippage_bps: float = Field(2.0, description="Extra adverse move per order")16    impact_coeff: float = Field(0.1, description="Impact (bps) = coeff × sqrt(qty / bar_volume) × 1e4")17    max_participation: float = Field(0.05, description="Max fraction of bar volume filled per bar (partial fills)")18    latency_bars: int = Field(0, description="Extra bars of delay beyond next-open execution")19    use_maker: bool = False20    fee_multiplier: float = 1.0  # stress: fee increases21    spread_multiplier: float = 1.0  # stress: spread widening222324def round_lot(qty: float, lot_decimals: int) -> float:25    if qty <= 0 or not math.isfinite(qty):26        return 0.027    q = Decimal(str(qty)).quantize(Decimal(1).scaleb(-lot_decimals), rounding=ROUND_DOWN)28    return float(q)293031def fill_price(side: str, ref_price: float, qty: float, bar_volume: float, cm: CostModel) -> float:32    half_spread = ref_price * (cm.spread_bps * cm.spread_multiplier) / 2e433    slip = ref_price * cm.slippage_bps / 1e434    impact = ref_price * cm.impact_coeff * math.sqrt(qty / bar_volume) if bar_volume > 0 else 0.035    adverse = (0.0 if cm.use_maker else half_spread) + slip + impact36    return ref_price + adverse if side == "buy" else max(ref_price - adverse, 1e-12)373839def fee_rate(cm: CostModel) -> float:40    return (cm.maker_fee if cm.use_maker else cm.taker_fee) * cm.fee_multiplier41