Cannot access new value from MACD Divergence indicator from bot

Created at 07 Mar 2019, 21:46
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!
DA

daniel.agg

Joined 03.02.2019

Cannot access new value from MACD Divergence indicator from bot
07 Mar 2019, 21:46


Hi, I wanted to create a simple bot that's using only this indicator:

[https://ctrader.com/algos/indicators/show/1807]

However, when I backtest the bot, it seems that while indicator itself does add a new entry to its Data property (which is public), but right after it has added a new entry and the bot reaches the OnTick(), the indicator's instance's (initialized at OnStart from the bot) Data does not contain the newly added entry.

I have removed the IsBacktesting() checks from the indicator.

I've debugged the bot and indicator via attaching to ctrader from Visual Studio: here we can see the indicator's code, as it adds a new entry to 'Data':

 

Right after this, I've placed a breakpoint to the bot's OnTick, where I found that the bot cannot see the 5th item from the Data.

 

Interestingly enough, it seems this indicator is not the same instance as the indicator I've stopped on a breakpoint.

I have tried raising an event when the indicator adds a new entry to Data and have the bot subscribe to that, but the subscriber method of the bot was never reached then (I'm not sure that cAlgo even supports that anyway).

The source code of the bot and indicator: https://www.justbeamit.com/xbg3v

Thanks,
Dan


@daniel.agg
Replies

daniel.agg
07 Mar 2019, 21:51

Sorry, seems like the link to the source code is broken. Reuploaded:
https://drive.google.com/file/d/1CuMe7hKGLAK3XJW0HDQ9RucmDDiEps0S/view?usp=sharing


@daniel.agg

PanagiotisCharalampous
08 Mar 2019, 09:32

Hi daniel.agg,

Thanks for posting in our forum. I downloaded the cBot but there is no source code. Can you please send it with source code? Also you can just post the code here, no need to send files.

Best Regards,

Panagiotis


@PanagiotisCharalampous

daniel.agg
08 Mar 2019, 10:07

That's strange, the .cs files should have been in the corresponding subfolders.

Anyway, here's the bot:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.Internet)]
    public class MACDTestBot : Robot
    {
        #region indicator parameters


        [Parameter("Divergence Ledge", DefaultValue = 3, MinValue = 1, MaxValue = 10, Step = 1)]
        public int Divergence_Ledge { get; set; }

        [Parameter("Divergence Extremums", DefaultValue = false)]
        public bool Divergence_Extremums { get; set; }

        [Parameter("Divergence Min Length", DefaultValue = 6, MinValue = 4, MaxValue = 10, Step = 1)]
        public int Divergence_Min_Length { get; set; }

        [Parameter("Last Points", DefaultValue = 3, MinValue = 1, MaxValue = 10, Step = 1)]
        public int Last_Points { get; set; }

        [Parameter("MACD:  Short Cycle", DefaultValue = 12)]
        public int MACD_Short_Cycle { get; set; }

        [Parameter("MACD:  Long Cycle", DefaultValue = 26)]
        public int MACD_Long_Cycle { get; set; }

        [Parameter("MACD:  Signal Period", DefaultValue = 9)]
        public int MACD_Signal_Period { get; set; }

        [Parameter("MACD:  Reverse", DefaultValue = false)]
        public bool MACD_Reverse { get; set; }

        #endregion

        private MACDDivergence indicator;

        private int indicatorDataCount;

        protected override void OnStart()
        {
            indicator = Indicators.GetIndicator<MACDDivergence>(
                Divergence_Ledge,
                Divergence_Extremums,
                Divergence_Min_Length,
                Last_Points,
                MACD_Short_Cycle,
                MACD_Long_Cycle,
                MACD_Signal_Period,
                MACD_Reverse);

            indicatorDataCount = indicator.Data.Count();
        }

        protected override void OnTick()
        {
            if(indicatorDataCount != indicator.Data.Count())
            {
                // do something
            }
        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

 

And here's the indicator:

using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
//using System.Linq;
using System.Collections.Generic;


namespace cAlgo.Indicators
{
    [Indicator(TimeZone = TimeZones.UTC, IsOverlay = false, AutoRescale = true, ScalePrecision = 7, AccessRights = AccessRights.None)]
    public class MACDDivergence : Indicator
    {



        [Parameter("Divergence Ledge", DefaultValue = 3, MinValue = 1, MaxValue = 10, Step = 1)]
        public int Divergence_Ledge { get; set; }

        [Parameter("Divergence Extremums", DefaultValue = false)]
        public bool Divergence_Extremums { get; set; }

        [Parameter("Divergence Min Length", DefaultValue = 6, MinValue = 4, MaxValue = 10, Step = 1)]
        public int Divergence_Min_Length { get; set; }

        [Parameter("Last Points", DefaultValue = 3, MinValue = 1, MaxValue = 10, Step = 1)]
        public int Last_Points { get; set; }

        [Parameter("MACD:  Short Cycle", DefaultValue = 12)]
        public int MACD_Short_Cycle { get; set; }

        [Parameter("MACD:  Long Cycle", DefaultValue = 26)]
        public int MACD_Long_Cycle { get; set; }

        [Parameter("MACD:  Signal Period", DefaultValue = 9)]
        public int MACD_Signal_Period { get; set; }

        [Parameter("MACD:  Reverse", DefaultValue = false)]
        public bool MACD_Reverse { get; set; }

        [Output("Main", PlotType = PlotType.Histogram, Color = Colors.DeepSkyBlue)]
        public IndicatorDataSeries Result { get; set; }




        /// Indicator

        private MacdHistogram I_MACD;




        /// Properties

        string Chart_Object_Title = "MACD Divergence";

        private DivergenceType HIGH = DivergenceType.High;
        private DivergenceType LOW = DivergenceType.Low;

        private ExtremumActionType for_Update = ExtremumActionType.Update;
        private ExtremumActionType for_New = ExtremumActionType.New;


        /// Data to use in Bot

        private List<Label> High_Extremums = new List<Label>();
        private List<Label> Low_Extremums = new List<Label>();

        public List<Divergence> Data = new List<Divergence>();
        public List<TrendType> Trend = new List<TrendType>();




        /// Models

        public struct Divergence
        {
            public DivergenceType T;
            public Label A;
            public Label B;

            public Divergence(DivergenceType _Type = DivergenceType.None, Label Label_A = new Label(), Label Label_B = new Label())
            {
                T = _Type;
                A = Label_A;
                B = Label_B;
            }

            public string Text
            {
                get { return string.Format("- A -  {0}      - B -  {1}", A.Text, B.Text); }
            }

            public Colors Color
            {
                get
                {
                    switch (T)
                    {
                        case DivergenceType.High:
                            return Colors.SpringGreen;
                            break;
                        case DivergenceType.Low:
                            return Colors.DeepPink;
                            break;
                        default:
                            return Colors.Yellow;
                            break;
                    }
                }
            }
        }

        public struct Label
        {
            public Point MACD;
            public Point MS;

            public Label(Point M1 = new Point(), Point M2 = new Point())
            {
                MACD = M1;
                MS = M2;
            }

            public string Text
            {
                get { return string.Format("MACD = {0}    MS = {1}", MACD.Text, MS.Text); }
            }
        }

        public struct Point
        {
            public int Index;
            public double Value;

            public Point(int I = 0, double V = 0)
            {
                Index = I;
                Value = V;
            }

            public string Text
            {
                get { return string.Format("{0} ({1})", Value.ToString("N6"), Index); }
            }
        }

        public enum ExtremumActionType
        {
            Update,
            New
        }

        public enum DivergenceType
        {
            High,
            Low,
            None
        }

        public enum TrendType
        {
            Up,
            Down,
            None
        }





        /// TODO: Init

        protected override void Initialize()
        {
            I_MACD = Indicators.MacdHistogram(MACD_Short_Cycle, MACD_Long_Cycle, MACD_Signal_Period);
            Print("MACD Divergence Calculator is initialized.     Results = {0}     Data = {1}     Data_Trend = {2}", Result.Count, Data.Count, Trend.Count);
        }




        /// TODO: Indicator

        public override void Calculate(int index)
        {
            /// MACD Calc

            Result[index] = MACD_Reverse ? I_MACD.Histogram[index] - I_MACD.Signal[index] : I_MACD.Signal[index] - I_MACD.Histogram[index];





            /// MACD Divergence

            if (index <= Divergence_Ledge)
                return;



            /// TODO: High Divergence

            Point MACD_Max = Max_MACD(From: index - 1, For_Last_Bars: Divergence_Ledge);
            Point MS_Max = Max_MS(From: index - 1, For_Last_Bars: Divergence_Ledge);

            Label Max = new Label(MACD_Max, MS_Max);


            if (High_Extremums.Count == 0)
            {
                if (Is_Max(L: Max, At: index))
                    Update_Data(Stage: "1 Step: FIRST", _Type: HIGH, New_Extremum: Max, At: index, Action: for_New);

            }
            else
            {
                Label Last = High_Extremums[High_Extremums.Count - 1];

                if (Math.Max(Max.MACD.Index, Max.MS.Index) - Last.MACD.Index <= Divergence_Min_Length)
                {
                    //if (Last.MACD.Value < MACD(index) && Last.MACD.Index == index - 1 && Max.MACD.Index - Last.MACD.Index <= Divergence_Ledge)
                    //{
                    //    Max.MACD.Value = MACD(index);
                    //    Max.MACD.Index = index;
                    //    Update_Data(Stage: "3 Step: update NOW", _Type: HIGH, New_Extremum: Max, At: index, Action: for_Update);
                    //}

                    if (Allow_To_Update_High(L: Last, New: Max, At: index))
                        Update_Data(Stage: "3 Step: update LAST", _Type: HIGH, New_Extremum: Max, At: index, Action: for_Update);
                }
                else if (Is_Next_High_Wave(A: Last, B: Max, At: index))
                    Update_Data(Stage: "4 Step: NEW", _Type: HIGH, New_Extremum: Max, At: index, Action: for_New);

            }






            /// TODO: Low Divergence

            Point MACD_Min = Min_MACD(From: index - 1, For_Last_Bars: Divergence_Ledge);
            Point MS_Min = Min_MS(From: index - 1, For_Last_Bars: Divergence_Ledge);

            Label Min = new Label(MACD_Min, MS_Min);

            if (Low_Extremums.Count == 0)
            {
                if (Is_Min(L: Min, At: index))
                    Update_Data(Stage: "1 Step: FIRST", _Type: LOW, New_Extremum: Min, At: index, Action: for_New);
            }
            else
            {
                Label Last = Low_Extremums[Low_Extremums.Count - 1];

                if (Math.Max(Min.MACD.Index, Min.MS.Index) - Last.MACD.Index <= Divergence_Min_Length)
                {
                    //if (Last.MACD.Value < MACD(index) && Last.MACD.Index == index - 1 && Min.MACD.Index - Last.MACD.Index <= Divergence_Ledge)
                    //{
                    //    Min.MACD.Value = MACD(index);
                    //    Min.MACD.Index = index;
                    //    Update_Data(Stage: "3 Step: update NOW", _Type: LOW, New_Extremum: Min, At: index, Action: for_Update);
                    //}

                    if (Allow_To_Update_Low(L: Last, New: Min, At: index))
                        Update_Data(Stage: "3 Step: update LAST", _Type: LOW, New_Extremum: Min, At: index, Action: for_Update);
                }
                else if (Is_Next_Low_Wave(A: Last, B: Min, At: index))
                    Update_Data(Stage: "4 Step: NEW", _Type: LOW, New_Extremum: Min, At: index, Action: for_New);

            }





            /// Update Trend List

            if (Trend.Count == 0)
                while (Trend.Count < index)
                    Trend.Add(TrendType.None);

            if (Data.Count > 0)
            {
                Divergence D = Data[Data.Count - 1];

                bool T_High = D.T == DivergenceType.High;
                bool T_Low = D.T == DivergenceType.Low;

                TrendType T = T_High ? TrendType.Down : (T_Low ? TrendType.Up : TrendType.None);

                if (Trend.Count < index)
                    Trend.Add(T);
                else if (Trend.Count - 1 == index)
                    Trend[index] = T;
            }
            else
            {
                TrendType T = TrendType.None;

                if (Trend.Count < index)
                    Trend.Add(T);
                else if (Trend.Count - 1 == index)
                    Trend[index] = T;
            }

        }





        /// Methods

        /// Info

        private void Info(string Stage, Label Last, Label Extremum, int At, DivergenceType _Type)
        {
            //if (IsBacktesting)
            //    return;

            Print("{0} - {1} - {2} - {3} - {4} -  Last  {5}  -  Extremum  {6}", At, MarketSeries.OpenTime[At].Date.ToShortDateString(), Data.Count, _Type.ToString(), Stage, Last.Text, Extremum.Text);
        }

        /// Update list Data_Divergence

        private void Update_Data(string Stage, DivergenceType _Type, Label New_Extremum, int At, ExtremumActionType Action)
        {
            if (_Type == HIGH ? High_Extremums.Count > 0 : Low_Extremums.Count > 0)
            {
                Label Previous_Extremum = _Type == HIGH ? High_Extremums[High_Extremums.Count - 1] : Low_Extremums[Low_Extremums.Count - 1];
                Info(Stage: Stage, Last: Previous_Extremum, Extremum: New_Extremum, At: At, _Type: _Type);

                if (Action == for_New)
                    if (_Type == HIGH)
                        High_Extremums.Add(New_Extremum);
                    else if (_Type == LOW)
                        Low_Extremums.Add(New_Extremum);

                Label Last_Extremum = _Type == HIGH ? High_Extremums[High_Extremums.Count - 1] : Low_Extremums[Low_Extremums.Count - 1];

                int N_Extremums = _Type == HIGH ? High_Extremums.Count - 1 : Low_Extremums.Count - 1;

                for (int Index = Math.Max(N_Extremums - Last_Points, 0); Index < N_Extremums; Index++)
                {
                    Label Current_Extremum = _Type == HIGH ? High_Extremums[Index] : Low_Extremums[Index];

                    Divergence Last = new Divergence(_Type: _Type, Label_A: Current_Extremum, Label_B: Last_Extremum);
                    Divergence New = new Divergence(_Type: _Type, Label_A: Current_Extremum, Label_B: New_Extremum);

                    if (No_Obstacles(D: New) && Is_Divergence(D: New))
                    {
                        if (Data.Contains(Last))
                        {
                            int D_Index = Data.IndexOf(Last);
                            Data[D_Index] = New;
                            Info(Stage: "7 Step:  update DATA", Last: Current_Extremum, Extremum: New_Extremum, At: At, _Type: _Type);
                            Draw(D: New, Prefix: D_Index.ToString());

                        }
                        else if (!Data.Exists(D => D.B.MACD.Index == New.B.MACD.Index))
                        {
                            Data.Add(New);
                            Info(Stage: "7 Step:  new DATA", Last: Current_Extremum, Extremum: New_Extremum, At: At, _Type: _Type);
                            Draw(D: New, Prefix: (Data.Count - 1).ToString());
                        }
                    }
                    else if (Data.Contains(Last))
                    {
                        Info(Stage: "7 Step:  remove DATA", Last: Current_Extremum, Extremum: New_Extremum, At: At, _Type: _Type);
                        Remove(D: Last, Prefix: Data.IndexOf(Last).ToString());
                        Data.Remove(Last);
                    }
                }
            }
            else
            {
                if (Action == for_New)
                    if (_Type == HIGH)
                        High_Extremums.Add(New_Extremum);
                    else if (_Type == LOW)
                        Low_Extremums.Add(New_Extremum);
            }

            if (Action == for_Update)
                if (_Type == HIGH)
                    High_Extremums[High_Extremums.Count - 1] = New_Extremum;
                else if (_Type == LOW)
                    Low_Extremums[Low_Extremums.Count - 1] = New_Extremum;
        }


        /// Draw and remove chart objects

        private void Draw(Divergence D, string Prefix)
        {
            //if (IsBacktesting)
            //    return;

            string Name = Prefix + Chart_Object_Title + D.T.ToString() + D.A.MACD.Index.ToString();
            int Index_1 = D.A.MACD.Index;
            int Index_2 = D.B.MACD.Index;
            double Value_1 = D.A.MACD.Value;
            double Value_2 = D.B.MACD.Value;
            Colors Color = D.Color;

            ChartObjects.DrawLine(Name, Index_1, Value_1, Index_2, Value_2, Color);
            ChartObjects.DrawText(Name + "A", "•", Index_1, Value_1, VerticalAlignment.Center, HorizontalAlignment.Center, Color);
            ChartObjects.DrawText(Name + "B", "•", Index_2, Value_2, VerticalAlignment.Center, HorizontalAlignment.Center, Color);

            Info(Stage: "Draw Divergence:", Last: D.A, Extremum: D.B, At: D.A.MACD.Index, _Type: D.T);
        }

        private void Remove(Divergence D, string Prefix)
        {
            //if (IsBacktesting)
            //    return;

            string Name = Prefix + Chart_Object_Title + D.T.ToString() + D.A.MACD.Index.ToString();

            ChartObjects.RemoveObject(Name);
            ChartObjects.RemoveObject(Name + "A");
            ChartObjects.RemoveObject(Name + "B");
        }





        /// Helpers

        private double MACD(int Index)
        {
            return Result[Index];
        }

        private bool Is_Divergence(Divergence D)
        {
            bool T1 = D.A.MACD.Value >= D.B.MACD.Value && D.A.MS.Value < D.B.MS.Value;
            bool T2 = D.A.MACD.Value <= D.B.MACD.Value && D.A.MS.Value > D.B.MS.Value;

            bool T_P = D.T == HIGH ? D.A.MACD.Value > 0 : D.A.MACD.Value < 0;

            return (T1 || T2) && T_P;
        }



        /// Is Max

        private bool Is_Max(Label L, int At)
        {
            return (MACD_Is_Max(P: L.MACD, At: At) && MS_Is_Max(P: L.MS, At: At));
        }

        private bool MACD_Is_Max(Point P, int At)
        {
            return P.Value > 0 && P.Value > MACD(At) && P.Value > MACD(P.Index - 1);
        }

        private bool MS_Is_Max(Point P, int At)
        {
            return P.Value > MS_High(At) && P.Value > MS_High(P.Index - 1);
        }



        /// Is Min

        private bool Is_Min(Label L, int At)
        {
            return (MACD_Is_Min(P: L.MACD, At: At) && MS_Is_Min(P: L.MS, At: At));
        }

        private bool MACD_Is_Min(Point P, int At)
        {
            return P.Value < 0 && P.Value < MACD(At) && P.Value < MACD(P.Index - 1);
        }

        private bool MS_Is_Min(Point P, int At)
        {
            return P.Value < MS_High(At) && P.Value < MS_High(P.Index - 1);
        }




        /// Allow to update

        private bool Allow_To_Update_High(Label L, Label New, int At)
        {
            if (New.MACD.Index == At)
                return false;

            if ((L.MACD.Value < New.MACD.Value && MACD_Is_Max(P: New.MACD, At: At)) || (L.MS.Value < New.MS.Value && MS_Is_Max(P: New.MS, At: At)))
                return true;

            return false;
        }

        private bool Allow_To_Update_Low(Label L, Label New, int At)
        {
            if (New.MACD.Index == At)
                return false;

            if ((L.MACD.Value > New.MACD.Value && MACD_Is_Min(P: New.MACD, At: At)) || (L.MS.Value > New.MS.Value && MS_Is_Min(P: New.MS, At: At)))
                return true;

            return false;
        }



        /// Next Wave

        private bool Is_Next_High_Wave(Label A, Label B, int At)
        {
            bool Was_Lower = MACD_Was_Lower(From: A.MACD.Index, To: B.MACD.Index);

            bool B_MACD_Max = MACD_Is_Max(P: B.MACD, At: At);
            bool B_MS_Max = MS_Is_Max(P: B.MS, At: At);

            bool T1 = A.MACD.Value > 0 && B.MACD.Value > 0 && Was_Lower && B_MACD_Max && B_MS_Max;
            bool T2 = A.MACD.Value < 0 && B.MACD.Value > 0 && Was_Lower && B_MACD_Max && B_MS_Max;
            bool T3 = A.MACD.Value > 0 && B.MACD.Value < 0 && A.MS.Value < B.MS.Value && B_MS_Max && MACD(Index: B.MS.Index) < 0;

            return (T1 || T2 || T3);
        }

        private bool Is_Next_Low_Wave(Label A, Label B, int At)
        {
            bool Was_Higher = MACD_Was_Higher(From: A.MACD.Index, To: B.MACD.Index);

            bool B_MACD_Min = MACD_Is_Min(P: B.MACD, At: At);
            bool B_MS_Min = MS_Is_Min(P: B.MS, At: At);

            bool T1 = A.MACD.Value < 0 && B.MACD.Value < 0 && Was_Higher && B_MACD_Min && B_MS_Min;
            bool T2 = A.MACD.Value > 0 && B.MACD.Value < 0 && Was_Higher && B_MACD_Min && B_MS_Min;
            bool T3 = A.MACD.Value < 0 && B.MACD.Value > 0 && A.MS.Value > B.MS.Value && B_MS_Min && MACD(Index: B.MS.Index) > 0;

            return (T1 || T2 || T3);
        }



        /// Нет препятсвий

        private bool No_Obstacles(Divergence D)
        {
            bool T_MACD = D.T == HIGH ? MACD_Was_Not_Higher(D: D) : MACD_Was_Not_Lower(D: D);
            bool T_MS = D.T == HIGH ? MS_Was_Not_Higher(D: D) : MS_Was_Not_Lower(D: D);


            //Info(Stage: string.Format("No O:  MACD = {0}  MS = {1}", T_MACD, T_MS), D: D, At: D.B.MACD.Index);

            return (T_MACD && T_MS);
        }




        /// MS Not higher or lower than

        private bool MACD_Was_Not_Higher(Divergence D)
        {
            return MACD_Was_Not_Higher(From: D.A.MACD.Index, To: D.B.MACD.Index, Value: Math.Max(D.A.MACD.Value, D.B.MACD.Value));
        }

        private bool MACD_Was_Not_Lower(Divergence D)
        {
            return MACD_Was_Not_Lower(From: D.A.MACD.Index, To: D.B.MACD.Index, Value: Math.Min(D.A.MACD.Value, D.B.MACD.Value));
        }

        private bool MACD_Was_Not_Higher(int From, int To, double Value)
        {
            if (From + 1 > To)
                return false;

            for (int Index = From + 1; Index < To; Index++)
                if (MACD(Index) > Value)
                    return false;

            return true;
        }

        private bool MACD_Was_Not_Lower(int From, int To, double Value)
        {
            if (From + 1 > To)
                return false;

            for (int Index = From + 1; Index < To; Index++)
                if (MACD(Index) < Value)
                    return false;

            return true;
        }



        /// MACD: was lower or higher 2 points

        private bool MACD_Was_Lower_Zero(int From, int To)
        {
            if (From > To)
                return false;

            for (int Index = From + 1; Index < To; Index++)
                if (MACD(Index) < 0)
                    return true;

            return false;
        }

        private bool MACD_Was_Lower(int From, int To)
        {
            if (From + 1 > To)
                return false;

            double From_Value = MACD(From);
            double To_Value = MACD(To);

            for (int Index = From + 1; Index < To; Index++)
                if (MACD(Index) < From_Value && MACD(Index) < To_Value)
                    return true;

            return false;
        }




        /// MACD: was higher or lower 0

        private bool MACD_Was_Higher_Zero(int From, int To)
        {
            if (From > To)
                return false;

            for (int Index = From + 1; Index < To; Index++)
                if (MACD(Index) > 0)
                    return true;

            return false;
        }

        private bool MACD_Was_Higher(int From, int To)
        {
            if (From + 1 > To)
                return false;

            double From_Value = MACD(From);
            double To_Value = MACD(To);

            for (int Index = From + 1; Index < To; Index++)
                if (MACD(Index) > From_Value && MACD(Index) > To_Value)
                    return true;

            return false;
        }



        // MS: high & low

        private double MS_High(int Index)
        {
            return Divergence_Extremums ? MarketSeries.High[Index] : MarketSeries.Close[Index];
        }

        private double MS_Low(int Index)
        {
            return Divergence_Extremums ? MarketSeries.Low[Index] : MarketSeries.Close[Index];
        }




        /// MS Not higher or lower than

        private bool MS_Was_Not_Higher(Divergence D)
        {
            return MS_Was_Not_Higher(From: D.A.MS.Index, To: D.B.MS.Index, Value: Math.Max(D.A.MS.Value, D.B.MS.Value));
        }

        private bool MS_Was_Not_Lower(Divergence D)
        {
            return MS_Was_Not_Lower(From: D.A.MS.Index, To: D.B.MS.Index, Value: Math.Min(D.A.MS.Value, D.B.MS.Value));
        }

        private bool MS_Was_Not_Higher(int From, int To, double Value)
        {
            if (From + 1 > To)
                return false;

            for (int Index = From + 1; Index < To; Index++)
                if (MS_High(Index) > Value)
                    return false;

            return true;
        }

        private bool MS_Was_Not_Lower(int From, int To, double Value)
        {
            if (From + 1 > To)
                return false;

            for (int Index = From + 1; Index < To; Index++)
                if (MS_Low(Index) < Value)
                    return false;

            return true;
        }




        /// MS: max & min points 

        private Point Max_MS(int From, int For_Last_Bars)
        {
            int Index = From;
            double Value = MS_High(Index);

            for (int Bar = 1; Bar <= For_Last_Bars; Bar++)
            {
                int New_Index = From - Bar;
                double New_Value = MS_High(New_Index);

                if (New_Value > Value)
                {
                    Value = New_Value;
                    Index = New_Index;
                }
            }

            return new Point(Index, Value);
        }

        private Point Min_MS(int From, int For_Last_Bars)
        {
            int Index = From;
            double Value = MS_Low(Index);

            for (int Bar = 1; Bar <= For_Last_Bars; Bar++)
            {
                int New_Index = From - Bar;
                double New_Value = MS_Low(New_Index);

                if (New_Value < Value)
                {
                    Value = New_Value;
                    Index = New_Index;
                }
            }

            return new Point(Index, Value);
        }




        /// MACD: max & min points

        private Point Max_MACD(int From, int For_Last_Bars)
        {
            int Index = From;
            double Value = MACD(Index);

            for (int Bar = 1; Bar <= For_Last_Bars; Bar++)
            {
                int New_Index = From - Bar;
                double New_Value = MACD(New_Index);

                if (New_Value < 0)
                    return new Point(Index, Value);

                if (New_Value > Value)
                {
                    Value = New_Value;
                    Index = New_Index;
                }
            }

            return new Point(Index, Value);
        }

        private Point Min_MACD(int From, int For_Last_Bars)
        {
            int Index = From;
            double Value = MACD(Index);

            for (int Bar = 1; Bar <= For_Last_Bars; Bar++)
            {
                int New_Index = From - Bar;
                double New_Value = MACD(New_Index);

                if (New_Value > 0)
                    return new Point(Index, Value);

                if (New_Value < Value)
                {
                    Value = New_Value;
                    Index = New_Index;
                }
            }
            return new Point(Index, Value);
        }
    }
}

 


@daniel.agg

gyalusdavid
11 Mar 2019, 10:58

RE:

Panagiotis Charalampous said:

Hi daniel.agg,

Thanks for posting in our forum. I downloaded the cBot but there is no source code. Can you please send it with source code? Also you can just post the code here, no need to send files.

Best Regards,

Panagiotis

Dear Panagiotis,

I got almost the same problem, which is quite important, could you please investigate as soon as possible?

Thank you very much, Panagiotis!

Best Regards,
 David
 


@gyalusdavid

PanagiotisCharalampous
12 Mar 2019, 12:49

Hi guys,

I tried to reproduce the problem but could not. If you can isolate the issue into a smaller indicator with more specific reproduction steps I can take another look.

Best Regards,

Panagiotis


@PanagiotisCharalampous

daniel.agg
26 Mar 2019, 18:09

Hi, the problem is solved (using a different indicator). Can you please delete this post?

Thanks in advance,
Dan


@daniel.agg