use market_maker_rs::prelude::*;
use market_maker_rs::strategy::interface::{AvellanedaStoikov, DefaultAvellanedaStoikov};
use market_maker_rs::types::error::MMResult;
struct CustomStrategy {
base_strategy: DefaultAvellanedaStoikov,
min_additional_spread: Decimal,
}
impl CustomStrategy {
fn new(min_additional_spread: Decimal) -> Self {
Self {
base_strategy: DefaultAvellanedaStoikov,
min_additional_spread,
}
}
}
impl AvellanedaStoikov for CustomStrategy {
fn calculate_reservation_price(
&self,
mid_price: Decimal,
inventory: Decimal,
risk_aversion: Decimal,
volatility: Decimal,
time_to_terminal_ms: u64,
) -> MMResult<Decimal> {
self.base_strategy.calculate_reservation_price(
mid_price,
inventory,
risk_aversion,
volatility,
time_to_terminal_ms,
)
}
fn calculate_optimal_spread(
&self,
risk_aversion: Decimal,
volatility: Decimal,
time_to_terminal_ms: u64,
order_intensity: Decimal,
) -> MMResult<Decimal> {
let base_spread = self.base_strategy.calculate_optimal_spread(
risk_aversion,
volatility,
time_to_terminal_ms,
order_intensity,
)?;
Ok(base_spread + self.min_additional_spread)
}
fn calculate_optimal_quotes(
&self,
mid_price: Decimal,
inventory: Decimal,
risk_aversion: Decimal,
volatility: Decimal,
time_to_terminal_ms: u64,
order_intensity: Decimal,
) -> MMResult<(Decimal, Decimal)> {
let reservation = self.calculate_reservation_price(
mid_price,
inventory,
risk_aversion,
volatility,
time_to_terminal_ms,
)?;
let spread = self.calculate_optimal_spread(
risk_aversion,
volatility,
time_to_terminal_ms,
order_intensity,
)?;
let half_spread = spread / dec!(2);
let bid = reservation - half_spread;
let ask = reservation + half_spread;
Ok((bid, ask))
}
}
fn main() {
println!("=== Synchronous Trait Usage Example ===\n");
let mid_price = dec!(100.0);
let inventory = dec!(10.0); let risk_aversion = dec!(0.1);
let volatility = dec!(0.2);
let time_to_terminal = 3600000; let order_intensity = dec!(1.5);
println!("Market Parameters:");
println!(" Mid Price: ${}", mid_price);
println!(" Inventory: {} units", inventory);
println!(" Risk Aversion: {}", risk_aversion);
println!(" Volatility: {}", volatility);
println!(" Time to Terminal: {} ms", time_to_terminal);
println!(" Order Intensity: {}", order_intensity);
println!();
println!("=== Example 1: Default Strategy ===");
let default_strategy = DefaultAvellanedaStoikov;
let reservation = default_strategy
.calculate_reservation_price(
mid_price,
inventory,
risk_aversion,
volatility,
time_to_terminal,
)
.expect("Failed to calculate reservation price");
let spread = default_strategy
.calculate_optimal_spread(risk_aversion, volatility, time_to_terminal, order_intensity)
.expect("Failed to calculate spread");
let (bid, ask) = default_strategy
.calculate_optimal_quotes(
mid_price,
inventory,
risk_aversion,
volatility,
time_to_terminal,
order_intensity,
)
.expect("Failed to calculate quotes");
println!("Reservation Price: ${:.2}", reservation);
println!("Optimal Spread: ${:.4}", spread);
println!("Bid: ${:.2}", bid);
println!("Ask: ${:.2}", ask);
println!("Actual Spread: ${:.4}", ask - bid);
println!();
println!("=== Example 2: Custom Strategy (with additional spread) ===");
let custom_strategy = CustomStrategy::new(dec!(0.5));
let custom_spread = custom_strategy
.calculate_optimal_spread(risk_aversion, volatility, time_to_terminal, order_intensity)
.expect("Failed to calculate custom spread");
let (custom_bid, custom_ask) = custom_strategy
.calculate_optimal_quotes(
mid_price,
inventory,
risk_aversion,
volatility,
time_to_terminal,
order_intensity,
)
.expect("Failed to calculate custom quotes");
println!("Custom Spread: ${:.4}", custom_spread);
println!("Custom Bid: ${:.2}", custom_bid);
println!("Custom Ask: ${:.2}", custom_ask);
println!("Actual Spread: ${:.4}", custom_ask - custom_bid);
println!();
println!("=== Comparison ===");
println!("Additional Spread: ${:.4}", custom_spread - spread);
println!("Bid Difference: ${:.2}", custom_bid - bid);
println!("Ask Difference: ${:.2}", custom_ask - ask);
println!("\n✓ Trait usage examples completed successfully!");
}