#![allow(missing_docs)] // Internal implementation details don't require documentation #![allow(missing_debug_implementations)] // Not all types need Debug #![allow(dead_code)] // Many utility functions are defined for future use #![allow(unused_crate_dependencies)] // Dev dependencies not used in lib.rs #![allow(clippy::float_arithmetic)] // ML operations require float arithmetic #![recursion_limit = "256"] // Required for complex TFT quantile operations //! Machine Learning Models for Foxhunt //! //! This crate provides comprehensive machine learning models and algorithms //! for the Foxhunt high-frequency trading system. All ML operations use //! enterprise-grade safety controls to prevent system failures. //! //! ## Safety Features //! //! - **Comprehensive mathematical safety**: All operations handle NaN/Infinity gracefully //! - **Tensor bounds checking**: Prevents buffer overflows and memory issues //! - **Model drift detection**: Automatic monitoring of model performance degradation //! - **Financial validation**: Ensures all predictions use unified financial types //! - **Memory management**: Prevents OOM conditions and memory leaks //! - **Timeout handling**: Prevents hanging operations //! //! ## Usage //! //! ```no_run //! // ML safety manager usage example //! // Note: This is a conceptual example - actual implementation may vary //! use ml::safety::MLSafetyConfig; //! //! #[tokio::main] //! async fn main() -> Result<(), Box> { //! // Initialize safety with custom configuration //! let _config = MLSafetyConfig::default(); //! //! // ML operations would use the safety manager //! // (actual implementation details depend on the safety module structure) //! Ok(()) //! } //! ``` #![warn(missing_debug_implementations)] #![warn(rust_2018_idioms)] #![deny( clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::unreachable, clippy::indexing_slicing )] // Import common types properly - NO ALIASES THAT CONFLICT! use candle_core::Tensor; use candle_core::Var; use candle_nn::Optimizer; // For Adam optimizer support use serde::{Deserialize, Serialize}; // For tensor variables // Silence unused crate warnings for dependencies used in tests or feature-gated code use approx as _; use bincode as _; use half as _; use memmap2 as _; use num as _; use num_traits as _; use semver as _; use tempfile as _; use trading_engine as _; // Note: Optimizer trait not available in candle_optimisers v0.9 // Files using optimizers may need to be updated or removed // Note: For candle_nn types like Linear and Dropout, they implement Module trait // Use Module::forward(&self, input) instead of self.forward(input) /// Wrapper for Adam optimizer to provide required methods /// /// This wrapper provides a unified interface around the candle_optimisers Adam optimizer, /// ensuring consistent behavior across the ML crate and providing additional convenience methods. /// Adam is an adaptive learning rate optimization algorithm that computes individual learning /// rates for different parameters from estimates of first and second moments of the gradients. /// /// # Examples /// /// ```rust,no_run /// use ml::Adam; /// use candle_core::Var; /// use candle_optimisers::adam::ParamsAdam; /// /// let vars = vec![]; // Your model variables /// let params = ParamsAdam::default(); /// let optimizer = Adam::new(vars, params)?; /// # Ok::<(), ml::MLError>(()) /// ``` #[derive(Debug)] pub struct Adam { optimizer: candle_optimisers::adam::Adam, learning_rate: f64, } impl Adam { /// Create a new Adam optimizer with the given variables and parameters /// /// # Arguments /// /// * `vars` - Vector of model variables to optimize /// * `params` - Adam optimizer parameters including learning rate, betas, and epsilon /// /// # Returns /// /// Returns `Ok(Adam)` on success, or `Err(MLError::TrainingError)` if optimizer creation fails /// /// # Errors /// /// This function will return an error if the underlying candle Adam optimizer fails to initialize pub fn new( vars: Vec, params: candle_optimisers::adam::ParamsAdam, ) -> Result { let learning_rate = params.lr; let optimizer = candle_optimisers::adam::Adam::new(vars, params).map_err(|e| { MLError::TrainingError(format!("Failed to create Adam optimizer: {}", e)) })?; Ok(Self { optimizer, learning_rate, }) } /// Perform a backward pass and optimizer step /// /// This method computes gradients via backpropagation and then applies the Adam /// optimization update to all registered variables. /// /// # Arguments /// /// * `loss` - The loss tensor to compute gradients from /// /// # Returns /// /// Returns `Ok(())` on successful optimization step, or `Err(MLError::TrainingError)` on failure /// /// # Errors /// /// This function will return an error if: /// - The backward pass fails to compute gradients /// - The optimizer step fails to apply updates pub fn backward_step(&mut self, loss: &Tensor) -> Result<(), MLError> { // Calculate gradients let grads = loss .backward() .map_err(|e| MLError::TrainingError(format!("Backward pass failed: {}", e)))?; // Apply optimizer step using trait method Optimizer::step(&mut self.optimizer, &grads) .map_err(|e| MLError::TrainingError(format!("Optimizer step failed: {}", e)))?; Ok(()) } /// Get the learning rate used by this optimizer /// /// # Returns /// /// Returns the learning rate as a 64-bit floating point number pub fn learning_rate(&self) -> f64 { self.learning_rate } } // Direct type imports - no compatibility aliases use rust_decimal::Decimal; /// Common type errors that can occur during ML operations /// /// This enum represents various type-related errors that can occur when working /// with different data types across the ML pipeline, including type conversions, /// validation errors, and compatibility issues. #[derive(Debug, Clone, thiserror::Error, serde::Serialize, serde::Deserialize)] pub enum CommonTypeError { /// Generic type error with descriptive message #[error("Type error: {0}")] Error(String), } /// Market regime classification for algorithmic trading strategies /// /// This enum represents different market conditions that can be detected through /// statistical analysis and machine learning models. Market regime detection is /// crucial for adaptive trading strategies that adjust their behavior based on /// current market conditions. /// /// # Examples /// /// ```rust /// use ml::MarketRegime; /// /// let regime = MarketRegime::Trending; /// match regime { /// MarketRegime::Bull => println!("Use momentum strategies"), /// MarketRegime::Bear => println!("Use defensive strategies"), /// MarketRegime::Crisis => println!("Implement risk controls"), /// _ => println!("Use balanced approach"), /// } /// ``` #[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub enum MarketRegime { /// Normal market conditions with typical volatility and volume Normal, /// Strong directional movement with clear trends Trending, /// Range-bound market with limited directional movement Sideways, /// Bullish market with rising prices and positive sentiment Bull, /// Bearish market with falling prices and negative sentiment Bear, /// Crisis conditions with extreme volatility and risk Crisis, } /// Common errors that can occur across the ML system /// /// This enum provides a unified error type that can be used throughout the ML /// pipeline to ensure consistent error handling and reporting. It serves as a /// bridge between different subsystems and provides appropriate error categorization. #[derive(Debug, Clone, thiserror::Error, serde::Serialize, serde::Deserialize)] pub enum CommonError { /// General error with descriptive message #[error("Error: {0}")] General(String), } impl CommonError { /// Create a validation error with a descriptive message /// /// # Arguments /// /// * `msg` - A descriptive message explaining the validation failure /// /// # Returns /// /// Returns a `CommonError::General` variant with the validation message /// /// # Examples /// /// ```rust /// use ml::CommonError; /// /// let error = CommonError::validation("Invalid input range"); /// assert!(error.to_string().contains("Invalid input range")); /// ``` pub fn validation(msg: impl Into) -> Self { Self::General(msg.into()) } /// Create a configuration error with a descriptive message /// /// # Arguments /// /// * `msg` - A descriptive message explaining the configuration issue /// /// # Returns /// /// Returns a `CommonError::General` variant with the configuration message /// /// # Examples /// /// ```rust /// use ml::CommonError; /// /// let error = CommonError::config("Missing required parameter"); /// assert!(error.to_string().contains("Missing required parameter")); /// ``` pub fn config(msg: impl Into) -> Self { Self::General(msg.into()) } /// Create a service error with category and descriptive message /// /// # Arguments /// /// * `category` - The error category to classify the service error /// * `msg` - A descriptive message explaining the service issue /// /// # Returns /// /// Returns a `CommonError::General` variant with the categorized service message /// /// # Examples /// /// ```rust /// use ml::{CommonError, ErrorCategory}; /// /// let error = CommonError::service(ErrorCategory::System, "Database connection failed"); /// assert!(error.to_string().contains("System")); /// assert!(error.to_string().contains("Database connection failed")); /// ``` pub fn service(category: ErrorCategory, msg: impl Into) -> Self { Self::General(format!("{:?}: {}", category, msg.into())) } } /// Error categories for system-wide error classification /// /// This enum provides a way to categorize errors across the entire system, /// enabling better error handling, logging, and monitoring strategies. #[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub enum ErrorCategory { /// System-level errors including hardware, network, and infrastructure issues System, } // Now using real types from common crate // Core ML types /// Represents a financial trade for ML model training and analysis /// /// This structure contains the essential information about a trade that is used /// by ML models for pattern recognition, market analysis, and strategy optimization. /// The structure is optimized for both in-memory processing and database storage. /// /// # Examples /// /// ```rust /// use ml::Trade; /// use rust_decimal::Decimal; /// /// let trade = Trade { /// symbol: "AAPL".to_string(), /// price: Decimal::new(15000, 2), // $150.00 /// quantity: Decimal::new(100, 0), // 100 shares /// timestamp: 1640995200000000, // microseconds since epoch /// side: "buy".to_string(), /// }; /// ``` #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Trade { /// Trading symbol (e.g., "AAPL", "MSFT") pub symbol: String, /// Trade price in decimal format for precision pub price: Decimal, /// Trade quantity in decimal format for precision pub quantity: Decimal, /// Timestamp in microseconds since Unix epoch pub timestamp: u64, /// Trade side: "buy" or "sell" pub side: String, } /// Health status for ensemble models and ML system components /// /// This enum tracks the operational status of ML models and system components, /// enabling automated health monitoring, alerting, and failover mechanisms. /// Health status is crucial for maintaining system reliability in production. /// /// # Examples /// /// ```rust /// use ml::HealthStatus; /// /// let status = HealthStatus::Healthy; /// match status { /// HealthStatus::Healthy => println!("System operating normally"), /// HealthStatus::Degraded => println!("Performance below optimal"), /// HealthStatus::Unhealthy => println!("System requires intervention"), /// } /// ``` #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum HealthStatus { /// Component is operating within normal parameters Healthy, /// Component is operational but performance is below optimal Degraded, /// Component is not functioning properly and requires intervention Unhealthy, } // Import specific types from trading_engine that we need // (removed wildcard prelude to avoid conflicts) // Using Decimal for financial types /// Market data snapshot for ML model input /// /// Represents a point-in-time snapshot of market data that serves as input /// for ML models. This structure contains the essential market information /// needed for real-time trading decisions and model inference. /// /// # Examples /// /// ```rust /// use ml::MarketDataSnapshot; /// use rust_decimal::Decimal; /// use chrono::Utc; /// /// let snapshot = MarketDataSnapshot { /// timestamp: Utc::now(), /// symbol: "AAPL".to_string(), /// price: Decimal::new(15000, 2), // $150.00 /// volume: Decimal::new(1000000, 0), // 1M shares /// }; /// ``` #[derive(Debug, Clone, Serialize, Deserialize)] pub struct MarketDataSnapshot { /// Timestamp of the market data snapshot pub timestamp: DateTime, /// Trading symbol (e.g., "AAPL", "MSFT") pub symbol: String, /// Current market price pub price: Decimal, /// Trading volume at this timestamp pub volume: Decimal, } /// Feature vector for ML model input /// /// A wrapper around a vector of f64 values that represents extracted features /// for machine learning models. Features are numerical representations of /// market data, indicators, and other relevant information. /// /// # Examples /// /// ```rust /// use ml::FeatureVector; /// /// let features = FeatureVector(vec![1.0, 2.5, -0.3, 4.2]); /// assert_eq!(features.0.len(), 4); /// ``` #[derive(Debug, Clone, Serialize, Deserialize)] pub struct FeatureVector(pub Vec); impl FeatureVector { /// Get the length of the feature vector pub fn len(&self) -> usize { self.0.len() } /// Check if the feature vector is empty pub fn is_empty(&self) -> bool { self.0.is_empty() } } /// Integer tensor for discrete ML model operations /// /// A wrapper around a vector of i64 values used for discrete operations /// such as classification labels, indices, and categorical data in ML models. /// /// # Examples /// /// ```rust /// use ml::IntegerTensor; /// /// let tensor = IntegerTensor(vec![0, 1, 2, 1, 0]); /// assert_eq!(tensor.0.len(), 5); /// ``` #[derive(Debug, Clone, Serialize, Deserialize)] pub struct IntegerTensor(pub Vec); /// Summary of model update operations /// /// Provides information about batch update operations on ML models, /// including success counts and overall statistics. Used for monitoring /// and logging model maintenance operations. /// /// # Examples /// /// ```rust /// use ml::UpdateSummary; /// /// let summary = UpdateSummary { /// updated_models: 5, /// total_models: 10, /// }; /// /// let success_rate = summary.updated_models as f64 / summary.total_models as f64; /// println!("Update success rate: {:.1}%", success_rate * 100.0); /// ``` #[derive(Debug, Clone, Serialize, Deserialize)] pub struct UpdateSummary { /// Number of models successfully updated pub updated_models: usize, /// Total number of models in the update operation pub total_models: usize, } use thiserror::Error; /// Machine Learning specific errors #[derive(Debug, Clone, Error, Serialize, Deserialize)] pub enum MLError { /// Configuration error #[error("Configuration error: {reason}")] ConfigError { reason: String }, /// Configuration error (alternative naming) #[error("Configuration error: {0}")] ConfigurationError(String), /// Dimension mismatch error #[error("Dimension mismatch: expected {expected}, got {actual}")] DimensionMismatch { expected: usize, actual: usize }, /// Graph-related error #[error("Graph error: {message}")] GraphError { message: String }, /// Resource limit exceeded #[error("Resource limit exceeded: {resource} limit {limit}")] ResourceLimit { resource: String, limit: usize }, /// Serialization error #[error("Serialization error: {reason}")] SerializationError { reason: String }, /// Validation error #[error("Validation error: {message}")] ValidationError { message: String }, /// Concurrency error #[error("Concurrency error in operation: {operation}")] ConcurrencyError { operation: String }, /// Invalid input error #[error("Invalid input: {0}")] InvalidInput(String), /// Initialization error #[error("Initialization error in {component}: {message}")] InitializationError { component: String, message: String, }, /// Training error #[error("Training error: {0}")] TrainingError(String), /// Inference error #[error("Inference error: {0}")] InferenceError(String), /// Model error #[error("Model error: {0}")] ModelError(String), /// Model not trained error #[error("Model not trained: {0}")] NotTrained(String), /// Anyhow error wrapping #[error("General error: {0}")] AnyhowError(String), /// Tensor creation error #[error("Tensor creation error in {operation}: {reason}")] TensorCreationError { operation: String, reason: String }, /// Tensor operation error #[error("Tensor operation error: {0}")] TensorOperationError(String), /// Lock error #[error("Lock error: {0}")] LockError(String), /// Model not found error #[error("Model not found: {0}")] ModelNotFound(String), /// Insufficient data error #[error("Insufficient data: {0}")] InsufficientData(String), /// Checkpoint error #[error("Checkpoint error: {0}")] CheckpointError(String), } // Implement From trait for candle_core::Error impl From for MLError { fn from(err: candle_core::Error) -> Self { MLError::ModelError(format!("Candle error: {}", err)) } } // Implement From trait for LabelingError impl From for MLError { fn from(err: labeling::gpu_acceleration::LabelingError) -> Self { MLError::InferenceError(err.to_string()) } } // NOTE: Commented out workspace dependency - will be re-enabled when workspace is available // impl From for MLError { // fn from(err: error_handling::TradingError) -> Self { // match err { // error_handling::TradingError::InvalidPrice { value, reason } => { // MLError::ValidationError { // message: format!("Invalid price {}: {}", value, reason), // } // } // error_handling::TradingError::InvalidQuantity { value, reason } => { // MLError::ValidationError { // message: format!("Invalid quantity {}: {}", value, reason), // } // } // error_handling::TradingError::FinancialSafety { message, .. } => { // MLError::ValidationError { // message: format!("Financial safety error: {}", message), // } // } // error_handling::TradingError::DivisionByZero { operation } => { // MLError::ValidationError { // message: format!("Division by zero in {}", operation), // } // } // error_handling::TradingError::ModelInference { reason, model } => { // MLError::InferenceError(format!("Model inference error for {}: {}", model, reason)) // } // error_handling::TradingError::GpuComputation { reason, operation } => { // let msg = match operation { // Some(op) => format!("GPU computation error ({}): {}", op, reason), // None => format!("GPU computation error: {}", reason), // }; // MLError::ModelError(msg) // } // other => MLError::ModelError(format!("Trading error: {}", other)), // } // } // } // Implement From trait for anyhow::Error impl From for MLError { fn from(err: anyhow::Error) -> Self { MLError::AnyhowError(err.to_string()) } } // Implement From trait for std::io::Error impl From for MLError { fn from(err: std::io::Error) -> Self { MLError::ModelError(format!("IO error: {}", err)) } } // UNIFIED ERROR HANDLING: Convert all ML errors to CommonError for workspace consistency impl From for CommonError { fn from(err: MLError) -> Self { match err { MLError::ConfigError { reason } => { CommonError::config(format!("ML configuration error: {}", reason)) }, MLError::ConfigurationError(msg) => { CommonError::config(format!("ML configuration error: {}", msg)) }, MLError::InitializationError { component, message } => { CommonError::service( ErrorCategory::System, format!("ML initialization error in {}: {}", component, message), ) }, MLError::DimensionMismatch { expected, actual } => CommonError::validation(format!( "ML dimension mismatch: expected {}, got {}", expected, actual )), MLError::GraphError { message } => CommonError::service( ErrorCategory::System, format!("ML graph error: {}", message), ), MLError::ResourceLimit { resource, limit } => CommonError::service( ErrorCategory::System, format!("ML resource limit exceeded: {} limit {}", resource, limit), ), MLError::SerializationError { reason } => CommonError::service( ErrorCategory::System, format!("ML serialization error: {}", reason), ), MLError::ValidationError { message } => { CommonError::validation(format!("ML validation error: {}", message)) }, MLError::ConcurrencyError { operation } => CommonError::service( ErrorCategory::System, format!("ML concurrency error in operation: {}", operation), ), MLError::InvalidInput(msg) => { CommonError::validation(format!("ML invalid input: {}", msg)) }, MLError::TrainingError(msg) => { CommonError::service(ErrorCategory::System, format!("ML training error: {}", msg)) }, MLError::InferenceError(msg) => CommonError::service( ErrorCategory::System, format!("ML inference error: {}", msg), ), MLError::ModelError(msg) => { CommonError::service(ErrorCategory::System, format!("ML model error: {}", msg)) }, MLError::CheckpointError(msg) => { CommonError::service(ErrorCategory::System, format!("ML checkpoint error: {}", msg)) }, MLError::NotTrained(msg) => CommonError::service( ErrorCategory::System, format!("ML model not trained: {}", msg), ), MLError::AnyhowError(msg) => { CommonError::service(ErrorCategory::System, format!("ML error: {}", msg)) }, MLError::TensorCreationError { operation, reason } => CommonError::service( ErrorCategory::System, format!("ML tensor creation error in {}: {}", operation, reason), ), MLError::TensorOperationError(msg) => CommonError::service( ErrorCategory::System, format!("ML tensor operation error: {}", msg), ), MLError::LockError(msg) => { CommonError::service(ErrorCategory::System, format!("ML lock error: {}", msg)) }, MLError::ModelNotFound(msg) => CommonError::service( ErrorCategory::System, format!("ML model not found: {}", msg), ), MLError::InsufficientData(msg) => { CommonError::validation(format!("ML insufficient data: {}", msg)) }, } } } // Convert common type errors to MLError impl From for MLError { fn from(err: CommonTypeError) -> Self { MLError::ModelError(format!("Common type error: {}", err)) } } impl From for MLError { fn from(err: serde_json::Error) -> Self { MLError::SerializationError { reason: err.to_string(), } } } impl From for MLError { fn from(err: inference::RealInferenceError) -> Self { match err { inference::RealInferenceError::GpuRequired { reason } => { MLError::ModelError(format!("GPU required: {}", reason)) }, inference::RealInferenceError::ComputationFailed { reason } => { MLError::InferenceError(reason) }, inference::RealInferenceError::FeatureMismatch { expected, actual } => { MLError::DimensionMismatch { expected, actual } }, inference::RealInferenceError::PredictionValidation { reason } => { MLError::ValidationError { message: reason } }, inference::RealInferenceError::HardwareError { reason } => { MLError::ModelError(format!("Hardware error: {}", reason)) }, other => MLError::InferenceError(other.to_string()), } } } // Implement From for MLError impl From for MLError { fn from(err: training_pipeline::ProductionTrainingError) -> Self { match err { training_pipeline::ProductionTrainingError::ConfigError { reason } => { MLError::ConfigError { reason } }, training_pipeline::ProductionTrainingError::ArchitectureError { reason } => { MLError::ModelError(format!("Architecture error: {}", reason)) }, training_pipeline::ProductionTrainingError::DataError { reason } => { MLError::ValidationError { message: format!("Data error: {}", reason), } }, training_pipeline::ProductionTrainingError::OptimizationError { reason } => { MLError::TrainingError(format!("Optimization error: {}", reason)) }, training_pipeline::ProductionTrainingError::FinancialError { reason } => { MLError::ValidationError { message: format!("Financial error: {}", reason), } }, training_pipeline::ProductionTrainingError::SafetyViolation { reason } => { MLError::ValidationError { message: format!("Safety violation: {}", reason), } }, training_pipeline::ProductionTrainingError::ConvergenceError { reason } => { MLError::TrainingError(format!("Convergence error: {}", reason)) }, training_pipeline::ProductionTrainingError::ResourceError { reason } => { MLError::ModelError(format!("Resource error: {}", reason)) }, training_pipeline::ProductionTrainingError::GpuRequired { reason } => { MLError::ModelError(format!("GPU required: {}", reason)) }, } } } // Note: From trait for liquid::LiquidError is implemented in the liquid module to avoid conflicts /// Result type for ML operations pub type MLResult = Result; /// New unified result type using CommonError for better integration pub type UnifiedMLResult = Result; /// Precision factor for fixed-point arithmetic pub const PRECISION_FACTOR: i64 = 100_000_000; /// Maximum inference latency target in microseconds pub const MAX_INFERENCE_LATENCY_US: u64 = 100; // ========== CORE ML MODULES ========== // Core ML modules pub mod checkpoint; pub mod cuda_compat; // CUDA-compatible operations (manual sigmoid, etc.) pub mod data_loaders; // Data loaders for ML training pub mod dqn; pub mod ensemble; pub mod flash_attention; pub mod integration; pub mod labeling; pub mod liquid; pub mod mamba; pub mod memory_optimization; // Memory optimization utilities (lazy loading, quantization, precision) pub mod microstructure; pub mod ppo; pub mod risk; pub mod safety; pub mod security; // ML security (prediction validation, anomaly detection) pub mod tft; pub mod tgnn; pub mod tlob; // Re-export quantized TFT types (Wave 9.12) pub use tft::{ QuantizedTemporalFusionTransformer, QuantizedVariableSelectionNetwork, QuantizedLSTMEncoder, QuantizedTemporalAttention, QuantizedGatedResidualNetwork, }; pub mod trainers; // ML model trainers with gRPC integration pub mod transformers; pub mod universe; // ============================================================================ // MANDATORY CUDA TRAINING DEVICE // ============================================================================ // // ALL ML training requires CUDA GPU acceleration. CPU fallback wastes time. // // This module provides a fail-fast device initialization function that: // 1. Requires CUDA GPU (no silent CPU fallback) // 2. Provides helpful error messages for common setup issues // 3. Ensures consistent device initialization across all trainers // // Training scripts MUST use this function instead of Device::cuda_if_available() /// Get mandatory CUDA device for training /// /// # Panics /// /// Panics if CUDA GPU is not available with detailed error message /// /// # Example /// /// ```no_run /// use ml::get_training_device; /// /// let device = get_training_device(); // Panics if no GPU /// ``` pub fn get_training_device() -> candle_core::Device { match candle_core::Device::new_cuda(0) { Ok(device) => device, Err(e) => { panic!( "\n\n\ ╔═══════════════════════════════════════════════════════════════════╗\n\ ║ CUDA GPU REQUIRED FOR TRAINING ║\n\ ╚═══════════════════════════════════════════════════════════════════╝\n\ \n\ Training requires CUDA GPU acceleration. CPU fallback is disabled.\n\ \n\ Error: {}\n\ \n\ Troubleshooting:\n\ \n\ 1. Check GPU availability:\n\ nvidia-smi\n\ \n\ 2. Verify CUDA toolkit installation:\n\ nvcc --version\n\ \n\ 3. Check CUDA libraries are in LD_LIBRARY_PATH:\n\ echo $LD_LIBRARY_PATH | grep cuda\n\ \n\ 4. Ensure project built with CUDA feature:\n\ cargo build --release --features cuda\n\ \n\ 5. Check CUDA environment variables:\n\ echo $CUDA_HOME\n\ ls $CUDA_HOME/lib64/\n\ \n\ If GPU is unavailable, training cannot proceed.\n\ \n", e ); } } } /// Get CUDA device with index (for multi-GPU setups) /// /// # Panics /// /// Panics if CUDA GPU at specified index is not available pub fn get_training_device_at(device_id: usize) -> candle_core::Device { match candle_core::Device::new_cuda(device_id) { Ok(device) => device, Err(e) => { panic!( "\n\n\ ╔═══════════════════════════════════════════════════════════════════╗\n\ ║ CUDA GPU {} NOT AVAILABLE ║\n\ ╚═══════════════════════════════════════════════════════════════════╝\n\ \n\ Error: {}\n\ \n\ Check available GPUs with: nvidia-smi\n\ \n", device_id, e ); } } } // ========== INFRASTRUCTURE MODULES ========== // Infrastructure pub mod benchmark; pub mod benchmarks; pub mod common; pub mod metrics; // Performance metrics (Sharpe ratio, etc.) pub mod training; // Test utilities (only available during testing) #[cfg(test)] pub mod test_common; // ========== MODEL DEPLOYMENT AND FACTORY ========== // TEMPORARILY DISABLED: deployment module has 250+ compilation errors // Needs proper implementation of missing types (ModelSwapEngine, ABTestManager, etc.) // #[cfg(feature = "deployment")] // pub mod deployment; pub mod model_factory; // Re-export commonly used deployment types at root // pub use deployment::versioning::ModelVersion; // ========== CORE EXPORTS ========== // Core exports pub mod error; pub mod error_consolidated; pub mod features; // Feature cache and extraction (Parquet + MinIO) #[allow(deprecated)] pub mod features_old; // Legacy features (for backward compatibility) pub mod inference; pub mod model; pub mod operations; pub mod performance; pub mod production; pub mod validation; // ========== ADDITIONAL MODULES ========== // Additional ML processing modules pub mod batch_processing; // Batch processing for ML operations pub mod bridge; // Type system bridge for ML-Financial integration pub mod operations_safe; // Safe operations module pub mod ops_production; // Production ML operations pub mod portfolio_transformer; // Portfolio-specific transformer pub mod regime_detection; // Market regime detection pub mod tensor_ops; // TLOB transformer implementation moved to tlob module pub mod examples; // Removed examples_stubs module - contained only placeholder implementations pub mod integration_test; // DISABLED: model_loader_integration requires external model_loader crate that doesn't exist // Production deployment requires implementing proper model loading infrastructure // pub mod model_loader_integration; pub mod models_demo; pub mod observability; pub mod stress_testing; // Stress testing framework pub mod test_fixtures; // Common test symbols and fixtures pub mod training_pipeline; // Complete training pipeline system pub mod traits; // Common traits for ML models // Production observability and monitoring // Integration with model_loader crate // ML Readiness Validation modules (Wave 152+) pub mod real_data_loader; // Load real DBN data and extract ML features // TEMPORARILY DISABLED for compilation: pub mod inference_validator; // Validate model inference pipelines pub mod random_model; // Random baseline model for testing pub mod data_validation; // Automated data quality validation (Wave 160+) // Model versioning and registry (Wave 152 - Agent 47) pub mod model_registry; // Model versioning with PostgreSQL storage // Temporarily disabled due to compilation errors // #[cfg(test)] // pub mod tests; // Test modules // ========== MISSING TYPES STUBS ========== /// Application result wrapper for ML operations #[derive(Debug, Clone, Serialize, Deserialize)] pub struct MLAppResult { pub data: T, pub success: bool, pub message: Option, pub execution_time_ms: u64, pub metadata: HashMap, } impl MLAppResult { /// Create a successful result pub fn success(data: T) -> Self { Self { data, success: true, message: None, execution_time_ms: 0, metadata: HashMap::new(), } } /// Create a failed result with message pub fn error(data: T, message: String) -> Self { Self { data, success: false, message: Some(message), execution_time_ms: 0, metadata: HashMap::new(), } } /// Set execution time pub fn with_timing(mut self, execution_time_ms: u64) -> Self { self.execution_time_ms = execution_time_ms; self } /// Add metadata pub fn with_metadata(mut self, key: String, value: String) -> Self { self.metadata.insert(key, value); self } } /// Performance profile configuration for HFT models #[derive(Debug, Clone, Serialize, Deserialize)] pub struct HFTPerformanceProfile { pub max_latency_us: u64, pub target_throughput: u32, pub memory_limit_mb: u64, pub cpu_affinity: Option>, pub gpu_enabled: bool, pub batch_size: u32, pub optimization_level: OptimizationLevel, } /// Optimization levels for HFT performance #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub enum OptimizationLevel { /// Maximum speed, minimal safety checks UltraLow, /// Balanced speed and safety Low, /// Standard optimization Medium, /// Conservative with full validation High, } impl Default for HFTPerformanceProfile { fn default() -> Self { Self { max_latency_us: 100, // 100 microseconds target target_throughput: 10000, // 10k operations per second memory_limit_mb: 1024, // 1GB memory limit cpu_affinity: None, gpu_enabled: false, batch_size: 1, optimization_level: OptimizationLevel::Medium, } } } /// Create HFT performance profile with default settings pub fn create_hft_performance_profile() -> HFTPerformanceProfile { HFTPerformanceProfile::default() } /// Create HFT performance profile with custom latency target pub fn create_hft_performance_profile_with_latency(max_latency_us: u64) -> HFTPerformanceProfile { HFTPerformanceProfile { max_latency_us, ..Default::default() } } /// Create HFT performance profile optimized for ultra-low latency pub fn create_ultra_low_latency_profile() -> HFTPerformanceProfile { HFTPerformanceProfile { max_latency_us: 10, // 10 microseconds target target_throughput: 50000, // 50k operations per second memory_limit_mb: 512, // Reduced memory for cache efficiency gpu_enabled: true, // Enable GPU acceleration batch_size: 1, // No batching for minimal latency optimization_level: OptimizationLevel::UltraLow, ..Default::default() } } // ========== UNIFIED ML MODEL INTERFACE ========== use async_trait::async_trait; use chrono::{DateTime, Utc}; use futures::future::join_all; use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; /// Features vector for ML model input #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Features { /// Raw feature values pub values: Vec, /// Feature names for debugging pub names: Vec, /// Timestamp of features pub timestamp: u64, /// Symbol these features are for pub symbol: Option, } impl Features { pub fn new(values: Vec, names: Vec) -> Self { Self { values, names, timestamp: std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap_or_default() .as_micros() as u64, symbol: None, } } /// Set the symbol for this market data point /// /// # Arguments /// * `symbol` - The trading symbol (e.g., "AAPL", "MSFT") /// /// # Returns /// Modified MarketData instance with symbol set pub fn with_symbol(mut self, symbol: String) -> Self { self.symbol = Some(symbol); self } } /// Model prediction result #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ModelPrediction { /// Predicted value (price direction, probability, etc.) pub value: f64, /// Model confidence (0.0 to 1.0) pub confidence: f64, /// Additional model-specific metadata pub metadata: HashMap, /// Prediction timestamp pub timestamp: u64, /// Model identifier pub model_id: String, } impl ModelPrediction { pub fn new(model_id: String, value: f64, confidence: f64) -> Self { Self { value, confidence, metadata: HashMap::new(), timestamp: std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap_or_default() .as_micros() as u64, model_id, } } /// Add metadata to the model prediction /// /// # Arguments /// * `key` - Metadata key identifier /// * `value` - JSON value containing metadata /// /// # Returns /// Modified ModelPrediction with additional metadata pub fn with_metadata(mut self, key: String, value: serde_json::Value) -> Self { self.metadata.insert(key, value); self } } /// Feedback for model weight updates #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Feedback { /// Actual outcome (for supervised learning) pub actual_value: Option, /// Reward signal (for reinforcement learning) pub reward: Option, /// Trading performance metrics pub performance_metrics: HashMap, /// Timestamp of feedback pub timestamp: u64, } impl Feedback { pub fn new() -> Self { Self { actual_value: None, reward: None, performance_metrics: HashMap::new(), timestamp: std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap_or_default() .as_micros() as u64, } } /// Set the actual outcome value for supervised learning feedback /// /// # Arguments /// * `actual` - The actual observed value /// /// # Returns /// Modified Feedback with actual value set pub fn with_actual(mut self, actual: f64) -> Self { self.actual_value = Some(actual); self } /// Set the reward signal for reinforcement learning feedback /// /// # Arguments /// * `reward` - The reward value (positive for good outcomes, negative for bad) /// /// # Returns /// Modified Feedback with reward signal set pub fn with_reward(mut self, reward: f64) -> Self { self.reward = Some(reward); self } } /// Unified interface for all ML models in the system #[async_trait] pub trait MLModel: Send + Sync + std::fmt::Debug { /// Get unique model identifier fn name(&self) -> &str; /// Get model type fn model_type(&self) -> ModelType; /// Make prediction based on features async fn predict(&self, features: &Features) -> MLResult; /// Get current model confidence score (0.0 to 1.0) fn get_confidence(&self) -> f64; /// Update model weights based on feedback (optional - not all models support online learning) async fn update_weights(&mut self, _feedback: &Feedback) -> MLResult<()> { // Default implementation does nothing (for immutable models) Ok(()) } /// Check if model is ready for predictions fn is_ready(&self) -> bool { true // Default to ready } /// Get model metadata fn get_metadata(&self) -> ModelMetadata; /// Validate input features fn validate_features(&self, features: &Features) -> MLResult<()> { // Default validation - check for empty features if features.values.is_empty() { return Err(MLError::ValidationError { message: "Empty feature vector".to_string(), }); } Ok(()) } } /// Thread-safe model registry using DashMap for high-performance concurrent access pub struct ModelRegistry { /// Models stored by name models: dashmap::DashMap>, /// Registry metadata metadata: Arc>, } impl std::fmt::Debug for ModelRegistry { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("ModelRegistry") .field( "models", &format_args!("", self.models.len()), ) .field("metadata", &self.metadata) .finish() } } #[derive(Debug, Clone)] struct RegistryMetadata { created_at: std::time::SystemTime, total_registrations: u64, last_access: std::time::SystemTime, } impl ModelRegistry { /// Create new model registry pub fn new() -> Self { Self { models: dashmap::DashMap::new(), metadata: Arc::new(RwLock::new(RegistryMetadata { created_at: std::time::SystemTime::now(), total_registrations: 0, last_access: std::time::SystemTime::now(), })), } } /// Register a model in the registry pub async fn register(&self, model: Arc) -> MLResult<()> { let name = model.name().to_string(); // Check if model is ready if !model.is_ready() { return Err(MLError::ModelError(format!("Model {} is not ready", name))); } self.models.insert(name.clone(), model); // Update metadata { let mut meta = self.metadata.write().await; meta.total_registrations += 1; meta.last_access = std::time::SystemTime::now(); } tracing::info!("Registered ML model: {}", name); Ok(()) } /// Get model by name pub async fn get(&self, name: &str) -> Option> { // Update last access time { let mut meta = self.metadata.write().await; meta.last_access = std::time::SystemTime::now(); } self.models.get(name).map(|entry| entry.value().clone()) } /// Get all registered models pub fn get_all(&self) -> Vec> { self.models .iter() .map(|entry| entry.value().clone()) .collect() } /// Get model names pub fn get_model_names(&self) -> Vec { self.models .iter() .map(|entry| entry.key().clone()) .collect() } /// Remove model from registry pub async fn remove(&self, name: &str) -> Option> { let result = self.models.remove(name).map(|(_, model)| model); if result.is_some() { tracing::info!("Removed ML model: {}", name); } result } /// Get registry statistics pub async fn get_stats(&self) -> RegistryStats { let meta = self.metadata.read().await; RegistryStats { total_models: self.models.len(), total_registrations: meta.total_registrations, created_at: meta.created_at, last_access: meta.last_access, } } /// Parallel prediction across all models pub async fn predict_all(&self, features: &Features) -> Vec> { let models = self.get_all(); let futures = models.iter().map(|model| { let features = features.clone(); async move { model.predict(&features).await } }); join_all(futures).await } /// Parallel prediction across specific models pub async fn predict_selected( &self, model_names: &[String], features: &Features, ) -> Vec> { let futures = model_names.iter().map(|name| { let name = name.clone(); let features = features.clone(); async move { if let Some(model) = self.get(&name).await { model.predict(&features).await } else { Err(MLError::ModelNotFound(name)) } } }); join_all(futures).await } } impl Default for ModelRegistry { fn default() -> Self { Self::new() } } /// Registry statistics #[derive(Debug, Clone)] pub struct RegistryStats { pub total_models: usize, pub total_registrations: u64, pub created_at: std::time::SystemTime, pub last_access: std::time::SystemTime, } /// Global model registry instance (singleton pattern) static GLOBAL_REGISTRY: once_cell::sync::Lazy> = once_cell::sync::Lazy::new(|| Arc::new(ModelRegistry::new())); /// Get global model registry pub fn get_global_registry() -> Arc { GLOBAL_REGISTRY.clone() } // ========== PARALLEL EXECUTION OPTIMIZATIONS ========== /// High-performance parallel executor for ML models optimized for sub-50μs latency #[derive(Debug)] pub struct ParallelExecutor { /// Performance profile profile: HFTPerformanceProfile, /// CPU affinity settings cpu_affinity: Option>, /// Thread pool for CPU-bound operations cpu_pool: Arc, /// Async runtime handle #[allow(dead_code)] runtime_handle: tokio::runtime::Handle, } impl ParallelExecutor { /// Create new parallel executor with HFT performance profile pub fn new(profile: HFTPerformanceProfile) -> Result { // Create dedicated thread pool based on profile let cpu_pool = rayon::ThreadPoolBuilder::new() .num_threads( profile .cpu_affinity .as_ref() .map(|v| v.len()) .unwrap_or(num_cpus::get()), ) .thread_name(|i| format!("ml-cpu-{}", i)) .build() .map_err(|e| MLError::ModelError(format!("Failed to create thread pool: {}", e)))?; let runtime_handle = tokio::runtime::Handle::try_current() .map_err(|e| MLError::ModelError(format!("No tokio runtime available: {}", e)))?; let cpu_affinity = profile.cpu_affinity.clone(); Ok(Self { profile, cpu_affinity, cpu_pool: Arc::new(cpu_pool), runtime_handle, }) } /// Execute parallel predictions with latency optimization pub async fn execute_parallel_predictions( &self, models: Vec>, features: Features, ) -> Vec> { let start_time = std::time::Instant::now(); // Determine execution strategy based on performance profile let results = match self.profile.optimization_level { OptimizationLevel::UltraLow => { // Ultra-low latency: parallel execution with minimal overhead self.execute_ultra_low_latency(models, features).await }, OptimizationLevel::Low => { // Low latency: parallel with basic batching self.execute_low_latency(models, features).await }, OptimizationLevel::Medium => { // Medium: balanced parallel execution self.execute_balanced(models, features).await }, OptimizationLevel::High => { // High: conservative with full validation self.execute_conservative(models, features).await }, }; let execution_time = start_time.elapsed(); // Log performance if exceeding target latency if execution_time.as_micros() > self.profile.max_latency_us as u128 { tracing::warn!( "Parallel execution exceeded target latency: {}μs > {}μs", execution_time.as_micros(), self.profile.max_latency_us ); } results } /// Ultra-low latency execution (<10μs target) async fn execute_ultra_low_latency( &self, models: Vec>, features: Features, ) -> Vec> { // Use futures::future::join_all for minimal overhead let futures = models.into_iter().map(|model| { let features = features.clone(); async move { model.predict(&features).await } }); join_all(futures).await } /// Low latency execution with basic optimizations async fn execute_low_latency( &self, models: Vec>, features: Features, ) -> Vec> { // Group models by type for potential batching let mut model_groups: HashMap>> = HashMap::new(); for model in models { let model_type = model.model_type(); model_groups.entry(model_type).or_default().push(model); } let mut all_futures = Vec::new(); for (_, group_models) in model_groups { for model in group_models { let features = features.clone(); all_futures.push(async move { model.predict(&features).await }); } } join_all(all_futures).await } /// Balanced execution with moderate optimizations async fn execute_balanced( &self, models: Vec>, features: Features, ) -> Vec> { // Validate features once for all models for model in &models { if let Err(e) = model.validate_features(&features) { tracing::debug!( "Feature validation failed for model {}: {}", model.name(), e ); } } let futures = models.into_iter().map(|model| { let features = features.clone(); async move { if model.is_ready() { model.predict(&features).await } else { Err(MLError::ModelError(format!( "Model {} not ready", model.name() ))) } } }); join_all(futures).await } /// Conservative execution with full validation async fn execute_conservative( &self, models: Vec>, features: Features, ) -> Vec> { let mut results = Vec::new(); for model in models { // Comprehensive validation if !model.is_ready() { results.push(Err(MLError::ModelError(format!( "Model {} not ready", model.name() )))); continue; } if let Err(e) = model.validate_features(&features) { results.push(Err(e)); continue; } // Execute with timeout let prediction_future = model.predict(&features); let timeout_duration = std::time::Duration::from_micros(self.profile.max_latency_us); match tokio::time::timeout(timeout_duration, prediction_future).await { Ok(result) => results.push(result), Err(_) => results.push(Err(MLError::ModelError(format!( "Model {} prediction timed out after {}μs", model.name(), self.profile.max_latency_us )))), } } results } /// Get execution statistics pub fn get_stats(&self) -> ExecutorStats { ExecutorStats { optimization_level: self.profile.optimization_level, target_latency_us: self.profile.max_latency_us, cpu_threads: self.cpu_pool.current_num_threads(), cpu_affinity: self.cpu_affinity.clone(), } } } /// Executor performance statistics #[derive(Debug, Clone)] pub struct ExecutorStats { pub optimization_level: OptimizationLevel, pub target_latency_us: u64, pub cpu_threads: usize, pub cpu_affinity: Option>, } /// Latency optimizer for ML inference pipelines #[derive(Debug)] pub struct LatencyOptimizer { /// Target latency in microseconds target_latency_us: u64, /// Performance history performance_history: Arc>>, /// Optimization parameters #[allow(dead_code)] optimization_params: OptimizationParams, } #[derive(Debug, Clone)] #[allow(dead_code)] struct PerformancePoint { timestamp: std::time::Instant, latency_us: u64, model_count: usize, batch_size: u32, success: bool, } #[derive(Debug, Clone)] #[allow(dead_code)] struct OptimizationParams { max_batch_size: u32, adaptive_batching: bool, prefetch_enabled: bool, cache_predictions: bool, } impl Default for OptimizationParams { fn default() -> Self { Self { max_batch_size: 8, adaptive_batching: true, prefetch_enabled: true, cache_predictions: false, // Disabled for real-time trading } } } impl LatencyOptimizer { /// Create new latency optimizer pub fn new(target_latency_us: u64) -> Self { Self { target_latency_us, performance_history: Arc::new(RwLock::new(Vec::new())), optimization_params: OptimizationParams::default(), } } /// Record performance measurement pub async fn record_performance( &self, latency_us: u64, model_count: usize, batch_size: u32, success: bool, ) { let point = PerformancePoint { timestamp: std::time::Instant::now(), latency_us, model_count, batch_size, success, }; { let mut history = self.performance_history.write().await; history.push(point); // Keep only recent history (last 1000 measurements) if history.len() > 1000 { let excess = history.len() - 1000; history.drain(0..excess); } } } /// Get optimization recommendations pub async fn get_recommendations(&self) -> OptimizationRecommendations { let history = self.performance_history.read().await; if history.is_empty() { return OptimizationRecommendations::default(); } let recent_points: Vec<&PerformancePoint> = history.iter().rev().take(100).collect(); let avg_latency = recent_points.iter().map(|p| p.latency_us).sum::() / recent_points.len() as u64; let success_rate = recent_points.iter().filter(|p| p.success).count() as f64 / recent_points.len() as f64; OptimizationRecommendations { current_avg_latency_us: avg_latency, target_latency_us: self.target_latency_us, success_rate, meets_target: avg_latency <= self.target_latency_us, recommended_batch_size: self.calculate_optimal_batch_size(&recent_points), recommended_model_limit: self.calculate_optimal_model_limit(&recent_points), } } fn calculate_optimal_batch_size(&self, points: &[&PerformancePoint]) -> u32 { // Simple heuristic: find batch size with best latency/success ratio let mut batch_performance: HashMap = HashMap::new(); for point in points { let entry = batch_performance .entry(point.batch_size) .or_insert((0, 0.0)); entry.0 += point.latency_us; entry.1 += if point.success { 1.0 } else { 0.0 }; } batch_performance .into_iter() .filter(|(_, (_, success_count))| *success_count > 0.0) .min_by_key(|(_, (latency, success_count))| { // Optimize for latency with success rate weighting ((*latency as f64) / success_count) as u64 }) .map(|(batch_size, _)| batch_size) .unwrap_or(1) } fn calculate_optimal_model_limit(&self, points: &[&PerformancePoint]) -> usize { // Find the sweet spot where adding more models doesn't improve latency let mut model_performance: HashMap = HashMap::new(); for point in points { if point.success { let entry = model_performance.entry(point.model_count).or_insert(0); *entry += point.latency_us; } } model_performance .into_iter() .filter(|(_, avg_latency)| *avg_latency <= self.target_latency_us) .max_by_key(|(model_count, _)| *model_count) .map(|(model_count, _)| model_count) .unwrap_or(1) } } /// Optimization recommendations from latency analysis #[derive(Debug, Clone)] pub struct OptimizationRecommendations { pub current_avg_latency_us: u64, pub target_latency_us: u64, pub success_rate: f64, pub meets_target: bool, pub recommended_batch_size: u32, pub recommended_model_limit: usize, } impl Default for OptimizationRecommendations { fn default() -> Self { Self { current_avg_latency_us: 0, target_latency_us: 50, success_rate: 0.0, meets_target: false, recommended_batch_size: 1, recommended_model_limit: 1, } } } /// Create optimized parallel executor for HFT scenarios pub fn create_hft_parallel_executor() -> Result { let profile = create_ultra_low_latency_profile(); ParallelExecutor::new(profile) } /// Create latency optimizer with HFT targets pub fn create_hft_latency_optimizer() -> LatencyOptimizer { LatencyOptimizer::new(50) // 50 microsecond target } // ========== CANONICAL TRAINING AND VALIDATION METRICS ========== // These are the unified types that all ML modules must use to prevent type conflicts /// Canonical training metrics used throughout ML module #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TrainingMetrics { /// Training loss value pub loss: f64, /// Training accuracy (0.0 to 1.0) pub accuracy: f64, /// Training precision (0.0 to 1.0) pub precision: f64, /// Training recall (0.0 to 1.0) pub recall: f64, /// Training F1 score (0.0 to 1.0) pub f1_score: f64, /// Total training time in seconds pub training_time_seconds: f64, /// Number of epochs trained pub epochs_trained: u32, /// Whether convergence was achieved pub convergence_achieved: bool, /// Additional model-specific metrics pub additional_metrics: HashMap, } impl TrainingMetrics { /// Create new training metrics pub fn new() -> Self { Self { loss: 0.0, accuracy: 0.0, precision: 0.0, recall: 0.0, f1_score: 0.0, training_time_seconds: 0.0, epochs_trained: 0, convergence_achieved: false, additional_metrics: HashMap::new(), } } /// Add an additional metric pub fn add_metric(&mut self, name: &str, value: f64) { self.additional_metrics.insert(name.to_string(), value); } /// Check if training was successful pub fn is_successful(&self) -> bool { self.convergence_achieved && self.accuracy > 0.5 } } impl Default for TrainingMetrics { fn default() -> Self { Self::new() } } /// Canonical validation metrics used throughout ML module #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ValidationMetrics { /// Validation loss value pub validation_loss: f64, /// Validation accuracy (0.0 to 1.0) pub validation_accuracy: f64, /// Validation precision (0.0 to 1.0) pub validation_precision: f64, /// Validation recall (0.0 to 1.0) pub validation_recall: f64, /// Validation F1 score (0.0 to 1.0) pub validation_f1_score: f64, /// Number of samples validated pub samples_validated: usize, /// Additional model-specific validation metrics pub additional_metrics: HashMap, } impl ValidationMetrics { /// Create new validation metrics pub fn new() -> Self { Self { validation_loss: 0.0, validation_accuracy: 0.0, validation_precision: 0.0, validation_recall: 0.0, validation_f1_score: 0.0, samples_validated: 0, additional_metrics: HashMap::new(), } } /// Add an additional validation metric pub fn add_metric(&mut self, name: &str, value: f64) { self.additional_metrics.insert(name.to_string(), value); } /// Check if validation was successful pub fn is_successful(&self) -> bool { self.validation_accuracy > 0.5 && self.samples_validated > 0 } } impl Default for ValidationMetrics { fn default() -> Self { Self::new() } } // Public exports moved to end of file after all type definitions // ========== CANONICAL ML TYPES ========== // These are the unified types that all ML modules must use to prevent type conflicts /// Canonical inference result used throughout ML module #[derive(Debug, Clone, Serialize, Deserialize)] pub struct InferenceResult { /// Model identifier pub model_id: String, /// Prediction value (primary prediction) pub prediction_value: f64, /// Confidence score (0.0 to 1.0) pub confidence: f64, /// Latency in microseconds pub latency_us: u64, /// Timestamp in microseconds since UNIX epoch pub timestamp: u64, /// Model metadata pub metadata: ModelMetadata, } impl InferenceResult { /// Create new inference result pub fn new( model_id: String, prediction_value: f64, confidence: f64, latency_us: u64, timestamp: u64, metadata: ModelMetadata, ) -> Self { Self { model_id, prediction_value, confidence, latency_us, timestamp, metadata, } } /// Extract prediction as float value pub fn prediction_as_float(&self) -> f64 { self.prediction_value } /// Get the model identifier pub fn model_id(&self) -> &str { &self.model_id } } /// Canonical model metadata used throughout ML module #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ModelMetadata { /// Type of the model pub model_type: ModelType, /// Model version pub version: String, /// Number of features used for inference pub features_used: usize, /// Memory usage in megabytes pub memory_usage_mb: f64, /// Additional metadata key-value pairs pub additional_metadata: HashMap, } impl ModelMetadata { /// Create new model metadata pub fn new( model_type: ModelType, version: String, features_used: usize, memory_usage_mb: f64, ) -> Self { Self { model_type, version, features_used, memory_usage_mb, additional_metadata: HashMap::new(), } } /// Add additional metadata pub fn add_metadata(&mut self, key: &str, value: String) { self.additional_metadata.insert(key.to_string(), value); } /// Mark the model as trained pub fn mark_trained(&mut self) { self.add_metadata("training_status", "trained".to_string()); self.add_metadata( "training_timestamp", std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap_or_default() .as_secs() .to_string(), ); } } /// Canonical model type enum used throughout ML module #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)] pub enum ModelType { /// Compact Deep Q-Network CompactDQN, /// Distilled micro network for ultra-low latency DistilledMicroNet, /// Standard Deep Q-Network DQN, /// Rainbow `DQN` with all enhancements RainbowDQN, /// `MAMBA` model (SSM) MAMBA, /// Temporal Fusion Transformer TFT, /// Temporal Graph Neural Network TGGN, /// Liquid Neural Network LNN, /// Temporal Limit Order Book transformer TLOB, /// Proximal Policy Optimization PPO, /// Transformer for sequence modeling Transformer, /// Mamba state space model (alias for `MAMBA`) Mamba, /// Liquid time constant networks (alias for LNN) LiquidNet, /// Temporal Graph Neural Network (alias for TGGN) TGNN, /// Ensemble methods Ensemble, } impl ModelType { /// Get file extension for model type pub fn file_extension(&self) -> &'static str { match self { ModelType::DQN => "dqn", ModelType::MAMBA | ModelType::Mamba => "mamba", ModelType::TFT => "tft", ModelType::TGGN | ModelType::TGNN => "tggn", ModelType::LNN | ModelType::LiquidNet => "lnn", ModelType::CompactDQN => "compact_dqn", ModelType::DistilledMicroNet => "distilled", ModelType::RainbowDQN => "rainbow_dqn", ModelType::TLOB => "tlob", ModelType::PPO => "ppo", ModelType::Transformer => "transformer", ModelType::Ensemble => "ensemble", } } /// Get model type from string pub fn from_str(s: &str) -> Option { match s.to_lowercase().as_str() { "dqn" => Some(ModelType::DQN), "mamba" => Some(ModelType::MAMBA), "tft" => Some(ModelType::TFT), "tggn" | "tgnn" => Some(ModelType::TGGN), "lnn" | "liquidnet" => Some(ModelType::LNN), "compact_dqn" | "compactdqn" => Some(ModelType::CompactDQN), "distilled" | "distilledmicronet" => Some(ModelType::DistilledMicroNet), "rainbow_dqn" | "rainbowdqn" => Some(ModelType::RainbowDQN), "tlob" => Some(ModelType::TLOB), "ppo" => Some(ModelType::PPO), "transformer" => Some(ModelType::Transformer), "ensemble" => Some(ModelType::Ensemble), _ => None, } } } // TEMPORARILY COMMENTED OUT - These modules need to be checked for availability // Re-export training pipeline system (from existing training_pipeline module) // pub use training_pipeline::{ // ProductionMLTrainingSystem, ProductionTrainingConfig, ProductionTrainingMetrics, // FinancialFeatures, MicrostructureFeatures, RiskFeatures, TrainingResult, // }; // Note: All types in this module are already public and available // External crates can import them directly as: use ml::{Features, ModelPrediction, etc.} /// Prelude module for convenient imports of commonly used ML types /// /// This module re-exports the most commonly used types and traits from the ML crate /// to allow users to import everything they need with a single `use ml::prelude::*;` pub mod prelude { // Core ML types pub use crate::{ CommonError, CommonTypeError, ErrorCategory, Features, Feedback, FeatureVector, HealthStatus, InferenceResult, IntegerTensor, MarketDataSnapshot, MarketRegime, ModelMetadata, ModelPrediction, ModelType, Trade, TrainingMetrics, UpdateSummary, ValidationMetrics, }; // Error types pub use crate::{MLError, MLResult, UnifiedMLResult}; // ML Model trait pub use crate::MLModel; // Model registry pub use crate::{get_global_registry, ModelRegistry, RegistryStats}; // Performance types pub use crate::{ create_hft_latency_optimizer, create_hft_parallel_executor, create_hft_performance_profile, create_hft_performance_profile_with_latency, create_ultra_low_latency_profile, ExecutorStats, HFTPerformanceProfile, LatencyOptimizer, OptimizationLevel, OptimizationRecommendations, ParallelExecutor, }; // Constants pub use crate::{MAX_INFERENCE_LATENCY_US, PRECISION_FACTOR}; // Deployment types // DISABLED until deployment module is fixed // pub use crate::deployment::versioning::ModelVersion; // Tensor types from candle pub use candle_core::{Device, Tensor}; pub use candle_nn::{Module, VarBuilder, VarMap}; // Common external types pub use rust_decimal::Decimal; pub use serde::{Deserialize, Serialize}; }