use std::collections::HashMap;
use chrono::{DateTime, FixedOffset, Utc};
use hyperliquid_backtest::prelude::*;
use hyperliquid_backtest::risk_manager::{RiskManager, RiskError, AssetClass};
use hyperliquid_backtest::trading_mode::{RiskConfig, TradingMode};
use hyperliquid_backtest::trading_mode_impl::{Position, OrderRequest, OrderSide, OrderType, TimeInForce};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Risk Management Configuration Example");
println!("====================================\n");
println!("1. Creating risk configurations for different trading modes...");
let live_risk_config = RiskConfig {
max_position_size_pct: 0.05, max_daily_loss_pct: 0.02, stop_loss_pct: 0.05, take_profit_pct: 0.10, max_leverage: 2.0, max_open_positions: 5, max_concentration_pct: 0.20, max_correlation: 0.7, max_drawdown_pct: 0.15, max_volatility_pct: 0.02, emergency_stop_loss_pct: 0.05, };
let paper_risk_config = RiskConfig {
max_position_size_pct: 0.10, max_daily_loss_pct: 0.05, stop_loss_pct: 0.08, take_profit_pct: 0.15, max_leverage: 5.0, max_open_positions: 10, max_concentration_pct: 0.30, max_correlation: 0.8, max_drawdown_pct: 0.25, max_volatility_pct: 0.03, emergency_stop_loss_pct: 0.10, };
let backtest_risk_config = RiskConfig {
max_position_size_pct: 0.20, max_daily_loss_pct: 0.10, stop_loss_pct: 0.15, take_profit_pct: 0.30, max_leverage: 10.0, max_open_positions: 20, max_concentration_pct: 0.50, max_correlation: 0.9, max_drawdown_pct: 0.35, max_volatility_pct: 0.05, emergency_stop_loss_pct: 0.15, };
println!(" Live trading risk config: {:?}", live_risk_config);
println!(" Paper trading risk config: {:?}", paper_risk_config);
println!(" Backtesting risk config: {:?}", backtest_risk_config);
println!("\n2. Initializing risk managers for different trading modes...");
let initial_portfolio_value = 100000.0;
let mut live_risk_manager = RiskManager::new(live_risk_config, initial_portfolio_value);
let mut paper_risk_manager = RiskManager::new(paper_risk_config, initial_portfolio_value);
let mut backtest_risk_manager = RiskManager::new(backtest_risk_config, initial_portfolio_value);
println!(" Risk managers initialized with ${:.2} portfolio value", initial_portfolio_value);
println!("\n3. Creating sample positions and orders...");
let mut positions = HashMap::new();
positions.insert("BTC".to_string(), create_position("BTC", 1.0, 50000.0, 51000.0));
positions.insert("ETH".to_string(), create_position("ETH", 10.0, 3000.0, 3100.0));
let btc_order = OrderRequest {
symbol: "BTC".to_string(),
side: OrderSide::Buy,
order_type: OrderType::Limit,
quantity: 0.5,
price: Some(51000.0),
reduce_only: false,
time_in_force: TimeInForce::GoodTilCancelled,
};
let eth_order = OrderRequest {
symbol: "ETH".to_string(),
side: OrderSide::Buy,
order_type: OrderType::Limit,
quantity: 5.0,
price: Some(3100.0),
reduce_only: false,
time_in_force: TimeInForce::GoodTilCancelled,
};
let sol_order = OrderRequest {
symbol: "SOL".to_string(),
side: OrderSide::Buy,
order_type: OrderType::Limit,
quantity: 100.0,
price: Some(100.0),
reduce_only: false,
time_in_force: TimeInForce::GoodTilCancelled,
};
println!(" Created sample positions and orders");
println!("\n4. Validating orders against risk limits...");
println!("\n Validating BTC order (0.5 BTC @ $51,000 = $25,500):");
match live_risk_manager.validate_order(&btc_order, &positions) {
Ok(_) => println!(" Live trading: Order ACCEPTED"),
Err(e) => println!(" Live trading: Order REJECTED - {}", e),
}
match paper_risk_manager.validate_order(&btc_order, &positions) {
Ok(_) => println!(" Paper trading: Order ACCEPTED"),
Err(e) => println!(" Paper trading: Order REJECTED - {}", e),
}
match backtest_risk_manager.validate_order(&btc_order, &positions) {
Ok(_) => println!(" Backtesting: Order ACCEPTED"),
Err(e) => println!(" Backtesting: Order REJECTED - {}", e),
}
println!("\n Validating SOL order (100 SOL @ $100 = $10,000):");
match live_risk_manager.validate_order(&sol_order, &positions) {
Ok(_) => println!(" Live trading: Order ACCEPTED"),
Err(e) => println!(" Live trading: Order REJECTED - {}", e),
}
match paper_risk_manager.validate_order(&sol_order, &positions) {
Ok(_) => println!(" Paper trading: Order ACCEPTED"),
Err(e) => println!(" Paper trading: Order REJECTED - {}", e),
}
match backtest_risk_manager.validate_order(&sol_order, &positions) {
Ok(_) => println!(" Backtesting: Order ACCEPTED"),
Err(e) => println!(" Backtesting: Order REJECTED - {}", e),
}
println!("\n5. Generating stop-loss and take-profit orders...");
let btc_position = positions.get("BTC").unwrap();
if let Some(stop_loss) = live_risk_manager.generate_stop_loss(btc_position, "btc_order_1") {
println!(" BTC Stop-Loss: {} {} @ ${:.2}",
stop_loss.side, stop_loss.quantity, stop_loss.trigger_price);
}
if let Some(take_profit) = live_risk_manager.generate_take_profit(btc_position, "btc_order_1") {
println!(" BTC Take-Profit: {} {} @ ${:.2}",
take_profit.side, take_profit.quantity, take_profit.trigger_price);
}
println!("\n6. Demonstrating daily loss limit...");
let new_portfolio_value = initial_portfolio_value * 0.98; let realized_pnl_delta = -2000.0;
println!(" Updating portfolio value to ${:.2} (2% loss)", new_portfolio_value);
match live_risk_manager.update_portfolio_value(new_portfolio_value, realized_pnl_delta) {
Ok(_) => println!(" Live trading: Daily loss within limits"),
Err(e) => println!(" Live trading: Daily loss limit triggered - {}", e),
}
let new_portfolio_value = initial_portfolio_value * 0.97; let realized_pnl_delta = -1000.0;
println!(" Updating portfolio value to ${:.2} (3% loss)", new_portfolio_value);
match live_risk_manager.update_portfolio_value(new_portfolio_value, realized_pnl_delta) {
Ok(_) => println!(" Live trading: Daily loss within limits"),
Err(e) => println!(" Live trading: Daily loss limit triggered - {}", e),
}
println!("\n7. Demonstrating emergency stop functionality...");
println!(" Activating emergency stop");
live_risk_manager.activate_emergency_stop();
match live_risk_manager.validate_order(&btc_order, &positions) {
Ok(_) => println!(" Order ACCEPTED despite emergency stop (unexpected)"),
Err(e) => println!(" Order REJECTED due to emergency stop - {}", e),
}
println!(" Deactivating emergency stop");
live_risk_manager.deactivate_emergency_stop();
println!("\n8. Calculating margin requirements...");
let btc_position_value = 50000.0; let eth_position_value = 30000.0; let sol_position_value = 10000.0;
println!(" Live trading margin requirements:");
println!(" BTC position (${:.2}): ${:.2} margin required",
btc_position_value, live_risk_manager.calculate_required_margin(btc_position_value));
println!(" ETH position (${:.2}): ${:.2} margin required",
eth_position_value, live_risk_manager.calculate_required_margin(eth_position_value));
println!(" SOL position (${:.2}): ${:.2} margin required",
sol_position_value, live_risk_manager.calculate_required_margin(sol_position_value));
println!(" Paper trading margin requirements:");
println!(" BTC position (${:.2}): ${:.2} margin required",
btc_position_value, paper_risk_manager.calculate_required_margin(btc_position_value));
println!(" ETH position (${:.2}): ${:.2} margin required",
eth_position_value, paper_risk_manager.calculate_required_margin(eth_position_value));
println!(" SOL position (${:.2}): ${:.2} margin required",
sol_position_value, paper_risk_manager.calculate_required_margin(sol_position_value));
println!("\n9. Demonstrating risk configuration for different market conditions...");
let low_volatility_config = create_market_condition_risk_config("low_volatility");
let high_volatility_config = create_market_condition_risk_config("high_volatility");
let trending_market_config = create_market_condition_risk_config("trending");
let ranging_market_config = create_market_condition_risk_config("ranging");
println!(" Low Volatility Risk Config:");
print_risk_config_summary(&low_volatility_config);
println!(" High Volatility Risk Config:");
print_risk_config_summary(&high_volatility_config);
println!(" Trending Market Risk Config:");
print_risk_config_summary(&trending_market_config);
println!(" Ranging Market Risk Config:");
print_risk_config_summary(&ranging_market_config);
println!("\n10. Demonstrating risk manager integration with trading modes...");
println!(" Creating trading mode managers with appropriate risk configurations");
println!(" - Backtest mode: Uses more aggressive risk parameters");
println!(" - Paper trading mode: Uses moderate risk parameters");
println!(" - Live trading mode: Uses conservative risk parameters");
println!(" - Each mode automatically applies the appropriate risk checks");
println!("\nRisk management configuration example completed successfully!");
Ok(())
}
fn create_position(symbol: &str, size: f64, entry_price: f64, current_price: f64) -> Position {
Position {
symbol: symbol.to_string(),
size,
entry_price,
current_price,
unrealized_pnl: (current_price - entry_price) * size,
realized_pnl: 0.0,
funding_pnl: 0.0,
timestamp: Utc::now().with_timezone(&FixedOffset::east(0)),
}
}
fn create_market_condition_risk_config(market_condition: &str) -> RiskConfig {
match market_condition {
"low_volatility" => RiskConfig {
max_position_size_pct: 0.15, max_daily_loss_pct: 0.03, stop_loss_pct: 0.05, take_profit_pct: 0.10, max_leverage: 5.0, max_open_positions: 10, max_concentration_pct: 0.30, max_correlation: 0.8, max_drawdown_pct: 0.20, max_volatility_pct: 0.02, emergency_stop_loss_pct: 0.07, },
"high_volatility" => RiskConfig {
max_position_size_pct: 0.05, max_daily_loss_pct: 0.02, stop_loss_pct: 0.07, take_profit_pct: 0.15, max_leverage: 2.0, max_open_positions: 5, max_concentration_pct: 0.20, max_correlation: 0.6, max_drawdown_pct: 0.15, max_volatility_pct: 0.03, emergency_stop_loss_pct: 0.05, },
"trending" => RiskConfig {
max_position_size_pct: 0.10, max_daily_loss_pct: 0.03, stop_loss_pct: 0.08, take_profit_pct: 0.20, max_leverage: 3.0, max_open_positions: 7, max_concentration_pct: 0.25, max_correlation: 0.7, max_drawdown_pct: 0.18, max_volatility_pct: 0.025, emergency_stop_loss_pct: 0.06, },
"ranging" => RiskConfig {
max_position_size_pct: 0.08, max_daily_loss_pct: 0.02, stop_loss_pct: 0.05, take_profit_pct: 0.08, max_leverage: 2.5, max_open_positions: 8, max_concentration_pct: 0.20, max_correlation: 0.6, max_drawdown_pct: 0.15, max_volatility_pct: 0.02, emergency_stop_loss_pct: 0.05, },
_ => RiskConfig::default(),
}
}
fn print_risk_config_summary(config: &RiskConfig) {
println!(" - Max position size: {:.1}% of portfolio", config.max_position_size_pct * 100.0);
println!(" - Max daily loss: {:.1}%", config.max_daily_loss_pct * 100.0);
println!(" - Stop loss: {:.1}%", config.stop_loss_pct * 100.0);
println!(" - Take profit: {:.1}%", config.take_profit_pct * 100.0);
println!(" - Max leverage: {:.1}x", config.max_leverage);
println!(" - Max open positions: {}", config.max_open_positions);
}