# Iceberg Order Algorithm Implementation Design

## Overview

This document details the implementation of the Iceberg order algorithm in the Order Management System (OMS), which executes large orders by only displaying a small portion of the total order size at any given time to minimize market impact and reduce information leakage.

## Iceberg Algorithm Fundamentals

### Algorithm Description
The Iceberg algorithm hides large order sizes by only displaying a small, visible portion of the total order quantity. As each displayed portion is filled, a new portion is revealed until the entire order is executed. This approach minimizes market impact by preventing other market participants from seeing the true size of the order.

### Key Characteristics
1. **Size Concealment**: Hides large order sizes from the market
2. **Sequential Execution**: Executes orders in small, visible portions
3. **Market Impact Reduction**: Reduces information leakage and adverse price movements
4. **Continuous Replenishment**: Automatically replenishes visible quantity as portions are filled

## Iceberg Parameters

### Core Parameters
```csharp
/// <summary>
/// Parameters for Iceberg algorithm execution
/// </summary>
public record IcebergParameters
{
    /// <summary>
    /// Trading symbol
    /// </summary>
    public string Symbol { get; set; }
    
    /// <summary>
    /// Order side (Buy/Sell)
    /// </summary>
    public OrderSide Side { get; set; }
    
    /// <summary>
    /// Total quantity to execute
    /// </summary>
    public int TotalQuantity { get; set; }
    
    /// <summary>
    /// Visible quantity (displayed to market)
    /// </summary>
    public int VisibleQuantity { get; set; }
    
    /// <summary>
    /// Optional limit price for limit orders
    /// </summary>
    public decimal? LimitPrice { get; set; }
    
    /// <summary>
    /// Time in force for orders
    /// </summary>
    public TimeInForce TimeInForce { get; set; } = TimeInForce.Day;
    
    /// <summary>
    /// Whether to automatically replenish visible quantity
    /// </summary>
    public bool AutoReplenish { get; set; } = true;
    
    /// <summary>
    /// Minimum visible quantity (to avoid very small orders)
    /// </summary>
    public int MinVisibleQuantity { get; set; } = 1;
    
    /// <summary>
    /// Maximum visible quantity (to control individual order impact)
    /// </summary>
    public int? MaxVisibleQuantity { get; set; }
    
    /// <summary>
    /// Delay between order placements (in milliseconds)
    /// </summary>
    public int PlacementDelayMs { get; set; } = 1000;
    
    /// <summary>
    /// Whether to cancel remaining visible quantity at end
    /// </summary>
    public bool CancelAtEnd { get; set; } = true;
    
    /// <summary>
    /// Aggressiveness factor (0.0 to 1.0) - higher values place orders more aggressively
    /// </summary>
    public double Aggressiveness { get; set; } = 0.5;
    
    /// <summary>
    /// Whether to adjust visible quantity based on market conditions
    /// </summary>
    public bool AdaptiveVisibility { get; set; } = false;
    
    /// <summary>
    /// Custom metadata for the algorithm
    /// </summary>
    public Dictionary<string, object> Metadata { get; set; } = new Dictionary<string, object>();
}
```

### Iceberg Configuration
```csharp
/// <summary>
/// Configuration for Iceberg algorithm behavior
/// </summary>
public record IcebergConfig
{
    /// <summary>
    /// Default visible quantity as percentage of total quantity
    /// </summary>
    public double DefaultVisiblePercentage { get; set; } = 0.1; // 10%
    
    /// <summary>
    /// Default placement delay (in milliseconds)
    /// </summary>
    public int DefaultPlacementDelayMs { get; set; } = 1000;
    
    /// <summary>
    /// Whether to enable adaptive visibility based on market conditions
    /// </summary>
    public bool EnableAdaptiveVisibility { get; set; } = false;
    
    /// <summary>
    /// Maximum visible quantity as percentage of total quantity
    /// </summary>
    public double MaxVisiblePercentage { get; set; } = 0.25; // 25%
    
    /// <summary>
    /// Minimum visible quantity as percentage of total quantity
    /// </summary>
    public double MinVisiblePercentage { get; set; } = 0.01; // 1%
    
    /// <summary>
    /// Whether to prioritize execution speed over impact reduction
    /// </summary>
    public bool PrioritizeSpeed { get; set; } = false;
    
    /// <summary>
    /// Retry count for failed order placements
    /// </summary>
    public int MaxRetries { get; set; } = 3;
    
    /// <summary>
    /// Delay between retries (in milliseconds)
    /// </summary>
    public int RetryDelayMs { get; set; } = 5000;
    
    /// <summary>
    /// Whether to use market depth analysis for visibility adjustment
    /// </summary>
    public bool EnableMarketDepthAnalysis { get; set; } = false;
    
    /// <summary>
    /// Whether to log detailed execution information
    /// </summary>
    public bool EnableDetailedLogging { get; set; } = false;
    
    public static IcebergConfig Default => new IcebergConfig();
}
```

## Iceberg Execution Models

### Iceberg Execution State
```csharp
/// <summary>
/// State of an Iceberg execution
/// </summary>
public record IcebergExecutionState
{
    /// <summary>
    /// Unique identifier for this Iceberg execution
    /// </summary>
    public string ExecutionId { get; set; } = Guid.NewGuid().ToString();
    
    /// <summary>
    /// Parameters used for this execution
    /// </summary>
    public IcebergParameters Parameters { get; set; }
    
    /// <summary>
    /// Current execution status
    /// </summary>
    public IcebergExecutionStatus Status { get; set; } = IcebergExecutionStatus.Pending;
    
    /// <summary>
    /// Total quantity to execute
    /// </summary>
    public int TotalQuantity { get; set; }
    
    /// <summary>
    /// Quantity already executed
    /// </summary>
    public int ExecutedQuantity { get; set; }
    
    /// <summary>
    /// Remaining quantity to execute
    /// </summary>
    public int RemainingQuantity => TotalQuantity - ExecutedQuantity;
    
    /// <summary>
    /// Currently visible quantity
    /// </summary>
    public int VisibleQuantity { get; set; }
    
    /// <summary>
    /// Currently displayed order (if any)
    /// </summary>
    public IcebergOrder DisplayedOrder { get; set; }
    
    /// <summary>
    /// All orders placed during execution
    /// </summary>
    public List<IcebergOrder> Orders { get; set; } = new List<IcebergOrder>();
    
    /// <summary>
    /// Completed orders
    /// </summary>
    public List<IcebergOrder> CompletedOrders { get; set; } = new List<IcebergOrder>();
    
    /// <summary>
    /// Failed orders
    /// </summary>
    public List<IcebergOrder> FailedOrders { get; set; } = new List<IcebergOrder>();
    
    /// <summary>
    /// Start time of execution
    /// </summary>
    public DateTime? StartTime { get; set; }
    
    /// <summary>
    /// End time of execution
    /// </summary>
    public DateTime? EndTime { get; set; }
    
    /// <summary>
    /// When this execution was created
    /// </summary>
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    
    /// <summary>
    /// When this execution was last updated
    /// </summary>
    public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
    
    /// <summary>
    /// Error information if execution failed
    /// </summary>
    public string ErrorMessage { get; set; }
    
    /// <summary>
    /// Performance metrics for this execution
    /// </summary>
    public IcebergPerformanceMetrics PerformanceMetrics { get; set; } = new IcebergPerformanceMetrics();
}
```

### Iceberg Order
```csharp
/// <summary>
/// Represents a single order placed as part of Iceberg execution
/// </summary>
public record IcebergOrder
{
    /// <summary>
    /// Unique identifier for this order
    /// </summary>
    public string OrderId { get; set; }
    
    /// <summary>
    /// Reference to parent Iceberg execution
    /// </summary>
    public string ExecutionId { get; set; }
    
    /// <summary>
    /// Order number within execution (1-based)
    /// </summary>
    public int OrderNumber { get; set; }
    
    /// <summary>
    /// Scheduled placement time
    /// </summary>
    public DateTime ScheduledTime { get; set; }
    
    /// <summary>
    /// Actual placement time
    /// </summary>
    public DateTime? ActualTime { get; set; }
    
    /// <summary>
    /// Quantity for this order
    /// </summary>
    public int Quantity { get; set; }
    
    /// <summary>
    /// Status of this order
    /// </summary>
    public IcebergOrderStatus Status { get; set; } = IcebergOrderStatus.Pending;
    
    /// <summary>
    /// Order details
    /// </summary>
    public OrderRequest OrderDetails { get; set; }
    
    /// <summary>
    /// Fills for this order
    /// </summary>
    public List<OrderFill> Fills { get; set; } = new List<OrderFill>();
    
    /// <summary>
    /// Total filled quantity
    /// </summary>
    public int FilledQuantity => Fills?.Sum(f => f.Quantity) ?? 0;
    
    /// <summary>
    /// Average fill price
    /// </summary>
    public decimal AverageFillPrice => Fills?.Any() == true ? 
        Fills.Sum(f => f.Quantity * f.FillPrice) / FilledQuantity : 0;
    
    /// <summary>
    /// Total commission for this order
    /// </summary>
    public decimal TotalCommission => Fills?.Sum(f => f.Commission) ?? 0;
    
    /// <summary>
    /// Error information if order failed
    /// </summary>
    public string ErrorMessage { get; set; }
    
    /// <summary>
    /// Retry count for this order
    /// </summary>
    public int RetryCount { get; set; }
    
    /// <summary>
    /// Whether this order was cancelled
    /// </summary>
    public bool WasCancelled { get; set; }
    
    /// <summary>
    /// When this order was created
    /// </summary>
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    
    /// <summary>
    /// When this order was last updated
    /// </summary>
    public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}
```

### Iceberg Performance Metrics
```csharp
/// <summary>
/// Performance metrics for Iceberg execution
/// </summary>
public record IcebergPerformanceMetrics
{
    /// <summary>
    /// Total execution time
    /// </summary>
    public TimeSpan TotalExecutionTime { get; set; }
    
    /// <summary>
    /// Average fill price
    /// </summary>
    public decimal AverageFillPrice { get; set; }
    
    /// <summary>
    /// Slippage (percentage)
    /// </summary>
    public decimal Slippage { get; set; }
    
    /// <summary>
    /// Implementation shortfall (percentage)
    /// </summary>
    public decimal ImplementationShortfall { get; set; }
    
    /// <summary>
    /// Number of order placements
    /// </summary>
    public int TotalOrders { get; set; }
    
    /// <summary>
    /// Number of successful orders
    /// </summary>
    public int SuccessfulOrders { get; set; }
    
    /// <summary>
    /// Number of failed orders
    /// </summary>
    public int FailedOrders { get; set; }
    
    /// <summary>
    /// Number of cancelled orders
    /// </summary>
    public int CancelledOrders { get; set; }
    
    /// <summary>
    /// Average visible quantity as percentage of total
    /// </summary>
    public decimal AverageVisibility { get; set; }
    
    /// <summary>
    /// Total commission paid
    /// </summary>
    public decimal TotalCommission { get; set; }
    
    /// <summary>
    /// When metrics were last updated
    /// </summary>
    public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}
```

### Enums
```csharp
/// <summary>
/// Status of Iceberg execution
/// </summary>
public enum IcebergExecutionStatus
{
    Pending,
    Running,
    Completed,
    Cancelled,
    Failed
}

/// <summary>
/// Status of Iceberg order
/// </summary>
public enum IcebergOrderStatus
{
    Pending,
    Scheduled,
    Submitted,
    PartiallyFilled,
    Filled,
    Cancelled,
    Failed
}
```

## Iceberg Algorithm Implementation

### Iceberg Executor
```csharp
/// <summary>
/// Executes Iceberg algorithms
/// </summary>
public class IcebergExecutor
{
    private readonly ILogger<IcebergExecutor> _logger;
    private readonly IOrderManager _orderManager;
    private readonly IMarketDataProvider _marketDataProvider;
    private readonly IcebergConfig _config;
    private readonly Dictionary<string, IcebergExecutionState> _executions;
    private readonly Dictionary<string, CancellationTokenSource> _executionCancellations;
    private readonly object _lock = new object();
    
    public IcebergExecutor(
        ILogger<IcebergExecutor> logger,
        IOrderManager orderManager,
        IMarketDataProvider marketDataProvider,
        IcebergConfig config = null)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        _orderManager = orderManager ?? throw new ArgumentNullException(nameof(orderManager));
        _marketDataProvider = marketDataProvider ?? throw new ArgumentNullException(nameof(marketDataProvider));
        _config = config ?? IcebergConfig.Default;
        _executions = new Dictionary<string, IcebergExecutionState>();
        _executionCancellations = new Dictionary<string, CancellationTokenSource>();
    }
    
    /// <summary>
    /// Execute an Iceberg order
    /// </summary>
    public async Task<IcebergExecutionState> ExecuteIcebergAsync(IcebergParameters parameters, StrategyContext context)
    {
        if (parameters == null) throw new ArgumentNullException(nameof(parameters));
        if (context == null) throw new ArgumentNullException(nameof(context));
        
        // Validate parameters
        ValidateParameters(parameters);
        
        // Create execution state
        var executionState = CreateExecutionState(parameters);
        
        lock (_lock)
        {
            _executions[executionState.ExecutionId] = executionState;
        }
        
        _logger.LogInformation("Starting Iceberg execution {ExecutionId} for {Symbol} {Side} {Quantity} (visible: {VisibleQuantity})", 
            executionState.ExecutionId, parameters.Symbol, parameters.Side, parameters.TotalQuantity, parameters.VisibleQuantity);
        
        try
        {
            // Start execution
            await StartExecutionAsync(executionState, context);
            
            return executionState;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error starting Iceberg execution {ExecutionId}", executionState.ExecutionId);
            
            executionState.Status = IcebergExecutionStatus.Failed;
            executionState.ErrorMessage = ex.Message;
            executionState.UpdatedAt = DateTime.UtcNow;
            
            throw;
        }
    
    private void ValidateParameters(IcebergParameters parameters)
    {
        if (string.IsNullOrEmpty(parameters.Symbol))
            throw new ArgumentException("Symbol is required", nameof(parameters));
            
        if (parameters.TotalQuantity <= 0)
            throw new ArgumentException("Total quantity must be positive", nameof(parameters));
            
        if (parameters.VisibleQuantity <= 0)
            throw new ArgumentException("Visible quantity must be positive", nameof(parameters));
            
        if (parameters.VisibleQuantity > parameters.TotalQuantity)
            throw new ArgumentException("Visible quantity cannot exceed total quantity", nameof(parameters));
            
        if (parameters.PlacementDelayMs < 0)
            throw new ArgumentException("Placement delay must be non-negative", nameof(parameters));
    }
    
    private IcebergExecutionState CreateExecutionState(IcebergParameters parameters)
    {
        var executionState = new IcebergExecutionState
        {
            Parameters = parameters,
            TotalQuantity = parameters.TotalQuantity,
            VisibleQuantity = parameters.VisibleQuantity,
            StartTime = DateTime.UtcNow
        };
        
        return executionState;
    }
    
    private async Task StartExecutionAsync(IcebergExecutionState executionState, StrategyContext context)
    {
        executionState.Status = IcebergExecutionStatus.Running;
        executionState.StartTime = DateTime.UtcNow;
        executionState.UpdatedAt = DateTime.UtcNow;
        
        // Create cancellation token for this execution
        var cancellationTokenSource = new CancellationTokenSource();
        lock (_lock)
        {
            _executionCancellations[executionState.ExecutionId] = cancellationTokenSource;
        }
        
        // Start execution loop
        _ = ExecuteIcebergLoopAsync(executionState, context, cancellationTokenSource.Token);
        
        _logger.LogInformation("Iceberg execution {ExecutionId} started", executionState.ExecutionId);
    }
    
    private async Task ExecuteIcebergLoopAsync(IcebergExecutionState executionState, StrategyContext context, CancellationToken cancellationToken)
    {
        try
        {
            while (executionState.RemainingQuantity > 0 && !cancellationToken.IsCancellationRequested)
            {
                // Check if we should place a new order
                if (executionState.DisplayedOrder == null || 
                    executionState.DisplayedOrder.Status == IcebergOrderStatus.Filled ||
                    executionState.DisplayedOrder.Status == IcebergOrderStatus.Cancelled ||
                    executionState.DisplayedOrder.Status == IcebergOrderStatus.Failed)
                {
                    // Place new order
                    await PlaceNextOrderAsync(executionState, context);
                }
                else if (executionState.DisplayedOrder.Status == IcebergOrderStatus.Submitted ||
                         executionState.DisplayedOrder.Status == IcebergOrderStatus.PartiallyFilled)
                {
                    // Monitor existing order
                    await MonitorOrderAsync(executionState, context);
                }
                
                // Wait before next iteration
                await Task.Delay(executionState.Parameters.PlacementDelayMs, cancellationToken);
            }
            
            // Complete execution
            await CompleteExecutionAsync(executionState);
        }
        catch (OperationCanceledException)
        {
            // Execution was cancelled
            _logger.LogInformation("Iceberg execution {ExecutionId} was cancelled", executionState.ExecutionId);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error in Iceberg execution loop {ExecutionId}", executionState.ExecutionId);
            executionState.Status = IcebergExecutionStatus.Failed;
            executionState.ErrorMessage = ex.Message;
            executionState.UpdatedAt = DateTime.UtcNow;
        }
    }
    
    private async Task PlaceNextOrderAsync(IcebergExecutionState executionState, StrategyContext context)
    {
        // Calculate order size
        var orderSize = Math.Min(executionState.VisibleQuantity, executionState.RemainingQuantity);
        if (orderSize <= 0)
        {
            return;
        }
        
        // Adjust visible quantity if adaptive
        if (executionState.Parameters.AdaptiveVisibility)
        {
            orderSize = await AdjustVisibleQuantityAsync(executionState, orderSize);
        }
        
        var orderNumber = executionState.Orders.Count + 1;
        
        var order = new IcebergOrder
        {
            ExecutionId = executionState.ExecutionId,
            OrderNumber = orderNumber,
            ScheduledTime = DateTime.UtcNow,
            Quantity = orderSize,
            OrderDetails = new OrderRequest(
                Symbol: executionState.Parameters.Symbol,
                Side: executionState.Parameters.Side,
                Type: executionState.Parameters.LimitPrice.HasValue ? OrderType.Limit : OrderType.Market,
                Quantity: orderSize,
                LimitPrice: executionState.Parameters.LimitPrice,
                StopPrice: null,
                TimeInForce: executionState.Parameters.TimeInForce,
                Algorithm: null,
                AlgorithmParameters: new Dictionary<string, object>()
            )
        };
        
        executionState.Orders.Add(order);
        executionState.DisplayedOrder = order;
        
        try
        {
            order.Status = IcebergOrderStatus.Submitted;
            order.ActualTime = DateTime.UtcNow;
            order.UpdatedAt = DateTime.UtcNow;
            
            _logger.LogInformation("Placing Iceberg order {OrderNumber} for {Quantity} (remaining: {Remaining})", 
                orderNumber, orderSize, executionState.RemainingQuantity);
            
            // Submit order
            var orderResult = await _orderManager.SubmitOrderAsync(order.OrderDetails, context);
            
            if (orderResult.Success)
            {
                order.OrderId = orderResult.OrderId;
                order.Status = IcebergOrderStatus.Submitted;
                order.UpdatedAt = DateTime.UtcNow;
                
                _logger.LogInformation("Iceberg order {OrderNumber} submitted: {OrderId}", 
                    orderNumber, orderResult.OrderId);
            }
            else
            {
                order.Status = IcebergOrderStatus.Failed;
                order.ErrorMessage = orderResult.Message;
                order.UpdatedAt = DateTime.UtcNow;
                
                _logger.LogWarning("Iceberg order {OrderNumber} failed: {ErrorMessage}", 
                    orderNumber, orderResult.Message);
                
                // Handle retry if configured
                if (order.RetryCount < _config.MaxRetries)
                {
                    order.RetryCount++;
                    _logger.LogInformation("Retrying Iceberg order {OrderNumber} (attempt {RetryCount})", 
                        orderNumber, order.RetryCount);
                    
                    await Task.Delay(_config.RetryDelayMs);
                    await PlaceNextOrderAsync(executionState, context);
                    return;
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error placing Iceberg order {OrderNumber}", orderNumber);
            
            order.Status = IcebergOrderStatus.Failed;
            order.ErrorMessage = ex.Message;
            order.UpdatedAt = DateTime.UtcNow;
        }
        
        UpdateExecutionState(executionState, order);
    }
    
    private async Task<int> AdjustVisibleQuantityAsync(IcebergExecutionState executionState, int currentVisibleQuantity)
    {
        if (!_config.EnableAdaptiveVisibility)
            return currentVisibleQuantity;
            
        // Get market depth information
        var marketDepth = await GetMarketDepthAsync(executionState.Parameters.Symbol);
        if (marketDepth == null)
            return currentVisibleQuantity;
            
        // Adjust based on market depth
        var adjustedQuantity = currentVisibleQuantity;
        
        // If there's good liquidity at our price level, we can be more aggressive
        if (executionState.Parameters.Side == OrderSide.Buy)
        {
            var askDepth = marketDepth.Asks.FirstOrDefault()?.Size ?? 0;
            if (askDepth > currentVisibleQuantity * 5) // 5x our size available
            {
                adjustedQuantity = Math.Min(currentVisibleQuantity * 2, executionState.VisibleQuantity);
            }
        }
        else
        {
            var bidDepth = marketDepth.Bids.FirstOrDefault()?.Size ?? 0;
            if (bidDepth > currentVisibleQuantity * 5) // 5x our size available
            {
                adjustedQuantity = Math.Min(currentVisibleQuantity * 2, executionState.VisibleQuantity);
            }
        }
        
        // Ensure we don't exceed configured limits
        var maxVisible = executionState.Parameters.MaxVisibleQuantity ?? 
            (int)(executionState.TotalQuantity * _config.MaxVisiblePercentage);
        var minVisible = Math.Max(executionState.Parameters.MinVisibleQuantity,
            (int)(executionState.TotalQuantity * _config.MinVisiblePercentage));
            
        if (adjustedQuantity > maxVisible)
            adjustedQuantity = maxVisible;
            
        if (adjustedQuantity < minVisible)
            adjustedQuantity = minVisible;
            
        return adjustedQuantity;
    }
    
    private async Task<MarketDepth> GetMarketDepthAsync(string symbol)
    {
        // In a real implementation, this would get real-time market depth data
        // For now, we'll return null to indicate no adjustment
        return null;
    }
    
    private async Task MonitorOrderAsync(IcebergExecutionState executionState, StrategyContext context)
    {
        if (executionState.DisplayedOrder == null)
            return;
            
        // In a real implementation, we would monitor the order status
        // For now, we'll simulate order completion
        var random = new Random();
        if (random.NextDouble() < 0.3) // 30% chance of order completion each cycle
        {
            // Simulate order fill
            executionState.DisplayedOrder.Status = IcebergOrderStatus.Filled;
            executionState.DisplayedOrder.Fills.Add(new OrderFill
            {
                OrderId = executionState.DisplayedOrder.OrderId,
                Symbol = executionState.Parameters.Symbol,
                Quantity = executionState.DisplayedOrder.Quantity,
                FillPrice = executionState.Parameters.LimitPrice ?? 100, // Simulated price
                FillTime = DateTime.UtcNow,
                Commission = executionState.DisplayedOrder.Quantity * 0.5m, // Simulated commission
                ExecutionId = Guid.NewGuid().ToString()
            });
            
            executionState.DisplayedOrder.UpdatedAt = DateTime.UtcNow;
            UpdateExecutionState(executionState, executionState.DisplayedOrder);
        }
    }
    
    private void UpdateExecutionState(IcebergExecutionState executionState, IcebergOrder order)
    {
        lock (_lock)
        {
            // Update executed quantity
            executionState.ExecutedQuantity = executionState.Orders
                .Where(o => o.Status == IcebergOrderStatus.Filled)
                .Sum(o => o.FilledQuantity);
                
            // Move order to appropriate list
            if (order.Status == IcebergOrderStatus.Filled)
            {
                executionState.CompletedOrders.Add(order);
                executionState.DisplayedOrder = null; // Clear displayed order
            }
            else if (order.Status == IcebergOrderStatus.Failed)
            {
                executionState.FailedOrders.Add(order);
            }
            
            // Update execution metrics
            UpdatePerformanceMetrics(executionState);
            
            // Check if execution is complete
            if (executionState.RemainingQuantity <= 0)
            {
                _ = CompleteExecutionAsync(executionState);
            }
            
            executionState.UpdatedAt = DateTime.UtcNow;
        }
    }
    
    private void UpdatePerformanceMetrics(IcebergExecutionState executionState)
    {
        var metrics = new IcebergPerformanceMetrics();
        
        // Calculate basic metrics
        var allOrders = executionState.Orders;
        if (allOrders.Any())
        {
            metrics.TotalOrders = allOrders.Count;
            metrics.SuccessfulOrders = executionState.CompletedOrders.Count;
            metrics.FailedOrders = executionState.FailedOrders.Count;
            metrics.TotalCommission = allOrders.Sum(o => o.TotalCommission);
            
            // Calculate average visibility
            if (executionState.TotalQuantity > 0)
            {
                metrics.AverageVisibility = (decimal)(executionState.VisibleQuantity / (double)executionState.TotalQuantity);
            }
            
            // Calculate average fill price
            var totalValue = allOrders.Where(o => o.Status == IcebergOrderStatus.Filled)
                .Sum(o => o.FilledQuantity * (double)o.AverageFillPrice);
            var totalQuantity = allOrders.Where(o => o.Status == IcebergOrderStatus.Filled)
                .Sum(o => o.FilledQuantity);
                
            if (totalQuantity > 0)
            {
                metrics.AverageFillPrice = (decimal)(totalValue / totalQuantity);
            }
        }
        
        executionState.PerformanceMetrics = metrics;
    }
    
    private async Task CompleteExecutionAsync(IcebergExecutionState executionState)
    {
        if (executionState.RemainingQuantity <= 0)
        {
            executionState.Status = IcebergExecutionStatus.Completed;
            _logger.LogInformation("Iceberg execution {ExecutionId} completed successfully", executionState.ExecutionId);
        }
        else
        {
            executionState.Status = IcebergExecutionStatus.Failed;
            _logger.LogWarning("Iceberg execution {ExecutionId} completed with remaining quantity", executionState.ExecutionId);
        }
        
        executionState.EndTime = DateTime.UtcNow;
        executionState.UpdatedAt = DateTime.UtcNow;
        
        // Cancel any remaining displayed order if configured
        if (executionState.Parameters.CancelAtEnd && executionState.DisplayedOrder != null)
        {
            await CancelDisplayedOrderAsync(executionState);
        }
        
        // Clean up cancellation token
        lock (_lock)
        {
            if (_executionCancellations.ContainsKey(executionState.ExecutionId))
            {
                _executionCancellations[executionState.ExecutionId].Dispose();
                _executionCancellations.Remove(executionState.ExecutionId);
            }
        }
    }
    
    private async Task CancelDisplayedOrderAsync(IcebergExecutionState executionState)
    {
        if (executionState.DisplayedOrder?.OrderId != null)
        {
            try
            {
                await _orderManager.CancelOrderAsync(executionState.DisplayedOrder.OrderId);
                executionState.DisplayedOrder.Status = IcebergOrderStatus.Cancelled;
                executionState.DisplayedOrder.WasCancelled = true;
                executionState.DisplayedOrder.UpdatedAt = DateTime.UtcNow;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error cancelling displayed Iceberg order {OrderId}", 
                    executionState.DisplayedOrder.OrderId);
            }
        }
    }
    
    /// <summary>
    /// Cancel an Iceberg execution
    /// </summary>
    public async Task<bool> CancelExecutionAsync(string executionId)
    {
        if (string.IsNullOrEmpty(executionId)) throw new ArgumentException("Execution ID required", nameof(executionId));
        
        IcebergExecutionState executionState;
        CancellationTokenSource cancellationTokenSource;
        
        lock (_lock)
        {
            if (!_executions.ContainsKey(executionId))
                return false;
                
            executionState = _executions[executionId];
            
            if (!_executionCancellations.ContainsKey(executionId))
                return false;
                
            cancellationTokenSource = _executionCancellations[executionId];
        }
        
        if (executionState.Status != IcebergExecutionStatus.Running)
            return false;
        
        try
        {
            // Cancel the execution loop
            cancellationTokenSource.Cancel();
            
            // Cancel any displayed order
            await CancelDisplayedOrderAsync(executionState);
            
            // Update execution state
            executionState.Status = IcebergExecutionStatus.Cancelled;
            executionState.EndTime = DateTime.UtcNow;
            executionState.UpdatedAt = DateTime.UtcNow;
            
            _logger.LogInformation("Iceberg execution {ExecutionId} cancelled", executionId);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error cancelling Iceberg execution {ExecutionId}", executionId);
            return false;
        }
    }
    
    /// <summary>
    /// Get execution state
    /// </summary>
    public IcebergExecutionState GetExecutionState(string executionId)
    {
        if (string.IsNullOrEmpty(executionId)) return null;
        
        lock (_lock)
        {
            return _executions.ContainsKey(executionId) ? 
                new IcebergExecutionState(_executions[executionId]) : null;
        }
    }
    
    /// <summary>
    /// Get all execution states
    /// </summary>
    public List<IcebergExecutionState> GetAllExecutionStates()
    {
        lock (_lock)
        {
            return _executions.Values.Select(e => new IcebergExecutionState(e)).ToList();
        }
    }
}
```

## Integration with OrderManager

### Iceberg Integration in OrderManager
```csharp
public partial class OrderManager : IOrderManager
{
    private readonly IcebergExecutor _icebergExecutor;
    
    // Enhanced constructor with Iceberg executor
    public OrderManager(
        IRiskManager riskManager,
        IPositionSizer positionSizer,
        ILogger<OrderManager> logger,
        RoutingConfigurationManager configManager,
        RoutingMetricsCollector metricsCollector,
        TwapExecutor twapExecutor,
        VwapExecutor vwapExecutor,
        IcebergExecutor icebergExecutor) : base(riskManager, positionSizer, logger, configManager, metricsCollector, twapExecutor, vwapExecutor)
    {
        _icebergExecutor = icebergExecutor ?? throw new ArgumentNullException(nameof(icebergExecutor));
        _venueManager = new VenueManager(logger);
        _omsToVenueOrderIdMap = new Dictionary<string, string>();
        _venueToOmsOrderIdMap = new Dictionary<string, string>();
        
        // Initialize with configurations
        InitializeWithConfigurationsAsync().Wait();
    }
    
    /// <summary>
    /// Execute an Iceberg order
    /// </summary>
    public async Task<OrderResult> ExecuteIcebergAsync(IcebergParameters parameters, StrategyContext context)
    {
        if (parameters == null) throw new ArgumentNullException(nameof(parameters));
        if (context == null) throw new ArgumentNullException(nameof(context));
        
        try
        {
            _logger.LogInformation("Executing Iceberg order for {Symbol} {Side} {Quantity} (visible: {VisibleQuantity})", 
                parameters.Symbol, parameters.Side, parameters.TotalQuantity, parameters.VisibleQuantity);
            
            // Validate through risk management
            var riskDecision = await ValidateIcebergOrderAsync(parameters, context);
            if (!riskDecision.Allow)
            {
                _logger.LogWarning("Iceberg order rejected by risk management: {Reason}", riskDecision.RejectReason);
                return new OrderResult(false, null, $"Risk validation failed: {riskDecision.RejectReason}", null);
            }
            
            // Execute Iceberg
            var executionState = await _icebergExecutor.ExecuteIcebergAsync(parameters, context);
            
            // Create order result
            var orderResult = new OrderResult(
                Success: executionState.Status == IcebergExecutionStatus.Completed,
                OrderId: executionState.ExecutionId,
                Message: executionState.Status == IcebergExecutionStatus.Completed ? 
                    "Iceberg execution completed successfully" : 
                    $"Iceberg execution failed: {executionState.ErrorMessage}",
                Status: ConvertToOrderStatus(executionState)
            );
            
            _logger.LogInformation("Iceberg order execution {Result}: {Message}", 
                orderResult.Success ? "succeeded" : "failed", orderResult.Message);
            
            return orderResult;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error executing Iceberg order for {Symbol}", parameters.Symbol);
            return new OrderResult(false, null, $"Error executing Iceberg order: {ex.Message}", null);
        }
    }
    
    private async Task<RiskDecision> ValidateIcebergOrderAsync(IcebergParameters parameters, StrategyContext context)
    {
        // Convert Iceberg parameters to strategy intent for risk validation
        var intent = new StrategyIntent(
            Symbol: parameters.Symbol,
            Side: ConvertOrderSide(parameters.Side),
            EntryType: parameters.LimitPrice.HasValue ? OrderType.Limit : OrderType.Market,
            LimitPrice: (double?)parameters.LimitPrice,
            StopTicks: 10, // Placeholder - would calculate based on stop price
            TargetTicks: null,
            Confidence: 1.0,
            Reason: "Iceberg Algorithm Order",
            Metadata: parameters.Metadata
        );
        
        // Get risk configuration
        var config = new RiskConfig(1000, 200, 10, true); // Placeholder - would get from configuration
        
        return _riskManager.ValidateOrder(intent, context, config);
    }
    
    private OrderStatus ConvertToOrderStatus(IcebergExecutionState executionState)
    {
        if (executionState == null) return null;
        
        var state = executionState.Status switch
        {
            IcebergExecutionStatus.Pending => OrderState.New,
            IcebergExecutionStatus.Running => OrderState.Accepted,
            IcebergExecutionStatus.Completed => OrderState.Filled,
            IcebergExecutionStatus.Cancelled => OrderState.Cancelled,
            IcebergExecutionStatus.Failed => OrderState.Rejected,
            _ => OrderState.Unknown
        };
        
        // Combine all fills from completed orders
        var allFills = executionState.Orders.SelectMany(o => o.Fills).ToList();
        
        return new OrderStatus(
            OrderId: executionState.ExecutionId,
            Symbol: executionState.Parameters.Symbol,
            Side: executionState.Parameters.Side,
            Type: executionState.Parameters.LimitPrice.HasValue ? OrderType.Limit : OrderType.Market,
            Quantity: executionState.TotalQuantity,
            FilledQuantity: executionState.ExecutedQuantity,
            LimitPrice: executionState.Parameters.LimitPrice,
            StopPrice: null,
            State: state,
            CreatedTime: executionState.CreatedAt,
            FilledTime: executionState.EndTime,
            Fills: allFills
        );
    }
    
    /// <summary>
    /// Cancel an Iceberg execution
    /// </summary>
    public async Task<bool> CancelIcebergAsync(string executionId)
    {
        if (string.IsNullOrEmpty(executionId)) throw new ArgumentException("Execution ID required", nameof(executionId));
        
        return await _icebergExecutor.CancelExecutionAsync(executionId);
    }
    
    /// <summary>
    /// Get Iceberg execution state
    /// </summary>
    public IcebergExecutionState GetIcebergExecutionState(string executionId)
    {
        if (string.IsNullOrEmpty(executionId)) return null;
        
        return _icebergExecutor.GetExecutionState(executionId);
    }
}
```

## Iceberg Configuration Management

### Iceberg Configuration Integration
```csharp
public partial class RoutingConfigurationManager
{
    /// <summary>
    /// Get Iceberg configuration
    /// </summary>
    public async Task<IcebergConfig> GetIcebergConfigAsync()
    {
        var config = await GetConfigurationAsync<IcebergConfig>("iceberg-config");
        return config ?? IcebergConfig.Default;
    }
    
    /// <summary>
    /// Update Iceberg configuration
    /// </summary>
    public async Task UpdateIcebergConfigAsync(IcebergConfig config)
    {
        if (config == null) throw new ArgumentNullException(nameof(config));
        
        config.Id = "iceberg-config";
        config.Name = "Iceberg Configuration";
        config.Description = "Configuration for Iceberg algorithm behavior";
        
        await UpdateConfigurationAsync(config);
        _logger.LogInformation("Iceberg configuration updated");
    }
}
```

## Testing Considerations

### Unit Tests for Iceberg Algorithm
1. **Order Size Calculation**: Test calculation of order sizes based on visible quantity
2. **Parameter Validation**: Test validation of Iceberg parameters
3. **Order Placement**: Test placement of individual orders
4. **Order Monitoring**: Test monitoring of order status and fills
5. **Error Handling**: Test handling of execution errors and retries
6. **Cancellation**: Test cancellation of Iceberg executions
7. **Metrics Collection**: Test collection of performance metrics
8. **Visibility Adjustment**: Test adjustment of visible quantity based on market conditions

### Integration Tests
1. **End-to-End Execution**: Test complete Iceberg execution from start to finish
2. **Order Manager Integration**: Test integration with OrderManager
3. **Risk Management Integration**: Test risk validation for Iceberg orders
4. **Market Data Integration**: Test integration with market data providers
5. **Performance Testing**: Test performance with large order sizes
6. **Concurrent Executions**: Test multiple concurrent Iceberg executions

## Performance Considerations

### Memory Management
```csharp
/// <summary>
/// Manages memory usage for Iceberg executions
/// </summary>
public class IcebergMemoryManager
{
    private readonly int _maxExecutions;
    private readonly TimeSpan _executionRetentionTime;
    private readonly Dictionary<string, DateTime> _executionAccessTimes;
    private readonly object _lock = new object();
    
    public IcebergMemoryManager(int maxExecutions = 1000, TimeSpan retentionTime = default)
    {
        _maxExecutions = maxExecutions;
        _executionRetentionTime = retentionTime == default ? 
            TimeSpan.FromHours(24) : retentionTime;
        _executionAccessTimes = new Dictionary<string, DateTime>();
    }
    
    public void RecordExecutionAccess(string executionId)
    {
        lock (_lock)
        {
            _executionAccessTimes[executionId] = DateTime.UtcNow;
        }
    }
    
    public List<string> GetExpiredExecutions()
    {
        var cutoffTime = DateTime.UtcNow.Subtract(_executionRetentionTime);
        
        lock (_lock)
        {
            return _executionAccessTimes
                .Where(kvp => kvp.Value < cutoffTime)
                .Select(kvp => kvp.Key)
                .ToList();
        }
    }
    
    public bool IsMemoryPressureHigh(int currentExecutionCount)
    {
        return currentExecutionCount > (_maxExecutions * 0.8); // 80% threshold
    }
}
```

### Adaptive Iceberg
```csharp
/// <summary>
/// Adaptive Iceberg that adjusts based on market conditions
/// </summary>
public class AdaptiveIcebergExecutor : IcebergExecutor
{
    private readonly IMarketAnalyzer _marketAnalyzer;
    
    public AdaptiveIcebergExecutor(
        ILogger<IcebergExecutor> logger,
        IOrderManager orderManager,
        IMarketDataProvider marketDataProvider,
        IMarketAnalyzer marketAnalyzer,
        IcebergConfig config = null) : base(logger, orderManager, marketDataProvider, config)
    {
        _marketAnalyzer = marketAnalyzer ?? throw new ArgumentNullException(nameof(marketAnalyzer));
    }
    
    protected override async Task<int> AdjustVisibleQuantityAsync(IcebergExecutionState executionState, int currentVisibleQuantity)
    {
        if (!_config.EnableAdaptiveVisibility || _marketAnalyzer == null)
            return await base.AdjustVisibleQuantityAsync(executionState, currentVisibleQuantity);
            
        try
        {
            var marketConditions = await _marketAnalyzer.AnalyzeMarketConditionsAsync(
                executionState.Parameters.Symbol);
                
            var adjustedQuantity = currentVisibleQuantity;
            
            // Adjust based on market volatility
            if (marketConditions.Volatility > 0.02m) // High volatility (2%+)
            {
                // Reduce visibility in volatile markets
                adjustedQuantity = (int)(currentVisibleQuantity * 0.7);
            }
            else if (marketConditions.Volatility < 0.005m) // Low volatility (<0.5%)
            {
                // Increase visibility in stable markets
                adjustedQuantity = (int)(currentVisibleQuantity * 1.3);
            }
            
            // Adjust based on liquidity
            if (marketConditions.Liquidity < 0.3) // Low liquidity
            {
                // Reduce visibility in illiquid markets
                adjustedQuantity = Math.Min(adjustedQuantity, (int)(currentVisibleQuantity * 0.5));
            }
            
            // Ensure we don't exceed configured limits
            var maxVisible = executionState.Parameters.MaxVisibleQuantity ?? 
                (int)(executionState.TotalQuantity * _config.MaxVisiblePercentage);
            var minVisible = Math.Max(executionState.Parameters.MinVisibleQuantity,
                (int)(executionState.TotalQuantity * _config.MinVisiblePercentage));
                
            if (adjustedQuantity > maxVisible)
                adjustedQuantity = maxVisible;
                
            if (adjustedQuantity < minVisible)
                adjustedQuantity = minVisible;
                
            return adjustedQuantity;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error adjusting visible quantity for {Symbol}", executionState.Parameters.Symbol);
            return await base.AdjustVisibleQuantityAsync(executionState, currentVisibleQuantity);
        }
    }
}

/// <summary>
/// Interface for market analysis
/// </summary>
public interface IMarketAnalyzer
{
    /// <summary>
    /// Analyze current market conditions for a symbol
    /// </summary>
    Task<MarketConditions> AnalyzeMarketConditionsAsync(string symbol);
}

/// <summary>
/// Market conditions analysis result
/// </summary>
public record MarketConditions
{
    public string Symbol { get; set; }
    public decimal Volatility { get; set; } // 0.0 to 1.0
    public decimal Liquidity { get; set; } // 0.0 to 1.0
    public MarketTrend Trend { get; set; }
    public decimal Spread { get; set; }
    public DateTime AnalysisTime { get; set; }
}

/// <summary>
/// Market trend enumeration
/// </summary>
public enum MarketTrend
{
    Up,
    Down,
    Sideways
}
```

## Monitoring and Alerting

### Iceberg Metrics Export
```csharp
/// <summary>
/// Exports Iceberg metrics for monitoring
/// </summary>
public class IcebergMetricsExporter
{
    private readonly IcebergExecutor _icebergExecutor;
    
    public IcebergMetricsExporter(IcebergExecutor icebergExecutor)
    {
        _icebergExecutor = icebergExecutor ?? throw new ArgumentNullException(nameof(icebergExecutor));
    }
    
    public string ExportToPrometheus()
    {
        var executions = _icebergExecutor.GetAllExecutionStates();
        var sb = new StringBuilder();
        
        // Overall Iceberg metrics
        var activeExecutions = executions.Count(e => e.Status == IcebergExecutionStatus.Running);
        var completedExecutions = executions.Count(e => e.Status == IcebergExecutionStatus.Completed);
        var failedExecutions = executions.Count(e => e.Status == IcebergExecutionStatus.Failed);
        
        sb.AppendLine($"# HELP iceberg_active_executions Number of active Iceberg executions");
        sb.AppendLine($"# TYPE iceberg_active_executions gauge");
        sb.AppendLine($"iceberg_active_executions {activeExecutions}");
        
        sb.AppendLine($"# HELP iceberg_completed_executions Total number of completed Iceberg executions");
        sb.AppendLine($"# TYPE iceberg_completed_executions counter");
        sb.AppendLine($"iceberg_completed_executions {completedExecutions}");
        
        sb.AppendLine($"# HELP iceberg_failed_executions Total number of failed Iceberg executions");
        sb.AppendLine($"# TYPE iceberg_failed_executions counter");
        sb.AppendLine($"iceberg_failed_executions {failedExecutions}");
        
        // Performance metrics for completed executions
        var completed = executions.Where(e => e.Status == IcebergExecutionStatus.Completed).ToList();
        if (completed.Any())
        {
            var avgSlippage = completed.Average(e => (double)e.PerformanceMetrics.Slippage);
            var avgCommission = (double)completed.Average(e => e.PerformanceMetrics.TotalCommission);
            var avgVisibility = completed.Average(e => (double)e.PerformanceMetrics.AverageVisibility);
            
            sb.AppendLine($"# HELP iceberg_average_slippage Average slippage for completed executions");
            sb.AppendLine($"# TYPE iceberg_average_slippage gauge");
            sb.AppendLine($"iceberg_average_slippage {avgSlippage:F4}");
            
            sb.AppendLine($"# HELP iceberg_average_commission Average commission for completed executions");
            sb.AppendLine($"# TYPE iceberg_average_commission gauge");
            sb.AppendLine($"iceberg_average_commission {avgCommission:F2}");
            
            sb.AppendLine($"# HELP iceberg_average_visibility Average visibility for completed executions");
            sb.AppendLine($"# TYPE iceberg_average_visibility gauge");
            sb.AppendLine($"iceberg_average_visibility {avgVisibility:F4}");
        }
        
        return sb.ToString();
    }
}
```

## Future Enhancements

1. **Machine Learning Optimization**: Use ML to optimize Iceberg parameters based on historical performance
2. **Real-time Market Adaptation**: Adjust Iceberg execution based on real-time market conditions
3. **Cross-Venue Iceberg**: Execute Iceberg orders across multiple venues simultaneously
4. **Iceberg Analytics**: Advanced analytics and reporting on Iceberg performance
5. **Iceberg Strategy Builder**: Visual tools for building and testing Iceberg strategies
6. **Iceberg Benchmarking**: Compare Iceberg performance against other execution algorithms
7. **Iceberg Risk Controls**: Enhanced risk controls specific to algorithmic execution
8. **Iceberg Compliance**: Ensure Iceberg execution complies with regulatory requirements
9. **Smart Iceberg**: Iceberg orders that adapt visibility based on fill patterns
10. **Iceberg with TWAP/VWAP**: Hybrid algorithms combining Iceberg with other strategies
