cbot Stop after closing a trade.

Created at 01 Jun 2021, 16:50
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

traderfxmaster007

Joined 09.07.2019

cbot Stop after closing a trade.
01 Jun 2021, 16:50


hi i have a cbot that i created base on other free cbot plus some google search, i put on on the vps to let it run 24 hours 5 days a week.

but i notice that it only trade one per instance, after a trade the instance also stops, i dont want this i want it to run all the time. 

can any please try to take a look, whats wrong...

Sas

 


@traderfxmaster007
Replies

PanagiotisCharalampous
02 Jun 2021, 08:15

Hi traderfxmaster007,

Can you please share the cBot source code?

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

traderfxmaster007
02 Jun 2021, 14:34

RE:

Sir PanagiotisCharalampous, thank you for the reply, the error i got is 

Crashed in OnTick with NullReferenceException: Object reference not set to an instance of an object.
Im not a programmer so I can't find problems.
Pls help me.Thank you for looking.
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 MiaEMARibbon : Robot
    {
        #region User defined parameters

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

        [Parameter("Percentage Risk Model?", Group = "Money Management", DefaultValue = true)]
        public bool volPercentBool { get; set; }

        [Parameter("Scale Out?", Group = "Money Management", DefaultValue = true)]
        public bool ScaleOut { get; set; }

        [Parameter("Risk %", Group = "Money Management", DefaultValue = 1.5, MinValue = 1, MaxValue = 5)]
        public double volPercent { get; set; }

        [Parameter("Volume Quantity", Group = "Money Management", DefaultValue = 2000, MinValue = 1000, Step = 1000)]
        public int volQty { get; set; }

        [Parameter("StopLoss (*ATR)", Group = "Protection", DefaultValue = 1.5, Step = 0.1, MinValue = 1, MaxValue = 5)]
        public double ATRStopLoss { get; set; }

        [Parameter("TakeProfit (*ATR)", Group = "Protection", DefaultValue = 1.0, Step = 0.1, MinValue = 1, MaxValue = 5)]
        public double ATRTakeProfit { get; set; }

        [Parameter("BreakEven", Group = "Protection", DefaultValue = true)]
        public bool BreakEven { get; set; }

        [Parameter("BreakEvenTrigger (*ATR)", Group = "Protection", DefaultValue = 1.0, Step = 0.1, MinValue = 1, MaxValue = 5)]
        public double TriggerPips { get; set; }

        [Parameter("Locked in Profit", Group = "Protection", DefaultValue = 3.0, MinValue = 1.0)]
        public double AddPips { get; set; }

        [Parameter("Use Trailing Stop", Group = "Protection", DefaultValue = true)]
        public bool UseTrailingStop { get; set; }

        [Parameter("Trailing Stop Trigger (*ATR)", Group = "Protection", DefaultValue = 1.5, Step = 0.1, MinValue = 1, MaxValue = 5)]
        public double TrailingStopTrigger { get; set; }

        [Parameter("Trailing Stop Step (*ATR)", Group = "Protection", DefaultValue = 2.0, Step = 0.1, MinValue = 1, MaxValue = 5)]
        public double TrailingStopStep { get; set; }

        [Parameter("Close on Weekend?", Group = "Filter", DefaultValue = true)]
        public bool CloseOnWeekend { get; set; }

        [Parameter("Allowable Slippage", Group = "Filter", DefaultValue = 3.0, MinValue = 0.5, Step = 0.1)]
        public double Slippage { get; set; }

        [Parameter("Max Allowable Spread", Group = "Filter", DefaultValue = 2.0, MinValue = 0.1, MaxValue = 100.0, Step = 0.1)]
        public double MaxSpread { get; set; }

        [Parameter("Calculate OnBar?", Group = "Filter", DefaultValue = true)]
        public bool CalculateOnBar { get; set; }
        #endregion

        #region Indicator declarations
        private ExponentialMovingAverage EMA_1 { get; set; }
        private ExponentialMovingAverage EMA_2 { get; set; }
        private ExponentialMovingAverage EMA_3 { get; set; }
        private ExponentialMovingAverage EMA_4 { get; set; }
        private ExponentialMovingAverage EMA_5 { get; set; }
        private ExponentialMovingAverage EMA_6 { get; set; }
        private ExponentialMovingAverage EMA_7 { get; set; }
        private ExponentialMovingAverage EMA_8 { get; set; }
        private ExponentialMovingAverage EMA_9 { get; set; }
        private ExponentialMovingAverage EMA_10 { get; set; }

        private AverageTrueRange ATR;

        private double SPREAD;
        private int volume;
        private string Comment;
        private int lastbar;
        private double StopLoss;
        private double TakeProfit;

        #endregion

        #region Calculate Volume
        private int CalculateVolume(double stop_loss)
        {
            int result;
            switch (volPercentBool)
            {
                case true:
                    double costPerPip = (double)((int)(Symbol.PipValue * 100000));
                    double posSizeForRisk = Math.Round((Account.Balance * (volPercent / 100)) / (stop_loss * costPerPip), 2);
                    double posSizeToVol = (Math.Round(posSizeForRisk * 100000, 0));
                    Print("costperppip : $ {0}  ||  Lot : {1}  ||  Volume : {2}", costPerPip, posSizeForRisk, posSizeToVol);
                    result = (int)Symbol.NormalizeVolumeInUnits(posSizeToVol, RoundingMode.ToNearest);
                    result = result > 150000 ? 150000 : result;
                    result = result == 1000 ? 2000 : result;
                    Print("{0}% of Account Balance [ $ {1} ] used for Volume: {2}  ||  Risk : $ {3}", volPercent, Account.Balance, result, (StopLoss * costPerPip * result) / 100000);
                    break;
                default:
                    result = volQty;
                    Print("Volume Quantity Used! : {0}", result);
                    break;
            }
            return result;
        }
        #endregion

        #region Standard event handlers
        /// This is called when the robot first starts, it is only called once.
        protected override void OnStart()
        {
            ATR = Indicators.AverageTrueRange(14, MovingAverageType.Exponential);
            EMA_1 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 5);
            EMA_2 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 7);
            EMA_3 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 9);
            EMA_4 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 11);
            EMA_5 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 13);
            EMA_6 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 30);
            EMA_7 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 35);
            EMA_8 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 40);
            EMA_9 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 45);
            EMA_10 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 50);

            StopLoss = Math.Round((ATR.Result.Last(lastbar)) * ATRStopLoss / Symbol.PipSize, 0);
            TakeProfit = Math.Round((ATR.Result.Last(lastbar)) * ATRTakeProfit / Symbol.PipSize, 0);
            volume = CalculateVolume(StopLoss);
            SPREAD = Math.Round(Symbol.Spread / Symbol.PipSize, 2);
            Comment = "Chris Trend Trading ";
            if (CalculateOnBar)
                lastbar = 1;
            else
                lastbar = 0;

            // Subscribe to the Trade Closing event
            Positions.Closed += OnPositionsClosed;
        }


        /// This event handler is called every tick or every time the price changes for the symbol.
        protected override void OnTick()
        {
            //         ManagePositions();
        }

        /// a special event handler that is called each time a new bar is drawn on chart.
        /// if you want your robot to act only when the previous bar is closed, this standard handler is where you put your main trading code.
        protected override void OnBar()
        {
            ManagePositions();
            CloseHalf();
            MoveToBreakEven();
            SetTrailingStop();
        }

        /// a handler that is called on stopping the cBot.
        protected override void OnStop()
        {
// unused
        }

        /// a special Robot class member that handles situations with errors.
        protected override void OnError(Error error)
        {
            Print("Error Code {0}  ||  {1} {2}:{3}:{4}", error.Code, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
        }
        #endregion

        #region Logic

        private void ManagePositions()
        {
            /// if there is no buy position open, open one
            if (IsPositionOpenByType(TradeType.Buy) == false && Extreme() == false && BuyEntry() == true && EntryBar() == true)
            {
                if (Trader_Bullish() == false && Investor_Bullish() == true)
                {
                    OpenPosition(TradeType.Buy);
                }
                else if (Trader_Bullish() == true && Bars.ClosePrices.Last(lastbar + 1) < Bars.OpenPrices.Last(lastbar + 1))
                {
                    OpenPosition(TradeType.Buy);
                }
            }
            /// if there is no sell position open, open one
            else if (IsPositionOpenByType(TradeType.Sell) == false && Extreme() == false && SellEntry() == true && EntryBar() == true)
            {
                if (Trader_Bearish() == false && Investor_Bearish() == true)
                {
                    OpenPosition(TradeType.Sell);
                }
                else if (Trader_Bearish() == true && Bars.ClosePrices.Last(lastbar + 1) > Bars.OpenPrices.Last(lastbar + 1))
                {
                    OpenPosition(TradeType.Sell);
                }
            }

            /// Call custom class method to Close Open Position
            if (IsPositionOpenByType(TradeType.Buy) == true && BuyExit() == true)
                ClosePosition(TradeType.Buy);
            else if (IsPositionOpenByType(TradeType.Sell) == true && SellExit() == true)
                ClosePosition(TradeType.Sell);
        }
        #endregion
        #region Scale Out
        private void CloseHalf()
        {
            var positions = Positions.FindAll(InstanceName.ToString(), SymbolName);
            foreach (var position in positions)
            {
                var Secured = position.TradeType == TradeType.Buy ? position.StopLoss - position.EntryPrice : position.EntryPrice - position.StopLoss;
                var HalfVol = Math.Round(Symbol.NormalizeVolumeInUnits(((position.VolumeInUnits) / 2), RoundingMode.ToNearest), 0);
                if (ScaleOut == true && position.VolumeInUnits >= 2000 && (Secured / Symbol.PipSize) <= AddPips && position.Pips >= (ATR.Result.Last(lastbar) * ATRTakeProfit) / Symbol.PipSize)
                {
                    ClosePosition(position, HalfVol);
                    Print("[ {0} ] Scale Out {1}   ||   New Volume: {2}   ||   Gain/Loss {3} Pips / $ {4}   ||   {5} {6}:{7}:{8}", LastResult.Position.Id, SymbolName, position.VolumeInUnits, LastResult.Position.Pips, LastResult.Position.NetProfit, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
                }
            }
        }
        #endregion

        #region BreakEven

        /// Call custom class method to move StopLoss to BreakEven
        private void MoveToBreakEven()
        {
            var positions = Positions.FindAll(InstanceName.ToString(), SymbolName);
            foreach (var position in positions)
            {
                var desiredNetProfitInDepositAsset = AddPips * Symbol.PipValue * position.VolumeInUnits;
                var desiredGrossProfitInDepositAsset = desiredNetProfitInDepositAsset - position.Commissions * 2 - position.Swap;
                var quoteToDepositRate = Symbol.PipValue / Symbol.PipSize;
                var priceDifference = desiredGrossProfitInDepositAsset / (position.VolumeInUnits * quoteToDepositRate);
                var priceAdjustment = GetPriceAdjustmentByTradeType(position.TradeType, priceDifference);
                var breakEvenLevel = position.EntryPrice + priceAdjustment;
                var roundedBreakEvenLevel = RoundPrice(breakEvenLevel, position.TradeType);

                var stopposition = position.TradeType == TradeType.Buy ? position.EntryPrice - position.StopLoss : position.StopLoss - position.EntryPrice;
                if (BreakEven == true && stopposition > 0 && position.Pips >= (ATR.Result.Last(lastbar) * TriggerPips) / Symbol.PipSize)
                {
                    ModifyPosition(position, roundedBreakEvenLevel, position.TakeProfit);
                    Print("[ {0} ] Breakeven {1}   ||   {2} {3}:{4}:{5}", LastResult.Position.Id, SymbolName, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
                }
            }
        }
        #endregion

        #region TrailingStop
        private void SetTrailingStop()
        {
            var sellPositions = Positions.FindAll(InstanceName, SymbolName, TradeType.Sell);

            foreach (Position position in sellPositions)
            {
                double distance = position.EntryPrice - Symbol.Ask;

                if (distance < (ATR.Result.Last(lastbar) * TrailingStopTrigger))
                    continue;

                double newStopLossPrice = Symbol.Ask + (ATR.Result.Last(lastbar) * TrailingStopStep);
                var newStopLoss = RoundPrice(newStopLossPrice, position.TradeType);

                if (UseTrailingStop == true && (position.StopLoss == null || newStopLossPrice < position.StopLoss))
                    ModifyPosition(position, newStopLoss, position.TakeProfit);
                if (LastResult.IsSuccessful)
                    Print("[ {0} ] Trailing {1}   ||   New StopLoss: {2}   ||   {3} {4}:{5}:{6}", LastResult.Position.Id, SymbolName, LastResult.Position.StopLoss, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);

            }

            var buyPositions = Positions.FindAll(InstanceName, SymbolName, TradeType.Buy);

            foreach (Position position in buyPositions)
            {
                double distance = Symbol.Bid - position.EntryPrice;

                if (distance < (ATR.Result.Last(lastbar) * TrailingStopTrigger))
                    continue;

                double newStopLossPrice = Symbol.Bid - (ATR.Result.Last(lastbar) * TrailingStopStep);
                var newStopLoss = RoundPrice(newStopLossPrice, position.TradeType);
                if (UseTrailingStop == true && (position.StopLoss == null || newStopLossPrice > position.StopLoss))
                    ModifyPosition(position, newStopLoss, position.TakeProfit);
                if (LastResult.IsSuccessful)
                    Print("[ {0} ] Trailing {1}   ||   New StopLoss: {2}   ||   {3} {4}:{5}:{6}", LastResult.Position.Id, SymbolName, LastResult.Position.StopLoss, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
        }

        #endregion
        #region Open Trade
        /// Call custom class method to send a market order || open a new position

        private void OpenPosition(TradeType type)
        {
            var Pos = Positions.FindAll(InstanceName.ToString(), SymbolName);
            if (Pos.Count() == 0 && Server.Time.DayOfWeek <= DayOfWeek.Friday && Server.Time.Hour <= 19 && SPREAD <= MaxSpread)
            {
                if (ScaleOut)
                    ExecuteMarketRangeOrder(type, this.Symbol.Name, volume, Slippage, Symbol.Bid, InstanceName.ToString(), StopLoss, 0, Comment);
                else
                    ExecuteMarketRangeOrder(type, this.Symbol.Name, volume, Slippage, Symbol.Bid, InstanceName.ToString(), StopLoss, TakeProfit, Comment);
                if (LastResult.IsSuccessful)
                    Print("[ {0} ] Open {1} {2}    ||   Volume:{3}    ||   Spread:{4}   ||   {5} {6}:{7}:{8}", LastResult.Position.Id, type, SymbolName, LastResult.Position.VolumeInUnits, SPREAD, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
        }
        #endregion
        #region Close Trade
        /// Standard event handler that triggers upon position closing.
        private void ClosePosition(TradeType type)
        {
            var p = Positions.Find(InstanceName.ToString(), SymbolName, type);
            if (p != null)
            {
                ClosePosition(p);
                Print("[ {0} ] Close {1} {2}    ||   Volume:{3}    ||   Spread:{4}   ||   Gain/Loss {5}Pips / $ {6}   ||   {7} {8}:{9}:{10}", LastResult.Position.Id, type, SymbolName, LastResult.Position.VolumeInUnits, SPREAD, LastResult.Position.Pips, LastResult.Position.NetProfit, Server.Time.DayOfWeek, Server.Time.Hour,
                Server.Time.Minute, Server.Time.Second);
            }
            else if (CloseOnWeekend == true && p != null && Server.Time.DayOfWeek == DayOfWeek.Friday && Server.Time.Hour >= 21 && Server.Time.Minute >= 30)
            {
                ClosePosition(p);
                Print("[ {0} ] Close {1}  on Weekend   ||   Gain/Loss {1}Pips / $ {2}   ||   {3} {4}:{5}:{6}", LastResult.Position.Id, SymbolName, LastResult.Position.Pips, LastResult.Position.NetProfit, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }

        }


        /// Check for opened position
        private bool IsPositionOpenByType(TradeType type)
        {
            var p = Positions.FindAll(InstanceName.ToString(), SymbolName, type);

            if (p.Count() > 0 || p.Count() != 0)
                return true;
            return false;
        }
        private void OnPositionsClosed(PositionClosedEventArgs args)
        {
            // check if the position has been closed due to stoploss or takeprofit or any other(stop out etc)
            if (args.Reason == PositionCloseReason.StopLoss)
            {
                Print("[ {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("[ {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);
            }
        }
        #endregion

        #region Check for Setups
        //////////////////////////////////////////////////////////////////////////
        ///////////////////////// Check for Setups //////////////////////////////
        ////////////////////////////////////////////////////////////////////////
        private bool Trader_Bullish()
        {
            if (EMA_1.Result.Last(lastbar) >= EMA_2.Result.Last(lastbar) && EMA_2.Result.Last(lastbar) >= EMA_3.Result.Last(lastbar) && EMA_3.Result.Last(lastbar) >= EMA_4.Result.Last(lastbar) && EMA_4.Result.Last(lastbar) >= EMA_5.Result.Last(lastbar))
                return true;
            return false;
        }

        private bool Trader_Bearish()
        {
            if (EMA_1.Result.Last(lastbar) <= EMA_2.Result.Last(lastbar) && EMA_2.Result.Last(lastbar) <= EMA_3.Result.Last(lastbar) && EMA_3.Result.Last(lastbar) <= EMA_4.Result.Last(lastbar) && EMA_4.Result.Last(lastbar) <= EMA_5.Result.Last(lastbar))
                return true;
            return false;
        }
        private bool Investor_Bullish()
        {
            if (EMA_6.Result.Last(lastbar) >= EMA_7.Result.Last(lastbar) && EMA_7.Result.Last(lastbar) >= EMA_8.Result.Last(lastbar) && EMA_8.Result.Last(lastbar) >= EMA_9.Result.Last(lastbar) && EMA_9.Result.Last(lastbar) >= EMA_10.Result.Last(lastbar))
                return true;
            return false;
        }
        private bool Investor_Bearish()
        {
            if (EMA_6.Result.Last(lastbar) <= EMA_7.Result.Last(lastbar) && EMA_7.Result.Last(lastbar) <= EMA_8.Result.Last(lastbar) && EMA_8.Result.Last(lastbar) <= EMA_9.Result.Last(lastbar) && EMA_9.Result.Last(lastbar) <= EMA_10.Result.Last(lastbar))
                return true;
            return false;
        }
        private bool BuyEntry()
        {
            if (Bars.ClosePrices.Last(lastbar) > Bars.OpenPrices.Last(lastbar) && Bars.LowPrices.Last(lastbar) < EMA_3.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) > EMA_1.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) > EMA_5.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) > EMA_6.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) > EMA_10.Result.Last(lastbar))
                return true;
            return false;
        }
        private bool SellEntry()
        {
            if (Bars.ClosePrices.Last(lastbar) < Bars.OpenPrices.Last(lastbar) && Bars.HighPrices.Last(lastbar) > EMA_3.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) < EMA_1.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) < EMA_5.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) < EMA_6.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) < EMA_10.Result.Last(lastbar))
                return true;
            return false;
        }

        private bool BuyExit()
        {
            if (IsPositionOpenByType(TradeType.Buy) == true && EMA_1.Result.Last(lastbar) < EMA_2.Result.Last(lastbar) && EMA_1.Result.Last(lastbar) < EMA_3.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) < EMA_5.Result.Last(lastbar))
                return true;
            else if (IsPositionOpenByType(TradeType.Buy) == true && Bars.ClosePrices.Last(lastbar + 1) == Bars.LowPrices.Last(lastbar + 1) && Bars.ClosePrices.Last(lastbar + 2) == Bars.LowPrices.Last(lastbar + 2))
                return true;

            return false;
        }
        private bool SellExit()
        {
            if (IsPositionOpenByType(TradeType.Sell) == true && EMA_1.Result.Last(lastbar) > EMA_2.Result.Last(lastbar) && EMA_1.Result.Last(lastbar) > EMA_3.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) > EMA_5.Result.Last(lastbar))
                return true;
            else if (IsPositionOpenByType(TradeType.Sell) == true && Bars.ClosePrices.Last(lastbar + 1) == Bars.HighPrices.Last(lastbar + 1) && Bars.ClosePrices.Last(lastbar + 2) == Bars.HighPrices.Last(lastbar + 2))
                return true;
            return false;
        }
        private bool Extreme()
        {
            if (Math.Abs(EMA_1.Result.Last(lastbar) - EMA_5.Result.Last(lastbar)) > ATR.Result.Last(lastbar) * 1.618 || Math.Abs(EMA_5.Result.Last(lastbar) - EMA_6.Result.Last(lastbar)) > ATR.Result.Last(lastbar) * 1.382 || Math.Abs(EMA_6.Result.Last(lastbar) - EMA_10.Result.Last(lastbar)) > ATR.Result.Last(lastbar) * 1.618)
                return true;
            return false;
        }
        private bool EntryBar()
        {
            if (Math.Abs(Bars.OpenPrices.Last(lastbar) - Bars.ClosePrices.Last(lastbar)) > Math.Abs(Bars.HighPrices.Last(lastbar) - Bars.LowPrices.Last(lastbar)) * 0.618)
                return true;
            return false;
        }

        #endregion

        #region RoundPrice
        ////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////////////

        private double RoundPrice(double price, TradeType tradeType)
        {
            var multiplier = Math.Pow(10, Symbol.Digits);
            if (tradeType == TradeType.Buy)
                return Math.Ceiling(price * multiplier) / multiplier;

            return Math.Floor(price * multiplier) / multiplier;
        }

        private static double GetPriceAdjustmentByTradeType(TradeType tradeType, double priceDifference)
        {
            if (tradeType == TradeType.Buy)
                return priceDifference;

            return -priceDifference;
        }

        #endregion
    }
}

 


@traderfxmaster007

amusleh
02 Jun 2021, 16:58

Hi,

I backtested your cBot and it worked fine, if cBot got stopped then it means something is wrong with your code.

Please use this cBot code instead:

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

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

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

        [Parameter("Percentage Risk Model?", Group = "Money Management", DefaultValue = true)]
        public bool volPercentBool { get; set; }

        [Parameter("Scale Out?", Group = "Money Management", DefaultValue = true)]
        public bool ScaleOut { get; set; }

        [Parameter("Risk %", Group = "Money Management", DefaultValue = 1.5, MinValue = 1, MaxValue = 5)]
        public double volPercent { get; set; }

        [Parameter("Volume Quantity", Group = "Money Management", DefaultValue = 2000, MinValue = 1000, Step = 1000)]
        public int volQty { get; set; }

        [Parameter("StopLoss (*ATR)", Group = "Protection", DefaultValue = 1.5, Step = 0.1, MinValue = 1, MaxValue = 5)]
        public double ATRStopLoss { get; set; }

        [Parameter("TakeProfit (*ATR)", Group = "Protection", DefaultValue = 1.0, Step = 0.1, MinValue = 1, MaxValue = 5)]
        public double ATRTakeProfit { get; set; }

        [Parameter("BreakEven", Group = "Protection", DefaultValue = true)]
        public bool BreakEven { get; set; }

        [Parameter("BreakEvenTrigger (*ATR)", Group = "Protection", DefaultValue = 1.0, Step = 0.1, MinValue = 1, MaxValue = 5)]
        public double TriggerPips { get; set; }

        [Parameter("Locked in Profit", Group = "Protection", DefaultValue = 3.0, MinValue = 1.0)]
        public double AddPips { get; set; }

        [Parameter("Use Trailing Stop", Group = "Protection", DefaultValue = true)]
        public bool UseTrailingStop { get; set; }

        [Parameter("Trailing Stop Trigger (*ATR)", Group = "Protection", DefaultValue = 1.5, Step = 0.1, MinValue = 1, MaxValue = 5)]
        public double TrailingStopTrigger { get; set; }

        [Parameter("Trailing Stop Step (*ATR)", Group = "Protection", DefaultValue = 2.0, Step = 0.1, MinValue = 1, MaxValue = 5)]
        public double TrailingStopStep { get; set; }

        [Parameter("Close on Weekend?", Group = "Filter", DefaultValue = true)]
        public bool CloseOnWeekend { get; set; }

        [Parameter("Allowable Slippage", Group = "Filter", DefaultValue = 3.0, MinValue = 0.5, Step = 0.1)]
        public double Slippage { get; set; }

        [Parameter("Max Allowable Spread", Group = "Filter", DefaultValue = 2.0, MinValue = 0.1, MaxValue = 100.0, Step = 0.1)]
        public double MaxSpread { get; set; }

        [Parameter("Calculate OnBar?", Group = "Filter", DefaultValue = true)]
        public bool CalculateOnBar { get; set; }

        #endregion User defined parameters

        #region Indicator declarations

        private ExponentialMovingAverage EMA_1 { get; set; }
        private ExponentialMovingAverage EMA_2 { get; set; }
        private ExponentialMovingAverage EMA_3 { get; set; }
        private ExponentialMovingAverage EMA_4 { get; set; }
        private ExponentialMovingAverage EMA_5 { get; set; }
        private ExponentialMovingAverage EMA_6 { get; set; }
        private ExponentialMovingAverage EMA_7 { get; set; }
        private ExponentialMovingAverage EMA_8 { get; set; }
        private ExponentialMovingAverage EMA_9 { get; set; }
        private ExponentialMovingAverage EMA_10 { get; set; }

        private AverageTrueRange ATR;

        private double SPREAD;
        private int volume;
        private string Comment;
        private int lastbar;
        private double StopLoss;
        private double TakeProfit;

        #endregion Indicator declarations

        #region Calculate Volume

        private int CalculateVolume(double stop_loss)
        {
            int result;
            switch (volPercentBool)
            {
                case true:
                    double costPerPip = (double)((int)(Symbol.PipValue * 100000));
                    double posSizeForRisk = Math.Round((Account.Balance * (volPercent / 100)) / (stop_loss * costPerPip), 2);
                    double posSizeToVol = (Math.Round(posSizeForRisk * 100000, 0));
                    Print("costperppip : $ {0}  ||  Lot : {1}  ||  Volume : {2}", costPerPip, posSizeForRisk, posSizeToVol);
                    result = (int)Symbol.NormalizeVolumeInUnits(posSizeToVol, RoundingMode.ToNearest);
                    result = result > 150000 ? 150000 : result;
                    result = result == 1000 ? 2000 : result;
                    Print("{0}% of Account Balance [ $ {1} ] used for Volume: {2}  ||  Risk : $ {3}", volPercent, Account.Balance, result, (StopLoss * costPerPip * result) / 100000);
                    break;

                default:
                    result = volQty;
                    Print("Volume Quantity Used! : {0}", result);
                    break;
            }
            return result;
        }

        #endregion Calculate Volume

        #region Standard event handlers

        /// This is called when the robot first starts, it is only called once.
        protected override void OnStart()
        {
            ATR = Indicators.AverageTrueRange(14, MovingAverageType.Exponential);
            EMA_1 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 5);
            EMA_2 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 7);
            EMA_3 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 9);
            EMA_4 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 11);
            EMA_5 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 13);
            EMA_6 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 30);
            EMA_7 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 35);
            EMA_8 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 40);
            EMA_9 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 45);
            EMA_10 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 50);

            StopLoss = Math.Round((ATR.Result.Last(lastbar)) * ATRStopLoss / Symbol.PipSize, 0);
            TakeProfit = Math.Round((ATR.Result.Last(lastbar)) * ATRTakeProfit / Symbol.PipSize, 0);
            volume = CalculateVolume(StopLoss);
            SPREAD = Math.Round(Symbol.Spread / Symbol.PipSize, 2);
            Comment = "Chris Trend Trading ";
            if (CalculateOnBar)
                lastbar = 1;
            else
                lastbar = 0;

            // Subscribe to the Trade Closing event
            Positions.Closed += OnPositionsClosed;
        }

        /// This event handler is called every tick or every time the price changes for the symbol.
        protected override void OnTick()
        {
            try
            {
                ManagePositions();
            }
            catch (Exception ex)
            {
                Print(ex);

                Stop();
            }
        }

        /// a special event handler that is called each time a new bar is drawn on chart.
        /// if you want your robot to act only when the previous bar is closed, this standard handler is where you put your main trading code.
        protected override void OnBar()
        {
            try
            {
                ManagePositions();
                CloseHalf();
                MoveToBreakEven();
                SetTrailingStop();
            }
            catch (Exception ex)
            {
                Print(ex);

                Stop();
            }
        }

        /// a special Robot class member that handles situations with errors.
        protected override void OnError(Error error)
        {
            Print("Error Code {0}  ||  {1} {2}:{3}:{4}", error.Code, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
        }

        #endregion Standard event handlers

        #region Logic

        private void ManagePositions()
        {
            /// if there is no buy position open, open one
            if (IsPositionOpenByType(TradeType.Buy) == false && Extreme() == false && BuyEntry() == true && EntryBar() == true)
            {
                if (Trader_Bullish() == false && Investor_Bullish() == true)
                {
                    OpenPosition(TradeType.Buy);
                }
                else if (Trader_Bullish() == true && Bars.ClosePrices.Last(lastbar + 1) < Bars.OpenPrices.Last(lastbar + 1))
                {
                    OpenPosition(TradeType.Buy);
                }
            }
            /// if there is no sell position open, open one
            else if (IsPositionOpenByType(TradeType.Sell) == false && Extreme() == false && SellEntry() == true && EntryBar() == true)
            {
                if (Trader_Bearish() == false && Investor_Bearish() == true)
                {
                    OpenPosition(TradeType.Sell);
                }
                else if (Trader_Bearish() == true && Bars.ClosePrices.Last(lastbar + 1) > Bars.OpenPrices.Last(lastbar + 1))
                {
                    OpenPosition(TradeType.Sell);
                }
            }

            /// Call custom class method to Close Open Position
            if (IsPositionOpenByType(TradeType.Buy) == true && BuyExit() == true)
                ClosePosition(TradeType.Buy);
            else if (IsPositionOpenByType(TradeType.Sell) == true && SellExit() == true)
                ClosePosition(TradeType.Sell);
        }

        #endregion Logic

        #region Scale Out

        private void CloseHalf()
        {
            var positions = Positions.FindAll(InstanceName.ToString(), SymbolName);
            foreach (var position in positions)
            {
                var Secured = position.TradeType == TradeType.Buy ? position.StopLoss - position.EntryPrice : position.EntryPrice - position.StopLoss;
                var HalfVol = Math.Round(Symbol.NormalizeVolumeInUnits(((position.VolumeInUnits) / 2), RoundingMode.ToNearest), 0);
                if (ScaleOut == true && position.VolumeInUnits >= 2000 && (Secured / Symbol.PipSize) <= AddPips && position.Pips >= (ATR.Result.Last(lastbar) * ATRTakeProfit) / Symbol.PipSize)
                {
                    ClosePosition(position, HalfVol);
                    Print("[ {0} ] Scale Out {1}   ||   New Volume: {2}   ||   Gain/Loss {3} Pips / $ {4}   ||   {5} {6}:{7}:{8}", LastResult.Position.Id, SymbolName, position.VolumeInUnits, LastResult.Position.Pips, LastResult.Position.NetProfit, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
                }
            }
        }

        #endregion Scale Out

        #region BreakEven

        /// Call custom class method to move StopLoss to BreakEven
        private void MoveToBreakEven()
        {
            var positions = Positions.FindAll(InstanceName.ToString(), SymbolName);
            foreach (var position in positions)
            {
                var desiredNetProfitInDepositAsset = AddPips * Symbol.PipValue * position.VolumeInUnits;
                var desiredGrossProfitInDepositAsset = desiredNetProfitInDepositAsset - position.Commissions * 2 - position.Swap;
                var quoteToDepositRate = Symbol.PipValue / Symbol.PipSize;
                var priceDifference = desiredGrossProfitInDepositAsset / (position.VolumeInUnits * quoteToDepositRate);
                var priceAdjustment = GetPriceAdjustmentByTradeType(position.TradeType, priceDifference);
                var breakEvenLevel = position.EntryPrice + priceAdjustment;
                var roundedBreakEvenLevel = RoundPrice(breakEvenLevel, position.TradeType);

                var stopposition = position.TradeType == TradeType.Buy ? position.EntryPrice - position.StopLoss : position.StopLoss - position.EntryPrice;
                if (BreakEven == true && stopposition > 0 && position.Pips >= (ATR.Result.Last(lastbar) * TriggerPips) / Symbol.PipSize)
                {
                    ModifyPosition(position, roundedBreakEvenLevel, position.TakeProfit);
                    Print("[ {0} ] Breakeven {1}   ||   {2} {3}:{4}:{5}", LastResult.Position.Id, SymbolName, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
                }
            }
        }

        #endregion BreakEven

        #region TrailingStop

        private void SetTrailingStop()
        {
            var sellPositions = Positions.FindAll(InstanceName, SymbolName, TradeType.Sell);

            foreach (Position position in sellPositions)
            {
                double distance = position.EntryPrice - Symbol.Ask;

                if (distance < (ATR.Result.Last(lastbar) * TrailingStopTrigger))
                    continue;

                double newStopLossPrice = Symbol.Ask + (ATR.Result.Last(lastbar) * TrailingStopStep);
                var newStopLoss = RoundPrice(newStopLossPrice, position.TradeType);

                if (UseTrailingStop == true && (position.StopLoss == null || newStopLossPrice < position.StopLoss))
                    ModifyPosition(position, newStopLoss, position.TakeProfit);
                if (LastResult.IsSuccessful)
                    Print("[ {0} ] Trailing {1}   ||   New StopLoss: {2}   ||   {3} {4}:{5}:{6}", LastResult.Position.Id, SymbolName, LastResult.Position.StopLoss, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }

            var buyPositions = Positions.FindAll(InstanceName, SymbolName, TradeType.Buy);

            foreach (Position position in buyPositions)
            {
                double distance = Symbol.Bid - position.EntryPrice;

                if (distance < (ATR.Result.Last(lastbar) * TrailingStopTrigger))
                    continue;

                double newStopLossPrice = Symbol.Bid - (ATR.Result.Last(lastbar) * TrailingStopStep);
                var newStopLoss = RoundPrice(newStopLossPrice, position.TradeType);
                if (UseTrailingStop == true && (position.StopLoss == null || newStopLossPrice > position.StopLoss))
                    ModifyPosition(position, newStopLoss, position.TakeProfit);
                if (LastResult.IsSuccessful)
                    Print("[ {0} ] Trailing {1}   ||   New StopLoss: {2}   ||   {3} {4}:{5}:{6}", LastResult.Position.Id, SymbolName, LastResult.Position.StopLoss, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
        }

        #endregion TrailingStop

        #region Open Trade

        /// Call custom class method to send a market order || open a new position

        private void OpenPosition(TradeType type)
        {
            var Pos = Positions.FindAll(InstanceName.ToString(), SymbolName);
            if (Pos.Count() == 0 && Server.Time.DayOfWeek <= DayOfWeek.Friday && Server.Time.Hour <= 19 && SPREAD <= MaxSpread)
            {
                if (ScaleOut)
                    ExecuteMarketRangeOrder(type, this.Symbol.Name, volume, Slippage, Symbol.Bid, InstanceName.ToString(), StopLoss, 0, Comment);
                else
                    ExecuteMarketRangeOrder(type, this.Symbol.Name, volume, Slippage, Symbol.Bid, InstanceName.ToString(), StopLoss, TakeProfit, Comment);
                if (LastResult.IsSuccessful)
                    Print("[ {0} ] Open {1} {2}    ||   Volume:{3}    ||   Spread:{4}   ||   {5} {6}:{7}:{8}", LastResult.Position.Id, type, SymbolName, LastResult.Position.VolumeInUnits, SPREAD, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
        }

        #endregion Open Trade

        #region Close Trade

        /// Standard event handler that triggers upon position closing.
        private void ClosePosition(TradeType type)
        {
            var p = Positions.Find(InstanceName.ToString(), SymbolName, type);
            if (p != null)
            {
                ClosePosition(p);
                Print("[ {0} ] Close {1} {2}    ||   Volume:{3}    ||   Spread:{4}   ||   Gain/Loss {5}Pips / $ {6}   ||   {7} {8}:{9}:{10}", LastResult.Position.Id, type, SymbolName, LastResult.Position.VolumeInUnits, SPREAD, LastResult.Position.Pips, LastResult.Position.NetProfit, Server.Time.DayOfWeek, Server.Time.Hour,
                Server.Time.Minute, Server.Time.Second);
            }
            else if (CloseOnWeekend == true && p != null && Server.Time.DayOfWeek == DayOfWeek.Friday && Server.Time.Hour >= 21 && Server.Time.Minute >= 30)
            {
                ClosePosition(p);
                Print("[ {0} ] Close {1}  on Weekend   ||   Gain/Loss {1}Pips / $ {2}   ||   {3} {4}:{5}:{6}", LastResult.Position.Id, SymbolName, LastResult.Position.Pips, LastResult.Position.NetProfit, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
        }

        /// Check for opened position
        private bool IsPositionOpenByType(TradeType type)
        {
            var p = Positions.FindAll(InstanceName.ToString(), SymbolName, type);

            if (p.Count() > 0 || p.Count() != 0)
                return true;
            return false;
        }

        private void OnPositionsClosed(PositionClosedEventArgs args)
        {
            // check if the position has been closed due to stoploss or takeprofit or any other(stop out etc)
            if (args.Reason == PositionCloseReason.StopLoss)
            {
                Print("[ {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("[ {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);
            }
        }

        #endregion Close Trade

        #region Check for Setups

        //////////////////////////////////////////////////////////////////////////
        ///////////////////////// Check for Setups //////////////////////////////
        ////////////////////////////////////////////////////////////////////////
        private bool Trader_Bullish()
        {
            if (EMA_1.Result.Last(lastbar) >= EMA_2.Result.Last(lastbar) && EMA_2.Result.Last(lastbar) >= EMA_3.Result.Last(lastbar) && EMA_3.Result.Last(lastbar) >= EMA_4.Result.Last(lastbar) && EMA_4.Result.Last(lastbar) >= EMA_5.Result.Last(lastbar))
                return true;
            return false;
        }

        private bool Trader_Bearish()
        {
            if (EMA_1.Result.Last(lastbar) <= EMA_2.Result.Last(lastbar) && EMA_2.Result.Last(lastbar) <= EMA_3.Result.Last(lastbar) && EMA_3.Result.Last(lastbar) <= EMA_4.Result.Last(lastbar) && EMA_4.Result.Last(lastbar) <= EMA_5.Result.Last(lastbar))
                return true;
            return false;
        }

        private bool Investor_Bullish()
        {
            if (EMA_6.Result.Last(lastbar) >= EMA_7.Result.Last(lastbar) && EMA_7.Result.Last(lastbar) >= EMA_8.Result.Last(lastbar) && EMA_8.Result.Last(lastbar) >= EMA_9.Result.Last(lastbar) && EMA_9.Result.Last(lastbar) >= EMA_10.Result.Last(lastbar))
                return true;
            return false;
        }

        private bool Investor_Bearish()
        {
            if (EMA_6.Result.Last(lastbar) <= EMA_7.Result.Last(lastbar) && EMA_7.Result.Last(lastbar) <= EMA_8.Result.Last(lastbar) && EMA_8.Result.Last(lastbar) <= EMA_9.Result.Last(lastbar) && EMA_9.Result.Last(lastbar) <= EMA_10.Result.Last(lastbar))
                return true;
            return false;
        }

        private bool BuyEntry()
        {
            if (Bars.ClosePrices.Last(lastbar) > Bars.OpenPrices.Last(lastbar) && Bars.LowPrices.Last(lastbar) < EMA_3.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) > EMA_1.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) > EMA_5.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) > EMA_6.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) > EMA_10.Result.Last(lastbar))
                return true;
            return false;
        }

        private bool SellEntry()
        {
            if (Bars.ClosePrices.Last(lastbar) < Bars.OpenPrices.Last(lastbar) && Bars.HighPrices.Last(lastbar) > EMA_3.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) < EMA_1.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) < EMA_5.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) < EMA_6.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) < EMA_10.Result.Last(lastbar))
                return true;
            return false;
        }

        private bool BuyExit()
        {
            if (IsPositionOpenByType(TradeType.Buy) == true && EMA_1.Result.Last(lastbar) < EMA_2.Result.Last(lastbar) && EMA_1.Result.Last(lastbar) < EMA_3.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) < EMA_5.Result.Last(lastbar))
                return true;
            else if (IsPositionOpenByType(TradeType.Buy) == true && Bars.ClosePrices.Last(lastbar + 1) == Bars.LowPrices.Last(lastbar + 1) && Bars.ClosePrices.Last(lastbar + 2) == Bars.LowPrices.Last(lastbar + 2))
                return true;

            return false;
        }

        private bool SellExit()
        {
            if (IsPositionOpenByType(TradeType.Sell) == true && EMA_1.Result.Last(lastbar) > EMA_2.Result.Last(lastbar) && EMA_1.Result.Last(lastbar) > EMA_3.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) > EMA_5.Result.Last(lastbar))
                return true;
            else if (IsPositionOpenByType(TradeType.Sell) == true && Bars.ClosePrices.Last(lastbar + 1) == Bars.HighPrices.Last(lastbar + 1) && Bars.ClosePrices.Last(lastbar + 2) == Bars.HighPrices.Last(lastbar + 2))
                return true;
            return false;
        }

        private bool Extreme()
        {
            if (Math.Abs(EMA_1.Result.Last(lastbar) - EMA_5.Result.Last(lastbar)) > ATR.Result.Last(lastbar) * 1.618 || Math.Abs(EMA_5.Result.Last(lastbar) - EMA_6.Result.Last(lastbar)) > ATR.Result.Last(lastbar) * 1.382 || Math.Abs(EMA_6.Result.Last(lastbar) - EMA_10.Result.Last(lastbar)) > ATR.Result.Last(lastbar) * 1.618)
                return true;
            return false;
        }

        private bool EntryBar()
        {
            if (Math.Abs(Bars.OpenPrices.Last(lastbar) - Bars.ClosePrices.Last(lastbar)) > Math.Abs(Bars.HighPrices.Last(lastbar) - Bars.LowPrices.Last(lastbar)) * 0.618)
                return true;
            return false;
        }

        #endregion Check for Setups

        #region RoundPrice

        ////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////////////

        private double RoundPrice(double price, TradeType tradeType)
        {
            var multiplier = Math.Pow(10, Symbol.Digits);
            if (tradeType == TradeType.Buy)
                return Math.Ceiling(price * multiplier) / multiplier;

            return Math.Floor(price * multiplier) / multiplier;
        }

        private static double GetPriceAdjustmentByTradeType(TradeType tradeType, double priceDifference)
        {
            if (tradeType == TradeType.Buy)
                return priceDifference;

            return -priceDifference;
        }

        #endregion RoundPrice
    }
}

I added some debugging stuff, next time it stopped check the cTrader logs tab, there will be an error message, copy it and post it here.


@amusleh

traderfxmaster007
02 Jun 2021, 23:16

RE:

amusleh said:

Hi,

I backtested your cBot and it worked fine, if cBot got stopped then it means something is wrong with your code.

Please use this cBot code instead:

I added some debugging stuff, next time it stopped check the cTrader logs tab, there will be an error message, copy it and post it here.

hi thanks for your effort yes i also backtested it and its okay but when i forward test it only trade one trade then crashed. i will try your code and i will post here again if there will be error.

again thank you.

 


@traderfxmaster007

traderfxmaster007
03 Jun 2021, 08:31

RE: RE:

Sir Amusleh,

Same Error Code: 

Crashed in OnTick with NullReferenceException: Object reference not set to an instance of an object.

@traderfxmaster007

amusleh
04 Jun 2021, 07:41

RE: RE: RE:

traderfxmaster007 said:

Sir Amusleh,

Same Error Code: 

Crashed in OnTick with NullReferenceException: Object reference not set to an instance of an object.

Hi,

Can you copy the full logs tab data and post here? that's the default cTrader error message, I need the message that the Print method shows.

Something is wrong with your ManagePositions method.

Please use the below code this time, it will display more detailed data regarding the exception:

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

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

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

        [Parameter("Percentage Risk Model?", Group = "Money Management", DefaultValue = true)]
        public bool volPercentBool { get; set; }

        [Parameter("Scale Out?", Group = "Money Management", DefaultValue = true)]
        public bool ScaleOut { get; set; }

        [Parameter("Risk %", Group = "Money Management", DefaultValue = 1.5, MinValue = 1, MaxValue = 5)]
        public double volPercent { get; set; }

        [Parameter("Volume Quantity", Group = "Money Management", DefaultValue = 2000, MinValue = 1000, Step = 1000)]
        public int volQty { get; set; }

        [Parameter("StopLoss (*ATR)", Group = "Protection", DefaultValue = 1.5, Step = 0.1, MinValue = 1, MaxValue = 5)]
        public double ATRStopLoss { get; set; }

        [Parameter("TakeProfit (*ATR)", Group = "Protection", DefaultValue = 1.0, Step = 0.1, MinValue = 1, MaxValue = 5)]
        public double ATRTakeProfit { get; set; }

        [Parameter("BreakEven", Group = "Protection", DefaultValue = true)]
        public bool BreakEven { get; set; }

        [Parameter("BreakEvenTrigger (*ATR)", Group = "Protection", DefaultValue = 1.0, Step = 0.1, MinValue = 1, MaxValue = 5)]
        public double TriggerPips { get; set; }

        [Parameter("Locked in Profit", Group = "Protection", DefaultValue = 3.0, MinValue = 1.0)]
        public double AddPips { get; set; }

        [Parameter("Use Trailing Stop", Group = "Protection", DefaultValue = true)]
        public bool UseTrailingStop { get; set; }

        [Parameter("Trailing Stop Trigger (*ATR)", Group = "Protection", DefaultValue = 1.5, Step = 0.1, MinValue = 1, MaxValue = 5)]
        public double TrailingStopTrigger { get; set; }

        [Parameter("Trailing Stop Step (*ATR)", Group = "Protection", DefaultValue = 2.0, Step = 0.1, MinValue = 1, MaxValue = 5)]
        public double TrailingStopStep { get; set; }

        [Parameter("Close on Weekend?", Group = "Filter", DefaultValue = true)]
        public bool CloseOnWeekend { get; set; }

        [Parameter("Allowable Slippage", Group = "Filter", DefaultValue = 3.0, MinValue = 0.5, Step = 0.1)]
        public double Slippage { get; set; }

        [Parameter("Max Allowable Spread", Group = "Filter", DefaultValue = 2.0, MinValue = 0.1, MaxValue = 100.0, Step = 0.1)]
        public double MaxSpread { get; set; }

        [Parameter("Calculate OnBar?", Group = "Filter", DefaultValue = true)]
        public bool CalculateOnBar { get; set; }

        #endregion User defined parameters

        #region Indicator declarations

        private ExponentialMovingAverage EMA_1 { get; set; }
        private ExponentialMovingAverage EMA_2 { get; set; }
        private ExponentialMovingAverage EMA_3 { get; set; }
        private ExponentialMovingAverage EMA_4 { get; set; }
        private ExponentialMovingAverage EMA_5 { get; set; }
        private ExponentialMovingAverage EMA_6 { get; set; }
        private ExponentialMovingAverage EMA_7 { get; set; }
        private ExponentialMovingAverage EMA_8 { get; set; }
        private ExponentialMovingAverage EMA_9 { get; set; }
        private ExponentialMovingAverage EMA_10 { get; set; }

        private AverageTrueRange ATR;

        private double SPREAD;
        private int volume;
        private string Comment;
        private int lastbar;
        private double StopLoss;
        private double TakeProfit;

        #endregion Indicator declarations

        #region Calculate Volume

        private int CalculateVolume(double stop_loss)
        {
            int result;
            switch (volPercentBool)
            {
                case true:
                    double costPerPip = (double)((int)(Symbol.PipValue * 100000));
                    double posSizeForRisk = Math.Round((Account.Balance * (volPercent / 100)) / (stop_loss * costPerPip), 2);
                    double posSizeToVol = (Math.Round(posSizeForRisk * 100000, 0));
                    Print("costperppip : $ {0}  ||  Lot : {1}  ||  Volume : {2}", costPerPip, posSizeForRisk, posSizeToVol);
                    result = (int)Symbol.NormalizeVolumeInUnits(posSizeToVol, RoundingMode.ToNearest);
                    result = result > 150000 ? 150000 : result;
                    result = result == 1000 ? 2000 : result;
                    Print("{0}% of Account Balance [ $ {1} ] used for Volume: {2}  ||  Risk : $ {3}", volPercent, Account.Balance, result, (StopLoss * costPerPip * result) / 100000);
                    break;

                default:
                    result = volQty;
                    Print("Volume Quantity Used! : {0}", result);
                    break;
            }
            return result;
        }

        #endregion Calculate Volume

        #region Standard event handlers

        /// This is called when the robot first starts, it is only called once.
        protected override void OnStart()
        {
            ATR = Indicators.AverageTrueRange(14, MovingAverageType.Exponential);
            EMA_1 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 5);
            EMA_2 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 7);
            EMA_3 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 9);
            EMA_4 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 11);
            EMA_5 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 13);
            EMA_6 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 30);
            EMA_7 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 35);
            EMA_8 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 40);
            EMA_9 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 45);
            EMA_10 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 50);

            StopLoss = Math.Round((ATR.Result.Last(lastbar)) * ATRStopLoss / Symbol.PipSize, 0);
            TakeProfit = Math.Round((ATR.Result.Last(lastbar)) * ATRTakeProfit / Symbol.PipSize, 0);
            volume = CalculateVolume(StopLoss);
            SPREAD = Math.Round(Symbol.Spread / Symbol.PipSize, 2);
            Comment = "Chris Trend Trading ";
            if (CalculateOnBar)
                lastbar = 1;
            else
                lastbar = 0;

            // Subscribe to the Trade Closing event
            Positions.Closed += OnPositionsClosed;
        }

        /// This event handler is called every tick or every time the price changes for the symbol.
        protected override void OnTick()
        {
            try
            {
                ManagePositions();
            }
            catch (Exception ex)
            {
                Print(ex.GetLog());

                //Stop();
            }
        }

        /// a special event handler that is called each time a new bar is drawn on chart.
        /// if you want your robot to act only when the previous bar is closed, this standard handler is where you put your main trading code.
        protected override void OnBar()
        {
            try
            {
                ManagePositions();
                CloseHalf();
                MoveToBreakEven();
                SetTrailingStop();
            }
            catch (Exception ex)
            {
                Print(ex.GetLog());

                //Stop();
            }
        }

        /// a special Robot class member that handles situations with errors.
        protected override void OnError(Error error)
        {
            Print("Error Code {0}  ||  {1} {2}:{3}:{4}", error.Code, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
        }

        #endregion Standard event handlers

        #region Logic

        private void ManagePositions()
        {
            /// if there is no buy position open, open one
            if (IsPositionOpenByType(TradeType.Buy) == false && Extreme() == false && BuyEntry() == true && EntryBar() == true)
            {
                if (Trader_Bullish() == false && Investor_Bullish() == true)
                {
                    OpenPosition(TradeType.Buy);
                }
                else if (Trader_Bullish() == true && Bars.ClosePrices.Last(lastbar + 1) < Bars.OpenPrices.Last(lastbar + 1))
                {
                    OpenPosition(TradeType.Buy);
                }
            }
            /// if there is no sell position open, open one
            else if (IsPositionOpenByType(TradeType.Sell) == false && Extreme() == false && SellEntry() == true && EntryBar() == true)
            {
                if (Trader_Bearish() == false && Investor_Bearish() == true)
                {
                    OpenPosition(TradeType.Sell);
                }
                else if (Trader_Bearish() == true && Bars.ClosePrices.Last(lastbar + 1) > Bars.OpenPrices.Last(lastbar + 1))
                {
                    OpenPosition(TradeType.Sell);
                }
            }

            /// Call custom class method to Close Open Position
            if (IsPositionOpenByType(TradeType.Buy) == true && BuyExit() == true)
                ClosePosition(TradeType.Buy);
            else if (IsPositionOpenByType(TradeType.Sell) == true && SellExit() == true)
                ClosePosition(TradeType.Sell);
        }

        #endregion Logic

        #region Scale Out

        private void CloseHalf()
        {
            var positions = Positions.FindAll(InstanceName.ToString(), SymbolName);
            foreach (var position in positions)
            {
                var Secured = position.TradeType == TradeType.Buy ? position.StopLoss - position.EntryPrice : position.EntryPrice - position.StopLoss;
                var HalfVol = Math.Round(Symbol.NormalizeVolumeInUnits(((position.VolumeInUnits) / 2), RoundingMode.ToNearest), 0);
                if (ScaleOut == true && position.VolumeInUnits >= 2000 && (Secured / Symbol.PipSize) <= AddPips && position.Pips >= (ATR.Result.Last(lastbar) * ATRTakeProfit) / Symbol.PipSize)
                {
                    ClosePosition(position, HalfVol);
                    Print("[ {0} ] Scale Out {1}   ||   New Volume: {2}   ||   Gain/Loss {3} Pips / $ {4}   ||   {5} {6}:{7}:{8}", LastResult.Position.Id, SymbolName, position.VolumeInUnits, LastResult.Position.Pips, LastResult.Position.NetProfit, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
                }
            }
        }

        #endregion Scale Out

        #region BreakEven

        /// Call custom class method to move StopLoss to BreakEven
        private void MoveToBreakEven()
        {
            var positions = Positions.FindAll(InstanceName.ToString(), SymbolName);
            foreach (var position in positions)
            {
                var desiredNetProfitInDepositAsset = AddPips * Symbol.PipValue * position.VolumeInUnits;
                var desiredGrossProfitInDepositAsset = desiredNetProfitInDepositAsset - position.Commissions * 2 - position.Swap;
                var quoteToDepositRate = Symbol.PipValue / Symbol.PipSize;
                var priceDifference = desiredGrossProfitInDepositAsset / (position.VolumeInUnits * quoteToDepositRate);
                var priceAdjustment = GetPriceAdjustmentByTradeType(position.TradeType, priceDifference);
                var breakEvenLevel = position.EntryPrice + priceAdjustment;
                var roundedBreakEvenLevel = RoundPrice(breakEvenLevel, position.TradeType);

                var stopposition = position.TradeType == TradeType.Buy ? position.EntryPrice - position.StopLoss : position.StopLoss - position.EntryPrice;
                if (BreakEven == true && stopposition > 0 && position.Pips >= (ATR.Result.Last(lastbar) * TriggerPips) / Symbol.PipSize)
                {
                    ModifyPosition(position, roundedBreakEvenLevel, position.TakeProfit);
                    Print("[ {0} ] Breakeven {1}   ||   {2} {3}:{4}:{5}", LastResult.Position.Id, SymbolName, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
                }
            }
        }

        #endregion BreakEven

        #region TrailingStop

        private void SetTrailingStop()
        {
            var sellPositions = Positions.FindAll(InstanceName, SymbolName, TradeType.Sell);

            foreach (Position position in sellPositions)
            {
                double distance = position.EntryPrice - Symbol.Ask;

                if (distance < (ATR.Result.Last(lastbar) * TrailingStopTrigger))
                    continue;

                double newStopLossPrice = Symbol.Ask + (ATR.Result.Last(lastbar) * TrailingStopStep);
                var newStopLoss = RoundPrice(newStopLossPrice, position.TradeType);

                if (UseTrailingStop == true && (position.StopLoss == null || newStopLossPrice < position.StopLoss))
                    ModifyPosition(position, newStopLoss, position.TakeProfit);
                if (LastResult.IsSuccessful)
                    Print("[ {0} ] Trailing {1}   ||   New StopLoss: {2}   ||   {3} {4}:{5}:{6}", LastResult.Position.Id, SymbolName, LastResult.Position.StopLoss, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }

            var buyPositions = Positions.FindAll(InstanceName, SymbolName, TradeType.Buy);

            foreach (Position position in buyPositions)
            {
                double distance = Symbol.Bid - position.EntryPrice;

                if (distance < (ATR.Result.Last(lastbar) * TrailingStopTrigger))
                    continue;

                double newStopLossPrice = Symbol.Bid - (ATR.Result.Last(lastbar) * TrailingStopStep);
                var newStopLoss = RoundPrice(newStopLossPrice, position.TradeType);
                if (UseTrailingStop == true && (position.StopLoss == null || newStopLossPrice > position.StopLoss))
                    ModifyPosition(position, newStopLoss, position.TakeProfit);
                if (LastResult.IsSuccessful)
                    Print("[ {0} ] Trailing {1}   ||   New StopLoss: {2}   ||   {3} {4}:{5}:{6}", LastResult.Position.Id, SymbolName, LastResult.Position.StopLoss, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
        }

        #endregion TrailingStop

        #region Open Trade

        /// Call custom class method to send a market order || open a new position

        private void OpenPosition(TradeType type)
        {
            var Pos = Positions.FindAll(InstanceName.ToString(), SymbolName);
            if (Pos.Count() == 0 && Server.Time.DayOfWeek <= DayOfWeek.Friday && Server.Time.Hour <= 19 && SPREAD <= MaxSpread)
            {
                if (ScaleOut)
                    ExecuteMarketRangeOrder(type, this.Symbol.Name, volume, Slippage, Symbol.Bid, InstanceName.ToString(), StopLoss, 0, Comment);
                else
                    ExecuteMarketRangeOrder(type, this.Symbol.Name, volume, Slippage, Symbol.Bid, InstanceName.ToString(), StopLoss, TakeProfit, Comment);
                if (LastResult.IsSuccessful)
                    Print("[ {0} ] Open {1} {2}    ||   Volume:{3}    ||   Spread:{4}   ||   {5} {6}:{7}:{8}", LastResult.Position.Id, type, SymbolName, LastResult.Position.VolumeInUnits, SPREAD, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
        }

        #endregion Open Trade

        #region Close Trade

        /// Standard event handler that triggers upon position closing.
        private void ClosePosition(TradeType type)
        {
            var p = Positions.Find(InstanceName.ToString(), SymbolName, type);
            if (p != null)
            {
                ClosePosition(p);
                Print("[ {0} ] Close {1} {2}    ||   Volume:{3}    ||   Spread:{4}   ||   Gain/Loss {5}Pips / $ {6}   ||   {7} {8}:{9}:{10}", LastResult.Position.Id, type, SymbolName, LastResult.Position.VolumeInUnits, SPREAD, LastResult.Position.Pips, LastResult.Position.NetProfit, Server.Time.DayOfWeek, Server.Time.Hour,
                Server.Time.Minute, Server.Time.Second);
            }
            else if (CloseOnWeekend == true && p != null && Server.Time.DayOfWeek == DayOfWeek.Friday && Server.Time.Hour >= 21 && Server.Time.Minute >= 30)
            {
                ClosePosition(p);
                Print("[ {0} ] Close {1}  on Weekend   ||   Gain/Loss {1}Pips / $ {2}   ||   {3} {4}:{5}:{6}", LastResult.Position.Id, SymbolName, LastResult.Position.Pips, LastResult.Position.NetProfit, Server.Time.DayOfWeek, Server.Time.Hour, Server.Time.Minute, Server.Time.Second);
            }
        }

        /// Check for opened position
        private bool IsPositionOpenByType(TradeType type)
        {
            var p = Positions.FindAll(InstanceName.ToString(), SymbolName, type);

            if (p.Count() > 0 || p.Count() != 0)
                return true;
            return false;
        }

        private void OnPositionsClosed(PositionClosedEventArgs args)
        {
            // check if the position has been closed due to stoploss or takeprofit or any other(stop out etc)
            if (args.Reason == PositionCloseReason.StopLoss)
            {
                Print("[ {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("[ {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);
            }
        }

        #endregion Close Trade

        #region Check for Setups

        //////////////////////////////////////////////////////////////////////////
        ///////////////////////// Check for Setups //////////////////////////////
        ////////////////////////////////////////////////////////////////////////
        private bool Trader_Bullish()
        {
            if (EMA_1.Result.Last(lastbar) >= EMA_2.Result.Last(lastbar) && EMA_2.Result.Last(lastbar) >= EMA_3.Result.Last(lastbar) && EMA_3.Result.Last(lastbar) >= EMA_4.Result.Last(lastbar) && EMA_4.Result.Last(lastbar) >= EMA_5.Result.Last(lastbar))
                return true;
            return false;
        }

        private bool Trader_Bearish()
        {
            if (EMA_1.Result.Last(lastbar) <= EMA_2.Result.Last(lastbar) && EMA_2.Result.Last(lastbar) <= EMA_3.Result.Last(lastbar) && EMA_3.Result.Last(lastbar) <= EMA_4.Result.Last(lastbar) && EMA_4.Result.Last(lastbar) <= EMA_5.Result.Last(lastbar))
                return true;
            return false;
        }

        private bool Investor_Bullish()
        {
            if (EMA_6.Result.Last(lastbar) >= EMA_7.Result.Last(lastbar) && EMA_7.Result.Last(lastbar) >= EMA_8.Result.Last(lastbar) && EMA_8.Result.Last(lastbar) >= EMA_9.Result.Last(lastbar) && EMA_9.Result.Last(lastbar) >= EMA_10.Result.Last(lastbar))
                return true;
            return false;
        }

        private bool Investor_Bearish()
        {
            if (EMA_6.Result.Last(lastbar) <= EMA_7.Result.Last(lastbar) && EMA_7.Result.Last(lastbar) <= EMA_8.Result.Last(lastbar) && EMA_8.Result.Last(lastbar) <= EMA_9.Result.Last(lastbar) && EMA_9.Result.Last(lastbar) <= EMA_10.Result.Last(lastbar))
                return true;
            return false;
        }

        private bool BuyEntry()
        {
            if (Bars.ClosePrices.Last(lastbar) > Bars.OpenPrices.Last(lastbar) && Bars.LowPrices.Last(lastbar) < EMA_3.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) > EMA_1.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) > EMA_5.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) > EMA_6.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) > EMA_10.Result.Last(lastbar))
                return true;
            return false;
        }

        private bool SellEntry()
        {
            if (Bars.ClosePrices.Last(lastbar) < Bars.OpenPrices.Last(lastbar) && Bars.HighPrices.Last(lastbar) > EMA_3.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) < EMA_1.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) < EMA_5.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) < EMA_6.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) < EMA_10.Result.Last(lastbar))
                return true;
            return false;
        }

        private bool BuyExit()
        {
            if (IsPositionOpenByType(TradeType.Buy) == true && EMA_1.Result.Last(lastbar) < EMA_2.Result.Last(lastbar) && EMA_1.Result.Last(lastbar) < EMA_3.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) < EMA_5.Result.Last(lastbar))
                return true;
            else if (IsPositionOpenByType(TradeType.Buy) == true && Bars.ClosePrices.Last(lastbar + 1) == Bars.LowPrices.Last(lastbar + 1) && Bars.ClosePrices.Last(lastbar + 2) == Bars.LowPrices.Last(lastbar + 2))
                return true;

            return false;
        }

        private bool SellExit()
        {
            if (IsPositionOpenByType(TradeType.Sell) == true && EMA_1.Result.Last(lastbar) > EMA_2.Result.Last(lastbar) && EMA_1.Result.Last(lastbar) > EMA_3.Result.Last(lastbar) && Bars.ClosePrices.Last(lastbar) > EMA_5.Result.Last(lastbar))
                return true;
            else if (IsPositionOpenByType(TradeType.Sell) == true && Bars.ClosePrices.Last(lastbar + 1) == Bars.HighPrices.Last(lastbar + 1) && Bars.ClosePrices.Last(lastbar + 2) == Bars.HighPrices.Last(lastbar + 2))
                return true;
            return false;
        }

        private bool Extreme()
        {
            if (Math.Abs(EMA_1.Result.Last(lastbar) - EMA_5.Result.Last(lastbar)) > ATR.Result.Last(lastbar) * 1.618 || Math.Abs(EMA_5.Result.Last(lastbar) - EMA_6.Result.Last(lastbar)) > ATR.Result.Last(lastbar) * 1.382 || Math.Abs(EMA_6.Result.Last(lastbar) - EMA_10.Result.Last(lastbar)) > ATR.Result.Last(lastbar) * 1.618)
                return true;
            return false;
        }

        private bool EntryBar()
        {
            if (Math.Abs(Bars.OpenPrices.Last(lastbar) - Bars.ClosePrices.Last(lastbar)) > Math.Abs(Bars.HighPrices.Last(lastbar) - Bars.LowPrices.Last(lastbar)) * 0.618)
                return true;
            return false;
        }

        #endregion Check for Setups

        #region RoundPrice

        ////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////////////

        private double RoundPrice(double price, TradeType tradeType)
        {
            var multiplier = Math.Pow(10, Symbol.Digits);
            if (tradeType == TradeType.Buy)
                return Math.Ceiling(price * multiplier) / multiplier;

            return Math.Floor(price * multiplier) / multiplier;
        }

        private static double GetPriceAdjustmentByTradeType(TradeType tradeType, double priceDifference)
        {
            if (tradeType == TradeType.Buy)
                return priceDifference;

            return -priceDifference;
        }

        #endregion RoundPrice
    }

    public static class ExceptionExtensions
    {
        public static string GetLog(this Exception exception)
        {
            return exception.GetLog(null, false);
        }

        private static string GetLog(this Exception exception, string intend, bool isInnerException)
        {
            var stringBuilder = new StringBuilder();

            intend = intend ?? string.Empty;

            if (isInnerException)
            {
                stringBuilder.AppendLine();
                stringBuilder.AppendFormat("{0}InnerException:", intend);
            }
            else
            {
                var systemType = Environment.Is64BitOperatingSystem ? "64-bit" : "32-bit";

                stringBuilder.AppendLine();
                stringBuilder.AppendFormat("OS Version: {0}", Environment.OSVersion.VersionString);
                stringBuilder.AppendLine();
                stringBuilder.AppendFormat("System Type: {0}", systemType);
            }

            stringBuilder.AppendLine();
            stringBuilder.AppendFormat("{0}Source: {1}", intend, exception.Source);
            stringBuilder.AppendLine();
            stringBuilder.AppendFormat("{0}Message: {1}", intend, exception.Message);
            stringBuilder.AppendLine();
            stringBuilder.AppendFormat("{0}TargetSite: {1}", intend, exception.TargetSite);
            stringBuilder.AppendLine();
            stringBuilder.AppendFormat("{0}Type: {1}", intend, exception.GetType());
            stringBuilder.AppendLine();

            var stackTrace = exception.GetStackTrace(intend);

            stringBuilder.AppendLine(stackTrace);

            stringBuilder.AppendLine();

            if (exception.InnerException != null)
            {
                var innerExceptionIntent = new string(' ', intend.Length + 4);

                var innerExceptionSummary = exception.InnerException.GetLog(innerExceptionIntent, true);

                stringBuilder.Append(innerExceptionSummary);
            }

            return stringBuilder.ToString();
        }

        public static string GetStackTrace(this Exception exception)
        {
            return exception.GetStackTrace(null);
        }

        private static string GetStackTrace(this Exception exception, string intend)
        {
            if (string.IsNullOrEmpty(exception.StackTrace))
            {
                return string.Empty;
            }

            var stackTrace = new StackTrace(exception, true);

            var frames = stackTrace.GetFrames();

            if (frames == null || !frames.Any())
            {
                return string.Empty;
            }

            var stringBuilder = new StringBuilder();

            stringBuilder.AppendFormat("{0}StackTrace:", intend);
            stringBuilder.AppendLine();

            var tracesIntend = new string(' ', string.IsNullOrEmpty(intend) ? 4 : intend.Length + 4);

            foreach (var stackFram in frames)
            {
                var fileName = stackFram.GetFileName();

                fileName = !string.IsNullOrEmpty(fileName)
                    ? fileName.Substring(fileName.LastIndexOf(@"\", StringComparison.InvariantCultureIgnoreCase) + 1)
                    : string.Empty;

                stringBuilder.AppendFormat("{0}File: {1} | Line: {2} | Col: {3} | Offset: {4} | Method: {5}", tracesIntend, fileName, stackFram.GetFileLineNumber(), stackFram.GetFileColumnNumber(), stackFram.GetILOffset(), stackFram.GetMethod());

                stringBuilder.AppendLine();
            }

            return stringBuilder.ToString();
        }
    }
}

 


@amusleh

traderfxmaster007
04 Jun 2021, 13:00

Faulting application name: cTrader.exe, version: 4.0.14.48970, time stamp: 0xafdfe7f4
Faulting module name: PresentationCore.ni.dll, version: 4.8.4110.0, time stamp: 0x5de7179c
Exception code: 0xc00000fd
Fault offset: 0x0000000000350324
Faulting process id: 0x8d4
Faulting application start time: 0x01d756152ce5d722
Faulting application path: C:\Users\Administrator\AppData\Local\Apps\2.0\6PBGL0GK.DOV\JTW5VCAE.AMT\icma..ader_7ef853fc4bdbd138_0004.0000_0ba06d2b7438f083\cTrader.exe
Faulting module path: C:\windows\assembly\NativeImages_v4.0.30319_64\PresentationCore\461b892934d24d029a6ef6d42101af09\PresentationCore.ni.dll
Report Id: 44b3c76c-c45b-11eb-85ad-f15c940a3a9d


@traderfxmaster007

amusleh
05 Jun 2021, 19:30

RE:

traderfxmaster007 said:

Faulting application name: cTrader.exe, version: 4.0.14.48970, time stamp: 0xafdfe7f4
Faulting module name: PresentationCore.ni.dll, version: 4.8.4110.0, time stamp: 0x5de7179c
Exception code: 0xc00000fd
Fault offset: 0x0000000000350324
Faulting process id: 0x8d4
Faulting application start time: 0x01d756152ce5d722
Faulting application path: C:\Users\Administrator\AppData\Local\Apps\2.0\6PBGL0GK.DOV\JTW5VCAE.AMT\icma..ader_7ef853fc4bdbd138_0004.0000_0ba06d2b7438f083\cTrader.exe
Faulting module path: C:\windows\assembly\NativeImages_v4.0.30319_64\PresentationCore\461b892934d24d029a6ef6d42101af09\PresentationCore.ni.dll
Report Id: 44b3c76c-c45b-11eb-85ad-f15c940a3a9d

Hi,

Its not what I asked you to post, please run the cBot code I posted on my latest post and run it, when it crashed a message will appear on cTrader cBot logs tab, copy it and post it here.


@amusleh