//------------------------------------------------------------------ #property copyright "© mladen, 2016, MetaQuotes Software Corp." #property link "www.forex-tsd.com, www.mql5.com" //------------------------------------------------------------------ #property indicator_separate_window #property indicator_buffers 5 #property indicator_plots 3 #property indicator_label1 "Buy sell volume histo" #property indicator_type1 DRAW_COLOR_HISTOGRAM #property indicator_color1 clrGray,clrLimeGreen,clrSandyBrown #property indicator_width1 2 #property indicator_label2 "Buy sell volume up" #property indicator_type2 DRAW_LINE #property indicator_color2 clrLimeGreen #property indicator_style2 STYLE_DOT #property indicator_label3 "Buy sell volume down" #property indicator_type3 DRAW_LINE #property indicator_color3 clrSandyBrown #property indicator_style3 STYLE_DOT // // // // // enum enMaTypes { ma_sma, // Simple moving average ma_ema, // Exponential moving average ma_smma, // Smoothed MA ma_lwma // Linear weighted MA }; enum enVolType { vol_real, // Use real volume vol_tick // Use tick volume }; input ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT; // Time frame input int SmoothPeriod = 14; // Smoothing period input enMaTypes SmoothMethod = ma_sma; // Smoothing me input enVolType VolumeType = vol_tick; // Volume to use 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 valu[],vald[],hist[],histc[],count[]; int _mtfHandle = INVALID_HANDLE; ENUM_TIMEFRAMES timeFrame; #define _mtfCall iCustom(_Symbol,timeFrame,getIndicatorName(),PERIOD_CURRENT,SmoothPeriod,SmoothMethod,VolumeType,AlertsOn,AlertsOnCurrent,AlertsMessage,AlertsSound,AlertsEmail,AlertsNotify) //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // int OnInit() { SetIndexBuffer(0,hist ,INDICATOR_DATA); SetIndexBuffer(1,histc ,INDICATOR_COLOR_INDEX); SetIndexBuffer(2,valu ,INDICATOR_DATA); SetIndexBuffer(3,vald ,INDICATOR_DATA); SetIndexBuffer(4,count ,INDICATOR_CALCULATIONS); timeFrame = MathMax(_Period,TimeFrame); IndicatorSetString(INDICATOR_SHORTNAME,timeFrameToString(timeFrame)+" Buy sell volume ("+(string)SmoothPeriod+")"); 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& real_volume[], const int& spread[]) { if (Bars(_Symbol,_Period) 0 && time[i-n] >= currTime[0]; n++) continue; for(k=1; (i-k)>=0 && kma) ? tv : (close[i]0) ? (volume>0) ? valu[i-1]+alpha*(volume-valu[i-1]) : valu[i-1] : 0; vald[i] = (i>0) ? (volume<0) ? vald[i-1]+alpha*(volume-vald[i-1]) : vald[i-1] : 0; hist[i] = (volume>0) ? valu[i] : (volume<0) ? vald[i] : 0; histc[i] = (volume>0) ? 1 : (volume<0) ? 2 : 0; } count[rates_total-1] = MathMax(rates_total-prev_calculated+1,1); manageAlerts(time,histc,rates_total); return(i); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // 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)+" buy sell volume state changed to "+doWhat; if (AlertsMessage) Alert(message); if (AlertsEmail) SendMail(_Symbol+" buy sell volume",message); if (AlertsNotify) SendNotification(message); if (AlertsSound) PlaySound("alert2.wav"); } } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // #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); } //------------------------------------------------------------------- // //------------------------------------------------------------------- // // // // // string getIndicatorName() { string path = MQL5InfoString(MQL5_PROGRAM_PATH); string data = TerminalInfoString(TERMINAL_DATA_PATH)+"\\MQL5\\Indicators\\"; string name = StringSubstr(path,StringLen(data)); return(name); } // // // // // int _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;i0) { 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); }