Adaptable MACD by footon

45054 downloads / 4603 views / Created: 24.05.2013
 Average Rating: 0

Indicator Description

Adaptable MACD

Forum link: Footon's indi corner

Comments

Naming bug fixed, thanks Jetaro for the report!
//============================================================== // Forex Strategy Builder // Copyright (c) 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 AdaptableMACD : Indicator { public AdaptableMACD() { IndicatorName = "Adaptable MACD"; PossibleSlots = SlotTypes.OpenFilter | SlotTypes.CloseFilter; SeparatedChart = true; IndicatorAuthor = "Footon"; IndicatorVersion = "2.0"; IndicatorDescription = "Footon's indi corner: custom indicators for FSB and FST."; } public override void Initialize(SlotTypes slotType) { SlotType = slotType; // The ComboBox parameters IndParam.ListParam[0].Caption = "Logic"; IndParam.ListParam[0].ItemList = new string[] { "MACD line rises", "MACD line falls", "MACD line is higher than zero", "MACD line is lower than zero", "MACD line crosses the zero line upward", "MACD line crosses the zero line downward", "MACD line changes its direction upward", "MACD line changes its direction downward", "MACD line crosses the Signal line upward", "MACD line crosses the Signal line downward", "MACD line is higher than the Signal line", "MACD line is lower than the Signal line" }; 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 = "Short 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 smoothing method of Moving Averages."; IndParam.ListParam[4].Caption = "Long method method"; IndParam.ListParam[4].ItemList = Enum.GetNames(typeof(MAMethod)); IndParam.ListParam[4].Index = (int)MAMethod.Exponential; IndParam.ListParam[4].Text = IndParam.ListParam[4].ItemList[IndParam.ListParam[4].Index]; IndParam.ListParam[4].Enabled = true; IndParam.ListParam[4].ToolTip = "The smoothing method of Moving Averages."; 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 Moving Averages are based on."; IndParam.ListParam[3].Caption = "Signal line method"; IndParam.ListParam[3].ItemList = Enum.GetNames(typeof(MAMethod)); IndParam.ListParam[3].Index = (int)MAMethod.Simple; IndParam.ListParam[3].Text = IndParam.ListParam[3].ItemList[IndParam.ListParam[3].Index]; IndParam.ListParam[3].Enabled = true; IndParam.ListParam[3].ToolTip = "The smoothing method of the signal line."; // The NumericUpDown parameters IndParam.NumParam[0].Caption = "Slow MA period"; IndParam.NumParam[0].Value = 26; IndParam.NumParam[0].Min = 1; IndParam.NumParam[0].Max = 200; IndParam.NumParam[0].Enabled = true; IndParam.NumParam[0].ToolTip = "The period of Slow MA."; IndParam.NumParam[1].Caption = "Fast MA period"; IndParam.NumParam[1].Value = 12; IndParam.NumParam[1].Min = 1; IndParam.NumParam[1].Max = 200; IndParam.NumParam[1].Enabled = true; IndParam.NumParam[1].ToolTip = "The period of Fast MA."; IndParam.NumParam[2].Caption = "Signal line period"; IndParam.NumParam[2].Value = 9; IndParam.NumParam[2].Min = 1; IndParam.NumParam[2].Max = 200; IndParam.NumParam[2].Enabled = true; IndParam.NumParam[2].ToolTip = "The period of Signal line."; IndParam.NumParam[5].Caption = "AbsoluteValue"; IndParam.NumParam[5].Value = 1; IndParam.NumParam[5].Min = 0; IndParam.NumParam[5].Max = 1; IndParam.NumParam[5].Enabled = true; IndParam.NumParam[5].ToolTip = "AbsoluteValue"; // The CheckBox parameters IndParam.CheckParam[0].Caption = "Use previous bar value"; IndParam.CheckParam[0].Enabled = true; IndParam.CheckParam[0].ToolTip = "Use the indicator value from the previous bar."; return; } public override void Calculate(IDataSet dataSet) { DataSet = dataSet; // Reading the parameters MAMethod shortmaMethod = (MAMethod )IndParam.ListParam[1].Index; MAMethod longmaMethod = (MAMethod )IndParam.ListParam[4].Index; MAMethod slMethod = (MAMethod )IndParam.ListParam[3].Index; BasePrice basePrice = (BasePrice)IndParam.ListParam[2].Index; int nSlow = (int)IndParam.NumParam[1].Value; int nFast = (int)IndParam.NumParam[0].Value; int nSignal = (int)IndParam.NumParam[2].Value; int iPrvs = IndParam.CheckParam[0].Checked ? 1 : 0; int AbsoluteValue = (int)IndParam.NumParam[5].Value; // Calculation int iFirstBar = nSlow + nFast + 3; double[] adMASlow = MovingAverage(nSlow, 0, shortmaMethod, Price(basePrice)); double[] adMAFast = MovingAverage(nFast, 0, longmaMethod, Price(basePrice)); double[] adMACD = new double[Bars]; for (int iBar = iFirstBar; iBar < Bars; iBar++) { if (AbsoluteValue == 1) { adMACD[iBar] = adMASlow[iBar]-adMAFast[iBar]; } else { if (adMAFast[iBar]!=0) adMACD[iBar] = (adMASlow[iBar]-adMAFast[iBar])/adMAFast[iBar]; } } double[] maSignalLine = MovingAverage(nSignal, 0, slMethod, adMACD); // adHistogram represents the MACD oscillator double[] adHistogram = new double[Bars]; for (int iBar = nSlow + nSignal - 1; iBar < Bars; iBar++) adHistogram[iBar] = adMACD[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 = adHistogram; Component[1] = new IndicatorComp(); Component[1].CompName = "Signal line"; Component[1].DataType = IndComponentType.IndicatorValue; Component[1].ChartType = IndChartType.Line; Component[1].ChartColor = Color.Gold; 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 = adMACD; Component[3] = new IndicatorComp(); Component[3].ChartType = IndChartType.NoChart; Component[3].FirstBar = iFirstBar; Component[3].Value = new double[Bars]; Component[4] = new IndicatorComp(); Component[4].ChartType = IndChartType.NoChart; Component[4].FirstBar = iFirstBar; Component[4].Value = new double[Bars]; // Sets the Component's type if (SlotType == SlotTypes.OpenFilter) { Component[3].DataType = IndComponentType.AllowOpenLong; Component[3].CompName = "Is long entry allowed"; Component[4].DataType = IndComponentType.AllowOpenShort; Component[4].CompName = "Is short entry allowed"; } else if (SlotType == SlotTypes.CloseFilter) { Component[3].DataType = IndComponentType.ForceCloseLong; Component[3].CompName = "Close out long position"; Component[4].DataType = IndComponentType.ForceCloseShort; Component[4].CompName = "Close out short position"; } switch (IndParam.ListParam[0].Text) { case "MACD line rises": OscillatorLogic(iFirstBar, iPrvs, adMACD, 0, 0, ref Component[3], ref Component[4], IndicatorLogic.The_indicator_rises); break; case "MACD line falls": OscillatorLogic(iFirstBar, iPrvs, adMACD, 0, 0, ref Component[3], ref Component[4], IndicatorLogic.The_indicator_falls); break; case "MACD line is higher than zero": OscillatorLogic(iFirstBar, iPrvs, adMACD, 0, 0, ref Component[3], ref Component[4], IndicatorLogic.The_indicator_is_higher_than_the_level_line); break; case "MACD line is lower than zero": OscillatorLogic(iFirstBar, iPrvs, adMACD, 0, 0, ref Component[3], ref Component[4], IndicatorLogic.The_indicator_is_lower_than_the_level_line); break; case "MACD line crosses the zero line upward": OscillatorLogic(iFirstBar, iPrvs, adMACD, 0, 0, ref Component[3], ref Component[4], IndicatorLogic.The_indicator_crosses_the_level_line_upward); break; case "MACD line crosses the zero line downward": OscillatorLogic(iFirstBar, iPrvs, adMACD, 0, 0, ref Component[3], ref Component[4], IndicatorLogic.The_indicator_crosses_the_level_line_downward); break; case "MACD line changes its direction upward": OscillatorLogic(iFirstBar, iPrvs, adMACD, 0, 0, ref Component[3], ref Component[4], IndicatorLogic.The_indicator_changes_its_direction_upward); break; case "MACD line changes its direction downward": OscillatorLogic(iFirstBar, iPrvs, adMACD, 0, 0, ref Component[3], ref Component[4], IndicatorLogic.The_indicator_changes_its_direction_downward); break; case "MACD line crosses the Signal line upward": OscillatorLogic(iFirstBar, iPrvs, adHistogram, 0, 0, ref Component[3], ref Component[4], IndicatorLogic.The_indicator_crosses_the_level_line_upward); break; case "MACD line crosses the Signal line downward": OscillatorLogic(iFirstBar, iPrvs, adHistogram, 0, 0, ref Component[3], ref Component[4], IndicatorLogic.The_indicator_crosses_the_level_line_downward); break; case "MACD line is higher than the Signal line": OscillatorLogic(iFirstBar, iPrvs, adHistogram, 0, 0, ref Component[3], ref Component[4], IndicatorLogic.The_indicator_is_higher_than_the_level_line); break; case "MACD line is lower than the Signal line": OscillatorLogic(iFirstBar, iPrvs, adHistogram, 0, 0, ref Component[3], ref Component[4], IndicatorLogic.The_indicator_is_lower_than_the_level_line); break; default: break; } return; } /// /// Sets the indicator logic description /// public override void SetDescription() { EntryFilterLongDescription = ToString() + "; the MACD line "; EntryFilterShortDescription = ToString() + "; the MACD line "; ExitFilterLongDescription = ToString() + "; the MACD line "; ExitFilterShortDescription = ToString() + "; the MACD line "; switch (IndParam.ListParam[0].Text) { case "MACD line rises": EntryFilterLongDescription += "rises"; EntryFilterShortDescription += "falls"; ExitFilterLongDescription += "rises"; ExitFilterShortDescription += "falls"; break; case "MACD line falls": EntryFilterLongDescription += "falls"; EntryFilterShortDescription += "rises"; ExitFilterLongDescription += "falls"; ExitFilterShortDescription += "rises"; break; case "MACD line is higher than zero": EntryFilterLongDescription += "is higher than the zero line"; EntryFilterShortDescription += "is lower than the zero line"; ExitFilterLongDescription += "is higher than the zero line"; ExitFilterShortDescription += "is lower than the zero line"; break; case "MACD line is lower than zero": EntryFilterLongDescription += "is lower than the zero line"; EntryFilterShortDescription += "is higher than the zero line"; ExitFilterLongDescription += "is lower than the zero line"; ExitFilterShortDescription += "is higher than the zero line"; break; case "MACD line crosses the zero line upward": EntryFilterLongDescription += "crosses the zero line upward"; EntryFilterShortDescription += "crosses the zero line downward"; ExitFilterLongDescription += "crosses the zero line upward"; ExitFilterShortDescription += "crosses the zero line downward"; break; case "MACD line crosses the zero line downward": EntryFilterLongDescription += "crosses the zero line downward"; EntryFilterShortDescription += "crosses the zero line upward"; ExitFilterLongDescription += "crosses the zero line downward"; ExitFilterShortDescription += "crosses the zero line upward"; break; case "MACD line changes its direction upward": EntryFilterLongDescription += "changes its direction upward"; EntryFilterShortDescription += "changes its direction downward"; ExitFilterLongDescription += "changes its direction upward"; ExitFilterShortDescription += "changes its direction downward"; break; case "MACD line changes its direction downward": EntryFilterLongDescription += "changes its direction downward"; EntryFilterShortDescription += "changes its direction upward"; ExitFilterLongDescription += "changes its direction downward"; ExitFilterShortDescription += "changes its direction upward"; break; case "MACD line is higher than the Signal line": EntryFilterLongDescription += "is higher than the Signal line"; EntryFilterShortDescription += "is lower than the Signal line"; ExitFilterLongDescription += "is higher than the Signal line"; ExitFilterShortDescription += "is lower than the Signal line"; break; case "MACD line is lower than the Signal line": EntryFilterLongDescription += "is lower than the Signal line"; EntryFilterShortDescription += "is higher than the Signal line"; ExitFilterLongDescription += "is lower than the Signal line"; ExitFilterShortDescription += "is higher than the Signal line"; break; case "MACD line crosses the Signal line upward": EntryFilterLongDescription += "crosses the Signal line upward"; EntryFilterShortDescription += "crosses the Signal line downward"; ExitFilterLongDescription += "crosses the Signal line upward"; ExitFilterShortDescription += "crosses the Signal line downward"; break; case "MACD line crosses the Signal line downward": EntryFilterLongDescription += "crosses the Signal line downward"; EntryFilterShortDescription += "crosses the Signal line upward"; ExitFilterLongDescription += "crosses the Signal line downward"; ExitFilterShortDescription += "crosses the Signal line upward"; break; default: break; } return; } /// /// Indicator to string /// public override string ToString() { string sString = IndicatorName + (IndParam.CheckParam[0].Checked ? "* (" : " (") + IndParam.ListParam[1].Text + ", " + // Method IndParam.ListParam[2].Text + ", " + // Price IndParam.ListParam[3].Text + ", " + // Signal MA Method IndParam.NumParam[0].ValueToString + ", " + // Slow MA period IndParam.NumParam[1].ValueToString + ", " + // Fast MA period IndParam.NumParam[2].ValueToString + ")"; // Signal MA period return sString; } } }
//+--------------------------------------------------------------------+ //| 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 AdaptableMACD : public Indicator { public: AdaptableMACD(SlotTypes slotType) { SlotType=slotType; IndicatorName="Adaptable MACD"; WarningMessage = ""; IsAllowLTF = true; ExecTime = ExecutionTime_DuringTheBar; IsSeparateChart = true; IsDiscreteValues = false; IsDeafultGroupAll = false; } virtual void Calculate(DataSet &dataSet); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void AdaptableMACD::Calculate(DataSet &dataSet) { Data=GetPointer(dataSet); // Reading the parameters MAMethod shortmaMethod=(MAMethod)ListParam[1].Index; MAMethod longmaMethod =(MAMethod)ListParam[4].Index; MAMethod slMethod=(MAMethod)ListParam[3].Index; BasePrice basePrice=(BasePrice)ListParam[2].Index; int nSlow = (int)NumParam[1].Value; int nFast = (int)NumParam[0].Value; int nSignal=(int)NumParam[2].Value; int iPrvs=CheckParam[0].Checked ? 1 : 0; int AbsoluteValue=(int)NumParam[5].Value; // Calculation int iFirstBar=nSlow+nFast+3; double basePrc[]; Price(basePrice,basePrc); double adMASlow[]; MovingAverage(nSlow,0,shortmaMethod,basePrc,adMASlow); double adMAFast[]; MovingAverage(nFast,0,longmaMethod,basePrc,adMAFast); double adMACD[]; ArrayResize(adMACD,Data.Bars); ArrayInitialize(adMACD, 0); for(int iBar=iFirstBar; iBar<Data.Bars; iBar++) { if(AbsoluteValue==1) adMACD[iBar]=adMASlow[iBar]-adMAFast[iBar]; else if(adMAFast[iBar]!=0) adMACD[iBar]=(adMASlow[iBar]-adMAFast[iBar])/adMAFast[iBar]; } double maSignalLine[]; MovingAverage(nSignal,0,slMethod,adMACD,maSignalLine); // adHistogram represents the MACD oscillator double adHistogram[]; ArrayResize(adHistogram,Data.Bars); ArrayInitialize(adHistogram, 0); for(int iBar=nSlow+nSignal-1; iBar<Data.Bars; iBar++) adHistogram[iBar]=adMACD[iBar]-maSignalLine[iBar]; // Saving the components ArrayResize(Component[0].Value,Data.Bars); Component[0].CompName = "Histogram"; Component[0].DataType = IndComponentType_IndicatorValue; Component[0].FirstBar = iFirstBar; ArrayCopy(Component[0].Value,adHistogram); ArrayResize(Component[1].Value,Data.Bars); Component[1].CompName = "Signal line"; Component[1].DataType = IndComponentType_IndicatorValue; Component[1].FirstBar = iFirstBar; ArrayCopy(Component[1].Value,maSignalLine); ArrayResize(Component[2].Value,Data.Bars); Component[2].CompName = "MACD line"; Component[2].DataType = IndComponentType_IndicatorValue; Component[2].FirstBar = iFirstBar; ArrayCopy(Component[2].Value,adMACD); ArrayResize(Component[3].Value,Data.Bars); Component[3].FirstBar=iFirstBar; ArrayResize(Component[4].Value,Data.Bars); Component[4].FirstBar=iFirstBar; // Sets the Component's type if(SlotType==SlotTypes_OpenFilter) { Component[3].DataType = IndComponentType_AllowOpenLong; Component[3].CompName = "Is long entry allowed"; Component[4].DataType = IndComponentType_AllowOpenShort; Component[4].CompName = "Is short entry allowed"; } else if(SlotType==SlotTypes_CloseFilter) { Component[3].DataType = IndComponentType_ForceCloseLong; Component[3].CompName = "Close out long position"; Component[4].DataType = IndComponentType_ForceCloseShort; Component[4].CompName = "Close out short position"; } if(ListParam[0].Text=="MACD line rises") { OscillatorLogic(iFirstBar,iPrvs,adMACD,0,0,Component[3],Component[4],IndicatorLogic_The_indicator_rises); } else if(ListParam[0].Text=="MACD line falls") { OscillatorLogic(iFirstBar,iPrvs,adMACD,0,0,Component[3],Component[4],IndicatorLogic_The_indicator_falls); } else if(ListParam[0].Text=="MACD line is higher than zero") { OscillatorLogic(iFirstBar,iPrvs,adMACD,0,0,Component[3],Component[4],IndicatorLogic_The_indicator_is_higher_than_the_level_line); } else if(ListParam[0].Text=="MACD line is lower than zero") { OscillatorLogic(iFirstBar,iPrvs,adMACD,0,0,Component[3],Component[4],IndicatorLogic_The_indicator_is_lower_than_the_level_line); } else if(ListParam[0].Text=="MACD line crosses the zero line upward") { OscillatorLogic(iFirstBar,iPrvs,adMACD,0,0,Component[3],Component[4],IndicatorLogic_The_indicator_crosses_the_level_line_upward); } else if(ListParam[0].Text=="MACD line crosses the zero line downward") { OscillatorLogic(iFirstBar,iPrvs,adMACD,0,0,Component[3],Component[4],IndicatorLogic_The_indicator_crosses_the_level_line_downward); } else if(ListParam[0].Text=="MACD line changes its direction upward") { OscillatorLogic(iFirstBar,iPrvs,adMACD,0,0,Component[3],Component[4],IndicatorLogic_The_indicator_changes_its_direction_upward); } else if(ListParam[0].Text=="MACD line changes its direction downward") { OscillatorLogic(iFirstBar,iPrvs,adMACD,0,0,Component[3],Component[4],IndicatorLogic_The_indicator_changes_its_direction_downward); } else if(ListParam[0].Text=="MACD line crosses the Signal line upward") { OscillatorLogic(iFirstBar,iPrvs,adHistogram,0,0,Component[3],Component[4],IndicatorLogic_The_indicator_crosses_the_level_line_upward); } else if(ListParam[0].Text=="MACD line crosses the Signal line downward") { OscillatorLogic(iFirstBar,iPrvs,adHistogram,0,0,Component[3],Component[4],IndicatorLogic_The_indicator_crosses_the_level_line_downward); } else if(ListParam[0].Text=="MACD line is higher than the Signal line") { OscillatorLogic(iFirstBar,iPrvs,adHistogram,0,0,Component[3],Component[4],IndicatorLogic_The_indicator_is_higher_than_the_level_line); } else if(ListParam[0].Text=="MACD line is lower than the Signal line") { OscillatorLogic(iFirstBar,iPrvs,adHistogram,0,0,Component[3],Component[4],IndicatorLogic_The_indicator_is_lower_than_the_level_line); } } //+------------------------------------------------------------------+
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 - 2024, Forex Software Ltd.;