Help: indicator plots different on historical data and in backtesting!
Help: indicator plots different on historical data and in backtesting!
12 May 2024, 15:23
I made an indicator that looks perfectly as intended in the chart,, but when I play backtesting( wtith a cbot that is based on it) it plots in a different way! I hope anybody can help with this ?? Here is pics of the indicator on the chart with and without backtesting:
notice the yellow curve of the indicator:now see it in backtesting:
Replies
DR.SHADI_JARRAR
13 May 2024, 08:57
( Updated at: 13 May 2024, 10:13 )
RE: Help: indicator plots different on historical data and in backtesting!
PanagiotisCharalampous said:
Hi there,
It looks like a logical bug in your code. Share your indicator code in case somebody can have a look and spot it.
Best regards,
Panagiotis
thank for your reply .. here is the indicators code:
using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class DoubleLagEMA : Indicator
{
[Parameter("Period", DefaultValue = 3)]
public int Period { get; set; }
[Parameter("EMA Period", DefaultValue = 100)]
public int EMAPeriod { get; set; }
[Parameter("Rlagema Period", DefaultValue = 60)]
public int RlagemaPeriod { get; set; }
[Parameter("Smoothing Period", DefaultValue = 30)]
public int SmoothingPeriod { get; set; }
[Parameter("Factor", DefaultValue = 10)]
public int Factor { get; set; }
[Output("DLagEMAs", LineColor = "DodgerBlue")]
public IndicatorDataSeries DLagEMAs { get; set; }
[Output("Rlagema", LineColor = "Red")]
public IndicatorDataSeries Rlagema { get; set; }
[Output("Smooth", LineColor = "Yellow")]
public IndicatorDataSeries sr { get; set; }
private ExponentialMovingAverage _ema1;
private ExponentialMovingAverage _ema2;
private MovingAverage smoothenedRlagema;
private MovingAverage _emaRlagema;
private int barsSinceEvent = 0;
private AverageTrueRange atr;
protected override void Initialize()
{
_ema1 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, Period);
_ema2 = Indicators.ExponentialMovingAverage(_ema1.Result, EMAPeriod);
smoothenedRlagema = Indicators.MovingAverage(Rlagema, SmoothingPeriod, MovingAverageType.Exponential);
_emaRlagema = Indicators.MovingAverage(Bars.OpenPrices, RlagemaPeriod, MovingAverageType.Exponential);
atr = Indicators.AverageTrueRange(1000, MovingAverageType.Exponential);
}
public override void Calculate(int index)
{
DLagEMAs[index] = _ema2.Result[index] + _ema2.Result[index] - _ema1.Result[index];
if ((Bars.ClosePrices[index] > DLagEMAs[index] && Bars.ClosePrices[index - 1] < DLagEMAs[index - 1]) ||
(Bars.ClosePrices[index] < DLagEMAs[index] && Bars.ClosePrices[index - 1] > DLagEMAs[index - 1]))
{
barsSinceEvent = 0;
}
else
{
barsSinceEvent++;
}
if (barsSinceEvent > Factor * 5)
{
barsSinceEvent = Factor * 5;
}
var difference2 = Bars.OpenPrices[index] - _emaRlagema.Result[index];
Rlagema[index] = Bars.OpenPrices[index] + difference2;
if (Bars.ClosePrices[index] > DLagEMAs[index])
{
sr[index] = smoothenedRlagema.Result[index] + atr.Result[index] * (Factor - barsSinceEvent * 0.2);
}
else if (Bars.ClosePrices[index] < DLagEMAs[index])
{
sr[index] = smoothenedRlagema.Result[index] - atr.Result[index] * (Factor - barsSinceEvent * 0.2);
}
else
{
sr[index] = smoothenedRlagema.Result[index];
}
}
}
}
and here is the robots code:
using System;
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class DoubleLagEMARobot : Robot
{
private DoubleLagEMA _doubleLagEMA;
private const double LotSize = 0.1;
protected override void OnStart()
{
_doubleLagEMA = Indicators.GetIndicator<DoubleLagEMA>(3, 100, 60, 30, 10);
}
protected override void OnBar()
{ int index = Bars.ClosePrices.Count - 1;
// Closing previous sell position and opening new buy position if the previous bar closes above and the bar before it closes below Dlagemas
if (Bars.ClosePrices[index-1] < _doubleLagEMA.DLagEMAs[index-1] && Bars.ClosePrices[index] > _doubleLagEMA.DLagEMAs[index])
{
CloseSellPositions();
ExecuteMarketOrder(TradeType.Buy, Symbol, LotSize, "Buy");
}
// Closing previous buy position and opening new sell position if the previous bar closes below and the bar before it closes above Dlagemas
else if (Bars.ClosePrices[index-1] > _doubleLagEMA.DLagEMAs[index-1] && Bars.ClosePrices[index] < _doubleLagEMA.DLagEMAs[index])
{
CloseBuyPositions();
ExecuteMarketOrder(TradeType.Sell, Symbol, LotSize, "Sell");
}
}
protected override void OnTick()
{ int index = Bars.ClosePrices.Count - 1;
// Closing all buy positions if high price rises above sr and sr is higher than Dlagemas
if (Symbol.Bid > _doubleLagEMA.sr[index] && _doubleLagEMA.sr[index] > _doubleLagEMA.DLagEMAs[index])
{
CloseBuyPositions();
}
// Closing all sell positions if low price drops below sr and sr is lower than Dlagemas
if (Symbol.Ask < _doubleLagEMA.sr[index] && _doubleLagEMA.sr[index] < _doubleLagEMA.DLagEMAs[index])
{
CloseSellPositions();
}
}
private void CloseBuyPositions()
{
foreach (var position in Positions.FindAll("Buy", Symbol, TradeType.Buy))
{
ClosePosition(position);
}
}
private void CloseSellPositions()
{
foreach (var position in Positions.FindAll("Sell", Symbol, TradeType.Sell))
{
ClosePosition(position);
}
}
}
}
@DR.SHADI_JARRAR
PanagiotisCharalampous
13 May 2024, 10:27
Hi there,
Calculate() method is called once per bar for historical bars and once per tick for live bars. The part below will behave differently when the method is called once per bar, compared to once per tick
if ((Bars.ClosePrices[index] > DLagEMAs[index] && Bars.ClosePrices[index - 1] < DLagEMAs[index - 1]) ||
(Bars.ClosePrices[index] < DLagEMAs[index] && Bars.ClosePrices[index - 1] > DLagEMAs[index - 1]))
{
barsSinceEvent = 0;
}
else
{
barsSinceEvent++;
}
You need to rethink your logic and make sure this part is called only once for each bar.
Best regards,
Panagiotis
@PanagiotisCharalampous
DR.SHADI_JARRAR
13 May 2024, 18:33
RE: Help: indicator plots different on historical data and in backtesting!
PanagiotisCharalampous said:
Hi there,
Calculate() method is called once per bar for historical bars and once per tick for live bars. The part below will behave differently when the method is called once per bar, compared to once per tick
if ((Bars.ClosePrices[index] > DLagEMAs[index] && Bars.ClosePrices[index - 1] < DLagEMAs[index - 1]) || (Bars.ClosePrices[index] < DLagEMAs[index] && Bars.ClosePrices[index - 1] > DLagEMAs[index - 1])) { barsSinceEvent = 0; } else { barsSinceEvent++; }
You need to rethink your logic and make sure this part is called only once for each bar.
Best regards,
Panagiotis
Thanks for your response, I really did my best several ways but couldnt solve it yet, can you suggest anyway to do it!
@DR.SHADI_JARRAR
PanagiotisCharalampous
14 May 2024, 05:41
RE: RE: Help: indicator plots different on historical data and in backtesting!
DR.SHADI_JARRAR said:
PanagiotisCharalampous said:
Hi there,
Calculate() method is called once per bar for historical bars and once per tick for live bars. The part below will behave differently when the method is called once per bar, compared to once per tick
if ((Bars.ClosePrices[index] > DLagEMAs[index] && Bars.ClosePrices[index - 1] < DLagEMAs[index - 1]) || (Bars.ClosePrices[index] < DLagEMAs[index] && Bars.ClosePrices[index - 1] > DLagEMAs[index - 1])) { barsSinceEvent = 0; } else { barsSinceEvent++; }
You need to rethink your logic and make sure this part is called only once for each bar.
Best regards,
Panagiotis
Thanks for your response, I really did my best several ways but couldnt solve it yet, can you suggest anyway to do it!
You can use a parameter that registers at which index the last addition was made and not call that part of the code until the index changes.
@PanagiotisCharalampous
PanagiotisCharalampous
13 May 2024, 06:12
Hi there,
It looks like a logical bug in your code. Share your indicator code in case somebody can have a look and spot it.
Best regards,
Panagiotis
@PanagiotisCharalampous