Latency modeling is critical for accurate high-frequency trading backtesting. There are two types of latency to model:
Feed Latency: Time between when an event occurs at the exchange and when you receive it
Order Latency: Time between when you send an order and when the exchange processes it (entry) and responds (response)
Ignoring latency can lead to unrealistic backtests that assume you can react instantaneously to market events or that your orders are processed immediately.
Even microseconds of latency matter in HFT. A strategy that appears profitable with zero latency may lose money with realistic latency modeling.
Feed latency represents the time lag between market events and your observation of them:
# Market event timelineExchange Event Timestamp: TYour Receipt Timestamp: T + feed_latency# Example: 500μs feed latencyExchange: Trade at 12:00:00.000000 (69000)Your View: Trade at 12:00:00.000500 (69000)
Feed latency is typically already included in your market data if you’re using real feed data with local timestamps. HftBacktest uses the difference between exch_ts and local_ts fields.
If you don’t have order latency data, you can estimate from feed latency:
import numpy as npdef estimate_order_latency_from_feed(market_data_file): """Estimate order latency from feed latency""" data = np.load(market_data_file)['data'] # Feed latency = local_ts - exch_ts feed_latencies = data['local_ts'] - data['exch_ts'] # Order latency is typically similar to feed latency # But can be slightly higher due to order processing mean_feed_lat = np.mean(feed_latencies) std_feed_lat = np.std(feed_latencies) # Use feed latency + processing overhead entry_latency = mean_feed_lat + 100_000 # +100μs processing response_latency = mean_feed_lat + 50_000 # +50μs processing return entry_latency, response_latency
You can adjust all latencies by a constant offset:
# Add 100μs to all historical latencieslatency_model = IntpOrderLatency( data=[DataSource.File('latency_20240101.npz')], latency_offset=100_000 # +100μs)# This is useful for:# - Testing sensitivity to latency# - Simulating network upgrades/downgrades# - Correcting clock skew in data
Begin with higher latency estimates (1-2ms for crypto, 100-500μs for co-located) and gradually optimize. It’s better to be pessimistic in backtesting than over-optimistic.
Use Real Data When Possible
Collect actual latency measurements from your production environment. Synthetic models cannot capture all real-world effects like network congestion, exchange load, and time-of-day patterns.
Test Across Conditions
Validate your latency model during:
High volatility periods
Market open/close
Low liquidity hours
Exchange maintenance windows
Monitor Latency Drift
Latency characteristics change over time due to:
Exchange infrastructure updates
Network routing changes
Time-of-day patterns
Market participant changes
Regularly update your latency models with recent data.