Source » MACD Histogram - source code

// Forex Strategy Builder
// Copyright (c) 2006 - 2008 Miroslav Popov - All rights reserved!
// http://forexsb.com
// info(a)forexsb.com
//
// Last changed on: 2007-09-20

using System;
using System.Drawing;

namespace Forex_Strategy_Builder
{
    /// <summary>
    /// Indicator: MACD Histogram
    /// </summary>
    public class MACD_Histogram : Indicator
    {
        /// <summary>
        /// The default constructor.
        /// </summary>
        public MACD_Histogram()
        {
        }

        /// <summary>
        /// Sets the default parameters for the designated slot type.
        /// </summary>
        /// <param name="slotType">The slot type.</param>
        public MACD_Histogram(SlotTypes slotType)
        {
            sIndicatorName  = "MACD Histogram";
            parameters      = new IndicatorParam();
            component       = new IndicatorComp[] { };
            afSpecValue     = new float[1] { 0f };
            bSeparatedChart = true;
            bIsCalculated   = false;


            // The indicator name.
            parameters.IndicatorName = sIndicatorName;

            // The slot type.
            parameters.SlotType = slotType;

            // The ComboBox parameters.
            parameters.ListParam[0].Caption = "Logic";
            parameters.ListParam[0].ItemList = new string[]
            {
                "The MACD histogram rises",
                "The MACD histogram falls",
                "The MACD histogram is higher than the level line",
                "The MACD histogram is lower than the level line",
                "The MACD histogram crosses the level line upward",
                "The MACD histogram crosses the level line downward",
                "The MACD histogram changes its direction upward",
                "The MACD histogram changes its direction downward"
            };
            parameters.ListParam[0].Index    = 0;
            parameters.ListParam[0].Text     = parameters.ListParam[0].ItemList[parameters.ListParam[0].Index];
            parameters.ListParam[0].Enabled  = true;
            parameters.ListParam[0].ToolTip  = "Logic of application of the indicator";

            parameters.ListParam[1].Caption  = "Smoothing method";
            parameters.ListParam[1].ItemList = Enum.GetNames(typeof(MAMethod));
            parameters.ListParam[1].Index    = 2;
            parameters.ListParam[1].Text     = parameters.ListParam[1].ItemList[parameters.ListParam[1].Index];
            parameters.ListParam[1].Enabled  = true;
            parameters.ListParam[1].ToolTip  = "The smoothing method of Moving Averages";

            parameters.ListParam[2].Caption  = "Base price";
            parameters.ListParam[2].ItemList = Enum.GetNames(typeof(BasePrice));
            parameters.ListParam[2].Index    = 3;
            parameters.ListParam[2].Text     = parameters.ListParam[2].ItemList[parameters.ListParam[2].Index];
            parameters.ListParam[2].Enabled  = true;
            parameters.ListParam[2].ToolTip  = "The price the Moving Averages are based on";

            parameters.ListParam[3].Caption  = "Signal line method";
            parameters.ListParam[3].ItemList = Enum.GetNames(typeof(MAMethod));
            parameters.ListParam[3].Index    = 0;
            parameters.ListParam[3].Text     = parameters.ListParam[3].ItemList[parameters.ListParam[3].Index];
            parameters.ListParam[3].Enabled  = true;
            parameters.ListParam[3].ToolTip  = "The smoothing method of the signal line";

            // The NumericUpDown parameters.
            parameters.NumParam[0].Caption = "Slow MA period";
            parameters.NumParam[0].Value   = 26;
            parameters.NumParam[0].Min     = 1;
            parameters.NumParam[0].Max     = 200;
            parameters.NumParam[0].Enabled = true;
            parameters.NumParam[0].ToolTip = "The period of Slow MA";

            parameters.NumParam[1].Caption = "Fast MA period";
            parameters.NumParam[1].Value   = 12;
            parameters.NumParam[1].Min     = 1;
            parameters.NumParam[1].Max     = 200;
            parameters.NumParam[1].Enabled = true;
            parameters.NumParam[1].ToolTip = "The period of Fast MA";

            parameters.NumParam[2].Caption = "Signal line period";
            parameters.NumParam[2].Value   = 9;
            parameters.NumParam[2].Min     = 1;
            parameters.NumParam[2].Max     = 200;
            parameters.NumParam[2].Enabled = true;
            parameters.NumParam[2].ToolTip = "The period of Signal line";

            parameters.NumParam[3].Caption = "Level";
            parameters.NumParam[3].Value   = 0;
            parameters.NumParam[3].Min     = 0;
            parameters.NumParam[3].Max     = 5;
            parameters.NumParam[3].Point   = 4;
            parameters.NumParam[3].Enabled = true;
            parameters.NumParam[3].ToolTip = "A critical level (for the appropriate logic)";

            // The CheckBox parameters.
            parameters.CheckParam[0].Caption = "Use previous bar value";
            parameters.CheckParam[0].Checked = Data.Strategy.PrepareUsePrevBarValueCheckBox(slotType);
            parameters.CheckParam[0].Enabled = true;
            parameters.CheckParam[0].ToolTip = "Use the indicator value from the previous bar";
        }

        /// <summary>
        /// Calculates the indicator's components.
        /// </summary>
        /// <param name="slotType">The slot type.</param>
        public override void Calculate(SlotTypes slotType)
        {
            if (parameters.SlotType == SlotTypes.NotDefined) return;

            // Reading the parameters
            MAMethod  maMethod  = (MAMethod )Enum.GetValues(typeof(MAMethod )).GetValue(parameters.ListParam[1].Index);
            MAMethod  slMethod  = (MAMethod )Enum.GetValues(typeof(MAMethod )).GetValue(parameters.ListParam[3].Index);
            BasePrice basePrice = (BasePrice)Enum.GetValues(typeof(BasePrice)).GetValue(parameters.ListParam[2].Index);
            int       nSlow     = (int)parameters.NumParam[0].Value;
            int       nFast     = (int)parameters.NumParam[1].Value;
            int       nSignal   = (int)parameters.NumParam[2].Value;
            float     fLevel    = parameters.NumParam[3].Value;
            int       iPrvs     = parameters.CheckParam[0].Checked ? 1 : 0;

            // Calculation
            int iFirstBar = nSlow + nFast + 2;

            float[] maSlow = MovingAverage(nSlow, 0, maMethod, Price(basePrice));
            float[] maFast = MovingAverage(nFast, 0, maMethod, Price(basePrice));

            float[] afMACD = new float[Bars];

            for (int iBar = nSlow - 1; iBar < Bars; iBar++)
                afMACD[iBar] = maFast[iBar] - maSlow[iBar];

            float[] maSignalLine = MovingAverage(nSignal, 0, slMethod, afMACD);

            // afHistogram reprezents the MACD oscillator
            float[] afHistogram = new float[Bars];
            for (int iBar = nSlow + nSignal - 1; iBar < Bars; iBar++)
                afHistogram[iBar] = afMACD[iBar] - maSignalLine[iBar];

            // Saving the components
            component = new IndicatorComp[5];

            component[0] = new IndicatorComp();
            component[0].CompName   = "Histogram";
            component[0].DataType   = IndComponentType.IndicatorValue;
            component[0].ChartType  = IndChartType.Histogram;
            component[0].FirstBar   = iFirstBar;
            component[0].Value      = afHistogram;

            component[1] = new IndicatorComp();
            component[1].CompName   = "Signal line";
            component[1].DataType   = IndComponentType.IndicatorValue;
            component[1].ChartType  = IndChartType.Line;
            component[1].ChartColor = Color.Yellow;
            component[1].FirstBar   = iFirstBar;
            component[1].Value      = maSignalLine;

            component[2] = new IndicatorComp();
            component[2].CompName   = "MACD line";
            component[2].DataType   = IndComponentType.IndicatorValue;
            component[2].ChartType  = IndChartType.Line;
            component[2].ChartColor = Color.Blue;
            component[2].FirstBar   = iFirstBar;
            component[2].Value      = afMACD;

            component[3] = new IndicatorComp();
            component[3].ChartType = IndChartType.NoChart;
            component[3].FirstBar  = iFirstBar;
            component[3].Value     = new float[Bars];

            component[4] = new IndicatorComp();
            component[4].ChartType = IndChartType.NoChart;
            component[4].FirstBar  = iFirstBar;
            component[4].Value     = new float[Bars];

            // Sets the component's type.
            if (slotType == SlotTypes.OpenFilter)
            {
                component[3].DataType = IndComponentType.AllowOpenLong;
                component[3].CompName = "Allows long positions opening";
                component[4].DataType = IndComponentType.AllowOpenShort;
                component[4].CompName = "Allows short positions opening";
            }
            else if (slotType == SlotTypes.CloseFilter)
            {
                component[3].DataType = IndComponentType.ForceCloseLong;
                component[3].CompName = "Forces long positions closing";
                component[4].DataType = IndComponentType.ForceCloseShort;
                component[4].CompName = "Forces short positions closing";
            }

            // Calculation of the logic.
            IndicatorLogic indLogic = IndicatorLogic.It_does_not_act_as_a_filter;

            switch (parameters.ListParam[0].Text)
            {
                case "The MACD histogram rises":
                    indLogic = IndicatorLogic.The_indicator_rises;
                    break;

                case "The MACD histogram falls":
                    indLogic = IndicatorLogic.The_indicator_falls;
                    break;

                case "The MACD histogram is higher than the level line":
                    indLogic = IndicatorLogic.The_indicator_is_higher_than_the_level_line;
                    afSpecValue = new float[2] { fLevel, - fLevel };
                    break;

                case "The MACD histogram is lower than the level line":
                    indLogic = IndicatorLogic.The_indicator_is_lower_than_the_level_line;
                    afSpecValue = new float[2] { fLevel, - fLevel };
                    break;

                case "The MACD histogram crosses the level line upward":
                    indLogic = IndicatorLogic.The_indicator_crosses_the_level_line_upward;
                    afSpecValue = new float[2] { fLevel, - fLevel };
                    break;

                case "The MACD histogram crosses the level line downward":
                    indLogic = IndicatorLogic.The_indicator_crosses_the_level_line_downward;
                    afSpecValue = new float[2] { fLevel, - fLevel };
                    break;

                case "The MACD histogram changes its direction upward":
                    indLogic = IndicatorLogic.The_indicator_changes_its_direction_upward;
                    break;

                case "The MACD histogram changes its direction downward":
                    indLogic = IndicatorLogic.The_indicator_changes_its_direction_downward;
                    break;

                default:
                    break;
            }

            bIsCalculated = OscillatorLogic(iFirstBar, iPrvs, afHistogram, fLevel, -fLevel, ref component[3], ref component[4], indLogic);
        }
    }
}

Top