// All rights reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR
// FITNESS FOR A PARTICULAR PURPOSE.
using System;
using Trader.Data;
namespace Trader.Study {
/// <summary>
/// Represents a Bollinger Band indicator.
/// </summary>
public class BollingerBand : Indicator {
private SMA sma;
private StdDev stdDev;
private double middle;
private double upper;
private double lower;
private int period;
private int range;
/// <summary>
/// ctor.
/// </summary>
/// <remarks>
/// Default: Period = 20 and Range = 2 sigma
/// </remarks>
public BollingerBand() : base("Bollinger Band") {
this.period = 20;
this.range = 2;
this.sma = new SMA(20);
this.stdDev = new StdDev(20);
base.Position = ChartPosition.Upper;
}
/// <summary>
/// ctor.
/// </summary>
public BollingerBand(int period, int range) : base("Bollinger Band") {
this.period = period;
this.range = range;
this.sma = new SMA(period);
this.stdDev = new StdDev(period);
base.Position = ChartPosition.Upper;
}
/// <summary>
/// Gets or sets the period.
/// </summary>
[IndicatorParameter]
public int Period {
get {
return this.period;
}
set {
this.period = value;
this.sma.Period = value;
this.stdDev.Period = value;
}
}
/// <summary>
/// Gets or sets the range.
/// </summary>
[IndicatorParameter]
public int Range {
get {
return this.range;
}
set {
this.range = value;
}
}
/// <summary>
/// Calculates the sma at index.
/// </summary>
/// <remarks>
/// After each calculation, the result is in Upper, Lower and Middle
/// properties. The return value here is the middle.
/// </remarks>
/// <param name="index"></param>
/// <param name="series"></param>
public override double Calculate(int index, Series series) {
if (index == 0) {
base.Maximum = 0;
base.Minimum = 0;
}
double sigma = series.Accept(index, this.stdDev);
this.middle = series.Accept(index, this.sma);
this.upper = this.middle + sigma*this.range;
this.lower = this.middle - sigma*this.range;
return this.middle;
}
/// <summary>
/// Gets the upper band.
/// </summary>
[IndicatorValue]
public double Upper {
get {
return this.upper;
}
}
/// <summary>
/// Gets the middle line.
/// </summary>
[IndicatorValue]
public double Middle {
get {
return this.middle;
}
}
/// <summary>
/// Gets the lower band.
/// </summary>
[IndicatorValue]
public double Lower {
get {
return this.lower;
}
}
/// <summary>
/// Gets the sigma.
/// </summary>
public double Sigma {
get {
return this.stdDev.Sigma;
}
}
}
}