Custom Indicator Print() not showing in chart/trade log + data not available in CBot

Created at 20 Jan 2021, 23:47
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!
RG

rgasch

Joined 14.12.2017

Custom Indicator Print() not showing in chart/trade log + data not available in CBot
20 Jan 2021, 23:47


I've coded a custom indicator based on the publically available HeikenAshiPro indicator. The relevant sections of the code are as follows: 

 

using System;
using cAlgo.API;
using cAlgo.API.Indicators;
 
namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class HeikenAshiPro : Indicator
    {
        [OutputAttribute("_haOpen")]
        public  IndicatorDataSeries _haOpen { get; set; }
        [OutputAttribute("_haClose")]
        public  IndicatorDataSeries _haClose { get; set; }
        [OutputAttribute("_haHigh")]
        public  IndicatorDataSeries _haHigh { get; set; }
        [OutputAttribute("_haLow")]
        public  IndicatorDataSeries _haLow { get; set; }
        [OutputAttribute("_haColorDir")]
        public  IndicatorDataSeries _haColorDir { get; set; }
 
 
        protected override void Initialize()
        {
            _haOpen            = CreateDataSeries();
            _haClose           = CreateDataSeries();
            _haHigh            = CreateDataSeries();
            _haLow             = CreateDataSeries();
            _haColorDir        = CreateDataSeries();
        }
 
 
        public override void Calculate(int index) 
        {
            var open  = Bars.OpenPrices[index];
            var high  = Bars.HighPrices[index];
            var low   = Bars.LowPrices[index];
            var close = Bars.ClosePrices[index];
            var time  = Bars.OpenTimes[index];
 
            var haClose = (open + high + low + close) / 4;
            var haOpen  = (index > 0) ? (_haOpen[index - 1] + _haClose[index - 1]) / 2 : (open + close) / 2;
            var haHigh  = Math.Max(Math.Max(high, haOpen), haClose);
            var haLow   = Math.Min(Math.Min(low, haOpen), haClose);
 
            _haOpen[index]       = haOpen;
            _haHigh[index]       = haHigh;
            _haLow[index]        = haLow;
            _haClose[index]      = haClose;
            _haColorDir[index]   = haClose > haOpen ? 1 : -1;
            Print ("XXX " + index);
            Print ("YYY " + _haOpen[index]);

            Chart.ChartType = ChartType.Line;
            drawCandle(index, time, haOpen, haHigh, haLow, haClose);
        }

 
        private void drawTrendLine(int id, DateTime time1, double open1, DateTime time2, double open2, double close2)
        {
            var clr = close2 > open2 ? Color.ForestGreen : Color.OrangeRed;
            Chart.DrawTrendLine("trendline" + id, time1, open1, time2, open2, clr, 2);
        }
 
 
        private void drawCandle(int id, DateTime t, double open, double high, double low, double close)
        {
 
            var clr = close > open ? Color.ForestGreen : Color.OrangeRed;
            Chart.DrawTrendLine("candlebody" + id, t, open, t, close, clr, candlewidth(Chart.ZoomLevel));
            Chart.DrawTrendLine("candlewick" + id, t, high, t, low, clr, 1);
 
            Chart.DrawEllipse("price" + id, t, Bars.ClosePrices.LastValue, t, Bars.ClosePrices.LastValue, Color.Blue, 8);
            resetCandlewidth();
 
        }
 
 
        private int candlewidth(int zoomlevel)
        {
            return zoomlevel <= 10 ? 1 : (zoomlevel <= 20 ? 2 : (zoomlevel <= 40 ? 5 : (zoomlevel <= 80 ? 10 : (zoomlevel <= 180 ? 20 : (zoomlevel <= 320 ? 40 : (60))))));
        }
 
 
        private void resetCandlewidth()
        {
            if (_previousZoomLevel != Chart.ZoomLevel)
            {
                _previousZoomLevel = Chart.ZoomLevel;
                for (int i = 0; i < _haOpen.Count; i++)
                {
                    var time = Bars.OpenTimes[i];
                    var haclr = _haClose[i] > _haOpen[i] ? Color.ForestGreen : Color.OrangeRed;
                    Chart.DrawTrendLine("candlebody" + i, time, _haOpen[i], time, _haClose[i], haclr, candlewidth(Chart.ZoomLevel));
 
                    var dotwidth = Chart.ZoomLevel <= 80 ? 5 : 8;
                    Chart.DrawEllipse("price" + i, time, Bars.ClosePrices[i], time, Bars.ClosePrices[i], Color.Blue, dotwidth);
                }
            }
        }
 
 
 
    }
}

 

As you can see, in the calculate() method, I've added some Print() statements for debugging purposes. Interestingly enough, the indicator works in the sense that the chart is being drawn correctly, but the Print() calls are never displayed in the log. This issue occurs both when just adding this plain indicator to a chart as well as when using this indicator from a CBot. 

 

The second issue I have is that even though the indicator correctly draws the chart, the values are not available from my CBot. The relevant code for this is: 

 

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.None)]
    public class HeikenAshiCustom : Robot
    {
        private HeikenAshiPro  _HAMA;
        private string         _label = "HAMA";

        protected override void OnStart()
        {
            this._HAMA  = Indicators.GetIndicator<HeikenAshiPro>(true);
            this._label = "HAMA_" + this.SymbolName + "_" + this.TimeFrame; 
        }

        protected override void OnBar()
        {
            this.Print(string.Format("{0}: {1} {2} {3} {4}", _label, _HAMA._haOpen.Last(0), _HAMA._haClose.Last(0), _HAMA._haHigh.Last(0), _HAMA._haLow.Last(0)));
        }
    }
}

 

The code compiles (I've added the indicator reference in "Manage References") and seems to run without errors, but the values shown by Print() all return NaN.

 

Any help with either of these issues would be highly appreciated. 

 


@rgasch
Replies

PanagiotisCharalampous
21 Jan 2021, 08:51

Hi rgasch,

1) Print() method for indicators works only in cTrader Automate

2) Your indicator code seems outdated. Please use the one below

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

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class HeikenAshiPro : Indicator
    {
        [Output("_haOpen")]
        public IndicatorDataSeries _haOpen { get; set; }
        [Output("_haClose")]
        public IndicatorDataSeries _haClose { get; set; }
        [Output("_haHigh")]
        public IndicatorDataSeries _haHigh { get; set; }
        [Output("_haLow")]
        public IndicatorDataSeries _haLow { get; set; }
        [Output("_haColorDir")]
        public IndicatorDataSeries _haColorDir { get; set; }


        protected override void Initialize()
        {
        }


        public override void Calculate(int index)
        {
            var open = Bars.OpenPrices[index];
            var high = Bars.HighPrices[index];
            var low = Bars.LowPrices[index];
            var close = Bars.ClosePrices[index];
            var time = Bars.OpenTimes[index];

            var haClose = (open + high + low + close) / 4;
            var haOpen = (index > 0) ? (_haOpen[index - 1] + _haClose[index - 1]) / 2 : (open + close) / 2;
            var haHigh = Math.Max(Math.Max(high, haOpen), haClose);
            var haLow = Math.Min(Math.Min(low, haOpen), haClose);

            _haOpen[index] = haOpen;
            _haHigh[index] = haHigh;
            _haLow[index] = haLow;
            _haClose[index] = haClose;
            _haColorDir[index] = haClose > haOpen ? 1 : -1;
            Print("XXX " + index);
            Print("YYY " + _haOpen[index]);

            Chart.ChartType = ChartType.Line;
            drawCandle(index, time, haOpen, haHigh, haLow, haClose);
        }


        private void drawTrendLine(int id, DateTime time1, double open1, DateTime time2, double open2, double close2)
        {
            var clr = close2 > open2 ? Color.ForestGreen : Color.OrangeRed;
            Chart.DrawTrendLine("trendline" + id, time1, open1, time2, open2, clr, 2);
        }


        private void drawCandle(int id, DateTime t, double open, double high, double low, double close)
        {

            var clr = close > open ? Color.ForestGreen : Color.OrangeRed;
            Chart.DrawTrendLine("candlebody" + id, t, open, t, close, clr, candlewidth(Chart.ZoomLevel));
            Chart.DrawTrendLine("candlewick" + id, t, high, t, low, clr, 1);

            Chart.DrawEllipse("price" + id, t, Bars.ClosePrices.LastValue, t, Bars.ClosePrices.LastValue, Color.Blue, 8);
            resetCandlewidth();

        }


        private int candlewidth(int zoomlevel)
        {
            return zoomlevel <= 10 ? 1 : (zoomlevel <= 20 ? 2 : (zoomlevel <= 40 ? 5 : (zoomlevel <= 80 ? 10 : (zoomlevel <= 180 ? 20 : (zoomlevel <= 320 ? 40 : (60))))));
        }


        private void resetCandlewidth()
        {
            //  if (_previousZoomLevel != Chart.ZoomLevel)
            {
                //_previousZoomLevel = Chart.ZoomLevel;
                for (int i = 0; i < _haOpen.Count; i++)
                {
                    var time = Bars.OpenTimes[i];
                    var haclr = _haClose[i] > _haOpen[i] ? Color.ForestGreen : Color.OrangeRed;
                    Chart.DrawTrendLine("candlebody" + i, time, _haOpen[i], time, _haClose[i], haclr, candlewidth(Chart.ZoomLevel));

                    var dotwidth = Chart.ZoomLevel <= 80 ? 5 : 8;
                    Chart.DrawEllipse("price" + i, time, Bars.ClosePrices[i], time, Bars.ClosePrices[i], Color.Blue, dotwidth);
                }
            }
        }



    }
}

Best Regards,

Panagiotis 

Join us on Telegram

 


@PanagiotisCharalampous

rgasch
24 Jan 2021, 23:04

RE:

Thank you for your help, I got it to work ... 

 

PanagiotisCharalampous said:

Hi rgasch,

1) Print() method for indicators works only in cTrader Automate

2) Your indicator code seems outdated. Please use the one below

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

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class HeikenAshiPro : Indicator
    {
        [Output("_haOpen")]
        public IndicatorDataSeries _haOpen { get; set; }
        [Output("_haClose")]
        public IndicatorDataSeries _haClose { get; set; }
        [Output("_haHigh")]
        public IndicatorDataSeries _haHigh { get; set; }
        [Output("_haLow")]
        public IndicatorDataSeries _haLow { get; set; }
        [Output("_haColorDir")]
        public IndicatorDataSeries _haColorDir { get; set; }


        protected override void Initialize()
        {
        }


        public override void Calculate(int index)
        {
            var open = Bars.OpenPrices[index];
            var high = Bars.HighPrices[index];
            var low = Bars.LowPrices[index];
            var close = Bars.ClosePrices[index];
            var time = Bars.OpenTimes[index];

            var haClose = (open + high + low + close) / 4;
            var haOpen = (index > 0) ? (_haOpen[index - 1] + _haClose[index - 1]) / 2 : (open + close) / 2;
            var haHigh = Math.Max(Math.Max(high, haOpen), haClose);
            var haLow = Math.Min(Math.Min(low, haOpen), haClose);

            _haOpen[index] = haOpen;
            _haHigh[index] = haHigh;
            _haLow[index] = haLow;
            _haClose[index] = haClose;
            _haColorDir[index] = haClose > haOpen ? 1 : -1;
            Print("XXX " + index);
            Print("YYY " + _haOpen[index]);

            Chart.ChartType = ChartType.Line;
            drawCandle(index, time, haOpen, haHigh, haLow, haClose);
        }


        private void drawTrendLine(int id, DateTime time1, double open1, DateTime time2, double open2, double close2)
        {
            var clr = close2 > open2 ? Color.ForestGreen : Color.OrangeRed;
            Chart.DrawTrendLine("trendline" + id, time1, open1, time2, open2, clr, 2);
        }


        private void drawCandle(int id, DateTime t, double open, double high, double low, double close)
        {

            var clr = close > open ? Color.ForestGreen : Color.OrangeRed;
            Chart.DrawTrendLine("candlebody" + id, t, open, t, close, clr, candlewidth(Chart.ZoomLevel));
            Chart.DrawTrendLine("candlewick" + id, t, high, t, low, clr, 1);

            Chart.DrawEllipse("price" + id, t, Bars.ClosePrices.LastValue, t, Bars.ClosePrices.LastValue, Color.Blue, 8);
            resetCandlewidth();

        }


        private int candlewidth(int zoomlevel)
        {
            return zoomlevel <= 10 ? 1 : (zoomlevel <= 20 ? 2 : (zoomlevel <= 40 ? 5 : (zoomlevel <= 80 ? 10 : (zoomlevel <= 180 ? 20 : (zoomlevel <= 320 ? 40 : (60))))));
        }


        private void resetCandlewidth()
        {
            //  if (_previousZoomLevel != Chart.ZoomLevel)
            {
                //_previousZoomLevel = Chart.ZoomLevel;
                for (int i = 0; i < _haOpen.Count; i++)
                {
                    var time = Bars.OpenTimes[i];
                    var haclr = _haClose[i] > _haOpen[i] ? Color.ForestGreen : Color.OrangeRed;
                    Chart.DrawTrendLine("candlebody" + i, time, _haOpen[i], time, _haClose[i], haclr, candlewidth(Chart.ZoomLevel));

                    var dotwidth = Chart.ZoomLevel <= 80 ? 5 : 8;
                    Chart.DrawEllipse("price" + i, time, Bars.ClosePrices[i], time, Bars.ClosePrices[i], Color.Blue, dotwidth);
                }
            }
        }



    }
}

Best Regards,

Panagiotis 

Join us on Telegram

 

 


@rgasch