ChartTrendLines don't get removed from OnDestroy() method when indicator removed from chart
ChartTrendLines don't get removed from OnDestroy() method when indicator removed from chart
01 Nov 2024, 01:52
Hi everyone:
See code below. In the OnDestroy() method, I have two loops, neither of which work, which are intended to remove all the ChartTrendLines drawn on the chart, especially when the indicator is removed from the chart.
Code below. Can anyone tell me what I'm doing wrong? Thank you.
using System;
using System.Collections.Generic;
using System.Reflection;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
namespace cAlgo
{
[Indicator(AccessRights = AccessRights.FullAccess, IsOverlay = true)]
public class Test : Indicator
{
private const string CONST_IndicatorName = "TEST";
[Parameter("Num Bars Back to Start (-1 for all)", DefaultValue = 21, MinValue = -1)]
public int NumBarsBackToStart { get; set; }
[Parameter("Line Color", DefaultValue = "White")]
public Color LineColor { get; set; }
[Parameter("Line Thickness", DefaultValue = 3)]
public int LineThickness { get; set; }
[Parameter("Line Style", DefaultValue = LineStyle.Solid)]
public LineStyle LineStyleDrawn { get; set; }
public IndicatorDataSeries ResultHighs { get; set; }
private int _previousIndex;
private int _indexToStart;
private Dictionary<int, ChartTrendLine> _lowToHighsTrendLinesDrawn;
protected override void Initialize()
{
#if DEBUG
var result = System.Diagnostics.Debugger.Launch();
#endif
ResultHighs = CreateDataSeries();
_indexToStart = (NumBarsBackToStart == -1 ? 2 : Bars.Count - NumBarsBackToStart);
_previousIndex = _indexToStart - 2;
//Used to keep track of every line we draw so we can clean up properly at the end
_lowToHighsTrendLinesDrawn = new Dictionary<int, ChartTrendLine>(NumBarsBackToStart);
Chart.ObjectsRemoved += Chart_ObjectsRemoved;
}
//Can't debug through this method in Visual Studio -- the first foreach always crashes because it seems like cTrader closes itself off before this method completes running.
//
//THis method also doesn't seem to remove all the drawings from the chart.
//Why not?
//
//It doesn't matter which loop I use. Neither seems to work nor remove all the chart trend lines drawn.
//
//I DO NOT want to use Chart.RemoveAllObjects because there might be other objects drawn with this indicator I want to leave on the chart.
//
protected override void OnDestroy()
{
//THIS FOREACH LOOP DOESN"T REMOVE THE TRENDLINES FROM THE CHART
//I can't debug this forweach loop either in Visual Studio as VS always seems to exit before completion.
//
//foreach (KeyValuePair<int, ChartTrendLine> kvp in _lowToHighsTrendLinesDrawn)
//{
// //Set the object so it's no longer interactive and can be found in chart collections
// ChartObject co = kvp.Value;
// co.IsInteractive = false;
// //Remove. THis doesn't seem to work. Why?
// Chart.RemoveObject(CONST_IndicatorName + "LowsToHighs" + kvp.Key);
// co = null;
//}
//Try looping through each object in the dictionary to set to null to see if removed from chart.
//THIS LOOP DOES NOT WORK EITHER. Why?
//
for (int x = _lowToHighsTrendLinesDrawn.Count - 1; x >= 0; x--)
{
if (_lowToHighsTrendLinesDrawn.ContainsKey(x))
{
_lowToHighsTrendLinesDrawn[x].IsInteractive = false;
Chart.RemoveObject(CONST_IndicatorName + "LowsToHighs" + x);
_lowToHighsTrendLinesDrawn[x] = null;
}
}
//Clean up the Dictionary object
_lowToHighsTrendLinesDrawn.Clear();
_lowToHighsTrendLinesDrawn = null;
}
public override void Calculate(int index)
{
if (index < _indexToStart)
{
_previousIndex = index;
return;
}
//Only do this once per bar
if (index > _previousIndex)
{
int previousIndexMinus1 = _previousIndex - 1;
double highPricePrev = Bars.HighPrices[_previousIndex];
double highPrice2BarsAgo = Bars.HighPrices[previousIndexMinus1];
ResultHighs[_previousIndex] = highPricePrev;
ResultHighs[previousIndexMinus1] = highPrice2BarsAgo;
ChartTrendLine ctl = Chart.DrawTrendLine(CONST_IndicatorName + "LowsToHighs" + previousIndexMinus1, previousIndexMinus1, ResultHighs[previousIndexMinus1], _previousIndex, ResultHighs[_previousIndex], LineColor, LineThickness, LineStyleDrawn);
ctl.IsInteractive = true;
if (_lowToHighsTrendLinesDrawn.ContainsKey(previousIndexMinus1))
{
_lowToHighsTrendLinesDrawn[previousIndexMinus1].IsInteractive = false;
Chart.RemoveObject(CONST_IndicatorName + "LowsToHighs" + previousIndexMinus1);
_lowToHighsTrendLinesDrawn[previousIndexMinus1] = null;
_lowToHighsTrendLinesDrawn.Remove(previousIndexMinus1);
}
_lowToHighsTrendLinesDrawn.Add(previousIndexMinus1, ctl);
_previousIndex = index;
}
}
private void Chart_ObjectsRemoved(ChartObjectsRemovedEventArgs obj)
{
/* If the object is removed, we should rid of its
reference. Otherwise, it will remain in memory. */
for (int x = obj.ChartObjects.Count - 1; x >= 0 ; x--)
{
if (!obj.ChartObjects[x].IsAlive)
{
ChartObject co = obj.ChartObjects[x];
co.IsInteractive = false;
co = null;
}
}
}
}
}
Replies
AlgoCreators
04 Nov 2024, 08:59
I think the OnDestroy function is never executed. There is no such feature in the indicators
@AlgoCreators
firemyst
04 Nov 2024, 23:23
RE: ChartTrendLines don't get removed from OnDestroy() method when indicator removed from chart
AlgoCreators said:
I think the OnDestroy function is never executed. There is no such feature in the indicators
I'm not sure where you've been, but OnDestroy() has been there since version 4.2:
@firemyst
PanagiotisCharalampous
04 Nov 2024, 06:52
Hi firemyst,
Thank you for reporting this. We are investigating.
Best regards,
Panagiotis
@PanagiotisCharalampous