Custom Indicator Print() not showing in chart/trade log + data not available in CBot
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.
Replies
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
@rgasch
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
Best Regards,
Panagiotis
Join us on Telegram
@PanagiotisCharalampous