| Crates.io | market-maker-rs |
| lib.rs | market-maker-rs |
| version | 0.3.0 |
| created_at | 2025-10-13 16:25:55.21635+00 |
| updated_at | 2026-01-01 09:35:34.650372+00 |
| description | A Rust library implementing quantitative market making strategies, starting with the Avellaneda-Stoikov model |
| homepage | https://github.com/joaquinbejar/market-maker-rs |
| repository | https://github.com/joaquinbejar/market-maker-rs |
| max_upload_size | |
| id | 1880751 |
| size | 1,463,477 |
A comprehensive Rust library implementing quantitative market making strategies based on the Avellaneda-Stoikov model and extensions. This library provides production-ready components for building automated market making systems for financial markets.
Market making is the practice of simultaneously providing buy (bid) and sell (ask) quotes in a financial market. The market maker profits from the bid-ask spread while providing liquidity to the market.
options)chain)The Avellaneda-Stoikov model (2008) solves the optimal market making problem using stochastic control theory. Key formulas:
r = s - q × γ × σ² × (T - t)
spread = γ × σ² × (T - t) + (2/γ) × ln(1 + γ/k)
Where:
s: Mid priceq: Current inventoryγ: Risk aversion parameterσ: VolatilityT - t: Time remainingk: Order arrival intensitystrategy]: Quote generation algorithms (A-S, GLFT, Grid, Adaptive)position]: Inventory tracking and PnL managementmarket_state]: Market data and volatility estimationrisk]: Limits, circuit breakers, alerts, and portfolio riskanalytics]: Order flow, VPIN, intensity estimation, live metricsexecution]: Exchange connectivity, order management, latency trackingbacktest]: Historical simulation with fill models and metricstypes]: Common types, decimals, and error definitionsprelude]: Convenient re-exports of commonly used typesoptions: Options pricing, Greeks, and market making (feature: options)chain: Option chain integration and multi-strike quoting (feature: chain)api: REST/WebSocket API layer (feature: api)persistence: Data persistence layer (feature: persistence)multi_underlying: Multi-asset management (feature: multi-underlying)events: Event broadcasting system (feature: events)data_feeds: Real-time market data feeds (feature: data-feeds)use market_maker_rs::prelude::*;
// Calculate optimal quotes using Avellaneda-Stoikov
let mid_price = dec!(100.0);
let inventory = dec!(5.0);
let risk_aversion = dec!(0.5); // γ
let volatility = dec!(0.02);
let time_to_terminal_ms = 3600_000; // 1 hour
let order_intensity = dec!(1.5); // k
let (bid, ask) = market_maker_rs::strategy::avellaneda_stoikov::calculate_optimal_quotes(
mid_price,
inventory,
risk_aversion,
volatility,
time_to_terminal_ms,
order_intensity,
).unwrap();
println!("Bid: {}, Ask: {}", bid, ask);
prometheus: Enable Prometheus metrics export (adds prometheus, hyper, tokio dependencies)serde: Enable serialization/deserialization for all typesoptions: Enable OptionStratLib integration for options pricing and Greeks calculationchain: Enable Option-Chain-OrderBook integration (includes options)api: Enable REST/WebSocket API layer with OpenAPI documentationpersistence: Enable persistence layer for market maker datamulti-underlying: Enable multi-asset management with correlation trackingevents: Enable event broadcasting system for real-time updatesdata-feeds: Enable real-time market data feed abstractionsuse market_maker_rs::prelude::*;
// Set up position limits
let limits = RiskLimits::new(
dec!(100.0), // max 100 units position
dec!(10000.0), // max $10,000 notional
dec!(0.5), // 50% scaling factor
).unwrap();
// Check if order is allowed
let allowed = limits.check_order(dec!(50.0), dec!(10.0), dec!(100.0)).unwrap();
// Circuit breaker for automatic trading halts
let config = CircuitBreakerConfig::new(
dec!(1000.0), // max daily loss
dec!(0.05), // max loss per trade (5%)
5, // max consecutive losses
dec!(0.10), // max drawdown (10%)
300_000, // cooldown period (5 min)
60_000, // loss window (1 min)
).unwrap();
let breaker = CircuitBreaker::new(config);
use market_maker_rs::prelude::*;
// Configure backtest
let config = BacktestConfig::default()
.with_initial_capital(dec!(100000.0))
.with_fee_rate(dec!(0.001))
.with_slippage(SlippageModel::Fixed(dec!(0.01)));
// Run backtest with your strategy
let mut engine = BacktestEngine::new(config, strategy, data_source);
let result = engine.run();
println!("Net PnL: {}", result.net_pnl);
println!("Sharpe Ratio: {:?}", result.sharpe_ratio);
println!("Max Drawdown: {}", result.max_drawdown);
use market_maker_rs::risk::portfolio::*;
use market_maker_rs::dec;
// Create correlation matrix
let btc = AssetId::new("BTC");
let eth = AssetId::new("ETH");
let mut matrix = CorrelationMatrix::new(vec![btc.clone(), eth.clone()]);
matrix.set_correlation(&btc, ð, dec!(0.8)).unwrap();
// Calculate portfolio risk
let mut portfolio = PortfolioPosition::new();
portfolio.set_position(btc, dec!(1.0), dec!(0.05));
portfolio.set_position(eth, dec!(10.0), dec!(0.08));
let calculator = PortfolioRiskCalculator::new(matrix);
let vol = calculator.portfolio_volatility(&portfolio).unwrap();
options)use market_maker_rs::options::{OptionsAdapter, PortfolioGreeks, PositionGreeks};
use optionstratlib::model::option::Options;
// Calculate Greeks for an option
let greeks = OptionsAdapter::calculate_greeks(&option).unwrap();
println!("Delta: {}, Gamma: {}", greeks.delta, greeks.gamma);
// Aggregate portfolio Greeks
let mut portfolio = PortfolioGreeks::new();
portfolio.add(&greeks, dec!(10.0)); // 10 contracts
// Check delta neutrality
let shares_to_hedge = portfolio.shares_to_hedge(dec!(100.0));
options)use market_maker_rs::options::{
OptionsMarketMaker, OptionsMarketMakerImpl, OptionsMarketMakerConfig,
GreeksLimits, PortfolioGreeks,
};
// Create market maker with Greeks-aware quoting
let config = OptionsMarketMakerConfig::default();
let market_maker = OptionsMarketMakerImpl::new(config);
// Calculate Greeks-adjusted quotes
let (bid, ask) = market_maker.calculate_greeks_adjusted_quotes(
&option,
&portfolio_greeks,
&risk_limits,
).unwrap();
// Get delta hedge suggestions
let hedges = market_maker.calculate_delta_hedge(
&portfolio_greeks,
underlying_price,
"BTC",
).unwrap();
options)use market_maker_rs::options::{
GreeksRiskManager, AutoHedgerConfig, GreeksLimits, OrderDecision,
};
// Create risk manager with auto-hedging
let limits = GreeksLimits::default();
let hedger_config = AutoHedgerConfig::default();
let mut risk_manager = GreeksRiskManager::new("BTC", limits, hedger_config);
// Check if order is allowed
let decision = risk_manager.check_order(&option_greeks, dec!(10.0));
match decision {
OrderDecision::Allowed => { /* proceed */ },
OrderDecision::Scaled { new_size, .. } => { /* use scaled size */ },
OrderDecision::Rejected { reason } => { /* reject */ },
}
// Check if hedging is needed
if risk_manager.needs_hedge() {
let hedge = risk_manager.calculate_hedge_order(underlying_price);
}
chain)use market_maker_rs::chain::{ChainMarketMaker, ChainMarketMakerConfig};
use option_chain_orderbook::orderbook::ExpirationOrderBook;
use std::sync::Arc;
// Create chain market maker
let chain = Arc::new(ExpirationOrderBook::new("BTC", expiration));
let config = ChainMarketMakerConfig::default();
let mm = ChainMarketMaker::new(chain, config);
// Refresh all quotes across the chain
let quotes = mm.refresh_all_quotes(underlying_price).unwrap();
// Check chain risk status
let status = mm.check_chain_risk();
if !status.can_quote() {
// Stop quoting or hedge
}
multi-underlying)use market_maker_rs::multi_underlying::{
MultiUnderlyingManager, UnderlyingConfig, CapitalAllocationStrategy,
};
use market_maker_rs::dec;
// Create manager with $1M capital
let mut manager = MultiUnderlyingManager::new(dec!(1_000_000))
.with_allocation_strategy(CapitalAllocationStrategy::RiskParity)
.with_max_total_delta(dec!(50000));
// Add underlyings with target weights
manager.add_underlying(UnderlyingConfig::new("BTC", dec!(0.40))).unwrap();
manager.add_underlying(UnderlyingConfig::new("ETH", dec!(0.30))).unwrap();
// Set correlations
manager.set_correlation("BTC", "ETH", dec!(0.85));
// Update market data
manager.update_price("BTC", dec!(45000));
manager.update_greeks("BTC", dec!(5.5), dec!(0.02), dec!(1500));
// Get unified risk view
let risk = manager.get_unified_risk();
println!("Total delta: {}", risk.greeks.total_dollar_delta);
// Get cross-asset hedge suggestions
let hedges = manager.get_cross_asset_hedges();
events)use market_maker_rs::events::{
EventBroadcaster, EventBroadcasterConfig, EventFilter, EventType,
MarketMakerEvent, Side,
};
use std::sync::Arc;
// Create broadcaster
let config = EventBroadcasterConfig::default();
let broadcaster = Arc::new(EventBroadcaster::new(config));
// Subscribe to all events
let mut all_rx = broadcaster.subscribe();
// Subscribe with filter (fills only)
let filter = EventFilter::new()
.with_event_types([EventType::OrderFilled])
.with_symbols(["BTC".to_string()]);
let mut filtered_rx = broadcaster.subscribe_filtered(filter);
// Broadcast an event
broadcaster.broadcast(MarketMakerEvent::OrderFilled {
order_id: "ORD-001".to_string(),
symbol: "BTC".to_string(),
instrument: "BTC-PERP".to_string(),
side: Side::Buy,
quantity: 10,
price: 50000,
fee: 5,
edge: 100,
timestamp: 1234567890,
}).await;
// Get history for reconnection
let missed = broadcaster.get_reconnection_history(last_sequence).await;
This project includes a Makefile with common tasks to simplify development. Here's a list of useful commands:
make build # Compile the project
make release # Build in release mode
make run # Run the main binary
make test # Run all tests
make fmt # Format code
make fmt-check # Check formatting without applying
make lint # Run clippy with warnings as errors
make lint-fix # Auto-fix lint issues
make fix # Auto-fix Rust compiler suggestions
make check # Run fmt-check + lint + test
make doc # Check for missing docs via clippy
make doc-open # Build and open Rust documentation
make create-doc # Generate internal docs
make readme # Regenerate README using cargo-readme
make publish # Prepare and publish crate to crates.io
make coverage # Generate code coverage report (XML)
make coverage-html # Generate HTML coverage report
make open-coverage # Open HTML report
make bench # Run benchmarks using Criterion
make bench-show # Open benchmark report
make bench-save # Save benchmark history snapshot
make bench-compare # Compare benchmark runs
make bench-json # Output benchmarks in JSON
make bench-clean # Remove benchmark data
make git-log # Show commits on current branch vs main
make check-spanish # Check for Spanish words in code
make zip # Create zip without target/ and temp files
make tree # Visualize project tree (excludes common clutter)
make workflow-build # Simulate build workflow
make workflow-lint # Simulate lint workflow
make workflow-test # Simulate test workflow
make workflow-coverage # Simulate coverage workflow
make workflow # Run all workflows
ℹ️ Requires act for local workflow simulation and cargo-tarpaulin for coverage.
We welcome contributions to this project! If you would like to contribute, please follow these steps:
If you have any questions, issues, or would like to provide feedback, please feel free to contact the project maintainer:
Author: Joaquín Béjar García
Email: jb@taunais.com
Telegram: @joaquin_bejar
Repository: https://github.com/joaquinbejar/market-maker-rs
Documentation: https://docs.rs/market-maker-rs
We appreciate your interest and look forward to your contributions!
License: MIT