Custom indicator works on inactive charts but fails on active ones

Created at 03 Jan 2021, 15:59
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!
hrivven's avatar

hrivven

Joined 29.12.2020

Custom indicator works on inactive charts but fails on active ones
03 Jan 2021, 15:59


I've been working on this for a few days and I can't seem to understand which part of my code is wrong, also new to ctrader and c#.

currently, the GBPUSD chart is inactive and so the indicator is working -

But on the BTCUSD chart which is currently active, it stops working - 

Here is the code -

 

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, AutoRescale = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Renko2 : Indicator
    {

        [Parameter("Number of Pips", DefaultValue = 10)]
        public int Number_Of_Pips { get; set; }

        [Output("Close Price", LineColor = "Red", Thickness = 5, PlotType = PlotType.Points)]
        public IndicatorDataSeries Latest_Close { get; set; }

        [Output("Open", LineColor = "Green", Thickness = 5, PlotType = PlotType.Line)]
        public IndicatorDataSeries Bricks_Open { get; set; }

        [Output("Close", LineColor = "Red", Thickness = 5, PlotType = PlotType.Line)]
        public IndicatorDataSeries Bricks_Close { get; set; }


        public bool first_brick_added;
        public bool brick_added;

        public int prev_index;

        public double first_brick_open;
        public double previous_brick_open;
        public double previous_brick_close;
        public double closed_candle_price;
        public double pips_digits;
        public double pips_close;


        public class Renko_Brick
        {
            public double Brick_Open { get; set; }
            public double Brick_Close { get; set; }
        }

        public List<Renko_Brick> Bricks = new List<Renko_Brick>();




        public void first_brick()
        {

            if (closed_candle_price >= (first_brick_open + pips_digits))
            {
                // ADD FIRST BULL BRICK
                Bricks.Add(new Renko_Brick 
                {
                    Brick_Open = first_brick_open,
                    Brick_Close = first_brick_open + pips_digits

                });

                first_brick_added = true;
                
            }


            if (closed_candle_price <= (first_brick_open - pips_digits))
            {
                // ADD NEW BEAR BRICK
                Bricks.Add(new Renko_Brick 
                {
                    Brick_Open = first_brick_open,
                    Brick_Close = first_brick_open - pips_digits

                });

                first_brick_added = true;
                
            }


            if (!(closed_candle_price >= (first_brick_open + pips_digits)) && !(closed_candle_price <= (first_brick_open - pips_digits)))
            {
                first_brick_added = false;
            }

        }




        public void add_a_brick()
        {

            if (closed_candle_price >= previous_brick_close + pips_digits)
            {
                // ADD BULL BRICK
                Bricks.Add(new Renko_Brick 
                {
                    Brick_Open = previous_brick_close,
                    Brick_Close = previous_brick_close + pips_digits
                });
                return;
            }


            if (closed_candle_price <= previous_brick_close - pips_digits)
            {
                // ADD BEAR BRICK
                Bricks.Add(new Renko_Brick 
                {
                    Brick_Open = previous_brick_close,
                    Brick_Close = previous_brick_close - pips_digits
                });
                return;
            }


            if (!(closed_candle_price >= (previous_brick_close + pips_digits)) && !(closed_candle_price <= (previous_brick_close - pips_digits)))
            {
                Bricks.Add(new Renko_Brick 
                {
                    Brick_Open = previous_brick_open,
                    Brick_Close = previous_brick_close
                });
                return;
            }

        }



        private void OnBarClosed(int index)
        {
            closed_candle_price = Bars.ClosePrices[index];
            Latest_Close[index] = closed_candle_price;


            if (!first_brick_added)
            {
                Print("index {0}, prev_index {1}", index + 1, index);
                first_brick();
            }
            else if (first_brick_added && Bricks.Count > 0)
            {
                previous_brick_open = Bricks[Bricks.Count - 1].Brick_Open;
                previous_brick_close = Bricks[Bricks.Count - 1].Brick_Close;

                add_a_brick();

                Bricks_Open[index] = previous_brick_open;
                Bricks_Close[index] = previous_brick_close;

            }
        }

        private int lastIndex = 0;


        protected override void Initialize()
        {
            pips_digits = Number_Of_Pips * Symbol.PipSize;
            first_brick_added = false;
            first_brick_open = Bars.OpenPrices[0];

        }


        public override void Calculate(int index)
        {

            if (index > lastIndex)
            {
                OnBarClosed(lastIndex);
                lastIndex = index;
            }




        }
    }

}

After the historical bars , I want the Calculate() method to be run on every closed bar to check if the closing price is higher than the previous brick close by the number of pips (add a new higher brick), lower than the previous brick close by the number of pips (add a new lower brick) or if the closing price does not meet the minimum pip level add a new brick on the same level as the previous brick.

I hope this makes sense

Kind Regards


@hrivven