//+------------------------------------------------------------------+ //| SignalTFMA.mqh | //| Thorsten Fischer Copyright 2019-2020 | //| https://mql5.tfsystem.de | //+------------------------------------------------------------------+ #property copyright "Thorsten Fischer Copyright 2019-2020" #property link "https://mql5.tfsystem.de" #property version "1.00" #property strict #include #property tester_indicator "Shared Projects\\Indicatoren\\CiCustom\\Custom Moving Average.ex5" // wizard description start //+------------------------------------------------------------------+ //| Description of the class | //| Title=Signals of Custom indicator 'TF-Test Moving Average' | //| Type=SignalAdvanced | //| Name=TF-Test Moving Average | //| ShortName=TFMA | //| Class=CSignalTFMA | //| Page=signal_tfma | //| Parameter=PeriodFast,int,13,Period of fast MA | //| Parameter=MethodFast,ENUM_MA_METHOD,MODE_SMA,Method of fast MA | //| Parameter=PeriodSlow,int,21,Period of slow MA | //| Parameter=MethodSlow,ENUM_MA_METHOD,MODE_SMA,Method of slow MA | //+------------------------------------------------------------------+ // wizard description end //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CSignalTFMA : public CExpertSignal { private: CiCustom m_ma_fast; CiCustom m_ma_slow; int m_period_fast; ENUM_MA_METHOD m_method_fast; int m_period_slow; ENUM_MA_METHOD m_method_slow; public: CSignalTFMA(); ~CSignalTFMA(); //--- method of verification of settings virtual bool ValidationSettings(void); //--- method of creating the indicator and timeseries virtual bool InitIndicators(CIndicators *indicators); //--- Access to indicator data double FastMA(const int index) const { return(m_ma_fast.GetData(0,index)); } double SlowMA(const int index) const { return(m_ma_slow.GetData(0,index)); } //--- Checking buy and sell conditions virtual int LongCondition(); virtual int ShortCondition(); //--- methods of setting adjustable parameters void PeriodFast(int value) { m_period_fast=value; } void MethodFast(ENUM_MA_METHOD value) { m_method_fast=value; } void PeriodSlow(int value) { m_period_slow=value; } void MethodSlow(ENUM_MA_METHOD value) { m_method_slow=value; } protected: //--- method of initialization of the indicator bool InitMA(CIndicators *indicators); //--- Creating MA indicators bool CreateFastMA(CIndicators *indicators); bool CreateSlowMA(CIndicators *indicators); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CSignalTFMA::CSignalTFMA() : m_period_fast(13), m_method_fast(MODE_SMA), m_period_slow(21), m_method_slow(MODE_SMA) { } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CSignalTFMA::~CSignalTFMA() { } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CSignalTFMA::ValidationSettings(void) { //--- call of the method of the parent class if(!CExpertSignal::ValidationSettings()) return(false); //--- Check periods, number of bars for the calculation of the MA >=1 if(m_period_fast<1 || m_period_slow<1) { PrintFormat("Incorrect value set for one of the periods! FastPeriod=%d, SlowPeriod=%d", m_period_fast,m_period_slow); return(false); } //--- Slow MA period must be greater that the fast MA period if(m_period_fast>m_period_slow) { PrintFormat("SlowPeriod=%d must be greater than FastPeriod=%d!", m_period_slow,m_period_fast); return false; } //--- Fast MA smoothing type must be one of the four values of the enumeration if(m_method_fast!=MODE_SMA && m_method_fast!=MODE_EMA && m_method_fast!=MODE_SMMA && m_method_fast!=MODE_LWMA) { PrintFormat("Invalid type of smoothing of the fast MA!"); return false; } //--- Show MA smoothing type must be one of the four values of the enumeration if(m_method_slow!=MODE_SMA && m_method_slow!=MODE_EMA && m_method_slow!=MODE_SMMA && m_method_slow!=MODE_LWMA) { PrintFormat("Invalid type of smoothing of the slow MA!"); return false; } //--- ok return(true); } //+------------------------------------------------------------------+ //| Create indicators. | //+------------------------------------------------------------------+ bool CSignalTFMA::InitIndicators(CIndicators *indicators) { //--- check pointer if(indicators==NULL) return(false); //--- initialization of indicators and timeseries of additional filters if(!CExpertSignal::InitIndicators(indicators)) return(false); //--- create and initialize AMA indicator if(!InitMA(indicators)) return(false); //--- ok return(true); } //+------------------------------------------------------------------+ //| Create MA indicators. | //+------------------------------------------------------------------+ bool CSignalTFMA::InitMA(CIndicators *indicators) { //--- check pointer if(indicators==NULL) return(false); //--- Creating our MA indicators if(!CreateFastMA(indicators)) return(false); if(!CreateSlowMA(indicators)) return(false); //--- ok return(true); } //+------------------------------------------------------------------+ //| Creates the "Fast MA" indicator | //+------------------------------------------------------------------+ bool CSignalTFMA::CreateFastMA(CIndicators *indicators) { //--- check pointer if(indicators==NULL) return(false); //--- add object to collection if(!indicators.Add(GetPointer(m_ma_fast))) { printf(__FUNCTION__+": error adding object"); return(false); } //--- Setting parameters of the fast MA MqlParam parameters[4]; //--- parameters[0].type=TYPE_STRING; parameters[0].string_value="Shared Projects\\Indicatoren\\CiCustom\\Custom Moving Average.ex5"; parameters[1].type=TYPE_INT; parameters[1].integer_value=m_period_fast; // Period parameters[2].type=TYPE_INT; parameters[2].integer_value=0; // Shift parameters[3].type=TYPE_INT; parameters[3].integer_value=m_method_fast; // Averaging method //--- initialize object if(!m_ma_fast.Create(m_symbol.Name(),0,IND_CUSTOM,4,parameters)) { printf(__FUNCTION__+": error initializing object"); return(false); } //--- Number of buffers if(!m_ma_fast.NumBuffers(1)) return(false); //--- Reached this part, so the function was successful, return true return(true); } //+------------------------------------------------------------------+ //| Creates the "Slow MA" indicator | //+------------------------------------------------------------------+ bool CSignalTFMA::CreateSlowMA(CIndicators *indicators) { //--- check pointer if(indicators==NULL) return(false); //--- add object to collection if(!indicators.Add(GetPointer(m_ma_slow))) { printf(__FUNCTION__+": error adding object"); return(false); } //--- Setting parameters of the fast MA MqlParam parameters[4]; //--- parameters[0].type=TYPE_STRING; parameters[0].string_value="Shared Projects\\Indicatoren\\CiCustom\\Custom Moving Average.ex5"; parameters[1].type=TYPE_INT; parameters[1].integer_value=m_period_slow; // Period parameters[2].type=TYPE_INT; parameters[2].integer_value=0; // Shift parameters[3].type=TYPE_INT; parameters[3].integer_value=m_method_slow; // Averaging method //--- initialize object if(!m_ma_slow.Create(m_symbol.Name(),0,IND_CUSTOM,4,parameters)) { printf(__FUNCTION__+": error initializing object"); return(false); } //--- Number of buffers if(!m_ma_slow.NumBuffers(1)) return(false); //--- Reached this part, so the function was successful, return true return(true); } //+------------------------------------------------------------------+ //| Returns the strength of the buy signal | //+------------------------------------------------------------------+ int CSignalTFMA::LongCondition() { int signal=0; //--- For operation with ticks idx=0, for operation with formed bars idx=1 int idx=StartIndex(); //--- Values of MAs at the last formed bar double last_fast_value=FastMA(idx); double last_slow_value=SlowMA(idx); //--- Values of MAs at the last but one formed bar double prev_fast_value=FastMA(idx+1); double prev_slow_value=SlowMA(idx+1); //---If the fast MA crossed the slow MA from bottom upwards on the last two closed bars if((last_fast_value>last_slow_value) && (prev_fast_valueprev_slow_value)) { signal=100; // There is a signal to sell } //--- Return the signal value return(signal); } //+------------------------------------------------------------------+