Help with Null Reference and Pending Order Type

Created at 21 Mar 2022, 05:53
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
TR

triplelorenz

Joined 05.01.2022

Help with Null Reference and Pending Order Type
21 Mar 2022, 05:53


Hi guys,

I keep getting an error "Crashed in Positions.Closed with NullReferenceException: Object reference not set to an instance of an object" and I am struggling to find the error. I have gone through and put print functions everywhere to try and find the last place it calls before it errors but I can find it. I have been running it on EUR/USD 1 hr just to trouble shoot the code etc and it keeps giving the error in the bar period e.g 9:32, not when the new bar is called ?? sorry if the code is a bit clunky.

The other part of my question is, is it possible to call a pendingordertype for buys and sells ?? instead of stop, stoplimit etc. 

something like this (the PendingOrder and OrderDirection thing I cant get it to work) ??

        protected void Orderbytype(PendingOrder OrderDirection)
        {
            foreach (var order in PendingOrders)
            {
                if (order.Label == InstanceName && order.SymbolName == SymbolName)
                {
                    double newPrice = Symbol.Ask + 5 * Symbol.PipSize;
                    ModifyPendingOrder(order, newPrice, order.StopLossPips, order.TakeProfitPips, order.ExpirationTime);
                }
            }
        }

 

 

Full code for the Null reference error.

 


using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;


namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class EMATrendBuyonlyOpenOrders : Robot
    {
        #region User defined parameters

        [Parameter("Instance Name", DefaultValue = "EMAtrend")]
        public string InstanceName { get; set; }

        [Parameter("Open Sell Positions", Group = "Positions and Orders", DefaultValue = 1, MinValue = 1, MaxValue = 5)]
        public int possell { get; set; }

        [Parameter("Open Buy Positions", Group = "Positions and Orders", DefaultValue = 1, MinValue = 1, MaxValue = 5)]
        public int posbuy { get; set; }

        [Parameter("Open Total Positions", Group = "Positions and Orders", DefaultValue = 1, MinValue = 1, MaxValue = 10)]
        public int postotal { get; set; }

        [Parameter("Enable Add Spread to SL", Group = "Positions and Orders", DefaultValue = false)]
        public bool enableAddSpread { get; set; }


        [Parameter("% per trade", Group = "Money Management", DefaultValue = 2, MinValue = 0.5, MaxValue = 4, Step = 0.5)]
        public double PerTrade { get; set; }

        [Parameter("ATR Periods", Group = "Money Management", DefaultValue = 14)]
        public int atrPeriodsbuy { get; set; }


        [Parameter("Slow MA Source", Group = "Moving Averages")]
        public DataSeries Sourcema1 { get; set; }

        [Parameter("Slow MA Period", Group = "Moving Averages", DefaultValue = 200, MinValue = 100, MaxValue = 400)]
        public int Periodsma1 { get; set; }

        [Parameter("Slow MA Type", Group = "Moving Averages", DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType ma1Type { get; set; }

        [Parameter("Fast MA Source", Group = "Moving Averages")]
        public DataSeries Sourcema2 { get; set; }

        [Parameter("Fast MA Period", Group = "Moving Averages", DefaultValue = 50, MinValue = 10, MaxValue = 80)]
        public int Periodsma2 { get; set; }

        [Parameter("Fast MA Type", Group = "Moving Averages", DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType ma2Type { get; set; }

        [Parameter("Source", Group = "ADX")]
        public DataSeries SourceADX { get; set; }

        [Parameter("ADX Periods", Group = "ADX", DefaultValue = 14, MinValue = 1, MaxValue = 25)]
        public int PeriodsADX { get; set; }

        [Parameter("ADX Low Limit", Group = "ADX", DefaultValue = 20, MinValue = 5, MaxValue = 40)]
        public int ADXlow { get; set; }


        [Parameter("Source", Group = "RSI")]
        public DataSeries SourceRSI { get; set; }

        [Parameter("Periods", Group = "RSI", DefaultValue = 14, MinValue = 1, MaxValue = 25)]
        public int PeriodsRSI { get; set; }

        [Parameter("RSI Over Sold", Group = "RSI", DefaultValue = 40, MinValue = 1, MaxValue = 60)]
        public int RSILow { get; set; }

        [Parameter("RSI Over Bought", Group = "RSI", DefaultValue = 60, MinValue = 40, MaxValue = 99)]
        public int RSIHigh { get; set; }

        [Parameter("RSI MA Period", Group = "RSI", DefaultValue = 5, MinValue = 1, MaxValue = 15)]
        public int RSImaPeriod { get; set; }

        [Parameter("RSI Lookback Period", Group = "RSI", DefaultValue = 5, MinValue = 1, MaxValue = 15)]
        public int RSIlookback { get; set; }

        /*
                [Parameter("MACD LongCycle", Group = "MACD", DefaultValue = 26, MinValue = 1, MaxValue = 100)]
                public int LongCycle { get; set; }

                [Parameter("MACD ShortCycle", Group = "MACD", DefaultValue = 12, MinValue = 1, MaxValue = 100)]
                public int ShortCycle { get; set; }

                [Parameter("MACD Period", Group = "MACD", DefaultValue = 9, MinValue = 1, MaxValue = 100)]
                public int MACDPeriod { get; set; }
        */

        [Parameter("Normal SL Type", Group = "Stop Loss Info", DefaultValue = StopLossType.ATR)]
        public StopLossType stoplossType { get; set; }

        [Parameter("Trailing SL Type", Group = "Stop Loss Info", DefaultValue = TrailingStopType.ATR)]
        public TrailingStopType trailingStopType { get; set; }

        [Parameter("ATR Multiplier Stop Loss ", Group = "Normal SL & TP", DefaultValue = 1.5, MinValue = 1, MaxValue = 4, Step = 0.5)]
        public double SLATR { get; set; }

        [Parameter("ATR Multiplier Take Profit ", Group = "Normal SL & TP", DefaultValue = 1.5, MinValue = 1, MaxValue = 4, Step = 0.5)]
        public double TPATR { get; set; }

        [Parameter("Manual Stop Loss (pips)", Group = "Normal SL & TP", DefaultValue = 100, MinValue = 5, Step = 1)]
        public double stopLoss { get; set; }

        [Parameter("Trigger (pips)", Group = "TSL Optimiser", DefaultValue = 5.0, MinValue = 1, MaxValue = 20)]
        public double TriggerPips { get; set; }

        [Parameter("Trail SL (pips)", Group = "TSL Optimiser", DefaultValue = 10.0, MinValue = 1, MaxValue = 100)]
        public double TrailSLPips { get; set; }

        [Parameter("Trail TP (pips)", Group = "TSL Optimiser ", DefaultValue = 5.0, MinValue = 1, MaxValue = 100)]
        public double TrailTPPips { get; set; }

        [Parameter("ATR TSL Periods", Group = "TSL ATR", DefaultValue = 21)]
        public int atrPeriodsSL { get; set; }

        [Parameter("ATR TSL Multiplier", Group = "TSL ATR", DefaultValue = 2, MinValue = 1, MaxValue = 5, Step = 0.5)]
        public double atrMultiplierSL { get; set; }


        #endregion

        #region Indicator declarations


        private MovingAverage ma1 { get; set; }
        private MovingAverage ma2 { get; set; }
        private RelativeStrengthIndex rsi { get; set; }
        private AverageTrueRange atrbuy { get; set; }
        private AverageTrueRange atrTSL { get; set; }
        ///private MacdCrossOver _MACD { get; set; }
        private MovingAverage rsiMA { get; set; }

        private AverageDirectionalMovementIndexRating _ADX { get; set; }

        Symbol currentSymbol;
        Position currentPosition;
        double? newStopLoss = 0;
        double? newTakeProfit = 0;
        public double ATRMinimuStopLoss;

        #endregion

        #region cTrader events

        protected override void OnStart()
        {
            // construct the indicators

            ma1 = Indicators.MovingAverage(Sourcema1, Periodsma1, ma1Type);
            ma2 = Indicators.MovingAverage(Sourcema2, Periodsma2, ma2Type);
            atrbuy = Indicators.AverageTrueRange(atrPeriodsbuy, MovingAverageType.Exponential);
            atrTSL = Indicators.AverageTrueRange(atrPeriodsSL, MovingAverageType.Exponential);
            rsi = Indicators.RelativeStrengthIndex(SourceRSI, PeriodsRSI);
            rsiMA = Indicators.MovingAverage(rsi.Result, RSImaPeriod, MovingAverageType.Exponential);
            _ADX = Indicators.AverageDirectionalMovementIndexRating(PeriodsADX);
            ///_MACD = Indicators.MacdCrossOver(LongCycle, ShortCycle, MACDPeriod);


            ATRMinimuStopLoss = 5;
            Positions.Closed += OnPositionsClosed;
        }

        protected override void OnTick()
        {
        }
        /*
            ATRTrailingStop();
            MomentumTrailingStop();
            Optimiser();
            */

        protected override void OnBar()
        {


            var currentTime = Server.Time;
            var day = Server.Time.DayOfWeek;
            int positionCount = CountPositions();
            int positionCountbuy = CountPositionsbuy();
            int positionCountsell = CountPositionssell();
            int Orderscount = CountOrders();


            /// Bar values
            var PCV1 = Bars.ClosePrices.Last(1);
            var PCV2 = Bars.ClosePrices.Last(2);
            var PLV = Bars.LowPrices.Last(1);
            var PHV = Bars.HighPrices.Last(1);
            var GreenBar = Bars.ClosePrices.Last(1) - Bars.OpenPrices.Last(1);
            /// should be greater than 0 for green result
            var RedBar = Bars.OpenPrices.Last(1) - Bars.ClosePrices.Last(1);
            // should be greater than 0 for red result


            /// EMA Values
            var ma1Prev = ma1.Result.Last(1);
            var ma1Prev2 = ma1.Result.Last(2);
            var ma1Prev3 = ma1.Result.Last(3);

            var ma2Prev = ma2.Result.Last(1);
            var ma2Prev2 = ma2.Result.Last(2);
            var ma2Prev3 = ma2.Result.Last(3);


            /// ADX and RSI Values
            var ADXRvalue = _ADX.ADXR.LastValue;
            var diminus = _ADX.DIMinus.LastValue;
            var diplus = _ADX.DIPlus.LastValue;
            var rsiMAValue = rsiMA.Result.Last(1);
            var RSIvalue = rsi.Result.Last(1);

                        /*
var MACDLine = _MACD.MACD.Last(1);
var PrevMACDLine = _MACD.MACD.Last(2);
var Signal = _MACD.Signal.Last(1);
var PrevSignal = _MACD.Signal.Last(2);
*/


if (day == DayOfWeek.Monday || day == DayOfWeek.Tuesday || day == DayOfWeek.Thursday || day == DayOfWeek.Friday || day == DayOfWeek.Saturday || day == DayOfWeek.Sunday)
            {

                /// buy baby

                if (ma2Prev > ma1Prev && rsi.Result.HasCrossedBelow(RSILow, RSIlookback) && ADXRvalue > ADXlow)
                {
                    if (!IsPositionOpenByType(TradeType.Buy) && positionCount < postotal && Orderscount == 0)
                    {
                        ClosePositions(TradeType.Sell);
                        CloseAllOrders();


                        var PrevATR = Math.Round((atrbuy.Result.Last(1) / Symbol.PipSize), 3);
                        var newTakeProfit = TPATR * PrevATR;

                        var PerTradeadjust = PerTrade / 100;
                        var TradeAmount = (Account.Equity * PerTradeadjust) / (PrevATR * Symbol.PipValue);
                        TradeAmount = Symbol.NormalizeVolumeInUnits(TradeAmount, RoundingMode.Down);

                        var targetPrice = Bars.OpenPrices.Last(2);
                        var newStopLoss = normalstoploss() + addSpreadToStopLoss();
                        Print("StopLoss value: {0},", newStopLoss);

                        PlaceStopLimitOrder(TradeType.Buy, SymbolName, TradeAmount, targetPrice, 2, InstanceName, newStopLoss, newTakeProfit);

                    }
                    else if (PCV1 < PCV2 && RedBar >= 0 && !IsPositionOpenByType(TradeType.Buy) && positionCount < postotal && Orderscount > 0)
                    {
                        ClosePositions(TradeType.Sell);

                        foreach (var order in PendingOrders)
                        {
                            if (order.Label == InstanceName && order.SymbolName == SymbolName && order != null)
                            {
                                var PrevATR = Math.Round((atrbuy.Result.Last(1) / Symbol.PipSize), 3);
                                var targetPrice = Bars.OpenPrices.LastValue;
                                var newStopLoss = normalstoploss() + addSpreadToStopLoss();
                                var newTakeProfit = TPATR * PrevATR;


                                ModifyPendingOrder(order, targetPrice, newStopLoss, newTakeProfit);
                                Print("Modifyied StopLoss value: {0},", newStopLoss);
                            }
                        }
                    }
                }

                ///fire sale all needs redoing 
                else                /*
                else
                if (EmaPrev < SmaPrev)
                {
                    if (!IsPositionOpenByType(TradeType.Sell) && positionCount <= postotal)
                    {
                        ClosePositions(TradeType.Buy);
                        OpenPosition(InstanceName, TradeType.Sell);

                        PlaceLimitOrder(TradeType.Sell, SymbolName, TradeAmt(), entryPriceshort, InstanceName, stopLoss, TAKEP);

                    }
                    else if
                    {

                            foreach (var order in PendingOrders)
                            {
                                if (order.Label == label && order.SymbolName == SymbolName && order != null)
                                {
                                    var targetPrice = Bars.OpenPrices(1);
                                    if (PCV1 > PCV2 && GreenBar > 0 && order.TradeType == TradeType.Sell)
                                    {
                                        ModifyPendingOrder(order, targetPrice);
                                        ModifyPendingOrder(order, double targetPrice, double? stopLossPips, double? takeProfitPips)
                                    }

                                }
                            }
                    }
                }
*/
                {
                    CloseAllOrders();
                }

            }

        }


        protected override void OnStop()
        {
            // unused
        }

        #endregion

        #region Private subs

/*
        protected void Orderbytype(PendingOrder OrderDirection)
        {
            foreach (var order in PendingOrders)
            {
                if (order.Label == InstanceName && order.SymbolName == SymbolName)
                {
                    double newPrice = Symbol.Ask + 5 * Symbol.PipSize;
                    ModifyPendingOrder(order, newPrice, order.StopLossPips, order.TakeProfitPips, order.ExpirationTime);
                }
            }
        }

        */

                private void CloseAllOrders()
        {
            Print("CloseAllOrders", "CloseAllOrders");
            foreach (var order in PendingOrders)
            {
                if (order.Label == InstanceName && order.SymbolName == SymbolName)
                {
                    CancelPendingOrder(order);
                }
            }
        }


        /*
        private void OpenPosition(string Label, TradeType TradeDirection)
        {
            //Calculate Trade Amount base on the ATR

            var PrevATR = Math.Round((atrbuy.Result.Last(1) / Symbol.PipSize), 3);
            var PerTradeadjust = PerTrade / 100;
            var TradeAmount = (Account.Equity * PerTradeadjust) / (PrevATR * Symbol.PipValue);
            TradeAmount = Symbol.NormalizeVolumeInUnits(TradeAmount, RoundingMode.Down);

            ExecuteMarketOrder(TradeDirection, SymbolName, TradeAmount, InstanceName, SLATR * PrevATR, TPATR * PrevATR);

            /// Print to the log all the trade data
            ///Print("RSI Value: {0}, EMA Prev: {1}, EMA Prev 3 {2}, Price Close - EMA: {3}, Stop Loss in Pips {4}", RSIvalue, EMAPrev, EMAPrev3, abc123, SL2EMAbuy);

        }

        */

        private int CountPositions()
        {
            Print("CountPositionstotal", "CountPositionstotal");
            var positions = Positions.FindAll(InstanceName, SymbolName);
            return positions.Length;
        }

        private int CountPositionsbuy()
        {
            Print("CountPositionsbuy", "CountPositionsbuy");
            var positions = Positions.FindAll(InstanceName, SymbolName, TradeType.Buy);
            return positions.Length;
        }

        private int CountPositionssell()
        {
            Print("CountPositionssell", "CountPositionssell");
            var positions = Positions.FindAll(InstanceName, SymbolName, TradeType.Sell);
            return positions.Length;
        }

        private int CountOrders()
        {
            Print("CountOrders", "CountOrders");
            int count = 0;
            foreach (var order in PendingOrders)
            {
                if (order.Label == InstanceName && order.SymbolName == SymbolName)
                {
                    count++;
                }
            }
            return count;
        }

        private void ClosePositions(TradeType type)
        {
            Print("ClosePositions,", type);
            var p = Positions.Find(InstanceName, this.Symbol, type);


            if (p != null)
            {
                ClosePosition(p);
            }
        }

        private bool IsPositionOpenByType(TradeType type)
        {
            Print("IsPositionOpenByType,", type);
            var p = Positions.FindAll(InstanceName, Symbol, type);

            if (p.Count() >= posbuy)
            {
                return true;
            }

            return false;
        }


        bool isNearTarget()
        {
            Print("Trailing stop,", trailingStopType);

            if (this.currentPosition.TradeType == TradeType.Buy)
            {
                if (currentSymbol.Bid > this.currentPosition.TakeProfit - (this.currentSymbol.PipSize * this.TriggerPips))
                    return true;

            }
            else
            {
                if (currentSymbol.Ask < this.currentPosition.TakeProfit + (this.currentSymbol.PipSize * this.TriggerPips))
                    return true;
            }

            return false;
        }

        private void Optimiser()
        {
            if (trailingStopType != TrailingStopType.Optimiser)
            {
                return;
            }
            Print("Trailing stop,", trailingStopType);
            foreach (var pos in Positions)
            {
                this.currentSymbol = Symbols.GetSymbol(SymbolName);
                this.currentPosition = pos;

                if (isNearTarget())
                {

                    if (currentPosition.TradeType == TradeType.Buy)
                    {
                        newStopLoss = currentSymbol.Bid - (this.currentSymbol.PipSize * this.TrailSLPips);
                        newTakeProfit = currentSymbol.Bid + (this.currentSymbol.PipSize * this.TrailTPPips);
                    }
                    else
                    {
                        newStopLoss = currentSymbol.Ask + (this.currentSymbol.PipSize * this.TrailSLPips);
                        newTakeProfit = currentSymbol.Ask - (this.currentSymbol.PipSize * this.TrailTPPips);
                    }

                    if (newStopLoss == 0 || newTakeProfit == 0)
                        return;
                    ModifyPosition(currentPosition, newStopLoss, newTakeProfit);


                }
            }


        }


        private void ATRTrailingStop()
        {
            if (trailingStopType != TrailingStopType.ATR)
            {
                return;
            }
            Print("Trailing stop,", trailingStopType);
            var positions = Positions.FindAll(InstanceName, SymbolName);
            if (positions.Length > 0)
            {
                double atrPips = (atrTSL.Result.LastValue / Symbol.PipSize) * atrMultiplierSL;
                atrPips = Math.Round(atrPips, 1);
                ///Print(atrPips);
                foreach (var position in positions)
                {
                    if (position.TradeType == TradeType.Buy && Symbol.Bid - (atrPips * Symbol.PipSize) > position.StopLoss)
                    {
                        //Print("Old sl price: " + position.StopLoss);
                        ModifyPosition(position, Symbol.Bid - (atrPips * Symbol.PipSize), position.TakeProfit);
                        //Print("New sl price: " + position.StopLoss);
                    }
                    else if (position.TradeType == TradeType.Sell && Symbol.Ask + (atrPips * Symbol.PipSize) < position.StopLoss)
                    {
                        //Print("Old sl price: " + position.EntryPrice);
                        ModifyPosition(position, Symbol.Ask + (atrPips * Symbol.PipSize), position.TakeProfit);
                        //Print("New sl price: " + position.StopLoss);
                    }
                }
            }
        }

        private void MomentumTrailingStop()
        {
            if (trailingStopType != TrailingStopType.Momentum)
            {
                return;
            }
            Print("Trailing stop,", trailingStopType);
            var positions = Positions.FindAll(InstanceName, SymbolName);
            {
                if (positions.Length > 0)
                {
                    foreach (var position in positions)
                    {
                        if (position.TradeType == TradeType.Buy && position.StopLoss < position.EntryPrice)
                        {
                            var newStopLossPrice = Symbol.Ask - (Symbol.PipSize * stopLoss);
                            if (newStopLossPrice > position.StopLoss)
                            {
                                ModifyPosition(position, newStopLossPrice, position.TakeProfit);
                            }
                        }
                        else if (position.TradeType == TradeType.Sell && position.StopLoss > position.EntryPrice)
                        {
                            var newStopLossPrice = Symbol.Bid + (Symbol.PipSize * stopLoss);
                            if (newStopLossPrice < position.StopLoss)
                            {
                                ModifyPosition(position, newStopLossPrice, position.TakeProfit);
                            }
                        }
                    }
                }
            }
        }

        private double addSpreadToStopLoss()
        {
            if (enableAddSpread)
            {
                var spread = Math.Round(Symbol.Spread / Symbol.PipSize, 1);
                Print("Spread added to stop loss (", spread, ")");
                return spread;
            }
            return 0;
        }


        private double normalstoploss()
        {
            if (stoplossType == StopLossType.ATR)
            {

                double atrSLPips = (atrbuy.Result.LastValue / Symbol.PipSize) * SLATR;

                atrSLPips = Math.Round(atrSLPips, 1);
                if (atrSLPips < ATRMinimuStopLoss)
                {
                    atrSLPips = ATRMinimuStopLoss;
                }
                return atrSLPips;

            }

            else if (stoplossType == StopLossType.CandleLow)
            {
                var newStopLoss = Math.Round((Math.Abs((Bars.ClosePrices.Last(2) - Bars.LowPrices.Last(1))) / Symbol.PipSize), 3);
                return newStopLoss;

            }

            else
            {
                return stopLoss;

            }

        }

        private void OnPositionsClosed(PositionClosedEventArgs args)
        {
            double SPREAD;
            SPREAD = (double)((int)Math.Round(Symbol.Spread / Symbol.PipSize, 5));
            // check if the position has been closed due to stoploss or takeprofit or any other(stop out etc)
            if (args.Reason == PositionCloseReason.StopLoss)
            {
                Print("PID: [ {0} ] Stoploss Hit {1}   ||   Gain/Loss {2}Pips / $ {3}   ||   Spread:{4}   ||   {5} {6}:{7}:{8} ", LastResult.Position.Id, SymbolName, LastResult.Position.Pips, LastResult.Position.NetProfit, SPREAD, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
            else if (args.Reason == PositionCloseReason.TakeProfit)
            {
                Print("PID: [ {0} ] Take Profit Hit {1}   ||   Gain/Loss {2}Pips / $ {3}   ||   Spread:{4}   ||   {5} {6}:{7}:{8}", LastResult.Position.Id, SymbolName, LastResult.Position.Pips, LastResult.Position.NetProfit, SPREAD, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
            else if (args.Reason == PositionCloseReason.Closed)
            {
                Print("PID: [ {0} ] Exit Trade {1}   ||   Gain/Loss {2}Pips / $ {3}   ||   Spread:{4}   ||   {5} {6}:{7}:{8}", LastResult.Position.Id, SymbolName, LastResult.Position.Pips, LastResult.Position.NetProfit, SPREAD, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
            else if (args.Reason == PositionCloseReason.StopOut)
            {
                Print("PID: [ {0} ] StopOut {1}   ||   Gain/Loss {2}Pips / $ {3}   ||   Spread:{4}   ||   {5} {6}:{7}:{8}", LastResult.Position.Id, SymbolName, LastResult.Position.Pips, LastResult.Position.NetProfit, SPREAD, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
        }

        public enum TrailingStopType
        {
            Momentum,
            ATR,
            Optimiser,
            None
        }

        public enum StopLossType
        {
            Manual,
            ATR,
            CandleLow

        }
        #endregion


    }

}

 


@triplelorenz
Replies

amusleh
21 Mar 2022, 08:42

Hi,

Inside position closed event handler you are using LastResult, it's Position property is null:

        private void OnPositionsClosed(PositionClosedEventArgs args)
        {
            var SPREAD = (double)((int)Math.Round(Symbol.Spread / Symbol.PipSize, 5));
            // check if the position has been closed due to stoploss or takeprofit or any other(stop out etc)

            if (LastResult.Position == null)
            {
                Print("LastResult.Position is null");
            }

            if (args.Reason == PositionCloseReason.StopLoss)
            {
                Print("PID: [ {0} ] Stoploss Hit {1}   ||   Gain/Loss {2}Pips / $ {3}   ||   Spread:{4}   ||   {5} {6}:{7}:{8} ", LastResult.Position.Id, SymbolName, LastResult.Position.Pips, LastResult.Position.NetProfit, SPREAD, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
            else if (args.Reason == PositionCloseReason.TakeProfit)
            {
                Print("PID: [ {0} ] Take Profit Hit {1}   ||   Gain/Loss {2}Pips / $ {3}   ||   Spread:{4}   ||   {5} {6}:{7}:{8}", LastResult.Position.Id, SymbolName, LastResult.Position.Pips, LastResult.Position.NetProfit, SPREAD, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
            else if (args.Reason == PositionCloseReason.Closed)
            {
                Print("PID: [ {0} ] Exit Trade {1}   ||   Gain/Loss {2}Pips / $ {3}   ||   Spread:{4}   ||   {5} {6}:{7}:{8}", LastResult.Position.Id, SymbolName, LastResult.Position.Pips, LastResult.Position.NetProfit, SPREAD, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
            else if (args.Reason == PositionCloseReason.StopOut)
            {
                Print("PID: [ {0} ] StopOut {1}   ||   Gain/Loss {2}Pips / $ {3}   ||   Spread:{4}   ||   {5} {6}:{7}:{8}", LastResult.Position.Id, SymbolName, LastResult.Position.Pips, LastResult.Position.NetProfit, SPREAD, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
        }

Replace the above handler with yours, run your cBot, and you will that it prints "LastResult.Position is null" on logs.

To avoid such issues I strongly recommend you to learn C# basics before developing a cBot/Indicator.


@amusleh