forked from warproxxx/poly-maker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpredictors.py
More file actions
71 lines (55 loc) · 2.54 KB
/
Copy pathpredictors.py
File metadata and controls
71 lines (55 loc) · 2.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
"""Short-horizon price prediction hooks for market making.
The default predictor is deliberately conservative. It uses only order book
imbalance as a tiny mid-price nudge, but exposes the same interface that a
factor stack or model can implement later.
"""
from __future__ import annotations
from dataclasses import dataclass
from decimal import Decimal
from polymarket_adapter import Quote, TokenConfig
@dataclass(frozen=True)
class MarketFeatures:
token: TokenConfig
quote: Quote
imbalance: Decimal
latency_ms: int
best_bid_size: Decimal = Decimal("0")
best_ask_size: Decimal = Decimal("0")
@dataclass(frozen=True)
class Prediction:
predicted_mid: Decimal
edge_bps: Decimal
confidence: Decimal
reason: str
class ShortHorizonPredictor:
def predict(self, features: MarketFeatures) -> Prediction:
raise NotImplementedError
class ImbalancePredictor(ShortHorizonPredictor):
"""Short-horizon fair-price estimate from microprice plus book imbalance."""
def __init__(self, impact_bps_per_imbalance: Decimal, min_confidence: Decimal) -> None:
self.impact_bps_per_imbalance = impact_bps_per_imbalance
self.min_confidence = min_confidence
def predict(self, features: MarketFeatures) -> Prediction:
if features.quote.mid <= 0:
return Prediction(Decimal("0"), Decimal("0"), Decimal("0"), "no_mid")
edge_bps = self._microprice_edge_bps(features) + features.imbalance * self.impact_bps_per_imbalance
confidence = min(Decimal("1"), abs(features.imbalance))
reason = (
f"obi={features.imbalance:.4f};"
f"micro_edge_bps={self._microprice_edge_bps(features):.4f};"
f"horizon={features.latency_ms}ms"
)
if confidence < self.min_confidence:
return Prediction(features.quote.mid, Decimal("0"), confidence, f"weak_{reason}")
predicted_mid = features.quote.mid * (Decimal("1") + edge_bps / Decimal("10000"))
return Prediction(predicted_mid=predicted_mid, edge_bps=edge_bps, confidence=confidence, reason=reason)
@staticmethod
def _microprice_edge_bps(features: MarketFeatures) -> Decimal:
total_size = features.best_bid_size + features.best_ask_size
if total_size <= 0 or features.quote.mid <= 0:
return Decimal("0")
microprice = (
features.quote.ask * features.best_bid_size
+ features.quote.bid * features.best_ask_size
) / total_size
return (microprice - features.quote.mid) / features.quote.mid * Decimal("10000")