I have been trying to get this ema crossover strategy to execute trades intra-bar vs on bar close. Can anyone offer any advice as to how to accomplish this? I am trading on the 1 Min chart and I have tick replay enabled on the chart and selected in the strategy settings. Currently trades are being executed after bar close. Thanks
namespace NinjaTrader.NinjaScript.Strategies
{
public class SampleMACrossOver2 : Strategy
{
private EMA emaFast;
private EMA emaSlow;
private int? lastEntryBar = null;
private int tradesToday = 0;
private DateTime currentSessionDate = Core.Globals.MinDate;
region OnStateChange
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = "EMA Crossover with spread filter, angle exit, and concise debugging.";
Name = "SampleEMACrossOver2";
Fast = 3;
Slow = 18;
MinBarsBetweenEntries = 3;
MaxTradesPerDay = 5;
AngleReversalTicks = 4;
SpreadThresholdTicks = 2;
SpreadLookbackPeriod = 5;
EnableLong = true;
EnableShort = true;
EnableDebug = false;
IsInstantiatedOnEachOptimizationIteration = false;
}
else if (State == State.Configure)
{
Calculate = Calculate.OnEachTick; // intra‑bar tick‑by‑tick processing
}
else if (State == State.DataLoaded)
{
emaFast = EMA(Fast);
emaSlow = EMA(Slow);
emaFast.Plots[0].Brush = Brushes.Goldenrod;
emaSlow.Plots[0].Brush = Brushes.SeaGreen;
AddChartIndicator(emaFast);
AddChartIndicator(emaSlow);
}
}
#endregion
region OnBarUpdate (primary series only)
protected override void OnBarUpdate()
{
if (BarsInProgress != 0)
return; // just in case
if (CurrentBar < BarsRequiredToTrade || CurrentBar < SpreadLookbackPeriod)
return;
// -------- Daily reset --------
if (Time[0].Date != currentSessionDate.Date)
{
tradesToday = 0;
currentSessionDate = Time[0].Date;
}
// -------- Trade filters --------
if (tradesToday >= MaxTradesPerDay)
return;
if (lastEntryBar.HasValue && CurrentBar - lastEntryBar.Value < MinBarsBetweenEntries)
return;
if (!IsSpreadAdequate())
return;
// -------- Entry signals (intra‑bar) --------
bool longSignal = EnableLong && CrossAbove(emaFast, emaSlow, 1);
bool shortSignal = EnableShort && CrossBelow(emaFast, emaSlow, 1);
if (EnableDebug && (longSignal || shortSignal))
Print($"{Time[0]:yyyyMMdd HH:mm:ss.fff} longSig:{longSignal} shortSig:{shortSignal} emaF:{emaFast[0]:F2} emaS:{emaSlow[0]:F2}");
if (longSignal)
EnterLong("Long Entry");
else if (shortSignal)
EnterShort("Short Entry");
ManageAngleReversalExits();
}
#endregion
region Helper Methods
private bool IsSpreadAdequate()
{
for (int i = 0; i < SpreadLookbackPeriod; i++)
{
double spreadTicks = Math.Abs(emaFast[i] - emaSlow[i]) / TickSize;
if (spreadTicks < SpreadThresholdTicks)
return false;
}
return true;
}
private void ManageAngleReversalExits()
{
double slopeTicks = (emaFast[0] - emaFast[1]) / TickSize; // ticks change over 1 bar (still fine intra‑bar)
if (Position.MarketPosition == MarketPosition.Long && slopeTicks <= -AngleReversalTicks)
{
if (EnableDebug) Print($"Angle EXIT long slope:{slopeTicks:F1}");
ExitLong("AngleExitLong", "Long Entry");
}
if (Position.MarketPosition == MarketPosition.Short && slopeTicks >= AngleReversalTicks)
{
if (EnableDebug) Print($"Angle EXIT short slope:{slopeTicks:F1}");
ExitShort("AngleExitShort", "Short Entry");
}
}
#endregion
region OnExecutionUpdate
protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity,
MarketPosition marketPosition, string orderId, DateTime time)
{
if (execution.BarsInProgress != 0 || execution.Order.OrderState != OrderState.Filled)
return;
if (EnableDebug) Print($"FILLED {execution.Order.Name} {price} {time:HH:mm:ss.fff}");
if (execution.Order.Name == "Long Entry")
{
SetStopLoss("Long Entry", CalculationMode.Ticks, StopLossTicks, false);
SetProfitTarget("Long Entry", CalculationMode.Ticks, TakeProfitTicks);
}
else if (execution.Order.Name == "Short Entry")
{
SetStopLoss("Short Entry", CalculationMode.Ticks, StopLossTicks, false);
SetProfitTarget("Short Entry", CalculationMode.Ticks, TakeProfitTicks);
}
lastEntryBar = CurrentBar;
tradesToday++;
}
#endregion

Comment