// 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 System.Drawing;
using Trader.Data;
namespace Trader.Study
{
/// <summary>
/// Represents a MACD (Moving Average Convergence and Divergence).
/// </summary>
public class MACD : Indicator
{
private Series m = new Series();
private double s, h;
private int x, y, z, lastIndex = 0;
private EMA emaX;
private EMA emaY;
private EMA emaZ;
private SerializableColor macdColor = new SerializableColor(Color.Blue);
private SerializableColor signalColor = new SerializableColor(Color.Red);
private SerializableColor histoColor = new SerializableColor(Color.Gray);
/// <summary>
/// ctor.
/// </summary>
public MACD() : base("MACD") {
this.x = 12;
this.y = 26;
this.z = 9;
this.emaX = new EMA(this.x);
this.emaY = new EMA(this.y);
this.emaZ = new EMA(this.z);
base.Position = ChartPosition.Lower;
this.NeedQuotes = false;
}
/// <summary>
/// ctor.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
public MACD(int x, int y, int z) : base("MACD") {
this.x = x;
this.y = y;
this.z = z;
this.emaX = new EMA(this.x);
this.emaY = new EMA(this.y);
this.emaZ = new EMA(this.z);
base.Position = ChartPosition.Lower;
this.NeedQuotes = false;
}
/// <summary>
/// Gets or sets the x.
/// </summary>
[IndicatorParameter]
public int X {
get {
return this.x;
}
set {
this.x = value;
this.emaX.Period = value;
}
}
/// <summary>
/// Gets or sets the y.
/// </summary>
[IndicatorParameter]
public int Y {
get {
return this.y;
}
set {
this.y = value;
this.emaY.Period = value;
}
}
[IndicatorParameter]
public int Z {
get {
return this.z;
}
set {
this.z = value;
this.emaZ.Period = value;
}
}
/// <summary>
/// Calculates the MACD value from a quote.
/// </summary>
/// <remarks>
/// It returns the MACD value.
/// </remarks>
/// <param name="index"></param>
/// <param name="series"></param>
/// <returns></returns>
public override double Calculate(int index, Series series) {
if (index == 0) {
base.Maximum = 0;
base.Minimum = 0;
}
this.lastIndex = index;
double m1 = series.Accept(index, this.emaX) - series.Accept(index, this.emaY);
this.m[index] = m1;
this.s = this.m.Accept(index, this.emaZ);
this.h = m1 - this.s;
if (base.Maximum < m1)
base.Maximum = m1;
if (base.Maximum < this.s)
base.Maximum = this.s;
if (base.Minimum > m1)
base.Minimum = m1;
if (base.Minimum > this.s)
base.Minimum = this.s;
return m1;
}
/// <summary>
/// Gets the MACD.
/// </summary>
[IndicatorValue]
public double MACD_ {
get {
if (this.m.Count == 0) return double.NaN;
return this.m[this.lastIndex];
}
}
/// <summary>
/// Gets the Signal.
/// </summary>
[IndicatorValue]
public double Signal {
get {
return this.s;
}
}
/// <summary>
/// Gets the Histogram.
/// </summary>
[IndicatorValue]
public double DivergenceHistogram {
get {
return this.h;
}
}
/// <summary>
/// Gets or sets the color for K.
/// </summary>
[IndicatorParameter]
public SerializableColor MACD_Color {
get {
return this.macdColor;
}
set {
this.macdColor = value;
}
}
/// <summary>
/// Gets or sets the color for signal.
/// </summary>
[IndicatorParameter]
public SerializableColor SignalColor {
get {
return this.signalColor;
}
set {
this.signalColor = value;
}
}
/// <summary>
/// Gets or sets the color for histogram.
/// </summary>
[IndicatorParameter]
public SerializableColor DivergenceHistogramColor {
get {
return this.histoColor;
}
set {
this.histoColor = value;
}
}
}
}