Source » Fibonacci - 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 Fibonacci.
    /// </summary>
    public class Fibonacci : Indicator
    {
        public Fibonacci()
        {
        }

        /// <summary>
        /// Sets the default parameters for the designated slot type.
        /// </summary>
        /// <param name="slotType">The slot type.</param>
        public Fibonacci(SlotTypes slotType)
        {
            sIndicatorName  = "Fibonacci";
            parameters      = new IndicatorParam();
            component       = new IndicatorComp[] { };
            afSpecValue     = new float[] { };
            bSeparatedChart = false;
            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[]
            {
                "Enter the market at a Fibonacci level - For demo only!!!"
            };
            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  = "Direction";
            parameters.ListParam[1].ItemList = new string[]
            {
                "Break-through",
                "Retracement"
            };
            parameters.ListParam[1].Index    = 0;
            parameters.ListParam[1].Text     = parameters.ListParam[1].ItemList[parameters.ListParam[1].Index];
            parameters.ListParam[1].Enabled  = true;
            parameters.ListParam[1].ToolTip  = "Direction of trade";

            // The NumericUpDown parameters.
            parameters.NumParam[0].Caption = "Sensitivity";
            parameters.NumParam[0].Value   = 15;
            parameters.NumParam[0].Min     = 10;
            parameters.NumParam[0].Max     = 200;
            parameters.NumParam[0].Enabled = true;
            parameters.NumParam[0].ToolTip = "Sensitivity of the indicator";
        }

        /// <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
            int iSense = (int)parameters.NumParam[0].Value;

            int iFirstBar = iSense;

            float[] afFibo0;
            float[] afFibo382;
            float[] afFibo50;
            float[] afFibo618;
            float[] afFibo100;

            bool bReverseLogic = (parameters.ListParam[1].Text == "Retracement");
            int  iDeviation    = 5;
            int  iBackStep     = 3;

            float[] afHighPoint = new float[Bars];
            float[] afLowPoint  = new float[Bars];

            afFibo0   = new float[Bars];
            afFibo382 = new float[Bars];
            afFibo50  = new float[Bars];
            afFibo618 = new float[Bars];
            afFibo100 = new float[Bars];

            float fLastHigh = 0f;
            float fLastLow  = 0f;
            for (int iBar = iSense; iBar < Bars; iBar++)
            {
                // The highest High in the period [iBar-iSence, iBar]
                float fHigh = 0f;
                for (int iShift = 0; iShift < iSense; iShift++)
                    if (fHigh < High[iBar - iShift])
                        fHigh = High[iBar - iShift];

                if (fHigh == fLastHigh)
                    fHigh = 0f;
                else
                {
                    fLastHigh = fHigh;
                    if (fHigh - High[iBar] > iDeviation * Point)
                        fHigh = 0f;
                    else
                        for (int iBack = 1; iBack <= iBackStep; iBack++)
                            if (afHighPoint[iBar - iBack] > 0f && afHighPoint[iBar - iBack] < fHigh)
                                afHighPoint[iBar - iBack] = 0f;
                }
                afHighPoint[iBar] = fHigh;

                // The lowest Low in the period [iBar-iSence, iBar]
                float fLow = 10000f;
                for (int iShift = 0; iShift < iSense; iShift++)
                    if (Low[iBar - iShift] < fLow)
                        fLow = Low[iBar - iShift];

                if (fLow == fLastLow)
                    fLow = 0f;
                else
                {
                    fLastLow = fLow;
                    if (Low[iBar] - fLow > iDeviation * Point)
                        fLow = 0f;
                    else
                        for (int iBack = 1; iBack <= iBackStep; iBack++)
                            if (afLowPoint[iBar - iBack] > 0f && afLowPoint[iBar - iBack] > fLow)
                                afLowPoint[iBar - iBack] = 0f;
                }
                afLowPoint[iBar] = fLow;
            }

            int iLastHighBar = -1;
            int iLastLowBar  = -1;
            float fCurHigh;
            float fCurLow;
            fLastHigh = -1f;
            fLastLow  = -1f;

            for (int iBar = iSense; iBar < Bars; iBar++)
            {
                fCurHigh = afHighPoint[iBar];
                fCurLow = afLowPoint[iBar];
                if (fCurLow == 0f && fCurHigh == 0f) continue;

                if (fCurHigh != 0f)
                {
                    if (fLastHigh > 0f)
                    {
                        if (fLastHigh < fCurHigh) afHighPoint[iLastHighBar] = 0f;
                        else afHighPoint[iBar] = 0f;
                    }
                    if (fLastHigh < fCurHigh || fLastHigh < 0f)
                    {
                        fLastHigh = fCurHigh;
                        iLastHighBar = iBar;
                    }
                    fLastLow = -1f;
                }

                if (fCurLow != 0f)
                {
                    if (fLastLow > 0f)
                    {
                        if (fLastLow > fCurLow) afLowPoint[iLastLowBar] = 0f;
                        else afLowPoint[iBar] = 0f;
                    }
                    if (fCurLow < fLastLow || fLastLow < 0f)
                    {
                        fLastLow = fCurLow;
                        iLastLowBar = iBar;
                    }
                    fLastHigh = -1f;
                }
            }

            fLastHigh = 0f;
            fLastLow  = 0f;
            int iFirstLowBar  = 0;
            int iFirstHighBar = 0;
            for (int iBar = 0; iBar < Bars; iBar++)
            {
                if (afHighPoint[iBar] > 0f)
                {
                    fLastHigh = afHighPoint[iBar];
                    iFirstHighBar = iBar;
                }
                if (afLowPoint[iBar] > 0f)
                {
                    fLastLow = afLowPoint[iBar];
                    iFirstLowBar = iBar;
                }
                if (iFirstHighBar > 0 && iFirstLowBar > 0) break;
            }

            for (int iBar = Math.Max(iFirstLowBar, iFirstHighBar); iBar < Bars; iBar++)
            {
                if (afHighPoint[iBar - 1] > 0f)
                {
                    fLastHigh = afHighPoint[iBar - 1];
                    afFibo0  [iBar] = fLastHigh;
                    afFibo382[iBar] = fLastHigh - (fLastHigh - fLastLow) * 0.382f;
                    afFibo50 [iBar] = fLastHigh - (fLastHigh - fLastLow) * 0.500f;
                    afFibo618[iBar] = fLastHigh - (fLastHigh - fLastLow) * 0.618f;
                    afFibo100[iBar] = fLastLow;
                }
                else if (afLowPoint[iBar - 1] > 0f)
                {
                    fLastLow = afLowPoint[iBar - 1];
                    afFibo0  [iBar] = fLastLow;
                    afFibo382[iBar] = fLastLow + (fLastHigh - fLastLow) * 0.382f;
                    afFibo50 [iBar] = fLastLow + (fLastHigh - fLastLow) * 0.500f;
                    afFibo618[iBar] = fLastLow + (fLastHigh - fLastLow) * 0.618f;
                    afFibo100[iBar] = fLastHigh;
                }
                else
                {
                    afFibo0  [iBar] = afFibo0  [iBar - 1];
                    afFibo382[iBar] = afFibo382[iBar - 1];
                    afFibo50 [iBar] = afFibo50 [iBar - 1];
                    afFibo618[iBar] = afFibo618[iBar - 1];
                    afFibo100[iBar] = afFibo100[iBar - 1];
                }
            }

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

            component[0] = new IndicatorComp();
            component[0].CompName   = "Position's opening price";
            component[0].DataType   = IndComponentType.OpenPrice;
            component[0].ChartType  = IndChartType.NoChart;
            component[0].FirstBar   = iFirstBar;
            component[0].Value      = new float[Bars];

            component[1] = new IndicatorComp();
            component[1].CompName   = "Fibonacci retracement 0%";
            component[1].DataType   = IndComponentType.IndicatorValue;
            component[1].ChartType  = IndChartType.Level;
            component[1].ChartColor = Color.Green;
            component[1].FirstBar   = iFirstBar;
            component[1].Value      = afFibo0;

            component[2] = new IndicatorComp();
            component[2].CompName   = "Fibonacci retracement 38.2%";
            component[2].DataType   = IndComponentType.IndicatorValue;
            component[2].ChartType  = IndChartType.Level;
            component[2].ChartColor = Color.Yellow;
            component[2].FirstBar   = iFirstBar;
            component[2].Value      = afFibo382;

            component[3] = new IndicatorComp();
            component[3].CompName   = "Fibonacci retracement 50%";
            component[3].DataType   = IndComponentType.IndicatorValue;
            component[3].ChartType  = IndChartType.Level;
            component[3].ChartColor = Color.Orchid;
            component[3].FirstBar   = iFirstBar;
            component[3].Value      = afFibo50;

            component[4] = new IndicatorComp();
            component[4].CompName   = "Fibonacci retracement 61.8%";
            component[4].DataType   = IndComponentType.IndicatorValue;
            component[4].ChartType  = IndChartType.Level;
            component[4].ChartColor = Color.Purple;
            component[4].FirstBar   = iFirstBar;
            component[4].Value      = afFibo618;

            component[5] = new IndicatorComp();
            component[5].CompName   = "Fibonacci retracement 100%";
            component[5].DataType   = IndComponentType.IndicatorValue;
            component[5].ChartType  = IndChartType.Level;
            component[5].ChartColor = Color.Red;
            component[5].FirstBar   = iFirstBar;
            component[5].Value      = afFibo100;

            component[6] = new IndicatorComp();
            component[6].CompName  = "Allows long positions opening";
            component[6].DataType  = IndComponentType.AllowOpenLong;
            component[6].ChartType = IndChartType.NoChart;
            component[6].FirstBar  = iFirstBar;
            component[6].Value     = new float[Bars];

            component[7]           = new IndicatorComp();
            component[7].CompName  = "Allows short positions opening";
            component[7].DataType  = IndComponentType.AllowOpenShort;
            component[7].ChartType = IndChartType.NoChart;
            component[7].FirstBar  = iFirstBar;
            component[7].Value       = new float[Bars];

            int iBarFibo382Reached = 0;
            int iBarFibo500Reached = 0;
            int iBarFibo618Reached = 0;
            int iBarFibo100Reached = 0;

            for (int iBar = Math.Max(iFirstLowBar, iFirstHighBar); iBar < Bars; iBar++)
            {
                component[0].Value[iBar] = 0f;

                // Reset
                if (afHighPoint[iBar - 1] > 0f || afLowPoint[iBar - 1] > 0f)
                {
                    iBarFibo382Reached = 0;
                    iBarFibo500Reached = 0;
                    iBarFibo618Reached = 0;
                    iBarFibo100Reached = 0;
                }

                // Up trend
                if (afFibo0[iBar] < afFibo100[iBar])
                {
                    if (iBarFibo382Reached == 0 && Low[iBar] <= afFibo382[iBar] && High[iBar] >= afFibo382[iBar])
                    {
                        component[6].Value[iBar] = bReverseLogic ? 0f : 1f;
                        component[7].Value[iBar] = bReverseLogic ? 1f : 0f;
                        component[0].Value[iBar] = afFibo382[iBar];
                        iBarFibo382Reached = iBar;
                    }
                    if (iBarFibo500Reached == 0 && Low[iBar] <= afFibo50[iBar] && High[iBar] >= afFibo50[iBar])
                    {
                        component[6].Value[iBar] = bReverseLogic ? 0f : 1f;
                        component[7].Value[iBar] = bReverseLogic ? 1f : 0f;
                        if (iBarFibo382Reached != iBar)
                            component[0].Value[iBar] = afFibo50[iBar];
                        iBarFibo500Reached = iBar;
                    }
                    if (iBarFibo618Reached == 0 && Low[iBar] <= afFibo618[iBar] && High[iBar] >= afFibo618[iBar])
                    {
                        component[6].Value[iBar] = bReverseLogic ? 0f : 1f;
                        component[7].Value[iBar] = bReverseLogic ? 1f : 0f;
                        if (iBarFibo500Reached != iBar)
                            component[0].Value[iBar] = afFibo618[iBar];
                        iBarFibo618Reached = iBar;
                    }
                    if (iBarFibo100Reached == 0 && Low[iBar] <= afFibo100[iBar] && High[iBar] >= afFibo100[iBar])
                    {
                        component[6].Value[iBar] = bReverseLogic ? 0f : 1f;
                        component[7].Value[iBar] = bReverseLogic ? 1f : 0f;
                        if (iBarFibo618Reached != iBar)
                            component[0].Value[iBar] = afFibo100[iBar];
                        iBarFibo100Reached = iBar;
                    }
                }

                // Down trend
                if (afFibo0[iBar] > afFibo100[iBar])
                {
                    if (iBarFibo382Reached == 0 && Low[iBar] <= afFibo382[iBar] && High[iBar] >= afFibo382[iBar])
                    {
                        component[6].Value[iBar] = bReverseLogic ? 1f : 0f;
                        component[7].Value[iBar] = bReverseLogic ? 0f : 1f;
                        component[0].Value[iBar] = afFibo382[iBar];
                        iBarFibo382Reached = iBar;
                    }
                    if (iBarFibo500Reached == 0 && Low[iBar] <= afFibo50[iBar] && High[iBar] >= afFibo50[iBar])
                    {
                        component[6].Value[iBar] = bReverseLogic ? 1f : 0f;
                        component[7].Value[iBar] = bReverseLogic ? 0f : 1f;
                        if (iBarFibo382Reached != iBar)
                            component[0].Value[iBar] = afFibo50[iBar];
                        iBarFibo500Reached = iBar;
                    }
                    if (iBarFibo618Reached == 0 && Low[iBar] <= afFibo618[iBar] && High[iBar] >= afFibo618[iBar])
                    {
                        component[6].Value[iBar] = bReverseLogic ? 1f : 0f;
                        component[7].Value[iBar] = bReverseLogic ? 0f : 1f;
                        if (iBarFibo500Reached != iBar)
                            component[0].Value[iBar] = afFibo618[iBar];
                        iBarFibo618Reached = iBar;
                    }
                    if (iBarFibo100Reached == 0 && Low[iBar] <= afFibo100[iBar] && High[iBar] >= afFibo100[iBar])
                    {
                        component[6].Value[iBar] = bReverseLogic ? 1f : 0f;
                        component[7].Value[iBar] = bReverseLogic ? 0f : 1f;
                        if (iBarFibo618Reached != iBar)
                            component[0].Value[iBar] = afFibo100[iBar];
                        iBarFibo100Reached = iBar;
                    }
                }
            }

            bIsCalculated = true;
        }
    }
}

Top