NUNA/Logs/Indicators/Downloads/ADXm (experiment).mq5
2026-01-06 05:44:21 +00:00

167 行
11 KiB
MQL5

//----------------------------------------------------------------------------------------------
#property copyright "© mladen, 2022"
#property link "mladenfx@gmail.com"
//----------------------------------------------------------------------------------------------
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots 2
#property indicator_label1 "DI"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrDarkGray
#property indicator_label2 "ADXm"
#property indicator_type2 DRAW_COLOR_LINE
#property indicator_color2 clrDarkGray,clrDodgerBlue,clrSandyBrown
#property indicator_width2 2
//
//
//
input double inpAdxmPeriod = 14; // ADXm period
enum enDouble
{
adxm_regular, // Regular ADXm
adxm_double, // ADXm of ADXm
};
input enDouble inpDouble = adxm_regular; // ADXm calculating mode
//
//
//
double adxm[],adxmc[],di[];
//----------------------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------------------
//
//
//
int OnInit()
{
SetIndexBuffer(0,di ,INDICATOR_DATA);
SetIndexBuffer(1,adxm ,INDICATOR_DATA);
SetIndexBuffer(2,adxmc,INDICATOR_COLOR_INDEX);
//
//
//
IndicatorSetString(INDICATOR_SHORTNAME,StringFormat("ADXm experiment (%.2f,%s)",inpAdxmPeriod,StringSubstr(EnumToString(inpDouble),5)));
return (INIT_SUCCEEDED);
}
void OnDeinit(const int reason) { }
//----------------------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------------------
//
//
//
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
int limit = (prev_calculated>0) ? prev_calculated -1 : 0;
//
//
//
for (int i=limit; i<rates_total && !_StopFlag; i++)
{
if (inpDouble==adxm_double)
{
double _di;
double _adxm = iAdxm(close[i],high[i],low[i],inpAdxmPeriod,_di,i,rates_total,0);
adxm[i] = iAdxm(_adxm,_adxm,_adxm,inpAdxmPeriod,di[i],i,rates_total,1);
}
else adxm[i] = iAdxm(close[i],high[i],low[i],inpAdxmPeriod,di[i],i,rates_total);
adxmc[i] = (i>0) ? (adxm[i]>adxm[i-1]) ? 1 : (adxm[i]<adxm[i-1]) ? 2 : adxmc[i-1]: 0;
}
return (rates_total);
}
//----------------------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------------------
//
//
//
#define _adxmInstances 2
double iAdxm(double _close, double _high, double _low, double _period, double &_di, int i, int _bars, int instance=0)
{
struct sDataStruct
{
double di;
double adx;
double close;
double high;
double low;
double sdh;
double sdl;
};
struct sWorkStruct { sDataStruct data[_adxmInstances]; };
static sWorkStruct m_work[];
static int m_workSize = -1;
if (m_workSize<_bars) m_workSize = ArrayResize(m_work,_bars+500,2000);
//
//
//
#define _max(_a,_b) ((_a)>(_b)?(_a):(_b))
#define _min(_a,_b) ((_a)<(_b)?(_a):(_b))
#define _abs(_a) ((_a)>0.0?(_a):-(_a))
//
//
//
m_work[i].data[instance].close = _close;
m_work[i].data[instance].high = _high;
m_work[i].data[instance].low = _low;
double hc = _high;
double lc = _low;
double cp = (i>0) ? m_work[i-1].data[instance].close : _close;
double hp = (i>0) ? m_work[i-1].data[instance].high : _high;
double lp = (i>0) ? m_work[i-1].data[instance].low : _low;
double dh = (hc>hp) ? hc-hp : 0;
double dl = (lp>lc) ? lp-lc : 0;
if (dh<dl) dh = 0;
else if (dl<dh) dl = 0;
else { dh = dl = 0; }
double tr = _max(hc,cp)-_min(lc,cp);
double dhk = (tr!=0) ? 100.0*dh/tr : 0;
double dlk = (tr!=0) ? 100.0*dl/tr : 0;
double alpha = (_period>1) ? 2.0/(_period+1.0) : 1;
m_work[i].data[instance].sdh = (i>0) ? m_work[i-1].data[instance].sdh + alpha*(dhk-m_work[i-1].data[instance].sdh) : dhk;
m_work[i].data[instance].sdl = (i>0) ? m_work[i-1].data[instance].sdl + alpha*(dlk-m_work[i-1].data[instance].sdl) : dlk;
m_work[i].data[instance].di = _di = m_work[i].data[instance].sdh - m_work[i].data[instance].sdl;
double div = m_work[i].data[instance].sdh + m_work[i].data[instance].sdl; div = _abs(div);
double temp = (div!=0.0) ? 100.0*m_work[i].data[instance].di/div : 0;
m_work[i].data[instance].adx = (i>0) ? m_work[i-1].data[instance].adx + alpha*(temp-m_work[i-1].data[instance].adx) : 0;
return(m_work[i].data[instance].adx);
//
//
//
#undef _max #undef _min #undef _abs
}