Strategy Only takes the very first trade on chart
18.04.2024 22.42

Algorithmic Trading with NinjaTrader

NinjaCoding friend

Hello,


I have a EMA cross strategy that for some reason only takes the first trade on the chart. I've tried to debug so many times. Anyone else see why?


#region Using declarations

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.ComponentModel.DataAnnotations;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Input;

using System.Windows.Media;

using System.Xml.Serialization;

using NinjaTrader.Cbi;

using NinjaTrader.Gui;

using NinjaTrader.Gui.Chart;

using NinjaTrader.Gui.SuperDom;

using NinjaTrader.Gui.Tools;

using NinjaTrader.Data;

using NinjaTrader.NinjaScript;

using NinjaTrader.Core.FloatingPoint;

using NinjaTrader.NinjaScript.Indicators;

using NinjaTrader.NinjaScript.DrawingTools;

using NinjaTrader.CQG.ProtoBuf;

#endregion


//This namespace holds Strategies in this folder and is required. Do not change it. 

namespace NinjaTrader.NinjaScript.Strategies

{

public class LongEMACrossoverStrategy : Strategy

{

private EMA _fast;

private EMA _slow;


private bool _inPosition;

private Cbi.Order _longOrder;

private Cbi.Order _stopTrailOrder;

        private bool _isOnBreakEven = false;

        private bool _isOnTrail = false;


        private string _longSignal = "Long";

        private string _stopTrailSignal = "Trail Stop";

private int _trailTicks;


protected override void OnStateChange()

{

if (State == State.SetDefaults)

{

Description = @"Enter the description for your new custom Strategy here.";

Name = "Long EMA CrossoverStrategy";

Calculate = Calculate.OnEachTick;

EntriesPerDirection = 1;

EntryHandling = EntryHandling.AllEntries;

IsExitOnSessionCloseStrategy = true;

ExitOnSessionCloseSeconds = 240;

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 = 10;

// Disable this property for performance gains in Strategy Analyzer optimizations

// See the Help Guide for additional information

IsInstantiatedOnEachOptimizationIteration = true;

                IsUnmanaged = true;

DaysToLoad = 10;

                BreakevenTiks = 20;

                EnableTrailTicks = 30;

_inPosition = false;

                TrailStep = 2;

Fast = 20;

Slow = 60;

                _trailTicks = 0;

            }

else if (State == State.Configure)

{

}

else if ( State == State.DataLoaded)

{

                _fast = EMA(Convert.ToInt32(Fast));

                _slow = EMA(Convert.ToInt32(Slow));


                _fast.Plots[0].Brush = Brushes.LimeGreen;

                _slow.Plots[0].Brush = Brushes.DarkViolet;


                AddChartIndicator(_fast);

                AddChartIndicator(_slow);

            }

        }


protected override void OnBarUpdate()

{

if (CurrentBar < BarsRequiredToTrade)

return;


            Log("Fast: " + EMA(Fast)[1], LogLevel.Information);

            Log("Slow: " + EMA(Slow)[1], LogLevel.Information);


            if (CrossAbove(EMA(Fast), EMA(Slow), 1) && !_inPosition)

{

                SubmitOrderUnmanaged(0, OrderAction.Buy, OrderType.Market, 1, 0, 0, "", _longSignal);

_inPosition = true;

}


if(_inPosition)

{

                Log("Tiks: " + Position.GetUnrealizedProfitLoss(PerformanceUnit.Ticks, Close[0]), LogLevel.Information);


                if (Position.GetUnrealizedProfitLoss(PerformanceUnit.Currency, Close[0]) <= -300)

                {

                    Cancel();

                    _inPosition =false;

                }

                

                if (Position.GetUnrealizedProfitLoss(PerformanceUnit.Ticks, Close[0]) >= BreakevenTiks && !_isOnBreakEven)

                {

                    SubmitOrderUnmanaged(0, OrderAction.Sell, OrderType.MIT, 1, 0, Position.AveragePrice, "", _stopTrailSignal);

                    _isOnBreakEven = true;

                }


                if (Position.GetUnrealizedProfitLoss(PerformanceUnit.Ticks, Close[0]) >= EnableTrailTicks + _trailTicks)

                {

                    _trailTicks += TrailStep;

                    ChangeOrder(_stopTrailOrder, 1, 0, _stopTrailOrder.StopPrice + TrailStep * Instrument.MasterInstrument.TickSize);

                    _isOnTrail = true;

                }



            }

}


        private void Cancel()

        {

            _isOnTrail = false;

            _isOnBreakEven = false;

            _inPosition = false;

            _trailTicks = 0;


            if (_longOrder != null)

            {

                CancelOrder(_longOrder);

            }


            if(_stopTrailOrder != null)

            {

                CancelOrder(_stopTrailOrder);

            }

        }


        protected override void OnOrderUpdate(Cbi.Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string comment)

        {

            if (order.Name.Equals(_longSignal) && orderState == OrderState.Filled)

            {

                _longOrder = order;

            }


            if (order.Name.Equals(_longSignal) && orderState == OrderState.Cancelled)

            {

                Cancel();

                _longOrder = null;

            }


            if (order.Name.Equals(_stopTrailSignal) && orderState == OrderState.Submitted)

            {

                _stopTrailOrder = order;

            }


            if (order.Name.Equals(_stopTrailOrder) && orderState == OrderState.Filled)

            {

                Cancel();

                _stopTrailOrder = null;

            }

        }


        #region Properties

        [Range(1, int.MaxValue), NinjaScriptProperty]

        [Display(ResourceType = typeof(Custom.Resource), Name = "Fast", GroupName = "NinjaScriptStrategyParameters", Order = 0)]

        public int Fast

        { get; set; }


        [Range(1, int.MaxValue), NinjaScriptProperty]

        [Display(ResourceType = typeof(Custom.Resource), Name = "Slow", GroupName = "NinjaScriptStrategyParameters", Order = 1)]

        public int Slow

        { get; set; }


        [DefaultValue(2)]

        [Range(1, int.MaxValue), NinjaScriptProperty]

        [Display(ResourceType = typeof(Custom.Resource), Name = "TrailStep", GroupName = "NinjaScriptStrategyParameters", Order = 2)]

        public int TrailStep

        { get; set; }


        [DefaultValue(OrderAction.Buy)]

        [Display(ResourceType = typeof(Custom.Resource), Name = "Initiali order type", GroupName = "NinjaScriptStrategyParameters", Order = 3)]

        public OrderAction Action { get; set; }


        [DefaultValue(true)]

        [Display(ResourceType = typeof(Custom.Resource), Name = "Enable Trail Tick", GroupName = "NinjaScriptStrategyParameters", Order = 4)]

        public int EnableTrailTicks { get; set; }


        [DefaultValue(20)]

        [Range(1, int.MaxValue), NinjaScriptProperty]

        [Display(ResourceType = typeof(Custom.Resource), Name = "Breakeven Tiks", GroupName = "NinjaScriptStrategyParameters", Order = 5)]

        public int BreakevenTiks { get; set; }

        #endregion

    }


    public class ShortEMACrossoverStrategy : Strategy

    {

        private EMA _fast;

        private EMA _slow;


        private bool _inPosition;

        private Cbi.Order _longOrder;

        private Cbi.Order _stopTrailOrder;

        private bool _isOnBreakEven = false;

        private bool _isOnTrail = false;


        private string _longSignal = "Long";

        private string _stopTrailSignal = "Trail Stop";

        private int _trailTicks;


        protected override void OnStateChange()

        {

            if (State == State.SetDefaults)

            {

                Description = @"Enter the description for your new custom Strategy here.";

                Name = "Short EMA CrossoverStrategy";

                Calculate = Calculate.OnEachTick;

                EntriesPerDirection = 1;

                EntryHandling = EntryHandling.AllEntries;

                IsExitOnSessionCloseStrategy = true;

                ExitOnSessionCloseSeconds = 240;

                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 = 10;

                // Disable this property for performance gains in Strategy Analyzer optimizations

                // See the Help Guide for additional information

                IsInstantiatedOnEachOptimizationIteration = true;

                IsUnmanaged = true;

                DaysToLoad = 1;

                BreakevenTiks = 20;

                EnableTrailTicks = 30;

                _inPosition = false;

                TrailStep = 2;

                Fast = 20;

                Slow = 60;

                _trailTicks = 0;

            }

            else if (State == State.Configure)

            {


            }

            else if (State == State.DataLoaded)

            {

                _fast = EMA(Convert.ToInt32(Fast));

                _slow = EMA(Convert.ToInt32(Slow));


                _fast.Plots[0].Brush = Brushes.LimeGreen;

                _slow.Plots[0].Brush = Brushes.DarkViolet;


                AddChartIndicator(_fast);

                AddChartIndicator(_slow);

            }

        }


        protected override void OnBarUpdate()

        {

            if (CurrentBar < BarsRequiredToTrade)

                return;



            if (CrossBelow(EMA(Fast), EMA(Slow), 1) && !_inPosition)

            {

                Log("Cross Below: " + CrossBelow(EMA(Fast), EMA(Slow), 1), LogLevel.Information);


                SubmitOrderUnmanaged(0, OrderAction.Sell, OrderType.Market, 1, 0, 0, "", _longSignal);


                Log("Enter position", LogLevel.Information);

                _inPosition = true;

            }


            if (_inPosition)

            {

                Log("Tiks: " + Position.GetUnrealizedProfitLoss(PerformanceUnit.Ticks, Close[0]), LogLevel.Information);


                if (Position.GetUnrealizedProfitLoss(PerformanceUnit.Currency, Close[0]) <= -300 && Position.MarketPosition != MarketPosition.Flat)

                {

                    Cancel();

                    _inPosition = false;

                }


                if (Position.GetUnrealizedProfitLoss(PerformanceUnit.Ticks, Close[0]) >= BreakevenTiks && !_isOnBreakEven && Position.MarketPosition != MarketPosition.Flat)

                {

                    SubmitOrderUnmanaged(0, OrderAction.BuyToCover, OrderType.MIT, 1, 0, Position.AveragePrice, "", _stopTrailSignal);

                    _isOnBreakEven = true;

                }


                if (Position.GetUnrealizedProfitLoss(PerformanceUnit.Ticks, Close[0]) >= EnableTrailTicks + _trailTicks && Position.MarketPosition != MarketPosition.Flat)

                {

                    _trailTicks += TrailStep;

                    Log("Trail " + _stopTrailOrder.StopPrice + TrailStep * Instrument.MasterInstrument.TickSize, LogLevel.Information);

                    ChangeOrder(_stopTrailOrder, 1, 0, _stopTrailOrder.StopPrice + TrailStep * Instrument.MasterInstrument.TickSize);

                    _isOnTrail = true;

                }



            }

        }


        private void Cancel()

        {

            _isOnTrail = false;

            _isOnBreakEven = false;

            _inPosition = false;

            _trailTicks = 0;


            if (_longOrder != null)

            {

                CancelOrder(_longOrder);

            }


            if (_stopTrailOrder != null)

            {

                CancelOrder(_stopTrailOrder);

            }

        }


        protected override void OnOrderUpdate(Cbi.Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string comment)

        {

            if (order.Name.Equals(_longSignal) && orderState == OrderState.Filled)

            {

                _longOrder = order;

            }


            if (order.Name.Equals(_longSignal) && orderState == OrderState.Cancelled)

            {

                Cancel();

                _longOrder = null;

            }


            if (order.Name.Equals(_stopTrailSignal) && orderState == OrderState.Submitted)

            {

                _stopTrailOrder = order;

            }


            if(order.Name.Equals(_stopTrailOrder) && orderState == OrderState.Filled)

            {

                Cancel();

                _stopTrailOrder = null;

            }

        }


        #region Properties

        [Range(1, int.MaxValue), NinjaScriptProperty]

        [Display(ResourceType = typeof(Custom.Resource), Name = "Fast", GroupName = "NinjaScriptStrategyParameters", Order = 0)]

        public int Fast

        { get; set; }


        [Range(1, int.MaxValue), NinjaScriptProperty]

        [Display(ResourceType = typeof(Custom.Resource), Name = "Slow", GroupName = "NinjaScriptStrategyParameters", Order = 1)]

        public int Slow

        { get; set; }


        [DefaultValue(2)]

        [Range(1, int.MaxValue), NinjaScriptProperty]

        [Display(ResourceType = typeof(Custom.Resource), Name = "TrailStep", GroupName = "NinjaScriptStrategyParameters", Order = 2)]

        public int TrailStep

        { get; set; }


        [DefaultValue(OrderAction.Buy)]

        [Display(ResourceType = typeof(Custom.Resource), Name = "Initiali order type", GroupName = "NinjaScriptStrategyParameters", Order = 3)]

        public OrderAction Action { get; set; }


        [DefaultValue(true)]

        [Display(ResourceType = typeof(Custom.Resource), Name = "Enable Trail Tick", GroupName = "NinjaScriptStrategyParameters", Order = 4)]

        public int EnableTrailTicks { get; set; }


        [DefaultValue(20)]

        [Range(1, int.MaxValue), NinjaScriptProperty]

        [Display(ResourceType = typeof(Custom.Resource), Name = "Breakeven Tiks", GroupName = "NinjaScriptStrategyParameters", Order = 5)]

        public int BreakevenTiks { get; set; }

        #endregion

    }

}