//+------------------------------------------------------------------ #property copyright "© mladen, 2018" #property link "mladenfx@gmail.com" #property description "JMA z-score" //+------------------------------------------------------------------ #property indicator_separate_window #property indicator_buffers 2 #property indicator_plots 1 #property indicator_label1 "Z-score" #property indicator_type1 DRAW_COLOR_LINE #property indicator_color1 clrDarkGray,clrDodgerBlue,clrDeepPink #property indicator_width1 2 //--- input parameters input int inpPeriod = 14; // JMA smooth period input double inpPhase = 0; // JMA phase input int inpZsPeriod = 30; // Z-score period (<=1 for same as JMA period) input ENUM_APPLIED_PRICE inpPrice = PRICE_CLOSE; // Price //--- buffers and global variables declarations double val[],valc[]; int _zsPeriod; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,val,INDICATOR_DATA); SetIndexBuffer(1,valc,INDICATOR_COLOR_INDEX); _zsPeriod = (inpZsPeriod<=1 ? inpPeriod : inpZsPeriod); if (_zsPeriod<=1) { Alert("Z-score period can not be less than 2"); return(INIT_FAILED); } //--- IndicatorSetString(INDICATOR_SHORTNAME,"JMA z-score ("+(string)inpPeriod+","+(string)_zsPeriod+")"); 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[]) { int i=(int)MathMax(prev_calculated-1,0); for(; i0) ?(val[i]>val[i-1]) ? 1 :(val[i]=0; mean+=workZs[i-k], sumx+=workZs[i-k],sumxx+=workZs[i-k]*workZs[i-k],k++) {} double deviation = MathSqrt((sumxx-sumx*sumx/(double)period)/(double)period); mean /= (double)period; return(deviation!=0 ? (value-mean)/deviation : 0); } // //--- // #define _smoothInstances 1 #define _smoothInstancesSize 10 #define _smoothRingSize 11 double workSmooth[_smoothRingSize][_smoothInstances*_smoothInstancesSize]; #define bsmax 5 #define bsmin 6 #define volty 7 #define vsum 8 #define avolty 9 // // // double iSmooth(double price, double length, double phase, int i, int instance=0) { int _indP = (i-1)%_smoothRingSize; int _indC = (i )%_smoothRingSize; int _inst = instance*_smoothInstancesSize; if(i==0 || length<=1) { int k=0; for(; k absDel2) ? absDel1 : (absDel1 < absDel2) ? absDel2 : 0; workSmooth[_indC][_inst+vsum] = workSmooth[_indP][_inst+vsum]+(workSmooth[_indC][_inst+volty]-workSmooth[_indF][_inst+volty])*0.1; workSmooth[_indC][_inst+avolty] = workSmooth[_indP][_inst+avolty]+(2.0/(MathMax(4.0*length,30)+1.0))*(workSmooth[_indC][_inst+vsum]-workSmooth[_indP][_inst+avolty]); double dVolty = (workSmooth[_indC][_inst+avolty]>0) ? workSmooth[_indC][_inst+volty]/workSmooth[_indC][_inst+avolty]: 0; double dVoltyTmp = MathPow(len1,1.0/pow1); if (dVolty > dVoltyTmp) dVolty = dVoltyTmp; if (dVolty < 1.0) dVolty = 1.0; double pow2 = MathPow(dVolty, pow1); double len2 = MathSqrt(0.5*(length-1))*len1; double Kv = MathPow(len2/(len2+1), MathSqrt(pow2)); workSmooth[_indC][_inst+bsmax] = (del1 > 0) ? price : price - Kv*del1; workSmooth[_indC][_inst+bsmin] = (del2 < 0) ? price : 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); workSmooth[_indC][_inst+0] = price + alpha*(workSmooth[_indP][_inst+0]-price); workSmooth[_indC][_inst+1] = (price - workSmooth[_indC][_inst+0])*(1-beta) + beta*workSmooth[_indP][_inst+1]; workSmooth[_indC][_inst+2] = (workSmooth[_indC][_inst+0] + corr*workSmooth[_indC][_inst+1]); workSmooth[_indC][_inst+3] = (workSmooth[_indC][_inst+2] - workSmooth[_indP][_inst+4])*((1-alpha)*(1-alpha)) + (alpha*alpha)*workSmooth[_indP][_inst+3]; workSmooth[_indC][_inst+4] = (workSmooth[_indP][_inst+4] + workSmooth[_indC][_inst+3]); return(workSmooth[_indC][_inst+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) { 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); } //+------------------------------------------------------------------+