Files
foxhunt/ml/src/lib.rs
jgrusewski 030a15ee05 🔧 Emergency Fix: Resolve catastrophic _i32 suffix corruption (463→0 errors)
- Fixed systematic array indexing corruption: [0_i32] → [0]
- Fixed numeric literal suffixes across 835 files
- Fixed iterator patterns on RwLockReadGuard (.iter() required)
- Fixed float type annotations (365.25_f64 for sqrt)
- Fixed missing semicolons in position manager
- Fixed reference dereferencing in data loader

Root cause: Mass refactoring incorrectly added _i32 suffixes to array indices
Impact: Complete compilation failure (463 errors)
Resolution: Automated regex + targeted fixes
Result: 100% compilation success (0 errors)

Validated: cargo check --workspace passes
Ready for: Production deployment
2025-10-10 23:05:26 +02:00

2105 lines
67 KiB
Rust

#![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
//! 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<dyn std::error::Error>> {
//! // 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<Var>,
params: candle_optimisers::adam::ParamsAdam,
) -> Result<Self, MLError> {
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<String>) -> 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<String>) -> 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<String>) -> 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<Utc>,
/// 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<f64>);
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<i64>);
/// 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 },
/// 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<candle_core::Error> for MLError {
fn from(err: candle_core::Error) -> Self {
MLError::ModelError(format!("Candle error: {}", err))
}
}
// Implement From trait for LabelingError
impl From<labeling::gpu_acceleration::LabelingError> 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<error_handling::TradingError> 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<anyhow::Error> for MLError {
fn from(err: anyhow::Error) -> Self {
MLError::AnyhowError(err.to_string())
}
}
// Implement From trait for std::io::Error
impl From<std::io::Error> 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<MLError> 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::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<CommonTypeError> for MLError {
fn from(err: CommonTypeError) -> Self {
MLError::ModelError(format!("Common type error: {}", err))
}
}
impl From<serde_json::Error> for MLError {
fn from(err: serde_json::Error) -> Self {
MLError::SerializationError {
reason: err.to_string(),
}
}
}
impl From<inference::RealInferenceError> 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<ProductionTrainingError> for MLError
impl From<training_pipeline::ProductionTrainingError> 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<T> = Result<T, MLError>;
/// New unified result type using CommonError for better integration
pub type UnifiedMLResult<T> = Result<T, CommonError>;
/// 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 dqn;
pub mod ensemble;
pub mod flash_attention;
pub mod integration;
pub mod labeling;
pub mod liquid;
pub mod mamba;
pub mod microstructure;
pub mod ppo;
pub mod risk;
pub mod safety;
pub mod tft;
pub mod tgnn;
pub mod tlob;
pub mod transformers;
pub mod universe;
// ========== INFRASTRUCTURE MODULES ==========
// Infrastructure
pub mod benchmarks;
pub mod common;
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;
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
// 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<T> {
pub data: T,
pub success: bool,
pub message: Option<String>,
pub execution_time_ms: u64,
pub metadata: HashMap<String, String>,
}
impl<T> MLAppResult<T> {
/// 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<Vec<usize>>,
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<f64>,
/// Feature names for debugging
pub names: Vec<String>,
/// Timestamp of features
pub timestamp: u64,
/// Symbol these features are for
pub symbol: Option<String>,
}
impl Features {
pub fn new(values: Vec<f64>, names: Vec<String>) -> 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<String, serde_json::Value>,
/// 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<f64>,
/// Reward signal (for reinforcement learning)
pub reward: Option<f64>,
/// Trading performance metrics
pub performance_metrics: HashMap<String, f64>,
/// 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<ModelPrediction>;
/// 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<String, Arc<dyn MLModel>>,
/// Registry metadata
metadata: Arc<RwLock<RegistryMetadata>>,
}
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!("<DashMap with {} models>", 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<dyn MLModel>) -> 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<Arc<dyn MLModel>> {
// 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<Arc<dyn MLModel>> {
self.models
.iter()
.map(|entry| entry.value().clone())
.collect()
}
/// Get model names
pub fn get_model_names(&self) -> Vec<String> {
self.models
.iter()
.map(|entry| entry.key().clone())
.collect()
}
/// Remove model from registry
pub async fn remove(&self, name: &str) -> Option<Arc<dyn MLModel>> {
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<MLResult<ModelPrediction>> {
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<MLResult<ModelPrediction>> {
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<Arc<ModelRegistry>> =
once_cell::sync::Lazy::new(|| Arc::new(ModelRegistry::new()));
/// Get global model registry
pub fn get_global_registry() -> Arc<ModelRegistry> {
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<Vec<usize>>,
/// Thread pool for CPU-bound operations
cpu_pool: Arc<rayon::ThreadPool>,
/// 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<Self, MLError> {
// 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<Arc<dyn MLModel>>,
features: Features,
) -> Vec<MLResult<ModelPrediction>> {
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<Arc<dyn MLModel>>,
features: Features,
) -> Vec<MLResult<ModelPrediction>> {
// 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<Arc<dyn MLModel>>,
features: Features,
) -> Vec<MLResult<ModelPrediction>> {
// Group models by type for potential batching
let mut model_groups: HashMap<ModelType, Vec<Arc<dyn MLModel>>> = 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<Arc<dyn MLModel>>,
features: Features,
) -> Vec<MLResult<ModelPrediction>> {
// 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<Arc<dyn MLModel>>,
features: Features,
) -> Vec<MLResult<ModelPrediction>> {
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<Vec<usize>>,
}
/// Latency optimizer for ML inference pipelines
#[derive(Debug)]
pub struct LatencyOptimizer {
/// Target latency in microseconds
target_latency_us: u64,
/// Performance history
performance_history: Arc<RwLock<Vec<PerformancePoint>>>,
/// 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::<u64>() / 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<u32, (u64, f64)> = 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<usize, u64> = 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<ParallelExecutor, MLError> {
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<String, f64>,
}
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<String, f64>,
}
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<String, String>,
}
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<Self> {
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};
}