Files
sentiment-engine/MALKHUT/malkhut/cwm/latency_model.py
Codex f943191d56 malkhut(T2): Code World Model — deterministic exchange simulator
CWM core (core.py): price-time priority, sequential level consumption,
partial fills, queue position, latency injection, maker/taker fees.
Numba acceleration (numba_core.py): JIT hot loops, 1.8x fill speedup.
Replay verification (replay_verify.py): binary search, trajectory recording.
Supporting: adverse_selection, correlation, latency_model, multi_level,
queue_model, spread_dynamics, volatility, hftbacktest_validator.
2026-07-11 10:23:44 +02:00

132 lines
3.7 KiB
Python

"""
Latency Model — simulate realistic feed and order latencies.
Essential for:
- Realistic fill simulation
- Latency arbitrage defense
- Optimal order timing
"""
from __future__ import annotations
import math
from dataclasses import dataclass
from typing import Optional
import numpy as np
from numba import njit
@dataclass(frozen=True, slots=True)
class LatencyState:
"""Latency state for the CWM."""
feed_latency_ms: float
order_latency_ms: float
feed_jitter_ms: float
order_jitter_ms: float
@njit(cache=True)
def simulate_feed_latency(
base_latency_ms: float,
jitter_ms: float,
rng_seed: int,
) -> float:
"""
Simulate feed latency with jitter.
Model: base_latency + uniform(-jitter, +jitter)
Returns latency in milliseconds.
"""
# Simple deterministic jitter using seed
jitter = jitter_ms * (2.0 * ((rng_seed % 1000) / 1000.0) - 1.0)
return max(0.0, base_latency_ms + jitter)
@njit(cache=True)
def simulate_order_latency(
base_latency_ms: float,
jitter_ms: float,
queue_position: int,
recent_trade_rate: float,
rng_seed: int = 0,
) -> float:
"""
Simulate order latency with queue dynamics.
Model:
- Base latency + jitter
- Additional latency from queue position (longer queue = slower fill)
- Reduced latency when trade rate is high (faster queue consumption)
Returns latency in milliseconds.
"""
jitter = jitter_ms * (2.0 * ((rng_seed % 1000) / 1000.0) - 1.0)
queue_delay = queue_position / max(recent_trade_rate, 0.01) * 1000.0
return max(0.0, base_latency_ms + jitter + queue_delay * 0.1)
@njit(cache=True)
def compute_latency_impact(
feed_latency_ms: float,
order_latency_ms: float,
price_change_per_ms: float,
) -> float:
"""
Compute the cost of latency in basis points.
Model:
- Feed latency: price moves before we see it
- Order latency: price moves before our order arrives
- Total cost = (feed_latency + order_latency) * price_change_per_ms
Returns cost in basis points.
"""
total_latency_ms = feed_latency_ms + order_latency_ms
# Assume price moves ~1bp per 10ms in volatile markets
cost_bps = total_latency_ms * price_change_per_ms
return cost_bps
class LatencyModel:
"""
Latency model for the CWM.
Simulates realistic feed and order latencies.
Used by CWM to make fill simulation realistic.
"""
def __init__(
self,
feed_latency_ms: float = 10.0,
order_latency_ms: float = 50.0,
feed_jitter_ms: float = 2.0,
order_jitter_ms: float = 10.0,
) -> None:
self._feed_latency = feed_latency_ms
self._order_latency = order_latency_ms
self._feed_jitter = feed_jitter_ms
self._order_jitter = order_jitter_ms
self._rng_seed = 0
def simulate_feed_latency(self) -> float:
"""Simulate current feed latency."""
self._rng_seed += 1
return simulate_feed_latency(self._feed_latency, self._feed_jitter, self._rng_seed)
def simulate_order_latency(self, queue_position: int = 0, recent_trade_rate: float = 0.5) -> float:
"""Simulate current order latency."""
self._rng_seed += 1
return simulate_order_latency(self._order_latency, self._order_jitter, queue_position, recent_trade_rate, self._rng_seed)
def compute_latency_cost(self, price_change_per_ms: float = 0.001) -> float:
"""Compute latency cost in basis points."""
return compute_latency_impact(self._feed_latency, self._order_latency, price_change_per_ms)
@property
def feed_latency_ms(self) -> float:
return self._feed_latency
@property
def order_latency_ms(self) -> float:
return self._order_latency