- Fix format_push_string: write!() instead of push_str(&format!()) (25 sites) - Fix str_to_string: .to_owned() instead of .to_string() on &str (6 sites) - Fix unseparated_literal_suffix: add _ separator (6 sites) - Fix multiple_inherent_impl: merge split impl blocks in TGGN, TFT, OFI (3) - Fix else_if_without_else: add exhaustive else clauses (3 sites) - Fix if_then_some_else_none: use .then().transpose() (1 site) - Fix unwrap_in_result: replace expect() with match + ? (2 sites) - Fix wildcard_enum_match_arm: enumerate Storage variants explicitly (2) - Fix decimal_literal_representation: use hex for power-of-2 constants (5) - Fix rc_buffer: Arc<Vec<T>> → Arc<[T]> for OFI features - Fix needless_range_loop: convert to iterator patterns (17 sites) - Fix used_underscore_binding: remove prefix on used vars (6 sites) - Fix doc list item indentation (7 sites) - Allow too_many_arguments on ML training functions (4) - Allow multiple_unsafe_ops_per_block on CUDA FFI functions (3) - Allow upper_case_acronyms on SLSTM/MLSTM model names (2) - Add ML-crate pedantic allows: shadow, similar_names, type_complexity, indexing_slicing, partial_pub_fields, non_ascii_literal, same_name_method (following existing ml-labeling/ml-universe pattern) Result: cargo clippy --workspace -- -D warnings passes with zero warnings. All 2758+ lib tests pass (2 pre-existing backtesting failures unchanged). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
174 lines
6.4 KiB
Rust
174 lines
6.4 KiB
Rust
#![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<EnsembleError> 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<EnsembleError> 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))
|
|
}
|
|
}
|
|
}
|
|
}
|