//------------------------------------------------------------------ #property copyright "© mladen, 2016, MetaQuotes Software Corp." #property link "www.forex-tsd.com, www.mql5.com" //------------------------------------------------------------------ #property indicator_separate_window #property indicator_buffers 8 #property indicator_plots 5 #property indicator_label1 "velocity OB/OS zone" #property indicator_type1 DRAW_FILLING #property indicator_color1 C'209,243,209',C'255,230,183' #property indicator_label2 "velocity up level" #property indicator_type2 DRAW_LINE #property indicator_color2 clrLimeGreen #property indicator_style2 STYLE_DOT #property indicator_label3 "velocity middle level" #property indicator_type3 DRAW_LINE #property indicator_color3 clrSilver #property indicator_style3 STYLE_DOT #property indicator_label4 "velocity down level" #property indicator_type4 DRAW_LINE #property indicator_color4 clrOrange #property indicator_style4 STYLE_DOT #property indicator_label5 "velocity" #property indicator_type5 DRAW_COLOR_LINE #property indicator_color5 clrSilver,clrLimeGreen,clrOrange #property indicator_width5 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 enColorOn { cc_onSlope, // Change color on slope change cc_onMiddle, // Change color on middle line cross cc_onLevels // Change color on outer levels cross }; enum enNormMethod { nm_atr, // Use ATR for normalization nm_std, // Use standard deviation without sample correction nm_stc, // Use standard deviation with sample correction nm_non // No normalization }; input ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT; // Time frame input int VelPeriod = 32; // Velocity period input enPrices VelPrice = pr_close; // Price to use input enNormMethod NormMethod = nm_atr; // Normalization method input enColorOn ColorOn = cc_onLevels; // Color change : input int MinMaxPeriod = 50; // Floating levels period (<= 1 to use velocity period) input double LevelUp = 80.0; // Up level % input double LevelDown = 20.0; // Down level % input bool alertsOn = false; // Turn alerts on? input bool alertsOnCurrent = true; // Alert on current bar? input bool alertsMessage = true; // Display messageas 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[],velc[],fill1[],fill2[],levelUp[],levelMi[],levelDn[],count[]; int _mtfHandle = INVALID_HANDLE; ENUM_TIMEFRAMES timeFrame; #define _mtfCall iCustom(_Symbol,timeFrame,getIndicatorName(),PERIOD_CURRENT,VelPeriod,VelPrice,NormMethod,ColorOn,MinMaxPeriod,LevelUp,LevelDown,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail,alertsNotify) //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // int OnInit() { SetIndexBuffer(0,fill1 ,INDICATOR_DATA); SetIndexBuffer(1,fill2 ,INDICATOR_DATA); SetIndexBuffer(2,levelUp,INDICATOR_DATA); SetIndexBuffer(3,levelMi,INDICATOR_DATA); SetIndexBuffer(4,levelDn,INDICATOR_DATA); SetIndexBuffer(5,vel ,INDICATOR_DATA); SetIndexBuffer(6,velc ,INDICATOR_COLOR_INDEX); SetIndexBuffer(7,count ,INDICATOR_CALCULATIONS); for (int i=0; i<4; i++) PlotIndexSetInteger(i,PLOT_SHOW_DATA,false); timeFrame = MathMax(_Period,TimeFrame); if (timeFrame != _Period) _mtfHandle = _mtfCall; IndicatorSetString(INDICATOR_SHORTNAME,timeFrameToString(timeFrame)+" ATR normalzed velocity ("+(string)VelPeriod+","+(string)MinMaxPeriod+")"); return(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 (Bars(_Symbol,_Period) 0 && time[i-n] >= currTime[0]; n++) continue; for(k=1; (i-k)>=0 && k0) ? MinMaxPeriod : VelPeriod; for (int i=(int)MathMax(prev_calculated-1,0); i=0; k++) { min = MathMin(vel[i-k],min); max = MathMax(vel[i-k],max); } double range = max-min; levelUp[i] = min+LevelUp *range/100.0; levelDn[i] = min+LevelDown*range/100.0; levelMi[i] = min+0.5*range; switch(ColorOn) { case cc_onLevels: velc[i] = (vel[i]>levelUp[i]) ? 1 : (vel[i]levelMi[i]) ? 1 : (vel[i]0) ? (vel[i]>vel[i-1]) ? 1 : (vel[i]levelUp[i]) ? levelUp[i] : (vel[i]=0; k++) if (i-k==0) atr += high[i-k]+low[i-k]; else atr += MathMax(high[i-k],close[i-k-1])-MathMin(low[i-k],close[i-k-1]); return(atr/atrPeriod); } // // // // // double workDev[]; double iDeviation(double value, int length, bool isSample, int i, int bars) { if (ArraySize(workDev)!=bars) ArrayResize(workDev,bars); workDev[i] = value; // // // // // double oldMean = value; double newMean = value; double squares = 0; int k; for (k=1; k=0; k++) { newMean = (workDev[i-k]-oldMean)/(k+1)+oldMean; squares += (workDev[i-k]-oldMean)*(workDev[i-k]-newMean); oldMean = newMean; } return(MathSqrt(squares/MathMax(k-isSample,1))); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // void manageAlerts(const datetime& time[], double& ttrend[], int bars) { if (!alertsOn) return; int whichBar = bars-1; if (!alertsOnCurrent) whichBar = bars-2; datetime time1 = time[whichBar]; if (ttrend[whichBar] != ttrend[whichBar-1]) { if (ttrend[whichBar] == 1) doAlert(time1,"up"); if (ttrend[whichBar] == 2) doAlert(time1,"down"); } } // // // // // void doAlert(datetime forTime, string doWhat) { static string previousAlert="nothing"; static datetime previousTime; if (previousAlert != doWhat || previousTime != forTime) { previousAlert = doWhat; previousTime = forTime; string message = timeFrameToString(_Period)+" "+_Symbol+" at "+TimeToString(TimeLocal(),TIME_SECONDS)+" velocity state changed to "+doWhat; if (alertsMessage) Alert(message); if (alertsEmail) SendMail(_Symbol+" velocity",message); if (alertsNotify) SendNotification(message); if (alertsSound) PlaySound("alert2.wav"); } } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // double workMom[]; double iMomentumS(double price, double length, double powSlow, double powFast, int i, int bars) { if (ArraySize(workMom)!=bars) ArrayResize(workMom,bars); workMom[i] = 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 += workMom[i-k] * MathPow(weight,powSlow); sumb += workMom[i-k] * MathPow(weight,powFast); sumwa += MathPow(weight,powSlow); sumwb += MathPow(weight,powFast); } return(sumb/sumwb-suma/sumwa); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // // #define priceInstances 1 double workHa[][priceInstances*4]; 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*=4; // // // // // 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;i--) if(period==_tfsPer[i]) break; return(_tfsStr[i]); }