Issues drawing a ChartIcon Arrow in an indicator

Created at 20 Jul 2022, 20:12
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!
AM

amirus.stark

Joined 01.05.2020

Issues drawing a ChartIcon Arrow in an indicator
20 Jul 2022, 20:12


Basically I'de like to draw an arrow if a bool variable is true

I tried this 

 if (sl)
            {
                Chart.DrawIcon(Bars.OpenTimes.LastValue.ToString(), ChartIconType.DownArrow, index, Bars.HighPrices.LastValue, Color.Blue);
               
            }

 

But nothing appears when I activate my indicator (besides the line it displays


cTrader
@amirus.stark
Replies

PanagiotisCharalampous
21 Jul 2022, 10:59

Hi amirus.stark,

Please share the complete indicator code so that we can check.

Best Regards,

Panagiotis 

Join us on Telegram and Facebook


@PanagiotisCharalampous

amirus.stark
21 Jul 2022, 14:03

RE:

PanagiotisCharalampous said:

Hi amirus.stark,

Please share the complete indicator code so that we can check.

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

 

Here's the algo 

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class RetracementBar : Indicator
    {
        [Parameter("Inventory Retracement Percentage %", DefaultValue = 45)]
        public int z { get; set; }

        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }

       

      

        public override void Calculate(int index)
        {
            // Candle Range
            var a = Math.Abs(Bars.HighPrices.Last(0) - Bars.LowPrices.Last(0));
            // Candle Body
            var b = Math.Abs(Bars.ClosePrices.Last(0) - Bars.OpenPrices.Last(0));
            // Percent to Decimal
            var c = z / 100;

            var rv = def_rv(a, b, c);

            var x = Bars.LowPrices.LastValue + (c * a);
            var y = Bars.HighPrices.LastValue - (c * a);

            var sl = def_sl(rv, y);
            var ss = def_ss(rv, x);


            
            var li = def_li(sl, y, ss, x);
            Result[index] = li;

            if (sl)
            {
                Chart.DrawIcon(Bars.OpenTimes.LastValue.ToString(), ChartIconType.DownArrow, Bars.OpenTimes.LastValue, Bars.HighPrices.LastValue, Color.Blue);
                Print("sl");

            }
            if (ss)
            {
                Chart.DrawIcon(Bars.OpenTimes.LastValue.ToString(), ChartIconType.UpArrow, Bars.OpenTimes.LastValue, Bars.LowPrices.LastValue, Color.Red);
                Print("ss");
            }


            
        }

      


      
        public bool def_rv(double a, double b, double c)
        {
            if (b < c * a)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public bool def_sl(bool rv, double y)
        {
            if (rv && Bars.HighPrices.LastValue > y && Bars.ClosePrices.LastValue < y && Bars.OpenPrices.LastValue < y)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool def_ss(bool rv, double x)
        {
            if (rv && Bars.LowPrices.LastValue < x && Bars.ClosePrices.LastValue > x && Bars.OpenPrices.LastValue > x)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public double def_li(bool sl, double y, bool ss, double x)
        {
            if (sl)
            {
                return y;
            }
            if (ss && !sl)
            {
                return x;
            }
            else
            {
                return ((x + y) / 2);
            }
        }

    }
}

It's an adaptation of a tradingview algo, the main line works fine but apparently the bools sl and ss are always false for some reason


@amirus.stark

paolo.panicali
28 Jul 2022, 13:42 ( Updated at: 21 Dec 2023, 09:22 )

Rv is always false and Y is equal to HighPrices

If you debug the old fashioned  way adding this:

....................

  public bool def_sl(bool rv, double y)
        {
            if (rv)
            {
                Print("rv " + rv + "  Y value passed: " + y + "   high: " + Bars.HighPrices.LastValue + "  open: " + Bars.OpenPrices.LastValue + "   close: " + Bars.ClosePrices.LastValue);
            }

.................

you realize that rv is never true.

While if you add a not condition to rv:

....................

  public bool def_sl(bool rv, double y)
        {
            if (!rv)
            {
                Print("rv " + rv + "  Y value passed: " + y + "   high: " + Bars.HighPrices.LastValue + "  open: " + Bars.OpenPrices.LastValue + "   close: " + Bars.ClosePrices.LastValue);
            }

.................

and you realize that Y is always equal to HighPrices so that the second condition is never True neither

if fact if you manually subtract a minimal value to Y and removing rv true condition, adding the following code, you get an arrow on every bar.

 public bool def_sl(bool rv, double y)
        {
            if (!rv)
            {
                Print("rv " + rv + "  Y value passed: " + y + "   high: " + Bars.HighPrices.LastValue + "  open: " + Bars.OpenPrices.LastValue + "   close: " + Bars.ClosePrices.LastValue);
            }

            y = y - 1E-05;
            if (Bars.HighPrices.LastValue > y && Bars.ClosePrices.LastValue < y && Bars.OpenPrices.LastValue < y)
            {
                return true;
            }
            else...

So the problem is the rv condition and the y value, I do not understand what is the idea of the indicator so that cannot provide you a solution.

A fatherly advice, do not use alphabet letters to name variables.

 


@paolo.panicali

paolo.panicali
28 Jul 2022, 14:07

I managed to understand what you wanted to achieve, here is the code

Hi, several errors. Z was set as an integer while it is a double, when you divide it by 100 it goes to 0 if set as integer, while as double you get a real value.

Bar lastvalue is literally the last value, for an indicator you have to use bars.closeprices[index] for the current bar over time.

There are some LastValue left over you can correct them, the indicator works now.

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class RetracementBar : Indicator
    {
        [Parameter("Inventory Retracement Percentage %", DefaultValue = 45)]
        public double z { get; set; }

        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }


        public override void Calculate(int index)
        {
            // Candle Range
            double a = Math.Abs(Bars.HighPrices[index] - Bars.LowPrices[index]);
            // Candle Body
            double b = Math.Abs(Bars.ClosePrices[index] - Bars.OpenPrices[index]);
            // Percent to Decimal
            double c = z / 100;

            var rv = def_rv(a, b, c);

            var x = Bars.LowPrices[index] + (c * a);
            var y = Bars.HighPrices[index] - (c * a);

            var sl = def_sl(index, rv, y);
            var ss = def_ss(rv, x);



            var li = def_li(sl, y, ss, x);
            Result[index] = li;

            if (sl)
            {
                Chart.DrawIcon(Bars.OpenTimes.LastValue.ToString(), ChartIconType.DownArrow, Bars.OpenTimes.LastValue, Bars.HighPrices.LastValue, Color.Blue);
                Print("sl");

            }
            if (ss)
            {
                Chart.DrawIcon(Bars.OpenTimes.LastValue.ToString(), ChartIconType.UpArrow, Bars.OpenTimes.LastValue, Bars.LowPrices.LastValue, Color.Red);
                Print("ss");
            }



        }





        public bool def_rv(double a, double b, double c)
        {
            // Print(a + " " + b + "   " + c);
            if (b < c * a)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public bool def_sl(int index, bool rv, double y)
        {
            if (rv)
            {
                //Print("rv true");
                // Print("rv " + rv + "  Y value passed: " + y + "   high: " + Bars.HighPrices[index] + "  open: " + Bars.OpenPrices[index] + "   close: " + Bars.ClosePrices[index]);
            }

            //y = y - 1E-05;
            if (rv && Bars.HighPrices[index] > y && Bars.ClosePrices[index] < y && Bars.OpenPrices[index] < y)
            {
                //Print("rv " + rv + "  Y value passed: " + y + "   high: " + Bars.HighPrices[index] + "  open: " + Bars.OpenPrices[index] + "   close: " + Bars.ClosePrices[index]);

                return true;
            }
            else
            {
                //Print("rv " + rv + "  Y value passed: " + y + "   high: " + Bars.HighPrices[index] + "  open: " + Bars.OpenPrices[index] + "   close: " + Bars.ClosePrices[index]);

                return false;
            }
        }

        public bool def_ss(bool rv, double x)
        {
            if (rv && Bars.LowPrices.LastValue < x && Bars.ClosePrices.LastValue > x && Bars.OpenPrices.LastValue > x)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public double def_li(bool sl, double y, bool ss, double x)
        {
            if (sl)
            {
                return y;
            }
            if (ss && !sl)
            {
                return x;
            }
            else
            {
                return ((x + y) / 2);
            }
        }

    }
}

 

REMEMBER TO REPLACE LASTVALUE WITH [INDEX] OTHERWISE YOU GET THE VALUES OF THE LAST BAR ALWAYS

Bye.


@paolo.panicali

amirus.stark
28 Jul 2022, 14:37 ( Updated at: 21 Dec 2023, 09:22 )

RE: I managed to understand what you wanted to achieve, here is the code

paolo.panicali said:

Hi, several errors. Z was set as an integer while it is a double, when you divide it by 100 it goes to 0 if set as integer, while as double you get a real value.

Bar lastvalue is literally the last value, for an indicator you have to use bars.closeprices[index] for the current bar over time.

There are some LastValue left over you can correct them, the indicator works now.

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class RetracementBar : Indicator
    {
        [Parameter("Inventory Retracement Percentage %", DefaultValue = 45)]
        public double z { get; set; }

        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }


        public override void Calculate(int index)
        {
            // Candle Range
            double a = Math.Abs(Bars.HighPrices[index] - Bars.LowPrices[index]);
            // Candle Body
            double b = Math.Abs(Bars.ClosePrices[index] - Bars.OpenPrices[index]);
            // Percent to Decimal
            double c = z / 100;

            var rv = def_rv(a, b, c);

            var x = Bars.LowPrices[index] + (c * a);
            var y = Bars.HighPrices[index] - (c * a);

            var sl = def_sl(index, rv, y);
            var ss = def_ss(rv, x);



            var li = def_li(sl, y, ss, x);
            Result[index] = li;

            if (sl)
            {
                Chart.DrawIcon(Bars.OpenTimes.LastValue.ToString(), ChartIconType.DownArrow, Bars.OpenTimes.LastValue, Bars.HighPrices.LastValue, Color.Blue);
                Print("sl");

            }
            if (ss)
            {
                Chart.DrawIcon(Bars.OpenTimes.LastValue.ToString(), ChartIconType.UpArrow, Bars.OpenTimes.LastValue, Bars.LowPrices.LastValue, Color.Red);
                Print("ss");
            }



        }





        public bool def_rv(double a, double b, double c)
        {
            // Print(a + " " + b + "   " + c);
            if (b < c * a)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public bool def_sl(int index, bool rv, double y)
        {
            if (rv)
            {
                //Print("rv true");
                // Print("rv " + rv + "  Y value passed: " + y + "   high: " + Bars.HighPrices[index] + "  open: " + Bars.OpenPrices[index] + "   close: " + Bars.ClosePrices[index]);
            }

            //y = y - 1E-05;
            if (rv && Bars.HighPrices[index] > y && Bars.ClosePrices[index] < y && Bars.OpenPrices[index] < y)
            {
                //Print("rv " + rv + "  Y value passed: " + y + "   high: " + Bars.HighPrices[index] + "  open: " + Bars.OpenPrices[index] + "   close: " + Bars.ClosePrices[index]);

                return true;
            }
            else
            {
                //Print("rv " + rv + "  Y value passed: " + y + "   high: " + Bars.HighPrices[index] + "  open: " + Bars.OpenPrices[index] + "   close: " + Bars.ClosePrices[index]);

                return false;
            }
        }

        public bool def_ss(bool rv, double x)
        {
            if (rv && Bars.LowPrices.LastValue < x && Bars.ClosePrices.LastValue > x && Bars.OpenPrices.LastValue > x)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public double def_li(bool sl, double y, bool ss, double x)
        {
            if (sl)
            {
                return y;
            }
            if (ss && !sl)
            {
                return x;
            }
            else
            {
                return ((x + y) / 2);
            }
        }

    }
}

 

REMEMBER TO REPLACE LASTVALUE WITH [INDEX] OTHERWISE YOU GET THE VALUES OF THE LAST BAR ALWAYS

Bye.

Thanks a lot for the precious insight man !


@amirus.stark