//------------------------------------------------------------------ #property copyright "© mladen, 2016, MetaQuotes Software Corp." #property link "www.forex-tsd.com, www.mql5.com" //------------------------------------------------------------------ #property indicator_separate_window #property indicator_buffers 6 #property indicator_plots 3 #property indicator_label1 "MACD fill" #property indicator_type1 DRAW_FILLING #property indicator_color1 C'209,243,209',C'255,230,183' #property indicator_label2 "MACD" #property indicator_type2 DRAW_COLOR_LINE #property indicator_color2 clrSilver,clrLimeGreen,clrOrange #property indicator_style2 STYLE_SOLID #property indicator_width2 2 #property indicator_label3 "MACD signal" #property indicator_type3 DRAW_LINE #property indicator_color3 clrSilver #property indicator_style3 STYLE_DOT // // // // // 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 }; input ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT; // Time frame input int FastPeriod = 12; // Fast period input int SlowPeriod = 26; // Slow period input int SignalPeriod = 9; // Signal period input double Speed = 1; // Speed input enPrices Price = pr_close; // Price 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 macd[],signal[],fill1[],fill2[],trend[],count[]; ENUM_TIMEFRAMES timeFrame; //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // int OnInit() { SetIndexBuffer(0,fill1 ,INDICATOR_DATA); SetIndexBuffer(1,fill2 ,INDICATOR_DATA); SetIndexBuffer(2,macd ,INDICATOR_DATA); SetIndexBuffer(3,trend ,INDICATOR_COLOR_INDEX); SetIndexBuffer(4,signal ,INDICATOR_DATA); SetIndexBuffer(5,count ,INDICATOR_CALCULATIONS); PlotIndexSetInteger(0,PLOT_SHOW_DATA,false); timeFrame = MathMax(_Period,TimeFrame); IndicatorSetString(INDICATOR_SHORTNAME,timeFrameToString(timeFrame)+" qwma macd ("+(string)FastPeriod+","+(string)SlowPeriod+","+(string)SignalPeriod+","+(string)Speed+")"); 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 && !IsStopped(); limit--) if (count[limit]==_processed) break; for (i=MathMin(limit,MathMax(prev_calculated-1,0)); i 0 && time[i-n] >= currTime[0]; n++) continue; for(k=1; (i-k)>=0 && ksignal[i]) ? 1 : (macd[i]0) ? trend[i-1] : 0; } count[rates_total-1] = MathMax(rates_total-prev_calculated+1,1); manageAlerts(time,trend,rates_total); return(rates_total); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // #define _qwmaInstances 3 double workQwma[][_qwmaInstances]; double iQwma(double price, double period, double speed, int r, int bars, int instanceNo=0) { if (ArrayRange(workQwma,0)!= bars) ArrayResize(workQwma,bars); // // // // // workQwma[r][instanceNo] = price; double sumw = MathPow(period,speed); double sum = sumw*price; for(int k=1; k=0; k++) { double weight = MathPow(period-k,speed); sumw += weight; sum += weight*workQwma[r-k][instanceNo]; } return(sum/sumw); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // 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)+" qwma macd state changed to "+doWhat; if (alertsMessage) Alert(message); if (alertsEmail) SendMail(_Symbol+" qwma macd ",message); if (alertsNotify) SendNotification(message); if (alertsSound) PlaySound("alert2.wav"); } } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // // #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) start = foundAt; else break; } string indicatorName = StringSubstr(progPath,start+1); indicatorName = StringSubstr(indicatorName,0,StringLen(indicatorName)-4); return(indicatorName); } // // // // // 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=ArraySize(_tfsPer)-1;i>=0;i--) if(period==_tfsPer[i]) break; return(_tfsStr[i]); }