This project implements and extends the static order allocation model from Cont & Kukanov (2013) to simulate and evaluate optimal order placement strategies in fragmented limit order markets. Using historical L1 order book data, the simulator computes execution costs and compares optimized allocation against baseline strategies such as TWAP, VWAP, and Best Ask.
βWe calibrate the parameters Ξ»_over, Ξ»_under, and ΞΈ_queue based on empirical backtesting to minimize total execution cost.β
β Cont & Kukanov (2013)
Cont & Kukanov formulate a convex optimization problem to split a parent order (S) into market and limit orders across multiple venues. Each venue has:
- Initial queue size
Q_k, outflow uncertaintyΞΎ_k - Fee
f_k, Rebater_k - Execution uncertainty modeled via risk penalties (ΞΈ), underfill (Ξ»_u), and overfill (Ξ»_o)
The goal is to minimize total expected cost, factoring in partial fills and market impact.
The project follows a clear pipeline for simulating and comparing execution strategies:
-
preprocess_data(filepath)
β Loads and cleans raw L1 data; drops duplicates per timestamp and venue. -
get_venue_snapshot(df, timestamp)
β Extracts venue-level snapshot (price, size, fee/rebate) at a given timestamp.
-
allocate(order_size, venues, Ξ»_over, Ξ»_under, ΞΈ_queue)
β Brute-force grid search of all feasible order splits across venues.
πΈ Implements static allocation logic using step size to enumerate splits. -
compute_cost(split, venues, order_size, Ξ»_o, Ξ»_u, ΞΈ)
β Calculates execution cost:- Market order cost
- Rebate from limit orders
- Penalties for underfill/overfill and queue risk
πΈ Implements equation from the paper, using queue-adjusted fills.
-
execute_order(split, venues)
β Simulates real fill outcomes: partial fills at best ask, cash cost calculated.
-
best_ask_strategy(df, order_size)
β Naively fills orders from the cheapest venue until completion. -
twap_strategy(df, order_size, interval_seconds=60)
β Time-weighted execution: evenly splits order over time intervals. -
vwap_strategy(df, order_size)
β Volume-weighted execution: assigns order size based on venue volume share.
-
backtest(df, Ξ»_over, Ξ»_under, ΞΈ_queue)
β Runs a full simulation over the dataset for given parameter values. -
optimize_parameters(df, init_params)
β Uses finite-difference gradient descent to tune parameters. -
parameter_search(df)
β Repeats optimization with random restarts to avoid local minima. -
calculate_bps_savings(cont_cost, baseline_cost, order_size)
β Computes cost savings in basis points (bps) vs baseline strategies. -
main()
β End-to-end pipeline: loads data, finds best parameters, evaluates baselines, compares results.
The following functions implement the pseudocode from the paper's static order placement model:
| Function | Paper Reference | Description |
|---|---|---|
allocate |
Section 3, Eqn (2) | Brute-force optimizer for discrete order allocation |
compute_cost |
Section 3, Eqn (4) | Cost function accounting for fees, rebates, and penalties |
The simulation outputs:
- Optimal parameters: Ξ»_over, Ξ»_under, ΞΈ_queue
- Execution cost and average price of optimal vs baseline
- Savings in basis points (bps)
Current output:
{
"best_parameters": {
"lambda_over": 0.052485551207673814,
"lambda_under": 0.11143111457488658,
"theta_queue": 0.003227328859860633
},
"cont_kukanov": {
"total_cost": 1113700.0,
"avg_price": 222.74
},
"best_ask": {
"total_cost": 1114102.2800000003,
"avg_price": 222.82045600000006
},
"twap": {
"total_cost": 1114102.2800000003,
"avg_price": 222.82045600000006
},
"vwap": {
"total_cost": 1115319.1590477177,
"avg_price": 223.06383180954353
},
"savings_bps": {
"vs_best_ask": 3.610799539879539,
"vs_twap": 3.610799539879539,
"vs_vwap": 14.517450315298746
}
}