namespace NinjaTrader.NinjaScript.Strategies
{
public class AwesomeStrat : Strategy
{
#region Variables
enum EntryName
{
LONG,
SHORT,
}
private const string GROUP_NAME = "AwesomeStrat";
private const int VOLUMETRIC_BAR = 1;
private const int TICK_BAR = 2;
private bool entryLong = false;
private bool entryShort = false;
#endregion
#region Properties
[NinjaScriptProperty]
[Display(Name = "Quantity", Description = "The name order quantity.", Order = 0, GroupName = GROUP_NAME)]
public int Quantity { get; set; }
[NinjaScriptProperty]
[Display(Name = "Target", Description = "The target in ticks.", Order = 1, GroupName = GROUP_NAME)]
public int Target { get; set; }
[NinjaScriptProperty]
[Display(Name = "Stop", Description = "The stop in ticks.", Order = 2, GroupName = GROUP_NAME)]
public int Stop { get; set; }
[NinjaScriptProperty]
[Display(Name = "Trading Start Time", Description = "The start time to allow trade entries. (HHMMSS)", Order = 3, GroupName = GROUP_NAME)]
public int Start { get; set; }
[NinjaScriptProperty]
[Display(Name = "Trading End Time", Description = "The end time to stop allowing trade entries. (HHMMSS)", Order = 4, GroupName = GROUP_NAME)]
public int End { get; set; }
[NinjaScriptProperty]
[Display(Name = "Max Bar Look Back", Description = "The maximum bars to look back to contain in list.", Order = 5, GroupName = GROUP_NAME)]
public int MaxBarLookBack { get; set; }
[NinjaScriptProperty]
[Display(Name = "Disable Start/End Time Check", Description = "Disables the check for the start and end time.", Order = 6, GroupName = GROUP_NAME)]
public bool DisableStartEndTime { get; set; }
#endregion
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Most Awesome Strat Ever";
Name = "_AwesomeStrat";
Calculate = Calculate.OnEachTick;
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = true;
ExitOnSessionCloseSeconds = 30;
IsFillLimitOnTouch = false;
MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
OrderFillResolution = OrderFillResolution.Standard;
Slippage = 0;
StartBehavior = StartBehavior.WaitUntilFlat;
TimeInForce = TimeInForce.Gtc;
TraceOrders = false;
RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
StopTargetHandling = StopTargetHandling.PerEntryExecution;
BarsRequiredToTrade = 20;
// Disable this property for performance gains in Strategy Analyzer optimizations
// See the Help Guide for additional information
IsInstantiatedOnEachOptimizationIteration = true;
Quantity = 1;
Target = 16;
Stop = 10;
Start = 094000;
End = 154000;
MaxBarLookBack = 3;
DisableStartEndTime = false;
}
else if (State == State.Configure)
{
AddVolumetric(Instrument.FullName, BarsPeriodType.Range, 10, VolumetricDeltaType.BidAsk, 1);
AddDataSeries(Instrument.FullName, BarsPeriodType.Tick, 1);
}
}
protected override void OnBarUpdate()
{
if (Bars == null)
return;
if (allowTradeEntry() == false)
return;
if (Position.MarketPosition == MarketPosition.Flat)
{
if (BarsInProgress == TICK_BAR)
{
entryLong = validBullishMomentum();
if (entryLong)
{
validLongEntry();
}
if (entryShort)
{
validShortEntry();
}
}
}
}
private bool validBullishMomentum()
{
double previousValue = Momentum(HMA(BarsArray[VOLUMETRIC_BAR], 14), 1)[1];
double currentValue = Momentum(HMA(BarsArray[VOLUMETRIC_BAR], 14), 1)[0];
return previousValue < currentValue;
}
#region Management
private bool allowTradeEntry()
{
bool isWithinTimeRange = ToTime(Time[0]) >= Start && ToTime(Time[0]) <= End;
bool isTimeCheckDisabled = DisableStartEndTime ? true : isWithinTimeRange;
// Disable strategy at end time
if (ToTime(Time[0]) == End && State == State.Realtime)
{
Print("End time reached. Strategy disabled.");
// Only works in State.Realtime
CloseStrategy(Name);
}
return isTimeCheckDisabled;
}
private void validLongEntry()
{
SetProfitTarget(EntryName.LONG.ToString(), CalculationMode.Ticks, Target);
SetStopLoss(EntryName.LONG.ToString(), CalculationMode.Ticks, Stop, false);
EnterLong(Quantity, EntryName.LONG.ToString());
}
private void validShortEntry()
{
SetProfitTarget(EntryName.SHORT.ToString(), CalculationMode.Ticks, Target);
SetStopLoss(EntryName.SHORT.ToString(), CalculationMode.Ticks, Stop, false);
EnterShort(Quantity, EntryName.SHORT.ToString());
}
#endregion
}
}
Announcement
Collapse
No announcement yet.
Partner 728x90
Collapse
NinjaTrader
Errors only when selecting Optimization for Backtest type.
Collapse
X
-
Errors only when selecting Optimization for Backtest type.
For some reason I only get the following error when I select optimization "Error on calling 'OnStateChange' method: Object reference not set to an instance of an object". Everything runs fine in a regular backtest.
Code:Tags: None
-
Hello tonystarks,
Do you still see this error if you change to using a hard coded instrument name?
Code:AddVolumetric("ES 12-22", BarsPeriodType.Range, 10, VolumetricDeltaType.BidAsk, 1); AddDataSeries("ES 12-22", BarsPeriodType.Tick, 1);
Are you also certain that you have 1 tick data for the full time period that you requested in the test?
- Likes 1
-
Thanks. It looks like it is the Instrument.FullName. I came across this: "Arguments supplied to AddDataSeries() should be hardcoded and NOT dependent on run-time variables which cannot be reliably obtained during State.Configure (e.g., Instrument, Bars, or user input)." This seems to be an issue only when I select for backtest optimization. I rather not have to hardcode this in so I don't have to keep changing it. Is there a good approach to this? I'm assuming, I need to hard code it in for backtesting optimization and can just revert back to not having it hardcoded other times.Originally posted by NinjaTrader_Jesse View PostHello tonystarks,
Do you still see this error if you change to using a hard coded instrument name?
Code:AddVolumetric("ES 12-22", BarsPeriodType.Range, 10, VolumetricDeltaType.BidAsk, 1); AddDataSeries("ES 12-22", BarsPeriodType.Tick, 1);
Are you also certain that you have 1 tick data for the full time period that you requested in the test?
Comment
-
Hello tonystarks,
That note in the help guide is because AddDataSeries won't work correctly with variables so hard coding it is the only suggestion that we could make. The data may or may not be loaded correctly when using variables so its just suggested to not do that at all to make sure your script works correctly.
- Likes 1
Comment
Latest Posts
Collapse
| Topics | Statistics | Last Post | ||
|---|---|---|---|---|
|
Started by NullPointStrategies, Yesterday, 05:17 AM
|
0 responses
62 views
0 likes
|
Last Post
|
||
|
Started by argusthome, 03-08-2026, 10:06 AM
|
0 responses
134 views
0 likes
|
Last Post
by argusthome
03-08-2026, 10:06 AM
|
||
|
Started by NabilKhattabi, 03-06-2026, 11:18 AM
|
0 responses
75 views
0 likes
|
Last Post
|
||
|
Started by Deep42, 03-06-2026, 12:28 AM
|
0 responses
45 views
0 likes
|
Last Post
by Deep42
03-06-2026, 12:28 AM
|
||
|
Started by TheRealMorford, 03-05-2026, 06:15 PM
|
0 responses
50 views
0 likes
|
Last Post
|

Comment