# Order Types Implementation Design

## Overview

This document details the implementation of support for different order types in the Order Management System (OMS): Market, Limit, StopMarket, and StopLimit orders.

## Order Type Definitions

### Market Orders
Market orders are executed immediately at the best available price in the market. They guarantee execution but not price.

### Limit Orders
Limit orders specify the maximum price the buyer is willing to pay (for buy orders) or the minimum price the seller is willing to accept (for sell orders). They guarantee price but not execution.

### Stop Market Orders
Stop market orders become market orders when the stop price is reached or penetrated. They are used to limit losses or protect profits.

### Stop Limit Orders
Stop limit orders become limit orders when the stop price is reached or penetrated. They combine features of stop orders and limit orders.

## Implementation Approach

The OMS will support all four order types through a unified interface while maintaining the specific characteristics of each type.

## Data Models

### Extended OrderRequest
```csharp
/// <summary>
/// Extended order request with support for all order types
/// </summary>
public record OrderRequest(
    string Symbol,
    OrderSide Side,
    OrderType Type,
    int Quantity,
    decimal? LimitPrice,
    decimal? StopPrice,
    TimeInForce TimeInForce,
    string Algorithm, // TWAP, VWAP, Iceberg, or null for regular order
    Dictionary<string, object> AlgorithmParameters
)
{
    /// <summary>
    /// Validates the order request based on order type
    /// </summary>
    public bool IsValid(out List<string> errors)
    {
        errors = new List<string>();
        
        // All orders need symbol, side, and quantity
        if (string.IsNullOrEmpty(Symbol))
            errors.Add("Symbol is required");
            
        if (Quantity <= 0)
            errors.Add("Quantity must be positive");
            
        // Limit and StopLimit orders require limit price
        if ((Type == OrderType.Limit || Type == OrderType.StopLimit) && !LimitPrice.HasValue)
            errors.Add("Limit price is required for limit orders");
            
        // StopMarket and StopLimit orders require stop price
        if ((Type == OrderType.StopMarket || Type == OrderType.StopLimit) && !StopPrice.HasValue)
            errors.Add("Stop price is required for stop orders");
            
        // Limit price must be positive if specified
        if (LimitPrice.HasValue && LimitPrice.Value <= 0)
            errors.Add("Limit price must be positive");
            
        // Stop price must be positive if specified
        if (StopPrice.HasValue && StopPrice.Value <= 0)
            errors.Add("Stop price must be positive");
            
        return errors.Count == 0;
    }
}
```

## Order Type Processing Logic

### Market Order Processing
```csharp
private async Task<OrderResult> ProcessMarketOrderAsync(OrderRequest request, StrategyContext context)
{
    _logger.LogInformation("Processing market order for {Symbol} {Side} {Quantity}", 
        request.Symbol, request.Side, request.Quantity);
    
    // Market orders are executed immediately at market price
    // In a real implementation, this would connect to the execution venue
    var orderId = Guid.NewGuid().ToString();
    var executionPrice = await GetCurrentMarketPriceAsync(request.Symbol);
    
    if (!executionPrice.HasValue)
    {
        return new OrderResult(false, null, "Unable to get market price", null);
    }
    
    // Create fill
    var fill = new OrderFill(
        orderId,
        request.Symbol,
        request.Quantity,
        executionPrice.Value,
        DateTime.UtcNow,
        CalculateCommission(request.Quantity, executionPrice.Value),
        Guid.NewGuid().ToString()
    );
    
    // Update order status
    var orderStatus = new OrderStatus(
        orderId,
        request.Symbol,
        request.Side,
        request.Type,
        request.Quantity,
        request.Quantity, // Fully filled
        null, // No limit price for market orders
        null, // No stop price for market orders
        OrderState.Filled,
        DateTime.UtcNow,
        DateTime.UtcNow,
        new List<OrderFill> { fill }
    );
    
    // Store order status
    lock (_lock)
    {
        _orders[orderId] = orderStatus;
    }
    
    // Notify risk manager of fill
    await _riskManager.OnFillAsync(fill);
    
    _logger.LogInformation("Market order {OrderId} filled at {Price}", orderId, executionPrice.Value);
    
    return new OrderResult(true, orderId, "Market order filled successfully", orderStatus);
}
```

### Limit Order Processing
```csharp
private async Task<OrderResult> ProcessLimitOrderAsync(OrderRequest request, StrategyContext context)
{
    if (!request.LimitPrice.HasValue)
    {
        return new OrderResult(false, null, "Limit price required for limit orders", null);
    }
    
    _logger.LogInformation("Processing limit order for {Symbol} {Side} {Quantity} @ {LimitPrice}", 
        request.Symbol, request.Side, request.Quantity, request.LimitPrice.Value);
    
    // Limit orders are placed in the order book
    // In a real implementation, this would connect to the execution venue
    var orderId = Guid.NewGuid().ToString();
    
    // Check if order can be filled immediately
    var marketPrice = await GetCurrentMarketPriceAsync(request.Symbol);
    
    if (!marketPrice.HasValue)
    {
        return new OrderResult(false, null, "Unable to get market price", null);
    }
    
    bool canFillImmediately = false;
    
    if (request.Side == OrderSide.Buy && marketPrice.Value <= request.LimitPrice.Value)
    {
        canFillImmediately = true;
    }
    else if (request.Side == OrderSide.Sell && marketPrice.Value >= request.LimitPrice.Value)
    {
        canFillImmediately = true;
    }
    
    OrderState initialState;
    DateTime? filledTime = null;
    List<OrderFill> fills = new List<OrderFill>();
    
    if (canFillImmediately)
    {
        // Create fill
        var fill = new OrderFill(
            orderId,
            request.Symbol,
            request.Quantity,
            request.LimitPrice.Value, // Fill at limit price
            DateTime.UtcNow,
            CalculateCommission(request.Quantity, request.LimitPrice.Value),
            Guid.NewGuid().ToString()
        );
        
        fills.Add(fill);
        initialState = OrderState.Filled;
        filledTime = DateTime.UtcNow;
        
        // Notify risk manager of fill
        await _riskManager.OnFillAsync(fill);
        
        _logger.LogInformation("Limit order {OrderId} filled immediately at {Price}", orderId, request.LimitPrice.Value);
    }
    else
    {
        initialState = OrderState.Accepted;
        _logger.LogInformation("Limit order {OrderId} placed in order book at {Price}", orderId, request.LimitPrice.Value);
    }
    
    // Create order status
    var orderStatus = new OrderStatus(
        orderId,
        request.Symbol,
        request.Side,
        request.Type,
        request.Quantity,
        canFillImmediately ? request.Quantity : 0,
        request.LimitPrice.Value,
        null, // No stop price for limit orders
        initialState,
        DateTime.UtcNow,
        filledTime,
        fills
    );
    
    // Store order status
    lock (_lock)
    {
        _orders[orderId] = orderStatus;
    }
    
    return new OrderResult(true, orderId, 
        canFillImmediately ? "Limit order filled successfully" : "Limit order placed successfully", 
        orderStatus);
}
```

### Stop Market Order Processing
```csharp
private async Task<OrderResult> ProcessStopMarketOrderAsync(OrderRequest request, StrategyContext context)
{
    if (!request.StopPrice.HasValue)
    {
        return new OrderResult(false, null, "Stop price required for stop orders", null);
    }
    
    _logger.LogInformation("Processing stop market order for {Symbol} {Side} {Quantity} stop @ {StopPrice}", 
        request.Symbol, request.Side, request.Quantity, request.StopPrice.Value);
    
    // Stop market orders are placed as stop orders
    // They become market orders when the stop price is triggered
    var orderId = Guid.NewGuid().ToString();
    
    // Create order status
    var orderStatus = new OrderStatus(
        orderId,
        request.Symbol,
        request.Side,
        request.Type,
        request.Quantity,
        0, // Not filled yet
        null, // No limit price for stop market orders
        request.StopPrice.Value,
        OrderState.Accepted,
        DateTime.UtcNow,
        null,
        new List<OrderFill>()
    );
    
    // Store order status
    lock (_lock)
    {
        _orders[orderId] = orderStatus;
    }
    
    // In a real implementation, we would set up market data monitoring
    // to trigger the order when the stop price is reached
    _ = MonitorStopPriceAsync(orderId, request.Symbol, request.StopPrice.Value, request.Side);
    
    _logger.LogInformation("Stop market order {OrderId} placed with stop price {StopPrice}", 
        orderId, request.StopPrice.Value);
    
    return new OrderResult(true, orderId, "Stop market order placed successfully", orderStatus);
}

private async Task MonitorStopPriceAsync(string orderId, string symbol, decimal stopPrice, OrderSide side)
{
    try
    {
        // Simplified monitoring - in a real implementation, this would:
        // 1. Subscribe to real-time market data
        // 2. Check if stop price is triggered
        // 3. Convert to market order when triggered
        
        // For this design, we'll simulate a trigger after a delay
        await Task.Delay(TimeSpan.FromSeconds(30));
        
        // Check if order still exists and is not cancelled
        OrderStatus order;
        lock (_lock)
        {
            if (!_orders.ContainsKey(orderId))
                return;
                
            order = _orders[orderId];
            if (order.State == OrderState.Cancelled)
                return;
        }
        
        // Simulate stop price trigger
        _logger.LogInformation("Stop price triggered for order {OrderId}", orderId);
        
        // Convert to market order
        var marketOrderRequest = new OrderRequest(
            order.Symbol,
            order.Side,
            OrderType.Market,
            order.Quantity,
            null, // No limit price
            null, // No stop price
            TimeInForce.Day,
            null,
            new Dictionary<string, object>()
        );
        
        // Process as market order
        var result = await ProcessMarketOrderAsync(marketOrderRequest, null); // Context would be needed in real implementation
        
        // Update original order status
        if (result.Success)
        {
            lock (_lock)
            {
                if (_orders.ContainsKey(orderId))
                {
                    var updatedOrder = _orders[orderId] with
                    {
                        State = OrderState.Filled,
                        FilledTime = DateTime.UtcNow,
                        Fills = result.Status.Fills
                    };
                    _orders[orderId] = updatedOrder;
                }
            }
        }
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Error monitoring stop price for order {OrderId}", orderId);
    }
}
```

### Stop Limit Order Processing
```csharp
private async Task<OrderResult> ProcessStopLimitOrderAsync(OrderRequest request, StrategyContext context)
{
    if (!request.StopPrice.HasValue)
    {
        return new OrderResult(false, null, "Stop price required for stop limit orders", null);
    }
    
    if (!request.LimitPrice.HasValue)
    {
        return new OrderResult(false, null, "Limit price required for stop limit orders", null);
    }
    
    _logger.LogInformation("Processing stop limit order for {Symbol} {Side} {Quantity} stop @ {StopPrice} limit @ {LimitPrice}", 
        request.Symbol, request.Side, request.Quantity, request.StopPrice.Value, request.LimitPrice.Value);
    
    // Stop limit orders are placed as stop orders
    // They become limit orders when the stop price is triggered
    var orderId = Guid.NewGuid().ToString();
    
    // Create order status
    var orderStatus = new OrderStatus(
        orderId,
        request.Symbol,
        request.Side,
        request.Type,
        request.Quantity,
        0, // Not filled yet
        request.LimitPrice.Value,
        request.StopPrice.Value,
        OrderState.Accepted,
        DateTime.UtcNow,
        null,
        new List<OrderFill>()
    );
    
    // Store order status
    lock (_lock)
    {
        _orders[orderId] = orderStatus;
    }
    
    // In a real implementation, we would set up market data monitoring
    // to trigger the order when the stop price is reached
    _ = MonitorStopLimitPriceAsync(orderId, request.Symbol, request.StopPrice.Value, request.LimitPrice.Value, request.Side);
    
    _logger.LogInformation("Stop limit order {OrderId} placed with stop price {StopPrice} and limit price {LimitPrice}", 
        orderId, request.StopPrice.Value, request.LimitPrice.Value);
    
    return new OrderResult(true, orderId, "Stop limit order placed successfully", orderStatus);
}

private async Task MonitorStopLimitPriceAsync(string orderId, string symbol, decimal stopPrice, decimal limitPrice, OrderSide side)
{
    try
    {
        // Simplified monitoring - in a real implementation, this would:
        // 1. Subscribe to real-time market data
        // 2. Check if stop price is triggered
        // 3. Convert to limit order when triggered
        
        // For this design, we'll simulate a trigger after a delay
        await Task.Delay(TimeSpan.FromSeconds(30));
        
        // Check if order still exists and is not cancelled
        OrderStatus order;
        lock (_lock)
        {
            if (!_orders.ContainsKey(orderId))
                return;
                
            order = _orders[orderId];
            if (order.State == OrderState.Cancelled)
                return;
        }
        
        // Simulate stop price trigger
        _logger.LogInformation("Stop price triggered for stop limit order {OrderId}", orderId);
        
        // Convert to limit order
        var limitOrderRequest = new OrderRequest(
            order.Symbol,
            order.Side,
            OrderType.Limit,
            order.Quantity,
            limitPrice,
            null, // No stop price
            TimeInForce.Day,
            null,
            new Dictionary<string, object>()
        );
        
        // Process as limit order
        var result = await ProcessLimitOrderAsync(limitOrderRequest, null); // Context would be needed in real implementation
        
        // Update original order status
        if (result.Success)
        {
            lock (_lock)
            {
                if (_orders.ContainsKey(orderId))
                {
                    var updatedOrder = _orders[orderId] with
                    {
                        State = result.Status.State,
                        FilledTime = result.Status.FilledTime,
                        Fills = result.Status.Fills
                    };
                    _orders[orderId] = updatedOrder;
                }
            }
        }
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Error monitoring stop limit price for order {OrderId}", orderId);
    }
}
```

## Order Type Selection Logic

```csharp
public async Task<OrderResult> SubmitOrderAsync(OrderRequest request, StrategyContext context)
{
    // Validate request
    if (!request.IsValid(out var errors))
    {
        return new OrderResult(false, null, string.Join("; ", errors), null);
    }
    
    // Route to appropriate processing method based on order type
    return request.Type switch
    {
        OrderType.Market => await ProcessMarketOrderAsync(request, context),
        OrderType.Limit => await ProcessLimitOrderAsync(request, context),
        OrderType.StopMarket => await ProcessStopMarketOrderAsync(request, context),
        OrderType.StopLimit => await ProcessStopLimitOrderAsync(request, context),
        _ => new OrderResult(false, null, $"Unsupported order type: {request.Type}", null)
    };
}
```

## Price Retrieval Implementation

```csharp
private async Task<decimal?> GetCurrentMarketPriceAsync(string symbol)
{
    // In a real implementation, this would connect to a market data provider
    // For this design, we'll return a simulated price
    
    // Simulate price based on symbol
    var random = new Random();
    return symbol switch
    {
        "ES" => 4200 + (decimal)(random.NextDouble() * 100 - 50), // S&P 500 E-mini
        "NQ" => 15000 + (decimal)(random.NextDouble() * 200 - 100), // NASDAQ-10 E-mini
        "CL" => 75 + (decimal)(random.NextDouble() * 10 - 5), // Crude Oil
        _ => 100 + (decimal)(random.NextDouble() * 50 - 25) // Default
    };
}
```

## Commission Calculation

```csharp
private decimal CalculateCommission(int quantity, decimal price)
{
    // Simplified commission calculation
    // In a real implementation, this would be based on broker fees
    
    // Example: $0.50 per contract + 0.01% of value
    var value = quantity * price;
    var perContractFee = quantity * 0.50m;
    var percentageFee = value * 0.0001m;
    
    return perContractFee + percentageFee;
}
```

## Error Handling and Validation

The order type implementation includes comprehensive validation:

1. **Input Validation**: Each order type has specific validation rules
2. **Price Validation**: Prices must be positive and appropriate for the order type
3. **Quantity Validation**: Quantities must be positive
4. **State Validation**: Orders can only be modified or cancelled in appropriate states

## Testing Considerations

Each order type should be tested with:

1. **Valid Orders**: Properly formed orders of each type
2. **Invalid Orders**: Orders with missing or invalid parameters
3. **Edge Cases**: Boundary conditions like zero quantities or prices
4. **State Transitions**: Proper handling of order state changes
5. **Integration**: Interaction with risk management and position sizing

## Performance Considerations

1. **Market Data**: Efficient market data subscription and processing
2. **Order Book**: Proper management of limit order books
3. **Monitoring**: Efficient monitoring of stop prices without excessive resource usage
4. **Latency**: Minimal latency in order processing and execution

## Future Enhancements

1. **Advanced Order Types**: Support for trailing stops, one-cancels-other (OCO), etc.
2. **Time-Based Orders**: Time-specific order execution
3. **Conditional Orders**: Orders that trigger based on market conditions
4. **Bracket Orders**: Simultaneous entry with profit target and stop loss
