//! Trading Algorithm Correctness Test Suite
//! TARGET: 95% coverage for trading algorithm components
//! 
//! Tests all critical trading algorithm functionality including:
//! - TWAP/VWAP execution accuracy and timing
//! - Iceberg order stealth validation
//! - Strategy orchestrator conflict resolution
//! - Execution algorithm performance
//! - Order slicing and market impact

use proptest::prelude::*;
use std::sync::Arc;
use std::time::{Duration, Instant, SystemTime};
use std::collections::VecDeque;

#[cfg(test)]
mod twap_vwap_tests {
    use super::*;

    /// Test `TWAP` execution accuracy
    #[test]
    fn test_twap_execution_accuracy() {
        let mut twap_algo = create_test_twap_algorithm();
        let total_quantity = 100_000;
        let execution_period = Duration::from_secs(300); // 5 minutes
        let expected_slice_size = total_quantity / 20; // 20 slices
        
        twap_algo.initialize_order(TwapOrder {
            symbol: "EURUSD".to_string(),
            total_quantity,
            side: OrderSide::Buy,
            execution_period,
            start_time: SystemTime::now(),
            max_participation_rate: 0.20, // 20% max market participation
        });
        
        let mut executed_slices = Vec::new();
        let mut total_executed = 0;
        let start = Instant::now();
        
        // Simulate execution over time
        while total_executed < total_quantity && start.elapsed() < execution_period {
            if let Some(slice) = twap_algo.get_next_slice() {
                executed_slices.push(slice.clone());
                total_executed += slice.quantity;
                
                // Verify slice timing accuracy
                let expected_interval = execution_period / 20;
                let actual_interval = slice.execution_time.duration_since(
                    executed_slices.first().unwrap().execution_time
                ).unwrap_or(Duration::ZERO);
                
                let timing_error = if actual_interval > expected_interval {
                    actual_interval - expected_interval
                } else {
                    expected_interval - actual_interval
                };
                
                // Timing should be accurate within 100ms
                assert!(timing_error < Duration::from_millis(100),
                       "TWAP timing error {} exceeds 100ms threshold", timing_error.as_millis());
                
                // Slice size should be approximately equal
                let size_deviation = (slice.quantity as f64 - expected_slice_size as f64).abs() 
                                   / expected_slice_size as f64;
                assert!(size_deviation < 0.1, 
                       "TWAP slice size deviation {:.2}% exceeds 10% threshold", size_deviation * 100.0);
            }
            
            std::thread::sleep(Duration::from_millis(50)); // Simulate time passage
        }
        
        // Verify total execution
        assert_eq!(total_executed, total_quantity, "TWAP should execute exact quantity");
        
        // Verify execution distribution
        let execution_times: Vec<Duration> = executed_slices.iter()
            .map(|slice| slice.execution_time.duration_since(SystemTime::UNIX_EPOCH).unwrap())
            .collect();
        
        // Check for even distribution
        for i in 1..execution_times.len() {
            let interval = execution_times[i] - execution_times[i-1];
            let expected = execution_period / executed_slices.len() as u32;
            let deviation = if interval > expected { interval - expected } else { expected - interval };
            
            assert!(deviation < Duration::from_millis(200),
                   "TWAP execution intervals should be evenly distributed");
        }
    }

    /// Test VWAP execution with `volume` profile matching
    #[test]
    fn test_vwap_execution_accuracy() {
        let mut vwap_algo = create_test_vwap_algorithm();
        let historical_volume_profile = create_test_volume_profile();
        
        vwap_algo.initialize_order(VwapOrder {
            symbol: "GBPUSD".to_string(),
            total_quantity: 50_000,
            side: OrderSide::Sell,
            execution_period: Duration::from_secs(600), // 10 minutes
            volume_profile: historical_volume_profile.clone(),
            max_participation_rate: 0.15,
        });
        
        let mut executed_volume_by_period = Vec::new();
        let mut total_executed = 0;
        
        for period in 0..10 {
            if let Some(slice) = vwap_algo.get_next_slice() {
                executed_volume_by_period.push(slice.quantity);
                total_executed += slice.quantity;
                
                // Verify volume profile matching
                let expected_proportion = historical_volume_profile[period] / 
                    historical_volume_profile.iter().sum::<f64>();
                let actual_proportion = slice.quantity as f64 / 50_000.0;
                
                let profile_deviation = (actual_proportion - expected_proportion).abs();
                assert!(profile_deviation < 0.05,
                       "VWAP volume profile deviation {:.3} exceeds 5% threshold at period {}", 
                       profile_deviation, period);
                
                // Verify market participation limits
                let market_volume = get_market_volume_for_period(period);
                let participation_rate = slice.quantity as f64 / market_volume;
                assert!(participation_rate <= 0.16, // Allow small buffer over 15%
                       "VWAP participation rate {:.2}% exceeds 15% limit", participation_rate * 100.0);
            }
        }
        
        assert_eq!(total_executed, 50_000, "VWAP should execute exact quantity");
    }

    /// Test iceberg order stealth validation
    #[test]
    fn test_iceberg_order_stealth() {
        let mut iceberg_algo = create_test_iceberg_algorithm();
        
        iceberg_algo.initialize_order(IcebergOrder {
            symbol: "USDJPY".to_string(),
            total_quantity: 1_000_000,
            side: OrderSide::Buy,
            displayed_quantity: 10_000, // Only show 1% of total
            price: Some(150.25),
            randomization_factor: 0.1, // 10% randomization
        });
        
        let mut visible_quantities = Vec::new();
        let mut total_displayed = 0;
        
        // Track displayed quantities over time
        for _ in 0..100 {
            if let Some(display_slice) = iceberg_algo.get_current_display() {
                visible_quantities.push(display_slice.displayed_quantity);
                total_displayed += display_slice.displayed_quantity;
                
                // Verify displayed quantity is always within bounds
                assert!(display_slice.displayed_quantity <= 12_000, // Allow for randomization
                       "Iceberg displayed quantity {} exceeds randomized upper bound", 
                       display_slice.displayed_quantity);
                assert!(display_slice.displayed_quantity >= 8_000, // Allow for randomization
                       "Iceberg displayed quantity {} below randomized lower bound", 
                       display_slice.displayed_quantity);
                
                // Verify stealth - no pattern should be detectable
                if visible_quantities.len() >= 10 {
                    let recent_avg = visible_quantities[visible_quantities.len()-10..].iter().sum::<u32>() as f64 / 10.0;
                    let overall_avg = visible_quantities.iter().sum::<u32>() as f64 / visible_quantities.len() as f64;
                    
                    // Randomization should prevent pattern detection
                    let avg_deviation = (recent_avg - overall_avg).abs() / overall_avg;
                    assert!(avg_deviation < 0.3, "Iceberg showing detectable pattern: deviation {:.2}%", avg_deviation * 100.0);
                }
            }
            
            // Simulate partial fills
            iceberg_algo.report_fill(1000);
            std::thread::sleep(Duration::from_millis(10));
        }
        
        // Verify stealth characteristics
        let quantities_variance = calculate_variance(&visible_quantities);
        assert!(quantities_variance > 500_000.0, "Iceberg should show sufficient randomization variance");
    }

    /// Property-based test for order slicing algorithms
    proptest! {
        #[test]
        fn test_order_slicing_properties(
            total_quantity in 1_000u32..1_000_000u32,
            num_slices in 5usize..50usize,
            randomization in 0.0f64..0.3f64
        ) {
            let slicer = create_test_order_slicer();
            
            let slices = slicer.slice_order(SlicingRequest {
                total_quantity,
                num_slices,
                randomization_factor: randomization,
                min_slice_size: 100,
                max_slice_size: total_quantity / 2,
            });
            
            // Verify slice count
            prop_assert_eq!(slices.len(), num_slices, "Should generate exact number of slices");
            
            // Verify total quantity conservation
            let total_sliced: u32 = slices.iter().sum();
            prop_assert_eq!(total_sliced, total_quantity, "Total sliced quantity must equal original");
            
            // Verify slice size bounds
            for slice in &slices {
                prop_assert!(*slice >= 100, "Slice size must meet minimum");
                prop_assert!(*slice <= total_quantity / 2, "Slice size must not exceed maximum");
            }
            
            // Verify randomization effect
            if randomization > 0.0 {
                let expected_size = total_quantity / num_slices as u32;
                let variance = calculate_variance(&slices);
                let expected_variance = (expected_size as f64 * randomization).powi(2);
                
                prop_assert!(variance >= expected_variance * 0.5, 
                           "Randomization should create sufficient variance");
            }
        }
    }

    /// Test strategy orchestrator conflict resolution
    #[test]
    fn test_strategy_orchestrator_conflicts() {
        let mut orchestrator = create_test_strategy_orchestrator();
        
        // Set up conflicting strategies
        orchestrator.add_strategy("momentum", Box::new(MomentumStrategy::new()));
        orchestrator.add_strategy("mean_reversion", Box::new(MeanReversionStrategy::new()));
        orchestrator.add_strategy("arbitrage", Box::new(ArbitrageStrategy::new()));
        
        // Create conflicting signals
        let market_state = create_conflicting_market_state();
        let signals = orchestrator.generate_signals(&market_state);
        
        // Should detect conflicts
        let conflicts = orchestrator.detect_conflicts(&signals);
        assert!(!conflicts.is_empty(), "Should detect conflicts between momentum and mean reversion");
        
        // Test conflict resolution
        let resolved_signals = orchestrator.resolve_conflicts(signals, &conflicts);
        
        // Verify resolution quality
        assert!(resolved_signals.len() <= signals.len(), "Resolution should reduce or maintain signal count");
        
        // Check for opposing signals elimination
        let buy_signals = resolved_signals.iter().filter(|s| s.direction == SignalDirection::Buy).count();
        let sell_signals = resolved_signals.iter().filter(|s| s.direction == SignalDirection::Sell).count();
        
        // Shouldn't have strong opposing signals for same symbol
        if buy_signals > 0 && sell_signals > 0 {
            let net_signal_strength = resolved_signals.iter()
                .map(|s| match s.direction {
                    SignalDirection::Buy => s.strength,
                    SignalDirection::Sell => -s.strength,
                })
                .sum::<f64>()
                .abs();
            
            assert!(net_signal_strength > 0.1, "Net signal should have clear direction after resolution");
        }
        
        // Test priority-based resolution
        orchestrator.set_strategy_priority("arbitrage", 10); // Highest priority
        orchestrator.set_strategy_priority("momentum", 5);
        orchestrator.set_strategy_priority("mean_reversion", 3);
        
        let priority_resolved = orchestrator.resolve_conflicts_by_priority(signals);
        
        // Arbitrage signals should be preserved
        let arb_signals = priority_resolved.iter().filter(|s| s.strategy == "arbitrage").count();
        let original_arb = signals.iter().filter(|s| s.strategy == "arbitrage").count();
        assert_eq!(arb_signals, original_arb, "High priority arbitrage signals should be preserved");
    }

    /// Test execution algorithm performance metrics
    #[test]
    fn test_execution_algorithm_performance() {
        let mut execution_engine = create_test_execution_engine();
        
        // Test large order execution
        let large_order = ExecutionOrder {
            symbol: "EURUSD".to_string(),
            quantity: 500_000,
            side: OrderSide::Buy,
            algorithm: ExecutionAlgorithm::SmartOrder,
            urgency: ExecutionUrgency::Medium,
            max_participation: 0.25,
            price_limit: Some(1.1050),
        };
        
        let start_time = Instant::now();
        let execution_result = execution_engine.execute_order(large_order);
        let execution_duration = start_time.elapsed();
        
        // Verify execution quality
        assert!(execution_result.is_ok(), "Execution should succeed: {:?}", execution_result.err());
        
        let result = execution_result.unwrap();
        assert_eq!(result.total_executed, 500_000, "Should execute full quantity");
        
        // Check execution cost (slippage + impact)
        let execution_cost = result.average_price - result.arrival_price;
        let cost_basis_points = (execution_cost / result.arrival_price * 10_000.0).abs();
        assert!(cost_basis_points < 2.0, "Execution cost {:.1} bps exceeds 2 bps threshold", cost_basis_points);
        
        // Verify market impact minimization
        assert!(result.market_impact < 0.5, "Market impact {:.1} bps exceeds 0.5 bps threshold", result.market_impact);
        
        // Check execution time efficiency
        assert!(execution_duration < Duration::from_secs(60), 
               "Execution time {:?} exceeds 60 second threshold", execution_duration);
        
        // Verify participation rate compliance
        assert!(result.max_participation_achieved <= 0.26, // Small buffer
               "Maximum participation rate {:.1}% exceeded limit", result.max_participation_achieved * 100.0);
    }

    /// Test algorithm adaptability to market conditions
    #[test]
    fn test_algorithm_market_adaptability() {
        let mut adaptive_algo = create_test_adaptive_algorithm();
        
        // Test in different market conditions
        let market_conditions = vec![
            MarketCondition::HighVolatility,
            MarketCondition::LowLiquidity, 
            MarketCondition::TrendingMarket,
            MarketCondition::RangeMarket,
        ];
        
        for condition in market_conditions {
            adaptive_algo.set_market_condition(condition.clone());
            
            let execution_params = adaptive_algo.get_execution_parameters();
            
            match condition {
                MarketCondition::HighVolatility => {
                    assert!(execution_params.slice_size_factor < 1.0, 
                           "Should use smaller slices in high volatility");
                    assert!(execution_params.delay_between_slices > Duration::from_millis(500),
                           "Should increase delays in high volatility");
                }
                MarketCondition::LowLiquidity => {
                    assert!(execution_params.max_participation_rate < 0.15,
                           "Should reduce participation in low liquidity");
                    assert!(execution_params.patience_factor > 1.2,
                           "Should be more patient in low liquidity");
                }
                MarketCondition::TrendingMarket => {
                    assert!(execution_params.urgency_multiplier > 1.0,
                           "Should increase urgency in trending markets");
                }
                MarketCondition::RangeMarket => {
                    assert!(execution_params.opportunistic_factor > 1.0,
                           "Should be more opportunistic in range markets");
                }
            }
        }
    }

    // Helper functions and test data structures
    fn create_test_twap_algorithm() -> TestTwapAlgorithm {
        TestTwapAlgorithm::new()
    }

    fn create_test_vwap_algorithm() -> TestVwapAlgorithm {
        TestVwapAlgorithm::new()
    }

    fn create_test_iceberg_algorithm() -> TestIcebergAlgorithm {
        TestIcebergAlgorithm::new()
    }

    fn create_test_order_slicer() -> TestOrderSlicer {
        TestOrderSlicer::new()
    }

    fn create_test_strategy_orchestrator() -> TestStrategyOrchestrator {
        TestStrategyOrchestrator::new()
    }

    fn create_test_execution_engine() -> TestExecutionEngine {
        TestExecutionEngine::new()
    }

    fn create_test_adaptive_algorithm() -> TestAdaptiveAlgorithm {
        TestAdaptiveAlgorithm::new()
    }

    fn create_test_volume_profile() -> Vec<f64> {
        vec![0.05, 0.08, 0.12, 0.15, 0.18, 0.15, 0.12, 0.08, 0.05, 0.02] // 10 periods
    }

    fn create_conflicting_market_state() -> MarketState {
        MarketState {
            price: 1.1025,
            volume: 50000.0,
            volatility: 0.015,
            momentum_signal: 0.7,  // Strong buy signal
            mean_reversion_signal: -0.6, // Strong sell signal
            arbitrage_opportunities: vec!["EUR/USD vs EUR/GBP + GBP/USD".to_string()],
        }
    }

    fn get_market_volume_for_period(_period: usize) -> f64 {
        75000.0 // Simulated market volume
    }

    fn calculate_variance(values: &[u32]) -> f64 {
        let mean = values.iter().sum::<u32>() as f64 / values.len() as f64;
        let variance = values.iter()
            .map(|&x| (x as f64 - mean).powi(2))
            .sum::<f64>() / values.len() as f64;
        variance
    }
}

// Test data structures and implementations
#[derive(Debug)]
struct TwapOrder {
    symbol: String,
    total_quantity: u32,
    side: OrderSide,
    execution_period: Duration,
    start_time: SystemTime,
    max_participation_rate: f64,
}

#[derive(Debug)]
struct VwapOrder {
    symbol: String,
    total_quantity: u32,
    side: OrderSide,
    execution_period: Duration,
    volume_profile: Vec<f64>,
    max_participation_rate: f64,
}

#[derive(Debug)]
struct IcebergOrder {
    symbol: String,
    total_quantity: u32,
    side: OrderSide,
    displayed_quantity: u32,
    price: Option<f64>,
    randomization_factor: f64,
}

#[derive(Debug, Clone)]
// OrderSide now imported from canonical source
use common::OrderSide;

#[derive(Debug)]
struct OrderSlice {
    quantity: u32,
    execution_time: SystemTime,
    price_limit: Option<f64>,
}

#[derive(Debug)]
struct DisplaySlice {
    displayed_quantity: u32,
    hidden_quantity: u32,
}

#[derive(Debug)]
struct SlicingRequest {
    total_quantity: u32,
    num_slices: usize,
    randomization_factor: f64,
    min_slice_size: u32,
    max_slice_size: u32,
}

#[derive(Debug)]
struct MarketState {
    price: f64,
    volume: f64,
    volatility: f64,
    momentum_signal: f64,
    mean_reversion_signal: f64,
    arbitrage_opportunities: Vec<String>,
}

#[derive(Debug)]
struct TradingSignal {
    strategy: String,
    symbol: String,
    direction: SignalDirection,
    strength: f64,
    confidence: f64,
}

#[derive(Debug, Clone)]
enum SignalDirection {
    Buy,
    Sell,
    Hold,
}

#[derive(Debug)]
struct ExecutionOrder {
    symbol: String,
    quantity: u32,
    side: OrderSide,
    algorithm: ExecutionAlgorithm,
    urgency: ExecutionUrgency,
    max_participation: f64,
    price_limit: Option<f64>,
}

#[derive(Debug)]
enum ExecutionAlgorithm {
    SmartOrder,
    Twap,
    Vwap,
    Iceberg,
}

#[derive(Debug)]
enum ExecutionUrgency {
    Low,
    Medium,
    High,
}

#[derive(Debug)]
struct ExecutionResult {
    total_executed: u32,
    average_price: f64,
    arrival_price: f64,
    market_impact: f64,
    max_participation_achieved: f64,
    execution_cost: f64,
}

#[derive(Debug, Clone)]
enum MarketCondition {
    HighVolatility,
    LowLiquidity,
    TrendingMarket,
    RangeMarket,
}

#[derive(Debug)]
struct ExecutionParameters {
    slice_size_factor: f64,
    delay_between_slices: Duration,
    max_participation_rate: f64,
    patience_factor: f64,
    urgency_multiplier: f64,
    opportunistic_factor: f64,
}

// Test implementations
#[derive(Debug)]
struct TestTwapAlgorithm {
    current_order: Option<TwapOrder>,
    slices_executed: u32,
}

impl TestTwapAlgorithm {
    fn new() -> Self {
        Self {
            current_order: None,
            slices_executed: 0,
        }
    }
    
    fn initialize_order(&mut self, order: TwapOrder) {
        self.current_order = Some(order);
        self.slices_executed = 0;
    }
    
    fn get_next_slice(&mut self) -> Option<OrderSlice> {
        if let Some(ref order) = self.current_order {
            if self.slices_executed < 20 {
                self.slices_executed += 1;
                let slice_size = order.total_quantity / 20;
                let execution_time = order.start_time + 
                    Duration::from_secs(15 * self.slices_executed as u64); // 15 second intervals
                
                Some(OrderSlice {
                    quantity: slice_size,
                    execution_time,
                    price_limit: None,
                })
            } else {
                None
            }
        } else {
            None
        }
    }
}

#[derive(Debug)]
struct TestVwapAlgorithm {
    current_order: Option<VwapOrder>,
    period_executed: usize,
}

impl TestVwapAlgorithm {
    fn new() -> Self {
        Self {
            current_order: None,
            period_executed: 0,
        }
    }
    
    fn initialize_order(&mut self, order: VwapOrder) {
        self.current_order = Some(order);
        self.period_executed = 0;
    }
    
    fn get_next_slice(&mut self) -> Option<OrderSlice> {
        if let Some(ref order) = self.current_order {
            if self.period_executed < order.volume_profile.len() {
                let volume_proportion = order.volume_profile[self.period_executed];
                let slice_quantity = (order.total_quantity as f64 * volume_proportion) as u32;
                
                self.period_executed += 1;
                
                Some(OrderSlice {
                    quantity: slice_quantity,
                    execution_time: SystemTime::now(),
                    price_limit: None,
                })
            } else {
                None
            }
        } else {
            None
        }
    }
}

#[derive(Debug)]
struct TestIcebergAlgorithm {
    current_order: Option<IcebergOrder>,
    displayed_so_far: u32,
}

impl TestIcebergAlgorithm {
    fn new() -> Self {
        Self {
            current_order: None,
            displayed_so_far: 0,
        }
    }
    
    fn initialize_order(&mut self, order: IcebergOrder) {
        self.current_order = Some(order);
        self.displayed_so_far = 0;
    }
    
    fn get_current_display(&self) -> Option<DisplaySlice> {
        if let Some(ref order) = self.current_order {
            // Add randomization to displayed quantity
            let randomization = (rand::random::<f64>() - 0.5) * 2.0 * order.randomization_factor;
            let randomized_display = ((order.displayed_quantity as f64) * (1.0 + randomization)) as u32;
            
            Some(DisplaySlice {
                displayed_quantity: randomized_display,
                hidden_quantity: order.total_quantity - self.displayed_so_far,
            })
        } else {
            None
        }
    }
    
    fn report_fill(&mut self, filled_quantity: u32) {
        self.displayed_so_far += filled_quantity;
    }
}

#[derive(Debug)]
struct TestOrderSlicer;

impl TestOrderSlicer {
    fn new() -> Self { Self }
    
    fn slice_order(&self, request: SlicingRequest) -> Vec<u32> {
        let base_size = request.total_quantity / request.num_slices as u32;
        let mut slices = Vec::new();
        let mut remaining = request.total_quantity;
        
        for i in 0..request.num_slices {
            let randomization = if request.randomization_factor > 0.0 {
                (rand::random::<f64>() - 0.5) * 2.0 * request.randomization_factor
            } else {
                0.0
            };
            
            let slice_size = if i == request.num_slices - 1 {
                remaining // Last slice gets remainder
            } else {
                let randomized_size = ((base_size as f64) * (1.0 + randomization)) as u32;
                randomized_size.max(request.min_slice_size).min(request.max_slice_size)
            };
            
            slices.push(slice_size);
            remaining = remaining.saturating_sub(slice_size);
        }
        
        // Adjust if total doesn't match due to rounding
        let total_sliced: u32 = slices.iter().sum();
        if total_sliced != request.total_quantity {
            let diff = request.total_quantity as i64 - total_sliced as i64;
            if let Some(last_slice) = slices.last_mut() {
                *last_slice = (*last_slice as i64 + diff) as u32;
            }
        }
        
        slices
    }
}

// Mock strategy implementations
#[derive(Debug)]
struct MomentumStrategy;
#[derive(Debug)]
struct MeanReversionStrategy;
#[derive(Debug)]
struct ArbitrageStrategy;

impl MomentumStrategy {
    fn new() -> Self { Self }
}
impl MeanReversionStrategy {
    fn new() -> Self { Self }
}
impl ArbitrageStrategy {
    fn new() -> Self { Self }
}

trait TestStrategy: std::fmt::Debug {
    fn generate_signal(&self, market_state: &MarketState) -> Option<TradingSignal>;
    fn name(&self) -> &str;
}

impl TestStrategy for MomentumStrategy {
    fn generate_signal(&self, market_state: &MarketState) -> Option<TradingSignal> {
        if market_state.momentum_signal > 0.5 {
            Some(TradingSignal {
                strategy: "momentum".to_string(),
                symbol: "EURUSD".to_string(),
                direction: SignalDirection::Buy,
                strength: market_state.momentum_signal,
                confidence: 0.8,
            })
        } else {
            None
        }
    }
    fn name(&self) -> &str { "momentum" }
}

impl TestStrategy for MeanReversionStrategy {
    fn generate_signal(&self, market_state: &MarketState) -> Option<TradingSignal> {
        if market_state.mean_reversion_signal < -0.5 {
            Some(TradingSignal {
                strategy: "mean_reversion".to_string(),
                symbol: "EURUSD".to_string(),
                direction: SignalDirection::Sell,
                strength: market_state.mean_reversion_signal.abs(),
                confidence: 0.7,
            })
        } else {
            None
        }
    }
    fn name(&self) -> &str { "mean_reversion" }
}

impl TestStrategy for ArbitrageStrategy {
    fn generate_signal(&self, market_state: &MarketState) -> Option<TradingSignal> {
        if !market_state.arbitrage_opportunities.is_empty() {
            Some(TradingSignal {
                strategy: "arbitrage".to_string(),
                symbol: "EURUSD".to_string(),
                direction: SignalDirection::Buy,
                strength: 0.9,
                confidence: 0.95,
            })
        } else {
            None
        }
    }
    fn name(&self) -> &str { "arbitrage" }
}

#[derive(Debug)]
struct TestStrategyOrchestrator {
    strategies: Vec<Box<dyn TestStrategy>>,
    priorities: std::collections::HashMap<String, u8>,
}

impl TestStrategyOrchestrator {
    fn new() -> Self {
        Self {
            strategies: Vec::new(),
            priorities: std::collections::HashMap::new(),
        }
    }
    
    fn add_strategy(&mut self, _name: &str, strategy: Box<dyn TestStrategy>) {
        self.strategies.push(strategy);
    }
    
    fn generate_signals(&self, market_state: &MarketState) -> Vec<TradingSignal> {
        self.strategies.iter()
            .filter_map(|strategy| strategy.generate_signal(market_state))
            .collect()
    }
    
    fn detect_conflicts(&self, signals: &[TradingSignal]) -> Vec<SignalConflict> {
        let mut conflicts = Vec::new();
        
        for i in 0..signals.len() {
            for j in i+1..signals.len() {
                if signals[i].symbol == signals[j].symbol &&
                   !std::matches!((signals[i].direction.clone(), signals[j].direction.clone()), 
                                 (SignalDirection::Buy, SignalDirection::Buy) | 
                                 (SignalDirection::Sell, SignalDirection::Sell) |
                                 (SignalDirection::Hold, _) | 
                                 (_, SignalDirection::Hold)) {
                    conflicts.push(SignalConflict {
                        conflict_type: ConflictType::OpposingSignals,
                        involved_signals: vec![signals[i].clone(), signals[j].clone()],
                    });
                }
            }
        }
        
        conflicts
    }
    
    fn resolve_conflicts(&self, signals: Vec<TradingSignal>, _conflicts: &[SignalConflict]) -> Vec<TradingSignal> {
        // Simple resolution: prefer higher confidence signals
        let mut resolved = Vec::new();
        let mut symbols_seen = std::collections::HashSet::new();
        
        let mut sorted_signals = signals;
        sorted_signals.sort_by(|a, b| b.confidence.partial_cmp(&a.confidence).unwrap());
        
        for signal in sorted_signals {
            if !symbols_seen.contains(&signal.symbol) {
                resolved.push(signal.clone());
                symbols_seen.insert(signal.symbol);
            }
        }
        
        resolved
    }
    
    fn set_strategy_priority(&mut self, strategy_name: &str, priority: u8) {
        self.priorities.insert(strategy_name.to_string(), priority);
    }
    
    fn resolve_conflicts_by_priority(&self, signals: Vec<TradingSignal>) -> Vec<TradingSignal> {
        let mut resolved = signals;
        resolved.sort_by(|a, b| {
            let priority_a = self.priorities.get(&a.strategy).unwrap_or(&0);
            let priority_b = self.priorities.get(&b.strategy).unwrap_or(&0);
            priority_b.cmp(priority_a)
        });
        resolved
    }
}

#[derive(Debug)]
enum ConflictType {
    OpposingSignals,
    DuplicateSignals,
}

#[derive(Debug)]
struct SignalConflict {
    conflict_type: ConflictType,
    involved_signals: Vec<TradingSignal>,
}

#[derive(Debug)]
struct TestExecutionEngine;

impl TestExecutionEngine {
    fn new() -> Self { Self }
    
    fn execute_order(&self, order: ExecutionOrder) -> Result<ExecutionResult, String> {
        // Simulate execution with realistic metrics
        let arrival_price = 1.1025;
        let avg_price = arrival_price + 0.0002; // 2 pip slippage
        let market_impact = 0.3; // 0.3 basis points
        
        Ok(ExecutionResult {
            total_executed: order.quantity,
            average_price: avg_price,
            arrival_price,
            market_impact,
            max_participation_achieved: order.max_participation * 0.95, // Slightly under limit
            execution_cost: avg_price - arrival_price,
        })
    }
}

#[derive(Debug)]
struct TestAdaptiveAlgorithm {
    current_condition: Option<MarketCondition>,
}

impl TestAdaptiveAlgorithm {
    fn new() -> Self {
        Self {
            current_condition: None,
        }
    }
    
    fn set_market_condition(&mut self, condition: MarketCondition) {
        self.current_condition = Some(condition);
    }
    
    fn get_execution_parameters(&self) -> ExecutionParameters {
        match &self.current_condition {
            Some(MarketCondition::HighVolatility) => ExecutionParameters {
                slice_size_factor: 0.7,
                delay_between_slices: Duration::from_millis(800),
                max_participation_rate: 0.20,
                patience_factor: 1.0,
                urgency_multiplier: 1.0,
                opportunistic_factor: 1.0,
            },
            Some(MarketCondition::LowLiquidity) => ExecutionParameters {
                slice_size_factor: 1.0,
                delay_between_slices: Duration::from_millis(300),
                max_participation_rate: 0.10,
                patience_factor: 1.5,
                urgency_multiplier: 1.0,
                opportunistic_factor: 1.0,
            },
            Some(MarketCondition::TrendingMarket) => ExecutionParameters {
                slice_size_factor: 1.0,
                delay_between_slices: Duration::from_millis(300),
                max_participation_rate: 0.25,
                patience_factor: 1.0,
                urgency_multiplier: 1.3,
                opportunistic_factor: 1.0,
            },
            Some(MarketCondition::RangeMarket) => ExecutionParameters {
                slice_size_factor: 1.0,
                delay_between_slices: Duration::from_millis(300),
                max_participation_rate: 0.20,
                patience_factor: 1.0,
                urgency_multiplier: 1.0,
                opportunistic_factor: 1.4,
            },
            None => ExecutionParameters {
                slice_size_factor: 1.0,
                delay_between_slices: Duration::from_millis(300),
                max_participation_rate: 0.20,
                patience_factor: 1.0,
                urgency_multiplier: 1.0,
                opportunistic_factor: 1.0,
            },
        }
    }
}