feat: Implement Phase 1 OMS with complete state machine

- Add OrderModels with all enums and records
- Implement IOrderManager interface
- Create BasicOrderManager with thread-safe state machine
- Add INT8OrderAdapter interface for NT8 integration
- Implement MockNT8OrderAdapter for testing
- Add comprehensive unit tests (34 tests, all passing)
- Full C# 5.0 compliance
- >95% code coverage
- Zero build warnings for new code

Closes Phase 1 OMS implementation
This commit is contained in:
Billy Valentine
2026-02-15 14:57:31 -05:00
parent 6c48a2ad05
commit 42efd83e5d
7 changed files with 1940 additions and 0 deletions

View File

@@ -0,0 +1,359 @@
using System;
using System.Collections.Generic;
namespace NT8.Core.OMS
{
#region Enumerations
/// <summary>
/// Order side enumeration
/// </summary>
public enum OrderSide
{
Buy = 1,
Sell = -1
}
/// <summary>
/// Order type enumeration
/// </summary>
public enum OrderType
{
Market,
Limit,
StopMarket,
StopLimit
}
/// <summary>
/// Order state enumeration for the OMS state machine
/// </summary>
public enum OrderState
{
Pending, // Order request created, waiting for risk approval
Submitted, // Sent to broker, waiting for acceptance
Accepted, // Broker accepted the order
Working, // Order is live in the market
PartiallyFilled, // Order partially filled
Filled, // Order completely filled
Cancelled, // Order cancelled by user or system
Rejected, // Order rejected by broker or system
Expired // Order expired
}
/// <summary>
/// Time in force enumeration
/// </summary>
public enum TimeInForce
{
Day,
Gtc, // Good Till Cancelled
Ioc, // Immediate Or Cancel
Fok // Fill Or Kill
}
#endregion
#region Core Order Models
/// <summary>
/// Order request parameters
/// </summary>
public class OrderRequest
{
/// <summary>
/// Trading symbol
/// </summary>
public string Symbol { get; set; }
/// <summary>
/// Order side
/// </summary>
public OrderSide Side { get; set; }
/// <summary>
/// Order type
/// </summary>
public OrderType Type { get; set; }
/// <summary>
/// Order quantity
/// </summary>
public int Quantity { get; set; }
/// <summary>
/// Limit price (if applicable)
/// </summary>
public decimal? LimitPrice { get; set; }
/// <summary>
/// Stop price (if applicable)
/// </summary>
public decimal? StopPrice { get; set; }
/// <summary>
/// Time in force
/// </summary>
public TimeInForce TimeInForce { get; set; }
/// <summary>
/// Unique identifier for this order request
/// </summary>
public string ClientOrderId { get; set; }
/// <summary>
/// Timestamp when order was created
/// </summary>
public DateTime CreatedTime { get; set; }
/// <summary>
/// Constructor for OrderRequest
/// </summary>
public OrderRequest()
{
CreatedTime = DateTime.UtcNow;
}
}
/// <summary>
/// Order submission result
/// </summary>
public class OrderResult
{
/// <summary>
/// Whether the order submission was successful
/// </summary>
public bool Success { get; set; }
/// <summary>
/// Order ID if successful
/// </summary>
public string OrderId { get; set; }
/// <summary>
/// Message describing the result
/// </summary>
public string Message { get; set; }
/// <summary>
/// Original order request
/// </summary>
public OrderRequest Request { get; set; }
/// <summary>
/// Constructor for OrderResult
/// </summary>
public OrderResult(bool success, string orderId, string message, OrderRequest request)
{
Success = success;
OrderId = orderId;
Message = message;
Request = request;
}
}
/// <summary>
/// Current order status with full state information
/// </summary>
public class OrderStatus
{
/// <summary>
/// Internal order ID assigned by the OMS
/// </summary>
public string OrderId { get; set; }
/// <summary>
/// Client-provided order ID
/// </summary>
public string ClientOrderId { get; set; }
/// <summary>
/// Trading symbol
/// </summary>
public string Symbol { get; set; }
/// <summary>
/// Order side
/// </summary>
public OrderSide Side { get; set; }
/// <summary>
/// Order type
/// </summary>
public OrderType Type { get; set; }
/// <summary>
/// Original order quantity
/// </summary>
public int Quantity { get; set; }
/// <summary>
/// Filled quantity
/// </summary>
public int FilledQuantity { get; set; }
/// <summary>
/// Remaining quantity
/// </summary>
public int RemainingQuantity { get { return Quantity - FilledQuantity; } }
/// <summary>
/// Limit price (if applicable)
/// </summary>
public decimal? LimitPrice { get; set; }
/// <summary>
/// Stop price (if applicable)
/// </summary>
public decimal? StopPrice { get; set; }
/// <summary>
/// Current order state
/// </summary>
public OrderState State { get; set; }
/// <summary>
/// Order creation time
/// </summary>
public DateTime CreatedTime { get; set; }
/// <summary>
/// Order fill time (if filled)
/// </summary>
public DateTime? FilledTime { get; set; }
/// <summary>
/// Order fills
/// </summary>
public List<OrderFill> Fills { get; set; }
/// <summary>
/// Average fill price
/// </summary>
public decimal AverageFillPrice { get; set; }
/// <summary>
/// Total value of filled shares
/// </summary>
public decimal FillValue { get; set; }
/// <summary>
/// Constructor for OrderStatus
/// </summary>
public OrderStatus()
{
Fills = new List<OrderFill>();
CreatedTime = DateTime.UtcNow;
}
}
/// <summary>
/// Represents a single fill event for an order
/// </summary>
public class OrderFill
{
/// <summary>
/// Fill ID from the broker
/// </summary>
public string FillId { get; set; }
/// <summary>
/// Order ID this fill belongs to
/// </summary>
public string OrderId { get; set; }
/// <summary>
/// Quantity filled in this transaction
/// </summary>
public int FillQuantity { get; set; }
/// <summary>
/// Price at which the fill occurred
/// </summary>
public decimal FillPrice { get; set; }
/// <summary>
/// Timestamp of the fill
/// </summary>
public DateTime FillTime { get; set; }
/// <summary>
/// Commission paid for this fill
/// </summary>
public decimal Commission { get; set; }
/// <summary>
/// Constructor for OrderFill
/// </summary>
public OrderFill()
{
FillTime = DateTime.UtcNow;
}
}
/// <summary>
/// Order modification parameters
/// </summary>
public class OrderModification
{
/// <summary>
/// Order ID to modify
/// </summary>
public string OrderId { get; set; }
/// <summary>
/// New quantity (if changing)
/// </summary>
public int? NewQuantity { get; set; }
/// <summary>
/// New limit price (if changing)
/// </summary>
public decimal? NewLimitPrice { get; set; }
/// <summary>
/// New stop price (if changing)
/// </summary>
public decimal? NewStopPrice { get; set; }
/// <summary>
/// New time in force (if changing)
/// </summary>
public TimeInForce? NewTimeInForce { get; set; }
/// <summary>
/// Constructor for OrderModification
/// </summary>
public OrderModification(string orderId)
{
OrderId = orderId;
}
}
/// <summary>
/// Order cancellation request
/// </summary>
public class OrderCancellation
{
/// <summary>
/// Order ID to cancel
/// </summary>
public string OrderId { get; set; }
/// <summary>
/// Reason for cancellation
/// </summary>
public string Reason { get; set; }
/// <summary>
/// Constructor for OrderCancellation
/// </summary>
public OrderCancellation(string orderId, string reason)
{
OrderId = orderId;
Reason = reason;
}
}
#endregion
}