//+------------------------------------------------------------------+ //| SignalSAR.mqh | //| Copyright 2000-2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include "..\Expert\ExpertSignalCustom.mqh" // wizard description start //+------------------------------------------------------------------+ //| Description of the class | //| Title=Signals of indicator 'Parabolic SAR' | //| Type=SignalAdvanced | //| Name=Parabolic SAR | //| ShortName=SAR | //| Class=CSignalSAR | //| Page=signal_sar | //| Parameter=Step,double,0.02,Speed increment | //| Parameter=Maximum,double,0.2,Maximum rate | //+------------------------------------------------------------------+ // wizard description end //+------------------------------------------------------------------+ //| Class CSignalSAR. | //| Purpose: Class of generator of trade signals based on | //| the 'Parabolic SAR' indicator. | //| Is derived from the CExpertSignalCustom class. | //+------------------------------------------------------------------+ class CSignalSAR : public CExpertSignalCustom { protected: CiSAR m_sar; // object-indicator //--- adjusted parameters double m_step; // the "speed increment" parameter of the indicator double m_maximum; // the "maximum rate" parameter of the indicator //--- "weights" of market models (0-100) int m_pattern_0; // model 0 "the parabolic is on the necessary side from the price" int m_pattern_1; // model 1 "the parabolic has 'switched'" public: CSignalSAR(void); ~CSignalSAR(void); //--- methods of setting adjustable parameters void Step(double value) { m_step = value; } void Maximum(double value) { m_maximum = value; } //--- methods of adjusting "weights" of market models void Pattern_0(int value) { m_pattern_0 = value; } void Pattern_1(int value) { m_pattern_1 = value; } virtual void ApplyPatternWeight(int patternNumber, int weight); //--- method of verification of settings virtual bool ValidationSettings(void); //--- method of creating the indicator and timeseries virtual bool InitIndicators(CIndicators *indicators); //--- methods of checking if the market models are formed virtual int LongCondition(void); virtual int ShortCondition(void); protected: //--- method of initialization of the indicator bool InitSAR(CIndicators *indicators); //--- methods of getting data double SAR(int ind) { return(m_sar.Main(ind)); } double Close(int ind) { return(m_close.GetData(ind)); } double DiffClose(int ind) { return(Close(ind) - SAR(ind)); } }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CSignalSAR::CSignalSAR(void) : m_step(0.02), m_maximum(0.2), m_pattern_0(10), m_pattern_1(90) { m_id = "SAR"; m_pattern_count = 2; //--- initialization of protected data m_used_series = USE_SERIES_CLOSE; } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CSignalSAR::~CSignalSAR(void) { } //+------------------------------------------------------------------+ //| Validation settings protected data. | //+------------------------------------------------------------------+ bool CSignalSAR::ValidationSettings(void) { //--- call of the method of the parent class if(!CExpertSignalCustom::ValidationSettings()) return(false); //--- ok return(true); } //+------------------------------------------------------------------+ //| Create indicators. | //+------------------------------------------------------------------+ bool CSignalSAR::InitIndicators(CIndicators *indicators) { //--- check pointer if(indicators == NULL) return(false); //--- initialization of indicators and timeseries of additional filters if(!CExpertSignalCustom::InitIndicators(indicators)) return(false); //--- create and initialize SAR indicator if(!InitSAR(indicators)) return(false); //--- ok return(true); } //+------------------------------------------------------------------+ //| Create SAR indicators. | //+------------------------------------------------------------------+ bool CSignalSAR::InitSAR(CIndicators *indicators) { //--- check pointer if(indicators == NULL) return(false); //--- add object to collection if(!indicators.Add(GetPointer(m_sar))) { printf(__FUNCTION__ + ": error adding object"); return(false); } //--- initialize object if(!m_sar.Create(m_symbol.Name(), m_period, m_step, m_maximum)) { printf(__FUNCTION__ + ": error initializing object"); return(false); } //--- ok return(true); } //+------------------------------------------------------------------+ //| "Voting" that price will grow. | //+------------------------------------------------------------------+ int CSignalSAR::LongCondition(void) { int result = 0; int idx = StartIndex(); //--- if the indicator is above the price at the first analyzed bar, don't 'vote' buying if(DiffClose(idx++) < 0.0) return(result); //--- the indicator is below the price at the first analyzed bar (the indicator has no objections to buying) if(IS_PATTERN_USAGE(0)) { result = m_pattern_0; m_active_pattern = "Pattern_0"; } //--- if the indicator is above the price at the second analyzed bar, then there is a condition for buying if(IS_PATTERN_USAGE(1) && DiffClose(idx) < 0.0) { result = m_pattern_1; m_active_pattern = "Pattern_1"; } if(result != 0) { m_active_direction = "Buy"; } //--- return the result return(result); } //+------------------------------------------------------------------+ //| "Voting" that price will fall. | //+------------------------------------------------------------------+ int CSignalSAR::ShortCondition(void) { int result = 0; int idx = StartIndex(); //--- if the indicator is below the price at the first analyzed bar, don't "vote" for selling if(DiffClose(idx++) > 0.0) return(result); //--- the indicator is above the price at the first analyzed bar (the indicator has no objections to selling) if(IS_PATTERN_USAGE(0)) { result = m_pattern_0; m_active_pattern = "Pattern_0"; } //--- if the indicator is below the price at the second analyzed bar, then there is a condition for selling if(IS_PATTERN_USAGE(1) && DiffClose(idx) > 0.0) { result = m_pattern_1; m_active_pattern = "Pattern_1"; } if(result != 0) { m_active_direction = "Sell"; } //--- return the result return(result); } //+------------------------------------------------------------------+ //| Set the specified pattern's weight to the specified value | //+------------------------------------------------------------------+ void CSignalSAR::ApplyPatternWeight(int patternNumber, int weight) { switch(patternNumber) { default: break; case 0: Pattern_0(weight); break; case 1: Pattern_1(weight); break; } } //+------------------------------------------------------------------+