High-Frequency Trading is a form of algorithmic trading that uses powerful computers to execute a large number of orders in fractions of a second. HFT firms use complex algorithms to analyze multiple markets and execute orders based on market conditions.
Key Characteristics:
Market making is a common HFT strategy where traders provide liquidity by simultaneously placing buy and sell orders. The market maker profits from the bid-ask spread - the difference between the price at which they're willing to buy (bid) and sell (ask).
How it works:
Risks: Market makers face inventory risk (holding positions) and adverse selection (trading with informed traders).
Bid-Ask Spread:
Spread = Best Ask Price - Best Bid Price. This is the market maker's primary source of revenue.
Order Book:
A list of buy (bids) and sell (asks) orders showing the depth of the market at different price levels.
Slippage:
The difference between expected execution price and actual execution price, often caused by market movement during order processing.
Market Impact:
The effect of a large trade on the market price. Large orders can move prices against the trader.
The simulator runs in discrete time steps, updating prices and executing trades at regular intervals. The main simulation loop performs the following steps:
Price Source → Price Model/WebSocket → Strategy Engine → Trade Execution → Cash/Position Update → P&L Calculation → Visualization
The simulator uses React refs to prevent simulation restart when parameters change, allowing real-time parameter adjustment during simulation.
The simulation runs at a configurable speed (5-95ms per step). Each step represents one "tick" in the simulation.
interval = max(8ms, 100ms - speed)
Lower speed values = faster simulation. The minimum interval is 8ms to prevent browser overload.
The simulator implements several stochastic differential equations (SDEs) for price dynamics. Each model is discretized using appropriate numerical methods. These models are used when "Synthetic Data" is selected.
Continuous SDE:
dSt = μSt dt + σSt dWt
Discrete form (exponential Euler):
St+1 = St · exp((μ - 0.5σ²)Δt + σ√Δt · Z)
Where: μ = drift, σ = volatility, Z ~ N(0,1), Δt = time step
Use case: Standard model for stock prices, assumes constant volatility
Continuous SDE:
dSt = θ(μ - St)dt + σ dWt
Discrete form (Euler-Maruyama):
St+1 = St + θ(μ - St)Δt + σ√Δt · Z
Where: θ = mean reversion speed, μ = long-term mean, σ = volatility
Use case: Assets that revert to a mean (e.g., interest rates, spreads)
Two-factor model:
dSt = μSt dt + √vt St dW1,t
dvt = κ(θ - vt)dt + σv√vt dW2,t
Discrete form:
vt+1 = vt + κ(θ - vt)Δt + σv√vt√Δt · W2
St+1 = St · exp((μ - 0.5vt)Δt + √vt√Δt · W1)
Where: κ = vol mean reversion, θ = long-run variance, σv = vol of vol, Corr(W1, W2) = ρ
Use case: Modeling volatility clustering and smile effects
Variance update (GARCH(1,1)):
ht = ω + αr²t-1 + βht-1
Price evolution:
St+1 = St · exp((μ - 0.5ht)Δt + √ht√Δt · Z)
Where: rt-1 = log return, ω = base variance, α = ARCH term, β = GARCH term
Use case: Modeling volatility clustering observed in financial markets
Combines continuous diffusion with jumps:
St+1 = St · (1 + J) · exp((μ - 0.5σ²)Δt + σ√Δt · Z)
Where: J = jump component (with probability λ), J ~ N(μj, σ²j) when jump occurs
Use case: Modeling sudden price movements (news events, flash crashes)
Volatility scales with recent returns:
σt = σ0 · (1 + η · |rt-1|)
St+1 = St · exp((μ - 0.5σ²t)Δt + σt√Δt · Z)
Where: η = elasticity parameter, rt-1 = recent return
Use case: Modeling volatility that responds to recent price movements
Market making conditions determine when and which side to trade. Each condition uses different market signals to trigger trades.
Trades randomly with probability based on trading frequency. This is the simplest condition and serves as a baseline.
P(trade) = tradingFrequency
side = random(BUY, SELL) with bias toward reducing large positions
Use case: Testing basic execution mechanics, understanding fee impact
Parameters: tradingFrequency (0-1, probability of trading each tick)
Trades to maintain target inventory level. This is a key risk management technique in real market making - traders need to avoid accumulating too much inventory in one direction.
deviation = position - inventoryTarget
if |deviation| > max(rebalanceThreshold · maxPosition, 10):
side = SELL if deviation > 0, BUY if deviation < 0
Parameters: inventoryTarget (desired position), rebalanceThreshold (sensitivity %), maxPosition (limit)
Use case: Managing inventory risk, maintaining neutral position
How it works: When position deviates from target by more than threshold, trades in opposite direction to rebalance.
Trades when the bid-ask spread is wide enough to be profitable after fees. In live mode, uses actual spread from order book.
effectiveSpread = (liveSpread OR spread · spreadMultiplier · price)
if effectiveSpread > minSpread: trade
Parameters: spread (base spread %), spreadMultiplier (adjustment factor), minSpread (minimum to trade)
Use case: Only trading when spread is profitable, optimizing for wider spreads
How it works: Compares current spread (real or synthetic) against minimum threshold. Only trades when spread is wide enough.
Trades against price movements, assuming prices will revert to mean. This is a contrarian strategy that profits from price reversals.
ΔP = |Pt - Pt-1|
ΔP% = ΔP / Pt-1
if (ΔP > threshold OR ΔP% > threshold%):
side = SELL if Pt > Pt-1 (sell high), BUY if Pt < Pt-1 (buy low)
Parameters: priceChangeThreshold (minimum price movement to trigger)
Use case: Mean-reversion strategies, profiting from temporary price dislocations
How it works: Detects price movements and trades in opposite direction, betting on reversion.
Trades when recent volatility exceeds threshold. High volatility often means more trading opportunities and wider spreads.
volt = (1/n) · Σ|ri| for i in [t-n, t]
where ri = (Pi - Pi-1) / Pi-1
if volt > volatilityThreshold: trade
Parameters: volatilityThreshold (minimum volatility %), uses last 5 price points
Use case: Trading during volatile periods, capturing wider spreads in volatile markets
How it works: Calculates recent volatility from price returns. Trades when volatility exceeds threshold.
When "Live Crypto Feed" is selected, the simulator connects to Binance WebSocket streams for real-time Bitcoin (BTC/USDT) data.
Two WebSocket connections:
wss://stream.binance.com:9443/ws/btcusdt@tickerwss://stream.binance.com:9443/ws/btcusdt@depth20@100msExecution in Live Mode:
The WebSocket status indicator shows:
Understanding how profits, losses, and statistics are calculated is crucial for interpreting simulation results.
P&L is calculated using mark-to-market accounting, which values your current position at the current market price.
P&L = cash + (position × currentPrice) - initialCash
Components:
Note: This is unrealized P&L. Realized P&L would only count closed positions.
Live: execPrice = bestAsk (BUY) or bestBid (SELL)
Synthetic: execPrice = midPrice ± spreadAdjustment
slippage = min(maxSlippage, slippagePct × price × random[-1, 1])
impact = marketImpact × size × direction
finalPrice = execPrice + slippage + impact
Each trade incurs multiple cost components:
totalFee = commissionPerTrade + (commissionPct × |price × size|) + transactionCost
When a trade executes:
BUY Trade:
cashFlow = -(price × size + fees)
position += size
SELL Trade:
cashFlow = +(price × size - fees)
position -= size
Win rate measures how many trades improved your total equity (cash + position value).
For each trade (after the first):
winRate = (wins / (totalTrades - 1)) × 100%
Note: First trade is excluded as there's no "before" state to compare.
Market microstructure refers to the mechanics of how trades are executed, including price rounding, order sizing, and execution frictions.
The minimum price increment allowed. All prices are rounded to the nearest tick.
roundedPrice = round(price / tickSize) × tickSize
Example: If tickSize = 0.01, price $100.123 becomes $100.12
The minimum trade size increment. All order sizes are rounded down to the nearest lot multiple.
roundedSize = floor(size / lotSize) × lotSize
Example: If lotSize = 10, order size 23 becomes 20
The difference between expected and actual execution price. Can be positive (favorable) or negative (unfavorable).
slippage = min(maxSlippage, slippagePct × price × random[-1, 1])
slippagePct: Base slippage percentage (e.g., 0.1% = 0.001)
maxSlippage: Maximum slippage cap to prevent extreme values
Large orders move prices. Market impact models this effect - larger orders have more impact.
impact = marketImpact × size × direction
direction: +1 for BUY (pushes price up), -1 for SELL (pushes price down)
marketImpact: Impact per unit of size (e.g., 0.001 = $0.001 per unit)
Simulates network/system delays. With latency > 0, some ticks are randomly skipped.
if random() < latency: skip this tick
latency: Probability of skipping a tick (0 = no latency, 1 = always skip)
The simulator enforces position limits to prevent unlimited accumulation:
if |position| >= maxPosition: block new trades
Inventory Management: The inventory-based condition helps maintain target inventory levels, reducing directional risk. This is critical in real market making to avoid large losses from adverse price movements.
Synthetic Data: Uses mathematical models to generate prices. Useful for:
Live Data: Uses real Bitcoin prices from Binance. Useful for:
Understanding how parameters affect trading behavior:
This simulator makes several simplifications compared to real HFT systems:
Despite simplifications, the simulator captures key aspects of market making: spread capture, inventory management, and the impact of fees and slippage on profitability.