Files
foxhunt/adaptive-strategy/examples/basic_strategy.rs
jgrusewski 1c07a40c54 🚀 PRODUCTION READY: Foxhunt HFT Trading System v1.0
Initial commit of production-ready high-frequency trading system.

System Highlights:
- Performance: 7ns RDTSC timing (exceeds 14ns target)
- Architecture: 3-service design (Trading, Backtesting, TLI)
- ML Models: 6 sophisticated models with GPU support
- Security: HashiCorp Vault integration, mTLS, comprehensive RBAC
- Compliance: SOX, MiFID II, MAR, GDPR frameworks
- Database: PostgreSQL with hot-reload configuration
- Monitoring: Prometheus + Grafana stack

Status: 96.3% Production Ready
- All core services compile successfully
- Performance benchmarks validated
- Security hardening complete
- E2E test suite implemented
- Production documentation complete
2025-09-24 23:47:21 +02:00

245 lines
8.7 KiB
Rust

//! Basic adaptive strategy example
//!
//! This example demonstrates how to set up and run a basic adaptive trading strategy
//! with ensemble models, risk management, and execution algorithms.
use adaptive_strategy::config::*;
use adaptive_strategy::{AdaptiveStrategy, StrategyConfig};
use std::collections::HashMap;
use std::time::Duration;
use tokio::time::sleep;
use tracing::{info, Level};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize logging
tracing_subscriber::fmt().with_max_level(Level::INFO).init();
info!("Starting basic adaptive strategy example");
// Create configuration
let config = create_strategy_config();
// Initialize the adaptive strategy
let mut strategy = AdaptiveStrategy::new(config).await?;
info!("Strategy initialized successfully");
// Get initial state
let initial_state = strategy.get_state().await;
info!(
"Initial strategy state: active={}, regime={}",
initial_state.active, initial_state.current_regime
);
// Simulate running for a short period (in production, this would run continuously)
info!("Running strategy simulation for 10 seconds...");
// Start the strategy (this would run indefinitely in production)
// For demo purposes, we'll use a timeout
let strategy_task = tokio::spawn(async move {
if let Err(e) = strategy.start().await {
eprintln!("Strategy error: {}", e);
}
});
// Let it run for 10 seconds
sleep(Duration::from_secs(10)).await;
info!("Stopping strategy simulation");
strategy_task.abort();
info!("Example completed successfully");
Ok(())
}
/// Create a comprehensive strategy configuration
fn create_strategy_config() -> StrategyConfig {
StrategyConfig {
general: GeneralConfig {
name: "basic_adaptive_strategy".to_string(),
symbols: vec![
"BTC-USD".to_string(),
"ETH-USD".to_string(),
"SOL-USD".to_string(),
],
execution_interval: Duration::from_millis(500), // Execute every 500ms
error_backoff_duration: Duration::from_secs(2),
max_position_fraction: 0.15, // Maximum 15% position size
live_trading_enabled: false, // Paper trading for demo
},
ensemble: EnsembleConfig {
models: vec![
// Primary LSTM model with higher weight
ModelConfig {
model_type: "lstm".to_string(),
name: "primary_lstm".to_string(),
initial_weight: 0.4,
parameters: create_lstm_parameters(),
enabled: true,
performance_threshold: 0.55,
},
// Secondary Transformer model
ModelConfig {
model_type: "transformer".to_string(),
name: "secondary_transformer".to_string(),
initial_weight: 0.3,
parameters: create_transformer_parameters(),
enabled: true,
performance_threshold: 0.55,
},
// Tertiary GRU model
ModelConfig {
model_type: "gru".to_string(),
name: "tertiary_gru".to_string(),
initial_weight: 0.3,
parameters: create_gru_parameters(),
enabled: true,
performance_threshold: 0.52,
},
],
rebalance_interval: Duration::from_secs(300), // Rebalance every 5 minutes
min_confidence_threshold: 0.65, // Require 65% confidence
max_concurrent_models: 3,
weight_decay_factor: 0.95, // Slight decay to prevent overfitting
},
risk: RiskConfig {
max_portfolio_var: 0.025, // 2.5% max portfolio VaR
var_confidence_level: 0.95, // 95% confidence level
max_drawdown_threshold: 0.08, // 8% max drawdown
position_sizing_method: PositionSizingMethod::Kelly,
kelly_fraction: 0.25, // Conservative quarter-Kelly
max_leverage: 1.8, // Maximum 1.8x leverage
stop_loss_pct: 0.025, // 2.5% stop loss
take_profit_pct: 0.05, // 5% take profit
},
execution: ExecutionConfig {
algorithm: ExecutionAlgorithm::TWAP, // Use TWAP for demo
max_order_size: 50000.0, // Maximum $50k orders
min_order_size: 500.0, // Minimum $500 orders
order_timeout: Duration::from_secs(45),
max_slippage_bps: 15.0, // 15 basis points max slippage
smart_routing_enabled: true,
dark_pool_preference: 0.25, // 25% dark pool preference
},
regime: RegimeConfig {
detection_method: RegimeDetectionMethod::HMM, // Use HMM for regime detection
lookback_window: 500, // 500 data points lookback
min_regime_duration: Duration::from_secs(600), // 10 minutes minimum
transition_sensitivity: 0.75, // 75% sensitivity
features: vec![
"volatility".to_string(),
"volume".to_string(),
"returns".to_string(),
"momentum".to_string(),
"bid_ask_spread".to_string(),
],
},
microstructure: MicrostructureConfig {
book_depth: 15, // Analyze 15 levels deep
trade_size_buckets: vec![
1000.0, // Small trades
5000.0, // Medium trades
25000.0, // Large trades
100000.0, // Very large trades
],
features: vec![
MicrostructureFeature::BidAskSpread,
MicrostructureFeature::OrderBookImbalance,
MicrostructureFeature::TradeSign,
MicrostructureFeature::VolumeProfile,
MicrostructureFeature::PriceImpact,
],
update_frequency: Duration::from_millis(250), // Update every 250ms
},
}
}
/// Create LSTM model parameters
fn create_lstm_parameters() -> HashMap<String, serde_json::Value> {
let mut params = HashMap::new();
params.insert(
"learning_rate".to_string(),
serde_json::Value::Number(serde_json::Number::from_f64(0.001).unwrap()),
);
params.insert(
"hidden_size".to_string(),
serde_json::Value::Number(serde_json::Number::from(128)),
);
params.insert(
"num_layers".to_string(),
serde_json::Value::Number(serde_json::Number::from(2)),
);
params.insert(
"dropout".to_string(),
serde_json::Value::Number(serde_json::Number::from_f64(0.2).unwrap()),
);
params.insert(
"sequence_length".to_string(),
serde_json::Value::Number(serde_json::Number::from(50)),
);
params
}
/// Create Transformer model parameters
fn create_transformer_parameters() -> HashMap<String, serde_json::Value> {
let mut params = HashMap::new();
params.insert(
"learning_rate".to_string(),
serde_json::Value::Number(serde_json::Number::from_f64(0.0005).unwrap()),
);
params.insert(
"d_model".to_string(),
serde_json::Value::Number(serde_json::Number::from(256)),
);
params.insert(
"num_heads".to_string(),
serde_json::Value::Number(serde_json::Number::from(8)),
);
params.insert(
"num_layers".to_string(),
serde_json::Value::Number(serde_json::Number::from(6)),
);
params.insert(
"dropout".to_string(),
serde_json::Value::Number(serde_json::Number::from_f64(0.1).unwrap()),
);
params.insert(
"max_sequence_length".to_string(),
serde_json::Value::Number(serde_json::Number::from(100)),
);
params
}
/// Create GRU model parameters
fn create_gru_parameters() -> HashMap<String, serde_json::Value> {
let mut params = HashMap::new();
params.insert(
"learning_rate".to_string(),
serde_json::Value::Number(serde_json::Number::from_f64(0.002).unwrap()),
);
params.insert(
"hidden_size".to_string(),
serde_json::Value::Number(serde_json::Number::from(96)),
);
params.insert(
"num_layers".to_string(),
serde_json::Value::Number(serde_json::Number::from(3)),
);
params.insert(
"dropout".to_string(),
serde_json::Value::Number(serde_json::Number::from_f64(0.15).unwrap()),
);
params.insert(
"sequence_length".to_string(),
serde_json::Value::Number(serde_json::Number::from(40)),
);
params
}