//------------------------------------------------------------------ #property copyright "© mladen, 2016, MetaQuotes Software Corp." #property link "www.forex-tsd.com, www.mql5.com" //------------------------------------------------------------------ #property indicator_separate_window #property indicator_buffers 11 #property indicator_plots 6 #property indicator_type1 DRAW_LINE #property indicator_color1 clrGray #property indicator_style1 STYLE_DOT #property indicator_type2 DRAW_LINE #property indicator_color2 clrGray #property indicator_style2 STYLE_DOT #property indicator_type3 DRAW_LINE #property indicator_color3 clrSilver #property indicator_style3 STYLE_DASH #property indicator_type4 DRAW_LINE #property indicator_color4 clrDodgerBlue #property indicator_width4 3 #property indicator_type5 DRAW_LINE #property indicator_color5 clrSandyBrown #property indicator_width5 3 #property indicator_type6 DRAW_COLOR_ARROW #property indicator_color6 clrSilver,clrDodgerBlue,clrSandyBrown #property indicator_width6 2 // // // // // enum enPrices { pr_close, // Close pr_open, // Open pr_high, // High pr_low, // Low pr_median, // Median pr_typical, // Typical pr_weighted, // Weighted pr_average, // Average (high+low+open+close)/4 pr_medianb, // Average median body (open+close)/2 pr_tbiased, // Trend biased price pr_tbiased2, // Trend biased (extreme) price pr_haclose, // Heiken ashi close pr_haopen , // Heiken ashi open pr_hahigh, // Heiken ashi high pr_halow, // Heiken ashi low pr_hamedian, // Heiken ashi median pr_hatypical, // Heiken ashi typical pr_haweighted, // Heiken ashi weighted pr_haaverage, // Heiken ashi average pr_hamedianb, // Heiken ashi median body pr_hatbiased, // Heiken ashi trend biased price pr_hatbiased2 // Heiken ashi trend biased (extreme) price }; enum enMaTypes { ma_sma, // Simple moving average ma_ema, // Exponential moving average ma_smma, // Smoothed MA ma_lwma // Linear weighted MA }; input ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT; // Time frame input int VelPeriod = 32; // Velocity period input enPrices Price = pr_close; // Price input int MaPeriod = 20; // Bollinger bands period input enMaTypes MaMethod = ma_sma; // Moving average method input int DeviationPeriod = 20; // Deviations period input double Deviation = 1; // Deviation input bool DeviationSample = false; // Deviation sample correction? input double Risk = 1; // Risk input bool AlertsOn = false; // Turn alerts on? input bool AlertsOnCurrent = true; // Alert on current bar? input bool AlertsMessage = true; // Display messages on alerts? input bool AlertsSound = false; // Play sound on alerts? input bool AlertsEmail = false; // Send email on alerts? input bool AlertsNotify = false; // Send push notification on alerts? input bool Interpolate = true; // Interpolate mtf data ? double vel[],bba[],bbc[],bblu[],bbld[],amax[],amin[],bmax[],bmin[],trend[],count[]; int _mtfHandle = INVALID_HANDLE; ENUM_TIMEFRAMES timeFrame; #define _mtfCall iCustom(_Symbol,timeFrame,getIndicatorName(),PERIOD_CURRENT,VelPeriod,Price,MaPeriod,MaMethod,DeviationPeriod,Deviation,DeviationSample,Risk,AlertsOn,AlertsOnCurrent,AlertsMessage,AlertsSound,AlertsEmail,AlertsNotify) //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // void OnInit() { SetIndexBuffer(0 ,bmax ,INDICATOR_DATA); SetIndexBuffer(1 ,bmin ,INDICATOR_DATA); SetIndexBuffer(2 ,vel ,INDICATOR_DATA); SetIndexBuffer(3 ,bblu ,INDICATOR_DATA); SetIndexBuffer(4 ,bbld ,INDICATOR_DATA); SetIndexBuffer(5 ,bba ,INDICATOR_DATA); PlotIndexSetInteger(5,PLOT_ARROW,159); SetIndexBuffer(6 ,bbc ,INDICATOR_COLOR_INDEX); SetIndexBuffer(7 ,amax ,INDICATOR_CALCULATIONS); SetIndexBuffer(8 ,amin ,INDICATOR_CALCULATIONS); SetIndexBuffer(9 ,trend,INDICATOR_CALCULATIONS); SetIndexBuffer(10,count,INDICATOR_CALCULATIONS); timeFrame = MathMax(_Period,TimeFrame); IndicatorSetString(INDICATOR_SHORTNAME,timeFrameToString(timeFrame)+" bb stops velocity ("+(string)VelPeriod+","+(string)MaPeriod+")"); } //------------------------------------------------------------------ // //------------------------------------------------------------------ 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 &tickVolume[], const long &volume[], const int &spread[]) { if (Bars(_Symbol,_Period)0) ? (bbc[i]!=bbc[i-1]) ? (bbc[i]==1) ? bblu[i] : bbld[i] : EMPTY_VALUE : EMPTY_VALUE; // // // // // #define _mtfInterpolate(_buff) _buff[i-k] = _buff[i]+(_buff[i-n]-_buff[i])*k/n if (!Interpolate) continue; CopyTime(_Symbol,timeFrame,time[i ],1,currTime); if (i<(rates_total-1)) { CopyTime(_Symbol,timeFrame,time[i+1],1,nextTime); if (currTime[0]==nextTime[0]) continue; } for(n=1; (i-n)> 0 && time[i-n] >= currTime[0]; n++) continue; for(k=1; (i-k)>=0 && k0) ? (vel[i]>amax[i-1]) ? 1 : (vel[i]0) { if (trend[i]==-1 && amax[i]>amax[i-1]) amax[i] = amax[i-1]; if (trend[i]== 1 && amin[i]bmax[i-1]) bmax[i] = bmax[i-1]; if (trend[i]== 1 && bmin[i]0) ? (trend[i]!=trend[i-1]) ? (trend[i]== 1) ? bblu[i] : bbld[i] : EMPTY_VALUE : EMPTY_VALUE; } count[rates_total-1] = MathMax(rates_total-prev_calculated+1,1); manageAlerts(time,bbc,rates_total); return(i); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // #define _velInstances 1 double _velWork[][_velInstances]; double iVelocity(double price, double length, int i, int bars, int instanceNo=0) { if (ArrayRange(_velWork,0)!=bars) ArrayResize(_velWork,bars); _velWork[i][instanceNo] = price; double suma = 0.0, sumwa=0; double sumb = 0.0, sumwb=0; for(int k=0; k=0; k++) { double weight = length-k; suma += _velWork[i-k][instanceNo] * weight; sumb += _velWork[i-k][instanceNo] * weight * weight; sumwa += weight; sumwb += weight*weight; } return(sumb/sumwb-suma/sumwa); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // #define _devInstances 1 double workDev[][_devInstances]; double iDeviation(double value, int length, bool isSample, int i, int bars, int instanceNo=0) { if (ArrayRange(workDev,0)!=bars) ArrayResize(workDev,bars); workDev[i][instanceNo] = value; // // // // // double oldMean = value; double newMean = value; double squares = 0; int k; for (k=1; k=0; k++) { newMean = (workDev[i-k][instanceNo]-oldMean)/(k+1)+oldMean; squares += (workDev[i-k][instanceNo]-oldMean)*(workDev[i-k][instanceNo]-newMean); oldMean = newMean; } return(MathSqrt(squares/MathMax(k-isSample,1))); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // #define _maInstances 1 #define _maWorkBufferx1 1*_maInstances double iCustomMa(int mode, double price, double length, int r, int bars, int instanceNo=0) { switch (mode) { case ma_sma : return(iSma(price,(int)length,r,bars,instanceNo)); case ma_ema : return(iEma(price,length,r,bars,instanceNo)); case ma_smma : return(iSmma(price,(int)length,r,bars,instanceNo)); case ma_lwma : return(iLwma(price,(int)length,r,bars,instanceNo)); default : return(price); } } // // // // // double workSma[][_maWorkBufferx1]; double iSma(double price, int period, int r, int _bars, int instanceNo=0) { if (ArrayRange(workSma,0)!= _bars) ArrayResize(workSma,_bars); int k=1; workSma[r][instanceNo+0] = price; double avg = price; for(; k=0; k++) avg += workSma[r-k][instanceNo+0]; avg /= (double)k; return(avg); } // // // // // double workEma[][_maWorkBufferx1]; double iEma(double price, double period, int r, int _bars, int instanceNo=0) { if (ArrayRange(workEma,0)!= _bars) ArrayResize(workEma,_bars); workEma[r][instanceNo] = price; if (r>0 && period>1) workEma[r][instanceNo] = workEma[r-1][instanceNo]+(2.0/(1.0+period))*(price-workEma[r-1][instanceNo]); return(workEma[r][instanceNo]); } // // // // // double workSmma[][_maWorkBufferx1]; double iSmma(double price, double period, int r, int _bars, int instanceNo=0) { if (ArrayRange(workSmma,0)!= _bars) ArrayResize(workSmma,_bars); workSmma[r][instanceNo] = price; if (r>1 && period>1) workSmma[r][instanceNo] = workSmma[r-1][instanceNo]+(price-workSmma[r-1][instanceNo])/period; return(workSmma[r][instanceNo]); } // // // // // double workLwma[][_maWorkBufferx1]; double iLwma(double price, double period, int r, int _bars, int instanceNo=0) { if (ArrayRange(workLwma,0)!= _bars) ArrayResize(workLwma,_bars); workLwma[r][instanceNo] = price; if (period<1) return(price); double sumw = period; double sum = period*price; for(int k=1; k=0; k++) { double weight = period-k; sumw += weight; sum += weight*workLwma[r-k][instanceNo]; } return(sum/sumw); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // // #define _pricesInstances 1 #define _pricesSize 4 double workHa[][_pricesInstances*_pricesSize]; double getPrice(int tprice, const double& open[], const double& close[], const double& high[], const double& low[], int i,int _bars, int instanceNo=0) { if (tprice>=pr_haclose) { if (ArrayRange(workHa,0)!= _bars) ArrayResize(workHa,_bars); instanceNo*=_pricesSize; // // // // // double haOpen; if (i>0) haOpen = (workHa[i-1][instanceNo+2] + workHa[i-1][instanceNo+3])/2.0; else haOpen = (open[i]+close[i])/2; double haClose = (open[i] + high[i] + low[i] + close[i]) / 4.0; double haHigh = MathMax(high[i], MathMax(haOpen,haClose)); double haLow = MathMin(low[i] , MathMin(haOpen,haClose)); if(haOpen haOpen) return((haHigh+haClose)/2.0); else return((haLow+haClose)/2.0); case pr_hatbiased2: if (haClose>haOpen) return(haHigh); if (haCloseopen[i]) return((high[i]+close[i])/2.0); else return((low[i]+close[i])/2.0); case pr_tbiased2: if (close[i]>open[i]) return(high[i]); if (close[i]0) { CopyTime(_Symbol,_timeFrame,time[0],1,testTime); SeriesInfoInteger(_Symbol,_timeFrame,SERIES_FIRSTDATE,startTime); } if (startTime<=0 || startTime>time[0]) { Comment(MQL5InfoString(MQL5_PROGRAM_NAME)+"\nMissing data for "+timeFrameToString(_timeFrame)+" time frame\nRe-trying on next tick"); warned=true; return(false); } } if (warned) { Comment(""); warned=false; } return(true); }