//+------------------------------------------------------------------+ //| Indicators.mqh | //| Andrew Young | //| http://www.expertadvisorbook.com | //+------------------------------------------------------------------+ #property copyright "Andrew Young" #property link "http://www.expertadvisorbook.com" /* Creative Commons Attribution-NonCommercial 3.0 Unported http://creativecommons.org/licenses/by-nc/3.0/ You may use this file in your own personal projects. You may modify it if necessary. You may even share it, provided the copyright above is present. No commercial use permitted. */ #define MAX_COUNT 500 #include //+------------------------------------------------------------------+ //| Base Class | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CIndicator { protected: int handle; double main[]; public: CIndicator(void); double Main(int pShift = 0); void Main(double &pShift[]); int HighestMain(); int LowestMain(); void Release(); virtual int Init() { return(handle); } }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CIndicator::CIndicator(void) { ArraySetAsSeries(main, true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CIndicator::Main(int pShift = 0) { CopyBuffer(handle, 0, 0, MAX_COUNT, main); double value = NormalizeDouble(main[pShift], _Digits); return(value); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CIndicator:: Main(double &pShift[]) { int copied = CopyBuffer(handle, 0, 0, ArraySize(pShift), pShift); if(copied <= 0) { Print("Error copying upper band buffer: ", GetLastError()); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CIndicator::Release(void) { IndicatorRelease(handle); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CIndicator::HighestMain(void) { return ArrayMaximum(main); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CIndicator::LowestMain(void) { return ArrayMinimum(main); } //+------------------------------------------------------------------+ //| Moving Average | //+------------------------------------------------------------------+ /* CiMA MA; sinput string MA; // Moving Average input int MAPeriod = 10; input ENUM_MA_METHOD MAMethod = 0; input int MAShift = 0; input ENUM_APPLIED_PRICE MAPrice = PRICE_CLOSE; MA.Init(_Symbol,_Period,MAPeriod,MAShift,MAMethod,MAPrice); MA.Main() */ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CiMA : public CIndicator { public: int Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int pMAPeriod, int pMAShift, ENUM_MA_METHOD pMAMethod, ENUM_APPLIED_PRICE pMAPrice); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiMA::Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int pMAPeriod, int pMAShift, ENUM_MA_METHOD pMAMethod, ENUM_APPLIED_PRICE pMAPrice) { handle = iMA(pSymbol, pTimeframe, pMAPeriod, pMAShift, pMAMethod, pMAPrice); return(handle); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CiATR : public CIndicator { public: int Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int pMAPeriod); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiATR::Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int pMAPeriod) { handle = iATR(pSymbol, pTimeframe, pMAPeriod); return(handle); } //+------------------------------------------------------------------+ //| RSI | //+------------------------------------------------------------------+ /* CiRSI RSI; sinput string RS; // RSI input int RSIPeriod = 8; input ENUM_APPLIED_PRICE RSIPrice = PRICE_CLOSE; RSI.Init(_Symbol,_Period,RSIPeriod,RSIPrice); RSI.Main() */ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CiRSI : public CIndicator { public: int Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int pRSIPeriod, ENUM_APPLIED_PRICE pRSIPrice); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiRSI::Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int pRSIPeriod, ENUM_APPLIED_PRICE pRSIPrice) { handle = iRSI(pSymbol, pTimeframe, pRSIPeriod, pRSIPrice); return(handle); } //+------------------------------------------------------------------+ //| Stochastic | //+------------------------------------------------------------------+ /* CiStochastic Stoch; sinput string STO; // Stochastic input int KPeriod = 10; input int DPeriod = 3; input int Slowing = 3; input ENUM_MA_METHOD StochMethod = MODE_SMA; input ENUM_STO_PRICE StochPrice = STO_LOWHIGH; Stoch.Init(_Symbol,_Period,KPeriod,DPeriod,Slowing,StochMethod,StochPrice); Stoch.Main() Stoch.Signal() */ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CiStochastic : public CIndicator { private: double signal[]; public: int Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int pKPeriod, int pDPeriod, int pSlowing, ENUM_MA_METHOD pMAMethod, ENUM_STO_PRICE pPrice); double Signal(int pShift = 0); CiStochastic(void); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CiStochastic::CiStochastic(void) { ArraySetAsSeries(signal, true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiStochastic::Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int pKPeriod, int pDPeriod, int pSlowing, ENUM_MA_METHOD pMAMethod, ENUM_STO_PRICE pPrice) { handle = iStochastic(pSymbol, pTimeframe, pKPeriod, pDPeriod, pSlowing, pMAMethod, pPrice); return(handle); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CiStochastic::Signal(int pShift = 0) { CopyBuffer(handle, 1, 0, MAX_COUNT, signal); double value = NormalizeDouble(signal[pShift], _Digits); return(value); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CiZig: public CIndicator { private: double high[], low[]; CIntegerArrayList hs; CIntegerArrayList ls; public: int Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int inpDepth, int inpDeviation, int inpBackstep); int High(int pShift = 0); int Low(int pShift = 0); CiZig(); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CiZig::CiZig(void) { ArraySetAsSeries(high, true); ArraySetAsSeries(low, true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiZig::Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int inpDepth, int inpDeviation, int inpBackstep) { handle = iCustom(pSymbol, pTimeframe, "Examples\\ZigZagColor", inpDepth, inpDeviation, inpBackstep); if(handle == INVALID_HANDLE) { Print("Error creating Bollinger Bands indicator: ", GetLastError()); return(-1); } return(handle); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiZig::High(int pShift = 0) { hs.Clear(); if(CopyBuffer(handle, 0, 0, MAX_COUNT, high) <= 0) { Print("Error copying upper band buffer: ", GetLastError()); return(0); } for(int i = 0; i < MAX_COUNT; i++) { if(high[i] != 0 && high[i] != EMPTY_VALUE) { hs.Add(i); } } return(hs.Get(pShift)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiZig::Low(int pShift = 0) { ls.Clear(); if(CopyBuffer(handle, 1, 0, MAX_COUNT, low) <= 0) { Print("Error copying upper band buffer: ", GetLastError()); return(0); } for(int i = 0; i < MAX_COUNT; i++) { if(low[i] != 0 && low[i] != EMPTY_VALUE) { ls.Add(i); } } return(ls.Get(pShift)); } //+------------------------------------------------------------------+ //| Bollinger Bands | //+------------------------------------------------------------------+ class CiBollinger : public CIndicator { private: double upper[], lower[]; public: int Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int pPeriod, int shift, double pDeviation, ENUM_APPLIED_PRICE pPrice); double Upper(int pShift = 0); double Lower(int pShift = 0); void Upper(double &pShift[]); void Lower(double &pShift[]); CiBollinger(); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CiBollinger::CiBollinger(void) { ArraySetAsSeries(upper, true); ArraySetAsSeries(lower, true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiBollinger::Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int pPeriod, int shift, double pDeviation, ENUM_APPLIED_PRICE pPrice) { handle = iBands(pSymbol, pTimeframe, pPeriod, shift, pDeviation, pPrice); if(handle == INVALID_HANDLE) { Print("Error creating Bollinger Bands indicator: ", GetLastError()); return(-1); } return(handle); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CiBollinger::Upper(int pShift) { if(CopyBuffer(handle, 1, 0, pShift + 1, upper) <= 0) { Print("Error copying upper band buffer: ", GetLastError()); return(0); } return(upper[pShift]); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CiBollinger::Lower(int pShift) { if(CopyBuffer(handle, 2, 0, pShift + 1, lower) <= 0) { Print("Error copying lower band buffer: ", GetLastError()); return(0); } return(lower[pShift]); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CiBollinger::Upper(double & pShift[]) { int copied = CopyBuffer(handle, 1, 0, ArraySize(pShift), pShift); if(copied <= 0) { Print("Error copying upper band buffer: ", GetLastError()); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CiBollinger::Lower(double & pShift[]) { int copied = CopyBuffer(handle, 2, 0, ArraySize(pShift), pShift); if(copied <= 0) { Print("Error copying lower band buffer: ", GetLastError()); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CiMACD : public CIndicator { private: double signal[]; public: int Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int pFastPeriod, int pSlowPeriod, int pSignalPeriod, ENUM_APPLIED_PRICE pPrice); double Signal(int pShift = 0); void Signal(double &pShift[]); CiMACD(); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CiMACD::CiMACD() { ArraySetAsSeries(signal, true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiMACD::Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int pFastPeriod, int pSlowPeriod, int pSignalPeriod, ENUM_APPLIED_PRICE pPrice) { handle = iMACD(pSymbol, pTimeframe, pFastPeriod, pSlowPeriod, pSignalPeriod, pPrice); if(handle == INVALID_HANDLE) { Print("Error creating MACD indicator: ", GetLastError()); return(-1); } return(handle); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CiMACD::Signal(int pShift) { if(CopyBuffer(handle, 1, 0, pShift + 1, signal) <= 0) { Print("Error copying signal buffer: ", GetLastError()); return(0); } return(signal[pShift]); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CiMACD::Signal(double & pShift[]) { int copied = CopyBuffer(handle, 1, 0, ArraySize(pShift), pShift); if(copied <= 0) { Print("Error copying signal buffer: ", GetLastError()); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CiStochSwing: public CIndicator { private: double high[], low[]; CIntegerArrayList hs; CIntegerArrayList ls; public: int Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe,int InpLeftRightBars, int pKPeriod, int pDPeriod, int pSlowing, ENUM_MA_METHOD pMAMethod, ENUM_STO_PRICE pPrice); int High(int pShift = 0); int Low(int pShift = 0); CiStochSwing(); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CiStochSwing::CiStochSwing(void) { ArraySetAsSeries(high, true); ArraySetAsSeries(low, true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiStochSwing::Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe,int InpLeftRightBars, int pKPeriod, int pDPeriod, int pSlowing, ENUM_MA_METHOD pMAMethod, ENUM_STO_PRICE pPrice) { handle = iCustom(pSymbol, pTimeframe, "Mine\\bt_stoch",InpLeftRightBars,pKPeriod, pDPeriod, pSlowing, pMAMethod, pPrice); if(handle == INVALID_HANDLE) { Print("Error creating Bollinger Bands indicator: ", GetLastError()); return(-1); } return(handle); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiStochSwing::High(int pShift = 0) { hs.Clear(); if(CopyBuffer(handle, 2, 0, MAX_COUNT, high) <= 0) { Print("Error copying upper band buffer: ", GetLastError()); return(0); } for(int i = 0; i < MAX_COUNT; i++) { if(high[i] != 0 && high[i] != EMPTY_VALUE) { hs.Add(i); } } return(hs.Get(pShift)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiStochSwing::Low(int pShift = 0) { ls.Clear(); if(CopyBuffer(handle, 3, 0, MAX_COUNT, low) <= 0) { Print("Error copying upper band buffer: ", GetLastError()); return(0); } for(int i = 0; i < MAX_COUNT; i++) { if(low[i] != 0 && low[i] != EMPTY_VALUE) { ls.Add(i); } } return(ls.Get(pShift)); } //+------------------------------------------------------------------+ //| PSAR | //+------------------------------------------------------------------+ /* CiSAR SAR; sinput string SARSet; // SAR Settings input double SARStep = 0.02; input double SARMaximum = 0.2; SAR.Init(_Symbol,_Period,SARStep,SARMaximum); SAR.Main(); */ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CiSAR : public CIndicator { public: int Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, double pStep, double pMaximum); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiSAR::Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, double pStep, double pMaximum) { handle = iSAR(pSymbol, pTimeframe, pStep, pMaximum); return(handle); } //+------------------------------------------------------------------+ //| ADX | //+------------------------------------------------------------------+ /* CiADX ADX; sinput string ADXSet; // ADX Settings input int ADXPeriod = 10; ADX.Init(_Symbol,_Period,ADXPeriod); ADX.Plus(); ADX.Minus(); */ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CiADX : public CIndicator { private: double plus[]; double minus[]; public: int Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int pPeriod); double Plus(int pShift = 0); double Minus(int pShift = 0); CiADX(); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CiADX::CiADX() { ArraySetAsSeries(plus, true); ArraySetAsSeries(minus, true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiADX::Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int pPeriod) { handle = iADX(pSymbol, pTimeframe, pPeriod); return(handle); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CiADX::Plus(int pShift = 0) { CopyBuffer(handle, 1, 0, MAX_COUNT, plus); double value = NormalizeDouble(plus[pShift], _Digits); return(value); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CiADX::Minus(int pShift = 0) { CopyBuffer(handle, 2, 0, MAX_COUNT, minus); double value = NormalizeDouble(minus[pShift], _Digits); return(value); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CiCustom: public CIndicator { private: double high[], low[]; CIntegerArrayList hs; CIntegerArrayList ls; public: int Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int inpDepth, int inpDeviation, int inpBackstep); int High(int pShift = 0); int Low(int pShift = 0); CiCustom(); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CiCustom::CiCustom(void) { ArraySetAsSeries(high, true); ArraySetAsSeries(low, true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiCustom::Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int inpDepth, int inpDeviation, int inpBackstep) { handle = iCustom(pSymbol, pTimeframe, "Examples\\ZigZagColor", inpDepth, inpDeviation, inpBackstep); if(handle == INVALID_HANDLE) { Print("Error creating Bollinger Bands indicator: ", GetLastError()); return(-1); } return(handle); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiCustom::High(int pShift = 0) { hs.Clear(); if(CopyBuffer(handle, 0, 0, MAX_COUNT, high) <= 0) { Print("Error copying upper band buffer: ", GetLastError()); return(0); } for(int i = 0; i < MAX_COUNT; i++) { if(high[i] != 0 && high[i] != EMPTY_VALUE) { hs.Add(i); } } return(hs.Get(pShift)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CiCustom::Low(int pShift = 0) { ls.Clear(); if(CopyBuffer(handle, 1, 0, MAX_COUNT, low) <= 0) { Print("Error copying upper band buffer: ", GetLastError()); return(0); } for(int i = 0; i < MAX_COUNT; i++) { if(low[i] != 0 && low[i] != EMPTY_VALUE) { ls.Add(i); } } return(ls.Get(pShift)); } //+------------------------------------------------------------------+ //| Blank Indicator Class Templates | //+------------------------------------------------------------------+ /* Replace _INDNAME_ with the name of the indicator. Replace _INDFUNC_ with the name of the correct technical indicator function. Add appropriate input parameters (...) to Init() function. Rename Buffer1(), Buffer2(), etc. to something user-friendly. Add or remove buffer arrays and functions as necessary. // Single Buffer Indicator class Ci_INDNAME_ : public CIndicator { public: int Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, ... ); }; int Ci_INDNAME_::Init(string pSymbol,ENUM_TIMEFRAMES pTimeframe, ... ) { handle = _INDFUNC_(pSymbol,pTimeframe, ... ); return(handle); } // Multi-Buffer Indicator class Ci_INDNAME_ : public CIndicator { private: double buffer1[]; double buffer2[]; public: int Init(string pSymbol,ENUM_TIMEFRAMES pTimeframe, ... ); double Buffer1(int pShift=0); double Buffer2(int pShift=0); Ci_INDNAME_(); }; Ci_INDNAME_::Ci_INDNAME_() { ArraySetAsSeries(buffer1,true); ArraySetAsSeries(buffer2,true); } int Ci_INDNAME_::Init(string pSymbol,ENUM_TIMEFRAMES pTimeframe,...) { handle = _INDFUNC_(pSymbol,pTimeframe,...); return(handle); } double Ci_INDNAME_::Buffer1(int pShift=0) { CopyBuffer(handle,1,0,MAX_COUNT,buffer1); double value = NormalizeDouble(buffer1[pShift],_Digits); return(value); } double Ci_INDNAME_::Buffer2(int pShift=0) { CopyBuffer(handle,1,0,MAX_COUNT,buffer2); double value = NormalizeDouble(buffer2[pShift],_Digits); return(value); } */ //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //+------------------------------------------------------------------+