//------------------------------------------------------------------ #property copyright "© mladen, 2018" #property link "mladenfx@gmail.com" //------------------------------------------------------------------ #property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 2 #property indicator_label1 "JMA" #property indicator_type1 DRAW_COLOR_LINE #property indicator_color1 clrDarkGray,clrCrimson,clrLimeGreen #property indicator_style1 STYLE_DOT #property indicator_label2 "Corrected JMA" #property indicator_type2 DRAW_COLOR_LINE #property indicator_color2 clrDarkGray,clrCrimson,clrLimeGreen #property indicator_width2 2 //--- input parameters input double inpPeriod = 4; // Period input ENUM_APPLIED_PRICE inpPrice = PRICE_CLOSE; // Price //--- indicator buffers double val[],valc[],avg[],avgc[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,avg,INDICATOR_DATA); SetIndexBuffer(1,avgc,INDICATOR_COLOR_INDEX); SetIndexBuffer(2,val,INDICATOR_DATA); SetIndexBuffer(3,valc,INDICATOR_COLOR_INDEX); //--- indicator short name assignment IndicatorSetString(INDICATOR_SHORTNAME,"Corrected JMA ("+(string)inpPeriod+")"); //--- return (INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator de-initialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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(Bars(_Symbol,_Period)0) ?(val[i]avg[i]) ? 1 : valc[i-1]: 0; avgc[i] = valc[i]; } return(rates_total); } //+------------------------------------------------------------------+ //| Custom functions | //+------------------------------------------------------------------+ #define _corrMaInstances 1 #define _corrMaInstancesSize 3 double workCorrMa[][_corrMaInstances*_corrMaInstancesSize]; #define _price 0 #define _orig 1 #define _corr 2 // //--- // double iCorrMa(double _avg, double price, int period, int i, int _bars, int instanceNo=0) { if (ArrayRange(workCorrMa,0)!= _bars) ArrayResize(workCorrMa,_bars); instanceNo*=_corrMaInstancesSize; workCorrMa[i][_price] = price; workCorrMa[i][_orig] = _avg; // //--- // double oldMean = price; double newMean = price; double squares = 0; int k=1; for (; k=0; k++) { newMean = (workCorrMa[i-k][_price]-oldMean)/(k+1)+oldMean; squares += (workCorrMa[i-k][_price]-oldMean)*(workCorrMa[i-k][_price]-newMean); oldMean = newMean; } double _deviation = MathSqrt(squares/k); double v1 = MathPow(_deviation,2); double v2 = (i>0) ? MathPow(workCorrMa[i-1][_corr]-workCorrMa[i][_orig],2) : 0; double c = (v20) ? workCorrMa[i-1][_corr]+c*(workCorrMa[i][_orig]-workCorrMa[i-1][_corr]) : workCorrMa[i][_orig]; return(workCorrMa[i][_corr]); #undef _price #undef _orig #undef _corr } // //--- // #define _smoothInstances 1 #define _smoothInstancesSize 10 double m_wrk[][_smoothInstances*_smoothInstancesSize]; int m_size=0; // //--- // double iSmooth(double price,double length,double phase,int r,int bars,int instanceNo=0) { #define bsmax 5 #define bsmin 6 #define volty 7 #define vsum 8 #define avolty 9 if(ArrayRange(m_wrk,0)!=bars) ArrayResize(m_wrk,bars); if(ArrayRange(m_wrk,0)!=bars) return(price); instanceNo*=_smoothInstancesSize; if(r==0 || length<=1) { int k=0; for(; k<7; k++) m_wrk[r][instanceNo+k]=price; for(; k<10; k++) m_wrk[r][instanceNo+k]=0; return(price); } // //--- // double len1 = MathMax(MathLog(MathSqrt(0.5*(length-1)))/MathLog(2.0)+2.0,0); double pow1 = MathMax(len1-2.0,0.5); double del1 = price - m_wrk[r-1][instanceNo+bsmax]; double del2 = price - m_wrk[r-1][instanceNo+bsmin]; int forBar = MathMin(r,10); m_wrk[r][instanceNo+volty]=0; if(MathAbs(del1) > MathAbs(del2)) m_wrk[r][instanceNo+volty] = MathAbs(del1); if(MathAbs(del1) < MathAbs(del2)) m_wrk[r][instanceNo+volty] = MathAbs(del2); m_wrk[r][instanceNo+vsum]=m_wrk[r-1][instanceNo+vsum]+(m_wrk[r][instanceNo+volty]-m_wrk[r-forBar][instanceNo+volty])*0.1; // //--- // m_wrk[r][instanceNo+avolty]=m_wrk[r-1][instanceNo+avolty]+(2.0/(MathMax(4.0*length,30)+1.0))*(m_wrk[r][instanceNo+vsum]-m_wrk[r-1][instanceNo+avolty]); double dVolty=(m_wrk[r][instanceNo+avolty]>0) ? m_wrk[r][instanceNo+volty]/m_wrk[r][instanceNo+avolty]: 0; if(dVolty > MathPow(len1,1.0/pow1)) dVolty = MathPow(len1,1.0/pow1); if(dVolty < 1) dVolty = 1.0; // //--- // double pow2 = MathPow(dVolty, pow1); double len2 = MathSqrt(0.5*(length-1))*len1; double Kv = MathPow(len2/(len2+1), MathSqrt(pow2)); if(del1 > 0) m_wrk[r][instanceNo+bsmax] = price; else m_wrk[r][instanceNo+bsmax] = price - Kv*del1; if(del2 < 0) m_wrk[r][instanceNo+bsmin] = price; else m_wrk[r][instanceNo+bsmin] = price - Kv*del2; // //--- // double corr = MathMax(MathMin(phase,100),-100)/100.0 + 1.5; double beta = 0.45*(length-1)/(0.45*(length-1)+2); double alpha = MathPow(beta,pow2); m_wrk[r][instanceNo+0] = price + alpha*(m_wrk[r-1][instanceNo+0]-price); m_wrk[r][instanceNo+1] = (price - m_wrk[r][instanceNo+0])*(1-beta) + beta*m_wrk[r-1][instanceNo+1]; m_wrk[r][instanceNo+2] = (m_wrk[r][instanceNo+0] + corr*m_wrk[r][instanceNo+1]); m_wrk[r][instanceNo+3] = (m_wrk[r][instanceNo+2] - m_wrk[r-1][instanceNo+4])*MathPow((1-alpha),2) + MathPow(alpha,2)*m_wrk[r-1][instanceNo+3]; m_wrk[r][instanceNo+4] = (m_wrk[r-1][instanceNo+4] + m_wrk[r][instanceNo+3]); // //--- // return(m_wrk[r][instanceNo+4]); #undef bsmax #undef bsmin #undef volty #undef vsum #undef avolty } // //--- // double getPrice(ENUM_APPLIED_PRICE tprice,const double &open[],const double &close[],const double &high[],const double &low[],int i,int _bars) { if(i>=0) switch(tprice) { case PRICE_CLOSE: return(close[i]); case PRICE_OPEN: return(open[i]); case PRICE_HIGH: return(high[i]); case PRICE_LOW: return(low[i]); case PRICE_MEDIAN: return((high[i]+low[i])/2.0); case PRICE_TYPICAL: return((high[i]+low[i]+close[i])/3.0); case PRICE_WEIGHTED: return((high[i]+low[i]+close[i]+close[i])/4.0); } return(0); } //+------------------------------------------------------------------+