Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/dhir1007/nanoARB/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The LatencyConfig struct defines latency parameters for simulating realistic network and exchange delays in backtests. Proper latency modeling is critical for HFT strategy validation. Source: nano-backtest/src/config.rs

LatencyConfig

pub struct LatencyConfig {
    pub order_latency_ns: u64,
    pub market_data_latency_ns: u64,
    pub ack_latency_ns: u64,
    pub jitter_ns: u64,
    pub use_random_jitter: bool,
}

Fields

FieldTypeDefaultDescription
order_latency_nsu64100,000Order submission latency (nanoseconds)
market_data_latency_nsu6450,000Market data reception latency (ns)
ack_latency_nsu64100,000Order acknowledgment latency (ns)
jitter_nsu6410,000Latency jitter std deviation (ns)
use_random_jitterbooltrueEnable random jitter simulation

Constructor

default

Creates a default latency configuration modeling co-location environment.
impl Default for LatencyConfig
Default values:
  • Order latency: 100μs (typical colo to exchange)
  • Market data: 50μs (faster than orders)
  • Acknowledgment: 100μs (round-trip to exchange)
  • Jitter: 10μs standard deviation
  • Random jitter: enabled
Example:
use nano_backtest::config::LatencyConfig;

let latency = LatencyConfig::default();
assert_eq!(latency.order_latency_ns, 100_000);

Field Details

order_latency_ns

Time from order submission to arrival at exchange. Units: Nanoseconds (1 microsecond = 1,000 nanoseconds) Represents:
  • Network transmission time
  • Gateway processing
  • Exchange ingress processing
Example:
let latency = LatencyConfig {
    order_latency_ns: 50_000,  // 50 microseconds
    ..Default::default()
};
Typical Values by Environment:
EnvironmentLatencyNotes
Aurora (CME colo)5-10μsDirect exchange connection
NY5 colo50-100μsGeneric NY data center
Cross-venue100-500μsDifferent exchange locations
Retail (US)1-10msInternet connection
International10-100msTrans-oceanic
Conversion helpers:
// Common time unit conversions
const MICROSECOND_NS: u64 = 1_000;
const MILLISECOND_NS: u64 = 1_000_000;

let latency_50us = 50 * MICROSECOND_NS;     // 50,000 ns
let latency_1ms = 1 * MILLISECOND_NS;       // 1,000,000 ns

market_data_latency_ns

Time from exchange event to market data reception. Units: Nanoseconds Represents:
  • Market data feed transmission
  • Decoder processing time
  • Network delay
Typical relationship: Usually faster than order latency (optimized path) Example:
let latency = LatencyConfig {
    order_latency_ns: 100_000,      // 100μs
    market_data_latency_ns: 50_000,  // 50μs (faster)
    ..Default::default()
};
Typical Values:
  • Aurora (CME): 2-5μs
  • Colo: 25-50μs
  • Retail: 0.5-5ms

ack_latency_ns

Time from exchange processing to acknowledgment reception. Units: Nanoseconds Represents:
  • Exchange order processing
  • Return network path
  • Gateway processing
Typical relationship: Similar to order latency (round-trip) Example:
let latency = LatencyConfig {
    order_latency_ns: 100_000,   // 100μs outbound
    ack_latency_ns: 100_000,     // 100μs return path
    ..Default::default()
};

// Total round-trip: ~200μs + exchange processing
Typical Values:
  • Colo: 50-100μs
  • Remote: 1-10ms

jitter_ns

Standard deviation of latency variability (jitter). Units: Nanoseconds Purpose: Simulates realistic network variance Distribution: Normal distribution (when use_random_jitter: true) Example:
let latency = LatencyConfig {
    order_latency_ns: 100_000,  // 100μs mean
    jitter_ns: 10_000,          // 10μs std dev
    use_random_jitter: true,
    ..Default::default()
};

// Actual latencies will be approximately:
// - 68% between 90-110μs (1 std dev)
// - 95% between 80-120μs (2 std dev)
// - 99.7% between 70-130μs (3 std dev)
Typical Values:
  • Low jitter (fiber): 1-5μs
  • Medium jitter (colo): 5-20μs
  • High jitter (internet): 50-500μs

use_random_jitter

Enables random jitter simulation. Values:
  • true (default): Adds random jitter to each latency
  • false: Deterministic latencies (for reproducibility)
Purpose:
  • Realistic simulation: Models network variance
  • Stress testing: See how strategy handles variable latency
  • Reproducibility: Disable for deterministic backtests
Example:
// Realistic with jitter
let realistic = LatencyConfig {
    order_latency_ns: 100_000,
    jitter_ns: 10_000,
    use_random_jitter: true,
    ..Default::default()
};

// Deterministic without jitter
let deterministic = LatencyConfig {
    order_latency_ns: 100_000,
    jitter_ns: 10_000,
    use_random_jitter: false,  // Fixed latency
    ..Default::default()
};

Configuration Presets

Aurora (CME Primary Colo)

Ultra-low latency at CME’s Aurora data center.
let aurora = LatencyConfig {
    order_latency_ns: 5_000,      // 5μs
    market_data_latency_ns: 2_000, // 2μs
    ack_latency_ns: 6_000,         // 6μs
    jitter_ns: 1_000,              // 1μs
    use_random_jitter: true,
};

Generic Colo

Typical co-location facility.
let colo = LatencyConfig {
    order_latency_ns: 50_000,      // 50μs
    market_data_latency_ns: 25_000, // 25μs
    ack_latency_ns: 60_000,         // 60μs
    jitter_ns: 5_000,               // 5μs
    use_random_jitter: true,
};

Remote/Cloud

Cloud-based or remote trading.
let remote = LatencyConfig {
    order_latency_ns: 500_000,      // 500μs
    market_data_latency_ns: 300_000, // 300μs
    ack_latency_ns: 600_000,         // 600μs
    jitter_ns: 50_000,               // 50μs
    use_random_jitter: true,
};

Retail/Internet

Typical retail trader connection.
let retail = LatencyConfig {
    order_latency_ns: 5_000_000,      // 5ms
    market_data_latency_ns: 3_000_000, // 3ms
    ack_latency_ns: 6_000_000,         // 6ms
    jitter_ns: 500_000,                // 500μs
    use_random_jitter: true,
};

Conservative (Pessimistic)

Worst-case latency for stress testing.
let conservative = LatencyConfig {
    order_latency_ns: 200_000,      // 200μs
    market_data_latency_ns: 100_000, // 100μs
    ack_latency_ns: 250_000,         // 250μs
    jitter_ns: 50_000,               // 50μs (high variance)
    use_random_jitter: true,
};

Optimistic (Best-case)

Best-case latency for strategy research.
let optimistic = LatencyConfig {
    order_latency_ns: 25_000,      // 25μs
    market_data_latency_ns: 10_000, // 10μs
    ack_latency_ns: 30_000,         // 30μs
    jitter_ns: 2_000,               // 2μs
    use_random_jitter: true,
};

LatencySimulator Usage

The LatencySimulator uses this configuration:
use nano_backtest::latency::LatencySimulator;
use nano_backtest::config::LatencyConfig;
use nano_core::types::Timestamp;

// Create simulator from config
let config = LatencyConfig {
    order_latency_ns: 100_000,
    market_data_latency_ns: 50_000,
    ack_latency_ns: 100_000,
    jitter_ns: 10_000,
    use_random_jitter: true,
};

let mut sim = LatencySimulator::from_config(&config);

// Calculate latencies
let submit_time = Timestamp::now();
let arrival_time = sim.order_arrival_time(submit_time);
let latency = arrival_time.as_nanos() - submit_time.as_nanos();

println!("Order latency: {}μs", latency / 1000);

Latency Impact Analysis

Understand how latency affects strategy performance:
use nano_backtest::{BacktestConfig, BacktestEngine};

// Test multiple latency scenarios
let latencies = vec![10_000, 50_000, 100_000, 200_000, 500_000];

for order_latency in latencies {
    let config = BacktestConfig {
        latency: LatencyConfig {
            order_latency_ns: order_latency,
            market_data_latency_ns: order_latency / 2,
            ack_latency_ns: order_latency,
            jitter_ns: order_latency / 10,
            use_random_jitter: true,
        },
        ..BacktestConfig::default()
    };
    
    let mut engine = BacktestEngine::new(config);
    engine.run(&mut strategy.clone());
    
    let metrics = engine.metrics();
    println!("Latency: {}μs, P&L: ${:.2}, Sharpe: {:.2}",
        order_latency / 1000,
        metrics.total_pnl,
        engine.stats().sharpe_ratio);
}

Time Unit Reference

// Time unit constants for readability
const NS_PER_US: u64 = 1_000;           // nanoseconds per microsecond
const NS_PER_MS: u64 = 1_000_000;       // nanoseconds per millisecond
const NS_PER_SEC: u64 = 1_000_000_000;  // nanoseconds per second

// Usage examples
let latency = LatencyConfig {
    order_latency_ns: 50 * NS_PER_US,     // 50 microseconds
    market_data_latency_ns: 25 * NS_PER_US,  // 25 microseconds
    ack_latency_ns: 60 * NS_PER_US,       // 60 microseconds
    jitter_ns: 5 * NS_PER_US,             // 5 microseconds
    use_random_jitter: true,
};

Best Practices

  1. Measure Reality: Benchmark your actual latencies before backtesting
  2. Test Multiple Scenarios: Run backtests with optimistic, realistic, and pessimistic latencies
  3. Include Jitter: Always enable random jitter for realistic results
  4. Conservative for Live: Use pessimistic latencies when validating for live trading
  5. Document Assumptions: Record what infrastructure your latencies model
  6. Asymmetric Latencies: Market data is often faster than order submission
  7. Latency Matters: For HFT, 10μs difference can dramatically impact performance
  8. Round-Trip Time: Total latency = order + exchange processing + ack

Complete Example

use nano_backtest::config::{BacktestConfig, LatencyConfig};
use nano_backtest::BacktestEngine;

// Define latency for colo environment
let latency_config = LatencyConfig {
    order_latency_ns: 75_000,      // 75μs
    market_data_latency_ns: 40_000, // 40μs
    ack_latency_ns: 80_000,         // 80μs
    jitter_ns: 8_000,               // 8μs std dev
    use_random_jitter: true,
};

// Create backtest config
let config = BacktestConfig {
    initial_capital: 1_000_000.0,
    latency: latency_config,
    ..BacktestConfig::default()
};

// Run backtest
let mut engine = BacktestEngine::new(config);
engine.run(&mut strategy);

// Analyze results
let metrics = engine.metrics();
println!("Backtest with {}μs latency:", 
    config.latency.order_latency_ns / 1000);
println!("  P&L: ${:.2}", metrics.total_pnl);
println!("  Trades: {}", metrics.num_trades);
println!("  Sharpe: {:.2}", engine.stats().sharpe_ratio);

See Also

Build docs developers (and LLMs) love