I've encountered a bug regarding the visualization of a moving average indicator. Whether I zoom in or out of the chart, or move slightly to the left or to the right, the placement of my MAs move, i.e they are under or above a given close price of bar and not fixed.
Example :
Image 1 : Image 2 : As you can see on one case my MovingAverage2 is under the close of the bar at 08:45 and on the other case it's above. The MovingAverage2 value on the bar is 96.0378 and the close of the bar is 96.024719 - so it should be above constantly and it's not the case.
How can I fix this ?
Here's the code I used :
Code: Select all
using System;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;
namespace PowerLanguage.Indicator{
public class MultipleMovingAverage : IndicatorObject
{
// Attributes
private IPlotObject _oPlotMA1;
private IPlotObject _oPlotMA2;
private IPlotObject _oPlotMA3;
private IPlotObject _oPlotMA4;
private int _iMA1 = 5;
private int _iMA2 = 10;
private int _iMA3 = 15;
private int _iMA4 = 20;
private double _dMovingAverage1 = 0;
private double _dMovingAverage2 = 0;
private double _dMovingAverage3 = 0;
private double _dMovingAverage4 = 0;
// Constructor
public MultipleMovingAverage(object _ctx) : base(_ctx) { }
// Accessors
[Input]
public int iMA1
{
get{ return _iMA1;}
set{ _iMA1 = value; }
}
[Input]
public int iMA2
{
get { return _iMA2; }
set { _iMA2 = value; }
}
[Input]
public int iMA3
{
get { return _iMA3; }
set { _iMA3 = value; }
}
[Input]
public int iMA4
{
get { return _iMA4; }
set { _iMA4 = value; }
}
public double dMovingAverage1
{
get { return _dMovingAverage1; }
}
public double dMovingAverage2
{
get { return _dMovingAverage2; }
}
public double dMovingAverage3
{
get { return _dMovingAverage3; }
}
public double dMovingAverage4
{
get { return _dMovingAverage4; }
}
// Private Methods
/// <summary>
/// Calculates the Average Close Price over 'iLength' bars
/// </summary>
/// <param name="iLength"></param>
/// <returns>The average Close over 'iLength' bars</returns>
private double dCalculateAverage(int iLength)
{
double dValue = 0;
for(int i = 0; i < iLength; i++)
{
dValue += Bars.Close[i];
}
dValue /= iLength;
return dValue;
}
// Protected Methods
protected override void Create()
{
// create variable objects, function objects, plot objects etc.
_oPlotMA1 = AddPlot(new PlotAttributes("Moving Average 1", EPlotShapes.Line, Color.Red));
_oPlotMA2 = AddPlot(new PlotAttributes("Moving Average 2", EPlotShapes.Line, Color.Green));
_oPlotMA3 = AddPlot(new PlotAttributes("Moving Average 3", EPlotShapes.Line, Color.Blue));
_oPlotMA4 = AddPlot(new PlotAttributes("Moving Average 4", EPlotShapes.Line, Color.Yellow));
}
protected override void StartCalc()
{
// Nothing to do
}
protected override void CalcBar()
{
// Indicator logic
_dMovingAverage1 = dCalculateAverage(_iMA1);
_dMovingAverage2 = dCalculateAverage(_iMA2);
_dMovingAverage3 = dCalculateAverage(_iMA3);
_dMovingAverage4 = dCalculateAverage(_iMA4);
if (Bars.CurrentBar > _iMA1)
_oPlotMA1.Set(_dMovingAverage1);
if (Bars.CurrentBar > _iMA2)
_oPlotMA2.Set(_dMovingAverage2);
if (Bars.CurrentBar > _iMA3)
_oPlotMA3.Set(_dMovingAverage3);
if (Bars.CurrentBar > _iMA4)
_oPlotMA4.Set(_dMovingAverage4);
}
}
}