Keltner Channel Crossover by slipshod

43891 downloads / 3950 views / Created: 23.05.2013
 Average Rating: 5

Indicator Description

Used for filtering based on crossover of two channels, or of a channel being above or below another.

keltner cross

keltner cross chart

Developed with considerable help from Mr Popov :)

Forum link: Keltner Channel Crossover

Comments

Indicator was updated to v2.4.

Changes: Removed unused components representing Central MA of both bands.

MQL code updated. Fixed a typo in the logic rules that blocked indicator from trading.
Indicator works only on Close price. Other base prices were removed because of wrong set of "Use previous bar value".
Indicator updated to v2.5
Changes: return of all available baseprices, fix of ATR calculation.
//============================================================== // 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 KeltnerChannel : Indicator { public KeltnerChannel() { IndicatorName = "Keltner Channel Crossover"; PossibleSlots = SlotTypes.OpenFilter | SlotTypes.CloseFilter; IndicatorAuthor = "Andrew Sumner"; IndicatorVersion = "2.5"; IndicatorDescription = "Compares channels."; } public override void Initialize(SlotTypes slotType) { SlotType = slotType; // The ComboBox parameters IndParam.ListParam[0].Caption = "Logic"; IndParam.ListParam[0].ItemList = new[] { "Fast Channel High crosses Slow Channel Low upward", "Fast Channel High crosses Slow Channel Low downward", "Fast Channel High crosses Slow Channel High upward", "Fast Channel High crosses Slow Channel High downward", "Fast Channel Low crosses Slow Channel Low upward", "Fast Channel Low crosses Slow Channel Low downward", "Fast Channel Low crosses Slow Channel High upward", "Fast Channel Low crosses Slow Channel High downward", "Fast Channel High is higher than Slow Channel Low", "Fast Channel High is higher than Slow Channel High", "Fast Channel Low is higher than Slow Channel Low", "Fast Channel Low is higher than Slow Channel High", "Fast Channel High is lower than Slow Channel Low", "Fast Channel High is lower than Slow Channel High", "Fast Channel Low is lower than Slow Channel Low", "Fast Channel Low is lower than Slow Channel High" }; 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[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 central Moving Average is based on."; IndParam.ListParam[3].Caption = "Fast Channel MA method"; IndParam.ListParam[3].ItemList = Enum.GetNames(typeof (MAMethod)); IndParam.ListParam[3].Index = (int) MAMethod.Exponential; IndParam.ListParam[3].Text = IndParam.ListParam[3].ItemList[IndParam.ListParam[3].Index]; IndParam.ListParam[3].Enabled = true; IndParam.ListParam[3].ToolTip = "The method of smoothing of Fast central Moving Average."; IndParam.ListParam[4].Caption = "Slow Channel MA 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 method of smoothing of Slow central Moving Average."; // The NumericUpDown parameters IndParam.NumParam[0].Caption = "Fast MA period"; IndParam.NumParam[0].Value = 10; IndParam.NumParam[0].Min = 1; IndParam.NumParam[0].Max = 400; IndParam.NumParam[0].Enabled = true; IndParam.NumParam[0].ToolTip = "The Slow Moving Average period."; IndParam.NumParam[1].Caption = "Slow MA period"; IndParam.NumParam[1].Value = 40; IndParam.NumParam[1].Min = 1; IndParam.NumParam[1].Max = 400; IndParam.NumParam[1].Enabled = true; IndParam.NumParam[1].ToolTip = "The Slow Moving Average period."; IndParam.NumParam[2].Caption = "Fast ATR period"; IndParam.NumParam[2].Value = 5; IndParam.NumParam[2].Min = 1; IndParam.NumParam[2].Max = 200; IndParam.NumParam[2].Point = 0; IndParam.NumParam[2].Enabled = true; IndParam.NumParam[2].ToolTip = "Fast Average True Range Period."; IndParam.NumParam[3].Caption = "Slow ATR period"; IndParam.NumParam[3].Value = 10; IndParam.NumParam[3].Min = 1; IndParam.NumParam[3].Max = 200; IndParam.NumParam[3].Point = 0; IndParam.NumParam[3].Enabled = true; IndParam.NumParam[3].ToolTip = "Slow Average True Range Period."; IndParam.NumParam[4].Caption = "Fast ATR multiplier"; IndParam.NumParam[4].Value = 2; IndParam.NumParam[4].Min = 0.1; IndParam.NumParam[4].Max = 10; IndParam.NumParam[4].Point = 1; IndParam.NumParam[4].Enabled = true; IndParam.NumParam[4].ToolTip = "Fast Average True Range Multiplier."; IndParam.NumParam[5].Caption = "Slow ATR multiplier"; IndParam.NumParam[5].Value = 2; IndParam.NumParam[5].Min = 0.1; IndParam.NumParam[5].Max = 10; IndParam.NumParam[5].Point = 1; IndParam.NumParam[5].Enabled = true; IndParam.NumParam[5].ToolTip = "Fast Average True Range Multiplier."; // 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."; } public override void Calculate(IDataSet dataSet) { DataSet = dataSet; // Reading the parameters var price = (BasePrice) IndParam.ListParam[2].Index; var fastmaMethod = (MAMethod) IndParam.ListParam[3].Index; var fastnMA = (int) IndParam.NumParam[0].Value; var fastatrPeriod = (int) IndParam.NumParam[2].Value; var fastatrMultiplier = (double) IndParam.NumParam[4].Value; var slowmaMethod = (MAMethod) IndParam.ListParam[4].Index; var slownMA = (int) IndParam.NumParam[1].Value; var slowatrPeriod = (int) IndParam.NumParam[3].Value; var slowatrMultiplier = (double) IndParam.NumParam[5].Value; int previous = IndParam.CheckParam[0].Checked ? 1 : 0; // Calculation int iFirstBar = Math.Max(Math.Max(fastnMA, fastatrPeriod), Math.Max(slownMA, slowatrPeriod)) + previous + 2; double[] adMAFast = MovingAverage(fastnMA, 0, fastmaMethod, Price(price)); var adAtrFast = new double[Bars]; var adUpBandFast = new double[Bars]; var adDnBandFast = new double[Bars]; double[] adMASlow = MovingAverage(slownMA, 0, slowmaMethod, Price(price)); var adAtrSlow = new double[Bars]; var adUpBandSlow = new double[Bars]; var adDnBandSlow = new double[Bars]; for (int iBar = 3; iBar < Bars; iBar++) { adAtrFast[iBar] = Math.Max(Math.Abs(High[iBar-1] - Close[iBar - 2]), Math.Abs(Close[iBar - 2] - Low[iBar-1])); adAtrFast[iBar] = Math.Max(Math.Abs(High[iBar-1] - Low[iBar-1]), adAtrFast[iBar]); adAtrSlow[iBar] = Math.Max(Math.Abs(High[iBar-1] - Close[iBar - 2]), Math.Abs(Close[iBar - 2] - Low[iBar-1])); adAtrSlow[iBar] = Math.Max(Math.Abs(High[iBar-1] - Low[iBar-1]), adAtrSlow[iBar]); } adAtrFast = MovingAverage(fastatrPeriod, 0, fastmaMethod, adAtrFast); adAtrSlow = MovingAverage(slowatrPeriod, 0, slowmaMethod, adAtrSlow); for (int iBar = Math.Max(fastnMA, slownMA); iBar < Bars; iBar++) { adUpBandFast[iBar] = adMAFast[iBar] + adAtrFast[iBar]*fastatrMultiplier; adDnBandFast[iBar] = adMAFast[iBar] - adAtrFast[iBar]*fastatrMultiplier; adUpBandSlow[iBar] = adMASlow[iBar] + adAtrSlow[iBar]*slowatrMultiplier; adDnBandSlow[iBar] = adMASlow[iBar] - adAtrSlow[iBar]*slowatrMultiplier; } // Saving the components Component = new IndicatorComp[7]; Component[0] = new IndicatorComp { CompName = "Fast Upper Band", DataType = IndComponentType.IndicatorValue, ChartType = IndChartType.Line, ChartColor = Color.Blue, FirstBar = iFirstBar, Value = adUpBandFast }; Component[1] = new IndicatorComp { CompName = "Slow Upper Band", DataType = IndComponentType.IndicatorValue, ChartType = IndChartType.Line, ChartColor = Color.Brown, FirstBar = iFirstBar, Value = adUpBandSlow }; Component[2] = new IndicatorComp { CompName = "Fast Lower Band", DataType = IndComponentType.IndicatorValue, ChartType = IndChartType.Line, ChartColor = Color.Blue, FirstBar = iFirstBar, Value = adDnBandFast }; Component[3] = new IndicatorComp { CompName = "Slow Lower Band", DataType = IndComponentType.IndicatorValue, ChartType = IndChartType.Line, ChartColor = Color.Brown, FirstBar = iFirstBar, Value = adDnBandSlow }; Component[4] = new IndicatorComp { ChartType = IndChartType.NoChart, FirstBar = iFirstBar, Value = new double[Bars] }; Component[5] = new IndicatorComp { ChartType = IndChartType.NoChart, FirstBar = iFirstBar, Value = new double[Bars] }; Component[6] = new IndicatorComp { CompName = "Dummy component", ShowInDynInfo = false, ChartType = IndChartType.NoChart, FirstBar = iFirstBar, DataType = IndComponentType.IndicatorValue, Value = new double[Bars] }; // Sets the Component's type if (SlotType == SlotTypes.OpenFilter) { Component[4].DataType = IndComponentType.AllowOpenLong; Component[4].CompName = "Is long entry allowed"; Component[5].DataType = IndComponentType.AllowOpenShort; Component[5].CompName = "Is short entry allowed"; } else if (SlotType == SlotTypes.CloseFilter) { Component[4].DataType = IndComponentType.ForceCloseLong; Component[4].CompName = "Close out long position"; Component[5].DataType = IndComponentType.ForceCloseShort; Component[5].CompName = "Close out short position"; } switch (IndParam.ListParam[0].Text) { case "Fast Channel High crosses Slow Channel Low upward": IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar, previous, adUpBandFast, adDnBandSlow, ref Component[4], ref Component[6]); IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar, previous, adDnBandFast, adUpBandSlow, ref Component[6], ref Component[5]); break; case "Fast Channel High crosses Slow Channel High upward": IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar, previous, adUpBandFast, adUpBandSlow, ref Component[4], ref Component[6]); IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar, previous, adDnBandFast, adDnBandSlow, ref Component[6], ref Component[5]); break; case "Fast Channel Low crosses Slow Channel Low upward": IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar, previous, adDnBandFast, adDnBandSlow, ref Component[4], ref Component[6]); IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar, previous, adUpBandFast, adUpBandSlow, ref Component[6], ref Component[5]); break; case "Fast Channel Low crosses Slow Channel High upward": IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar, previous, adDnBandFast, adUpBandSlow, ref Component[4], ref Component[6]); IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar, previous, adUpBandFast, adDnBandSlow, ref Component[6], ref Component[5]); break; case "Fast Channel High crosses Slow Channel Low downward": IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar, previous, adUpBandFast, adDnBandSlow, ref Component[4], ref Component[6]); IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar, previous, adDnBandFast, adUpBandSlow, ref Component[6], ref Component[5]); break; case "Fast Channel High crosses Slow Channel High downward": IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar, previous, adUpBandFast, adUpBandSlow, ref Component[4], ref Component[6]); IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar, previous, adDnBandFast, adDnBandSlow, ref Component[6], ref Component[5]); break; case "Fast Channel Low crosses Slow Channel Low downward": IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar, previous, adDnBandFast, adDnBandSlow, ref Component[4], ref Component[6]); IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar, previous, adUpBandFast, adUpBandSlow, ref Component[6], ref Component[5]); break; case "Fast Channel Low crosses Slow Channel High downward": IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar, previous, adDnBandFast, adUpBandSlow, ref Component[4], ref Component[6]); IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar, previous, adUpBandFast, adDnBandSlow, ref Component[6], ref Component[5]); break; case "Fast Channel High is higher than Slow Channel Low": IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar, previous, adUpBandFast, adDnBandSlow, ref Component[4], ref Component[6]); IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar, previous, adUpBandFast, adDnBandSlow, ref Component[6], ref Component[5]); break; case "Fast Channel High is higher than Slow Channel High": IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar, previous, adUpBandFast, adUpBandSlow, ref Component[4], ref Component[6]); IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar, previous, adDnBandFast, adDnBandSlow, ref Component[6], ref Component[5]); break; case "Fast Channel Low is higher than Slow Channel Low": IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar, previous, adDnBandFast, adDnBandSlow, ref Component[4], ref Component[6]); IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar, previous, adUpBandFast, adUpBandSlow, ref Component[6], ref Component[5]); break; case "Fast Channel Low is higher than Slow Channel High": IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar, previous, adDnBandFast, adUpBandSlow, ref Component[4], ref Component[6]); IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar, previous, adUpBandFast, adDnBandSlow, ref Component[6], ref Component[5]); break; case "Fast Channel High is lower than Slow Channel Low": IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar, previous, adUpBandFast, adDnBandSlow, ref Component[4], ref Component[6]); IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar, previous, adDnBandFast, adUpBandSlow, ref Component[6], ref Component[5]); break; case "Fast Channel High is lower than Slow Channel High": IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar, previous, adUpBandFast, adUpBandSlow, ref Component[4], ref Component[6]); IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar, previous, adDnBandFast, adDnBandSlow, ref Component[6], ref Component[5]); break; case "Fast Channel Low is lower than Slow Channel Low": IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar, previous, adDnBandFast, adDnBandSlow, ref Component[4], ref Component[6]); IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar, previous, adUpBandFast, adUpBandSlow, ref Component[6], ref Component[5]); break; case "Fast Channel Low is lower than Slow Channel High": IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar, previous, adUpBandFast, adDnBandSlow, ref Component[4], ref Component[6]); IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar, previous, adDnBandFast, adUpBandSlow, ref Component[6], ref Component[5]); break; } } public override void SetDescription() { EntryFilterLongDescription = ToString() + "; Fast Channel "; EntryFilterShortDescription = ToString() + "; Fast Channel "; ExitFilterLongDescription = ToString() + "; Fast Channel "; ExitFilterShortDescription = ToString() + "; Fast Channel "; switch (IndParam.ListParam[0].Text) { case "Fast Channel High crosses Slow Channel Low upward": EntryFilterLongDescription += "High crosses above Slow Channel Low"; EntryFilterShortDescription = "High crosses under Slow Channel Low"; ExitFilterLongDescription += "High crosses above Slow Channel Low"; ExitFilterShortDescription = "High crosses under Slow Channel Low"; break; case "Fast Channel High crosses Slow Channel High upward": EntryFilterLongDescription += "High crosses above Slow Channel High"; EntryFilterShortDescription = "High crosses under Slow Channel High"; ExitFilterLongDescription += "High crosses above Slow Channel High"; ExitFilterShortDescription = "High crosses under Slow Channel High"; break; case "Fast Channel Low crosses Slow Channel Low upward": EntryFilterLongDescription += "Low crosses above Slow Channel Low"; EntryFilterShortDescription = "Low crosses under Slow Channel Low"; ExitFilterLongDescription += "Low crosses above Slow Channel Low"; ExitFilterShortDescription = "Low crosses under Slow Channel Low"; break; case "Fast Channel Low crosses Slow Channel High upward": EntryFilterLongDescription += "Low crosses above Slow Channel High"; EntryFilterShortDescription = "Low crosses under Slow Channel High"; ExitFilterLongDescription += "Low crosses above Slow Channel High"; ExitFilterShortDescription = "Low crosses under Slow Channel High"; break; case "Fast Channel High crosses Slow Channel Low downward": EntryFilterLongDescription += "High crosses under Slow Channel Low"; EntryFilterShortDescription = "High crosses above Slow Channel Low"; ExitFilterLongDescription += "High crosses under Slow Channel Low"; ExitFilterShortDescription = "High crosses above Slow Channel Low"; break; case "Fast Channel High crosses Slow Channel High downward": EntryFilterLongDescription += "High crosses under Slow Channel High"; EntryFilterShortDescription = "High crosses above Slow Channel High"; ExitFilterLongDescription += "High crosses under Slow Channel High"; ExitFilterShortDescription = "High crosses above Slow Channel High"; break; case "Fast Channel Low crosses Slow Channel Low downward": EntryFilterLongDescription += "Low crosses under Slow Channel Low"; EntryFilterShortDescription = "Low crosses above Slow Channel Low"; ExitFilterLongDescription += "Low crosses under Slow Channel Low"; ExitFilterShortDescription = "Low crosses above Slow Channel Low"; break; case "Fast Channel Low crosses Slow Channel High downward": EntryFilterLongDescription += "Low crosses under Slow Channel High"; EntryFilterShortDescription = "Low crosses above Slow Channel High"; ExitFilterLongDescription += "Low crosses under Slow Channel High"; ExitFilterShortDescription = "Low crosses above Slow Channel High"; break; case "Fast Channel High is higher than Slow Channel Low": EntryFilterLongDescription += "High is above Slow Channel Low"; EntryFilterShortDescription = "High is under Slow Channel Low"; ExitFilterLongDescription += "High is above Slow Channel Low"; ExitFilterShortDescription = "High is under Slow Channel Low"; break; case "Fast Channel High is higher than Slow Channel High": EntryFilterLongDescription += "High is above Slow Channel High"; EntryFilterShortDescription = "High is under Slow Channel High"; ExitFilterLongDescription += "High is above Slow Channel High"; ExitFilterShortDescription = "High is under Slow Channel High"; break; case "Fast Channel Low is higher than Slow Channel Low": EntryFilterLongDescription += "Low is above Slow Channel Low"; EntryFilterShortDescription = "Low is under Slow Channel Low"; ExitFilterLongDescription += "Low is above Slow Channel Low"; ExitFilterShortDescription = "Low is under Slow Channel Low"; break; case "Fast Channel Low is higher than Slow Channel High": EntryFilterLongDescription += "Low is above Slow Channel High"; EntryFilterShortDescription = "Low is under Slow Channel High"; ExitFilterLongDescription += "Low is above Slow Channel High"; ExitFilterShortDescription = "Low is under Slow Channel High"; break; case "Fast Channel High is lower than Slow Channel Low": EntryFilterLongDescription += "High is under Slow Channel Low"; EntryFilterShortDescription = "High is above Slow Channel Low"; ExitFilterLongDescription += "High is under Slow Channel Low"; ExitFilterShortDescription = "High is above Slow Channel Low"; break; case "Fast Channel High is lower than Slow Channel High": EntryFilterLongDescription += "High is under Slow Channel High"; EntryFilterShortDescription = "High is above Slow Channel High"; ExitFilterLongDescription += "High is under Slow Channel High"; ExitFilterShortDescription = "High is above Slow Channel High"; break; case "Fast Channel Low is lower than Slow Channel Low": EntryFilterLongDescription += "Low is under Slow Channel High"; EntryFilterShortDescription = "Low is above Slow Channel High"; ExitFilterLongDescription += "Low is under Slow Channel High"; ExitFilterShortDescription = "Low is above Slow Channel High"; break; case "Fast Channel Low is lower than Slow Channel High": EntryFilterLongDescription += "Low is under Slow Channel High"; EntryFilterShortDescription = "Low is above Slow Channel High"; ExitFilterLongDescription += "Low is under Slow Channel High"; ExitFilterShortDescription = "Low is above Slow Channel High"; break; } } public override string ToString() { return IndicatorName + (IndParam.CheckParam[0].Checked ? "* (" : " (") + IndParam.ListParam[1].Text + ", " + // Price IndParam.ListParam[3].Text + ", " + // Fast Price IndParam.ListParam[4].Text + ", " + // Slow Price IndParam.NumParam[0].ValueToString + ", " + // Fast MA period IndParam.NumParam[1].ValueToString + ")"; // Slow MA 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.10" #property strict #include <Forexsb.com/Indicator.mqh> #include <Forexsb.com/Enumerations.mqh> //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class KeltnerChannelCrossover : public Indicator { public: KeltnerChannelCrossover(SlotTypes slotType) { SlotType=slotType; IndicatorName="Keltner Channel Crossover"; WarningMessage = ""; IsAllowLTF = true; ExecTime = ExecutionTime_DuringTheBar; IsSeparateChart = false; IsDiscreteValues = false; IsDeafultGroupAll = false; } virtual void Calculate(DataSet &dataSet); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void KeltnerChannelCrossover::Calculate(DataSet &dataSet) { Data=GetPointer(dataSet); // Reading the parameters BasePrice price=(BasePrice) ListParam[2].Index; MAMethod fastmaMethod = (MAMethod) ListParam[3].Index; int fastnMA=(int) NumParam[0].Value; int fastatrPeriod=(int) NumParam[2].Value; double fastatrMultiplier=(double) NumParam[4].Value; MAMethod slowmaMethod=(MAMethod) ListParam[4].Index; int slownMA=(int) NumParam[1].Value; int slowatrPeriod=(int) NumParam[3].Value; double slowatrMultiplier=(double) NumParam[5].Value; int previous=CheckParam[0].Checked ? 1 : 0; // Calculation int iFirstBar=MathMax(MathMax(fastnMA,fastatrPeriod),MathMax(slownMA,slowatrPeriod))+previous+2; double basePrc[]; Price(price,basePrc); double adMAFast[]; MovingAverage(fastnMA,0,fastmaMethod,basePrc,adMAFast); double adAtrFast[]; ArrayResize(adAtrFast,Data.Bars); ArrayInitialize(adAtrFast, 0); double adUpBandFast[]; ArrayResize(adUpBandFast,Data.Bars); ArrayInitialize(adUpBandFast, 0); double adDnBandFast[]; ArrayResize(adDnBandFast,Data.Bars); ArrayInitialize(adDnBandFast, 0); double adMASlow[]; MovingAverage(slownMA,0,slowmaMethod,basePrc,adMASlow); double adAtrSlow[]; ArrayResize(adAtrSlow,Data.Bars); ArrayInitialize(adAtrSlow, 0); double adUpBandSlow[]; ArrayResize(adUpBandSlow,Data.Bars); ArrayInitialize(adUpBandSlow, 0); double adDnBandSlow[]; ArrayResize(adDnBandSlow,Data.Bars); ArrayInitialize(adDnBandSlow, 0); for(int iBar=3; iBar<Data.Bars; iBar++) { adAtrFast[iBar] = MathMax(MathAbs(Data.High[iBar-1] - Data.Close[iBar - 2]), MathAbs(Data.Close[iBar - 2] - Data.Low[iBar-1])); adAtrFast[iBar] = MathMax(MathAbs(Data.High[iBar-1] - Data.Low[iBar-1]), adAtrFast[iBar]); adAtrSlow[iBar] = MathMax(MathAbs(Data.High[iBar-1] - Data.Close[iBar - 2]), MathAbs(Data.Close[iBar - 2] - Data.Low[iBar-1])); adAtrSlow[iBar] = MathMax(MathAbs(Data.High[iBar-1] - Data.Low[iBar-1]), adAtrSlow[iBar]); } double adAtrFast1[]; MovingAverage(fastatrPeriod,0,fastmaMethod,adAtrFast,adAtrFast1); double adAtrSlow1[]; MovingAverage(slowatrPeriod,0,slowmaMethod,adAtrSlow,adAtrSlow1); for(int iBar=MathMax(fastnMA,slownMA); iBar<Data.Bars; iBar++) { adUpBandFast[iBar] = adMAFast[iBar] + adAtrFast1[iBar]*fastatrMultiplier; adDnBandFast[iBar] = adMAFast[iBar] - adAtrFast1[iBar]*fastatrMultiplier; adUpBandSlow[iBar] = adMASlow[iBar] + adAtrSlow1[iBar]*slowatrMultiplier; adDnBandSlow[iBar] = adMASlow[iBar] - adAtrSlow1[iBar]*slowatrMultiplier; } // Saving the components ArrayResize(Component[0].Value,Data.Bars); Component[0].CompName = "Fast Upper Band"; Component[0].DataType = IndComponentType_IndicatorValue; Component[0].FirstBar = iFirstBar; ArrayCopy(Component[0].Value,adUpBandFast); ArrayResize(Component[1].Value,Data.Bars); Component[1].CompName = "Slow Upper Band"; Component[1].DataType = IndComponentType_IndicatorValue; Component[1].FirstBar = iFirstBar; ArrayCopy(Component[1].Value,adUpBandSlow); ArrayResize(Component[2].Value,Data.Bars); Component[2].CompName = "Fast Lower Band"; Component[2].DataType = IndComponentType_IndicatorValue; Component[2].FirstBar = iFirstBar; ArrayCopy(Component[2].Value,adDnBandFast); ArrayResize(Component[3].Value,Data.Bars); Component[3].CompName = "Slow Lower Band"; Component[3].DataType = IndComponentType_IndicatorValue; Component[3].FirstBar = iFirstBar; ArrayCopy(Component[3].Value,adDnBandSlow); ArrayResize(Component[4].Value,Data.Bars); Component[4].FirstBar=iFirstBar; ArrayResize(Component[5].Value,Data.Bars); Component[5].FirstBar=iFirstBar; ArrayResize(Component[6].Value,Data.Bars); Component[6].CompName="Dummy component"; Component[6].ShowInDynInfo=false; Component[6].FirstBar = iFirstBar; Component[6].DataType = IndComponentType_IndicatorValue; // Sets the Component's type if(SlotType==SlotTypes_OpenFilter) { Component[4].DataType = IndComponentType_AllowOpenLong; Component[4].CompName = "Is long entry allowed"; Component[5].DataType = IndComponentType_AllowOpenShort; Component[5].CompName = "Is short entry allowed"; } else if(SlotType==SlotTypes_CloseFilter) { Component[4].DataType = IndComponentType_ForceCloseLong; Component[4].CompName = "Close out long position"; Component[5].DataType = IndComponentType_ForceCloseShort; Component[5].CompName = "Close out short position"; } if(ListParam[0].Text=="Fast Channel High crosses Slow Channel Low upward") { IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar,previous,adUpBandFast,adDnBandSlow, Component[4],Component[6]); IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar,previous,adDnBandFast,adUpBandSlow, Component[6],Component[5]); } else if(ListParam[0].Text=="Fast Channel High crosses Slow Channel High upward") { IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar,previous,adUpBandFast,adUpBandSlow, Component[4],Component[6]); IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar,previous,adDnBandFast,adDnBandSlow, Component[6],Component[5]); } else if(ListParam[0].Text=="Fast Channel Low crosses Slow Channel Low upward") { IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar,previous,adDnBandFast,adDnBandSlow, Component[4],Component[6]); IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar,previous,adUpBandFast,adUpBandSlow, Component[6],Component[5]); } else if(ListParam[0].Text=="Fast Channel Low crosses Slow Channel High upward") { IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar,previous,adDnBandFast,adUpBandSlow, Component[4],Component[6]); IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar,previous,adUpBandFast,adDnBandSlow, Component[6],Component[5]); } else if(ListParam[0].Text=="Fast Channel High crosses Slow Channel Low downward") { IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar,previous,adUpBandFast,adDnBandSlow, Component[4],Component[6]); IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar,previous,adDnBandFast,adUpBandSlow, Component[6],Component[5]); } else if(ListParam[0].Text=="Fast Channel High crosses Slow Channel High downward") { IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar,previous,adUpBandFast,adUpBandSlow, Component[4],Component[6]); IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar,previous,adDnBandFast,adDnBandSlow, Component[6],Component[5]); } else if(ListParam[0].Text=="Fast Channel Low crosses Slow Channel Low downward") { IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar,previous,adDnBandFast,adDnBandSlow, Component[4],Component[6]); IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar,previous,adUpBandFast,adUpBandSlow, Component[6],Component[5]); } else if(ListParam[0].Text=="Fast Channel Low crosses Slow Channel Data.High downward") { IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar,previous,adDnBandFast,adUpBandSlow, Component[4],Component[6]); IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar,previous,adUpBandFast,adDnBandSlow, Component[6],Component[5]); } else if(ListParam[0].Text=="Fast Channel High is higher than Slow Channel Low") { IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar,previous,adUpBandFast,adDnBandSlow, Component[4],Component[6]); IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar,previous,adUpBandFast,adDnBandSlow, Component[6],Component[5]); } else if(ListParam[0].Text=="Fast Channel High is higher than Slow Channel High") { IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar,previous,adUpBandFast,adUpBandSlow, Component[4],Component[6]); IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar,previous,adDnBandFast,adDnBandSlow, Component[6],Component[5]); } else if(ListParam[0].Text=="Fast Channel Low is higher than Slow Channel Low") { IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar,previous,adDnBandFast,adDnBandSlow, Component[4],Component[6]); IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar,previous,adUpBandFast,adUpBandSlow, Component[6],Component[5]); } else if(ListParam[0].Text=="Fast Channel Low is higher than Slow Channel High") { IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar,previous,adDnBandFast,adUpBandSlow, Component[4],Component[6]); IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar,previous,adUpBandFast,adDnBandSlow, Component[6],Component[5]); } else if(ListParam[0].Text=="Fast Channel High is lower than Slow Channel Low") { IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar,previous,adUpBandFast,adDnBandSlow, Component[4],Component[6]); IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar,previous,adDnBandFast,adUpBandSlow, Component[6],Component[5]); } else if(ListParam[0].Text=="Fast Channel High is lower than Slow Channel High") { IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar,previous,adUpBandFast,adUpBandSlow, Component[4],Component[6]); IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar,previous,adDnBandFast,adDnBandSlow, Component[6],Component[5]); } else if(ListParam[0].Text=="Fast Channel Low is lower than Slow Channel Low") { IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar,previous,adDnBandFast,adDnBandSlow, Component[4],Component[6]); IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar,previous,adUpBandFast,adUpBandSlow, Component[6],Component[5]); } else if(ListParam[0].Text=="Fast Channel Low is lower than Slow Channel High") { IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar,previous,adUpBandFast,adDnBandSlow, Component[4],Component[6]); IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar,previous,adDnBandFast,adUpBandSlow, Component[6],Component[5]); } } //+------------------------------------------------------------------+
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.;