Miscellaneous
0
Views
0
Downloads
0
Favorites
Corr Wilder EMA (fl)(mtf)
ÿþ//------------------------------------------------------------------
#property copyright "© mladen, 2019"
#property link "mladenfx@gmail.com"
#property description "Corrected double smoothed Wilder's EMA"
//------------------------------------------------------------------
#property indicator_chart_window
#property indicator_buffers 9
#property indicator_plots 4
#property indicator_label1 "Corrected average zone"
#property indicator_type1 DRAW_FILLING
#property indicator_color1 C'230,230,230'
#property indicator_label2 "Corrected average middle"
#property indicator_type2 DRAW_LINE
#property indicator_style2 STYLE_DOT
#property indicator_color2 clrGray
#property indicator_label3 "Corrected average original"
#property indicator_type3 DRAW_COLOR_LINE
#property indicator_color3 clrSilver,clrMediumSeaGreen,clrOrangeRed
#property indicator_label4 "Corrected average "
#property indicator_type4 DRAW_COLOR_LINE
#property indicator_color4 clrSilver,clrMediumSeaGreen,clrOrangeRed
#property indicator_width4 3
//
//---
//
enum enTimeFrames
{
tf_cu = PERIOD_CURRENT, // Current time frame
tf_m1 = PERIOD_M1, // 1 minute
tf_m2 = PERIOD_M2, // 2 minutes
tf_m3 = PERIOD_M3, // 3 minutes
tf_m4 = PERIOD_M4, // 4 minutes
tf_m5 = PERIOD_M5, // 5 minutes
tf_m6 = PERIOD_M6, // 6 minutes
tf_m10 = PERIOD_M10, // 10 minutes
tf_m12 = PERIOD_M12, // 12 minutes
tf_m15 = PERIOD_M15, // 15 minutes
tf_m20 = PERIOD_M20, // 20 minutes
tf_m30 = PERIOD_M30, // 30 minutes
tf_h1 = PERIOD_H1, // 1 hour
tf_h2 = PERIOD_H2, // 2 hours
tf_h3 = PERIOD_H3, // 3 hours
tf_h4 = PERIOD_H4, // 4 hours
tf_h6 = PERIOD_H6, // 6 hours
tf_h8 = PERIOD_H8, // 8 hours
tf_h12 = PERIOD_H12, // 12 hours
tf_d1 = PERIOD_D1, // daily
tf_w1 = PERIOD_W1, // weekly
tf_mn = PERIOD_MN1, // monthly
tf_cp1 = -1, // Next higher time frame
tf_cp2 = -2, // Second higher time frame
tf_cp3 = -3 // Third higher time frame
};
input enTimeFrames inpTimeFrame = tf_cu; // Time frame
input int inpPeriod = 14; // Average period
input ENUM_APPLIED_PRICE inpPrice = PRICE_CLOSE; // Price
input int inpCorrectionPeriod = 0; // "Correction" period (<0 no correction,0 to 1 same as average)
enum chgColor
{
chg_onSlope, // change color on slope change
chg_onLevel, // Change color on outer levels cross
chg_onMiddle, // Change color on middle level cross
chg_onOrig // Change color on average value cross
};
input chgColor inpColorOn = chg_onLevel; // Color change on :
input int inpFlPeriod = 25; // Period for finding floating levels
input double inpFlUp = 90; // Upper level %
input double inpFlDown = 10; // Lower level %
enum enIterpolate
{
interolate_yes=(int)true, // Interpolate data when in multi time frame
interolate_no =(int)false // Do not interpolate data when in multi time frame
};
input enIterpolate inpInterpolate = interolate_yes; // Interpolation
//
//---
//
double val[],valc[],mid[],fup[],fdn[],avg[],avgw[],avgc[],count[],_alpha;
int ª_maPeriod,ª_corrPeriod,ª_colorOn,ª_mtfHandle;
ENUM_TIMEFRAMES _indicatorTimeFrame; string _indicatorName;
#define _mtfCall iCustom(_Symbol,_indicatorTimeFrame,_indicatorName,0,inpPeriod,inpPrice,inpCorrectionPeriod,inpColorOn,inpFlPeriod,inpFlUp,inpFlDown)
//------------------------------------------------------------------
//
//------------------------------------------------------------------
int OnInit()
{
//
//---
//
SetIndexBuffer(0,fup ,INDICATOR_DATA);
SetIndexBuffer(1,fdn ,INDICATOR_DATA);
SetIndexBuffer(2,mid ,INDICATOR_DATA);
SetIndexBuffer(3,avg ,INDICATOR_DATA);
SetIndexBuffer(4,avgc ,INDICATOR_COLOR_INDEX);
SetIndexBuffer(5,val ,INDICATOR_DATA);
SetIndexBuffer(6,valc ,INDICATOR_COLOR_INDEX);
SetIndexBuffer(7,avgw ,INDICATOR_CALCULATIONS);
SetIndexBuffer(8,count,INDICATOR_CALCULATIONS);
//
//---
//
_indicatorTimeFrame = MathMax(_Period,timeFrameGet(inpTimeFrame));
if (_indicatorTimeFrame != _Period) { _indicatorName = getIndicatorName(); ª_mtfHandle = _mtfCall; if (!_checkHandle(ª_mtfHandle,"Target time frame instance")) return(INIT_FAILED); }
ª_corrPeriod = (inpCorrectionPeriod>0) ? inpCorrectionPeriod : (inpCorrectionPeriod<0) ? 0 : inpPeriod ;
ª_colorOn = (inpFlPeriod>1 && ª_corrPeriod>1) ? inpColorOn : (inpColorOn!=chg_onOrig) ? inpColorOn : chg_onSlope;
ª_maPeriod = (inpPeriod>1) ? inpPeriod : 1;
_alpha = 1.0 /MathSqrt(ª_maPeriod);
//
//---
//
IndicatorSetString(INDICATOR_SHORTNAME,timeFrameToString(_indicatorTimeFrame)+" \"Corrected\" Wilder\'s EMA ("+(string)inpPeriod+","+(string)inpCorrectionPeriod+")");
return(0);
}
//------------------------------------------------------------------
// Custom indicator iteration function
//------------------------------------------------------------------
//
//---
//
#define _setPrice(_priceType,_target,_index) \
{ \
switch(_priceType) \
{ \
case PRICE_CLOSE: _target = close[_index]; break; \
case PRICE_OPEN: _target = open[_index]; break; \
case PRICE_HIGH: _target = high[_index]; break; \
case PRICE_LOW: _target = low[_index]; break; \
case PRICE_MEDIAN: _target = (high[_index]+low[_index])/2.0; break; \
case PRICE_TYPICAL: _target = (high[_index]+low[_index]+close[_index])/3.0; break; \
case PRICE_WEIGHTED: _target = (high[_index]+low[_index]+close[_index]+close[_index])/4.0; break; \
default : _target = 0; \
}}
//
//---
//
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[])
{
//
//---
//
if(_indicatorTimeFrame!=_Period)
{
double result[1]; if (CopyBuffer(ª_mtfHandle,8,0,1,result)<0) result[0] = rates_total;
//
//---
//
#define _mtfRatio (double)PeriodSeconds((ENUM_TIMEFRAMES)_indicatorTimeFrame)/PeriodSeconds(_Period)
int n,k,i=MathMin(MathMax(prev_calculated-1,0),MathMax(rates_total-int(result[0]*_mtfRatio)-1,0)),_prevMark=-99; datetime _prevTime;
for(; i<rates_total && !_StopFlag; i++)
{
int _currMark = iBarShift(_Symbol,_indicatorTimeFrame,time[i]); if (_currMark<0) continue;
if (_currMark!=_prevMark)
{
_prevMark =_currMark;
_prevTime = time[i];
#define _mtfCopy(_buff,_buffNo) { if(CopyBuffer(ª_mtfHandle,_buffNo,_currMark,1,result)<1) break; _buff[i]=result[0]; }
_mtfCopy(fup ,0);
_mtfCopy(fdn ,1);
_mtfCopy(mid ,2);
_mtfCopy(avg ,3);
_mtfCopy(avgc,4);
_mtfCopy(val ,5);
_mtfCopy(valc,6);
}
else
{
#define _mtfCopyValue(_buff) _buff[i] = _buff[i-1];
_mtfCopyValue(fup);
_mtfCopyValue(fdn);
_mtfCopyValue(mid);
_mtfCopyValue(avg);
_mtfCopyValue(avgc);
_mtfCopyValue(val);
_mtfCopyValue(valc);
}
//
//---
//
if(!inpInterpolate) continue;
int _nextMark = (i<rates_total-1) ? iBarShift(_Symbol,_indicatorTimeFrame,time[i+1]) : _prevMark+1; if(_nextMark==_prevMark) continue;
for (n=1; (i-n)> 0 && time[i-n] >= _prevTime; n++) continue;
for (k=1; (i-k)>=0 && k<n; k++)
{
#define _mtfInterpolate(_buff) _buff[i-k]=_buff[i]+(_buff[i-n]-_buff[i])*k/n
_mtfInterpolate(fup);
_mtfInterpolate(fdn);
_mtfInterpolate(mid);
_mtfInterpolate(avg);
_mtfInterpolate(val);
}
}
return(i);
}
//
//
//----------------------------------------
//
//
static int prev_i=-1;
static double prev_max,prev_min;
//
//
//
int i= prev_calculated-1; if (i<0) i=0; for (; i<rates_total && !_StopFlag; i++)
{
double _price; _setPrice(inpPrice,_price,i);
if (i>0)
{
avgw[i] = avgw[i-1] + _alpha*(_price-avgw[i-1]);
avg[i] = avg[i-1] + _alpha*(avgw[i]-avg[i-1]);
}
else avg[i] = avgw[i] = _price;
val[i] = iCorrMa(_price,avg[i],ª_corrPeriod,i,rates_total);
//
//
//
if (prev_i!=i)
{
prev_i = i;
int start = i-inpFlPeriod+1; if (start<0) start=0;
prev_max = val[ArrayMaximum(val,start,inpFlPeriod-1)];
prev_min = val[ArrayMinimum(val,start,inpFlPeriod-1)];
}
double max = (val[i] > prev_max) ? val[i] : prev_max;
double min = (val[i] < prev_min) ? val[i] : prev_min;
double range = (max-min)/100.0;
fup[i] = min+inpFlUp *range;
fdn[i] = min+inpFlDown*range;
mid[i] = min+ 50.0*range;
//
//---
//
avgc[i] = (avg[i]>val[i]) ? 1 : (avg[i]<val[i]) ? 2 : 0;
switch (ª_colorOn)
{
case chg_onOrig : valc[i] = avgc[i]; break;
case chg_onLevel : valc[i] = (val[i]>fup[i]) ? 1 : (val[i]<fdn[i]) ? 2 : (i>0) ? (val[i]==val[i-1]) ? valc[i-1] : 0 : 0; break;
case chg_onMiddle : valc[i] = (val[i]>mid[i]) ? 1 : (val[i]<mid[i]) ? 2 : (i>0) ? (val[i]==val[i-1]) ? valc[i-1] : 0 : 0; break;
default : valc[i] = (i>0) ? (val[i]>val[i-1]) ? 1 : (val[i]<val[i-1]) ? 2 : valc[i-1] : 0;
}
}
count[rates_total-1]=MathMax(i-prev_calculated+1,1);
return(i);
}
//------------------------------------------------------------------
// Custom function(s)
//------------------------------------------------------------------
//
//---
//
double iCorrMa(double price, double average, int period, int i, int bars, int instance=0)
{
#define ¤ instance
#define _functionInstances 1
struct sCorrMaStruct
{
double corrected;
double price;
double price2;
double summ;
double summ2;
};
static sCorrMaStruct m_array[][_functionInstances];
static int m_arraySize=0;
if (m_arraySize<bars) { m_arraySize = ArrayResize(m_array,bars+500); if (m_arraySize<=bars) return(0); }
//
//---
//
m_array[i][¤].price = price;
m_array[i][¤].price2 = price*price;
if (i>period)
{
m_array[i][¤].summ = m_array[i-1][¤].summ +price -m_array[i-period][¤].price;
m_array[i][¤].summ2 = m_array[i-1][¤].summ2+m_array[i][¤].price2-m_array[i-period][¤].price2;
}
else {
m_array[i][¤].summ = m_array[i][¤].price;
m_array[i][¤].summ2 = m_array[i][¤].price2;
for(int k=1; k<period && i>=k; k++)
{
m_array[i][¤].summ += m_array[i-k][¤].price;
m_array[i][¤].summ2 += m_array[i-k][¤].price2;
}
}
//
//---
//
if (i>0)
{
double v1 = (m_array[i][¤].summ2-m_array[i][¤].summ*m_array[i][¤].summ/(double)period)/(double)period;
double v2 = (m_array[i-1][¤].corrected-average)*(m_array[i-1][¤].corrected-average);
double c = (v2<v1 || v2==0) ? 0 : 1.0-v1/v2;
m_array[i][¤].corrected = m_array[i-1][¤].corrected + c*(average-m_array[i-1][¤].corrected);
}
else m_array[i][¤].corrected = average;
return (m_array[i][¤].corrected);
//
//---
//
#undef ¤ #undef _functionInstances
}
//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
//
//---
//
ENUM_TIMEFRAMES _tfsPer[]={PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M20,PERIOD_M30,PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1};
string _tfsStr[]={"1 minute","2 minutes","3 minutes","4 minutes","5 minutes","6 minutes","10 minutes","12 minutes","15 minutes","20 minutes","30 minutes","1 hour","2 hours","3 hours","4 hours","6 hours","8 hours","12 hours","daily","weekly","monthly"};
//
//---
//
string timeFrameToString(int period)
{
if(period==PERIOD_CURRENT)
period=_Period;
int i; for(i=0;i<ArraySize(_tfsPer);i++) if(period==_tfsPer[i]) break;
return(_tfsStr[i]);
}
//
//---
//
ENUM_TIMEFRAMES timeFrameGet(int period)
{
int _shift = (period<0 ? MathAbs(period) : 0); if (period<=0) period=_Period;
int i; for(i=0;i<ArraySize(_tfsPer);i++) if(period==_tfsPer[i]) break;
return(_tfsPer[(int)MathMin(i+_shift,ArraySize(_tfsPer)-1)]);
}
//
//---
//
string getIndicatorName()
{
string _path=MQL5InfoString(MQL5_PROGRAM_PATH); StringToLower(_path);
string _partsA[];
int _partsN = StringSplit(_path,StringGetCharacter("\\",0),_partsA);
string name=_partsA[_partsN-1]; for(int n=_partsN-2; n>=0 && _partsA[n]!="indicators"; n--) name=_partsA[n]+"\\"+name;
return(name);
}
//
//---
//
bool _checkHandle(int _handle, string _description)
{
static int _chandles[];
int _size = ArraySize(_chandles);
bool _answer = (_handle!=INVALID_HANDLE);
if (_answer)
{ ArrayResize(_chandles,_size+1); _chandles[_size]=_handle; }
else { for (int i=_size-1; i>=0; i--) IndicatorRelease(_chandles[i]); ArrayResize(_chandles,0); Alert(_description+" initialization failed"); }
return(_answer);
}
//------------------------------------------------------------------
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---