//This namespace holds Strategies in this folder and is required. Do not change it.
namespace NinjaTrader.NinjaScript.Strategies
{
public class HourlyLongOrShortES : Strategy
{
private const int sessionFirstBarCloseHour = 17;
private const int earliestTradableBarCloseHour = 8;
private const int latestTradeableBarCloseHour = 15;
private string instrumentNameFull;
private string contractSymbol;
private string hourlyPricesPath;
private DateTime previousSessionFinalBarCloseDateTime;
private double previousSessionFinalBarOpen;
private double previousSessionFinalBarHigh;
private double previousSessionFinalBarLow;
private double previousSessionFinalBarClose;
private double previousSessionFinalBarVolume;
private DateTime previousBarCloseDateTime;
private DateTime lastKnownBarCloseDateTime;
private DateTime currentBarCloseDateTime;
private string currentBarCloseDateTimeString;
private int currentBarCloseHour;
private double previousOpen;
private double previousHigh;
private double previousLow;
private double previousClose;
private double previousVolume;
private double currentOpen;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Enter the description for your new custom Strategy here.";
Name = "HourlyLongOrShortES";
Calculate = Calculate.OnEachTick;
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = true;
ExitOnSessionCloseSeconds = 30;
IsFillLimitOnTouch = false;
MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
OrderFillResolution = OrderFillResolution.Standard;
Slippage = 0;
IsAdoptAccountPositionAware = true;
StartBehavior = StartBehavior.AdoptAccountPosition;
TimeInForce = TimeInForce.Day;
TraceOrders = true;
RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
StopTargetHandling = StopTargetHandling.PerEntryExecution;
BarsRequiredToTrade = 0;
// Disable this property for performance gains in Strategy Analyzer optimizations
// See the Help Guide for additional information
IsInstantiatedOnEachOptimizationIteration = true;
}
else if (State == State.Configure)
{
SetStopLoss(CalculationMode.Ticks, stopLossTicks);
}
else if (State == State.DataLoaded)
{
instrumentNameFull = Instrument.FullName;
contractSymbol = instrumentNameFull.Substring(0, 2);
hourlyPricesPath = @"F:/hourlyPrices_" + contractSymbol + ".csv";
}
}
protected override void OnBarUpdate()
{
if (State == State.Historical) // Process only realtime events
return;
if (BarsInProgress != 0)
return;
if (CurrentBars[0] < 1)
return;
currentBarCloseDateTime = Time[0]; // Expected close time of current bar
currentBarCloseDateTimeString = currentBarCloseDateTime.ToString();
currentBarCloseHour = int.Parse(currentBarCloseDateTimeString.Substring(11, 2));
// If current bar is first of trading session then capture last bar of previous session
if (currentBarCloseHour == sessionFirstBarCloseHour)
{
previousSessionFinalBarCloseDateTime = Time[1];
previousSessionFinalBarOpen = Open[1];
previousSessionFinalBarHigh = High[1];
previousSessionFinalBarLow = Low[1];
previousSessionFinalBarClose = Close[1];
previousSessionFinalBarVolume = Volume[1];
lastKnownBarCloseDateTime = currentBarCloseDateTime; // Initialize lastKnownBarCloseDateTime
}
if (currentBarCloseHour <= latestTradeableBarCloseHour && currentBarCloseHour >= earliestTradableBarCloseHour)
{
if (currentBarCloseDateTime != lastKnownBarCloseDateTime) // If a new bar has just opened...
{
lastKnownBarCloseDateTime = currentBarCloseDateTime; // Update lastKnownBarCloseDateTime
// If current bar is first actionable bar then let previous session's final bar become previous bar
if (currentBarCloseHour == earliestTradableBarCloseHour)
{
previousBarCloseDateTime = previousSessionFinalBarCloseDateTime;
previousOpen = previousSessionFinalBarOpen;
previousHigh = previousSessionFinalBarHigh;
previousLow = previousSessionFinalBarLow;
previousClose = previousSessionFinalBarClose;
previousVolume = previousSessionFinalBarVolume;
}
else
{
previousBarCloseDateTime = Time[1];
previousOpen = Open[1];
previousHigh = High[1];
previousLow = Low[1];
previousClose = Close[1];
previousVolume = Volume[1];
}
currentOpen = Open[0];
if (File.Exists(hourlyPricesPath))
{
string[] ohlcLinesToWriteNoHeader = {
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "," +
previousBarCloseDateTime.ToString() + "," +
previousOpen.ToString() + "," +
previousHigh.ToString() + "," +
previousLow.ToString() + "," +
previousClose.ToString() + "," +
previousVolume.ToString() + "," +
currentBarCloseDateTime.ToString("yyyy-MM-dd HH:mm:ss") + "," +
currentOpen.ToString()};
using (StreamWriter outputFile2 = new StreamWriter(hourlyPricesPath, append: true))
{
foreach (string line in ohlcLinesToWriteNoHeader)
outputFile2.WriteLine(line);
}
}
else // Else hourly prices file does not exist
{
string[] ohlcLinesToWriteWithHeader = {"CurrentDateTime,PreviousBarCloseDateTime,PreviousOpen,PreviousHigh,PreviousLow,PreviousClose,PreviousVolume,CurrentBarCloseDateTime,CurrentOpen",
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "," +
previousBarCloseDateTime.ToString("yyyy-MM-dd HH:mm:ss") + "," +
previousOpen.ToString() + "," +
previousHigh.ToString() + "," +
previousLow.ToString() + "," +
previousClose.ToString() + "," +
previousVolume.ToString() + "," +
currentBarCloseDateTime.ToString("yyyy-MM-dd HH:mm:ss") + "," +
currentOpen.ToString()};
using (StreamWriter outputFile1 = new StreamWriter(hourlyPricesPath))
{
foreach (string line in ohlcLinesToWriteWithHeader)
outputFile1.WriteLine(line);
}
} // End block if (File.Exists(hourlyPricesPath))
} // End block if (currentBarCloseDateTime != lastKnownBarCloseDateTime)
} // End block if (currentBarCloseHour <= latestTradeableBarCloseHour && currentBarCloseHour >= earliestTradableBarCloseHour)
} // End block OnBarUpdate
} // End block HourlyLongOrShortES : Strategy
} // End block namespace NinjaTrader.NinjaScript.Strategies
Here's the resulting CSV output file:
CurrentDateTime,PreviousBarCloseDateTime,PreviousOpen,PreviousHigh,PreviousLow,PreviousClose,PreviousVolume,CurrentBarCloseDateTime,CurrentOpen 2023-07-10 06:59:59,0001-01-01 00:00:00,0,0,0,0,0,2023-07-10 08:00:00,4431.75 2023-07-10 07:59:59,2023-07-10 08:00:00,4431.75,4442,4428.5,4439.25,179914,2023-07-10 09:00:00,4439 2023-07-10 08:59:58,2023-07-10 09:00:00,4439,4446.75,4431.75,4434.5,213488,2023-07-10 10:00:00,4434.5 2023-07-10 09:52:58,2023-07-10 09:00:00,4439,4446.75,4431.75,4434.5,213488,2023-07-10 10:00:00,4434.5 2023-07-10 09:59:58,2023-07-10 10:00:00,4434.5,4439.25,4428.25,4432.5,159376,2023-07-10 11:00:00,4432.75 2023-07-10 11:00:00,2023-07-10 11:00:00,4432.75,4438.25,4424,4437.25,141640,2023-07-10 12:00:00,4437.25 2023-07-10 11:59:59,2023-07-10 12:00:00,4437.25,4442.5,4436,4438.25,87339,2023-07-10 13:00:00,4438 2023-07-10 12:59:59,2023-07-10 13:00:00,4438,4442.75,4433.5,4441,87977,2023-07-10 14:00:00,4441.25 2023-07-10 13:59:59,2023-07-10 14:00:00,4441.25,4446,4434.75,4445.5,159376,2023-07-10 15:00:00,4445.5 2023-07-11 06:59:59,0001-01-01 00:00:00,0,0,0,0,0,2023-07-11 08:00:00,4456.25 2023-07-11 07:59:59,2023-07-11 08:00:00,4456.25,4458.75,4444.25,4451.75,188905,20 23-07-11 09:00:00,4451.75 2023-07-11 08:59:58,2023-07-11 09:00:00,4451.75,4456,4442,4454.25,190983,2023-07-11 10:00:00,4454.25 2023-07-11 09:59:58,2023-07-11 10:00:00,4454.25,4463,4451.75,4462.5,130729,2023-07-11 11:00:00,4462.75 2023-07-11 11:00:00,2023-07-11 11:00:00,4462.75,4465.25,4452.5,4459.5,126102,2023-07-11 12:00:00,4459.5 2023-07-11 12:00:00,2023-07-11 12:00:00,4459.5,4461.5,4453.25,4458.25,79293,2023-07-11 13:00:00,4458.25 2023-07-11 13:00:00,2023-07-11 13:00:00,4458.25,4462.5,4450.5,4462,115621,2023-07-11 14:00:00,4462 2023-07-11 13:59:59,2023-07-11 14:00:00,4462,4478.5,4459,4473.25,232300,2023-07-11 15:00:00,4473.25 2023-07-15 08:21:56,2023-07-12 15:00:00,4509.25,4512.25,4507.75,4509.5,73498,2023-07-13 08:00:00,4524.25 2023-07-15 08:22:02,2023-07-13 08:00:00,4524.25,4532.25,4521.25,4531.25,164336,20 23-07-13 09:00:00,4531.25 2023-07-15 08:22:11,2023-07-13 09:00:00,4531.25,4531.75,4525.25,4530.75,149448,20 23-07-13 10:00:00,4531 2023-07-15 08:22:15,2023-07-13 10:00:00,4531,4532.5,4525.75,4531.75,95727,2023-07-13 11:00:00,4531.75 2023-07-15 08:22:18,2023-07-13 11:00:00,4531.75,4536.5,4530.75,4533.5,85264,2023-07-13 12:00:00,4533.5 2023-07-15 08:22:22,2023-07-13 12:00:00,4533.5,4535.75,4528.75,4534.25,68331,2023-07-13 13:00:00,4534 2023-07-15 08:22:26,2023-07-13 13:00:00,4534,4540.25,4533.5,4540.25,84207,2023-07-13 14:00:00,4540.25 2023-07-15 08:22:31,2023-07-13 14:00:00,4540.25,4551.5,4539.25,4542.75,213039,202 3-07-13 15:00:00,4542.75
I want the first line of data written for each new trading session to contain the values from the previous session's final bar for the "Previous..." variables. The first two recorded sessions (2023-07-10 and 2023-07-11) were run realtime using a simulation account, and the last recorded session (2023-07-13) was run in playback mode. As you can see, the realtime results recorded zeros for each previous session's final bar, while the playback results recorded the correct values for the previous session's final bar.
My question is: Why are the previous session's final bar values being recorded as zeros when the strategy runs realtime?

Comment