NUNA/Logs/Indicators/Downloads/Rex (extended).mq5

252 lines
16 KiB
MQL5
Raw Permalink Normal View History

2026-01-06 05:44:21 +00:00
<EFBFBD><EFBFBD>//------------------------------------------------------------------------------------------------
#property copyright "<00> mladen, 2021"
#property link "mladenfx@gmail.com"
#property version "1.00"
//------------------------------------------------------------------------------------------------
#property indicator_separate_window
#property indicator_buffers 6
#property indicator_plots 4
#property indicator_label1 "Uper DC"
#property indicator_type1 DRAW_FILLING
#property indicator_color1 clrBisque
#property indicator_label2 "Lower DC"
#property indicator_type2 DRAW_FILLING
#property indicator_color2 clrPaleGreen
#property indicator_label3 "Rex"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrDarkOrange
#property indicator_width3 2
#property indicator_label4 "Rex signal"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrDarkGray
//
//
//
input uint inpPeriod = 14; // Rex period
input ENUM_MA_METHOD inpMethod = MODE_SMA; // Rex method
input uint inpPeriodSig = 14; // Signal period
input ENUM_MA_METHOD inpMethodSig = MODE_SMA; // Signal method
input uint inpDcPeriod = 89; // Donchian channel period
//
//
//
double val[],sig[],dcuph[],dcupl[],dcdnh[],dcdnl[];
#define _maName(_method) StringSubstr(EnumToString(_method),5)
typedef double (*TAverage)(double price, int period, int index, int bars, int instance=0); TAverage rexAverage,sigAverage;
//------------------------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------------------------
//
//
//
int OnInit()
{
SetIndexBuffer(0,dcuph,INDICATOR_DATA);
SetIndexBuffer(1,dcupl,INDICATOR_DATA);
SetIndexBuffer(2,dcdnh,INDICATOR_DATA);
SetIndexBuffer(3,dcdnl,INDICATOR_DATA);
SetIndexBuffer(4,val ,INDICATOR_DATA);
SetIndexBuffer(5,sig ,INDICATOR_DATA);
//
//
//
switch (inpMethod)
{
case MODE_SMA : rexAverage = iSma; break;
case MODE_EMA : rexAverage = iEma; break;
case MODE_SMMA : rexAverage = iSmma; break;
case MODE_LWMA : rexAverage = iLwma; break;
}
switch (inpMethodSig)
{
case MODE_SMA : sigAverage = iSma; break;
case MODE_EMA : sigAverage = iEma; break;
case MODE_SMMA : sigAverage = iSmma; break;
case MODE_LWMA : sigAverage = iLwma; break;
}
//
//
//
IndicatorSetString(INDICATOR_SHORTNAME,StringFormat("Rex (%i %s,%i %s, %i)",inpPeriod,_maName(inpMethod),inpPeriodSig,_maName(inpMethodSig),inpDcPeriod));
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason) { return; }
//------------------------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------------------------
//
//
//
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; i++)
{
double _rexPrice = 3.0*close[i]-(low[i]+open[i]+high[i]);
val[i] = rexAverage(_rexPrice,inpPeriod ,i,rates_total,0);
sig[i] = sigAverage(val[i] ,inpPeriodSig,i,rates_total,1);
//
//
//
if (inpDcPeriod>0)
{
int _start = int(i-inpDcPeriod); if (_start<0) _start=0;
double _max = val[ArrayMaximum(val,_start,inpDcPeriod)];
double _min = val[ArrayMinimum(val,_start,inpDcPeriod)];
dcuph[i] = _max; dcupl[i] = _max-(_max-_min)/5.0;
dcdnl[i] = _min; dcdnh[i] = _min+(_max-_min)/5.0;
}
else dcuph[i] = dcupl[i] = dcdnh[i] = dcdnl[i] = EMPTY_VALUE;
}
//
//
//
return(rates_total);
}
//------------------------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------------------------
//
//
//
#define _maInstances 2
double iSma(double value, int period, int i, int bars, int instanceNo=0)
{
struct sdataStruct
{
double value;
double valueSum;
};
struct sWorkStruct { sdataStruct data[_maInstances]; };
static sWorkStruct m_work[];
static int m_workSize = -1;
if (m_workSize<bars) m_workSize = ArrayResize(m_work,bars+500,2000);
//
//
//
m_work[i].data[instanceNo].value = value;
if (i>=period)
{ m_work[i].data[instanceNo].valueSum = m_work[i-1].data[instanceNo].valueSum + m_work[i].data[instanceNo].value - m_work[i-period].data[instanceNo].value; }
else { m_work[i].data[instanceNo].valueSum = m_work[i].data[instanceNo].value; for (int k=1; k<period && i>=k; k++) m_work[i].data[instanceNo].valueSum += m_work[i-k].data[instanceNo].value; }
return (period>0 ? m_work[i].data[instanceNo].valueSum/(double)period : m_work[i].data[instanceNo].value);
}
//
//
//
double iEma(double value, int period, int i, int bars, int instanceNo=0)
{
struct sdataStruct
{
double ema;
};
struct sWorkStruct { sdataStruct data[_maInstances]; };
static sWorkStruct m_work[];
static int m_workSize = -1;
if (m_workSize<bars) m_workSize = ArrayResize(m_work,bars+500,2000);
//
//
//
m_work[i].data[instanceNo].ema = (i>0 && period >1) ? m_work[i-1].data[instanceNo].ema + (2.0 / (1.0 + (double)period))*(value - m_work[i-1].data[instanceNo].ema) : value;
return (m_work[i].data[instanceNo].ema);
}
//
//
//
double iSmma(double value, int period, int i, int bars, int instanceNo=0)
{
struct sdataStruct
{
double smma;
};
struct sWorkStruct { sdataStruct data[_maInstances]; };
static sWorkStruct m_work[];
static int m_workSize = -1;
if (m_workSize<bars) m_workSize = ArrayResize(m_work,bars+500,2000);
//
//
//
m_work[i].data[instanceNo].smma = (i>0 && period >1) ? m_work[i-1].data[instanceNo].smma + (value - m_work[i-1].data[instanceNo].smma)/(double)period : value;
return (m_work[i].data[instanceNo].smma);
}
//
//
//
double iLwma(double value, int period, int i, int bars, int instanceNo=0)
{
struct sdataStruct
{
double value;
};
struct sWorkStruct { sdataStruct data[_maInstances]; };
static sWorkStruct m_work[];
static int m_workSize = -1;
if (m_workSize<bars) m_workSize = ArrayResize(m_work,bars+500,2000);
//
//
//
m_work[i].data[instanceNo].value = value;
//
//
//
double sumw = period;
double sum = period*m_work[i].data[instanceNo].value;
if (period>1)
for(int k=1; k<period && i>=k; k++)
{
double weight = period-k;
sumw += weight;
sum += weight*m_work[i-k].data[instanceNo].value;
}
else sumw = 1;
return (sum/sumw);
}