update 03-29 01:36

This commit is contained in:
2026-03-29 01:36:30 +09:00
parent 710949f034
commit dbf2c2bb1f
12 changed files with 399 additions and 44 deletions

View File

@@ -65,6 +65,8 @@ class RiskConfig:
class FeesConfig:
taker_fee_5m: float = 0.0156
taker_fee_15m: float = 0.03
fee_rate: float = 0.045
fee_exponent: int = 1
def fee_for_timeframe(self, timeframe: str) -> float:
"""Return the taker fee for a given timeframe string (e.g. '5M')."""
@@ -76,6 +78,13 @@ class FeesConfig:
raise ValueError(f"Unknown timeframe '{timeframe}'; expected one of {list(mapping)}")
return mapping[timeframe]
def dynamic_fee(self, price: float, shares: int = 1) -> float:
"""Compute Polymarket's dynamic taker fee for a given price and share count.
Formula: shares * price * fee_rate * (price * (1 - price)) ** fee_exponent
"""
return shares * price * self.fee_rate * (price * (1.0 - price)) ** self.fee_exponent
@dataclass(frozen=True)
class BinanceConfig:

View File

@@ -109,7 +109,8 @@ class TemporalArbStrategy:
)
# 6. Edge calculation (after fees)
taker_fee = self.fees.fee_for_timeframe(timeframe)
# Use dynamic fee formula: fee per share / price = effective fee rate
taker_fee = self.fees.dynamic_fee(poly_price, 1) / poly_price
edge = estimated_prob - poly_price - taker_fee
if edge < self.arb.min_edge:
@@ -118,7 +119,7 @@ class TemporalArbStrategy:
# 7. Position sizing
asset = Asset(symbol)
size = self.calculate_kelly_size(
edge=edge,
estimated_prob=estimated_prob,
price=poly_price,
balance=self.balance,
max_size=self.risk.max_position_per_market_usd,
@@ -181,25 +182,25 @@ class TemporalArbStrategy:
"""
abs_change = abs(price_change_pct)
# Factor 1: Base probability from price magnitude
# 0.15% → ~70%, 0.3% → ~82%, 0.5% → ~90%, 1.0%+ → ~95%
base_prob = 0.55 + abs_change * 1.0 # 1.0 scaling factor
base_prob = min(base_prob, 0.95)
# Factor 1: Sigmoid base probability from price magnitude
# k=18.0 steepness, inflection at 0.10% change
# 0.03% → ~0.53, 0.10% → ~0.65, 0.20% → ~0.80, 0.50% → ~0.93
k = 18.0
threshold = 0.10
sigmoid_val = 1.0 / (1.0 + math.exp(-k * (abs_change - threshold)))
base_prob = 0.52 + sigmoid_val * 0.43 # maps [0,1] → [0.52, 0.95]
# Factor 2: Time decay — more time elapsed = more confirmation
# If 80% of window has passed and price is still in this direction,
# the probability of reversal is lower
elapsed_fraction = max(0, 1.0 - (time_remaining / total_window_sec))
# Sigmoid-like boost: ramps up in the last 40% of the window
elapsed_fraction = 1.0 - (time_remaining / total_window_sec) if total_window_sec > 0 else 0.5
# Ramps up in the last 40% of the window
time_factor = 1.0 + 0.08 * max(0, elapsed_fraction - 0.6) / 0.4
time_factor = min(time_factor, 1.08)
# Factor 3: Volatility / momentum strength
# Very large moves (>0.5%) get extra confidence
if abs_change > 0.5:
vol_boost = min(0.05, (abs_change - 0.5) * 0.1)
else:
vol_boost = 0.0
vol_boost = min(0.05, (abs_change - 0.5) * 0.1) if abs_change > 0.5 else 0.0
final_prob = base_prob * time_factor + vol_boost
return min(0.95, max(0.50, final_prob))
@@ -210,7 +211,7 @@ class TemporalArbStrategy:
def calculate_kelly_size(
self,
edge: float,
estimated_prob: float,
price: float,
balance: float,
max_size: float,
@@ -224,7 +225,7 @@ class TemporalArbStrategy:
return 0
b = (1.0 / price) - 1.0 # Payout odds
p = edge + price # estimated_prob (edge = prob - price - fee)
p = estimated_prob
q = 1.0 - p
if b <= 0: