# Routing Configuration System Design

## Overview

This document details the implementation of the routing configuration system for the Order Management System (OMS), which allows users to configure and customize the smart order routing behavior through a flexible and extensible configuration system.

## Configuration Architecture

The routing configuration system provides a hierarchical approach to configuration management:

1. **Global Configuration**: System-wide default settings
2. **Venue-Specific Configuration**: Settings that apply to specific execution venues
3. **Symbol-Specific Configuration**: Settings that apply to specific trading symbols
4. **Strategy-Specific Configuration**: Settings that apply to specific trading strategies
5. **Runtime Configuration**: Dynamic configuration that can be updated during operation

## Configuration Models

### Base Configuration Interface
```csharp
/// <summary>
/// Base interface for all configuration objects
/// </summary>
public interface IConfiguration
{
    /// <summary>
    /// Unique identifier for this configuration
    /// </summary>
    string Id { get; }
    
    /// <summary>
    /// Name of this configuration
    /// </summary>
    string Name { get; }
    
    /// <summary>
    /// Description of this configuration
    /// </summary>
    string Description { get; }
    
    /// <summary>
    /// Whether this configuration is active
    /// </summary>
    bool IsActive { get; set; }
    
    /// <summary>
    /// When this configuration was created
    /// </summary>
    DateTime CreatedAt { get; }
    
    /// <summary>
    /// When this configuration was last updated
    /// </summary>
    DateTime UpdatedAt { get; set; }
    
    /// <summary>
    /// Version of this configuration
    /// </summary>
    int Version { get; }
}
```

### Routing Configuration Model
```csharp
/// <summary>
/// Main routing configuration parameters
/// </summary>
public record RoutingConfig : IConfiguration
{
    public string Id { get; set; } = Guid.NewGuid().ToString();
    public string Name { get; set; } = "Default Routing Configuration";
    public string Description { get; set; } = "Default routing configuration for the OMS";
    public bool IsActive { get; set; } = true;
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
    public int Version { get; set; } = 1;
    
    // Core routing settings
    public bool SmartRoutingEnabled { get; set; } = true;
    public string DefaultVenue { get; set; } = "primary-broker";
    public Dictionary<string, double> VenuePreferences { get; set; } = new Dictionary<string, double>
    {
        ["primary-broker"] = 1.0,
        ["secondary-broker"] = 0.8,
        ["dark-pool"] = 0.6
    };
    
    // Routing criteria weights
    public double CostWeight { get; set; } = 0.4; // 40% weight to cost
    public double SpeedWeight { get; set; } = 0.3; // 30% weight to speed
    public double ReliabilityWeight { get; set; } = 0.3; // 30% weight to reliability
    
    // Risk controls
    public double MaxSlippagePercent { get; set; } = 0.5;
    public TimeSpan MaxRoutingTime { get; set; } = TimeSpan.FromSeconds(30);
    public bool EnableSlippageControl { get; set; } = true;
    public bool EnableTimeoutControl { get; set; } = true;
    
    // Advanced routing features
    public bool EnableTimeBasedRouting { get; set; } = true;
    public bool EnableLiquidityBasedRouting { get; set; } = true;
    public bool EnableSizeBasedRouting { get; set; } = true;
    
    // Performance thresholds
    public double MinFillRateThreshold { get; set; } = 0.95; // 95% minimum fill rate
    public double MaxLatencyThresholdMs { get; set; } = 500; // 500ms maximum latency
    public int MaxConsecutiveFailures { get; set; } = 5; // Max consecutive failures before deactivating venue
    
    // Algorithmic order routing
    public Dictionary<string, string> AlgorithmVenuePreferences { get; set; } = new Dictionary<string, string>
    {
        ["TWAP"] = "primary-broker",
        ["VWAP"] = "primary-broker",
        ["Iceberg"] = "dark-pool"
    };
    
    // Symbol-specific routing
    public Dictionary<string, string> SymbolVenuePreferences { get; set; } = new Dictionary<string, string>();
    
    // Time-based routing
    public Dictionary<TimeOfDayRange, string> TimeBasedVenuePreferences { get; set; } = new Dictionary<TimeOfDayRange, string>();
    
    public static RoutingConfig Default => new RoutingConfig();
}
```

### Time of Day Range Model
```csharp
/// <summary>
/// Represents a time range during the day
/// </summary>
public record TimeOfDayRange(
    TimeSpan StartTime,
    TimeSpan EndTime
)
{
    public bool Contains(DateTime time)
    {
        var timeOfDay = time.TimeOfDay;
        return timeOfDay >= StartTime && timeOfDay <= EndTime;
    }
    
    public bool Overlaps(TimeOfDayRange other)
    {
        return StartTime <= other.EndTime && EndTime >= other.StartTime;
    }
}
```

### Venue Configuration Model
```csharp
/// <summary>
/// Configuration for a specific execution venue
/// </summary>
public record VenueConfig : IConfiguration
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public bool IsActive { get; set; } = true;
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
    public int Version { get; set; } = 1;
    
    // Venue-specific routing settings
    public double CostFactor { get; set; } = 1.0;
    public double SpeedFactor { get; set; } = 1.0;
    public double ReliabilityFactor { get; set; } = 1.0;
    
    // Venue capabilities
    public List<VenueOrderType> SupportedOrderTypes { get; set; } = new List<VenueOrderType>
    {
        VenueOrderType.Market,
        VenueOrderType.Limit,
        VenueOrderType.StopMarket,
        VenueOrderType.StopLimit
    };
    
    public List<string> SupportedSymbols { get; set; } = new List<string>();
    public Dictionary<string, decimal> MinimumOrderSizes { get; set; } = new Dictionary<string, decimal>();
    public Dictionary<string, decimal> MaximumOrderSizes { get; set; } = new Dictionary<string, decimal>();
    
    // Connection settings
    public string ApiKey { get; set; }
    public string ApiSecret { get; set; }
    public string BaseUrl { get; set; }
    public int RateLimit { get; set; } = 100; // Requests per minute
    
    // Performance settings
    public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(30);
    public int MaxRetries { get; set; } = 3;
    public TimeSpan RetryDelay { get; set; } = TimeSpan.FromSeconds(1);
    
    // Market data settings
    public bool EnableMarketData { get; set; } = true;
    public int MarketDataDepth { get; set; } = 10; // Levels of market depth
    public TimeSpan MarketDataRefreshInterval { get; set; } = TimeSpan.FromMilliseconds(100);
}
```

### Symbol Configuration Model
```csharp
/// <summary>
/// Configuration for routing specific symbols
/// </summary>
public record SymbolRoutingConfig : IConfiguration
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public bool IsActive { get; set; } = true;
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
    public int Version { get; set; } = 1;
    
    // Symbol-specific routing settings
    public string Symbol { get; set; }
    public string PreferredVenue { get; set; }
    public List<string> BackupVenues { get; set; } = new List<string>();
    
    // Symbol characteristics
    public LiquidityLevel Liquidity { get; set; } = LiquidityLevel.Medium;
    public VolatilityLevel Volatility { get; set; } = VolatilityLevel.Medium;
    public string AssetClass { get; set; } = "Equity";
    
    // Order size thresholds
    public int LargeOrderThreshold { get; set; } = 100;
    public int BlockOrderThreshold { get; set; } = 1000;
    
    // Pricing settings
    public int TickSize { get; set; } = 1; // In cents or appropriate units
    public decimal MinPriceIncrement { get; set; } = 0.01m;
    
    // Venue preferences for this symbol
    public Dictionary<string, double> VenuePreferences { get; set; } = new Dictionary<string, double>();
}
```

## Configuration Management System

### Configuration Manager
```csharp
/// <summary>
/// Manages routing configuration for the OMS
/// </summary>
public class RoutingConfigurationManager
{
    private readonly ILogger<RoutingConfigurationManager> _logger;
    private readonly IConfigurationRepository _configRepository;
    private readonly Dictionary<string, IConfiguration> _configurations;
    private readonly object _lock = new object();
    
    public RoutingConfigurationManager(
        ILogger<RoutingConfigurationManager> logger,
        IConfigurationRepository configRepository)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        _configRepository = configRepository ?? throw new ArgumentNullException(nameof(configRepository));
        _configurations = new Dictionary<string, IConfiguration>();
        
        // Load initial configurations
        LoadConfigurationsAsync().Wait();
    }
    
    /// <summary>
    /// Get the current routing configuration
    /// </summary>
    public async Task<RoutingConfig> GetRoutingConfigAsync()
    {
        var config = await GetConfigurationAsync<RoutingConfig>("routing-config");
        return config ?? RoutingConfig.Default;
    }
    
    /// <summary>
    /// Update the routing configuration
    /// </summary>
    public async Task UpdateRoutingConfigAsync(RoutingConfig config)
    {
        if (config == null) throw new ArgumentNullException(nameof(config));
        
        await UpdateConfigurationAsync(config);
        _logger.LogInformation("Routing configuration updated");
    }
    
    /// <summary>
    /// Get configuration for a specific venue
    /// </summary>
    public async Task<VenueConfig> GetVenueConfigAsync(string venueId)
    {
        if (string.IsNullOrEmpty(venueId)) throw new ArgumentException("Venue ID required", nameof(venueId));
        
        var config = await GetConfigurationAsync<VenueConfig>($"venue-{venueId}");
        return config;
    }
    
    /// <summary>
    /// Update configuration for a specific venue
    /// </summary>
    public async Task UpdateVenueConfigAsync(VenueConfig config)
    {
        if (config == null) throw new ArgumentNullException(nameof(config));
        if (string.IsNullOrEmpty(config.Id)) throw new ArgumentException("Venue config ID required", nameof(config));
        
        await UpdateConfigurationAsync(config);
        _logger.LogInformation("Venue configuration updated for {VenueId}", config.Id);
    }
    
    /// <summary>
    /// Get routing configuration for a specific symbol
    /// </summary>
    public async Task<SymbolRoutingConfig> GetSymbolRoutingConfigAsync(string symbol)
    {
        if (string.IsNullOrEmpty(symbol)) throw new ArgumentException("Symbol required", nameof(symbol));
        
        var config = await GetConfigurationAsync<SymbolRoutingConfig>($"symbol-{symbol}");
        return config;
    }
    
    /// <summary>
    /// Update routing configuration for a specific symbol
    /// </summary>
    public async Task UpdateSymbolRoutingConfigAsync(SymbolRoutingConfig config)
    {
        if (config == null) throw new ArgumentNullException(nameof(config));
        if (string.IsNullOrEmpty(config.Symbol)) throw new ArgumentException("Symbol required", nameof(config));
        
        var configId = $"symbol-{config.Symbol}";
        config.Id = configId;
        config.Name = $"Routing config for {config.Symbol}";
        config.Description = $"Routing configuration for symbol {config.Symbol}";
        
        await UpdateConfigurationAsync(config);
        _logger.LogInformation("Symbol routing configuration updated for {Symbol}", config.Symbol);
    }
    
    /// <summary>
    /// Get configuration by ID
    /// </summary>
    public async Task<T> GetConfigurationAsync<T>(string configId) where T : class, IConfiguration
    {
        if (string.IsNullOrEmpty(configId)) throw new ArgumentException("Config ID required", nameof(configId));
        
        lock (_lock)
        {
            if (_configurations.ContainsKey(configId))
            {
                return _configurations[configId] as T;
            }
        }
        
        // Load from repository if not in memory
        var config = await _configRepository.GetConfigurationAsync<T>(configId);
        if (config != null)
        {
            lock (_lock)
            {
                _configurations[configId] = config;
            }
        }
        
        return config;
    }
    
    /// <summary>
    /// Update a configuration
    /// </summary>
    public async Task UpdateConfigurationAsync<T>(T config) where T : class, IConfiguration
    {
        if (config == null) throw new ArgumentNullException(nameof(config));
        if (string.IsNullOrEmpty(config.Id)) throw new ArgumentException("Config ID required", nameof(config));
        
        // Validate configuration
        if (!ValidateConfiguration(config))
        {
            throw new ArgumentException("Invalid configuration", nameof(config));
        }
        
        // Increment version
        var versionProperty = typeof(T).GetProperty("Version");
        if (versionProperty != null && versionProperty.CanWrite)
        {
            var currentVersion = (int)versionProperty.GetValue(config);
            versionProperty.SetValue(config, currentVersion + 1);
        }
        
        // Update timestamp
        var updatedAtProperty = typeof(T).GetProperty("UpdatedAt");
        if (updatedAtProperty != null && updatedAtProperty.CanWrite)
        {
            updatedAtProperty.SetValue(config, DateTime.UtcNow);
        }
        
        // Save to repository
        await _configRepository.SaveConfigurationAsync(config);
        
        // Update in memory cache
        lock (_lock)
        {
            _configurations[config.Id] = config;
        }
    }
    
    /// <summary>
    /// Validate a configuration
    /// </summary>
    public bool ValidateConfiguration<T>(T config) where T : class, IConfiguration
    {
        if (config == null) return false;
        
        // Basic validation
        if (string.IsNullOrEmpty(config.Id)) return false;
        if (string.IsNullOrEmpty(config.Name)) return false;
        if (config.CreatedAt > DateTime.UtcNow) return false;
        if (config.UpdatedAt < config.CreatedAt) return false;
        if (config.Version < 1) return false;
        
        // Type-specific validation
        switch (config)
        {
            case RoutingConfig routingConfig:
                return ValidateRoutingConfig(routingConfig);
            case VenueConfig venueConfig:
                return ValidateVenueConfig(venueConfig);
            case SymbolRoutingConfig symbolConfig:
                return ValidateSymbolRoutingConfig(symbolConfig);
            default:
                return true; // Unknown config type, assume valid
        }
    }
    
    private bool ValidateRoutingConfig(RoutingConfig config)
    {
        // Validate weights sum to 1.0 (approximately)
        var totalWeight = config.CostWeight + config.SpeedWeight + config.ReliabilityWeight;
        if (Math.Abs(totalWeight - 1.0) > 0.01) return false;
        
        // Validate thresholds
        if (config.MaxSlippagePercent < 0 || config.MaxSlippagePercent > 100) return false;
        if (config.MaxRoutingTime.TotalMilliseconds <= 0) return false;
        if (config.MinFillRateThreshold < 0 || config.MinFillRateThreshold > 1) return false;
        if (config.MaxLatencyThresholdMs <= 0) return false;
        if (config.MaxConsecutiveFailures <= 0) return false;
        
        return true;
    }
    
    private bool ValidateVenueConfig(VenueConfig config)
    {
        // Validate factors are positive
        if (config.CostFactor <= 0) return false;
        if (config.SpeedFactor <= 0) return false;
        if (config.ReliabilityFactor <= 0) return false;
        
        // Validate connection settings
        if (string.IsNullOrEmpty(config.BaseUrl)) return false;
        if (config.RateLimit <= 0) return false;
        if (config.Timeout.TotalMilliseconds <= 0) return false;
        if (config.MaxRetries < 0) return false;
        
        return true;
    }
    
    private bool ValidateSymbolRoutingConfig(SymbolRoutingConfig config)
    {
        // Validate symbol
        if (string.IsNullOrEmpty(config.Symbol)) return false;
        
        // Validate thresholds
        if (config.LargeOrderThreshold <= 0) return false;
        if (config.BlockOrderThreshold <= 0) return false;
        if (config.LargeOrderThreshold > config.BlockOrderThreshold) return false;
        
        // Validate pricing settings
        if (config.TickSize <= 0) return false;
        if (config.MinPriceIncrement <= 0) return false;
        
        return true;
    }
    
    /// <summary>
    /// Load all configurations from repository
    /// </summary>
    private async Task LoadConfigurationsAsync()
    {
        try
        {
            var configs = await _configRepository.GetAllConfigurationsAsync();
            lock (_lock)
            {
                _configurations.Clear();
                foreach (var config in configs)
                {
                    _configurations[config.Id] = config;
                }
            }
            
            _logger.LogInformation("Loaded {Count} configurations", configs.Count);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error loading configurations");
            throw;
        }
    }
    
    /// <summary>
    /// Reload configurations from repository
    /// </summary>
    public async Task ReloadConfigurationsAsync()
    {
        await LoadConfigurationsAsync();
        _logger.LogInformation("Configurations reloaded");
    }
}
```

### Configuration Repository Interface
```csharp
/// <summary>
/// Repository for configuration storage and retrieval
/// </summary>
public interface IConfigurationRepository
{
    /// <summary>
    /// Get a configuration by ID
    /// </summary>
    Task<T> GetConfigurationAsync<T>(string configId) where T : class, IConfiguration;
    
    /// <summary>
    /// Save a configuration
    /// </summary>
    Task SaveConfigurationAsync<T>(T config) where T : class, IConfiguration;
    
    /// <summary>
    /// Delete a configuration
    /// </summary>
    Task DeleteConfigurationAsync(string configId);
    
    /// <summary>
    /// Get all configurations
    /// </summary>
    Task<List<IConfiguration>> GetAllConfigurationsAsync();
    
    /// <summary>
    /// Get configurations by type
    /// </summary>
    Task<List<T>> GetConfigurationsByTypeAsync<T>() where T : class, IConfiguration;
}
```

### File-Based Configuration Repository
```csharp
/// <summary>
/// File-based implementation of configuration repository
/// </summary>
public class FileConfigurationRepository : IConfigurationRepository
{
    private readonly string _configDirectory;
    private readonly ILogger<FileConfigurationRepository> _logger;
    private readonly JsonSerializerOptions _jsonOptions;
    
    public FileConfigurationRepository(
        string configDirectory,
        ILogger<FileConfigurationRepository> logger)
    {
        _configDirectory = configDirectory ?? throw new ArgumentNullException(nameof(configDirectory));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        
        // Ensure directory exists
        if (!Directory.Exists(_configDirectory))
        {
            Directory.CreateDirectory(_configDirectory);
        }
        
        _jsonOptions = new JsonSerializerOptions
        {
            WriteIndented = true,
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        };
    }
    
    public async Task<T> GetConfigurationAsync<T>(string configId) where T : class, IConfiguration
    {
        if (string.IsNullOrEmpty(configId)) throw new ArgumentException("Config ID required", nameof(configId));
        
        var filePath = Path.Combine(_configDirectory, $"{configId}.json");
        if (!File.Exists(filePath))
        {
            return null;
        }
        
        try
        {
            var json = await File.ReadAllTextAsync(filePath);
            return JsonSerializer.Deserialize<T>(json, _jsonOptions);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error reading configuration from {FilePath}", filePath);
            throw;
        }
    }
    
    public async Task SaveConfigurationAsync<T>(T config) where T : class, IConfiguration
    {
        if (config == null) throw new ArgumentNullException(nameof(config));
        if (string.IsNullOrEmpty(config.Id)) throw new ArgumentException("Config ID required", nameof(config));
        
        var filePath = Path.Combine(_configDirectory, $"{config.Id}.json");
        
        try
        {
            var json = JsonSerializer.Serialize(config, _jsonOptions);
            await File.WriteAllTextAsync(filePath, json);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error saving configuration to {FilePath}", filePath);
            throw;
        }
    }
    
    public async Task DeleteConfigurationAsync(string configId)
    {
        if (string.IsNullOrEmpty(configId)) throw new ArgumentException("Config ID required", nameof(configId));
        
        var filePath = Path.Combine(_configDirectory, $"{configId}.json");
        if (File.Exists(filePath))
        {
            try
            {
                File.Delete(filePath);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error deleting configuration file {FilePath}", filePath);
                throw;
            }
        }
    }
    
    public async Task<List<IConfiguration>> GetAllConfigurationsAsync()
    {
        var configs = new List<IConfiguration>();
        
        try
        {
            var files = Directory.GetFiles(_configDirectory, "*.json");
            foreach (var file in files)
            {
                try
                {
                    var json = await File.ReadAllTextAsync(file);
                    
                    // Try to deserialize as different config types
                    // In a real implementation, you might store type information in the file
                    var config = TryDeserializeConfig(json);
                    if (config != null)
                    {
                        configs.Add(config);
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, "Error reading configuration file {FilePath}", file);
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error reading configuration directory {ConfigDirectory}", _configDirectory);
            throw;
        }
        
        return configs;
    }
    
    public async Task<List<T>> GetConfigurationsByTypeAsync<T>() where T : class, IConfiguration
    {
        var configs = new List<T>();
        
        try
        {
            var files = Directory.GetFiles(_configDirectory, "*.json");
            foreach (var file in files)
            {
                try
                {
                    var json = await File.ReadAllTextAsync(file);
                    var config = JsonSerializer.Deserialize<T>(json, _jsonOptions);
                    if (config != null)
                    {
                        configs.Add(config);
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, "Error reading configuration file {FilePath}", file);
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error reading configuration directory {ConfigDirectory}", _configDirectory);
            throw;
        }
        
        return configs;
    }
    
    private IConfiguration TryDeserializeConfig(string json)
    {
        try
        {
            // Try different configuration types
            var doc = JsonDocument.Parse(json);
            var root = doc.RootElement;
            
            if (root.TryGetProperty("costWeight", out _))
            {
                return JsonSerializer.Deserialize<RoutingConfig>(json, _jsonOptions);
            }
            else if (root.TryGetProperty("costFactor", out _))
            {
                return JsonSerializer.Deserialize<VenueConfig>(json, _jsonOptions);
            }
            else if (root.TryGetProperty("symbol", out _))
            {
                return JsonSerializer.Deserialize<SymbolRoutingConfig>(json, _jsonOptions);
            }
            
            return null;
        }
        catch
        {
            return null;
        }
    }
}
```

## Integration with OrderManager

### Configuration Integration in OrderManager
```csharp
public partial class OrderManager : IOrderManager
{
    private readonly RoutingConfigurationManager _configManager;
    
    // Enhanced constructor with configuration manager
    public OrderManager(
        IRiskManager riskManager,
        IPositionSizer positionSizer,
        ILogger<OrderManager> logger,
        RoutingConfigurationManager configManager) : base(riskManager, positionSizer, logger)
    {
        _configManager = configManager ?? throw new ArgumentNullException(nameof(configManager));
        _venueManager = new VenueManager(logger);
        _omsToVenueOrderIdMap = new Dictionary<string, string>();
        _venueToOmsOrderIdMap = new Dictionary<string, string>();
        
        // Initialize with configurations
        InitializeWithConfigurationsAsync().Wait();
    }
    
    private async Task InitializeWithConfigurationsAsync()
    {
        try
        {
            // Get routing configuration
            var routingConfig = await _configManager.GetRoutingConfigAsync();
            
            // Initialize venues based on configuration
            await InitializeVenuesFromConfigAsync(routingConfig);
            
            _logger.LogInformation("OrderManager initialized with configurations");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error initializing OrderManager with configurations");
            throw;
        }
    }
    
    private async Task InitializeVenuesFromConfigAsync(RoutingConfig routingConfig)
    {
        // Get all venue configurations
        var venueConfigs = await _configManager.GetConfigurationsByTypeAsync<VenueConfig>();
        
        foreach (var venueConfig in venueConfigs)
        {
            if (!venueConfig.IsActive) continue;
            
            try
            {
                // Create venue based on configuration
                var venue = CreateVenueFromConfig(venueConfig);
                if (venue != null)
                {
                    _venueManager.AddVenue(venue);
                    _logger.LogInformation("Venue {VenueId} initialized from configuration", venueConfig.Id);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error initializing venue {VenueId} from configuration", venueConfig.Id);
            }
        }
    }
    
    private IExecutionVenue CreateVenueFromConfig(VenueConfig config)
    {
        // Create venue based on type and configuration
        // This is a simplified implementation - in reality, you would have
        // specific venue implementations for different broker/exchange APIs
        
        return new BrokerExecutionVenue(
            id: config.Id,
            name: config.Name,
            description: config.Description,
            type: VenueType.Broker,
            config: config,
            brokerApi: CreateBrokerApiFromConfig(config),
            logger: _logger
        );
    }
    
    private IBrokerApi CreateBrokerApiFromConfig(VenueConfig config)
    {
        // Create broker API client based on configuration
        // This would be specific to each broker's API
        
        return new GenericBrokerApi(
            apiKey: config.ApiKey,
            apiSecret: config.ApiSecret,
            baseUrl: config.BaseUrl,
            rateLimit: config.RateLimit,
            timeout: config.Timeout,
            maxRetries: config.MaxRetries,
            retryDelay: config.RetryDelay
        );
    }
    
    // Enhanced routing with configuration
    public async Task<RoutingResult> RouteOrderAsync(OrderRequest request, StrategyContext context)
    {
        try
        {
            // Get current routing configuration
            var routingConfig = await _configManager.GetRoutingConfigAsync();
            
            // Check if smart routing is enabled
            if (!routingConfig.SmartRoutingEnabled)
            {
                var defaultVenue = _venueManager.GetVenue(routingConfig.DefaultVenue);
                if (defaultVenue == null)
                {
                    return new RoutingResult(false, null, null, "Default venue not found", 
                        new Dictionary<string, object> { ["error"] = "Default venue not found" });
                }
                
                _logger.LogInformation("Smart routing disabled, using default venue: {Venue}", defaultVenue.Name);
                return new RoutingResult(true, null, defaultVenue, "Routing disabled, using default venue", 
                    new Dictionary<string, object> { ["venue"] = defaultVenue.Name });
            }
            
            // Get symbol-specific configuration if available
            SymbolRoutingConfig symbolConfig = null;
            if (!string.IsNullOrEmpty(request.Symbol))
            {
                symbolConfig = await _configManager.GetSymbolRoutingConfigAsync(request.Symbol);
            }
            
            // Select best venue based on configuration
            var selectedVenue = await SelectBestVenueAsync(request, context, routingConfig, symbolConfig);
            
            if (selectedVenue == null)
            {
                return new RoutingResult(false, null, null, "No suitable venue found", 
                    new Dictionary<string, object> { ["error"] = "No suitable venue found" });
            }
            
            // Validate venue is active
            if (!selectedVenue.IsActive)
            {
                return new RoutingResult(false, null, null, $"Venue {selectedVenue.Name} is not active", 
                    new Dictionary<string, object> { ["error"] = "Venue inactive" });
            }
            
            // Update routing metrics
            UpdateRoutingMetrics(selectedVenue);
            
            _logger.LogInformation("Order routed to venue: {Venue} (Cost: {Cost}, Speed: {Speed}, Reliability: {Reliability})", 
                selectedVenue.Name, selectedVenue.CostFactor, selectedVenue.SpeedFactor, selectedVenue.ReliabilityFactor);
            
            return new RoutingResult(true, null, selectedVenue, "Order routed successfully",
                new Dictionary<string, object> 
                { 
                    ["venue"] = selectedVenue.Name, 
                    ["cost_factor"] = selectedVenue.CostFactor,
                    ["speed_factor"] = selectedVenue.SpeedFactor,
                    ["reliability_factor"] = selectedVenue.ReliabilityFactor
                });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error routing order for {Symbol}", request.Symbol);
            return new RoutingResult(false, null, null, $"Error routing order: {ex.Message}", 
                new Dictionary<string, object> { ["error"] = ex.Message });
        }
    }
    
    private async Task<IExecutionVenue> SelectBestVenueAsync(
        OrderRequest request, 
        StrategyContext context, 
        RoutingConfig routingConfig, 
        SymbolRoutingConfig symbolConfig)
    {
        // Get all active venues
        var venues = _venueManager.GetActiveVenues();
        
        if (venues.Count == 0)
        {
            return null;
        }
        
        if (venues.Count == 1)
        {
            return venues[0];
        }
        
        // Apply symbol-specific venue preference if available
        if (symbolConfig != null && !string.IsNullOrEmpty(symbolConfig.PreferredVenue))
        {
            var preferredVenue = venues.FirstOrDefault(v => v.Id == symbolConfig.PreferredVenue);
            if (preferredVenue != null)
            {
                _logger.LogInformation("Using symbol-preferred venue: {Venue}", preferredVenue.Name);
                return preferredVenue;
            }
        }
        
        // Apply algorithm-specific venue preference if available
        if (!string.IsNullOrEmpty(request.Algorithm))
        {
            if (routingConfig.AlgorithmVenuePreferences.ContainsKey(request.Algorithm))
            {
                var algorithmVenue = routingConfig.AlgorithmVenuePreferences[request.Algorithm];
                var preferredVenue = venues.FirstOrDefault(v => v.Id == algorithmVenue);
                if (preferredVenue != null)
                {
                    _logger.LogInformation("Using algorithm-preferred venue: {Venue} for {Algorithm}", 
                        preferredVenue.Name, request.Algorithm);
                    return preferredVenue;
                }
            }
        }
        
        // Apply time-based routing if enabled
        if (routingConfig.EnableTimeBasedRouting)
        {
            var timeBasedVenue = SelectVenueBasedOnTime(venues, routingConfig);
            if (timeBasedVenue != null)
            {
                _logger.LogInformation("Using time-based venue: {Venue}", timeBasedVenue.Name);
                return timeBasedVenue;
            }
        }
        
        // Calculate scores for all venues
        var venueScores = new Dictionary<IExecutionVenue, double>();
        
        foreach (var venue in venues)
        {
            double score = 0;
            
            // Get venue-specific configuration
            var venueConfig = await _configManager.GetVenueConfigAsync(venue.Id);
            
            // Factor in venue preferences from routing config
            if (routingConfig.VenuePreferences.ContainsKey(venue.Id))
            {
                score += routingConfig.VenuePreferences[venue.Id] * 100;
            }
            
            // Factor in cost
            var costFactor = venueConfig?.CostFactor ?? venue.CostFactor;
            score -= costFactor * (routingConfig.CostWeight * 100);
            
            // Factor in speed
            var speedFactor = venueConfig?.SpeedFactor ?? venue.SpeedFactor;
            score += speedFactor * (routingConfig.SpeedWeight * 100);
            
            // Factor in reliability
            var reliabilityFactor = venueConfig?.ReliabilityFactor ?? venue.ReliabilityFactor;
            score += reliabilityFactor * (routingConfig.ReliabilityWeight * 100);
            
            // Adjust for order characteristics
            score = AdjustScoreForOrderCharacteristics(score, venue, request, context, routingConfig, symbolConfig);
            
            venueScores[venue] = score;
        }
        
        // Select venue with highest score
        return venueScores.OrderByDescending(kvp => kvp.Value).First().Key;
    }
    
    private double AdjustScoreForOrderCharacteristics(
        double score, 
        IExecutionVenue venue, 
        OrderRequest request, 
        StrategyContext context, 
        RoutingConfig routingConfig, 
        SymbolRoutingConfig symbolConfig)
    {
        // Adjust for order size
        if (request.Quantity > (symbolConfig?.LargeOrderThreshold ?? 100))
        {
            // Prefer venues that handle large orders well
            if (venue.Type == VenueType.DarkPool)
            {
                score += 20; // Bonus for dark pool handling of large orders
            }
            else
            {
                score -= 10; // Penalty for regular venues handling large orders
            }
        }
        
        // Adjust for algorithmic orders
        if (!string.IsNullOrEmpty(request.Algorithm))
        {
            // Some venues may be better optimized for algorithmic orders
            if (venue.Id == routingConfig.DefaultVenue)
            {
                score += 5; // Small bonus for default venue handling algorithms
            }
        }
        
        // Adjust for symbol-specific venue preferences
        if (symbolConfig?.VenuePreferences?.ContainsKey(venue.Id) == true)
        {
            score += symbolConfig.VenuePreferences[venue.Id] * 10;
        }
        
        return score;
    }
    
    private IExecutionVenue SelectVenueBasedOnTime(List<IExecutionVenue> venues, RoutingConfig routingConfig)
    {
        var currentTime = DateTime.UtcNow.TimeOfDay;
        
        // Check time-based venue preferences
        foreach (var kvp in routingConfig.TimeBasedVenuePreferences)
        {
            if (kvp.Key.Contains(DateTime.UtcNow))
            {
                var venue = venues.FirstOrDefault(v => v.Id == kvp.Value);
                if (venue != null)
                {
                    return venue;
                }
            }
        }
        
        return null;
    }
}
```

## Configuration Validation and Monitoring

### Configuration Validation
```csharp
/// <summary>
/// Validates routing configurations
/// </summary>
public class RoutingConfigurationValidator
{
    private readonly ILogger<RoutingConfigurationValidator> _logger;
    
    public RoutingConfigurationValidator(ILogger<RoutingConfigurationValidator> logger)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }
    
    public async Task<ConfigurationValidationResult> ValidateConfigurationAsync(RoutingConfig config)
    {
        var result = new ConfigurationValidationResult
        {
            IsValid = true,
            Errors = new List<string>(),
            Warnings = new List<string>()
        };
        
        if (config == null)
        {
            result.IsValid = false;
            result.Errors.Add("Configuration is null");
            return result;
        }
        
        // Validate weights
        var totalWeight = config.CostWeight + config.SpeedWeight + config.ReliabilityWeight;
        if (Math.Abs(totalWeight - 1.0) > 0.01)
        {
            result.Warnings.Add($"Routing weights do not sum to 1.0 (current sum: {totalWeight:F2})");
        }
        
        // Validate venue preferences
        foreach (var venueId in config.VenuePreferences.Keys)
        {
            if (config.VenuePreferences[venueId] < 0 || config.VenuePreferences[venueId] > 1)
            {
                result.Errors.Add($"Invalid venue preference for {venueId}: {config.VenuePreferences[venueId]} (must be between 0 and 1)");
            }
        }
        
        // Validate algorithm venue preferences
        foreach (var algorithm in config.AlgorithmVenuePreferences.Keys)
        {
            var venueId = config.AlgorithmVenuePreferences[algorithm];
            if (!config.VenuePreferences.ContainsKey(venueId))
            {
                result.Warnings.Add($"Algorithm {algorithm} prefers venue {venueId} which is not in venue preferences");
            }
        }
        
        // Validate thresholds
        if (config.MaxSlippagePercent < 0.01)
        {
            result.Warnings.Add("Max slippage percent is very low, may reject valid orders");
        }
        
        if (config.MaxRoutingTime.TotalMilliseconds < 100)
        {
            result.Warnings.Add("Max routing time is very short, may cause timeouts");
        }
        
        result.IsValid = result.Errors.Count == 0;
        return result;
    }
}

/// <summary>
/// Result of configuration validation
/// </summary>
public record ConfigurationValidationResult
{
    public bool IsValid { get; set; }
    public List<string> Errors { get; set; } = new List<string>();
    public List<string> Warnings { get; set; } = new List<string>();
}
```

## Testing Considerations

### Unit Tests for Configuration System
1. **Configuration Validation**: Test validation of different configuration types
2. **Configuration Loading/Saving**: Test persistence of configurations
3. **Configuration Updates**: Test updating configurations with versioning
4. **Venue Selection**: Test venue selection based on different configurations
5. **Symbol-Specific Routing**: Test routing based on symbol configurations

### Integration Tests
1. **Configuration Repository**: Test file-based configuration storage
2. **Dynamic Configuration Updates**: Test updating configurations at runtime
3. **Performance Impact**: Test performance with large configurations
4. **Error Handling**: Test error handling for invalid configurations

## Performance Considerations

### Configuration Caching
```csharp
/// <summary>
/// Caching layer for configurations
/// </summary>
public class ConfigurationCache
{
    private readonly MemoryCache _cache;
    private readonly ILogger<ConfigurationCache> _logger;
    
    public ConfigurationCache(ILogger<ConfigurationCache> logger)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        
        var options = new MemoryCacheOptions
        {
            SizeLimit = 1000, // Maximum number of entries
            ExpirationScanFrequency = TimeSpan.FromMinutes(5)
        };
        
        _cache = new MemoryCache(options);
    }
    
    public T Get<T>(string key) where T : class
    {
        return _cache.Get<T>(key);
    }
    
    public void Set<T>(string key, T value, TimeSpan expiration) where T : class
    {
        var cacheEntryOptions = new MemoryCacheEntryOptions
        {
            AbsoluteExpirationRelativeToNow = expiration,
            Size = 1
        };
        
        _cache.Set(key, value, cacheEntryOptions);
    }
    
    public void Remove(string key)
    {
        _cache.Remove(key);
    }
    
    public void Clear()
    {
        _cache.Clear();
    }
}
```

## Monitoring and Alerting

### Configuration Change Tracking
```csharp
/// <summary>
/// Tracks configuration changes for monitoring and auditing
/// </summary>
public class ConfigurationChangeTracker
{
    private readonly ILogger<ConfigurationChangeTracker> _logger;
    
    public ConfigurationChangeTracker(ILogger<ConfigurationChangeTracker> logger)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }
    
    public void TrackConfigurationChange<T>(T oldConfig, T newConfig, string userId) where T : class, IConfiguration
    {
        if (oldConfig == null || newConfig == null) return;
        
        var changes = CompareConfigurations(oldConfig, newConfig);
        if (changes.Any())
        {
            _logger.LogInformation("Configuration {ConfigId} changed by {UserId}: {Changes}", 
                newConfig.Id, userId, string.Join(", ", changes));
        }
    }
    
    private List<string> CompareConfigurations<T>(T oldConfig, T newConfig) where T : class, IConfiguration
    {
        var changes = new List<string>();
        
        // Use reflection to compare properties
        var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
            .Where(p => p.CanRead);
            
        foreach (var property in properties)
        {
            var oldValue = property.GetValue(oldConfig);
            var newValue = property.GetValue(newConfig);
            
            if (!Equals(oldValue, newValue))
            {
                changes.Add($"{property.Name}: {oldValue} -> {newValue}");
            }
        }
        
        return changes;
    }
}
```

## Future Enhancements

1. **Database Configuration Storage**: Store configurations in a database for enterprise deployments
2. **Configuration Versioning**: Full version history and rollback capabilities
3. **Configuration Templates**: Predefined configuration templates for different trading scenarios
4. **A/B Testing**: Test different configurations with subsets of orders
5. **Machine Learning**: Use ML to optimize configuration parameters based on performance
6. **Real-time Configuration Updates**: Push configuration updates to running instances
7. **Configuration Auditing**: Full audit trail of all configuration changes
8. **Multi-tenancy**: Support for multiple tenants with separate configurations
