//! Copula-Based Dependency Modeling with Machine Learning //! //! Implements ML-enhanced copula models for capturing complex dependencies between //! financial risk factors. Supports various copula families with neural network //! parameter estimation for dynamic dependency modeling. //! //! # Features //! - Dynamic copula parameter estimation using neural networks //! - Multiple copula families: Gaussian, t-Copula, Clayton, Gumbel, Frank //! - Vine copulas for high-dimensional dependencies //! - Time-varying copula parameters //! - Tail dependency modeling for extreme events //! - Conditional copulas for regime-dependent dependencies //! //! # Performance Targets //! - Parameter estimation: <500μs //! - Dependency simulation: <1ms for 1000 samples //! - Real-time parameter updates: <100μs //! - Memory efficiency: <128MB for 100 assets use std::sync::Arc; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use core::types::prelude::*; use super::*; #[test] fn test_neural_copula_creation() { let config = CopulaModelConfig::default(); let copula_family = CopulaFamily::Gaussian { correlation_matrix: vec![vec![1.0, 0.5], vec![0.5, 1.0]] }; let model = NeuralCopulaModel::new(copula_family, config); assert_eq!(model.config.n_factors, 10); assert!(model.parameter_history.is_empty()); } #[test] fn test_parameter_constraint() { let config = CopulaModelConfig::default(); let copula_family = CopulaFamily::Clayton { theta: 1.0 }; let model = NeuralCopulaModel::new(copula_family, config); // Test Clayton theta constraint (must be > 0) let constrained = model.constrain_parameters(vec![-0.5]); assert!(constrained[0] > 0.0); let constrained = model.constrain_parameters(vec![2.0]); assert_eq!(constrained[0], 2.0); } #[test] fn test_tail_dependence_estimation() { let config = CopulaModelConfig::default(); let copula_family = CopulaFamily::Gaussian { correlation_matrix: vec![vec![1.0, 0.5], vec![0.5, 1.0]] }; let model = NeuralCopulaModel::new(copula_family, config); // Create mock market data let asset_data = vec![ AssetMarketData { asset_id: "AAPL".to_string(), returns: vec![0.01, -0.02, 0.015, -0.01, 0.005], mean_return: 0.001, volatility: 0.02, skewness: 0.1, kurtosis: 3.0, }, AssetMarketData { asset_id: "MSFT".to_string(), returns: vec![0.008, -0.015, 0.012, -0.008, 0.003], mean_return: 0.0005, volatility: 0.018, skewness: -0.1, kurtosis: 2.8, }, ]; let market_data = MarketDataWindow { asset_data, window_start: Utc::now(), window_end: Utc::now(), n_observations: 5, }; let tail_dep = model.estimate_tail_dependence(&market_data); assert!(tail_dep.upper_tail >= 0.0 && tail_dep.upper_tail <= 1.0); assert!(tail_dep.lower_tail >= 0.0 && tail_dep.lower_tail <= 1.0); } #[test] fn test_copula_simulation() { let config = CopulaModelConfig::default(); let copula_family = CopulaFamily::Clayton { theta: 2.0 }; let model = NeuralCopulaModel::new(copula_family, config); let parameters = CopulaParameters { parameters: vec![2.0], confidence_intervals: vec![(1.5, 2.5)], tail_dependence: TailDependence { upper_tail: 0.0, lower_tail: 0.5, asymmetry: -0.5, upper_tail_ci: (0.0, 0.1), lower_tail_ci: (0.4, 0.6), }, gof_statistics: GoodnessOfFitStats { cramer_von_mises: 0.1, anderson_darling: 0.8, kolmogorov_smirnov: 0.05, aic: 100.0, bic: 105.0, p_value: 0.15, }, timestamp: Utc::now(), confidence_score: 0.85, }; let simulation_result = model.simulate_dependencies(1000, ¶meters); assert_eq!(simulation_result.simulated_uniforms.len(), 1000); assert_eq!(simulation_result.simulated_uniforms[0].len(), model.config.n_factors); assert!(simulation_result.simulation_time_us > 0); // Check that all values are in [0, 1] for sample in &simulation_result.simulated_uniforms { for &value in sample { assert!(value >= 0.0 && value <= 1.0); } } } #[test] fn test_performance_requirements() { let config = CopulaModelConfig::default(); let copula_family = CopulaFamily::Gaussian { correlation_matrix: vec![vec![1.0, 0.3], vec![0.3, 1.0]] }; let mut model = NeuralCopulaModel::new(copula_family, config); // Create minimal market data for performance test let asset_data = vec![ AssetMarketData { asset_id: "TEST1".to_string(), returns: vec![0.01; 100], mean_return: 0.01, volatility: 0.02, skewness: 0.0, kurtosis: 3.0, }, AssetMarketData { asset_id: "TEST2".to_string(), returns: vec![0.008; 100], mean_return: 0.008, volatility: 0.018, skewness: 0.0, kurtosis: 3.0, }, ]; let market_data = MarketDataWindow { asset_data, window_start: Utc::now(), window_end: Utc::now(), n_observations: 100, }; let start = std::time::Instant::now(); let parameters = model.estimate_parameters(&market_data); let estimation_time = start.elapsed(); // Should complete parameter estimation in <500μs assert!(estimation_time.as_micros() < 500); let start = std::time::Instant::now(); let simulation = model.simulate_dependencies(1000, ¶meters); let simulation_time = start.elapsed(); // Should complete simulation in <1ms assert!(simulation_time.as_millis() < 1); assert!(simulation.simulation_time_us < 1000); }