for learning purpose I am coding a custom indicator in ctrader. It should draw a trendline on 5 bars every 20 bars. But when it draws new trendline the previous one disappear. Can you help me please?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
namespace cAlgo
{
[Indicator(AccessRights = AccessRights.None)]
public class testdrawline : Indicator
{
[Output("Main")]
public IndicatorDataSeries Result { get; set; }
int period = 20;
protected override void Initialize()
{
}
public override void Calculate(int index)
{
// here calculate the bars. when it reached the 20. bar then draw the line
if (index < period)return;
if (index - 20 == period) period += 20;
var l = Chart.DrawTrendLine("line", Bars[index].OpenTime, Bars[index].Close, Bars[index - 5].OpenTime, Bars[index - 5].Close, "Yellow");
l.IsInteractive = true;
}
}
}
You actually have two issues in your code. As Cleptus mentioned, your condition
if (index - 20 == period)won't effectively capture a 20-bar cycle.Cleptus has already given a solution to fix your 20-bar cycle logic, but for the sake of completeness, I'll address both issues in this post.
20-Bar Cycle Logic:
You can use the solution Cleptus offered as is. You can also expand on that a bit to make the condition a bit more robust by doing something along the lines of,
if ((index % 20 == 0) && (index >= 5)). Whereindex >= 5is conjoined toindex % 20 == 0to ensure that during the first 4 bars, your code doesn't try to access negative bar indices.Persistent Chart Drawing Objects:
And now to address your main question. To ensure that chart drawing objects remain persistent, just give each drawing object a unique name. In your original code, you are naming all the trend lines you want to draw with the same name, i.e.
"line". In the cTrader Automate API, drawing objects are identified by their name, so if you create a drawing object named"line"and then change its coordinates, it will redraw that same object in the location of the new coordinates, which is the issue you appear to be experiencing.There are a bunch of ways to give chart drawing objects a unique name. Most of them involve taking some base name that you define, for example
"line", and then appending a unique feature to it, like an incrementing index for example, to get something along the lines of,"line_0","line_1","line_2", etc.Example Solution 1:
Here is an example of how you could update your code, to address both the bar cycle logic, and to ensure chart drawing object persistence using an incrementing index to create unique chart object names.
Example Solution 2:
For the sake of variation, here is another example that uses the bar index to create unique chart object names for each new trendline. The advantage of this is that,