Fractal Dimension Index by zuijaideai

2919 downloads / 3275 views / Created: 23.05.2013
 Average Rating: 5

Indicator Description

Hi All,
This is a new indicator requested by Zenoni on the following forum topic.

This indicator appeared in TASC magazine April 2007 and available in Metatrader MQL4 Codebase website. Iis commonly called as Fractal Dimension Index (FDI). It's a nondirectional index indicator that measures the strength of the trend. It is a indicator that shows strength of trend as compared to the vertical horizontal filter, ADX, DMI. It doesn't shows a trading signal, because this indicator can be used for filtering only. If you want to learn more about this indicator you can google it.

FDI

Link to the forum topic: Fractal Dimension Index

Rgds
Denny Imanuel
imanuel.denny@gmail.com

Comments

//============================================================== // Forex Strategy Builder // Copyright © Miroslav Popov. All rights reserved. //============================================================== // THIS CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, // EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE. //============================================================== using System; using System.Drawing; using ForexStrategyBuilder.Infrastructure.Entities; using ForexStrategyBuilder.Infrastructure.Enums; using ForexStrategyBuilder.Infrastructure.Interfaces; namespace ForexStrategyBuilder.Indicators.Store { public class FractalDimensionIndex : Indicator { public FractalDimensionIndex() { IndicatorName = "Fractal Dimension Index"; PossibleSlots = SlotTypes.OpenFilter | SlotTypes.CloseFilter; SeparatedChart = true; // SeparatedChartMinValue = 0; // SeparatedChartMaxValue = 100; IndicatorAuthor = "Denny Imanuel"; IndicatorVersion = "2.0"; IndicatorDescription = "This indicator appeared in TASC magazine April 2007 and available in Metatrader MQL4 Codebase website."; } public override void Initialize(SlotTypes slotType) { SlotType = slotType; // The ComboBox parameters IndParam.ListParam[0].Caption = "Logic"; IndParam.ListParam[0].ItemList = new string[] { "The FDI rises", "The FDI falls", "The FDI is higher than the Level line", "The FDI is lower than the Level line", "The FDI crosses the Level line upward", "The FDI crosses the Level line downward", "The FDI changes its direction upward", "The FDI changes its direction downward" }; IndParam.ListParam[0].Index = 0; IndParam.ListParam[0].Text = IndParam.ListParam[0].ItemList[IndParam.ListParam[0].Index]; IndParam.ListParam[0].Enabled = true; IndParam.ListParam[0].ToolTip = "Logic of application of the indicator."; IndParam.ListParam[1].Caption = "Smoothing method"; IndParam.ListParam[1].ItemList = Enum.GetNames(typeof(MAMethod)); IndParam.ListParam[1].Index = (int)MAMethod.Exponential; IndParam.ListParam[1].Text = IndParam.ListParam[1].ItemList[IndParam.ListParam[1].Index]; IndParam.ListParam[1].Enabled = true; IndParam.ListParam[1].ToolTip = "The Moving Average method used for smoothing the FDI value."; IndParam.ListParam[2].Caption = "Base price"; IndParam.ListParam[2].ItemList = Enum.GetNames(typeof(BasePrice)); IndParam.ListParam[2].Index = (int)BasePrice.Close; IndParam.ListParam[2].Text = IndParam.ListParam[2].ItemList[IndParam.ListParam[2].Index]; IndParam.ListParam[2].Enabled = true; IndParam.ListParam[2].ToolTip = "The price the RSI is based on."; // The NumericUpDown parameters IndParam.NumParam[0].Caption = "Period"; IndParam.NumParam[0].Value = 30; IndParam.NumParam[0].Min = 1; IndParam.NumParam[0].Max = 200; IndParam.NumParam[0].Enabled = true; IndParam.NumParam[0].ToolTip = "The period of FDI."; IndParam.NumParam[1].Caption = "Level"; IndParam.NumParam[1].Value = 1.5; IndParam.NumParam[1].Min = 1; IndParam.NumParam[1].Max = 2; IndParam.NumParam[1].Point = 2; IndParam.NumParam[1].Enabled = true; IndParam.NumParam[1].ToolTip = "A critical level (for the appropriate logic)."; // The CheckBox parameters IndParam.CheckParam[0].Caption = "Use previous bar value."; IndParam.CheckParam[0].Checked = (slotType == SlotTypes.OpenFilter); IndParam.CheckParam[0].Enabled = false; IndParam.CheckParam[0].ToolTip = "Use the indicator value from the previous bar."; } public override void Calculate(IDataSet dataSet) { DataSet = dataSet; // Reading the parameters MAMethod maMethod = (MAMethod)IndParam.ListParam[1].Index; BasePrice basePrice = (BasePrice)IndParam.ListParam[2].Index; int iPeriod = (int)IndParam.NumParam[0].Value; double dLevel = IndParam.NumParam[1].Value; int iPrvs = (SlotType == SlotTypes.OpenFilter) ? 1 : 0; //Calculation int iFirstBar = iPeriod + 10; double[] adBasePrice = Price(basePrice); double[] adFractalDim = new double[Bars]; double[] adUpperBand = new double[Bars]; double[] adLowerBand = new double[Bars]; double[] adLevel = new double[Bars]; double dPriceMax; double dPriceMin; double dDiff; double dPriorDiff; double dLength; double dVar; double dStdDev; double dMean; double dSum; double dDelta; for (int iBar=iFirstBar; iBardPriceMax) dPriceMax = adBasePrice[iBar-iBack]; if (adBasePrice[iBar-iBack]0) { dDiff = (adBasePrice[iIteration]-dPriceMin)/(dPriceMax-dPriceMin); if (iIteration>1) { dLength += Math.Sqrt( Math.Pow(dDiff-dPriorDiff,2) + (1/Math.Pow(iPeriod,2)) ); } dPriorDiff = dDiff; } } if (dLength>0) { adFractalDim[iBar] = 1 + (Math.Log(dLength) + Math.Log(2))/Math.Log(2*iPeriod); dMean = dLength/(iPeriod-1); for (int iIteration=1; iIteration0) { dDiff = (adBasePrice[iIteration]-dPriceMin)/(dPriceMax-dPriceMin); if (iIteration>1) { dDelta = Math.Sqrt( Math.Pow(dDiff-dPriorDiff,2) + (1/Math.Pow(iPeriod,2)) ); dSum += Math.Pow(dDelta-(dLength/(iPeriod-1)),2); } dPriorDiff = dDiff; } } dVar = dSum / (Math.Pow(dLength,2)*Math.Pow(Math.Log(2*(iPeriod-1)),2) ); } else { adFractalDim[iBar] = 0; dVar = 0; } dStdDev = Math.Sqrt(dVar); adUpperBand[iBar] = adFractalDim[iBar] + dStdDev; adLowerBand[iBar] = adFractalDim[iBar] - dStdDev; adLevel[iBar] = dLevel; } // Saving the components Component = new IndicatorComp[6]; Component[0] = new IndicatorComp(); Component[0].CompName = "FDI"; Component[0].DataType = IndComponentType.IndicatorValue; Component[0].ChartType = IndChartType.Line; Component[0].ChartColor = Color.Blue; Component[0].FirstBar = iFirstBar; Component[0].Value = adFractalDim; Component[1] = new IndicatorComp(); Component[1].ChartType = IndChartType.NoChart; Component[1].FirstBar = iFirstBar; Component[1].Value = new double[Bars]; Component[2] = new IndicatorComp(); Component[2].ChartType = IndChartType.NoChart; Component[2].FirstBar = iFirstBar; Component[2].Value = new double[Bars]; Component[3] = new IndicatorComp(); Component[3].CompName = "Upper Band"; Component[3].DataType = IndComponentType.IndicatorValue; Component[3].ChartType = IndChartType.Line; Component[3].ChartColor = Color.Red; Component[3].FirstBar = iFirstBar; Component[3].Value = adUpperBand; Component[4] = new IndicatorComp(); Component[4].CompName = "Lower Band"; Component[4].DataType = IndComponentType.IndicatorValue; Component[4].ChartType = IndChartType.Line; Component[4].ChartColor = Color.Green; Component[4].FirstBar = iFirstBar; Component[4].Value = adLowerBand; Component[5] = new IndicatorComp(); Component[5].CompName = "Level"; Component[5].DataType = IndComponentType.IndicatorValue; Component[5].ChartType = IndChartType.Line; Component[5].ChartColor = Color.Orange; Component[5].FirstBar = iFirstBar; Component[5].Value = adLevel; // Sets the Component's type if (SlotType == SlotTypes.OpenFilter) { Component[1].DataType = IndComponentType.AllowOpenLong; Component[1].CompName = "Is long entry allowed"; Component[2].DataType = IndComponentType.AllowOpenShort; Component[2].CompName = "Is short entry allowed"; } else if (SlotType == SlotTypes.CloseFilter) { Component[1].DataType = IndComponentType.ForceCloseLong; Component[1].CompName = "Close out long position"; Component[2].DataType = IndComponentType.ForceCloseShort; Component[2].CompName = "Close out short position"; } // Calculation of the logic IndicatorLogic indLogic = IndicatorLogic.It_does_not_act_as_a_filter; switch (IndParam.ListParam[0].Text) { case "The FDI rises": indLogic = IndicatorLogic.The_indicator_rises; break; case "The FDI falls": indLogic = IndicatorLogic.The_indicator_falls; break; case "The FDI is higher than the Level line": indLogic = IndicatorLogic.The_indicator_is_higher_than_the_level_line; SpecialValues = new double[1] { dLevel }; break; case "The FDI is lower than the Level line": indLogic = IndicatorLogic.The_indicator_is_lower_than_the_level_line; SpecialValues = new double[1] { dLevel }; break; case "The FDI crosses the Level line upward": indLogic = IndicatorLogic.The_indicator_crosses_the_level_line_upward; SpecialValues = new double[1] { dLevel }; break; case "The FDI crosses the Level line downward": indLogic = IndicatorLogic.The_indicator_crosses_the_level_line_downward; SpecialValues = new double[1] { dLevel }; break; case "The FDI changes its direction upward": indLogic = IndicatorLogic.The_indicator_changes_its_direction_upward; break; case "The FDI changes its direction downward": indLogic = IndicatorLogic.The_indicator_changes_its_direction_downward; break; default: break; } NoDirectionOscillatorLogic(iFirstBar, iPrvs, adFractalDim, dLevel, ref Component[1], indLogic); Component[2].Value = Component[1].Value; } public override void SetDescription() { string sLevelLong = IndParam.NumParam[1].ValueToString; string sLevelShort = sLevelLong; EntryFilterLongDescription = "the " + ToString() + " "; EntryFilterShortDescription = "the " + ToString() + " "; ExitFilterLongDescription = "the " + ToString() + " "; ExitFilterShortDescription = "the " + ToString() + " "; switch (IndParam.ListParam[0].Text) { case "The FDI rises": EntryFilterLongDescription += "rises"; EntryFilterShortDescription += "rises"; ExitFilterLongDescription += "rises"; ExitFilterShortDescription += "rises"; break; case "The FDI falls": EntryFilterLongDescription += "falls"; EntryFilterShortDescription += "falls"; ExitFilterLongDescription += "falls"; ExitFilterShortDescription += "falls"; break; case "The FDI is higher than the Level line": EntryFilterLongDescription += "is higher than the Level " + sLevelLong; EntryFilterShortDescription += "is higher than the Level " + sLevelShort; ExitFilterLongDescription += "is higher than the Level " + sLevelLong; ExitFilterShortDescription += "is higher than the Level " + sLevelShort; break; case "The FDI is lower than the Level line": EntryFilterLongDescription += "is lower than the Level " + sLevelLong; EntryFilterShortDescription += "is lower than the Level " + sLevelShort; ExitFilterLongDescription += "is lower than the Level " + sLevelLong; ExitFilterShortDescription += "is lower than the Level " + sLevelShort; break; case "The FDI crosses the Level line upward": EntryFilterLongDescription += "crosses the Level " + sLevelLong + " upward"; EntryFilterShortDescription += "crosses the Level " + sLevelShort + " upward"; ExitFilterLongDescription += "crosses the Level " + sLevelLong + " upward"; ExitFilterShortDescription += "crosses the Level " + sLevelShort + " upward"; break; case "The FDI crosses the Level line downward": EntryFilterLongDescription += "crosses the Level " + sLevelLong + " downward"; EntryFilterShortDescription += "crosses the Level " + sLevelShort + " downward"; ExitFilterLongDescription += "crosses the Level " + sLevelLong + " downward"; ExitFilterShortDescription += "crosses the Level " + sLevelShort + " downward"; break; case "The FDI changes its direction upward": EntryFilterLongDescription += "changes its direction upward"; EntryFilterShortDescription += "changes its direction upward"; ExitFilterLongDescription += "changes its direction upward"; ExitFilterShortDescription += "changes its direction upward"; break; case "The FDI changes its direction downward": EntryFilterLongDescription += "changes its direction downward"; EntryFilterShortDescription += "changes its direction downward"; ExitFilterLongDescription += "changes its direction downward"; ExitFilterShortDescription += "changes its direction downward"; break; } } public override string ToString() { return IndicatorName + (IndParam.SlotType == SlotTypes.OpenFilter ? "* (" : " (") + IndParam.ListParam[1].Text + ", " + // Smoothing method IndParam.ListParam[2].Text + ", " + // Base price IndParam.NumParam[0].ValueToString + ")"; // FDI Period } } }
//+--------------------------------------------------------------------+ //| Copyright: (C) 2014, Miroslav Popov - All rights reserved! | //| Website: http://forexsb.com/ | //| Support: http://forexsb.com/forum/ | //| License: Proprietary under the following circumstances: | //| | //| This code is a part of Forex Strategy Builder. It is free for | //| use as an integral part of Forex Strategy Builder. | //| One can modify it in order to improve the code or to fit it for | //| personal use. This code or any part of it cannot be used in | //| another applications without a permission. Contact information | //| cannot be changed. | //| | //| NO LIABILITY FOR CONSEQUENTIAL DAMAGES | //| | //| In no event shall the author be liable for any damages whatsoever | //| (including, without limitation, incidental, direct, indirect and | //| consequential damages, damages for loss of business profits, | //| business interruption, loss of business information, or other | //| pecuniary loss) arising out of the use or inability to use this | //| product, even if advised of the possibility of such damages. | //+--------------------------------------------------------------------+ #property copyright "Copyright 2014, Miroslav Popov" #property link "http://forexsb.com" #property version "1.00" #property strict #include <Forexsb.com/Indicator.mqh> #include <Forexsb.com/Enumerations.mqh> //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class FractalDimensionIndex : public Indicator { public: FractalDimensionIndex(SlotTypes slotType) { SlotType=slotType; IndicatorName="Fractal Dimension Index"; WarningMessage = ""; IsAllowLTF = true; ExecTime = ExecutionTime_DuringTheBar; IsSeparateChart = true; IsDiscreteValues = false; IsDeafultGroupAll = false; } virtual void Calculate(DataSet &dataSet); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void FractalDimensionIndex::Calculate(DataSet &dataSet) { Data=GetPointer(dataSet); // Reading the parameters BasePrice basePrice = (BasePrice)ListParam[2].Index; int iPeriod = (int)NumParam[0].Value; double dLevel = NumParam[1].Value; int iPrvs = (SlotType == SlotTypes_OpenFilter) ? 1 : 0; //Calculation int iFirstBar=iPeriod+10; double adBasePrice[]; Price(basePrice,adBasePrice); double adFractalDim[]; ArrayResize(adFractalDim,Data.Bars);ArrayInitialize(adFractalDim,0); double adUpperBand[]; ArrayResize(adUpperBand, Data.Bars);ArrayInitialize(adUpperBand,0); double adLowerBand[]; ArrayResize(adLowerBand, Data.Bars);ArrayInitialize(adLowerBand,0); double adLevel[]; ArrayResize(adLevel,Data.Bars); ArrayInitialize(adLevel,0); double dPriceMax; double dPriceMin; double dDiff; double dPriorDiff; double dLength; double dVar; double dStdDev; double dMean; double dSum; double dDelta; for(int iBar=iFirstBar; iBar<Data.Bars; iBar++) { dPriceMax = DBL_MIN; dPriceMin = DBL_MAX; for(int iBack=0; iBack<iPeriod; iBack++) { if(adBasePrice[iBar-iBack]>dPriceMax) dPriceMax=adBasePrice[iBar-iBack]; if(adBasePrice[iBar-iBack]<dPriceMin) dPriceMin=adBasePrice[iBar-iBack]; } dPriorDiff=0; dLength=0; dSum=0; for(int iIteration=1; iIteration<iPeriod; iIteration++) { if(dPriceMax-dPriceMin>0) { dDiff=(adBasePrice[iIteration]-dPriceMin)/(dPriceMax-dPriceMin); if(iIteration>1) { dLength+=MathSqrt(MathPow(dDiff-dPriorDiff,2)+(1/MathPow(iPeriod,2))); } dPriorDiff=dDiff; } } if(dLength>0) { adFractalDim[iBar]=1+(MathLog(dLength)+MathLog(2))/MathLog(2*iPeriod); dMean=dLength/(iPeriod-1); for(int iIteration=1; iIteration<iPeriod; iIteration++) { if(dPriceMax-dPriceMin>0) { dDiff=(adBasePrice[iIteration]-dPriceMin)/(dPriceMax-dPriceMin); if(iIteration>1) { dDelta=MathSqrt(MathPow(dDiff-dPriorDiff,2)+(1/MathPow(iPeriod,2))); dSum+=MathPow(dDelta-(dLength/(iPeriod-1)),2); } dPriorDiff=dDiff; } } dVar=dSum/(MathPow(dLength,2)*MathPow(MathLog(2*(iPeriod-1)),2)); } else { adFractalDim[iBar]=0; dVar=0; } dStdDev=MathSqrt(dVar); adUpperBand[iBar] = adFractalDim[iBar] + dStdDev; adLowerBand[iBar] = adFractalDim[iBar] - dStdDev; adLevel[iBar]=dLevel; } // Saving the components ArrayResize(Component[0].Value,Data.Bars); Component[0].CompName = "FDI"; Component[0].DataType = IndComponentType_IndicatorValue; Component[0].FirstBar = iFirstBar; ArrayCopy(Component[0].Value,adFractalDim); ArrayResize(Component[1].Value,Data.Bars); Component[1].FirstBar=iFirstBar; ArrayResize(Component[2].Value,Data.Bars); Component[2].FirstBar=iFirstBar; ArrayResize(Component[3].Value,Data.Bars); Component[3].CompName = "Upper Band"; Component[3].DataType = IndComponentType_IndicatorValue; Component[3].FirstBar = iFirstBar; ArrayCopy(Component[3].Value,adUpperBand); ArrayResize(Component[4].Value,Data.Bars); Component[4].CompName = "Lower Band"; Component[4].DataType = IndComponentType_IndicatorValue; Component[4].FirstBar = iFirstBar; ArrayCopy(Component[4].Value,adLowerBand); ArrayResize(Component[5].Value,Data.Bars); Component[5].CompName = "Level"; Component[5].DataType = IndComponentType_IndicatorValue; Component[5].FirstBar = iFirstBar; ArrayCopy(Component[5].Value,adLevel); // Sets the Component's type if(SlotType==SlotTypes_OpenFilter) { Component[1].DataType = IndComponentType_AllowOpenLong; Component[1].CompName = "Is long entry allowed"; Component[2].DataType = IndComponentType_AllowOpenShort; Component[2].CompName = "Is short entry allowed"; } else if(SlotType==SlotTypes_CloseFilter) { Component[1].DataType = IndComponentType_ForceCloseLong; Component[1].CompName = "Close out long position"; Component[2].DataType = IndComponentType_ForceCloseShort; Component[2].CompName = "Close out short position"; } // Calculation of the logic IndicatorLogic indLogic=IndicatorLogic_It_does_not_act_as_a_filter; if(ListParam[0].Text=="The FDI rises") { indLogic=IndicatorLogic_The_indicator_rises; } else if(ListParam[0].Text=="The FDI falls") { indLogic=IndicatorLogic_The_indicator_falls; } else if(ListParam[0].Text=="The FDI is higher than the Level line") { indLogic=IndicatorLogic_The_indicator_is_higher_than_the_level_line; } else if(ListParam[0].Text=="The FDI is lower than the Level line") { indLogic=IndicatorLogic_The_indicator_is_lower_than_the_level_line; } else if(ListParam[0].Text=="The FDI crosses the Level line upward") { indLogic=IndicatorLogic_The_indicator_crosses_the_level_line_upward; } else if(ListParam[0].Text=="The FDI crosses the Level line downward") { indLogic=IndicatorLogic_The_indicator_crosses_the_level_line_downward; } else if(ListParam[0].Text=="The FDI changes its direction upward") { indLogic=IndicatorLogic_The_indicator_changes_its_direction_upward; } else if(ListParam[0].Text=="The FDI changes its direction downward") { indLogic=IndicatorLogic_The_indicator_changes_its_direction_downward; } NoDirectionOscillatorLogic(iFirstBar,iPrvs,adFractalDim,dLevel,Component[1],indLogic); ArrayCopy(Component[2].Value,Component[1].Value); } //+------------------------------------------------------------------+
Risk warning: Forex, spread bets and CFD are leveraged products. They may not be suitable for you as they carry a high degree of risk to your capital and you can lose more than your initial investment. You should ensure you understand all of the risks.
Copyright © 2006 - 2017, Miroslav Popov; Created by Yavor Kirov