using System; using System.Collections.Generic; using NT8.Core.Common.Interfaces; using NT8.Core.Common.Models; using NT8.Core.Risk; using NT8.Core.Sizing; using NT8.Core.Logging; namespace NT8.Adapters.NinjaTrader { /// /// Main NT8 adapter implementation that integrates all components /// public class NT8Adapter : INT8Adapter { private readonly object _lock = new object(); private readonly NT8DataAdapter _dataAdapter; private readonly NT8OrderAdapter _orderAdapter; private readonly NT8LoggingAdapter _loggingAdapter; private readonly List _executionHistory; private IRiskManager _riskManager; private IPositionSizer _positionSizer; /// /// Constructor for NT8Adapter /// public NT8Adapter() { _dataAdapter = new NT8DataAdapter(); _orderAdapter = new NT8OrderAdapter(new NullExecutionBridge()); _loggingAdapter = new NT8LoggingAdapter(); _executionHistory = new List(); } private class NullExecutionBridge : INT8ExecutionBridge { public void EnterLongManaged(int quantity, string signalName, int stopTicks, int targetTicks, double tickSize) { } public void EnterShortManaged(int quantity, string signalName, int stopTicks, int targetTicks, double tickSize) { } public void ExitLongManaged(string signalName) { } public void ExitShortManaged(string signalName) { } public void FlattenAll() { } } /// /// Initialize the adapter with required components /// public void Initialize(IRiskManager riskManager, IPositionSizer positionSizer) { _riskManager = riskManager; _positionSizer = positionSizer; _orderAdapter.Initialize(riskManager, positionSizer); } /// /// Convert NT8 bar data to SDK format /// public BarData ConvertToSdkBar(string symbol, DateTime time, double open, double high, double low, double close, long volume, int barSizeMinutes) { return _dataAdapter.ConvertToSdkBar(symbol, time, open, high, low, close, volume, barSizeMinutes); } /// /// Convert NT8 account data to SDK format /// public AccountInfo ConvertToSdkAccount(double equity, double buyingPower, double dailyPnL, double maxDrawdown, DateTime lastUpdate) { return _dataAdapter.ConvertToSdkAccount(equity, buyingPower, dailyPnL, maxDrawdown, lastUpdate); } /// /// Convert NT8 position data to SDK format /// public Position ConvertToSdkPosition(string symbol, int quantity, double averagePrice, double unrealizedPnL, double realizedPnL, DateTime lastUpdate) { return _dataAdapter.ConvertToSdkPosition(symbol, quantity, averagePrice, unrealizedPnL, realizedPnL, lastUpdate); } /// /// Execute strategy intent through NT8 /// public void ExecuteIntent(StrategyIntent intent, SizingResult sizing) { if (intent == null) { throw new ArgumentNullException("intent"); } if (sizing == null) { throw new ArgumentNullException("sizing"); } // In a full implementation, this would execute the order through NT8 // For now, we'll just log what would be executed _loggingAdapter.LogInformation("Executing intent: {0} {1} contracts at {2} ticks stop", intent.Side, sizing.Contracts, intent.StopTicks); lock (_lock) { _executionHistory.Add(new NT8OrderExecutionRecord( intent.Symbol, intent.Side, intent.EntryType, sizing.Contracts, intent.StopTicks, intent.TargetTicks, DateTime.UtcNow)); } } /// /// Handle order updates from NT8 /// public void OnOrderUpdate(string orderId, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, string orderState, DateTime time, string errorCode, string nativeError) { _orderAdapter.OnOrderUpdate(orderId, limitPrice, stopPrice, quantity, filled, averageFillPrice, orderState, time, errorCode, nativeError); } /// /// Handle execution updates from NT8 /// public void OnExecutionUpdate(string executionId, string orderId, double price, int quantity, string marketPosition, DateTime time) { _orderAdapter.OnExecutionUpdate(executionId, orderId, price, quantity, marketPosition, time); } /// /// Gets execution history captured by the order adapter. /// /// Execution history snapshot. public IList GetExecutionHistory() { lock (_lock) { return new List(_executionHistory); } } } }