chore: add deployment/backups and DLLs to .gitignore
Some checks failed
Build and Test / build (push) Has been cancelled

This commit is contained in:
2026-03-10 15:50:53 -04:00
parent a283ef4673
commit ee4da1b607
41 changed files with 7 additions and 4108 deletions

View File

@@ -1,229 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
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
{
private readonly object _lock = new object();
#region SDK Components
protected IStrategy _sdkStrategy;
protected IRiskManager _riskManager;
protected IPositionSizer _positionSizer;
protected NT8Adapter _nt8Adapter;
protected StrategyConfig _strategyConfig;
protected ILogger _logger;
#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 with default implementations.
// Derived wrappers can replace these through InitializeSdkComponents.
_logger = new BasicLogger("BaseNT8StrategyWrapper");
_riskManager = new BasicRiskManager(_logger);
_positionSizer = new BasicPositionSizer(_logger);
InitializeSdkComponents(_riskManager, _positionSizer, _logger);
}
#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)
{
if (barData == null)
throw new ArgumentNullException("barData");
if (context == null)
throw new ArgumentNullException("context");
try
{
StrategyIntent intent;
lock (_lock)
{
if (_sdkStrategy == null)
{
throw new InvalidOperationException("SDK strategy has not been initialized.");
}
intent = _sdkStrategy.OnBar(barData, context);
}
if (intent != null)
{
ExecuteIntent(intent, context);
}
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed processing bar update for {0}: {1}", context.Symbol, ex.Message);
}
throw;
}
}
#endregion
#region Private Methods
/// <summary>
/// Initialize SDK components
/// </summary>
protected virtual void InitializeSdkComponents(IRiskManager riskManager, IPositionSizer positionSizer, ILogger logger)
{
if (riskManager == null)
throw new ArgumentNullException("riskManager");
if (positionSizer == null)
throw new ArgumentNullException("positionSizer");
if (logger == null)
throw new ArgumentNullException("logger");
_riskManager = riskManager;
_positionSizer = positionSizer;
_logger = logger;
_nt8Adapter = new NT8Adapter();
_nt8Adapter.Initialize(_riskManager, _positionSizer);
CreateSdkConfiguration();
_sdkStrategy = CreateSdkStrategy();
if (_sdkStrategy == null)
throw new InvalidOperationException("CreateSdkStrategy returned null.");
_sdkStrategy.Initialize(_strategyConfig, null, _logger);
_logger.LogInformation("Base NT8 strategy wrapper initialized for symbol {0}", _strategyConfig.Symbol);
}
/// <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)
{
if (intent == null)
throw new ArgumentNullException("intent");
if (context == null)
throw new ArgumentNullException("context");
try
{
SizingResult sizingResult;
lock (_lock)
{
if (_positionSizer == null)
{
throw new InvalidOperationException("Position sizer has not been initialized.");
}
sizingResult = _positionSizer.CalculateSize(intent, context, _strategyConfig.SizingSettings);
}
_nt8Adapter.ExecuteIntent(intent, sizingResult);
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed executing intent for {0}: {1}", intent.Symbol, ex.Message);
}
throw;
}
}
#endregion
}
}

View File

@@ -1,280 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
using NT8.Adapters.NinjaTrader;
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 Constructor
/// <summary>
/// Constructor for SimpleORBNT8Wrapper
/// </summary>
public SimpleORBNT8Wrapper()
{
OpeningRangeMinutes = 30;
StdDevMultiplier = 1.0;
}
#endregion
#region Base Class Implementation
/// <summary>
/// Exposes adapter reference for integration test assertions.
/// </summary>
public NT8Adapter GetAdapterForTesting()
{
return _nt8Adapter;
}
/// <summary>
/// Create the SDK strategy implementation
/// </summary>
protected override IStrategy CreateSdkStrategy()
{
var openingRangeMinutes = OpeningRangeMinutes > 0 ? OpeningRangeMinutes : 30;
var stdDevMultiplier = StdDevMultiplier > 0.0 ? StdDevMultiplier : 1.0;
return new SimpleORBStrategy(openingRangeMinutes, stdDevMultiplier);
}
#endregion
#region Strategy Logic
/// <summary>
/// Simple ORB strategy implementation
/// </summary>
private class SimpleORBStrategy : IStrategy
{
private readonly int _openingRangeMinutes;
private readonly double _stdDevMultiplier;
private ILogger _logger;
private DateTime _currentSessionDate;
private DateTime _openingRangeStart;
private DateTime _openingRangeEnd;
private double _openingRangeHigh;
private double _openingRangeLow;
private bool _openingRangeReady;
private bool _tradeTaken;
public StrategyMetadata Metadata { get; private set; }
public SimpleORBStrategy(int openingRangeMinutes, double stdDevMultiplier)
{
if (openingRangeMinutes <= 0)
{
throw new ArgumentException("openingRangeMinutes");
}
if (stdDevMultiplier <= 0.0)
{
throw new ArgumentException("stdDevMultiplier");
}
_openingRangeMinutes = openingRangeMinutes;
_stdDevMultiplier = stdDevMultiplier;
_currentSessionDate = DateTime.MinValue;
_openingRangeStart = DateTime.MinValue;
_openingRangeEnd = DateTime.MinValue;
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
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)
{
if (logger == null)
{
throw new ArgumentNullException("logger");
}
_logger = logger;
_logger.LogInformation("SimpleORBStrategy initialized with OR period {0} minutes and multiplier {1:F2}", _openingRangeMinutes, _stdDevMultiplier);
}
public StrategyIntent OnBar(BarData bar, StrategyContext context)
{
if (bar == null)
{
throw new ArgumentNullException("bar");
}
if (context == null)
{
throw new ArgumentNullException("context");
}
try
{
if (_currentSessionDate != context.CurrentTime.Date)
{
ResetSession(context.Session.SessionStart);
}
if (bar.Time <= _openingRangeEnd)
{
UpdateOpeningRange(bar);
return null;
}
if (!_openingRangeReady)
{
if (_openingRangeHigh > _openingRangeLow)
{
_openingRangeReady = true;
}
else
{
return null;
}
}
if (_tradeTaken)
{
return null;
}
var openingRange = _openingRangeHigh - _openingRangeLow;
var volatilityBuffer = openingRange * (_stdDevMultiplier - 1.0);
if (volatilityBuffer < 0)
{
volatilityBuffer = 0;
}
var longTrigger = _openingRangeHigh + volatilityBuffer;
var shortTrigger = _openingRangeLow - volatilityBuffer;
if (bar.Close > longTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Buy, openingRange, bar.Close);
}
if (bar.Close < shortTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Sell, openingRange, bar.Close);
}
return null;
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("SimpleORBStrategy OnBar failed: {0}", ex.Message);
}
throw;
}
}
public StrategyIntent OnTick(TickData tick, StrategyContext context)
{
// Most strategies don't need tick-level logic
return null;
}
public Dictionary<string, object> GetParameters()
{
var parameters = new Dictionary<string, object>();
parameters.Add("opening_range_minutes", _openingRangeMinutes);
parameters.Add("std_dev_multiplier", _stdDevMultiplier);
return parameters;
}
public void SetParameters(Dictionary<string, object> parameters)
{
// Parameters are constructor-bound for deterministic behavior in this wrapper.
// Method retained for interface compatibility.
}
private void ResetSession(DateTime sessionStart)
{
_currentSessionDate = sessionStart.Date;
_openingRangeStart = sessionStart;
_openingRangeEnd = sessionStart.AddMinutes(_openingRangeMinutes);
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
}
private void UpdateOpeningRange(BarData bar)
{
if (bar.High > _openingRangeHigh)
{
_openingRangeHigh = bar.High;
}
if (bar.Low < _openingRangeLow)
{
_openingRangeLow = bar.Low;
}
}
private StrategyIntent CreateIntent(string symbol, OrderSide side, double openingRange, double lastPrice)
{
var metadata = new Dictionary<string, object>();
metadata.Add("orb_high", _openingRangeHigh);
metadata.Add("orb_low", _openingRangeLow);
metadata.Add("orb_range", openingRange);
metadata.Add("trigger_price", lastPrice);
metadata.Add("multiplier", _stdDevMultiplier);
if (_logger != null)
{
_logger.LogInformation("SimpleORBStrategy generated {0} intent for {1}. OR High={2:F2}, OR Low={3:F2}, Last={4:F2}", side, symbol, _openingRangeHigh, _openingRangeLow, lastPrice);
}
return new StrategyIntent(
symbol,
side,
OrderType.Market,
null,
8,
16,
0.75,
"ORB breakout signal",
metadata);
}
}
#endregion
}
}

View File

@@ -1,229 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
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
{
private readonly object _lock = new object();
#region SDK Components
protected IStrategy _sdkStrategy;
protected IRiskManager _riskManager;
protected IPositionSizer _positionSizer;
protected NT8Adapter _nt8Adapter;
protected StrategyConfig _strategyConfig;
protected ILogger _logger;
#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 with default implementations.
// Derived wrappers can replace these through InitializeSdkComponents.
_logger = new BasicLogger("BaseNT8StrategyWrapper");
_riskManager = new BasicRiskManager(_logger);
_positionSizer = new BasicPositionSizer(_logger);
InitializeSdkComponents(_riskManager, _positionSizer, _logger);
}
#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)
{
if (barData == null)
throw new ArgumentNullException("barData");
if (context == null)
throw new ArgumentNullException("context");
try
{
StrategyIntent intent;
lock (_lock)
{
if (_sdkStrategy == null)
{
throw new InvalidOperationException("SDK strategy has not been initialized.");
}
intent = _sdkStrategy.OnBar(barData, context);
}
if (intent != null)
{
ExecuteIntent(intent, context);
}
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed processing bar update for {0}: {1}", context.Symbol, ex.Message);
}
throw;
}
}
#endregion
#region Private Methods
/// <summary>
/// Initialize SDK components
/// </summary>
protected virtual void InitializeSdkComponents(IRiskManager riskManager, IPositionSizer positionSizer, ILogger logger)
{
if (riskManager == null)
throw new ArgumentNullException("riskManager");
if (positionSizer == null)
throw new ArgumentNullException("positionSizer");
if (logger == null)
throw new ArgumentNullException("logger");
_riskManager = riskManager;
_positionSizer = positionSizer;
_logger = logger;
_nt8Adapter = new NT8Adapter();
_nt8Adapter.Initialize(_riskManager, _positionSizer);
CreateSdkConfiguration();
_sdkStrategy = CreateSdkStrategy();
if (_sdkStrategy == null)
throw new InvalidOperationException("CreateSdkStrategy returned null.");
_sdkStrategy.Initialize(_strategyConfig, null, _logger);
_logger.LogInformation("Base NT8 strategy wrapper initialized for symbol {0}", _strategyConfig.Symbol);
}
/// <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)
{
if (intent == null)
throw new ArgumentNullException("intent");
if (context == null)
throw new ArgumentNullException("context");
try
{
SizingResult sizingResult;
lock (_lock)
{
if (_positionSizer == null)
{
throw new InvalidOperationException("Position sizer has not been initialized.");
}
sizingResult = _positionSizer.CalculateSize(intent, context, _strategyConfig.SizingSettings);
}
_nt8Adapter.ExecuteIntent(intent, sizingResult);
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed executing intent for {0}: {1}", intent.Symbol, ex.Message);
}
throw;
}
}
#endregion
}
}

View File

@@ -1,280 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
using NT8.Adapters.NinjaTrader;
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 Constructor
/// <summary>
/// Constructor for SimpleORBNT8Wrapper
/// </summary>
public SimpleORBNT8Wrapper()
{
OpeningRangeMinutes = 30;
StdDevMultiplier = 1.0;
}
#endregion
#region Base Class Implementation
/// <summary>
/// Exposes adapter reference for integration test assertions.
/// </summary>
public NT8Adapter GetAdapterForTesting()
{
return _nt8Adapter;
}
/// <summary>
/// Create the SDK strategy implementation
/// </summary>
protected override IStrategy CreateSdkStrategy()
{
var openingRangeMinutes = OpeningRangeMinutes > 0 ? OpeningRangeMinutes : 30;
var stdDevMultiplier = StdDevMultiplier > 0.0 ? StdDevMultiplier : 1.0;
return new SimpleORBStrategy(openingRangeMinutes, stdDevMultiplier);
}
#endregion
#region Strategy Logic
/// <summary>
/// Simple ORB strategy implementation
/// </summary>
private class SimpleORBStrategy : IStrategy
{
private readonly int _openingRangeMinutes;
private readonly double _stdDevMultiplier;
private ILogger _logger;
private DateTime _currentSessionDate;
private DateTime _openingRangeStart;
private DateTime _openingRangeEnd;
private double _openingRangeHigh;
private double _openingRangeLow;
private bool _openingRangeReady;
private bool _tradeTaken;
public StrategyMetadata Metadata { get; private set; }
public SimpleORBStrategy(int openingRangeMinutes, double stdDevMultiplier)
{
if (openingRangeMinutes <= 0)
{
throw new ArgumentException("openingRangeMinutes");
}
if (stdDevMultiplier <= 0.0)
{
throw new ArgumentException("stdDevMultiplier");
}
_openingRangeMinutes = openingRangeMinutes;
_stdDevMultiplier = stdDevMultiplier;
_currentSessionDate = DateTime.MinValue;
_openingRangeStart = DateTime.MinValue;
_openingRangeEnd = DateTime.MinValue;
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
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)
{
if (logger == null)
{
throw new ArgumentNullException("logger");
}
_logger = logger;
_logger.LogInformation("SimpleORBStrategy initialized with OR period {0} minutes and multiplier {1:F2}", _openingRangeMinutes, _stdDevMultiplier);
}
public StrategyIntent OnBar(BarData bar, StrategyContext context)
{
if (bar == null)
{
throw new ArgumentNullException("bar");
}
if (context == null)
{
throw new ArgumentNullException("context");
}
try
{
if (_currentSessionDate != context.CurrentTime.Date)
{
ResetSession(context.Session.SessionStart);
}
if (bar.Time <= _openingRangeEnd)
{
UpdateOpeningRange(bar);
return null;
}
if (!_openingRangeReady)
{
if (_openingRangeHigh > _openingRangeLow)
{
_openingRangeReady = true;
}
else
{
return null;
}
}
if (_tradeTaken)
{
return null;
}
var openingRange = _openingRangeHigh - _openingRangeLow;
var volatilityBuffer = openingRange * (_stdDevMultiplier - 1.0);
if (volatilityBuffer < 0)
{
volatilityBuffer = 0;
}
var longTrigger = _openingRangeHigh + volatilityBuffer;
var shortTrigger = _openingRangeLow - volatilityBuffer;
if (bar.Close > longTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Buy, openingRange, bar.Close);
}
if (bar.Close < shortTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Sell, openingRange, bar.Close);
}
return null;
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("SimpleORBStrategy OnBar failed: {0}", ex.Message);
}
throw;
}
}
public StrategyIntent OnTick(TickData tick, StrategyContext context)
{
// Most strategies don't need tick-level logic
return null;
}
public Dictionary<string, object> GetParameters()
{
var parameters = new Dictionary<string, object>();
parameters.Add("opening_range_minutes", _openingRangeMinutes);
parameters.Add("std_dev_multiplier", _stdDevMultiplier);
return parameters;
}
public void SetParameters(Dictionary<string, object> parameters)
{
// Parameters are constructor-bound for deterministic behavior in this wrapper.
// Method retained for interface compatibility.
}
private void ResetSession(DateTime sessionStart)
{
_currentSessionDate = sessionStart.Date;
_openingRangeStart = sessionStart;
_openingRangeEnd = sessionStart.AddMinutes(_openingRangeMinutes);
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
}
private void UpdateOpeningRange(BarData bar)
{
if (bar.High > _openingRangeHigh)
{
_openingRangeHigh = bar.High;
}
if (bar.Low < _openingRangeLow)
{
_openingRangeLow = bar.Low;
}
}
private StrategyIntent CreateIntent(string symbol, OrderSide side, double openingRange, double lastPrice)
{
var metadata = new Dictionary<string, object>();
metadata.Add("orb_high", _openingRangeHigh);
metadata.Add("orb_low", _openingRangeLow);
metadata.Add("orb_range", openingRange);
metadata.Add("trigger_price", lastPrice);
metadata.Add("multiplier", _stdDevMultiplier);
if (_logger != null)
{
_logger.LogInformation("SimpleORBStrategy generated {0} intent for {1}. OR High={2:F2}, OR Low={3:F2}, Last={4:F2}", side, symbol, _openingRangeHigh, _openingRangeLow, lastPrice);
}
return new StrategyIntent(
symbol,
side,
OrderType.Market,
null,
8,
16,
0.75,
"ORB breakout signal",
metadata);
}
}
#endregion
}
}

View File

@@ -1,229 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
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
{
private readonly object _lock = new object();
#region SDK Components
protected IStrategy _sdkStrategy;
protected IRiskManager _riskManager;
protected IPositionSizer _positionSizer;
protected NT8Adapter _nt8Adapter;
protected StrategyConfig _strategyConfig;
protected ILogger _logger;
#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 with default implementations.
// Derived wrappers can replace these through InitializeSdkComponents.
_logger = new BasicLogger("BaseNT8StrategyWrapper");
_riskManager = new BasicRiskManager(_logger);
_positionSizer = new BasicPositionSizer(_logger);
InitializeSdkComponents(_riskManager, _positionSizer, _logger);
}
#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)
{
if (barData == null)
throw new ArgumentNullException("barData");
if (context == null)
throw new ArgumentNullException("context");
try
{
StrategyIntent intent;
lock (_lock)
{
if (_sdkStrategy == null)
{
throw new InvalidOperationException("SDK strategy has not been initialized.");
}
intent = _sdkStrategy.OnBar(barData, context);
}
if (intent != null)
{
ExecuteIntent(intent, context);
}
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed processing bar update for {0}: {1}", context.Symbol, ex.Message);
}
throw;
}
}
#endregion
#region Private Methods
/// <summary>
/// Initialize SDK components
/// </summary>
protected virtual void InitializeSdkComponents(IRiskManager riskManager, IPositionSizer positionSizer, ILogger logger)
{
if (riskManager == null)
throw new ArgumentNullException("riskManager");
if (positionSizer == null)
throw new ArgumentNullException("positionSizer");
if (logger == null)
throw new ArgumentNullException("logger");
_riskManager = riskManager;
_positionSizer = positionSizer;
_logger = logger;
_nt8Adapter = new NT8Adapter();
_nt8Adapter.Initialize(_riskManager, _positionSizer);
CreateSdkConfiguration();
_sdkStrategy = CreateSdkStrategy();
if (_sdkStrategy == null)
throw new InvalidOperationException("CreateSdkStrategy returned null.");
_sdkStrategy.Initialize(_strategyConfig, null, _logger);
_logger.LogInformation("Base NT8 strategy wrapper initialized for symbol {0}", _strategyConfig.Symbol);
}
/// <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)
{
if (intent == null)
throw new ArgumentNullException("intent");
if (context == null)
throw new ArgumentNullException("context");
try
{
SizingResult sizingResult;
lock (_lock)
{
if (_positionSizer == null)
{
throw new InvalidOperationException("Position sizer has not been initialized.");
}
sizingResult = _positionSizer.CalculateSize(intent, context, _strategyConfig.SizingSettings);
}
_nt8Adapter.ExecuteIntent(intent, sizingResult);
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed executing intent for {0}: {1}", intent.Symbol, ex.Message);
}
throw;
}
}
#endregion
}
}

View File

@@ -1,280 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
using NT8.Adapters.NinjaTrader;
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 Constructor
/// <summary>
/// Constructor for SimpleORBNT8Wrapper
/// </summary>
public SimpleORBNT8Wrapper()
{
OpeningRangeMinutes = 30;
StdDevMultiplier = 1.0;
}
#endregion
#region Base Class Implementation
/// <summary>
/// Exposes adapter reference for integration test assertions.
/// </summary>
public NT8Adapter GetAdapterForTesting()
{
return _nt8Adapter;
}
/// <summary>
/// Create the SDK strategy implementation
/// </summary>
protected override IStrategy CreateSdkStrategy()
{
var openingRangeMinutes = OpeningRangeMinutes > 0 ? OpeningRangeMinutes : 30;
var stdDevMultiplier = StdDevMultiplier > 0.0 ? StdDevMultiplier : 1.0;
return new SimpleORBStrategy(openingRangeMinutes, stdDevMultiplier);
}
#endregion
#region Strategy Logic
/// <summary>
/// Simple ORB strategy implementation
/// </summary>
private class SimpleORBStrategy : IStrategy
{
private readonly int _openingRangeMinutes;
private readonly double _stdDevMultiplier;
private ILogger _logger;
private DateTime _currentSessionDate;
private DateTime _openingRangeStart;
private DateTime _openingRangeEnd;
private double _openingRangeHigh;
private double _openingRangeLow;
private bool _openingRangeReady;
private bool _tradeTaken;
public StrategyMetadata Metadata { get; private set; }
public SimpleORBStrategy(int openingRangeMinutes, double stdDevMultiplier)
{
if (openingRangeMinutes <= 0)
{
throw new ArgumentException("openingRangeMinutes");
}
if (stdDevMultiplier <= 0.0)
{
throw new ArgumentException("stdDevMultiplier");
}
_openingRangeMinutes = openingRangeMinutes;
_stdDevMultiplier = stdDevMultiplier;
_currentSessionDate = DateTime.MinValue;
_openingRangeStart = DateTime.MinValue;
_openingRangeEnd = DateTime.MinValue;
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
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)
{
if (logger == null)
{
throw new ArgumentNullException("logger");
}
_logger = logger;
_logger.LogInformation("SimpleORBStrategy initialized with OR period {0} minutes and multiplier {1:F2}", _openingRangeMinutes, _stdDevMultiplier);
}
public StrategyIntent OnBar(BarData bar, StrategyContext context)
{
if (bar == null)
{
throw new ArgumentNullException("bar");
}
if (context == null)
{
throw new ArgumentNullException("context");
}
try
{
if (_currentSessionDate != context.CurrentTime.Date)
{
ResetSession(context.Session.SessionStart);
}
if (bar.Time <= _openingRangeEnd)
{
UpdateOpeningRange(bar);
return null;
}
if (!_openingRangeReady)
{
if (_openingRangeHigh > _openingRangeLow)
{
_openingRangeReady = true;
}
else
{
return null;
}
}
if (_tradeTaken)
{
return null;
}
var openingRange = _openingRangeHigh - _openingRangeLow;
var volatilityBuffer = openingRange * (_stdDevMultiplier - 1.0);
if (volatilityBuffer < 0)
{
volatilityBuffer = 0;
}
var longTrigger = _openingRangeHigh + volatilityBuffer;
var shortTrigger = _openingRangeLow - volatilityBuffer;
if (bar.Close > longTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Buy, openingRange, bar.Close);
}
if (bar.Close < shortTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Sell, openingRange, bar.Close);
}
return null;
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("SimpleORBStrategy OnBar failed: {0}", ex.Message);
}
throw;
}
}
public StrategyIntent OnTick(TickData tick, StrategyContext context)
{
// Most strategies don't need tick-level logic
return null;
}
public Dictionary<string, object> GetParameters()
{
var parameters = new Dictionary<string, object>();
parameters.Add("opening_range_minutes", _openingRangeMinutes);
parameters.Add("std_dev_multiplier", _stdDevMultiplier);
return parameters;
}
public void SetParameters(Dictionary<string, object> parameters)
{
// Parameters are constructor-bound for deterministic behavior in this wrapper.
// Method retained for interface compatibility.
}
private void ResetSession(DateTime sessionStart)
{
_currentSessionDate = sessionStart.Date;
_openingRangeStart = sessionStart;
_openingRangeEnd = sessionStart.AddMinutes(_openingRangeMinutes);
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
}
private void UpdateOpeningRange(BarData bar)
{
if (bar.High > _openingRangeHigh)
{
_openingRangeHigh = bar.High;
}
if (bar.Low < _openingRangeLow)
{
_openingRangeLow = bar.Low;
}
}
private StrategyIntent CreateIntent(string symbol, OrderSide side, double openingRange, double lastPrice)
{
var metadata = new Dictionary<string, object>();
metadata.Add("orb_high", _openingRangeHigh);
metadata.Add("orb_low", _openingRangeLow);
metadata.Add("orb_range", openingRange);
metadata.Add("trigger_price", lastPrice);
metadata.Add("multiplier", _stdDevMultiplier);
if (_logger != null)
{
_logger.LogInformation("SimpleORBStrategy generated {0} intent for {1}. OR High={2:F2}, OR Low={3:F2}, Last={4:F2}", side, symbol, _openingRangeHigh, _openingRangeLow, lastPrice);
}
return new StrategyIntent(
symbol,
side,
OrderType.Market,
null,
8,
16,
0.75,
"ORB breakout signal",
metadata);
}
}
#endregion
}
}

View File

@@ -1,6 +0,0 @@
Deployment manifest
Timestamp: 20260224_154420
Source Core DLL: C:\dev\nt8-sdk\deployment\..\src\NT8.Core\bin\Release\net48\NT8.Core.dll
Source Adapters DLL: C:\dev\nt8-sdk\deployment\..\src\NT8.Adapters\bin\Release\net48\NT8.Adapters.dll
Destination Custom Folder: C:\Users\billy\Documents\NinjaTrader 8\bin\Custom
Destination Strategies Folder: C:\Users\billy\Documents\NinjaTrader 8\bin\Custom\Strategies

View File

@@ -1,229 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
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
{
private readonly object _lock = new object();
#region SDK Components
protected IStrategy _sdkStrategy;
protected IRiskManager _riskManager;
protected IPositionSizer _positionSizer;
protected NT8Adapter _nt8Adapter;
protected StrategyConfig _strategyConfig;
protected ILogger _logger;
#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 with default implementations.
// Derived wrappers can replace these through InitializeSdkComponents.
_logger = new BasicLogger("BaseNT8StrategyWrapper");
_riskManager = new BasicRiskManager(_logger);
_positionSizer = new BasicPositionSizer(_logger);
InitializeSdkComponents(_riskManager, _positionSizer, _logger);
}
#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)
{
if (barData == null)
throw new ArgumentNullException("barData");
if (context == null)
throw new ArgumentNullException("context");
try
{
StrategyIntent intent;
lock (_lock)
{
if (_sdkStrategy == null)
{
throw new InvalidOperationException("SDK strategy has not been initialized.");
}
intent = _sdkStrategy.OnBar(barData, context);
}
if (intent != null)
{
ExecuteIntent(intent, context);
}
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed processing bar update for {0}: {1}", context.Symbol, ex.Message);
}
throw;
}
}
#endregion
#region Private Methods
/// <summary>
/// Initialize SDK components
/// </summary>
protected virtual void InitializeSdkComponents(IRiskManager riskManager, IPositionSizer positionSizer, ILogger logger)
{
if (riskManager == null)
throw new ArgumentNullException("riskManager");
if (positionSizer == null)
throw new ArgumentNullException("positionSizer");
if (logger == null)
throw new ArgumentNullException("logger");
_riskManager = riskManager;
_positionSizer = positionSizer;
_logger = logger;
_nt8Adapter = new NT8Adapter();
_nt8Adapter.Initialize(_riskManager, _positionSizer);
CreateSdkConfiguration();
_sdkStrategy = CreateSdkStrategy();
if (_sdkStrategy == null)
throw new InvalidOperationException("CreateSdkStrategy returned null.");
_sdkStrategy.Initialize(_strategyConfig, null, _logger);
_logger.LogInformation("Base NT8 strategy wrapper initialized for symbol {0}", _strategyConfig.Symbol);
}
/// <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)
{
if (intent == null)
throw new ArgumentNullException("intent");
if (context == null)
throw new ArgumentNullException("context");
try
{
SizingResult sizingResult;
lock (_lock)
{
if (_positionSizer == null)
{
throw new InvalidOperationException("Position sizer has not been initialized.");
}
sizingResult = _positionSizer.CalculateSize(intent, context, _strategyConfig.SizingSettings);
}
_nt8Adapter.ExecuteIntent(intent, sizingResult);
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed executing intent for {0}: {1}", intent.Symbol, ex.Message);
}
throw;
}
}
#endregion
}
}

View File

@@ -1,280 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
using NT8.Adapters.NinjaTrader;
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 Constructor
/// <summary>
/// Constructor for SimpleORBNT8Wrapper
/// </summary>
public SimpleORBNT8Wrapper()
{
OpeningRangeMinutes = 30;
StdDevMultiplier = 1.0;
}
#endregion
#region Base Class Implementation
/// <summary>
/// Exposes adapter reference for integration test assertions.
/// </summary>
public NT8Adapter GetAdapterForTesting()
{
return _nt8Adapter;
}
/// <summary>
/// Create the SDK strategy implementation
/// </summary>
protected override IStrategy CreateSdkStrategy()
{
var openingRangeMinutes = OpeningRangeMinutes > 0 ? OpeningRangeMinutes : 30;
var stdDevMultiplier = StdDevMultiplier > 0.0 ? StdDevMultiplier : 1.0;
return new SimpleORBStrategy(openingRangeMinutes, stdDevMultiplier);
}
#endregion
#region Strategy Logic
/// <summary>
/// Simple ORB strategy implementation
/// </summary>
private class SimpleORBStrategy : IStrategy
{
private readonly int _openingRangeMinutes;
private readonly double _stdDevMultiplier;
private ILogger _logger;
private DateTime _currentSessionDate;
private DateTime _openingRangeStart;
private DateTime _openingRangeEnd;
private double _openingRangeHigh;
private double _openingRangeLow;
private bool _openingRangeReady;
private bool _tradeTaken;
public StrategyMetadata Metadata { get; private set; }
public SimpleORBStrategy(int openingRangeMinutes, double stdDevMultiplier)
{
if (openingRangeMinutes <= 0)
{
throw new ArgumentException("openingRangeMinutes");
}
if (stdDevMultiplier <= 0.0)
{
throw new ArgumentException("stdDevMultiplier");
}
_openingRangeMinutes = openingRangeMinutes;
_stdDevMultiplier = stdDevMultiplier;
_currentSessionDate = DateTime.MinValue;
_openingRangeStart = DateTime.MinValue;
_openingRangeEnd = DateTime.MinValue;
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
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)
{
if (logger == null)
{
throw new ArgumentNullException("logger");
}
_logger = logger;
_logger.LogInformation("SimpleORBStrategy initialized with OR period {0} minutes and multiplier {1:F2}", _openingRangeMinutes, _stdDevMultiplier);
}
public StrategyIntent OnBar(BarData bar, StrategyContext context)
{
if (bar == null)
{
throw new ArgumentNullException("bar");
}
if (context == null)
{
throw new ArgumentNullException("context");
}
try
{
if (_currentSessionDate != context.CurrentTime.Date)
{
ResetSession(context.Session.SessionStart);
}
if (bar.Time <= _openingRangeEnd)
{
UpdateOpeningRange(bar);
return null;
}
if (!_openingRangeReady)
{
if (_openingRangeHigh > _openingRangeLow)
{
_openingRangeReady = true;
}
else
{
return null;
}
}
if (_tradeTaken)
{
return null;
}
var openingRange = _openingRangeHigh - _openingRangeLow;
var volatilityBuffer = openingRange * (_stdDevMultiplier - 1.0);
if (volatilityBuffer < 0)
{
volatilityBuffer = 0;
}
var longTrigger = _openingRangeHigh + volatilityBuffer;
var shortTrigger = _openingRangeLow - volatilityBuffer;
if (bar.Close > longTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Buy, openingRange, bar.Close);
}
if (bar.Close < shortTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Sell, openingRange, bar.Close);
}
return null;
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("SimpleORBStrategy OnBar failed: {0}", ex.Message);
}
throw;
}
}
public StrategyIntent OnTick(TickData tick, StrategyContext context)
{
// Most strategies don't need tick-level logic
return null;
}
public Dictionary<string, object> GetParameters()
{
var parameters = new Dictionary<string, object>();
parameters.Add("opening_range_minutes", _openingRangeMinutes);
parameters.Add("std_dev_multiplier", _stdDevMultiplier);
return parameters;
}
public void SetParameters(Dictionary<string, object> parameters)
{
// Parameters are constructor-bound for deterministic behavior in this wrapper.
// Method retained for interface compatibility.
}
private void ResetSession(DateTime sessionStart)
{
_currentSessionDate = sessionStart.Date;
_openingRangeStart = sessionStart;
_openingRangeEnd = sessionStart.AddMinutes(_openingRangeMinutes);
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
}
private void UpdateOpeningRange(BarData bar)
{
if (bar.High > _openingRangeHigh)
{
_openingRangeHigh = bar.High;
}
if (bar.Low < _openingRangeLow)
{
_openingRangeLow = bar.Low;
}
}
private StrategyIntent CreateIntent(string symbol, OrderSide side, double openingRange, double lastPrice)
{
var metadata = new Dictionary<string, object>();
metadata.Add("orb_high", _openingRangeHigh);
metadata.Add("orb_low", _openingRangeLow);
metadata.Add("orb_range", openingRange);
metadata.Add("trigger_price", lastPrice);
metadata.Add("multiplier", _stdDevMultiplier);
if (_logger != null)
{
_logger.LogInformation("SimpleORBStrategy generated {0} intent for {1}. OR High={2:F2}, OR Low={3:F2}, Last={4:F2}", side, symbol, _openingRangeHigh, _openingRangeLow, lastPrice);
}
return new StrategyIntent(
symbol,
side,
OrderType.Market,
null,
8,
16,
0.75,
"ORB breakout signal",
metadata);
}
}
#endregion
}
}

View File

@@ -1,6 +0,0 @@
Deployment manifest
Timestamp: 20260224_155513
Source Core DLL: C:\dev\nt8-sdk\deployment\..\src\NT8.Core\bin\Release\net48\NT8.Core.dll
Source Adapters DLL: C:\dev\nt8-sdk\deployment\..\src\NT8.Adapters\bin\Release\net48\NT8.Adapters.dll
Destination Custom Folder: C:\Users\billy\Documents\NinjaTrader 8\bin\Custom
Destination Strategies Folder: C:\Users\billy\Documents\NinjaTrader 8\bin\Custom\Strategies

View File

@@ -1,229 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
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
{
private readonly object _lock = new object();
#region SDK Components
protected IStrategy _sdkStrategy;
protected IRiskManager _riskManager;
protected IPositionSizer _positionSizer;
protected NT8Adapter _nt8Adapter;
protected StrategyConfig _strategyConfig;
protected ILogger _logger;
#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 with default implementations.
// Derived wrappers can replace these through InitializeSdkComponents.
_logger = new BasicLogger("BaseNT8StrategyWrapper");
_riskManager = new BasicRiskManager(_logger);
_positionSizer = new BasicPositionSizer(_logger);
InitializeSdkComponents(_riskManager, _positionSizer, _logger);
}
#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)
{
if (barData == null)
throw new ArgumentNullException("barData");
if (context == null)
throw new ArgumentNullException("context");
try
{
StrategyIntent intent;
lock (_lock)
{
if (_sdkStrategy == null)
{
throw new InvalidOperationException("SDK strategy has not been initialized.");
}
intent = _sdkStrategy.OnBar(barData, context);
}
if (intent != null)
{
ExecuteIntent(intent, context);
}
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed processing bar update for {0}: {1}", context.Symbol, ex.Message);
}
throw;
}
}
#endregion
#region Private Methods
/// <summary>
/// Initialize SDK components
/// </summary>
protected virtual void InitializeSdkComponents(IRiskManager riskManager, IPositionSizer positionSizer, ILogger logger)
{
if (riskManager == null)
throw new ArgumentNullException("riskManager");
if (positionSizer == null)
throw new ArgumentNullException("positionSizer");
if (logger == null)
throw new ArgumentNullException("logger");
_riskManager = riskManager;
_positionSizer = positionSizer;
_logger = logger;
_nt8Adapter = new NT8Adapter();
_nt8Adapter.Initialize(_riskManager, _positionSizer);
CreateSdkConfiguration();
_sdkStrategy = CreateSdkStrategy();
if (_sdkStrategy == null)
throw new InvalidOperationException("CreateSdkStrategy returned null.");
_sdkStrategy.Initialize(_strategyConfig, null, _logger);
_logger.LogInformation("Base NT8 strategy wrapper initialized for symbol {0}", _strategyConfig.Symbol);
}
/// <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)
{
if (intent == null)
throw new ArgumentNullException("intent");
if (context == null)
throw new ArgumentNullException("context");
try
{
SizingResult sizingResult;
lock (_lock)
{
if (_positionSizer == null)
{
throw new InvalidOperationException("Position sizer has not been initialized.");
}
sizingResult = _positionSizer.CalculateSize(intent, context, _strategyConfig.SizingSettings);
}
_nt8Adapter.ExecuteIntent(intent, sizingResult);
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed executing intent for {0}: {1}", intent.Symbol, ex.Message);
}
throw;
}
}
#endregion
}
}

View File

@@ -1,280 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
using NT8.Adapters.NinjaTrader;
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 Constructor
/// <summary>
/// Constructor for SimpleORBNT8Wrapper
/// </summary>
public SimpleORBNT8Wrapper()
{
OpeningRangeMinutes = 30;
StdDevMultiplier = 1.0;
}
#endregion
#region Base Class Implementation
/// <summary>
/// Exposes adapter reference for integration test assertions.
/// </summary>
public NT8Adapter GetAdapterForTesting()
{
return _nt8Adapter;
}
/// <summary>
/// Create the SDK strategy implementation
/// </summary>
protected override IStrategy CreateSdkStrategy()
{
var openingRangeMinutes = OpeningRangeMinutes > 0 ? OpeningRangeMinutes : 30;
var stdDevMultiplier = StdDevMultiplier > 0.0 ? StdDevMultiplier : 1.0;
return new SimpleORBStrategy(openingRangeMinutes, stdDevMultiplier);
}
#endregion
#region Strategy Logic
/// <summary>
/// Simple ORB strategy implementation
/// </summary>
private class SimpleORBStrategy : IStrategy
{
private readonly int _openingRangeMinutes;
private readonly double _stdDevMultiplier;
private ILogger _logger;
private DateTime _currentSessionDate;
private DateTime _openingRangeStart;
private DateTime _openingRangeEnd;
private double _openingRangeHigh;
private double _openingRangeLow;
private bool _openingRangeReady;
private bool _tradeTaken;
public StrategyMetadata Metadata { get; private set; }
public SimpleORBStrategy(int openingRangeMinutes, double stdDevMultiplier)
{
if (openingRangeMinutes <= 0)
{
throw new ArgumentException("openingRangeMinutes");
}
if (stdDevMultiplier <= 0.0)
{
throw new ArgumentException("stdDevMultiplier");
}
_openingRangeMinutes = openingRangeMinutes;
_stdDevMultiplier = stdDevMultiplier;
_currentSessionDate = DateTime.MinValue;
_openingRangeStart = DateTime.MinValue;
_openingRangeEnd = DateTime.MinValue;
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
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)
{
if (logger == null)
{
throw new ArgumentNullException("logger");
}
_logger = logger;
_logger.LogInformation("SimpleORBStrategy initialized with OR period {0} minutes and multiplier {1:F2}", _openingRangeMinutes, _stdDevMultiplier);
}
public StrategyIntent OnBar(BarData bar, StrategyContext context)
{
if (bar == null)
{
throw new ArgumentNullException("bar");
}
if (context == null)
{
throw new ArgumentNullException("context");
}
try
{
if (_currentSessionDate != context.CurrentTime.Date)
{
ResetSession(context.Session.SessionStart);
}
if (bar.Time <= _openingRangeEnd)
{
UpdateOpeningRange(bar);
return null;
}
if (!_openingRangeReady)
{
if (_openingRangeHigh > _openingRangeLow)
{
_openingRangeReady = true;
}
else
{
return null;
}
}
if (_tradeTaken)
{
return null;
}
var openingRange = _openingRangeHigh - _openingRangeLow;
var volatilityBuffer = openingRange * (_stdDevMultiplier - 1.0);
if (volatilityBuffer < 0)
{
volatilityBuffer = 0;
}
var longTrigger = _openingRangeHigh + volatilityBuffer;
var shortTrigger = _openingRangeLow - volatilityBuffer;
if (bar.Close > longTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Buy, openingRange, bar.Close);
}
if (bar.Close < shortTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Sell, openingRange, bar.Close);
}
return null;
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("SimpleORBStrategy OnBar failed: {0}", ex.Message);
}
throw;
}
}
public StrategyIntent OnTick(TickData tick, StrategyContext context)
{
// Most strategies don't need tick-level logic
return null;
}
public Dictionary<string, object> GetParameters()
{
var parameters = new Dictionary<string, object>();
parameters.Add("opening_range_minutes", _openingRangeMinutes);
parameters.Add("std_dev_multiplier", _stdDevMultiplier);
return parameters;
}
public void SetParameters(Dictionary<string, object> parameters)
{
// Parameters are constructor-bound for deterministic behavior in this wrapper.
// Method retained for interface compatibility.
}
private void ResetSession(DateTime sessionStart)
{
_currentSessionDate = sessionStart.Date;
_openingRangeStart = sessionStart;
_openingRangeEnd = sessionStart.AddMinutes(_openingRangeMinutes);
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
}
private void UpdateOpeningRange(BarData bar)
{
if (bar.High > _openingRangeHigh)
{
_openingRangeHigh = bar.High;
}
if (bar.Low < _openingRangeLow)
{
_openingRangeLow = bar.Low;
}
}
private StrategyIntent CreateIntent(string symbol, OrderSide side, double openingRange, double lastPrice)
{
var metadata = new Dictionary<string, object>();
metadata.Add("orb_high", _openingRangeHigh);
metadata.Add("orb_low", _openingRangeLow);
metadata.Add("orb_range", openingRange);
metadata.Add("trigger_price", lastPrice);
metadata.Add("multiplier", _stdDevMultiplier);
if (_logger != null)
{
_logger.LogInformation("SimpleORBStrategy generated {0} intent for {1}. OR High={2:F2}, OR Low={3:F2}, Last={4:F2}", side, symbol, _openingRangeHigh, _openingRangeLow, lastPrice);
}
return new StrategyIntent(
symbol,
side,
OrderType.Market,
null,
8,
16,
0.75,
"ORB breakout signal",
metadata);
}
}
#endregion
}
}

View File

@@ -1,6 +0,0 @@
Deployment manifest
Timestamp: 20260224_160009
Source Core DLL: C:\dev\nt8-sdk\deployment\..\src\NT8.Core\bin\Release\net48\NT8.Core.dll
Source Adapters DLL: C:\dev\nt8-sdk\deployment\..\src\NT8.Adapters\bin\Release\net48\NT8.Adapters.dll
Destination Custom Folder: C:\Users\billy\Documents\NinjaTrader 8\bin\Custom
Destination Strategies Folder: C:\Users\billy\Documents\NinjaTrader 8\bin\Custom\Strategies

View File

@@ -1,229 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
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
{
private readonly object _lock = new object();
#region SDK Components
protected IStrategy _sdkStrategy;
protected IRiskManager _riskManager;
protected IPositionSizer _positionSizer;
protected NT8Adapter _nt8Adapter;
protected StrategyConfig _strategyConfig;
protected ILogger _logger;
#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 with default implementations.
// Derived wrappers can replace these through InitializeSdkComponents.
_logger = new BasicLogger("BaseNT8StrategyWrapper");
_riskManager = new BasicRiskManager(_logger);
_positionSizer = new BasicPositionSizer(_logger);
InitializeSdkComponents(_riskManager, _positionSizer, _logger);
}
#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)
{
if (barData == null)
throw new ArgumentNullException("barData");
if (context == null)
throw new ArgumentNullException("context");
try
{
StrategyIntent intent;
lock (_lock)
{
if (_sdkStrategy == null)
{
throw new InvalidOperationException("SDK strategy has not been initialized.");
}
intent = _sdkStrategy.OnBar(barData, context);
}
if (intent != null)
{
ExecuteIntent(intent, context);
}
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed processing bar update for {0}: {1}", context.Symbol, ex.Message);
}
throw;
}
}
#endregion
#region Private Methods
/// <summary>
/// Initialize SDK components
/// </summary>
protected virtual void InitializeSdkComponents(IRiskManager riskManager, IPositionSizer positionSizer, ILogger logger)
{
if (riskManager == null)
throw new ArgumentNullException("riskManager");
if (positionSizer == null)
throw new ArgumentNullException("positionSizer");
if (logger == null)
throw new ArgumentNullException("logger");
_riskManager = riskManager;
_positionSizer = positionSizer;
_logger = logger;
_nt8Adapter = new NT8Adapter();
_nt8Adapter.Initialize(_riskManager, _positionSizer);
CreateSdkConfiguration();
_sdkStrategy = CreateSdkStrategy();
if (_sdkStrategy == null)
throw new InvalidOperationException("CreateSdkStrategy returned null.");
_sdkStrategy.Initialize(_strategyConfig, null, _logger);
_logger.LogInformation("Base NT8 strategy wrapper initialized for symbol {0}", _strategyConfig.Symbol);
}
/// <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)
{
if (intent == null)
throw new ArgumentNullException("intent");
if (context == null)
throw new ArgumentNullException("context");
try
{
SizingResult sizingResult;
lock (_lock)
{
if (_positionSizer == null)
{
throw new InvalidOperationException("Position sizer has not been initialized.");
}
sizingResult = _positionSizer.CalculateSize(intent, context, _strategyConfig.SizingSettings);
}
_nt8Adapter.ExecuteIntent(intent, sizingResult);
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed executing intent for {0}: {1}", intent.Symbol, ex.Message);
}
throw;
}
}
#endregion
}
}

View File

@@ -1,280 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
using NT8.Adapters.NinjaTrader;
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 Constructor
/// <summary>
/// Constructor for SimpleORBNT8Wrapper
/// </summary>
public SimpleORBNT8Wrapper()
{
OpeningRangeMinutes = 30;
StdDevMultiplier = 1.0;
}
#endregion
#region Base Class Implementation
/// <summary>
/// Exposes adapter reference for integration test assertions.
/// </summary>
public NT8Adapter GetAdapterForTesting()
{
return _nt8Adapter;
}
/// <summary>
/// Create the SDK strategy implementation
/// </summary>
protected override IStrategy CreateSdkStrategy()
{
var openingRangeMinutes = OpeningRangeMinutes > 0 ? OpeningRangeMinutes : 30;
var stdDevMultiplier = StdDevMultiplier > 0.0 ? StdDevMultiplier : 1.0;
return new SimpleORBStrategy(openingRangeMinutes, stdDevMultiplier);
}
#endregion
#region Strategy Logic
/// <summary>
/// Simple ORB strategy implementation
/// </summary>
private class SimpleORBStrategy : IStrategy
{
private readonly int _openingRangeMinutes;
private readonly double _stdDevMultiplier;
private ILogger _logger;
private DateTime _currentSessionDate;
private DateTime _openingRangeStart;
private DateTime _openingRangeEnd;
private double _openingRangeHigh;
private double _openingRangeLow;
private bool _openingRangeReady;
private bool _tradeTaken;
public StrategyMetadata Metadata { get; private set; }
public SimpleORBStrategy(int openingRangeMinutes, double stdDevMultiplier)
{
if (openingRangeMinutes <= 0)
{
throw new ArgumentException("openingRangeMinutes");
}
if (stdDevMultiplier <= 0.0)
{
throw new ArgumentException("stdDevMultiplier");
}
_openingRangeMinutes = openingRangeMinutes;
_stdDevMultiplier = stdDevMultiplier;
_currentSessionDate = DateTime.MinValue;
_openingRangeStart = DateTime.MinValue;
_openingRangeEnd = DateTime.MinValue;
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
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)
{
if (logger == null)
{
throw new ArgumentNullException("logger");
}
_logger = logger;
_logger.LogInformation("SimpleORBStrategy initialized with OR period {0} minutes and multiplier {1:F2}", _openingRangeMinutes, _stdDevMultiplier);
}
public StrategyIntent OnBar(BarData bar, StrategyContext context)
{
if (bar == null)
{
throw new ArgumentNullException("bar");
}
if (context == null)
{
throw new ArgumentNullException("context");
}
try
{
if (_currentSessionDate != context.CurrentTime.Date)
{
ResetSession(context.Session.SessionStart);
}
if (bar.Time <= _openingRangeEnd)
{
UpdateOpeningRange(bar);
return null;
}
if (!_openingRangeReady)
{
if (_openingRangeHigh > _openingRangeLow)
{
_openingRangeReady = true;
}
else
{
return null;
}
}
if (_tradeTaken)
{
return null;
}
var openingRange = _openingRangeHigh - _openingRangeLow;
var volatilityBuffer = openingRange * (_stdDevMultiplier - 1.0);
if (volatilityBuffer < 0)
{
volatilityBuffer = 0;
}
var longTrigger = _openingRangeHigh + volatilityBuffer;
var shortTrigger = _openingRangeLow - volatilityBuffer;
if (bar.Close > longTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Buy, openingRange, bar.Close);
}
if (bar.Close < shortTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Sell, openingRange, bar.Close);
}
return null;
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("SimpleORBStrategy OnBar failed: {0}", ex.Message);
}
throw;
}
}
public StrategyIntent OnTick(TickData tick, StrategyContext context)
{
// Most strategies don't need tick-level logic
return null;
}
public Dictionary<string, object> GetParameters()
{
var parameters = new Dictionary<string, object>();
parameters.Add("opening_range_minutes", _openingRangeMinutes);
parameters.Add("std_dev_multiplier", _stdDevMultiplier);
return parameters;
}
public void SetParameters(Dictionary<string, object> parameters)
{
// Parameters are constructor-bound for deterministic behavior in this wrapper.
// Method retained for interface compatibility.
}
private void ResetSession(DateTime sessionStart)
{
_currentSessionDate = sessionStart.Date;
_openingRangeStart = sessionStart;
_openingRangeEnd = sessionStart.AddMinutes(_openingRangeMinutes);
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
}
private void UpdateOpeningRange(BarData bar)
{
if (bar.High > _openingRangeHigh)
{
_openingRangeHigh = bar.High;
}
if (bar.Low < _openingRangeLow)
{
_openingRangeLow = bar.Low;
}
}
private StrategyIntent CreateIntent(string symbol, OrderSide side, double openingRange, double lastPrice)
{
var metadata = new Dictionary<string, object>();
metadata.Add("orb_high", _openingRangeHigh);
metadata.Add("orb_low", _openingRangeLow);
metadata.Add("orb_range", openingRange);
metadata.Add("trigger_price", lastPrice);
metadata.Add("multiplier", _stdDevMultiplier);
if (_logger != null)
{
_logger.LogInformation("SimpleORBStrategy generated {0} intent for {1}. OR High={2:F2}, OR Low={3:F2}, Last={4:F2}", side, symbol, _openingRangeHigh, _openingRangeLow, lastPrice);
}
return new StrategyIntent(
symbol,
side,
OrderType.Market,
null,
8,
16,
0.75,
"ORB breakout signal",
metadata);
}
}
#endregion
}
}

View File

@@ -1,6 +0,0 @@
Deployment manifest
Timestamp: 20260224_160457
Source Core DLL: C:\dev\nt8-sdk\deployment\..\src\NT8.Core\bin\Release\net48\NT8.Core.dll
Source Adapters DLL: C:\dev\nt8-sdk\deployment\..\src\NT8.Adapters\bin\Release\net48\NT8.Adapters.dll
Destination Custom Folder: C:\Users\billy\Documents\NinjaTrader 8\bin\Custom
Destination Strategies Folder: C:\Users\billy\Documents\NinjaTrader 8\bin\Custom\Strategies

View File

@@ -1,229 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
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
{
private readonly object _lock = new object();
#region SDK Components
protected IStrategy _sdkStrategy;
protected IRiskManager _riskManager;
protected IPositionSizer _positionSizer;
protected NT8Adapter _nt8Adapter;
protected StrategyConfig _strategyConfig;
protected ILogger _logger;
#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 with default implementations.
// Derived wrappers can replace these through InitializeSdkComponents.
_logger = new BasicLogger("BaseNT8StrategyWrapper");
_riskManager = new BasicRiskManager(_logger);
_positionSizer = new BasicPositionSizer(_logger);
InitializeSdkComponents(_riskManager, _positionSizer, _logger);
}
#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)
{
if (barData == null)
throw new ArgumentNullException("barData");
if (context == null)
throw new ArgumentNullException("context");
try
{
StrategyIntent intent;
lock (_lock)
{
if (_sdkStrategy == null)
{
throw new InvalidOperationException("SDK strategy has not been initialized.");
}
intent = _sdkStrategy.OnBar(barData, context);
}
if (intent != null)
{
ExecuteIntent(intent, context);
}
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed processing bar update for {0}: {1}", context.Symbol, ex.Message);
}
throw;
}
}
#endregion
#region Private Methods
/// <summary>
/// Initialize SDK components
/// </summary>
protected virtual void InitializeSdkComponents(IRiskManager riskManager, IPositionSizer positionSizer, ILogger logger)
{
if (riskManager == null)
throw new ArgumentNullException("riskManager");
if (positionSizer == null)
throw new ArgumentNullException("positionSizer");
if (logger == null)
throw new ArgumentNullException("logger");
_riskManager = riskManager;
_positionSizer = positionSizer;
_logger = logger;
_nt8Adapter = new NT8Adapter();
_nt8Adapter.Initialize(_riskManager, _positionSizer);
CreateSdkConfiguration();
_sdkStrategy = CreateSdkStrategy();
if (_sdkStrategy == null)
throw new InvalidOperationException("CreateSdkStrategy returned null.");
_sdkStrategy.Initialize(_strategyConfig, null, _logger);
_logger.LogInformation("Base NT8 strategy wrapper initialized for symbol {0}", _strategyConfig.Symbol);
}
/// <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)
{
if (intent == null)
throw new ArgumentNullException("intent");
if (context == null)
throw new ArgumentNullException("context");
try
{
SizingResult sizingResult;
lock (_lock)
{
if (_positionSizer == null)
{
throw new InvalidOperationException("Position sizer has not been initialized.");
}
sizingResult = _positionSizer.CalculateSize(intent, context, _strategyConfig.SizingSettings);
}
_nt8Adapter.ExecuteIntent(intent, sizingResult);
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed executing intent for {0}: {1}", intent.Symbol, ex.Message);
}
throw;
}
}
#endregion
}
}

View File

@@ -1,280 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
using NT8.Adapters.NinjaTrader;
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 Constructor
/// <summary>
/// Constructor for SimpleORBNT8Wrapper
/// </summary>
public SimpleORBNT8Wrapper()
{
OpeningRangeMinutes = 30;
StdDevMultiplier = 1.0;
}
#endregion
#region Base Class Implementation
/// <summary>
/// Exposes adapter reference for integration test assertions.
/// </summary>
public NT8Adapter GetAdapterForTesting()
{
return _nt8Adapter;
}
/// <summary>
/// Create the SDK strategy implementation
/// </summary>
protected override IStrategy CreateSdkStrategy()
{
var openingRangeMinutes = OpeningRangeMinutes > 0 ? OpeningRangeMinutes : 30;
var stdDevMultiplier = StdDevMultiplier > 0.0 ? StdDevMultiplier : 1.0;
return new SimpleORBStrategy(openingRangeMinutes, stdDevMultiplier);
}
#endregion
#region Strategy Logic
/// <summary>
/// Simple ORB strategy implementation
/// </summary>
private class SimpleORBStrategy : IStrategy
{
private readonly int _openingRangeMinutes;
private readonly double _stdDevMultiplier;
private ILogger _logger;
private DateTime _currentSessionDate;
private DateTime _openingRangeStart;
private DateTime _openingRangeEnd;
private double _openingRangeHigh;
private double _openingRangeLow;
private bool _openingRangeReady;
private bool _tradeTaken;
public StrategyMetadata Metadata { get; private set; }
public SimpleORBStrategy(int openingRangeMinutes, double stdDevMultiplier)
{
if (openingRangeMinutes <= 0)
{
throw new ArgumentException("openingRangeMinutes");
}
if (stdDevMultiplier <= 0.0)
{
throw new ArgumentException("stdDevMultiplier");
}
_openingRangeMinutes = openingRangeMinutes;
_stdDevMultiplier = stdDevMultiplier;
_currentSessionDate = DateTime.MinValue;
_openingRangeStart = DateTime.MinValue;
_openingRangeEnd = DateTime.MinValue;
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
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)
{
if (logger == null)
{
throw new ArgumentNullException("logger");
}
_logger = logger;
_logger.LogInformation("SimpleORBStrategy initialized with OR period {0} minutes and multiplier {1:F2}", _openingRangeMinutes, _stdDevMultiplier);
}
public StrategyIntent OnBar(BarData bar, StrategyContext context)
{
if (bar == null)
{
throw new ArgumentNullException("bar");
}
if (context == null)
{
throw new ArgumentNullException("context");
}
try
{
if (_currentSessionDate != context.CurrentTime.Date)
{
ResetSession(context.Session.SessionStart);
}
if (bar.Time <= _openingRangeEnd)
{
UpdateOpeningRange(bar);
return null;
}
if (!_openingRangeReady)
{
if (_openingRangeHigh > _openingRangeLow)
{
_openingRangeReady = true;
}
else
{
return null;
}
}
if (_tradeTaken)
{
return null;
}
var openingRange = _openingRangeHigh - _openingRangeLow;
var volatilityBuffer = openingRange * (_stdDevMultiplier - 1.0);
if (volatilityBuffer < 0)
{
volatilityBuffer = 0;
}
var longTrigger = _openingRangeHigh + volatilityBuffer;
var shortTrigger = _openingRangeLow - volatilityBuffer;
if (bar.Close > longTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Buy, openingRange, bar.Close);
}
if (bar.Close < shortTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Sell, openingRange, bar.Close);
}
return null;
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("SimpleORBStrategy OnBar failed: {0}", ex.Message);
}
throw;
}
}
public StrategyIntent OnTick(TickData tick, StrategyContext context)
{
// Most strategies don't need tick-level logic
return null;
}
public Dictionary<string, object> GetParameters()
{
var parameters = new Dictionary<string, object>();
parameters.Add("opening_range_minutes", _openingRangeMinutes);
parameters.Add("std_dev_multiplier", _stdDevMultiplier);
return parameters;
}
public void SetParameters(Dictionary<string, object> parameters)
{
// Parameters are constructor-bound for deterministic behavior in this wrapper.
// Method retained for interface compatibility.
}
private void ResetSession(DateTime sessionStart)
{
_currentSessionDate = sessionStart.Date;
_openingRangeStart = sessionStart;
_openingRangeEnd = sessionStart.AddMinutes(_openingRangeMinutes);
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
}
private void UpdateOpeningRange(BarData bar)
{
if (bar.High > _openingRangeHigh)
{
_openingRangeHigh = bar.High;
}
if (bar.Low < _openingRangeLow)
{
_openingRangeLow = bar.Low;
}
}
private StrategyIntent CreateIntent(string symbol, OrderSide side, double openingRange, double lastPrice)
{
var metadata = new Dictionary<string, object>();
metadata.Add("orb_high", _openingRangeHigh);
metadata.Add("orb_low", _openingRangeLow);
metadata.Add("orb_range", openingRange);
metadata.Add("trigger_price", lastPrice);
metadata.Add("multiplier", _stdDevMultiplier);
if (_logger != null)
{
_logger.LogInformation("SimpleORBStrategy generated {0} intent for {1}. OR High={2:F2}, OR Low={3:F2}, Last={4:F2}", side, symbol, _openingRangeHigh, _openingRangeLow, lastPrice);
}
return new StrategyIntent(
symbol,
side,
OrderType.Market,
null,
8,
16,
0.75,
"ORB breakout signal",
metadata);
}
}
#endregion
}
}

View File

@@ -1,6 +0,0 @@
Deployment manifest
Timestamp: 20260224_165037
Source Core DLL: C:\dev\nt8-sdk\deployment\..\src\NT8.Core\bin\Release\net48\NT8.Core.dll
Source Adapters DLL: C:\dev\nt8-sdk\deployment\..\src\NT8.Adapters\bin\Release\net48\NT8.Adapters.dll
Destination Custom Folder: C:\Users\billy\Documents\NinjaTrader 8\bin\Custom
Destination Strategies Folder: C:\Users\billy\Documents\NinjaTrader 8\bin\Custom\Strategies

View File

@@ -1,229 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
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
{
private readonly object _lock = new object();
#region SDK Components
protected IStrategy _sdkStrategy;
protected IRiskManager _riskManager;
protected IPositionSizer _positionSizer;
protected NT8Adapter _nt8Adapter;
protected StrategyConfig _strategyConfig;
protected ILogger _logger;
#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 with default implementations.
// Derived wrappers can replace these through InitializeSdkComponents.
_logger = new BasicLogger("BaseNT8StrategyWrapper");
_riskManager = new BasicRiskManager(_logger);
_positionSizer = new BasicPositionSizer(_logger);
InitializeSdkComponents(_riskManager, _positionSizer, _logger);
}
#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)
{
if (barData == null)
throw new ArgumentNullException("barData");
if (context == null)
throw new ArgumentNullException("context");
try
{
StrategyIntent intent;
lock (_lock)
{
if (_sdkStrategy == null)
{
throw new InvalidOperationException("SDK strategy has not been initialized.");
}
intent = _sdkStrategy.OnBar(barData, context);
}
if (intent != null)
{
ExecuteIntent(intent, context);
}
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed processing bar update for {0}: {1}", context.Symbol, ex.Message);
}
throw;
}
}
#endregion
#region Private Methods
/// <summary>
/// Initialize SDK components
/// </summary>
protected virtual void InitializeSdkComponents(IRiskManager riskManager, IPositionSizer positionSizer, ILogger logger)
{
if (riskManager == null)
throw new ArgumentNullException("riskManager");
if (positionSizer == null)
throw new ArgumentNullException("positionSizer");
if (logger == null)
throw new ArgumentNullException("logger");
_riskManager = riskManager;
_positionSizer = positionSizer;
_logger = logger;
_nt8Adapter = new NT8Adapter();
_nt8Adapter.Initialize(_riskManager, _positionSizer);
CreateSdkConfiguration();
_sdkStrategy = CreateSdkStrategy();
if (_sdkStrategy == null)
throw new InvalidOperationException("CreateSdkStrategy returned null.");
_sdkStrategy.Initialize(_strategyConfig, null, _logger);
_logger.LogInformation("Base NT8 strategy wrapper initialized for symbol {0}", _strategyConfig.Symbol);
}
/// <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)
{
if (intent == null)
throw new ArgumentNullException("intent");
if (context == null)
throw new ArgumentNullException("context");
try
{
SizingResult sizingResult;
lock (_lock)
{
if (_positionSizer == null)
{
throw new InvalidOperationException("Position sizer has not been initialized.");
}
sizingResult = _positionSizer.CalculateSize(intent, context, _strategyConfig.SizingSettings);
}
_nt8Adapter.ExecuteIntent(intent, sizingResult);
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("Failed executing intent for {0}: {1}", intent.Symbol, ex.Message);
}
throw;
}
}
#endregion
}
}

View File

@@ -1,280 +0,0 @@
using System;
using System.Collections.Generic;
using NT8.Core.Common.Interfaces;
using NT8.Core.Common.Models;
using NT8.Core.Logging;
using NT8.Adapters.NinjaTrader;
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 Constructor
/// <summary>
/// Constructor for SimpleORBNT8Wrapper
/// </summary>
public SimpleORBNT8Wrapper()
{
OpeningRangeMinutes = 30;
StdDevMultiplier = 1.0;
}
#endregion
#region Base Class Implementation
/// <summary>
/// Exposes adapter reference for integration test assertions.
/// </summary>
public NT8Adapter GetAdapterForTesting()
{
return _nt8Adapter;
}
/// <summary>
/// Create the SDK strategy implementation
/// </summary>
protected override IStrategy CreateSdkStrategy()
{
var openingRangeMinutes = OpeningRangeMinutes > 0 ? OpeningRangeMinutes : 30;
var stdDevMultiplier = StdDevMultiplier > 0.0 ? StdDevMultiplier : 1.0;
return new SimpleORBStrategy(openingRangeMinutes, stdDevMultiplier);
}
#endregion
#region Strategy Logic
/// <summary>
/// Simple ORB strategy implementation
/// </summary>
private class SimpleORBStrategy : IStrategy
{
private readonly int _openingRangeMinutes;
private readonly double _stdDevMultiplier;
private ILogger _logger;
private DateTime _currentSessionDate;
private DateTime _openingRangeStart;
private DateTime _openingRangeEnd;
private double _openingRangeHigh;
private double _openingRangeLow;
private bool _openingRangeReady;
private bool _tradeTaken;
public StrategyMetadata Metadata { get; private set; }
public SimpleORBStrategy(int openingRangeMinutes, double stdDevMultiplier)
{
if (openingRangeMinutes <= 0)
{
throw new ArgumentException("openingRangeMinutes");
}
if (stdDevMultiplier <= 0.0)
{
throw new ArgumentException("stdDevMultiplier");
}
_openingRangeMinutes = openingRangeMinutes;
_stdDevMultiplier = stdDevMultiplier;
_currentSessionDate = DateTime.MinValue;
_openingRangeStart = DateTime.MinValue;
_openingRangeEnd = DateTime.MinValue;
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
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)
{
if (logger == null)
{
throw new ArgumentNullException("logger");
}
_logger = logger;
_logger.LogInformation("SimpleORBStrategy initialized with OR period {0} minutes and multiplier {1:F2}", _openingRangeMinutes, _stdDevMultiplier);
}
public StrategyIntent OnBar(BarData bar, StrategyContext context)
{
if (bar == null)
{
throw new ArgumentNullException("bar");
}
if (context == null)
{
throw new ArgumentNullException("context");
}
try
{
if (_currentSessionDate != context.CurrentTime.Date)
{
ResetSession(context.Session.SessionStart);
}
if (bar.Time <= _openingRangeEnd)
{
UpdateOpeningRange(bar);
return null;
}
if (!_openingRangeReady)
{
if (_openingRangeHigh > _openingRangeLow)
{
_openingRangeReady = true;
}
else
{
return null;
}
}
if (_tradeTaken)
{
return null;
}
var openingRange = _openingRangeHigh - _openingRangeLow;
var volatilityBuffer = openingRange * (_stdDevMultiplier - 1.0);
if (volatilityBuffer < 0)
{
volatilityBuffer = 0;
}
var longTrigger = _openingRangeHigh + volatilityBuffer;
var shortTrigger = _openingRangeLow - volatilityBuffer;
if (bar.Close > longTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Buy, openingRange, bar.Close);
}
if (bar.Close < shortTrigger)
{
_tradeTaken = true;
return CreateIntent(context.Symbol, OrderSide.Sell, openingRange, bar.Close);
}
return null;
}
catch (Exception ex)
{
if (_logger != null)
{
_logger.LogError("SimpleORBStrategy OnBar failed: {0}", ex.Message);
}
throw;
}
}
public StrategyIntent OnTick(TickData tick, StrategyContext context)
{
// Most strategies don't need tick-level logic
return null;
}
public Dictionary<string, object> GetParameters()
{
var parameters = new Dictionary<string, object>();
parameters.Add("opening_range_minutes", _openingRangeMinutes);
parameters.Add("std_dev_multiplier", _stdDevMultiplier);
return parameters;
}
public void SetParameters(Dictionary<string, object> parameters)
{
// Parameters are constructor-bound for deterministic behavior in this wrapper.
// Method retained for interface compatibility.
}
private void ResetSession(DateTime sessionStart)
{
_currentSessionDate = sessionStart.Date;
_openingRangeStart = sessionStart;
_openingRangeEnd = sessionStart.AddMinutes(_openingRangeMinutes);
_openingRangeHigh = Double.MinValue;
_openingRangeLow = Double.MaxValue;
_openingRangeReady = false;
_tradeTaken = false;
}
private void UpdateOpeningRange(BarData bar)
{
if (bar.High > _openingRangeHigh)
{
_openingRangeHigh = bar.High;
}
if (bar.Low < _openingRangeLow)
{
_openingRangeLow = bar.Low;
}
}
private StrategyIntent CreateIntent(string symbol, OrderSide side, double openingRange, double lastPrice)
{
var metadata = new Dictionary<string, object>();
metadata.Add("orb_high", _openingRangeHigh);
metadata.Add("orb_low", _openingRangeLow);
metadata.Add("orb_range", openingRange);
metadata.Add("trigger_price", lastPrice);
metadata.Add("multiplier", _stdDevMultiplier);
if (_logger != null)
{
_logger.LogInformation("SimpleORBStrategy generated {0} intent for {1}. OR High={2:F2}, OR Low={3:F2}, Last={4:F2}", side, symbol, _openingRangeHigh, _openingRangeLow, lastPrice);
}
return new StrategyIntent(
symbol,
side,
OrderType.Market,
null,
8,
16,
0.75,
"ORB breakout signal",
metadata);
}
}
#endregion
}
}

View File

@@ -1,6 +0,0 @@
Deployment manifest
Timestamp: 20260224_165831
Source Core DLL: C:\dev\nt8-sdk\deployment\..\src\NT8.Core\bin\Release\net48\NT8.Core.dll
Source Adapters DLL: C:\dev\nt8-sdk\deployment\..\src\NT8.Adapters\bin\Release\net48\NT8.Adapters.dll
Destination Custom Folder: C:\Users\billy\Documents\NinjaTrader 8\bin\Custom
Destination Strategies Folder: C:\Users\billy\Documents\NinjaTrader 8\bin\Custom\Strategies