I have a relatively simply strategy that I would to backtest.
I want to place orders conditionally upon the primary data series, which is NQ 12-18 3000 tick bars.
I want my trailing stop orders to be called on the secondary data series, which is NQ 12-18 1 tick data.
This, if I understand correctly, will add intraday granularity so that my trail stop is updated on each tick of the 3000 tick bars, essentially giving me close to real time results, similar to playback connection replay.
The code is running smoothly. Although, for some reason, the trail stops are clearly not accurate, and are still waiting until the next bar opens to trigger, rather than triggered within the tick data of each bar.
I have CalculateSetOnEachTick = true
I have added both data series.
And I called the position orders based on the corresponding data series.
I don't understand why my orders are not showing results based on tick data.
I'll post the code below, please let me know if Im missing something silly, or if what I am trying to achieve is not possible.
namespace NinjaTrader.NinjaScript.Strategies
{
public class SMARTT : Strategy
{
private double V;
private double R;
private bool FirstTime;
private bool setBE;
private double stopLevel;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Start";
Name = "SMARTT";
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;
V = 1;
R = 1;
FirstTime = true;
setBE =false;
stopLevel =1;
}
else if (State == State.Configure)
{
AddDataSeries("NQ 12-18", Data.BarsPeriodType.Tick, 3000, Data.MarketDataType.Last);
AddDataSeries("NQ 12-18", Data.BarsPeriodType.Tick, 1, Data.MarketDataType.Last);
}
else if (State == State.DataLoaded);
}
protected override void OnBarUpdate()
{
if (Position.MarketPosition == MarketPosition.Flat)
{
setBE = false;
FirstTime = true;
}
{
if (BarsInProgress == 0)
{
}
if (CurrentBars[0] < 2)
return;
// Set 3
if (((R - (Low[0])) > (2.3 * (V - R)) )
&& ((R - (Low[0])) > (2.7 * (High[0] - (V))))
&& ((High[0] - (Low[0])) > 2.5)
&& (Low[0] < Low[1])
&& (Low[0] < Low[2])
&& (Low[0] < Low[3])
&& (Low[0] < Low[4])
&& (Low[0] < Low[5]))
{
EnterLong(Convert.ToInt32(1), @"LONG");
}
// Set 4
if (((High[0] - (V)) > (2.3 * (V - R)))
&& ((High[0] - (V)) > (2.7 * (R - (Low[0]))))
&& ((High[0] - (Low[0])) > 2.5)
&& (High[0] > High[1])
&& (High[0] > High[2])
&& (High[0] > High[3])
&& (High[0] > High[4])
&& (High[0] > High[5]))
{
EnterShort(Convert.ToInt32(1), @"SHORT");
}
if (BarsInProgress == 1)
if (Positions[0].MarketPosition == MarketPosition.Long)
{
if (FirstTime)
{
Print (Times[0][0]+" FirstTime"+" Init stop at: "+(Positions[0].AveragePrice - 4 * TickSize).ToString());
ExitLongStopMarket(0, true, 1, Positions[0].AveragePrice - 4 * TickSize, "","LONG");
FirstTime = false;
}
if (!FirstTime && !setBE)
{
if (Closes[0][0] >= Positions[0].AveragePrice + 4 * TickSize);
{
Print (Times[0][0]+ " set BE");
ExitLongStopMarket(0, true, 1, Positions[0].AveragePrice, "","LONG");
setBE = true;
stopLevel = Positions[0].AveragePrice;
}
}
if (!FirstTime && setBE)
{
if (Closes[0][0] > stopLevel + .25 * TickSize)
{
Print (Times[0][0] + " adjusting stop to: "+ stopLevel);
stopLevel = stopLevel + .25 * TickSize; // increment 5 to 1
ExitLongStopMarket(0, true, 1, stopLevel, "","LONG");
}
}
}
if (Positions[0].MarketPosition == MarketPosition.Short)
{
if (FirstTime)
{
Print (Times[0][0]+" FirstTime"+" Init stop at: "+(Positions[0].AveragePrice + 4 * TickSize).ToString());
ExitShortStopMarket(0, true, 1, Positions[0].AveragePrice + 4 * TickSize, "","SHORT");
FirstTime = false;
}
if (!FirstTime && !setBE)
{
if (Closes[0][0] <= Positions[0].AveragePrice - 4 * TickSize);
{
Print (Times[0][0]+ " set BE");
ExitShortStopMarket(0, true, 1, Positions[0].AveragePrice, "","SHORT");
setBE = true;
stopLevel = Positions[0].AveragePrice;
}
}
if (!FirstTime && setBE)
{
if (Closes[0][0] < stopLevel - .25 * TickSize)
{
Print (Times[0][0] + " adjusting stop to: "+ stopLevel);
stopLevel = stopLevel - .25 * TickSize; // increment 5 to 1
ExitShortStopMarket(0, true, 1, stopLevel, "","SHORT");
}
}
}
}
}
}}
Comment