Parabolic SAR Combo Crossover by ahmedalhoseny

46964 downloads / 5215 views / Created: 15.12.2013
 Average Rating: 5

Indicator Description

Parabolic SAR Combo Crossover

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 PsrCrossover : Indicator { public PsrCrossover() { IndicatorName = "Parabolic SAR Combo Crossover"; PossibleSlots = SlotTypes.OpenFilter | SlotTypes.CloseFilter; IndicatorAuthor = "Ahmed Alhoseny"; IndicatorVersion = "2.0"; IndicatorDescription = "Custom Indicator."; } public override void Initialize(SlotTypes slotType) { SlotType = slotType; // The ComboBox parameters IndParam.ListParam[0].Caption = "Logic"; IndParam.ListParam[0].ItemList = new[] { "Psar1 crosses Psar2 upward", "Psar1 crosses Psar2 downward", "Psar1 is higher than Psar2", "Psar1 is lower than Psar2" }; 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."; // The NumericUpDown parameters IndParam.NumParam[0].Caption = "Starting AF1"; IndParam.NumParam[0].Value = 0.02; IndParam.NumParam[0].Min = 0.00; IndParam.NumParam[0].Max = 1.00; IndParam.NumParam[0].Point = 2; IndParam.NumParam[0].Enabled = true; IndParam.NumParam[0].ToolTip = "The starting value of Acceleration Factor."; IndParam.NumParam[1].Caption = "Starting AF2"; IndParam.NumParam[1].Value = 0.02; IndParam.NumParam[1].Min = 0.00; IndParam.NumParam[1].Max = 1.00; IndParam.NumParam[1].Point = 2; IndParam.NumParam[1].Enabled = true; IndParam.NumParam[1].ToolTip = "The starting value of Acceleration Factor."; IndParam.NumParam[2].Caption = "Increment1"; IndParam.NumParam[2].Value = 0.02; IndParam.NumParam[2].Min = 0.01; IndParam.NumParam[2].Max = 1.00; IndParam.NumParam[2].Point = 2; IndParam.NumParam[2].Enabled = true; IndParam.NumParam[2].ToolTip = "Increment value."; IndParam.NumParam[3].Caption = "Increment2"; IndParam.NumParam[3].Value = 0.02; IndParam.NumParam[3].Min = 0.01; IndParam.NumParam[3].Max = 1.00; IndParam.NumParam[3].Point = 2; IndParam.NumParam[3].Enabled = true; IndParam.NumParam[3].ToolTip = "Increment value."; IndParam.NumParam[4].Caption = "Maximum AF1"; IndParam.NumParam[4].Value = 0.01; IndParam.NumParam[4].Min = 0.01; IndParam.NumParam[4].Max = 2.00; IndParam.NumParam[4].Point = 2; IndParam.NumParam[4].Enabled = true; IndParam.NumParam[4].ToolTip = "The maximum value of the Acceleration Factor."; IndParam.NumParam[5].Caption = "Maximum AF2"; IndParam.NumParam[5].Value = 0.01; IndParam.NumParam[5].Min = 0.01; IndParam.NumParam[5].Max = 2.00; IndParam.NumParam[5].Point = 2; IndParam.NumParam[5].Enabled = true; IndParam.NumParam[5].ToolTip = "The maximum value of the Acceleration Factor."; // 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 double dAfMin1 = IndParam.NumParam[0].Value; double dAfMin2 = IndParam.NumParam[1].Value; double dAfInc1 = IndParam.NumParam[2].Value; double dAfInc2 = IndParam.NumParam[3].Value; double dAfMax1 = IndParam.NumParam[4].Value; double dAfMax2 = IndParam.NumParam[5].Value; int previous = IndParam.CheckParam[0].Checked ? 1 : 0; // Reading the parameters double dPExtr1; double dPExtr2; double dadPsarNew1 = 0; double dadPsarNew2 = 0; var aiDir1 = new int[Bars]; var aiDir2 = new int[Bars]; var adPsar1 = new double[Bars]; var adPsar2 = new double[Bars]; //---- Calculating the initial values adPsar1[0] = 0; adPsar2[0] = 0; double dAf1 = dAfMin1; double dAf2 = dAfMin2; int intDirNew1 = 0; int intDirNew2 = 0; if (Close[1] > Open[0]) { aiDir1[0] = 1; aiDir2[0] = 1; aiDir1[1] = 1; aiDir2[1] = 1; dPExtr1 = Math.Max(High[0], High[1]); dPExtr2 = Math.Max(High[0], High[1]); adPsar1[1] = Math.Min(Low[0], Low[1]); adPsar2[1] = Math.Min(Low[0], Low[1]); } else { aiDir1[0] = -1; aiDir2[0] = -1; aiDir1[1] = -1; aiDir2[1] = -1; dPExtr1 = Math.Min(Low[0], Low[1]); dPExtr2 = Math.Min(Low[0], Low[1]); adPsar1[1] = Math.Max(High[0], High[1]); adPsar2[1] = Math.Max(High[0], High[1]); } for (int iBar = 2; iBar < Bars; iBar++) { //---- adPsar for the current period if (intDirNew1 != 0) { // The direction was changed during the last period aiDir1[iBar] = intDirNew1; intDirNew1 = 0; adPsar1[iBar] = dadPsarNew1 + dAf1 * (dPExtr1 - dadPsarNew1); } else { aiDir1[iBar] = aiDir1[iBar - 1]; adPsar1[iBar] = adPsar1[iBar - 1] + dAf1 * (dPExtr1 - adPsar1[iBar - 1]); } //---------------------------------------------------------------------------- if (intDirNew2 != 0) { // The direction was changed during the last period aiDir2[iBar] = intDirNew2; intDirNew2 = 0; adPsar2[iBar] = dadPsarNew2 + dAf2 * (dPExtr2 - dadPsarNew2); } else { aiDir2[iBar] = aiDir2[iBar - 1]; adPsar2[iBar] = adPsar2[iBar - 1] + dAf2 * (dPExtr2 - adPsar2[iBar - 1]); } // adPsar has to be out of the previous two bars limits if (aiDir1[iBar] > 0 && adPsar1[iBar] > Math.Min(Low[iBar - 1], Low[iBar - 2])) adPsar1[iBar] = Math.Min(Low[iBar - 1], Low[iBar - 2]); else if (aiDir1[iBar] < 0 && adPsar1[iBar] < Math.Max(High[iBar - 1], High[iBar - 2])) adPsar1[iBar] = Math.Max(High[iBar - 1], High[iBar - 2]); //------------------------------------------------------------------------------------------- if (aiDir2[iBar] > 0 && adPsar2[iBar] > Math.Min(Low[iBar - 1], Low[iBar - 2])) adPsar2[iBar] = Math.Min(Low[iBar - 1], Low[iBar - 2]); else if (aiDir2[iBar] < 0 && adPsar2[iBar] < Math.Max(High[iBar - 1], High[iBar - 2])) adPsar2[iBar] = Math.Max(High[iBar - 1], High[iBar - 2]); //---- adPsar for the next period // Calculation of the new values of flPExtr and flAF // if there is a new extreme price in the adPsar direction if (aiDir1[iBar] > 0 && High[iBar] > dPExtr1) { dPExtr1 = High[iBar]; dAf1 = Math.Min(dAf1 + dAfInc1, dAfMax1); } if (aiDir1[iBar] < 0 && Low[iBar] < dPExtr1) { dPExtr1 = Low[iBar]; dAf1 = Math.Min(dAf1 + dAfInc1, dAfMax1); } //------------------------------------------- if (aiDir2[iBar] > 0 && High[iBar] > dPExtr2) { dPExtr2 = High[iBar]; dAf2 = Math.Min(dAf2 + dAfInc2, dAfMax2); } if (aiDir2[iBar] < 0 && Low[iBar] < dPExtr2) { dPExtr2 = Low[iBar]; dAf2 = Math.Min(dAf2 + dAfInc2, dAfMax2); } // Whether the price reaches adPsar if (Low[iBar] <= adPsar1[iBar] && adPsar1[iBar] <= High[iBar]) { intDirNew1 = -aiDir1[iBar]; dadPsarNew1 = dPExtr1; dAf1 = dAfMin1; dPExtr1 = intDirNew1 > 0 ? High[iBar] : Low[iBar]; } //--------------------------------------------------------------- if (Low[iBar] <= adPsar2[iBar] && adPsar2[iBar] <= High[iBar]) { intDirNew2 = -aiDir2[iBar]; dadPsarNew2 = dPExtr2; dAf2 = dAfMin2; dPExtr2 = intDirNew2 > 0 ? High[iBar] : Low[iBar]; } } const int firstBar = 8 ; var adMAOscillator = new double[Bars]; for (int iBar = 8; iBar < Bars; iBar++) adMAOscillator[iBar] = adPsar1[iBar] - adPsar2[iBar]; // Saving the components Component = new IndicatorComp[4]; Component[0] = new IndicatorComp { CompName = "Fast Moving Average", ChartColor = Color.Goldenrod, DataType = IndComponentType.IndicatorValue, ChartType = IndChartType.Line, FirstBar = 8, Value = adPsar1 }; Component[1] = new IndicatorComp { CompName = "Slow Moving Average", ChartColor = Color.IndianRed, DataType = IndComponentType.IndicatorValue, ChartType = IndChartType.Line, FirstBar = 8, Value = adPsar2 }; Component[2] = new IndicatorComp { ChartType = IndChartType.NoChart, FirstBar = 8, Value = new double[Bars] }; Component[3] = new IndicatorComp { ChartType = IndChartType.NoChart, FirstBar = 8, Value = new double[Bars] }; // Sets the Component's type if (SlotType == SlotTypes.OpenFilter) { Component[2].DataType = IndComponentType.AllowOpenLong; Component[2].CompName = "Is long entry allowed"; Component[3].DataType = IndComponentType.AllowOpenShort; Component[3].CompName = "Is short entry allowed"; } else if (SlotType == SlotTypes.CloseFilter) { Component[2].DataType = IndComponentType.ForceCloseLong; Component[2].CompName = "Close out long position"; Component[3].DataType = IndComponentType.ForceCloseShort; Component[3].CompName = "Close out short position"; } // Calculation of the logic var indLogic = IndicatorLogic.It_does_not_act_as_a_filter; switch (IndParam.ListParam[0].Text) { case "Psar1 crosses Psar2 upward": indLogic = IndicatorLogic.The_indicator_crosses_the_level_line_upward; break; case "Psar1 crosses Psar2 downward": indLogic = IndicatorLogic.The_indicator_crosses_the_level_line_downward; break; case "Psar1 is higher than Psar2": indLogic = IndicatorLogic.The_indicator_is_higher_than_the_level_line; break; case "Psar1 is lower than Psar2": indLogic = IndicatorLogic.The_indicator_is_lower_than_the_level_line; break; } OscillatorLogic(8, previous, adMAOscillator, 0, 0, ref Component[2], ref Component[3], indLogic); } public override void SetDescription() { EntryFilterLongDescription = ToString() + "; Psar1 "; EntryFilterShortDescription = ToString() + "; Psar1 "; ExitFilterLongDescription = ToString() + "; Psar1 "; ExitFilterShortDescription = ToString() + "; Psar1 "; switch (IndParam.ListParam[0].Text) { case "Psar1 crosses Psar2 upward": EntryFilterLongDescription += "crosses Psar2 upward"; EntryFilterShortDescription += "crosses Psar2 downward"; ExitFilterLongDescription += "crosses Psar2 upward"; ExitFilterShortDescription += "crosses Psar2 downward"; break; case "Psar1 crosses Psar2 downward": EntryFilterLongDescription += "crosses Psar2 downward"; EntryFilterShortDescription += "crosses Psar2 upward"; ExitFilterLongDescription += "crosses Psar2 downward"; ExitFilterShortDescription += "crosses Psar2 upward"; break; case "Psar1 is higher than Psar2": EntryFilterLongDescription += "is higher than Psar2"; EntryFilterShortDescription += "is lower than Psar2"; ExitFilterLongDescription += "is higher than Psar2"; ExitFilterShortDescription += "is lower than Psar2"; break; case "Psar1 is lower than Psar2": EntryFilterLongDescription += "is lower than Psar2"; EntryFilterShortDescription += "is higher than Psar2"; ExitFilterLongDescription += "is lower than Psar2"; ExitFilterShortDescription += "is higher than Psar2"; break; } } public override string ToString() { return IndicatorName + (IndParam.CheckParam[0].Checked ? "* (" : " (") + IndParam.ListParam[1].Text + ", " + // Price IndParam.ListParam[3].Text + ", " + // Psar1 Method IndParam.ListParam[4].Text + ", " + // Psar2 Method IndParam.NumParam[0].ValueToString + ", " + // Psar1 period IndParam.NumParam[1].ValueToString + ", " + // Psar2 period IndParam.NumParam[2].ValueToString + ", " + // Psar1 shift IndParam.NumParam[3].ValueToString + ")"; // Psar2 shift } } }
//+--------------------------------------------------------------------+ //| 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 ParabolicSARComboCrossover : public Indicator { public: ParabolicSARComboCrossover(SlotTypes slotType) { SlotType=slotType; IndicatorName="Parabolic SAR Combo Crossover"; WarningMessage = ""; IsAllowLTF = true; ExecTime = ExecutionTime_DuringTheBar; IsSeparateChart = false; IsDiscreteValues = false; IsDeafultGroupAll = false; } virtual void Calculate(DataSet &dataSet); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void ParabolicSARComboCrossover::Calculate(DataSet &dataSet) { Data=GetPointer(dataSet); // Reading the parameters double dAfMin1 = NumParam[0].Value; double dAfMin2 = NumParam[1].Value; double dAfInc1 = NumParam[2].Value; double dAfInc2 = NumParam[3].Value; double dAfMax1 = NumParam[4].Value; double dAfMax2 = NumParam[5].Value; int previous=CheckParam[0].Checked ? 1 : 0; // Reading the parameters double dPExtr1; double dPExtr2; double dadPsarNew1 = 0; double dadPsarNew2 = 0; int aiDir1[]; ArrayResize(aiDir1,Data.Bars); ArrayInitialize(aiDir1, 0); int aiDir2[]; ArrayResize(aiDir2,Data.Bars); ArrayInitialize(aiDir2, 0); double adPsar1[]; ArrayResize(adPsar1,Data.Bars);ArrayInitialize(adPsar1, 0); double adPsar2[]; ArrayResize(adPsar2,Data.Bars);ArrayInitialize(adPsar2, 0); //---- Calculating the initial values adPsar1[0] = 0; adPsar2[0] = 0; double dAf1 = dAfMin1; double dAf2 = dAfMin2; int intDirNew1 = 0; int intDirNew2 = 0; if(Data.Close[1]>Data.Open[0]) { aiDir1[0] = 1; aiDir2[0] = 1; aiDir1[1] = 1; aiDir2[1] = 1; dPExtr1 = MathMax(Data.High[0], Data.High[1]); dPExtr2 = MathMax(Data.High[0], Data.High[1]); adPsar1[1] = MathMin(Data.Low[0], Data.Low[1]); adPsar2[1] = MathMin(Data.Low[0], Data.Low[1]); } else { aiDir1[0] = -1; aiDir2[0] = -1; aiDir1[1] = -1; aiDir2[1] = -1; dPExtr1 = MathMin(Data.Low[0], Data.Low[1]); dPExtr2 = MathMin(Data.Low[0], Data.Low[1]); adPsar1[1] = MathMax(Data.High[0], Data.High[1]); adPsar2[1] = MathMax(Data.High[0], Data.High[1]); } for(int iBar=2; iBar<Data.Bars; iBar++) { //---- adPsar for the current period if(intDirNew1!=0) { // The direction was changed during the last period aiDir1[iBar]=intDirNew1; intDirNew1=0; adPsar1[iBar]=dadPsarNew1+dAf1 *(dPExtr1-dadPsarNew1); } else { aiDir1[iBar]=aiDir1[iBar-1]; adPsar1[iBar]=adPsar1[iBar-1]+dAf1 *(dPExtr1-adPsar1[iBar-1]); } //---------------------------------------------------------------------------- if(intDirNew2!=0) { // The direction was changed during the last period aiDir2[iBar]=intDirNew2; intDirNew2=0; adPsar2[iBar]=dadPsarNew2+dAf2 *(dPExtr2-dadPsarNew2); } else { aiDir2[iBar]=aiDir2[iBar-1]; adPsar2[iBar]=adPsar2[iBar-1]+dAf2 *(dPExtr2-adPsar2[iBar-1]); } // adPsar has to be out of the previous two bars limits if(aiDir1[iBar]>0 && adPsar1[iBar]>MathMin(Data.Low[iBar-1],Data.Low[iBar-2])) adPsar1[iBar]=MathMin(Data.Low[iBar-1],Data.Low[iBar-2]); else if(aiDir1[iBar]<0 && adPsar1[iBar]<MathMax(Data.High[iBar-1],Data.High[iBar-2])) adPsar1[iBar]=MathMax(Data.High[iBar-1],Data.High[iBar-2]); //------------------------------------------------------------------------------------------- if(aiDir2[iBar]>0 && adPsar2[iBar]>MathMin(Data.Low[iBar-1],Data.Low[iBar-2])) adPsar2[iBar]=MathMin(Data.Low[iBar-1],Data.Low[iBar-2]); else if(aiDir2[iBar]<0 && adPsar2[iBar]<MathMax(Data.High[iBar-1],Data.High[iBar-2])) adPsar2[iBar]=MathMax(Data.High[iBar-1],Data.High[iBar-2]); //---- adPsar for the next period // Calculation of the new values of flPExtr and flAF if(aiDir1[iBar]>0 && Data.High[iBar]>dPExtr1) { dPExtr1=Data.High[iBar]; dAf1=MathMin(dAf1+dAfInc1,dAfMax1); } if(aiDir1[iBar]<0 && Data.Low[iBar]<dPExtr1) { dPExtr1=Data.Low[iBar]; dAf1=MathMin(dAf1+dAfInc1,dAfMax1); } //------------------------------------------- if(aiDir2[iBar]>0 && Data.High[iBar]>dPExtr2) { dPExtr2=Data.High[iBar]; dAf2=MathMin(dAf2+dAfInc2,dAfMax2); } if(aiDir2[iBar]<0 && Data.Low[iBar]<dPExtr2) { dPExtr2=Data.Low[iBar]; dAf2=MathMin(dAf2+dAfInc2,dAfMax2); } // Whether the price reaches adPsar if(Data.Low[iBar]<=adPsar1[iBar] && adPsar1[iBar]<=Data.High[iBar]) { intDirNew1=-aiDir1[iBar]; dadPsarNew1=dPExtr1; dAf1=dAfMin1; dPExtr1=intDirNew1>0 ? Data.High[iBar]: Data.Low[iBar]; } //--------------------------------------------------------------- if(Data.Low[iBar]<=adPsar2[iBar] && adPsar2[iBar]<=Data.High[iBar]) { intDirNew2=-aiDir2[iBar]; dadPsarNew2=dPExtr2; dAf2=dAfMin2; dPExtr2=intDirNew2>0 ? Data.High[iBar]: Data.Low[iBar]; } } double adMAOscillator[]; ArrayResize(adMAOscillator,Data.Bars);ArrayInitialize(adMAOscillator, 0); for(int iBar=8; iBar<Data.Bars; iBar++) adMAOscillator[iBar]=adPsar1[iBar]-adPsar2[iBar]; // Saving the components ArrayResize(Component[0].Value,Data.Bars); Component[0].CompName = "Fast Moving Average"; Component[0].DataType = IndComponentType_IndicatorValue; Component[0].FirstBar = 8; ArrayCopy(Component[0].Value,adPsar1); ArrayResize(Component[1].Value,Data.Bars); Component[1].CompName = "Slow Moving Average"; Component[1].DataType = IndComponentType_IndicatorValue; Component[1].FirstBar = 8; ArrayCopy(Component[1].Value,adPsar2); ArrayResize(Component[2].Value,Data.Bars); Component[2].FirstBar=8; ArrayResize(Component[3].Value,Data.Bars); Component[3].FirstBar=8; // Sets the Component's type if(SlotType==SlotTypes_OpenFilter) { Component[2].DataType = IndComponentType_AllowOpenLong; Component[2].CompName = "Is long entry allowed"; Component[3].DataType = IndComponentType_AllowOpenShort; Component[3].CompName = "Is short entry allowed"; } else if(SlotType==SlotTypes_CloseFilter) { Component[2].DataType = IndComponentType_ForceCloseLong; Component[2].CompName = "Close out long position"; Component[3].DataType = IndComponentType_ForceCloseShort; Component[3].CompName = "Close out short position"; } // Calculation of the logic IndicatorLogic indLogic=IndicatorLogic_It_does_not_act_as_a_filter; if(ListParam[0].Text=="Psar1 crosses Psar2 upward") { indLogic=IndicatorLogic_The_indicator_crosses_the_level_line_upward; } else if(ListParam[0].Text=="Psar1 crosses Psar2 downward") { indLogic=IndicatorLogic_The_indicator_crosses_the_level_line_downward; } else if(ListParam[0].Text=="Psar1 is higher than Psar2") { indLogic=IndicatorLogic_The_indicator_is_higher_than_the_level_line; } else if(ListParam[0].Text=="Psar1 is lower than Psar2") { indLogic=IndicatorLogic_The_indicator_is_lower_than_the_level_line; } OscillatorLogic(8,previous,adMAOscillator,0,0,Component[2],Component[3],indLogic); } //+------------------------------------------------------------------+
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.;