//------------------------------------------------------------------ #property copyright "mladen" #property link "www.forex-tsd.com" //------------------------------------------------------------------ #property indicator_chart_window #property indicator_buffers 5 #property indicator_plots 3 #property indicator_label1 "fill area" #property indicator_type1 DRAW_FILLING #property indicator_color1 clrLimeGreen,clrOrange #property indicator_label2 "st1" #property indicator_type2 DRAW_LINE #property indicator_color2 clrLime #property indicator_width2 2 #property indicator_label3 "st2" #property indicator_type3 DRAW_LINE #property indicator_color3 clrGold #property indicator_width3 2 // // // // // enum enAveragesType { avgSma, // Simple moving average avgEma, // Exponential moving average avgDsema, // Double smoothed EMA avgDema, // Double EMA avgTema, // Tripple EMA avgSmma, // Smoothed MA avgLwma, // Linear weighted MA avgPwma, // Parabolic weighted MA avgAlex, // Alexander MA avgVwma, // Volume weighted MA avgHull, // Hull MA avgTma, // Triangular MA avgSine, // Sine weighted MA avgLsma, // Linear regression value avgIe2, // IE/2 avgNlma, // Non lag MA avgZlma, // Zeo lag EMA avgLead // Leader EMA }; 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+oprn+close)/4 }; input ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT; // Time frame input int avgPeriod1 = 100; // first average period input enAveragesType avgMethod1 = avgHull; // first average type input enPrices avgPrice1 = pr_median; // first average price input int atrPeriod1 = 12; // first atr period input double atrMultiplier1 = 0.66; // first atr multiplier input int avgPeriod2 = 200; // second average period input enAveragesType avgMethod2 = avgHull; // second average type input enPrices avgPrice2 = pr_median; // second average price input int atrPeriod2 = 12; // second atr period input double atrMultiplier2 = 0.66; // second atr multiplier input bool alertsOn = false; // Turn alerts on? input bool alertsOnCurrent = true; // Alerts on current bar input bool alertsMessage = true; // Alerts should show message box input bool alertsSound = false; // Alerts should play sound input bool alertsEmail = false; // Alerts should send email input bool Interpolate = true; // Interpolate mtf data ? // // // // // // double fillUp[]; double fillDn[]; double st1[]; double st2[]; double CountBuffer[]; // // // // ENUM_TIMEFRAMES timeFrame; int mtfHandle; bool calculating; int totalBars; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // // // // // int OnInit() { SetIndexBuffer(0,fillUp,INDICATOR_DATA); SetIndexBuffer(1,fillDn,INDICATOR_DATA); SetIndexBuffer(2,st1 ,INDICATOR_DATA); SetIndexBuffer(3,st2 ,INDICATOR_DATA); SetIndexBuffer(4,CountBuffer,INDICATOR_CALCULATIONS); // // // // // timeFrame = MathMax(_Period,TimeFrame); calculating = (timeFrame==_Period); if (!calculating) { string name = getIndicatorName(); mtfHandle = iCustom(NULL,timeFrame,name,PERIOD_CURRENT,avgPeriod1,avgMethod1,avgPrice1,atrPeriod1,atrMultiplier1,avgPeriod2,avgMethod2,avgPrice2,atrPeriod2,atrMultiplier2,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsEmail); } return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // // // // // double trends[][1]; 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 (calculating) { totalBars = rates_total; if (ArrayRange(trends,0) != rates_total) ArrayResize(trends,rates_total); for (int i=(int)MathMax(prev_calculated-1,1); i=0; k++) atr1 += MathMax(high[i-k],close[i-k-1])-MathMin(low[i-k],close[i-k-1]); atr1 /= atrPeriod1; double atr2 = 0; for (int k=0; k=0; k++) atr2 += MathMax(high[i-k],close[i-k-1])-MathMin(low[i-k],close[i-k-1]); atr2 /= atrPeriod1; st1[i] = iSuperTrend(atrPeriod1,avgMethod1,close[i],getPrice(avgPrice1,open,close,high,low,i,rates_total),avgPeriod1,atr1,atrMultiplier1,tick_volume,dirrection,i,0); st2[i] = iSuperTrend(atrPeriod2,avgMethod2,close[i],getPrice(avgPrice2,open,close,high,low,i,rates_total),avgPeriod2,atr2,atrMultiplier2,tick_volume,dirrection,i,1); fillUp[i] = st1[i]; fillDn[i] = st2[i]; trends[i][0] = trends[i-1][0]; if (st1[i]>st2[i]) trends[i][0] = 1; if (st1[i]time[0] || bars<1) return(prev_calculated); double fil1[]; CopyBuffer(mtfHandle,0,0,bars,fil1); double fil2[]; CopyBuffer(mtfHandle,1,0,bars,fil2); double vst1[]; CopyBuffer(mtfHandle,2,0,bars,vst1); double vst2[]; CopyBuffer(mtfHandle,3,0,bars,vst2); double counts[]; CopyBuffer(mtfHandle,4,0,bars,counts); int maxb = (int)MathMax(MathMin(counts[bars-1]*PeriodSeconds(timeFrame)/PeriodSeconds(Period()),rates_total-1),1); // // // // // for(int i=(int)MathMax(prev_calculated-maxb,0);i -1 && d < bars) { st1[i] = vst1[d]; st2[i] = vst2[d]; fillUp[i] = fil1[d]; fillDn[i] = fil2[d]; } if (!Interpolate) continue; // // // // // int l=MathMin(i+1,rates_total-1); if (d!=dateArrayBsearch(times,time[l],bars) || i==l) { int n,k; for(n = 1; (i-n)> 0 && time[i-n] >= times[d]; n++) continue; for(k = 1; (i-k)>=0 && k workSt[r-1][_up+instanceNo]) workSt[r][_dirrection+instanceNo] = 1; if (cprice < workSt[r-1][_dn+instanceNo]) workSt[r][_dirrection+instanceNo] = -1; if (workSt[r][_dirrection+instanceNo] > 0) { workSt[r][_dn+instanceNo] = MathMax(workSt[r][_dn+instanceNo],workSt[r-1][_dn+instanceNo]); workSt[r][_trend+instanceNo] = workSt[r][_dn+instanceNo]; } else { workSt[r][_up+instanceNo] = MathMin(workSt[r][_up+instanceNo],workSt[r-1][_up+instanceNo]); workSt[r][_trend+instanceNo] = workSt[r][_up+instanceNo]; } dirrection = (int)workSt[r][_dirrection+instanceNo]; return(workSt[r][_trend+instanceNo]); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // double getPrice(enPrices price, const double& open[], const double& close[], const double& high[], const double& low[], int i, int bars) { switch (price) { case pr_close: return(close[i]); case pr_open: return(open[i]); case pr_high: return(high[i]); case pr_low: return(low[i]); case pr_median: return((high[i]+low[i])/2.0); case pr_typical: return((high[i]+low[i]+close[i])/3.0); case pr_weighted: return((high[i]+low[i]+close[i]+close[i])/4.0); case pr_average: return((high[i]+low[i]+close[i]+open[i])/4.0); } return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // // // // // int dateArrayBsearch(datetime& times[], datetime toFind, int total) { int mid = 0; int first = 0; int last = total-1; while (last >= first) { mid = (first + last) >> 1; if (toFind == times[mid] || (mid < (total-1) && (toFind > times[mid]) && (toFind < times[mid+1]))) break; if (toFind < times[mid]) last = mid - 1; else first = mid + 1; } return (mid); } // // // // // string getIndicatorName() { string progPath = MQL5InfoString(MQL5_PROGRAM_PATH); string terminalPath = TerminalInfoString(TERMINAL_PATH); int startLength = StringLen(terminalPath)+17; int progLength = StringLen(progPath); string indicatorName = StringSubstr(progPath,startLength); indicatorName = StringSubstr(indicatorName,0,StringLen(indicatorName)-4); return(indicatorName); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // string methodNames[] = {"SMA","EMA","Double smoothed EMA","Double EMA","Tripple EMA","Smoothed MA","Linear weighted MA","Parabolic weighted MA","Alexander MA","Volume weghted MA","Hull MA","Triangular MA","Sine weighted MA","Linear regression","IE/2","NonLag MA","Zero lag EMA","Leader EMA"}; string getAverageName(int method) { int max = ArraySize(methodNames)-1; method = (int)MathMax(MathMin(method,max),0); return(methodNames[method]); } // // // // // // // // // // #define _maWorkBufferx1 2 #define _maWorkBufferx2 4 #define _maWorkBufferx3 6 double iCustomMa(int mode, double price, double length, const long& volume[], int r, int instanceNo=0) { switch (mode) { case avgSma : return(iSma(price,(int)length,r,instanceNo)); case avgEma : return(iEma(price,length,r,instanceNo)); case avgDsema : return(iDsema(price,length,r,instanceNo)); case avgDema : return(iDema(price,length,r,instanceNo)); case avgTema : return(iTema(price,length,r,instanceNo)); case avgSmma : return(iSmma(price,length,r,instanceNo)); case avgLwma : return(iLwma(price,length,r,instanceNo)); case avgPwma : return(iLwmp(price,length,r,instanceNo)); case avgAlex : return(iAlex(price,length,r,instanceNo)); case avgVwma : return(iWwma(price,length,volume,r,instanceNo)); case avgHull : return(iHull(price,length,r,instanceNo)); case avgTma : return(iTma(price,length,r,instanceNo)); case avgSine : return(iSineWMA(price,(int)length,r,instanceNo)); case avgLsma : return(iLinr(price,length,r,instanceNo)); case avgIe2 : return(iIe2(price,length,r,instanceNo)); case avgNlma : return(iNonLagMa(price,length,r,instanceNo)); case avgZlma : return(iZeroLag(price,length,r,instanceNo)); case avgLead : return(iLeader(price,length,r,instanceNo)); default : return(price); } } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // double workSma[][_maWorkBufferx2]; double iSma(double price, int period, int r, int instanceNo=0) { if (ArrayRange(workSma,0)!= totalBars) ArrayResize(workSma,totalBars); instanceNo *= 2; // // // // // int k; workSma[r][instanceNo] = price; if (r>=period) workSma[r][instanceNo+1] = workSma[r-1][instanceNo+1]+(workSma[r][instanceNo]-workSma[r-period][instanceNo])/period; else { workSma[r][instanceNo+1] = 0; for(k=0; k=0; k++) workSma[r][instanceNo+1] += workSma[r-k][instanceNo]; workSma[r][instanceNo+1] /= k; } return(workSma[r][instanceNo+1]); } // // // // // double workEma[][_maWorkBufferx1]; double iEma(double price, double period, int r, int instanceNo=0) { if (ArrayRange(workEma,0)!= totalBars) ArrayResize(workEma,totalBars); // // // // // double alpha = 2.0 / (1.0+period); workEma[r][instanceNo] = workEma[r-1][instanceNo]+alpha*(price-workEma[r-1][instanceNo]); return(workEma[r][instanceNo]); } // // // // // double workDsema[][_maWorkBufferx2]; #define _ema1 0 #define _ema2 1 double iDsema(double price, double period, int r, int instanceNo=0) { if (ArrayRange(workDsema,0)!= totalBars) ArrayResize(workDsema,totalBars); instanceNo*=2; // // // // // double alpha = 2.0 /(1.0+MathSqrt(period)); workDsema[r][_ema1+instanceNo] = workDsema[r-1][_ema1+instanceNo]+alpha*(price -workDsema[r-1][_ema1+instanceNo]); workDsema[r][_ema2+instanceNo] = workDsema[r-1][_ema2+instanceNo]+alpha*(workDsema[r][_ema1+instanceNo]-workDsema[r-1][_ema2+instanceNo]); return(workDsema[r][_ema2+instanceNo]); } // // // // // double workDema[][_maWorkBufferx2]; double iDema(double price, double period, int r, int instanceNo=0) { if (ArrayRange(workDema,0)!= totalBars) ArrayResize(workDema,totalBars); instanceNo*=2; // // // // // double alpha = 2.0 / (1.0+period); workDema[r][_ema1+instanceNo] = workDema[r-1][_ema1+instanceNo]+alpha*(price -workDema[r-1][_ema1+instanceNo]); workDema[r][_ema2+instanceNo] = workDema[r-1][_ema2+instanceNo]+alpha*(workDema[r][_ema1+instanceNo]-workDema[r-1][_ema2+instanceNo]); return(workDema[r][_ema1+instanceNo]*2.0-workDema[r][_ema2+instanceNo]); } // // // // // double workTema[][_maWorkBufferx3]; #define _ema3 2 double iTema(double price, double period, int r, int instanceNo=0) { if (ArrayRange(workTema,0)!= totalBars) ArrayResize(workTema,totalBars); instanceNo*=3; // // // // // double alpha = 2.0 / (1.0+period); workTema[r][_ema1+instanceNo] = workTema[r-1][_ema1+instanceNo]+alpha*(price -workTema[r-1][_ema1+instanceNo]); workTema[r][_ema2+instanceNo] = workTema[r-1][_ema2+instanceNo]+alpha*(workTema[r][_ema1+instanceNo]-workTema[r-1][_ema2+instanceNo]); workTema[r][_ema3+instanceNo] = workTema[r-1][_ema3+instanceNo]+alpha*(workTema[r][_ema2+instanceNo]-workTema[r-1][_ema3+instanceNo]); return(workTema[r][_ema3+instanceNo]+3.0*(workTema[r][_ema1+instanceNo]-workTema[r][_ema2+instanceNo])); } // // // // // double workSmma[][_maWorkBufferx1]; double iSmma(double price, double period, int r, int instanceNo=0) { if (ArrayRange(workSmma,0)!= totalBars) ArrayResize(workSmma,totalBars); // // // // // if (r=0; k++) { double weight = period-k; sumw += weight; sum += weight*workLwma[r-k][instanceNo]; } return(sum/sumw); } // // // // // double workLwmp[][_maWorkBufferx1]; double iLwmp(double price, double period, int r, int instanceNo=0) { if (ArrayRange(workLwmp,0)!= totalBars) ArrayResize(workLwmp,totalBars); // // // // // workLwmp[r][instanceNo] = price; double sumw = period*period; double sum = sumw*price; for(int k=1; k=0; k++) { double weight = (period-k)*(period-k); sumw += weight; sum += weight*workLwmp[r-k][instanceNo]; } return(sum/sumw); } // // // // // double workAlex[][_maWorkBufferx1]; double iAlex(double price, double period, int r, int instanceNo=0) { if (ArrayRange(workAlex,0)!= totalBars) ArrayResize(workAlex,totalBars); if (period<4) return(price); // // // // // workAlex[r][instanceNo] = price; double sumw = period-2; double sum = sumw*price; for(int k=1; k=0; k++) { double weight = period-k-2; sumw += weight; sum += weight*workAlex[r-k][instanceNo]; } return(sum/sumw); } // // // // // double workTma[][_maWorkBufferx1]; double iTma(double price, double period, int r, int instanceNo=0) { if (ArrayRange(workTma,0)!= totalBars) ArrayResize(workTma,totalBars); // // // // // workTma[r][instanceNo] = price; double half = (period+1.0)/2.0; double sum = price; double sumw = 1; for(int k=1; k=0; k++) { double weight = k+1; if (weight > half) weight = period-k; sumw += weight; sum += weight*workTma[r-k][instanceNo]; } return(sum/sumw); } // // // // // double workSineWMA[][_maWorkBufferx1]; #define Pi 3.14159265358979323846264338327950288 double iSineWMA(double price, int period, int r, int instanceNo=0) { if (period<1) return(price); if (ArrayRange(workSineWMA,0)!= totalBars) ArrayResize(workSineWMA,totalBars); // // // // // workSineWMA[r][instanceNo] = price; double sum = 0; double sumw = 0; for(int k=0; k=0; k++) { double weight = MathSin(Pi*(k+1.0)/(period+1.0)); sumw += weight; sum += weight*workSineWMA[r-k][instanceNo]; } return(sum/sumw); } // // // // // double workWwma[][_maWorkBufferx1]; double iWwma(double price, double period,const long& Volume[], int r, int instanceNo=0) { if (ArrayRange(workWwma,0)!= totalBars) ArrayResize(workWwma,totalBars); // // // // // workWwma[r][instanceNo] = price; double sumw = (double)Volume[r]; double sum = sumw*price; for(int k=1; k=0; k++) { double weight = (double)Volume[r-k]; sumw += weight; sum += weight*workWwma[r-k][instanceNo]; } return(sum/sumw); } // // // // // double workHull[][_maWorkBufferx2]; double iHull(double price, double period, int r, int instanceNo=0) { if (ArrayRange(workHull,0)!= totalBars) ArrayResize(workHull,totalBars); // // // // // int k; int HmaPeriod = (int)MathMax(period,2); int HalfPeriod = (int)MathFloor(HmaPeriod/2); int HullPeriod = (int)MathFloor(MathSqrt(HmaPeriod)); double hma,hmw,weight; instanceNo *= 2; workHull[r][instanceNo] = price; // // // // // hmw = HalfPeriod; hma = hmw*price; for(k=1; k=0; k++) { weight = HalfPeriod-k; hmw += weight; hma += weight*workHull[r-k][instanceNo]; } workHull[r][instanceNo+1] = 2.0*hma/hmw; hmw = HmaPeriod; hma = hmw*price; for(k=1; k=0; k++) { weight = HmaPeriod-k; hmw += weight; hma += weight*workHull[r-k][instanceNo]; } workHull[r][instanceNo+1] -= hma/hmw; // // // // // hmw = HullPeriod; hma = hmw*workHull[r][instanceNo+1]; for(k=1; k=0; k++) { weight = HullPeriod-k; hmw += weight; hma += weight*workHull[r-k][1+instanceNo]; } return(hma/hmw); } // // // // // double workLinr[][_maWorkBufferx1]; double iLinr(double price, double period, int r, int instanceNo=0) { if (ArrayRange(workLinr,0)!= totalBars) ArrayResize(workLinr,totalBars); // // // // // period = MathMax(period,1); workLinr[r][instanceNo] = price; double lwmw = period; double lwma = lwmw*price; double sma = price; for(int k=1; k=0; k++) { double weight = period-k; lwmw += weight; lwma += weight*workLinr[r-k][instanceNo]; sma += workLinr[r-k][instanceNo]; } return(3.0*lwma/lwmw-2.0*sma/period); } // // // // // double workIe2[][_maWorkBufferx1]; double iIe2(double price, double period, int r, int instanceNo=0) { if (ArrayRange(workIe2,0)!= totalBars) ArrayResize(workIe2,totalBars); // // // // // period = MathMax(period,1); workIe2[r][instanceNo] = price; double sumx=0, sumxx=0, sumxy=0, sumy=0; for (int k=0; k=0; k++) { price = workIe2[r-k][instanceNo]; sumx += k; sumxx += k*k; sumxy += k*price; sumy += price; } double slope = (period*sumxy - sumx*sumy)/(sumx*sumx-period*sumxx); double average = sumy/period; return(((average+slope)+(sumy+slope*sumx)/period)/2.0); } // // // // // double workLeader[][_maWorkBufferx2]; double iLeader(double price, double period, int r, int instanceNo=0) { if (ArrayRange(workLeader,0)!= totalBars) ArrayResize(workLeader,totalBars); instanceNo*=2; // // // // // period = MathMax(period,1); double alpha = 2.0/(period+1.0); workLeader[r][instanceNo ] = workLeader[r-1][instanceNo ]+alpha*(price -workLeader[r-1][instanceNo ]); workLeader[r][instanceNo+1] = workLeader[r-1][instanceNo+1]+alpha*(price-workLeader[r][instanceNo]-workLeader[r-1][instanceNo+1]); return(workLeader[r][instanceNo]+workLeader[r][instanceNo+1]); } // // // // // double workZl[][_maWorkBufferx2]; #define _price 0 #define _zlema 1 double iZeroLag(double price, double length, int r, int instanceNo=0) { if (ArrayRange(workZl,0)!=totalBars) ArrayResize(workZl,totalBars); instanceNo *= 2; // // // // // double alpha = 2.0/(1.0+length); int per = (int)((length-1.0)/2.0); workZl[r][_price+instanceNo] = price; if (r0) { double sum = 0; for (k=0; k < nlm_values[_len][instanceNo] && (r-k)>=0; k++) sum += nlm_alphas[k][instanceNo]*nlm_prices[r-k][instanceNo]; return( sum / nlm_values[_weight][instanceNo]); } else return(0); }