Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

EMA Crossover Intra-bar execution not working

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    EMA Crossover Intra-bar execution not working

    Hi everyone,

    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​

    #2
    Hello cmaddrix,

    To have intra-bar actions in real-time, in the strategy properties in the Strategies window, set Calculate to OnPriceChange.

    Note, for this to work in historical 1-tick intra-bar granularity and TickReplay are necessary.
    Chelsea B.NinjaTrader Customer Service

    Comment

    Latest Posts

    Collapse

    Topics Statistics Last Post
    Started by NullPointStrategies, Today, 05:17 AM
    0 responses
    50 views
    0 likes
    Last Post NullPointStrategies  
    Started by argusthome, 03-08-2026, 10:06 AM
    0 responses
    126 views
    0 likes
    Last Post argusthome  
    Started by NabilKhattabi, 03-06-2026, 11:18 AM
    0 responses
    69 views
    0 likes
    Last Post NabilKhattabi  
    Started by Deep42, 03-06-2026, 12:28 AM
    0 responses
    42 views
    0 likes
    Last Post Deep42
    by Deep42
     
    Started by TheRealMorford, 03-05-2026, 06:15 PM
    0 responses
    46 views
    0 likes
    Last Post TheRealMorford  
    Working...
    X