#![allow(unused_variables, unused_imports)]
//! Unified Backtesting Types - CANONICAL SOURCE OF TRUTH
//!
//! This module provides the unified backtesting types for the entire Foxhunt system.
//! All services (analytics, ai-intelligence, backtesting) MUST use these types.
//!
//! # Architecture
//! - **Core Types**: BacktestResults, TradeResult, BacktestSummary
//! - **ML Extensions**: MonteCarloResult, MLExtensions for AI features
//! - **Analytics**: Comprehensive performance and risk metrics
//! - **Service Integration**: Clean interfaces for all backtesting services
//!
//! # Usage
//! ``rust
//! use types::backtesting::*;
//! use types::performance::PerformanceMetrics;
//! use chrono::Utc;
//! use std::collections::HashMap;
//!
//! let results = BacktestResults {
//!     metadata: BacktestMetadata {
//!         backtest_id: "test".to_string(),
//!         strategy_id: "strategy".to_string(),
//!         symbols: vec![],
//!         start_date: Utc::now(),
//!         end_date: Utc::now(),
//!         execution_time_ms: 1000,
//!         total_trades: 0,
//!         data_points_processed: 0,
//!         warnings: vec![],
//!         errors: vec![],
//!     },
//!     performance: PerformanceMetrics::default(),
//!     trades: vec![],
//!     daily_pnl: vec![],
//!     risk_metrics: RiskMetrics::default(),
//!     walk_forward_results: None,
//!     bias_analysis: BiasAnalysisResults::default(),
//!     benchmark_comparison: None,
//!     monte_carlo_result: None,
//!     attribution: HashMap::new(),
//!     ml_extensions: None,
//!     final_portfolio_value: None,
//!     execution_stats: None,
//! };
//! ``

use std::collections::HashMap;

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

use common::{PnL, Price, Quantity, Side, Symbol, TradeId};
use crate::types::performance::PerformanceMetrics;

// ============================================================================
// CORE BACKTESTING TYPES - UNIFIED ACROSS ALL SERVICES
// ============================================================================

/// Comprehensive backtest results - `CANONICAL` `SINGLE` `SOURCE` `OF` `TRUTH`
///
/// This `struct` unifies the needs of:
/// - Analytics crate: Comprehensive analysis with risk metrics
/// - `AI` Intelligence service: `ML` extensions and monte carlo analysis
/// - Backtesting service: Portfolio and execution metrics
///
/// `BacktestResults` component.
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
/// BacktestResults
/// 
/// Auto-generated documentation placeholder - enhance with specifics
pub struct BacktestResults {
    /// Backtest metadata (from analytics)
    pub metadata: BacktestMetadata,
    /// Performance metrics (from analytics)
    pub performance: PerformanceMetrics,
    /// Trade-by-trade results (from analytics)
    pub trades: Vec<TradeResult>,
    /// Daily `P`&`L` series (from analytics)
    pub daily_pnl: Vec<DailyPnL>,
    /// Risk metrics (from analytics)
    pub risk_metrics: RiskMetrics,
    /// Walk-forward analysis results (from analytics)
    pub walk_forward_results: Option<WalkForwardResults>,
    /// Bias analysis results (from analytics)
    pub bias_analysis: BiasAnalysisResults,
    /// Benchmark comparison (from analytics)
    pub benchmark_comparison: Option<BenchmarkComparison>,

    // ML EXTENSIONS for AI Intelligence service
    /// Monte Carlo analysis results (from ai-intelligence)
    pub monte_carlo_result: Option<MonteCarloResult>,
    /// Attribution analysis (from ai-intelligence)
    pub attribution: HashMap<String, f64>,
    /// `ML`-specific extensions
    pub ml_extensions: Option<MLExtensions>,

    // PORTFOLIO EXTENSIONS for backtesting service
    /// Final portfolio snapshot (from backtesting service)
    pub final_portfolio_value: Option<f64>,
    /// Execution statistics (from backtesting service)
    pub execution_stats: Option<ExecutionStats>,
}

/// Backtest metadata - unified across all services
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `BacktestMetadata` component.
pub struct BacktestMetadata {
    /// Backtest Id
    pub backtest_id: String,
    /// Strategy Id
    pub strategy_id: String,
    /// Symbols
    pub symbols: Vec<Symbol>,
    /// Start Date
    pub start_date: DateTime<Utc>,
    /// End Date
    pub end_date: DateTime<Utc>,
    /// Execution Time Ms
    pub execution_time_ms: u64,
    /// Total Trades
    pub total_trades: usize,
    /// Data Points Processed
    pub data_points_processed: usize,
    /// Warnings
    pub warnings: Vec<String>,
    /// Errors
    pub errors: Vec<String>,
}

/// Individual trade result - `CANONICAL` `SINGLE` `SOURCE` `OF` `TRUTH`
///
/// Unified to support both financial accuracy (analytics) and `ML` processing (ai-intelligence)
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `TradeResult` component.
pub struct TradeResult {
    /// Trade Id
    pub trade_id: TradeId,
    /// Symbol
    pub symbol: Symbol,
    /// Side
    pub side: Side,
    /// Entry Time
    pub entry_time: DateTime<Utc>,
    /// Exit Time
    pub exit_time: DateTime<Utc>,
    /// Entry Price
    pub entry_price: Price,
    /// Exit Price
    pub exit_price: Price,
    /// Quantity
    pub quantity: Quantity,
    /// Pnl
    pub pnl: Decimal,
    /// Commission
    pub commission: Decimal,
    /// Slippage
    pub slippage: Decimal,
    /// Market Impact
    pub market_impact: Decimal,
    /// `Duration` Seconds
    pub duration_seconds: u64,

    // ML Extensions for AI processing
    /// Confidence score from `ML` model (0.0 to 1.0)
    pub ml_confidence: Option<f64>,
    /// Feature vector used for this trade
    pub feature_vector: Option<Vec<f64>>,
}

/// Backtest summary statistics - unified interface
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `BacktestSummary` component.
pub struct BacktestSummary {
    /// Total Trades
    pub total_trades: usize,
    /// Winning Trades
    pub winning_trades: usize,
    /// Losing Trades
    pub losing_trades: usize,
    /// Total Pnl
    pub total_pnl: Decimal,
    /// Max Drawdown
    pub max_drawdown: f64,
    /// Sharpe Ratio
    pub sharpe_ratio: f64,
    /// Sortino Ratio
    pub sortino_ratio: f64,
    /// Win Rate
    pub win_rate: f64,
    /// Profit Factor
    pub profit_factor: f64,
    /// Average Trade `Duration` Seconds
    pub average_trade_duration_seconds: f64,
}

// ============================================================================
// PERFORMANCE AND RISK METRICS - FROM ANALYTICS CRATE
// ============================================================================

// PerformanceMetrics is now imported from crate::performance
// This provides comprehensive metrics for all domains (Financial, ML, System, Risk)

/// Daily `P`&`L` tracking from analytics crate
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `DailyPnL` component.
pub struct DailyPnL {
    /// Date
    pub date: DateTime<Utc>,
    /// Realized Pnl
    pub realized_pnl: Decimal,
    /// Unrealized Pnl
    pub unrealized_pnl: Decimal,
    /// Total Pnl
    pub total_pnl: Decimal,
    /// Portfolio Value
    pub portfolio_value: Decimal,
    /// Drawdown Pct
    pub drawdown_pct: f64,
    /// Daily Return Pct
    pub daily_return_pct: f64,
}

/// Comprehensive risk metrics from analytics crate
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `RiskMetrics` component.
pub struct RiskMetrics {
    /// Value At Risk 95
    pub value_at_risk_95: Decimal,
    /// Conditional Var 95
    pub conditional_var_95: Decimal,
    /// Maximum Drawdown
    pub maximum_drawdown: f64,
    /// Maximum Drawdown `Duration` Days
    pub maximum_drawdown_duration_days: u32,
    /// Volatility Annualized
    pub volatility_annualized: f64,
    /// Downside Deviation
    pub downside_deviation: f64,
    /// Skewness
    pub skewness: f64,
    /// Kurtosis
    pub kurtosis: f64,
    /// Tail Ratio
    pub tail_ratio: f64,
    /// Common Sense Ratio
    pub common_sense_ratio: f64,
}

/// Walk-forward analysis results from analytics crate
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `WalkForwardResults` component.
pub struct WalkForwardResults {
    /// Total Periods
    pub total_periods: usize,
    /// Profitable Periods
    pub profitable_periods: usize,
    /// Average Return Pct
    pub average_return_pct: f64,
    /// Return Consistency
    pub return_consistency: f64,
    /// Parameter Stability Score
    pub parameter_stability_score: f64,
    /// Degradation Factor
    pub degradation_factor: f64,
    /// Efficiency Score
    pub efficiency_score: f64,
    /// Period Results
    pub period_results: Vec<WalkForwardPeriodResult>,
}

/// Individual walk-forward period result
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `WalkForwardPeriodResult` component.
pub struct WalkForwardPeriodResult {
    /// Period Id
    pub period_id: usize,
    /// In Sample Start
    pub in_sample_start: DateTime<Utc>,
    /// In Sample End
    pub in_sample_end: DateTime<Utc>,
    /// Out Sample Start
    pub out_sample_start: DateTime<Utc>,
    /// Out Sample End
    pub out_sample_end: DateTime<Utc>,
    /// In Sample Return
    pub in_sample_return: f64,
    /// Out Sample Return
    pub out_sample_return: f64,
    /// Parameter Values
    pub parameter_values: HashMap<String, f64>,
    /// Confidence Score
    pub confidence_score: f64,
}

/// Bias analysis results from analytics crate
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `BiasAnalysisResults` component.
pub struct BiasAnalysisResults {
    /// Lookahead Bias Detected
    pub lookahead_bias_detected: bool,
    /// Survivorship Bias Score
    pub survivorship_bias_score: f64,
    /// Overfitting Probability
    pub overfitting_probability: f64,
    /// Statistical Significance
    pub statistical_significance: f64,
    /// Data Snooping Ratio
    pub data_snooping_ratio: f64,
    /// Multiple Testing Penalty
    pub multiple_testing_penalty: f64,
    /// White Reality Check Pvalue
    pub white_reality_check_pvalue: f64,
    /// Hansen Spa Pvalue
    pub hansen_spa_pvalue: f64,
    /// Romano Wolf Pvalue
    pub romano_wolf_pvalue: f64,
}

/// Benchmark comparison from analytics crate
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `BenchmarkComparison` component.
pub struct BenchmarkComparison {
    /// Benchmark Name
    pub benchmark_name: String,
    /// Benchmark Return
    pub benchmark_return: f64,
    /// Alpha
    pub alpha: f64,
    /// Beta
    pub beta: f64,
    /// Tracking Error
    pub tracking_error: f64,
    /// Information Ratio
    pub information_ratio: f64,
    /// Correlation
    pub correlation: f64,
    /// Outperformance
    pub outperformance: f64,
    /// Hit Rate
    pub hit_rate: f64,
}

// ============================================================================
// ML EXTENSIONS - FROM AI INTELLIGENCE SERVICE
// ============================================================================

/// Monte Carlo analysis results from `AI` intelligence service
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `MonteCarloResult` component.
pub struct MonteCarloResult {
    /// Simulation Count
    pub simulation_count: usize,
    /// Confidence Intervals
    pub confidence_intervals: HashMap<String, (f64, f64)>,
    /// Expected Return
    pub expected_return: f64,
    /// Expected Sharpe
    pub expected_sharpe: f64,
    /// Probability Of Loss
    pub probability_of_loss: f64,
    /// Worst Case Scenario
    pub worst_case_scenario: f64,
    /// Best Case Scenario
    pub best_case_scenario: f64,
    /// Var 95
    pub var_95: f64,
    /// Cvar 95
    pub cvar_95: f64,
    /// Max Drawdown
    pub max_drawdown: f64,
    /// Success Rate
    pub success_rate: f64,
}

/// `ML`-specific extensions for backtesting
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `MLExtensions` component.
pub struct MLExtensions {
    /// Model prediction accuracy
    pub prediction_accuracy: f64,
    /// Feature importance scores
    pub feature_importance: HashMap<String, f64>,
    /// Model confidence over time
    pub confidence_evolution: Vec<(DateTime<Utc>, f64)>,
    /// Cross-validation scores
    pub cv_scores: Vec<f64>,
    /// Hyperparameter tuning results
    pub hyperparameter_results: HashMap<String, f64>,
}

// ============================================================================
// EXECUTION EXTENSIONS - FROM BACKTESTING SERVICE
// ============================================================================

/// Execution statistics from backtesting service
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `ExecutionStats` component.
pub struct ExecutionStats {
    /// Total Fills
    pub total_fills: u64,
    /// Average Slippage
    pub average_slippage: f64,
    /// Total Commission
    pub total_commission: f64,
    /// Market Impact Cost
    pub market_impact_cost: f64,
    /// Execution Delay Avg Ms
    pub execution_delay_avg_ms: f64,
    /// Rejection Rate
    pub rejection_rate: f64,
}

/// Final performance metrics from backtesting service
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
/// `FinalPerformanceMetrics` component.
pub struct FinalPerformanceMetrics {
    /// Total Return
    pub total_return: f64,
    /// Max Drawdown
    pub max_drawdown: f64,
    /// Sharpe Ratio
    pub sharpe_ratio: f64,
    /// Win Rate
    pub win_rate: f64,
    /// Profit Factor
    pub profit_factor: f64,
}

// ============================================================================
// CONVERSION TRAITS - FOR SERVICE INTEROPERABILITY
// ============================================================================

/// Convert from `AI` service's simplified format to canonical format
impl From<(f64, f64, f64, f64, String)> for TradeResult {
    fn from(
        (entry_time, exit_time, entry_price, exit_price, side): (f64, f64, f64, f64, String),
    ) -> Self {
        Self {
            trade_id: TradeId::new(format!("{}_{}", entry_time as i64, exit_time as i64))
                .unwrap_or_else(|_| TradeId::new("unknown").unwrap()),
            symbol: Symbol::new("UNKNOWN".to_owned()),
            side: match side.as_str() {
                "Buy" => Side::Buy,
                "Sell" => Side::Sell,
                _ => Side::Buy,
            },
            entry_time: DateTime::from_timestamp((entry_time / 1_000_000_000.0) as i64, 0)
                .unwrap_or_else(Utc::now),
            exit_time: DateTime::from_timestamp((exit_time / 1_000_000_000.0) as i64, 0)
                .unwrap_or_else(Utc::now),
            entry_price: Price::from_f64(entry_price).unwrap_or_else(|e| {
                tracing::error!("Invalid entry price: {:?}", e);
                Price::ZERO
            }),
            exit_price: Price::from_f64(exit_price).unwrap_or_else(|e| {
                tracing::error!("Invalid exit price: {:?}", e);
                Price::ZERO
            }),
            quantity: Quantity::from_f64(1.0).unwrap_or_else(|e| {
                tracing::error!("Invalid quantity: {:?}", e);
                Quantity::ZERO
            }),
            pnl: Decimal::try_from(exit_price - entry_price).unwrap_or(Decimal::ZERO),
            commission: Decimal::ZERO,
            slippage: Decimal::ZERO,
            market_impact: Decimal::ZERO,
            duration_seconds: (exit_time - entry_time) as u64 / 1_000_000_000,
            ml_confidence: None,
            feature_vector: None,
        }
    }
}

// ============================================================================
// UTILITY FUNCTIONS
// ============================================================================

impl BacktestResults {
    /// Create a new `BacktestResults` with default values
    #[must_use]
    pub fn new(backtest_id: String, strategy_id: String) -> Self {
        Self {
            metadata: BacktestMetadata {
                backtest_id,
                strategy_id,
                symbols: vec![],
                start_date: Utc::now(),
                end_date: Utc::now(),
                execution_time_ms: 0,
                total_trades: 0,
                data_points_processed: 0,
                warnings: vec![],
                errors: vec![],
            },
            performance: PerformanceMetrics::default(),
            trades: vec![],
            daily_pnl: vec![],
            risk_metrics: RiskMetrics::default(),
            walk_forward_results: None,
            bias_analysis: BiasAnalysisResults::default(),
            benchmark_comparison: None,
            monte_carlo_result: None,
            attribution: HashMap::new(),
            ml_extensions: None,
            final_portfolio_value: None,
            execution_stats: None,
        }
    }

    /// Get a summary of the backtest results
    #[must_use]
    pub fn summary(&self) -> BacktestSummary {
        BacktestSummary {
            total_trades: self.trades.len(),
            winning_trades: self.trades.iter().filter(|t| t.pnl > Decimal::ZERO).count(),
            losing_trades: self.trades.iter().filter(|t| t.pnl < Decimal::ZERO).count(),
            total_pnl: self.trades.iter().map(|t| t.pnl).sum::<Decimal>(),
            max_drawdown: self.performance.maximum_drawdown.unwrap_or(0.0),
            sharpe_ratio: self.performance.sharpe_ratio.unwrap_or(0.0),
            sortino_ratio: self.performance.sortino_ratio.unwrap_or(0.0),
            win_rate: self.performance.win_rate.unwrap_or(0.0),
            profit_factor: self.performance.profit_factor.unwrap_or(0.0),
            average_trade_duration_seconds: self
                .trades
                .iter()
                .map(|t| t.duration_seconds as f64)
                .sum::<f64>()
                / self.trades.len().max(1) as f64,
        }
    }

    /// Convert BacktestResults to Python dictionary for PyO3 integration
    #[cfg(feature = "python")]
    pub fn to_python_dict(
        &self,
        py: pyo3::Python,
    ) -> Result<pyo3::Py<pyo3::types::PyDict>, pyo3::PyErr> {
        use pyo3::prelude::*;
        use pyo3::types::PyDict;

        let dict = PyDict::new(py);

        // Metadata
        dict.set_item("backtest_id", &self.metadata.backtest_id)?;
        dict.set_item("strategy_id", &self.metadata.strategy_id)?;
        dict.set_item("execution_time_ms", self.metadata.execution_time_ms)?;
        dict.set_item("total_trades", self.metadata.total_trades)?;
        dict.set_item("data_points_processed", self.metadata.data_points_processed)?;

        // Performance metrics
        dict.set_item("total_return", self.performance.total_return.unwrap_or(0.0))?;
        dict.set_item(
            "annualized_return",
            self.performance.annualized_return.unwrap_or(0.0),
        )?;
        dict.set_item("volatility", self.performance.volatility.unwrap_or(0.0))?;
        dict.set_item("sharpe_ratio", self.performance.sharpe_ratio.unwrap_or(0.0))?;
        dict.set_item(
            "sortino_ratio",
            self.performance.sortino_ratio.unwrap_or(0.0),
        )?;
        dict.set_item(
            "maximum_drawdown",
            self.performance.maximum_drawdown.unwrap_or(0.0),
        )?;
        dict.set_item("win_rate", self.performance.win_rate.unwrap_or(0.0))?;
        dict.set_item(
            "profit_factor",
            self.performance.profit_factor.unwrap_or(0.0),
        )?;

        // Risk metrics
        dict.set_item(
            "value_at_risk_95",
            self.risk_metrics.value_at_risk_95.to_string(),
        )?;
        dict.set_item(
            "conditional_var_95",
            self.risk_metrics.conditional_var_95.to_string(),
        )?;
        dict.set_item("beta", self.risk_metrics.beta)?;
        dict.set_item("alpha", self.risk_metrics.alpha)?;

        // Trade statistics
        let trade_pnls: Vec<String> = self.trades.iter().map(|t| t.pnl.to_string()).collect();
        dict.set_item("trade_pnls", trade_pnls)?;

        let trade_durations: Vec<u64> = self.trades.iter().map(|t| t.duration_seconds).collect();
        dict.set_item("trade_durations", trade_durations)?;

        // Daily P&L
        let daily_returns: Vec<String> = self.daily_pnl.iter().map(|d| d.pnl.to_string()).collect();
        dict.set_item("daily_returns", daily_returns)?;

        // Optional fields
        if let Some(ref wf_results) = self.walk_forward_results {
            dict.set_item("walk_forward_periods", wf_results.total_periods)?;
            dict.set_item(
                "walk_forward_profitable_periods",
                wf_results.profitable_periods,
            )?;
            dict.set_item("walk_forward_avg_return", wf_results.average_return_pct)?;
        }

        if let Some(ref mc_result) = self.monte_carlo_result {
            dict.set_item("monte_carlo_simulations", mc_result.num_simulations)?;
            dict.set_item(
                "monte_carlo_confidence_95",
                mc_result.confidence_intervals.get("95%").unwrap_or(&0.0),
            )?;
        }

        Ok(dict.into())
    }

    /// Convert from Python dictionary for PyO3 integration
    #[cfg(feature = "python")]
    pub fn from_python_dict(dict: &pyo3::types::PyDict) -> Result<Self, pyo3::PyErr> {
        use pyo3::prelude::*;

        let backtest_id: String = dict
            .get_item("backtest_id")
            .ok_or_else(|| pyo3::exceptions::PyKeyError::new_err("Missing backtest_id"))?
            .extract()?;

        let strategy_id: String = dict
            .get_item("strategy_id")
            .ok_or_else(|| pyo3::exceptions::PyKeyError::new_err("Missing strategy_id"))?
            .extract()?;

        // Create a basic result structure and populate from dictionary
        let mut result = Self::new(backtest_id, strategy_id);

        // Update metadata
        if let Some(execution_time) = dict.get_item("execution_time_ms") {
            result.metadata.execution_time_ms = execution_time.extract()?;
        }
        if let Some(total_trades) = dict.get_item("total_trades") {
            result.metadata.total_trades = total_trades.extract()?;
        }

        // Update performance metrics
        if let Some(total_return) = dict.get_item("total_return") {
            result.performance.total_return = Some(total_return.extract()?);
        }
        if let Some(sharpe) = dict.get_item("sharpe_ratio") {
            result.performance.sharpe_ratio = Some(sharpe.extract()?);
        }

    // Ok variant
        Ok(result)
    }
}

// Default implementation now provided by performance::PerformanceMetrics

impl Default for RiskMetrics {
    fn default() -> Self {
        Self {
            value_at_risk_95: Decimal::ZERO,
            conditional_var_95: Decimal::ZERO,
            maximum_drawdown: 0.0,
            maximum_drawdown_duration_days: 0,
            volatility_annualized: 0.0,
            downside_deviation: 0.0,
            skewness: 0.0,
            kurtosis: 0.0,
            tail_ratio: 0.0,
            common_sense_ratio: 0.0,
        }
    }
}

impl Default for BiasAnalysisResults {
    fn default() -> Self {
        Self {
            lookahead_bias_detected: false,
            survivorship_bias_score: 0.0,
            overfitting_probability: 0.0,
            statistical_significance: 0.0,
            data_snooping_ratio: 0.0,
            multiple_testing_penalty: 0.0,
            white_reality_check_pvalue: 1.0,
            hansen_spa_pvalue: 1.0,
            romano_wolf_pvalue: 1.0,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use chrono::{TimeZone, Utc};
    // CANONICAL TYPE IMPORTS - FromPrimitive available via types::prelude
    use anyhow::anyhow;
    use std::collections::HashMap;
    use crate::types::test_utils::test_symbols::*;
    // use crate::operations; // Available if needed

    #[test]
    fn test_backtest_results_creation() {
        let results =
            BacktestResults::new("test_backtest".to_string(), "test_strategy".to_string());

        assert_eq!(results.metadata.backtest_id, "test_backtest");
        assert_eq!(results.metadata.strategy_id, "test_strategy");
        assert!(results.trades.is_empty());
        assert!(results.daily_pnl.is_empty());
        assert!(results.attribution.is_empty());
        assert!(results.monte_carlo_result.is_none());
        assert!(results.ml_extensions.is_none());
        assert!(results.final_portfolio_value.is_none());
        assert!(results.execution_stats.is_none());
    }

    #[test]
    fn test_backtest_metadata_comprehensive() -> Result<(), Box<dyn std::error::Error>> {
        let symbols = test_symbols_vec();
        let start_date = Utc
            .with_ymd_and_hms(2023, 1, 1, 0, 0, 0)
            .single()
            .ok_or("Invalid start date")?;
        let end_date = Utc
            .with_ymd_and_hms(2023, 12, 31, 23, 59, 59)
            .single()
            .ok_or("Invalid end date")?;

        let metadata = BacktestMetadata {
            backtest_id: "comprehensive_test".to_string(),
            strategy_id: "momentum_strategy".to_string(),
            symbols: symbols.clone(),
            start_date,
            end_date,
            execution_time_ms: 15000,
            total_trades: 250,
            data_points_processed: 500000,
            warnings: vec!["High volatility detected".to_string()],
            errors: vec![],
        };

        assert_eq!(metadata.backtest_id, "comprehensive_test");
        assert_eq!(metadata.strategy_id, "momentum_strategy");
        assert_eq!(metadata.symbols.len(), 3);
        assert_eq!(metadata.symbols[0], test_symbol_1());
        assert_eq!(metadata.execution_time_ms, 15000);
        assert_eq!(metadata.total_trades, 250);
        assert_eq!(metadata.data_points_processed, 500000);
        assert_eq!(metadata.warnings.len(), 1);
        assert_eq!(metadata.errors.len(), 0);
        assert!(metadata.start_date < metadata.end_date);
        Ok(())
    }

    #[test]
    fn test_trade_result_creation_and_conversion() -> Result<(), Box<dyn std::error::Error>> {
        let symbol = test_symbol_1();
        let entry_time = Utc
            .with_ymd_and_hms(2023, 6, 15, 10, 30, 0)
            .single()
            .ok_or("Invalid entry time")?;
        let exit_time = Utc
            .with_ymd_and_hms(2023, 6, 15, 15, 45, 0)
            .single()
            .ok_or("Invalid exit time")?;

        let trade = TradeResult {
            trade_id: TradeId::new("trade_001".to_string()),
            symbol: symbol.clone(),
            side: Side::Buy,
            entry_time,
            exit_time,
            entry_price: Price::from_f64(150.25)?,
            exit_price: Price::from_f64(152.75)?,
            quantity: Quantity::from_f64(100.0)?,
            pnl: Decimal::try_from(250.0).ok_or("Invalid PnL value")?,
            commission: Decimal::try_from(2.50).ok_or("Invalid commission value")?,
            slippage: Decimal::try_from(0.05).ok_or("Invalid slippage value")?,
            market_impact: Decimal::try_from(0.02).ok_or("Invalid market impact value")?,
            duration_seconds: (15 * 60 + 15) * 60, // 5h 15m in seconds
            ml_confidence: Some(0.85),
            feature_vector: Some(vec![0.1, 0.2, 0.3, 0.4, 0.5]),
        };

        assert_eq!(trade.trade_id.value(), "trade_001");
        assert_eq!(trade.symbol, symbol);
        assert_eq!(trade.side, Side::Buy);
        assert_eq!(trade.entry_price.to_f64(), 150.25);
        assert_eq!(trade.exit_price.to_f64(), 152.75);
        assert_eq!(trade.quantity.to_f64(), 100.0);
        assert_eq!(
            trade.pnl,
            Decimal::try_from(250.0).ok_or("Invalid PnL value")?
        );
        assert_eq!(trade.ml_confidence, Some(0.85));
        assert_eq!(
            trade
                .feature_vector
                .as_ref()
                .ok_or("Missing feature vector")?
                .len(),
            5
        );
        assert!(trade.entry_time < trade.exit_time);
        Ok(())
    }

    #[test]
    fn test_trade_result_from_tuple_conversion() -> Result<(), Box<dyn std::error::Error>> {
        let entry_time = 1687000000000000000_f64; // nanoseconds
        let exit_time = 1687010000000000000_f64;
        let entry_price = 100.0;
        let exit_price = 105.0;
        let side = "Buy".to_string();

        let trade: TradeResult = (entry_time, exit_time, entry_price, exit_price, side).into();

        assert_eq!(trade.side, Side::Buy);
        assert_eq!(trade.entry_price.to_f64(), entry_price);
        assert_eq!(trade.exit_price.to_f64(), exit_price);
        assert_eq!(trade.quantity.to_f64(), 1.0);
        assert_eq!(
            trade.pnl,
            Decimal::try_from(5.0).ok_or("Invalid PnL value")?
        );
        assert_eq!(trade.commission, Decimal::ZERO);
        assert_eq!(trade.slippage, Decimal::ZERO);
        assert_eq!(trade.ml_confidence, None);
        assert_eq!(trade.feature_vector, None);
        Ok(())
    }

    #[test]
    fn test_trade_result_conversion_with_sell_side() -> Result<(), Box<dyn std::error::Error>> {
        let entry_time = 1687000000000000000_f64;
        let exit_time = 1687010000000000000_f64;
        let entry_price = 100.0;
        let exit_price = 95.0;
        let side = "Sell".to_string();

        let trade: TradeResult = (entry_time, exit_time, entry_price, exit_price, side).into();

        assert_eq!(trade.side, Side::Sell);
        assert_eq!(trade.entry_price.to_f64(), entry_price);
        assert_eq!(trade.exit_price.to_f64(), exit_price);
        assert_eq!(
            trade.pnl,
            Decimal::try_from(-5.0).ok_or("Invalid PnL value")?
        );
        Ok(())
    }

    #[test]
    fn test_backtest_summary_creation() -> Result<(), Box<dyn std::error::Error>> {
        let pnl = Decimal::try_from(15000.0).ok_or("Invalid PnL value")?;

        let summary = BacktestSummary {
            total_trades: 100,
            winning_trades: 65,
            losing_trades: 35,
            total_pnl: pnl,
            max_drawdown: 0.15,
            sharpe_ratio: 1.85,
            sortino_ratio: 2.45,
            win_rate: 0.65,
            profit_factor: 1.75,
            average_trade_duration_seconds: 3600.0, // 1 hour
        };

        assert_eq!(summary.total_trades, 100);
        assert_eq!(summary.winning_trades, 65);
        assert_eq!(summary.losing_trades, 35);
        assert_eq!(summary.total_pnl, pnl);
        assert_eq!(summary.max_drawdown, 0.15);
        assert_eq!(summary.sharpe_ratio, 1.85);
        assert_eq!(summary.win_rate, 0.65);
        assert_eq!(summary.profit_factor, 1.75);
        Ok(())
    }

    #[test]
    fn test_daily_pnl_comprehensive() -> Result<(), Box<dyn std::error::Error>> {
        let date = Utc
            .with_ymd_and_hms(2023, 6, 15, 0, 0, 0)
            .single()
            .ok_or("Invalid date")?;

        let daily_pnl = DailyPnL {
            date,
            realized_pnl: Decimal::try_from(500.0).ok_or("Invalid realized PnL")?,
            unrealized_pnl: Decimal::try_from(-100.0).ok_or("Invalid unrealized PnL")?,
            total_pnl: Decimal::try_from(400.0).ok_or("Invalid total PnL")?,
            portfolio_value: Decimal::try_from(100_000.0).ok_or("Invalid portfolio value")?,
            drawdown_pct: -0.02,
            daily_return_pct: 0.004,
        };

        assert_eq!(daily_pnl.date, date);
        assert_eq!(
            daily_pnl.realized_pnl,
            Decimal::try_from(500.0).ok_or("Invalid realized PnL")?
        );
        assert_eq!(
            daily_pnl.unrealized_pnl,
            Decimal::try_from(-100.0).ok_or("Invalid unrealized PnL")?
        );
        assert_eq!(
            daily_pnl.total_pnl,
            Decimal::try_from(400.0).ok_or("Invalid total PnL")?
        );
        assert_eq!(
            daily_pnl.portfolio_value,
            Decimal::try_from(100000.0).ok_or("Invalid portfolio value")?
        );
        assert_eq!(daily_pnl.drawdown_pct, -0.02);
        assert_eq!(daily_pnl.daily_return_pct, 0.004);
        Ok(())
    }

    #[test]
    fn test_risk_metrics_default_and_comprehensive() -> Result<(), Box<dyn std::error::Error>> {
        let default_risk = RiskMetrics::default();

        assert_eq!(default_risk.value_at_risk_95, Decimal::ZERO);
        assert_eq!(default_risk.conditional_var_95, Decimal::ZERO);
        assert_eq!(default_risk.maximum_drawdown, 0.0);
        assert_eq!(default_risk.maximum_drawdown_duration_days, 0);
        assert_eq!(default_risk.volatility_annualized, 0.0);
        assert_eq!(default_risk.downside_deviation, 0.0);
        assert_eq!(default_risk.skewness, 0.0);
        assert_eq!(default_risk.kurtosis, 0.0);
        assert_eq!(default_risk.tail_ratio, 0.0);
        assert_eq!(default_risk.common_sense_ratio, 0.0);

        let comprehensive_risk = RiskMetrics {
            value_at_risk_95: Decimal::try_from(-2500.0).ok_or("Invalid VaR")?,
            conditional_var_95: Decimal::try_from(-4000.0).ok_or("Invalid CVaR")?,
            maximum_drawdown: 0.18,
            maximum_drawdown_duration_days: 45,
            volatility_annualized: 0.25,
            downside_deviation: 0.15,
            skewness: -0.35,
            kurtosis: 3.2,
            tail_ratio: 0.45,
            common_sense_ratio: 1.75,
        };

        assert_eq!(
            comprehensive_risk.value_at_risk_95,
            Decimal::try_from(-2500.0).ok_or("Invalid VaR")?
        );
        assert_eq!(comprehensive_risk.maximum_drawdown, 0.18);
        assert_eq!(comprehensive_risk.maximum_drawdown_duration_days, 45);
        assert_eq!(comprehensive_risk.volatility_annualized, 0.25);
        Ok(())
    }

    #[test]
    fn test_walk_forward_results_comprehensive() -> Result<(), Box<dyn std::error::Error>> {
        let mut parameter_values = HashMap::new();
        parameter_values.insert("lookback_period".to_string(), 20.0);
        parameter_values.insert("threshold".to_string(), 0.02);

        let period_result = WalkForwardPeriodResult {
            period_id: 1,
            in_sample_start: Utc
                .with_ymd_and_hms(2023, 1, 1, 0, 0, 0)
                .single()
                .ok_or("Invalid in_sample_start date")?,
            in_sample_end: Utc
                .with_ymd_and_hms(2023, 3, 31, 0, 0, 0)
                .single()
                .ok_or("Invalid in_sample_end date")?,
            out_sample_start: Utc
                .with_ymd_and_hms(2023, 4, 1, 0, 0, 0)
                .single()
                .ok_or("Invalid out_sample_start date")?,
            out_sample_end: Utc
                .with_ymd_and_hms(2023, 6, 30, 0, 0, 0)
                .single()
                .ok_or("Invalid out_sample_end date")?,
            in_sample_return: 0.08,
            out_sample_return: 0.06,
            parameter_values: parameter_values.clone(),
            confidence_score: 0.75,
        };

        let walk_forward = WalkForwardResults {
            total_periods: 4,
            profitable_periods: 3,
            average_return_pct: 0.065,
            return_consistency: 0.82,
            parameter_stability_score: 0.78,
            degradation_factor: 0.15,
            efficiency_score: 0.85,
            period_results: vec![period_result.clone()],
        };

        assert_eq!(walk_forward.total_periods, 4);
        assert_eq!(walk_forward.profitable_periods, 3);
        assert_eq!(walk_forward.average_return_pct, 0.065);
        assert_eq!(walk_forward.return_consistency, 0.82);
        assert_eq!(walk_forward.parameter_stability_score, 0.78);
        assert_eq!(walk_forward.degradation_factor, 0.15);
        assert_eq!(walk_forward.efficiency_score, 0.85);
        assert_eq!(walk_forward.period_results.len(), 1);

        let period = &walk_forward.period_results[0];
        assert_eq!(period.period_id, 1);
        assert_eq!(period.in_sample_return, 0.08);
        assert_eq!(period.out_sample_return, 0.06);
        assert_eq!(period.confidence_score, 0.75);
        assert_eq!(period.parameter_values.len(), 2);
        assert_eq!(period.parameter_values.get("lookback_period"), Some(&20.0));
        Ok(())
    }

    #[test]
    fn test_bias_analysis_results_comprehensive() -> Result<(), Box<dyn std::error::Error>> {
        let default_bias = BiasAnalysisResults::default();

        assert!(!default_bias.lookahead_bias_detected);
        assert_eq!(default_bias.survivorship_bias_score, 0.0);
        assert_eq!(default_bias.overfitting_probability, 0.0);
        assert_eq!(default_bias.statistical_significance, 0.0);
        assert_eq!(default_bias.data_snooping_ratio, 0.0);
        assert_eq!(default_bias.multiple_testing_penalty, 0.0);
        assert_eq!(default_bias.white_reality_check_pvalue, 1.0);
        assert_eq!(default_bias.hansen_spa_pvalue, 1.0);
        assert_eq!(default_bias.romano_wolf_pvalue, 1.0);

        let comprehensive_bias = BiasAnalysisResults {
            lookahead_bias_detected: true,
            survivorship_bias_score: 0.15,
            overfitting_probability: 0.25,
            statistical_significance: 0.95,
            data_snooping_ratio: 1.25,
            multiple_testing_penalty: 0.05,
            white_reality_check_pvalue: 0.03,
            hansen_spa_pvalue: 0.02,
            romano_wolf_pvalue: 0.01,
        };

        assert!(comprehensive_bias.lookahead_bias_detected);
        assert_eq!(comprehensive_bias.survivorship_bias_score, 0.15);
        assert_eq!(comprehensive_bias.overfitting_probability, 0.25);
        assert_eq!(comprehensive_bias.statistical_significance, 0.95);
        Ok(())
    }

    #[test]
    fn test_benchmark_comparison() -> Result<(), Box<dyn std::error::Error>> {
        let benchmark = BenchmarkComparison {
            benchmark_name: "S&P 500".to_string(),
            benchmark_return: 0.12,
            alpha: 0.03,
            beta: 1.15,
            tracking_error: 0.08,
            information_ratio: 0.375,
            correlation: 0.85,
            outperformance: 0.03,
            hit_rate: 0.58,
        };

        assert_eq!(benchmark.benchmark_name, "S&P 500");
        assert_eq!(benchmark.benchmark_return, 0.12);
        assert_eq!(benchmark.alpha, 0.03);
        assert_eq!(benchmark.beta, 1.15);
        assert_eq!(benchmark.tracking_error, 0.08);
        assert_eq!(benchmark.information_ratio, 0.375);
        assert_eq!(benchmark.correlation, 0.85);
        assert_eq!(benchmark.outperformance, 0.03);
        assert_eq!(benchmark.hit_rate, 0.58);
        Ok(())
    }

    #[test]
    fn test_monte_carlo_result() -> Result<(), Box<dyn std::error::Error>> {
        let mut confidence_intervals = HashMap::new();
        confidence_intervals.insert("return".to_string(), (-0.05, 0.25));
        confidence_intervals.insert("sharpe".to_string(), (0.5, 2.5));

        let monte_carlo = MonteCarloResult {
            simulation_count: 10000,
            confidence_intervals,
            expected_return: 0.12,
            expected_sharpe: 1.45,
            probability_of_loss: 0.15,
            worst_case_scenario: -0.08,
            best_case_scenario: 0.35,
            var_95: -0.03,
            cvar_95: -0.05,
            max_drawdown: 0.12,
            success_rate: 0.85,
        };

        assert_eq!(monte_carlo.simulation_count, 10000);
        assert_eq!(monte_carlo.expected_return, 0.12);
        assert_eq!(monte_carlo.expected_sharpe, 1.45);
        assert_eq!(monte_carlo.probability_of_loss, 0.15);
        assert_eq!(monte_carlo.worst_case_scenario, -0.08);
        assert_eq!(monte_carlo.best_case_scenario, 0.35);
        assert_eq!(monte_carlo.success_rate, 0.85);
        assert_eq!(monte_carlo.confidence_intervals.len(), 2);
        assert_eq!(
            monte_carlo.confidence_intervals.get("return"),
            Some(&(-0.05, 0.25))
        );
        Ok(())
    }

    #[test]
    fn test_ml_extensions() -> Result<(), Box<dyn std::error::Error>> {
        let mut feature_importance = HashMap::new();
        feature_importance.insert("rsi".to_string(), 0.35);
        feature_importance.insert("macd".to_string(), 0.28);
        feature_importance.insert("volume".to_string(), 0.22);
        feature_importance.insert("price_momentum".to_string(), 0.15);

        let mut hyperparameter_results = HashMap::new();
        hyperparameter_results.insert("learning_rate".to_string(), 0.001);
        hyperparameter_results.insert("batch_size".to_string(), 64.0);

        let confidence_evolution = vec![
            (
                Utc.with_ymd_and_hms(2023, 1, 1, 0, 0, 0)
                    .single()
                    .ok_or("Invalid date")?,
                0.75,
            ),
            (
                Utc.with_ymd_and_hms(2023, 2, 1, 0, 0, 0)
                    .single()
                    .ok_or("Invalid date")?,
                0.82,
            ),
            (
                Utc.with_ymd_and_hms(2023, 3, 1, 0, 0, 0)
                    .single()
                    .ok_or("Invalid date")?,
                0.88,
            ),
        ];

        let ml_extensions = MLExtensions {
            prediction_accuracy: 0.78,
            feature_importance: feature_importance.clone(),
            confidence_evolution: confidence_evolution.clone(),
            cv_scores: vec![0.75, 0.82, 0.79, 0.85, 0.80],
            hyperparameter_results: hyperparameter_results.clone(),
        };

        assert_eq!(ml_extensions.prediction_accuracy, 0.78);
        assert_eq!(ml_extensions.feature_importance.len(), 4);
        assert_eq!(ml_extensions.feature_importance.get("rsi"), Some(&0.35));
        assert_eq!(ml_extensions.confidence_evolution.len(), 3);
        assert_eq!(ml_extensions.cv_scores.len(), 5);
        assert_eq!(ml_extensions.hyperparameter_results.len(), 2);
        Ok(())
    }

    #[test]
    fn test_execution_stats() -> Result<(), Box<dyn std::error::Error>> {
        let execution_stats = ExecutionStats {
            total_fills: 150,
            average_slippage: 0.0025,
            total_commission: 375.50,
            market_impact_cost: 125.25,
            execution_delay_avg_ms: 2.5,
            rejection_rate: 0.02,
        };

        assert_eq!(execution_stats.total_fills, 150);
        assert_eq!(execution_stats.average_slippage, 0.0025);
        assert_eq!(execution_stats.total_commission, 375.50);
        assert_eq!(execution_stats.market_impact_cost, 125.25);
        assert_eq!(execution_stats.execution_delay_avg_ms, 2.5);
        assert_eq!(execution_stats.rejection_rate, 0.02);
        Ok(())
    }

    #[test]
    fn test_final_performance_metrics() -> Result<(), Box<dyn std::error::Error>> {
        let final_metrics = FinalPerformanceMetrics {
            total_return: 0.15,
            max_drawdown: 0.08,
            sharpe_ratio: 1.75,
            win_rate: 0.62,
            profit_factor: 1.85,
        };

        assert_eq!(final_metrics.total_return, 0.15);
        assert_eq!(final_metrics.max_drawdown, 0.08);
        assert_eq!(final_metrics.sharpe_ratio, 1.75);
        assert_eq!(final_metrics.win_rate, 0.62);
        assert_eq!(final_metrics.profit_factor, 1.85);
        Ok(())
    }

    #[test]
    fn test_backtest_results_summary() -> Result<(), Box<dyn std::error::Error>> {
        let mut results =
            BacktestResults::new("test_backtest".to_string(), "test_strategy".to_string());

        // Add some trades
        let symbol = test_symbol_1();        let winning_trade = TradeResult {
            trade_id: TradeId::new("win_001".to_string()),
            symbol: symbol.clone(),
            side: Side::Buy,
            entry_time: Utc::now(),
            exit_time: Utc::now(),
            entry_price: Price::from_f64(100.0)?,
            exit_price: Price::from_f64(105.0)?,
            quantity: Quantity::from_f64(100.0)?,
            pnl: Decimal::try_from(500.0).ok_or("Invalid PnL")?,
            commission: Decimal::ZERO,
            slippage: Decimal::ZERO,
            market_impact: Decimal::ZERO,
            duration_seconds: 3600,
            ml_confidence: None,
            feature_vector: None,
        };

        let losing_trade = TradeResult {
            trade_id: TradeId::new("lose_001".to_string()),
            symbol: symbol.clone(),
            side: Side::Sell,
            entry_time: Utc::now(),
            exit_time: Utc::now(),
            entry_price: Price::from_f64(100.0)?,
            exit_price: Price::from_f64(95.0)?,
            quantity: Quantity::from_f64(100.0)?,
            pnl: Decimal::try_from(-500.0).ok_or("Invalid PnL")?,
            commission: Decimal::ZERO,
            slippage: Decimal::ZERO,
            market_impact: Decimal::ZERO,
            duration_seconds: 1800,
            ml_confidence: None,
            feature_vector: None,
        };

        results.trades = vec![winning_trade, losing_trade];
        results.performance.maximum_drawdown = Some(0.12);
        results.performance.sharpe_ratio = Some(1.5);
        results.performance.sortino_ratio = Some(2.0);
        results.performance.win_rate = Some(0.5);
        results.performance.profit_factor = Some(1.0);

        let summary = results.summary();

        assert_eq!(summary.total_trades, 2);
        assert_eq!(summary.winning_trades, 1);
        assert_eq!(summary.losing_trades, 1);
        assert_eq!(summary.total_pnl.to_f64(), Some(0.0)); // 500 - 500 = 0
        assert_eq!(summary.max_drawdown, 0.12);
        assert_eq!(summary.sharpe_ratio, 1.5);
        assert_eq!(summary.sortino_ratio, 2.0);
        assert_eq!(summary.win_rate, 0.5);
        assert_eq!(summary.profit_factor, 1.0);
        assert_eq!(
            summary.average_trade_duration_seconds,
            (3600.0 + 1800.0) / 2.0
        );
        Ok(())
    }

    #[test]
    fn test_backtest_results_serialization() -> Result<(), Box<dyn std::error::Error>> {
        let results = BacktestResults::new(
            "serialization_test".to_string(),
            "test_strategy".to_string(),
        );

        // Test JSON serialization
        let json_str =
            serde_json::to_string(&results).map_err(|e| anyhow!("Should serialize: {:?}", e))?;
        assert!(!json_str.is_empty());
        assert!(json_str.contains("serialization_test"));
        assert!(json_str.contains("test_strategy"));

        // Test JSON deserialization
        let deserialized: BacktestResults =
            serde_json::from_str(&json_str).map_err(|e| anyhow!("Should deserialize: {:?}", e))?;

        assert_eq!(
            deserialized.metadata.backtest_id,
            results.metadata.backtest_id
        );
        assert_eq!(
            deserialized.metadata.strategy_id,
            results.metadata.strategy_id
        );
        Ok(())
    }

    #[test]
    fn test_complex_backtest_results_integration() -> Result<(), Box<dyn std::error::Error>> {
        let mut results = BacktestResults::new(
            "integration_test".to_string(),
            "complex_strategy".to_string(),
        );

        // Set up metadata
        results.metadata.symbols = vec![test_symbol_1(), test_symbol_2()];        results.metadata.start_date = Utc
            .with_ymd_and_hms(2023, 1, 1, 0, 0, 0)
            .single()
            .ok_or("Invalid start date")?;
        results.metadata.end_date = Utc
            .with_ymd_and_hms(2023, 12, 31, 0, 0, 0)
            .single()
            .ok_or("Invalid end date")?;
        results.metadata.execution_time_ms = 30000;
        results.metadata.total_trades = 100;
        results.metadata.data_points_processed = 1000000;

        // Set up performance metrics
        results.performance.total_return = Some(0.15);
        results.performance.sharpe_ratio = Some(1.75);
        results.performance.maximum_drawdown = Some(0.08);

        // Add some trades
        let symbol = test_symbol_1();        let trade = TradeResult {
            trade_id: TradeId::new("integration_001".to_string()),
            symbol,
            side: Side::Buy,
            entry_time: Utc
                .with_ymd_and_hms(2023, 6, 15, 10, 0, 0)
                .single()
                .ok_or("Invalid entry time")?,
            exit_time: Utc
                .with_ymd_and_hms(2023, 6, 15, 16, 0, 0)
                .single()
                .ok_or("Invalid exit time")?,
            entry_price: Price::from_f64(150.0)?,
            exit_price: Price::from_f64(155.0)?,
            quantity: Quantity::from_f64(100.0)?,
            pnl: Decimal::try_from(500.0).ok_or("Invalid PnL")?,
            commission: Decimal::try_from(1.0).ok_or("Invalid commission")?,
            slippage: Decimal::try_from(0.1).ok_or("Invalid slippage")?,
            market_impact: Decimal::try_from(0.05).ok_or("Invalid market impact")?,
            duration_seconds: 6 * 3600,
            ml_confidence: Some(0.85),
            feature_vector: Some(vec![0.1, 0.2, 0.3]),
        };
        results.trades = vec![trade];

        // Add daily P&L
        let daily_pnl = DailyPnL {
            date: Utc
                .with_ymd_and_hms(2023, 6, 15, 0, 0, 0)
                .single()
                .ok_or("Invalid date")?,
            realized_pnl: Decimal::try_from(500.0).ok_or("Invalid realized PnL")?,
            unrealized_pnl: Decimal::ZERO,
            total_pnl: Decimal::try_from(500.0).ok_or("Invalid total PnL")?,
            portfolio_value: Decimal::try_from(100000.0).ok_or("Invalid portfolio value")?,
            drawdown_pct: 0.0,
            daily_return_pct: 0.005,
        };
        results.daily_pnl = vec![daily_pnl];

        // Add ML extensions
        let mut feature_importance = HashMap::new();
        feature_importance.insert("momentum".to_string(), 0.4);
        feature_importance.insert("volatility".to_string(), 0.35);
        feature_importance.insert("volume".to_string(), 0.25);

        results.ml_extensions = Some(MLExtensions {
            prediction_accuracy: 0.78,
            feature_importance,
            confidence_evolution: vec![],
            cv_scores: vec![0.75, 0.80, 0.82],
            hyperparameter_results: HashMap::new(),
        });

        // Add execution stats
        results.execution_stats = Some(ExecutionStats {
            total_fills: 100,
            average_slippage: 0.001,
            total_commission: 100.0,
            market_impact_cost: 50.0,
            execution_delay_avg_ms: 1.5,
            rejection_rate: 0.0,
        });

        // Test the complete integration
        assert_eq!(results.metadata.backtest_id, "integration_test");
        assert_eq!(results.trades.len(), 1);
        assert_eq!(results.daily_pnl.len(), 1);
        assert!(results.ml_extensions.is_some());
        assert!(results.execution_stats.is_some());

        // Test summary generation
        let summary = results.summary();
        assert_eq!(summary.total_trades, 1);
        assert_eq!(summary.winning_trades, 1);
        assert_eq!(summary.losing_trades, 0);
        Ok(())
    }

    #[test]
    fn test_edge_cases_and_error_conditions() -> Result<(), Box<dyn std::error::Error>> {
        // Test empty BacktestResults
        let empty_results =
            BacktestResults::new("empty_test".to_string(), "empty_strategy".to_string());

        let summary = empty_results.summary();
        assert_eq!(summary.total_trades, 0);
        assert_eq!(summary.winning_trades, 0);
        assert_eq!(summary.losing_trades, 0);
        assert!(
            summary.average_trade_duration_seconds.is_nan()
                || summary.average_trade_duration_seconds == 0.0
        );

        // Test TradeResult with zero pnl
        let symbol = test_symbol();
        let zero_pnl_trade = TradeResult {
            trade_id: TradeId::new("zero_pnl".to_string()),
            symbol,
            side: Side::Buy,
            entry_time: Utc::now(),
            exit_time: Utc::now(),
            entry_price: Price::from_f64(100.0)?,
            exit_price: Price::from_f64(100.0)?,
            quantity: Quantity::from_f64(100.0)?,
            pnl: Decimal::ZERO,
            commission: Decimal::ZERO,
            slippage: Decimal::ZERO,
            market_impact: Decimal::ZERO,
            duration_seconds: 0,
            ml_confidence: None,
            feature_vector: None,
        };

        assert_eq!(zero_pnl_trade.pnl, Decimal::ZERO);
        assert_eq!(zero_pnl_trade.duration_seconds, 0);

        // Test extreme values (use reasonable maximums instead of f64::MAX)
        let extreme_trade = TradeResult {
            trade_id: TradeId::new("extreme".to_string()),
            symbol: test_symbol_extreme(),
            side: Side::Sell,
            entry_time: Utc::now(),
            exit_time: Utc::now(),
            entry_price: Price::from_f64(999_999.99)?,
            exit_price: Price::from_f64(0.000_001)?,
            quantity: Quantity::from_f64(999_999.99)?,
            pnl: Decimal::MAX,
            commission: Decimal::MAX,
            slippage: Decimal::MAX,
            market_impact: Decimal::MAX,
            duration_seconds: u64::MAX,
            ml_confidence: Some(1.0),
            feature_vector: Some(vec![]),
        };

        assert!(extreme_trade.entry_price.to_f64() > 0.0);
        assert!(extreme_trade.exit_price.to_f64() > 0.0);
        assert_eq!(extreme_trade.ml_confidence, Some(1.0));
        assert_eq!(
            extreme_trade
                .feature_vector
                .as_ref()
                .ok_or("Missing feature vector")?
                .len(),
            0
        );
        Ok(())
    }

    #[test]
    fn test_comprehensive_enum_and_struct_coverage() -> Result<(), Box<dyn std::error::Error>> {
        // Test all struct creation patterns
        let metadata = BacktestMetadata {
            backtest_id: String::new(),
            strategy_id: String::new(),
            symbols: Vec::new(),
            start_date: Utc::now(),
            end_date: Utc::now(),
            execution_time_ms: 0,
            total_trades: 0,
            data_points_processed: 0,
            warnings: Vec::new(),
            errors: Vec::new(),
        };
        assert!(metadata.symbols.is_empty());
        assert!(metadata.warnings.is_empty());
        assert!(metadata.errors.is_empty());

        // Test all optional fields
        let mut results = BacktestResults::new("test".to_string(), "test".to_string());
        results.walk_forward_results = Some(WalkForwardResults {
            total_periods: 1,
            profitable_periods: 1,
            average_return_pct: 0.0,
            return_consistency: 0.0,
            parameter_stability_score: 0.0,
            degradation_factor: 0.0,
            efficiency_score: 0.0,
            period_results: Vec::new(),
        });
        results.benchmark_comparison = Some(BenchmarkComparison {
            benchmark_name: String::new(),
            benchmark_return: 0.0,
            alpha: 0.0,
            beta: 0.0,
            tracking_error: 0.0,
            information_ratio: 0.0,
            correlation: 0.0,
            outperformance: 0.0,
            hit_rate: 0.0,
        });
        results.final_portfolio_value = Some(100_000.0);

        assert!(results.walk_forward_results.is_some());
        assert!(results.benchmark_comparison.is_some());
        assert!(results.final_portfolio_value.is_some());
        Ok(())
    }
}
