#![deny(clippy::unwrap_used, clippy::expect_used)] #![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used))] #![allow(dead_code)] #![allow(missing_docs)] #![allow(missing_debug_implementations)] #![allow(unused_crate_dependencies)] #![allow(clippy::float_arithmetic)] #![allow(clippy::non_ascii_literal)] #![allow(clippy::str_to_string)] #![allow(clippy::partial_pub_fields)] #![allow(clippy::multiple_inherent_impl)] #![allow(clippy::same_name_method)] #![allow(clippy::shadow_reuse)] #![allow(clippy::shadow_unrelated)] #![allow(clippy::shadow_same)] #![allow(clippy::doc_markdown)] #![allow(clippy::indexing_slicing)] #![allow(clippy::missing_const_for_fn)] #![allow(clippy::module_name_repetitions)] #![allow(clippy::integer_division)] #![allow(clippy::cognitive_complexity)] #![allow(clippy::similar_names)] #![allow(clippy::clone_on_ref_ptr)] #![allow(clippy::too_many_lines)] #![allow(clippy::type_complexity)] #![allow(clippy::single_char_lifetime_names)] #![allow(clippy::as_conversions)] #![allow(clippy::cast_precision_loss)] #![allow(clippy::cast_possible_truncation)] #![allow(clippy::default_numeric_fallback)] #![allow(clippy::arithmetic_side_effects)] #![allow(clippy::needless_range_loop)] #![allow(clippy::into_iter_on_ref)] #![allow(clippy::new_without_default)] #![allow(clippy::manual_let_else)] #![allow(clippy::unnecessary_wraps)] #![allow(clippy::too_many_arguments)] #![allow(clippy::must_use_candidate)] #![allow(clippy::missing_errors_doc)] #![allow(clippy::cast_sign_loss)] #![allow(clippy::cast_possible_wrap)] #![allow(clippy::cast_lossless)] #![allow(clippy::unused_async)] #![allow(clippy::match_same_arms)] #![allow(clippy::unused_self)] #![allow(clippy::map_err_ignore)] #![allow(clippy::single_match_else)] #![allow(clippy::wildcard_imports)] #![allow(clippy::unnecessary_cast)] //! Ensemble signal aggregation for trading models use thiserror::Error; // Re-export core types so sub-modules can use `crate::X` pub use ml_core::{Features, HealthStatus, MLError, MLResult, ModelPrediction}; pub use common::model_types::ModelType; pub mod ab_testing; pub mod adaptive_ml_integration; pub mod aggregator; pub mod confidence; pub mod conviction_gates; pub mod coordinator; pub mod coordinator_extended; pub mod cuda_streams; pub mod decision; pub mod gate_optimizer; pub mod hot_swap; pub mod inference_adapter; pub mod inference_ensemble; pub mod metrics; pub mod model; pub mod signal; pub mod stream_ensemble; pub mod training_integration; pub mod voting; pub mod weight_optimizer; pub mod weights; // Re-export key types that are used across ensemble modules pub use ab_testing::{ ABGroup, ABMetricsTracker, ABTestConfig, ABTestResults, ABTestRouter, GroupMetrics, Recommendation, StatisticalTestResult, }; pub use adaptive_ml_integration::{ AdaptiveMLEnsemble, AdaptiveMetrics, MarketRegime, PricePoint, RegimeConfig, }; pub use aggregator::{ModelSignal, SignalMetadata, SignalStatistics}; pub use confidence::{ AggregationConfig, AleatoricConfig, CalibrationParams, CombinationMethod, ConfidenceAggregator, DisagreementRecord, DisagreementTracker, EnsemblePredictionWithUncertainty, EpistemicConfig, IntervalCombiner, ModelContribution, PredictionInterval, ReliabilityRecord, ReliabilityScorer, UncertaintyDecomposition, UncertaintyQuantifier, VarianceEstimationMethod, }; pub use conviction_gates::{ ConvictionGateConfig, ConvictionGateEvaluator, ConvictionGateOutcome, GateEvaluation, GateInput, GatePassResult, GateRejection, TradingSession, }; pub use coordinator::{EnsembleCoordinator, ModelRegistry, SignalAggregator}; pub use coordinator_extended::{ DiversityAnalyzer, DiversityMetrics, EnsembleConfig as ExtendedEnsembleConfig, ExtendedEnsembleCoordinator, ModelPerformance, PerformanceAttribution, PerformanceTracker, SupportedModel, WeightSnapshot, }; pub use decision::{EnsembleDecision, ModelVote, ModelWeight, PerformanceMetrics, TradingAction}; pub use gate_optimizer::{ GateBucketMetrics, GateOptimizationResult, GateOptimizer, GateOptimizerConfig, ThresholdAdjustment, }; pub use hot_swap::{ CanaryMetrics, CanaryResult, CheckpointModel, CheckpointValidator, HotSwapManager, ModelBufferPair, RollbackPolicy, ValidationResult, }; pub use inference_adapter::{EnsemblePrediction, FeatureVector, ModelInferenceAdapter, PredictionMeta}; pub use metrics::{ EnsembleMetrics, CANARY_MONITORING_TOTAL, CHECKPOINT_SWAPS_TOTAL, CHECKPOINT_SWAP_LATENCY_MICROSECONDS, CHECKPOINT_VALIDATION_TOTAL, }; pub use training_integration::EnsembleTrainingIntegration; pub use weight_optimizer::{ ModelRollingMetrics, OptimizationResult, WeightAdjustment, WeightOptimizer, WeightOptimizerConfig, }; /// Errors that can occur in ensemble operations #[derive(Error, Debug)] pub enum EnsembleError { #[error("Failed to acquire lock: {0}")] LockAcquisitionFailed(String), #[error("Invalid ensemble configuration: {0}")] InvalidConfiguration(String), #[error("Model not found: {0}")] ModelNotFound(String), #[error("Insufficient models for ensemble: expected {expected}, got {actual}")] InsufficientModels { expected: usize, actual: usize }, #[error("Weight calculation failed: {0}")] WeightCalculationFailed(String), #[error("Aggregation failed: {0}")] AggregationFailed(String), } // `From for MLError` lives here because ml-ensemble owns // EnsembleError (local) and imports MLError from ml-core (dependency). // This satisfies the orphan rule: EnsembleError is a local type parameter. impl From for MLError { fn from(err: EnsembleError) -> Self { match err { EnsembleError::InvalidConfiguration(msg) => MLError::ConfigError(msg), EnsembleError::ModelNotFound(msg) => MLError::ModelNotFound(msg), EnsembleError::InsufficientModels { expected, actual } => { MLError::ValidationError { message: format!( "Insufficient models: expected {}, got {}", expected, actual ), } } EnsembleError::LockAcquisitionFailed(msg) => MLError::LockError(msg), EnsembleError::WeightCalculationFailed(msg) => { MLError::ModelError(format!("Weight calculation failed: {}", msg)) } EnsembleError::AggregationFailed(msg) => { MLError::InferenceError(format!("Aggregation failed: {}", msg)) } } } }