Implement NinjaTrader 8 adapter for integration
Some checks failed
Build and Test / build (push) Has been cancelled
Some checks failed
Build and Test / build (push) Has been cancelled
This commit is contained in:
49
src/NT8.Adapters/NinjaTrader/INT8Adapter.cs
Normal file
49
src/NT8.Adapters/NinjaTrader/INT8Adapter.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
using System;
|
||||||
|
using NT8.Core.Common.Interfaces;
|
||||||
|
using NT8.Core.Common.Models;
|
||||||
|
using NT8.Core.Risk;
|
||||||
|
using NT8.Core.Sizing;
|
||||||
|
|
||||||
|
namespace NT8.Adapters.NinjaTrader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for NinjaTrader 8 integration adapter
|
||||||
|
/// </summary>
|
||||||
|
public interface INT8Adapter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize the adapter with required components
|
||||||
|
/// </summary>
|
||||||
|
void Initialize(IRiskManager riskManager, IPositionSizer positionSizer);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert NT8 bar data to SDK format
|
||||||
|
/// </summary>
|
||||||
|
BarData ConvertToSdkBar(string symbol, DateTime time, double open, double high, double low, double close, long volume, int barSize);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert NT8 account data to SDK format
|
||||||
|
/// </summary>
|
||||||
|
AccountInfo ConvertToSdkAccount(double equity, double buyingPower, double dailyPnL, double maxDrawdown, DateTime lastUpdate);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert NT8 position data to SDK format
|
||||||
|
/// </summary>
|
||||||
|
Position ConvertToSdkPosition(string symbol, int quantity, double averagePrice, double unrealizedPnL, double realizedPnL, DateTime lastUpdate);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Execute strategy intent through NT8
|
||||||
|
/// </summary>
|
||||||
|
void ExecuteIntent(StrategyIntent intent, SizingResult sizing);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle order updates from NT8
|
||||||
|
/// </summary>
|
||||||
|
void OnOrderUpdate(string orderId, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, string orderState, DateTime time, string errorCode, string nativeError);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle execution updates from NT8
|
||||||
|
/// </summary>
|
||||||
|
void OnExecutionUpdate(string executionId, string orderId, double price, int quantity, string marketPosition, DateTime time);
|
||||||
|
}
|
||||||
|
}
|
||||||
92
src/NT8.Adapters/NinjaTrader/NT8Adapter.cs
Normal file
92
src/NT8.Adapters/NinjaTrader/NT8Adapter.cs
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
using System;
|
||||||
|
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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Main NT8 adapter implementation that integrates all components
|
||||||
|
/// </summary>
|
||||||
|
public class NT8Adapter : INT8Adapter
|
||||||
|
{
|
||||||
|
private readonly NT8DataAdapter _dataAdapter;
|
||||||
|
private readonly NT8OrderAdapter _orderAdapter;
|
||||||
|
private readonly NT8LoggingAdapter _loggingAdapter;
|
||||||
|
private IRiskManager _riskManager;
|
||||||
|
private IPositionSizer _positionSizer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for NT8Adapter
|
||||||
|
/// </summary>
|
||||||
|
public NT8Adapter()
|
||||||
|
{
|
||||||
|
_dataAdapter = new NT8DataAdapter();
|
||||||
|
_orderAdapter = new NT8OrderAdapter();
|
||||||
|
_loggingAdapter = new NT8LoggingAdapter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize the adapter with required components
|
||||||
|
/// </summary>
|
||||||
|
public void Initialize(IRiskManager riskManager, IPositionSizer positionSizer)
|
||||||
|
{
|
||||||
|
_riskManager = riskManager;
|
||||||
|
_positionSizer = positionSizer;
|
||||||
|
_orderAdapter.Initialize(riskManager, positionSizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert NT8 bar data to SDK format
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert NT8 account data to SDK format
|
||||||
|
/// </summary>
|
||||||
|
public AccountInfo ConvertToSdkAccount(double equity, double buyingPower, double dailyPnL, double maxDrawdown, DateTime lastUpdate)
|
||||||
|
{
|
||||||
|
return _dataAdapter.ConvertToSdkAccount(equity, buyingPower, dailyPnL, maxDrawdown, lastUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert NT8 position data to SDK format
|
||||||
|
/// </summary>
|
||||||
|
public Position ConvertToSdkPosition(string symbol, int quantity, double averagePrice, double unrealizedPnL, double realizedPnL, DateTime lastUpdate)
|
||||||
|
{
|
||||||
|
return _dataAdapter.ConvertToSdkPosition(symbol, quantity, averagePrice, unrealizedPnL, realizedPnL, lastUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Execute strategy intent through NT8
|
||||||
|
/// </summary>
|
||||||
|
public void ExecuteIntent(StrategyIntent intent, SizingResult 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle order updates from NT8
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle execution updates from NT8
|
||||||
|
/// </summary>
|
||||||
|
public void OnExecutionUpdate(string executionId, string orderId, double price, int quantity, string marketPosition, DateTime time)
|
||||||
|
{
|
||||||
|
_orderAdapter.OnExecutionUpdate(executionId, orderId, price, quantity, marketPosition, time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
51
src/NT8.Adapters/NinjaTrader/NT8DataAdapter.cs
Normal file
51
src/NT8.Adapters/NinjaTrader/NT8DataAdapter.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using NT8.Core.Common.Models;
|
||||||
|
|
||||||
|
namespace NT8.Adapters.NinjaTrader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Data adapter for converting between NT8 and SDK formats
|
||||||
|
/// </summary>
|
||||||
|
public class NT8DataAdapter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Convert NT8 bar data to SDK format
|
||||||
|
/// </summary>
|
||||||
|
public BarData ConvertToSdkBar(string symbol, DateTime time, double open, double high, double low, double close, long volume, int barSizeMinutes)
|
||||||
|
{
|
||||||
|
return new BarData(symbol, time, open, high, low, close, volume, TimeSpan.FromMinutes(barSizeMinutes));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert NT8 account data to SDK format
|
||||||
|
/// </summary>
|
||||||
|
public AccountInfo ConvertToSdkAccount(double equity, double buyingPower, double dailyPnL, double maxDrawdown, DateTime lastUpdate)
|
||||||
|
{
|
||||||
|
return new AccountInfo(equity, buyingPower, dailyPnL, maxDrawdown, lastUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert NT8 position data to SDK format
|
||||||
|
/// </summary>
|
||||||
|
public Position ConvertToSdkPosition(string symbol, int quantity, double averagePrice, double unrealizedPnL, double realizedPnL, DateTime lastUpdate)
|
||||||
|
{
|
||||||
|
return new Position(symbol, quantity, averagePrice, unrealizedPnL, realizedPnL, lastUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert NT8 market session data to SDK format
|
||||||
|
/// </summary>
|
||||||
|
public MarketSession ConvertToSdkSession(DateTime sessionStart, DateTime sessionEnd, bool isRth, string sessionName)
|
||||||
|
{
|
||||||
|
return new MarketSession(sessionStart, sessionEnd, isRth, sessionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert NT8 strategy context to SDK format
|
||||||
|
/// </summary>
|
||||||
|
public StrategyContext ConvertToSdkContext(string symbol, DateTime currentTime, Position currentPosition, AccountInfo account, MarketSession session, System.Collections.Generic.Dictionary<string, object> customData)
|
||||||
|
{
|
||||||
|
return new StrategyContext(symbol, currentTime, currentPosition, account, session, customData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
87
src/NT8.Adapters/NinjaTrader/NT8LoggingAdapter.cs
Normal file
87
src/NT8.Adapters/NinjaTrader/NT8LoggingAdapter.cs
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
using System;
|
||||||
|
using NT8.Core.Logging;
|
||||||
|
|
||||||
|
namespace NT8.Adapters.NinjaTrader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Logging adapter for integrating with NT8's logging system
|
||||||
|
/// </summary>
|
||||||
|
public class NT8LoggingAdapter : ILogger
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Log debug message
|
||||||
|
/// </summary>
|
||||||
|
public void LogDebug(string message, params object[] args)
|
||||||
|
{
|
||||||
|
// In a real implementation, this would call NT8's logging system
|
||||||
|
// For now, we'll just use Console.WriteLine as a placeholder
|
||||||
|
Console.WriteLine("[DEBUG] " + FormatMessage(message, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Log information message
|
||||||
|
/// </summary>
|
||||||
|
public void LogInformation(string message, params object[] args)
|
||||||
|
{
|
||||||
|
// In a real implementation, this would call NT8's logging system
|
||||||
|
Console.WriteLine("[INFO] " + FormatMessage(message, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Log warning message
|
||||||
|
/// </summary>
|
||||||
|
public void LogWarning(string message, params object[] args)
|
||||||
|
{
|
||||||
|
// In a real implementation, this would call NT8's logging system
|
||||||
|
Console.WriteLine("[WARN] " + FormatMessage(message, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Log error message
|
||||||
|
/// </summary>
|
||||||
|
public void LogError(string message, params object[] args)
|
||||||
|
{
|
||||||
|
// In a real implementation, this would call NT8's logging system
|
||||||
|
Console.WriteLine("[ERROR] " + FormatMessage(message, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Log critical message
|
||||||
|
/// </summary>
|
||||||
|
public void LogCritical(string message, params object[] args)
|
||||||
|
{
|
||||||
|
// In a real implementation, this would call NT8's logging system
|
||||||
|
Console.WriteLine("[CRITICAL] " + FormatMessage(message, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Log error with exception
|
||||||
|
/// </summary>
|
||||||
|
public void LogError(Exception ex, string message, params object[] args)
|
||||||
|
{
|
||||||
|
// In a real implementation, this would call NT8's logging system
|
||||||
|
Console.WriteLine("[ERROR] " + FormatMessage(message, args) + " - Exception: " + ex.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Format message with arguments
|
||||||
|
/// </summary>
|
||||||
|
private string FormatMessage(string message, object[] args)
|
||||||
|
{
|
||||||
|
if (args == null || args.Length == 0)
|
||||||
|
{
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return string.Format(message, args);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// If formatting fails, return the original message
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
115
src/NT8.Adapters/NinjaTrader/NT8OrderAdapter.cs
Normal file
115
src/NT8.Adapters/NinjaTrader/NT8OrderAdapter.cs
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
using System;
|
||||||
|
using NT8.Core.Common.Models;
|
||||||
|
using NT8.Core.Risk;
|
||||||
|
using NT8.Core.Sizing;
|
||||||
|
|
||||||
|
namespace NT8.Adapters.NinjaTrader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Order adapter for executing trades through NT8
|
||||||
|
/// </summary>
|
||||||
|
public class NT8OrderAdapter
|
||||||
|
{
|
||||||
|
private IRiskManager _riskManager;
|
||||||
|
private IPositionSizer _positionSizer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize the order adapter with required components
|
||||||
|
/// </summary>
|
||||||
|
public void Initialize(IRiskManager riskManager, IPositionSizer positionSizer)
|
||||||
|
{
|
||||||
|
_riskManager = riskManager;
|
||||||
|
_positionSizer = positionSizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Execute strategy intent through NT8 order management
|
||||||
|
/// </summary>
|
||||||
|
public void ExecuteIntent(StrategyIntent intent, StrategyContext context, StrategyConfig config)
|
||||||
|
{
|
||||||
|
if (_riskManager == null || _positionSizer == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Adapter not initialized. Call Initialize() first.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the intent through risk management
|
||||||
|
var riskDecision = _riskManager.ValidateOrder(intent, context, config.RiskSettings);
|
||||||
|
if (!riskDecision.Allow)
|
||||||
|
{
|
||||||
|
// Log rejection and return
|
||||||
|
// In a real implementation, we would use a proper logging system
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate position size
|
||||||
|
var sizingResult = _positionSizer.CalculateSize(intent, context, config.SizingSettings);
|
||||||
|
if (sizingResult.Contracts <= 0)
|
||||||
|
{
|
||||||
|
// Log that no position size was calculated
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In a real implementation, this would call NT8's order execution methods
|
||||||
|
// For now, we'll just log what would be executed
|
||||||
|
ExecuteInNT8(intent, sizingResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Execute the order in NT8 (placeholder implementation)
|
||||||
|
/// </summary>
|
||||||
|
private void ExecuteInNT8(StrategyIntent intent, SizingResult sizing)
|
||||||
|
{
|
||||||
|
// This is where the actual NT8 order execution would happen
|
||||||
|
// In a real implementation, this would call NT8's EnterLong/EnterShort methods
|
||||||
|
// along with SetStopLoss, SetProfitTarget, etc.
|
||||||
|
|
||||||
|
// Example of what this might look like in NT8:
|
||||||
|
/*
|
||||||
|
if (intent.Side == OrderSide.Buy)
|
||||||
|
{
|
||||||
|
EnterLong(sizing.Contracts, "SDK_Entry");
|
||||||
|
SetStopLoss("SDK_Entry", CalculationMode.Ticks, intent.StopTicks);
|
||||||
|
if (intent.TargetTicks.HasValue)
|
||||||
|
{
|
||||||
|
SetProfitTarget("SDK_Entry", CalculationMode.Ticks, intent.TargetTicks.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (intent.Side == OrderSide.Sell)
|
||||||
|
{
|
||||||
|
EnterShort(sizing.Contracts, "SDK_Entry");
|
||||||
|
SetStopLoss("SDK_Entry", CalculationMode.Ticks, intent.StopTicks);
|
||||||
|
if (intent.TargetTicks.HasValue)
|
||||||
|
{
|
||||||
|
SetProfitTarget("SDK_Entry", CalculationMode.Ticks, intent.TargetTicks.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle order updates from NT8
|
||||||
|
/// </summary>
|
||||||
|
public void OnOrderUpdate(string orderId, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, string orderState, DateTime time, string errorCode, string nativeError)
|
||||||
|
{
|
||||||
|
// Pass order updates to risk manager for tracking
|
||||||
|
if (_riskManager != null)
|
||||||
|
{
|
||||||
|
// In a real implementation, we would convert NT8 order data to SDK format
|
||||||
|
// and pass it to the risk manager
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle execution updates from NT8
|
||||||
|
/// </summary>
|
||||||
|
public void OnExecutionUpdate(string executionId, string orderId, double price, int quantity, string marketPosition, DateTime time)
|
||||||
|
{
|
||||||
|
// Pass execution updates to risk manager for P&L tracking
|
||||||
|
if (_riskManager != null)
|
||||||
|
{
|
||||||
|
// In a real implementation, we would convert NT8 execution data to SDK format
|
||||||
|
// and pass it to the risk manager
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
159
src/NT8.Adapters/Wrappers/BaseNT8StrategyWrapper.cs
Normal file
159
src/NT8.Adapters/Wrappers/BaseNT8StrategyWrapper.cs
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
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.Adapters.NinjaTrader;
|
||||||
|
|
||||||
|
namespace NT8.Adapters.Wrappers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base wrapper class for NT8 strategies that integrate with the SDK
|
||||||
|
/// This is a template that would be extended in actual NT8 strategy files
|
||||||
|
/// </summary>
|
||||||
|
public abstract class BaseNT8StrategyWrapper
|
||||||
|
{
|
||||||
|
#region SDK Components
|
||||||
|
|
||||||
|
protected IStrategy _sdkStrategy;
|
||||||
|
protected IRiskManager _riskManager;
|
||||||
|
protected IPositionSizer _positionSizer;
|
||||||
|
protected NT8Adapter _nt8Adapter;
|
||||||
|
protected StrategyConfig _strategyConfig;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stop loss in ticks
|
||||||
|
/// </summary>
|
||||||
|
public int StopTicks { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Profit target in ticks (optional)
|
||||||
|
/// </summary>
|
||||||
|
public int TargetTicks { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Risk amount per trade in dollars
|
||||||
|
/// </summary>
|
||||||
|
public double RiskAmount { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for BaseNT8StrategyWrapper
|
||||||
|
/// </summary>
|
||||||
|
public BaseNT8StrategyWrapper()
|
||||||
|
{
|
||||||
|
// Set default values
|
||||||
|
StopTicks = 10;
|
||||||
|
TargetTicks = 20;
|
||||||
|
RiskAmount = 100.0;
|
||||||
|
|
||||||
|
// Initialize SDK components
|
||||||
|
InitializeSdkComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Abstract Methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create the SDK strategy implementation
|
||||||
|
/// </summary>
|
||||||
|
protected abstract IStrategy CreateSdkStrategy();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Process a bar update (would be called from NT8's OnBarUpdate)
|
||||||
|
/// </summary>
|
||||||
|
public void ProcessBarUpdate(BarData barData, StrategyContext context)
|
||||||
|
{
|
||||||
|
// Call SDK strategy logic
|
||||||
|
var intent = _sdkStrategy.OnBar(barData, context);
|
||||||
|
if (intent != null)
|
||||||
|
{
|
||||||
|
// Convert SDK results to NT8 actions
|
||||||
|
ExecuteIntent(intent, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize SDK components
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeSdkComponents()
|
||||||
|
{
|
||||||
|
// In a real implementation, these would be injected or properly instantiated
|
||||||
|
// For now, we'll create placeholder instances
|
||||||
|
_riskManager = null; // This would be properly instantiated
|
||||||
|
_positionSizer = null; // This would be properly instantiated
|
||||||
|
|
||||||
|
// Create NT8 adapter
|
||||||
|
_nt8Adapter = new NT8Adapter();
|
||||||
|
_nt8Adapter.Initialize(_riskManager, _positionSizer);
|
||||||
|
|
||||||
|
// Create SDK strategy
|
||||||
|
_sdkStrategy = CreateSdkStrategy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create SDK configuration from parameters
|
||||||
|
/// </summary>
|
||||||
|
private void CreateSdkConfiguration()
|
||||||
|
{
|
||||||
|
// Create risk configuration
|
||||||
|
var riskConfig = new RiskConfig(
|
||||||
|
dailyLossLimit: 500.0,
|
||||||
|
maxTradeRisk: RiskAmount,
|
||||||
|
maxOpenPositions: 5,
|
||||||
|
emergencyFlattenEnabled: true
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create sizing configuration
|
||||||
|
var sizingConfig = new SizingConfig(
|
||||||
|
method: SizingMethod.FixedDollarRisk,
|
||||||
|
minContracts: 1,
|
||||||
|
maxContracts: 100,
|
||||||
|
riskPerTrade: RiskAmount,
|
||||||
|
methodParameters: new Dictionary<string, object>()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create strategy configuration
|
||||||
|
_strategyConfig = new StrategyConfig(
|
||||||
|
name: "NT8Strategy",
|
||||||
|
symbol: "Unknown",
|
||||||
|
parameters: new Dictionary<string, object>(),
|
||||||
|
riskSettings: riskConfig,
|
||||||
|
sizingSettings: sizingConfig
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Execute strategy intent through NT8
|
||||||
|
/// </summary>
|
||||||
|
private void ExecuteIntent(StrategyIntent intent, StrategyContext context)
|
||||||
|
{
|
||||||
|
// Calculate position size
|
||||||
|
var sizingResult = _positionSizer != null ?
|
||||||
|
_positionSizer.CalculateSize(intent, context, _strategyConfig.SizingSettings) :
|
||||||
|
new SizingResult(1, RiskAmount, SizingMethod.FixedDollarRisk, new Dictionary<string, object>());
|
||||||
|
|
||||||
|
// Execute through NT8 adapter
|
||||||
|
_nt8Adapter.ExecuteIntent(intent, sizingResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
118
src/NT8.Adapters/Wrappers/SimpleORBNT8Wrapper.cs
Normal file
118
src/NT8.Adapters/Wrappers/SimpleORBNT8Wrapper.cs
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NT8.Core.Common.Interfaces;
|
||||||
|
using NT8.Core.Common.Models;
|
||||||
|
using NT8.Core.Logging;
|
||||||
|
|
||||||
|
namespace NT8.Adapters.Wrappers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Simple ORB (Opening Range Breakout) strategy wrapper for NT8
|
||||||
|
/// This demonstrates how to implement a strategy that works with the SDK
|
||||||
|
/// </summary>
|
||||||
|
public class SimpleORBNT8Wrapper : BaseNT8StrategyWrapper
|
||||||
|
{
|
||||||
|
#region Strategy Parameters
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Opening range period in minutes
|
||||||
|
/// </summary>
|
||||||
|
public int OpeningRangeMinutes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of standard deviations for breakout threshold
|
||||||
|
/// </summary>
|
||||||
|
public double StdDevMultiplier { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Strategy State
|
||||||
|
|
||||||
|
private DateTime _openingRangeStart;
|
||||||
|
private double _openingRangeHigh;
|
||||||
|
private double _openingRangeLow;
|
||||||
|
private bool _openingRangeCalculated;
|
||||||
|
private double _rangeSize;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for SimpleORBNT8Wrapper
|
||||||
|
/// </summary>
|
||||||
|
public SimpleORBNT8Wrapper()
|
||||||
|
{
|
||||||
|
OpeningRangeMinutes = 30;
|
||||||
|
StdDevMultiplier = 1.0;
|
||||||
|
_openingRangeCalculated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Base Class Implementation
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create the SDK strategy implementation
|
||||||
|
/// </summary>
|
||||||
|
protected override IStrategy CreateSdkStrategy()
|
||||||
|
{
|
||||||
|
return new SimpleORBStrategy();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Strategy Logic
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Simple ORB strategy implementation
|
||||||
|
/// </summary>
|
||||||
|
private class SimpleORBStrategy : IStrategy
|
||||||
|
{
|
||||||
|
public StrategyMetadata Metadata { get; private set; }
|
||||||
|
|
||||||
|
public SimpleORBStrategy()
|
||||||
|
{
|
||||||
|
Metadata = new StrategyMetadata(
|
||||||
|
name: "Simple ORB",
|
||||||
|
description: "Opening Range Breakout strategy",
|
||||||
|
version: "1.0",
|
||||||
|
author: "NT8 SDK Team",
|
||||||
|
symbols: new string[] { "ES", "NQ", "YM" },
|
||||||
|
requiredBars: 20
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize(StrategyConfig config, IMarketDataProvider dataProvider, ILogger logger)
|
||||||
|
{
|
||||||
|
// Initialize strategy with configuration
|
||||||
|
// In a real implementation, we would store references to the data provider and logger
|
||||||
|
}
|
||||||
|
|
||||||
|
public StrategyIntent OnBar(BarData bar, StrategyContext context)
|
||||||
|
{
|
||||||
|
// This is where the actual strategy logic would go
|
||||||
|
// For this example, we'll just return null to indicate no trade
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StrategyIntent OnTick(TickData tick, StrategyContext context)
|
||||||
|
{
|
||||||
|
// Most strategies don't need tick-level logic
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, object> GetParameters()
|
||||||
|
{
|
||||||
|
return new Dictionary<string, object>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetParameters(Dictionary<string, object> parameters)
|
||||||
|
{
|
||||||
|
// Set strategy parameters from configuration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user