Custom indicator wrongly displayed
Custom indicator wrongly displayed
25 Mar 2025, 10:43
Hello,
I made a custom indicator, which is wrongly displayed, if:
- compiled with IsOverlay = false and not added to a "New Panel" but to the “Chart” instead
If the same indicator is compiled with IsOverlay = true and added to the “Chart”, it's shown correctly.
For that as example a custom EMA-Indicator as test. The blue line is the custom EMA-Indicator with IsOverlay = false and added to the “Chart”. The green line is the buildin EMA-indicator, so the blue line / custom EMA-Indicator is completely wrong. Once compiled with IsOverlay = false and added to the “Chart”, it makes no difference whether restart cTrader or try to change parameter, it will be always displayed wrong. By the way, the internal values of calculating the EMA are correct, the result is internally always the same as the green line, I rechecked it with print statements - so only the cTrader Desktop display is wrong.

If compiled with IsOverlay = true and added to the “Chart” it's 100% perfect above the green line which is now hidden in that case:

It's not an urgent issue, because I know how to handle now, but it took me a lot of time to find the bug.
For test reasons if need, following the custom EMA-indicator I used:
using System;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.API.Collections;
using System.Linq;
namespace cAlgo
{
[Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class EMA_Test : Indicator
{
[Parameter("Source", DefaultValue = "Close")]
public DataSeries Source { get; set; }
[Parameter("Period", DefaultValue = 15)]
public int Period { get; set; }
[Output("Result", LineColor = "Blue", Thickness = 4, PlotType = PlotType.Line)]
public IndicatorDataSeries Result { get; set; }
private int LastIndex = -1;
private int IndexCount = 0;
protected override void Initialize()
{
this.LastIndex = -1;
this.IndexCount = 0;
}
public override void Calculate(int index)
{
if (index < 0)
return;
if (index != this.LastIndex)
{
this.LastIndex = index;
this.IndexCount++;
}
if (this.IndexCount < this.Period)
{
this.Result[index] = double.NaN;
return;
}
//Print(string.Format("Bars.OpenTimes: {0}, index: {1}, this.Source[index]: {2}", Bars.OpenTimes[index].ToString("dd.MM.yyyy HH:mm:ss.fff"), index, this.Source[index]));
double EMA_01 = 0;
double SF = (double)2 / (double)(this.Period + 1);
if (double.IsNaN(this.Result[index - 1]))
{
double Sum = 0;
for (int i = index; i > index - this.Period; i--)
{
Sum = (double.IsNaN(Sum) ? 0 : Sum) + (double.IsNaN(this.Source[i]) ? 0 : this.Source[i]);
}
EMA_01 = Sum / (double)this.Period;
//Print(string.Format("Bars.OpenTimes: {0}, index: {1}, EMA_01: {2} - Only Start", Bars.OpenTimes[index].ToString("dd.MM.yyyy HH:mm:ss.fff"), index, EMA_01));
}
else
{
EMA_01 = this.Result[index - 1];
//Print(string.Format("Bars.OpenTimes: {0}, index: {1}, EMA_01: {2} - ...", Bars.OpenTimes[index].ToString("dd.MM.yyyy HH:mm:ss.fff"), index, EMA_01));
}
this.Result[index] = SF * (this.Source[index] - EMA_01) + EMA_01;
//Print(string.Format("Bars.OpenTimes: {0}, index: {1}, this.Result[index]: {2} - ...", Bars.OpenTimes[index].ToString("dd.MM.yyyy HH:mm:ss.fff"), index, this.Result[index]));
}
}
}
PS: I use this cTrader Desktop version

Thank you and best regards,
Bernhard
Replies
BernhardCS
29 Mar 2025, 18:25
RE: Custom indicator wrongly displayed
Thanks for the advise, issue has been reported accordongly just now.
@BernhardCS
firemyst
29 Mar 2025, 14:09
Nicely posted with lots of great info to help them investigate/solve the issue.
I would report it in cTrader, and when you do, put a reference to this thread so they know where to look for the information:
@firemyst