385 lines
12 KiB
MQL5
385 lines
12 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| Indicators.mqh |
| |||
//| Copyright 2000-2025, MetaQuotes Ltd. |
| |||
//| https://www.mql5.com |
| |||
//+------------------------------------------------------------------+
| |||
#include "Trend.mqh"
| |||
#include "Oscilators.mqh"
| |||
#include "Volumes.mqh"
| |||
#include "BillWilliams.mqh"
| |||
#include "Custom.mqh"
| |||
#include "TimeSeries.mqh"
| |||
//+------------------------------------------------------------------+
| |||
//| Class CIndicators. |
| |||
//| Purpose: Class for creation of collection of instances of |
| |||
//| technical indicators. |
| |||
//+------------------------------------------------------------------+
| |||
class CIndicators : public CArrayObj
| |||
{
| |||
protected:
| |||
MqlDateTime m_prev_time;
| |||
| |||
public:
| |||
CIndicators(void);
| |||
~CIndicators(void);
| |||
//--- method for creation
| |||
CIndicator *Create(const string symbol,const ENUM_TIMEFRAMES period,
| |||
const ENUM_INDICATOR type,const int count,const MqlParam ¶ms[]);
| |||
bool BufferResize(const int size);
| |||
//--- method of refreshing of the data of all indicators in the collection
| |||
int Refresh(void);
| |||
protected:
| |||
//--- method of formation of flags timeframes
| |||
int TimeframesFlags(const MqlDateTime &time);
| |||
};
| |||
//+------------------------------------------------------------------+
| |||
//| Constructor |
| |||
//+------------------------------------------------------------------+
| |||
CIndicators::CIndicators(void)
| |||
{
| |||
m_prev_time.min=-1;
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Destructor |
| |||
//+------------------------------------------------------------------+
| |||
CIndicators::~CIndicators(void)
| |||
{
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Indicator creation |
| |||
//+------------------------------------------------------------------+
| |||
CIndicator *CIndicators::Create(const string symbol,const ENUM_TIMEFRAMES period,
| |||
const ENUM_INDICATOR type,const int count,const MqlParam ¶ms[])
| |||
{
| |||
CIndicator *result=NULL;
| |||
//---
| |||
switch(type)
| |||
{
| |||
case IND_AC:
| |||
//--- Identifier of "Accelerator Oscillator"
| |||
if(count==0)
| |||
result=new CiAC;
| |||
break;
| |||
case IND_AD:
| |||
//--- Identifier of "Accumulation/Distribution"
| |||
if(count==1)
| |||
result=new CiAD;
| |||
break;
| |||
case IND_ALLIGATOR:
| |||
//--- Identifier of "Alligator"
| |||
if(count==8)
| |||
result=new CiAlligator;
| |||
break;
| |||
case IND_ADX:
| |||
//--- Identifier of "Average Directional Index"
| |||
if(count==1)
| |||
result=new CiADX;
| |||
break;
| |||
case IND_ADXW:
| |||
//--- Identifier of "Average Directional Index by Welles Wilder"
| |||
if(count==1)
| |||
result=new CiADXWilder;
| |||
break;
| |||
case IND_ATR:
| |||
//--- Identifier of "Average True Range"
| |||
if(count==1)
| |||
result=new CiATR;
| |||
break;
| |||
case IND_AO:
| |||
//--- Identifier of "Awesome Oscillator"
| |||
if(count==0)
| |||
result=new CiAO;
| |||
break;
| |||
case IND_BEARS:
| |||
//--- Identifier of "Bears Power"
| |||
if(count==1)
| |||
result=new CiBearsPower;
| |||
break;
| |||
case IND_BANDS:
| |||
//--- Identifier of "Bollinger Bands"
| |||
if(count==4)
| |||
result=new CiBands;
| |||
break;
| |||
case IND_BULLS:
| |||
//--- Identifier of "Bulls Power"
| |||
if(count==1)
| |||
result=new CiBullsPower;
| |||
break;
| |||
case IND_CCI:
| |||
//--- Identifier of "Commodity Channel Index"
| |||
if(count==2)
| |||
result=new CiCCI;
| |||
break;
| |||
case IND_CHAIKIN:
| |||
//--- Identifier of "Chaikin Oscillator"
| |||
if(count==4)
| |||
result=new CiChaikin;
| |||
break;
| |||
case IND_DEMARKER:
| |||
//--- Identifier of "DeMarker"
| |||
if(count==1)
| |||
result=new CiDeMarker;
| |||
break;
| |||
case IND_ENVELOPES:
| |||
//--- Identifier of "Envelopes"
| |||
if(count==5)
| |||
result=new CiEnvelopes;
| |||
break;
| |||
case IND_FORCE:
| |||
//--- Identifier of "Force Index"
| |||
if(count==3)
| |||
result=new CiForce;
| |||
break;
| |||
case IND_FRACTALS:
| |||
//--- Identifier of "Fractals"
| |||
if(count==0)
| |||
result=new CiFractals;
| |||
break;
| |||
case IND_GATOR:
| |||
//--- Identifier of "Gator oscillator"
| |||
if(count==8)
| |||
result=new CiGator;
| |||
break;
| |||
case IND_ICHIMOKU:
| |||
//--- Identifier of "Ichimoku Kinko Hyo"
| |||
if(count==3)
| |||
result=new CiIchimoku;
| |||
break;
| |||
case IND_MACD:
| |||
//--- Identifier of "Moving Averages Convergence-Divergence"
| |||
if(count==4)
| |||
result=new CiMACD;
| |||
break;
| |||
case IND_BWMFI:
| |||
//--- Identifier of "Market Facilitation Index by Bill Williams"
| |||
if(count==1)
| |||
result=new CiBWMFI;
| |||
break;
| |||
case IND_MOMENTUM:
| |||
//--- Identifier of "Momentum"
| |||
if(count==2)
| |||
result=new CiMomentum;
| |||
break;
| |||
case IND_MFI:
| |||
//--- Identifier of "Money Flow Index"
| |||
if(count==2)
| |||
result=new CiMFI;
| |||
break;
| |||
case IND_MA:
| |||
//--- Identifier of "Moving Average"
| |||
if(count==4)
| |||
result=new CiMA;
| |||
break;
| |||
case IND_OSMA:
| |||
//--- Identifier of "Moving Average of Oscillator (MACD histogram)"
| |||
if(count==4)
| |||
result=new CiOsMA;
| |||
break;
| |||
case IND_OBV:
| |||
//--- Identifier of "On Balance Volume"
| |||
if(count==1)
| |||
result=new CiOBV;
| |||
break;
| |||
case IND_SAR:
| |||
//--- Identifier of "Parabolic Stop And Reverse System"
| |||
if(count==2)
| |||
result=new CiSAR;
| |||
break;
| |||
case IND_RSI:
| |||
//--- Identifier of "Relative Strength Index"
| |||
if(count==2)
| |||
result=new CiRSI;
| |||
break;
| |||
case IND_RVI:
| |||
//--- Identifier of "Relative Vigor Index"
| |||
if(count==1)
| |||
result=new CiRVI;
| |||
break;
| |||
case IND_STDDEV:
| |||
//--- Identifier of "Standard Deviation"
| |||
if(count==4)
| |||
result=new CiStdDev;
| |||
break;
| |||
case IND_STOCHASTIC:
| |||
//--- Identifier of "Stochastic Oscillator"
| |||
if(count==5)
| |||
result=new CiStochastic;
| |||
break;
| |||
case IND_WPR:
| |||
//--- Identifier of "Williams' Percent Range"
| |||
if(count==1)
| |||
result=new CiWPR;
| |||
break;
| |||
case IND_DEMA:
| |||
//--- Identifier of "Double Exponential Moving Average"
| |||
if(count==3)
| |||
result=new CiDEMA;
| |||
break;
| |||
case IND_TEMA:
| |||
//--- Identifier of "Triple Exponential Moving Average"
| |||
if(count==3)
| |||
result=new CiTEMA;
| |||
break;
| |||
case IND_TRIX:
| |||
//--- Identifier of "Triple Exponential Moving Averages Oscillator"
| |||
if(count==2)
| |||
result=new CiTriX;
| |||
break;
| |||
case IND_FRAMA:
| |||
//--- Identifier of "Fractal Adaptive Moving Average"
| |||
if(count==3)
| |||
result=new CiFrAMA;
| |||
break;
| |||
case IND_AMA:
| |||
//--- Identifier of "Adaptive Moving Average"
| |||
if(count==5)
| |||
result=new CiAMA;
| |||
break;
| |||
case IND_VIDYA:
| |||
//--- Identifier of "Variable Index DYnamic Average"
| |||
if(count==4)
| |||
result=new CiVIDyA;
| |||
break;
| |||
case IND_VOLUMES:
| |||
//--- Identifier of "Volumes"
| |||
if(count==1)
| |||
result=new CiVolumes;
| |||
break;
| |||
//--- Identifier of "Custom"
| |||
case IND_CUSTOM:
| |||
if(count>0)
| |||
result=new CiCustom;
| |||
break;
| |||
}
| |||
if(result!=NULL)
| |||
{
| |||
if(result.Create(symbol,period,type,count,params))
| |||
Add(result);
| |||
else
| |||
{
| |||
delete result;
| |||
result=NULL;
| |||
}
| |||
}
| |||
//---
| |||
return(result);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Set size of buffers of all indicators in the collection |
| |||
//+------------------------------------------------------------------+
| |||
bool CIndicators::BufferResize(const int size)
| |||
{
| |||
int total=Total();
| |||
for(int i=0;i<total;i++)
| |||
{
| |||
CSeries *series=At(i);
| |||
//--- check pointer
| |||
if(series==NULL)
| |||
return(false);
| |||
if(!series.BufferResize(size))
| |||
return(false);
| |||
}
| |||
//--- ok
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Refreshing of the data of all indicators in the collection |
| |||
//+------------------------------------------------------------------+
| |||
int CIndicators::Refresh(void)
| |||
{
| |||
MqlDateTime time;
| |||
TimeCurrent(time);
| |||
//---
| |||
int flags=TimeframesFlags(time);
| |||
int total=Total();
| |||
//---
| |||
for(int i=0;i<total;i++)
| |||
{
| |||
CSeries *indicator=At(i);
| |||
if(indicator!=NULL)
| |||
indicator.Refresh(flags);
| |||
}
| |||
//---
| |||
m_prev_time=time;
| |||
//---
| |||
return(flags);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Formation of timeframe flags |
| |||
//+------------------------------------------------------------------+
| |||
int CIndicators::TimeframesFlags(const MqlDateTime &time)
| |||
{
| |||
//--- set flags for all timeframes
| |||
int result=OBJ_ALL_PERIODS;
| |||
//--- if first check, then setting flags all timeframes
| |||
if(m_prev_time.min==-1)
| |||
return(result);
| |||
//--- check change time
| |||
if(time.min==m_prev_time.min &&
| |||
time.hour==m_prev_time.hour &&
| |||
time.day==m_prev_time.day &&
| |||
time.mon==m_prev_time.mon)
| |||
return(OBJ_NO_PERIODS);
| |||
//--- new month?
| |||
if(time.mon!=m_prev_time.mon)
| |||
return(result);
| |||
//--- reset the "new month" flag
| |||
result^=OBJ_PERIOD_MN1;
| |||
//--- new day?
| |||
if(time.day!=m_prev_time.day)
| |||
return(result);
| |||
//--- reset the "new day" and "new week" flags
| |||
result^=OBJ_PERIOD_D1+OBJ_PERIOD_W1;
| |||
//--- temporary variables to speed up working with structures
| |||
int curr,delta;
| |||
//--- new hour?
| |||
curr=time.hour;
| |||
delta=curr-m_prev_time.hour;
| |||
if(delta!=0)
| |||
{
| |||
if(curr%2>=delta)
| |||
result^=OBJ_PERIOD_H2;
| |||
if(curr%3>=delta)
| |||
result^=OBJ_PERIOD_H3;
| |||
if(curr%4>=delta)
| |||
result^=OBJ_PERIOD_H4;
| |||
if(curr%6>=delta)
| |||
result^=OBJ_PERIOD_H6;
| |||
if(curr%8>=delta)
| |||
result^=OBJ_PERIOD_H8;
| |||
if(curr%12>=delta)
| |||
result^=OBJ_PERIOD_H12;
| |||
return(result);
| |||
}
| |||
//--- reset all flags for hour timeframes
| |||
result^=OBJ_PERIOD_H1+OBJ_PERIOD_H2+OBJ_PERIOD_H3+OBJ_PERIOD_H4+OBJ_PERIOD_H6+OBJ_PERIOD_H8+OBJ_PERIOD_H12;
| |||
//--- new minute?
| |||
curr=time.min;
| |||
delta=curr-m_prev_time.min;
| |||
if(delta!=0)
| |||
{
| |||
if(curr%2>=delta)
| |||
result^=OBJ_PERIOD_M2;
| |||
if(curr%3>=delta)
| |||
result^=OBJ_PERIOD_M3;
| |||
if(curr%4>=delta)
| |||
result^=OBJ_PERIOD_M4;
| |||
if(curr%5>=delta)
| |||
result^=OBJ_PERIOD_M5;
| |||
if(curr%6>=delta)
| |||
result^=OBJ_PERIOD_M6;
| |||
if(curr%10>=delta)
| |||
result^=OBJ_PERIOD_M10;
| |||
if(curr%12>=delta)
| |||
result^=OBJ_PERIOD_M12;
| |||
if(curr%15>=delta)
| |||
result^=OBJ_PERIOD_M15;
| |||
if(curr%20>=delta)
| |||
result^=OBJ_PERIOD_M20;
| |||
if(curr%30>=delta)
| |||
result^=OBJ_PERIOD_M30;
| |||
}
| |||
//---
| |||
return(result);
| |||
}
| |||
//+------------------------------------------------------------------+
|