//------------------------------------------------------------------ #property copyright "copyright© mladen" #property description "chande dmi" #property description "made by mrtools" #property description "for more visit www.forex-station.com" #property link "www.forex-station.com" //------------------------------------------------------------------ #property indicator_separate_window #property indicator_buffers 6 #property indicator_label1 "Dmi upper band" #property indicator_type1 DRAW_LINE #property indicator_color1 clrMediumSeaGreen #property indicator_label2 "Dmi middle band" #property indicator_type2 DRAW_LINE #property indicator_color2 clrMediumSeaGreen #property indicator_label3 "Dmi lower band" #property indicator_type3 DRAW_LINE #property indicator_color3 clrMediumSeaGreen #property indicator_label4 "Dmi" #property indicator_type4 DRAW_LINE #property indicator_color4 clrLimeGreen #property indicator_width4 3 #property indicator_label5 "Dmi" #property indicator_type5 DRAW_LINE #property indicator_color5 clrDarkOrange #property indicator_width5 3 #property indicator_label6 "Dmi" #property indicator_type6 DRAW_LINE #property indicator_color6 clrDarkOrange #property indicator_width6 3 #property strict // // // // // 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 pr_habclose, // Heiken ashi (better formula) close pr_habopen , // Heiken ashi (better formula) open pr_habhigh, // Heiken ashi (better formula) high pr_hablow, // Heiken ashi (better formula) low pr_habmedian, // Heiken ashi (better formula) median pr_habtypical, // Heiken ashi (better formula) typical pr_habweighted,// Heiken ashi (better formula) weighted pr_habaverage, // Heiken ashi (better formula) average pr_habmedianb, // Heiken ashi (better formula) median body pr_habtbiased, // Heiken ashi (better formula) trend biased price pr_habtbiased2 // Heiken ashi (better formula) 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 ma_slwma, // Smoothed LWMA ma_dsema, // Double Smoothed Exponential average ma_tema, // Triple exponential moving average - TEMA ma_lsma, // Linear regression value (lsma) ma_nlma // Non Lag moving average - NLMA }; enum stdMethods { std_custSam, // Custom - with sample correction std_custNos // Custom - without sample correction }; input int inpDmiPeriod = 14; // Dynamic Momentum Index period input int inpDmiLowerLimit = 3; // Dynamic Momentum Index lower limit input int inpDmiUpperLimit = 30; // Dynamic Momentum Index upper limit input enPrices inpPrice = pr_close; // Price input int inpDevPeriod = 5; // Standard deviation period input int inpMaDevPeriod = 10; // Standard deviation smoothing period input enMaTypes inpMaDevMode = ma_sma; // Standard deviation smoothing method input stdMethods DevType = std_custSam; // Deviation calculation type input int BandPeriod = 20; // Band period input double BandMultiplier = 2.0; // Band multiplier double bandUp[],bandMi[],bandDn[],dmi[],dmiDa[],dmiDb[],prices[],dmic[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ // // int OnInit() { IndicatorBuffers(8); SetIndexBuffer(0,bandUp,INDICATOR_DATA); SetIndexBuffer(1,bandMi,INDICATOR_DATA); SetIndexBuffer(2,bandDn,INDICATOR_DATA); SetIndexBuffer(3,dmi, INDICATOR_DATA); SetIndexBuffer(4,dmiDa, INDICATOR_DATA); SetIndexBuffer(5,dmiDb, INDICATOR_DATA); SetIndexBuffer(6,prices,INDICATOR_CALCULATIONS); SetIndexBuffer(7,dmic, INDICATOR_CALCULATIONS); IndicatorShortName("Chande's DMI ("+(string)inpDmiPeriod+")"); return (INIT_SUCCEEDED); } void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // // int OnCalculate (const int rates_total, const int prev_calculated, const datetime& btime[], const double& open[], const double& high[], const double& low[], const double& close[], const long& tick_volume[], const long& volume[], const int& spread[]) { int i,counted_bars = prev_calculated; if(counted_bars < 0) return(-1); if(counted_bars > 0) counted_bars--; int limit=fmin(rates_total-counted_bars,rates_total-1); // // // // // if (dmic[limit] == -1) CleanPoint(limit,dmiDa,dmiDb); for(i = limit; i >= 0; i--) { prices[i] = getPrice(inpPrice,open,close,high,low,i,rates_total); double avg = prices[i]; int n = 1; for(; ndmi[i+1]) ? 1 : (dmi[i]=0; k++) { newMean = (workDev[i-k]-oldMean)/(k+1)+oldMean; squares += (workDev[i-k]-oldMean)*(workDev[i-k]-newMean); oldMean = newMean; } return(sqrt(squares/fmax(k-isSample,1))); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // // #define rsiInstances 1 double workRsi[][rsiInstances*3]; #define _price 0 #define _change 1 #define _changa 2 double iRsi(double price, double period, int i, int bars, int instanceNo=0) { if (ArrayRange(workRsi,0)!=bars) ArrayResize(workRsi,bars); int z = instanceNo*3; int r = bars-i-1; // // // // // workRsi[r][z+_price] = price; double alpha = 1.0/period; if (r=0; k++) sum += fabs(workRsi[r-k][z+_price]-workRsi[r-k-1][z+_price]); workRsi[r][z+_change] = (workRsi[r][z+_price]-workRsi[0][z+_price])/fmax(k,1); workRsi[r][z+_changa] = sum/fmax(k,1); } else { double change = workRsi[r][z+_price]-workRsi[r-1][z+_price]; workRsi[r][z+_change] = workRsi[r-1][z+_change] + alpha*( change - workRsi[r-1][z+_change]); workRsi[r][z+_changa] = workRsi[r-1][z+_changa] + alpha*(fabs(change) - workRsi[r-1][z+_changa]); } if (workRsi[r][z+_changa] != 0) return(50.0*(workRsi[r][z+_change]/workRsi[r][z+_changa]+1)); else return(50.0); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // #define _maInstances 1 #define _maWorkBufferx1 1*_maInstances #define _maWorkBufferx2 2*_maInstances #define _maWorkBufferx3 3*_maInstances double iCustomMa(int mode, double price, double length, int r, int bars, int instanceNo=0) { r = bars-r-1; switch (mode) { case ma_sma : return(iSma(price,(int)ceil(length),r,bars,instanceNo)); case ma_ema : return(iEma(price,length,r,bars,instanceNo)); case ma_smma : return(iSmma(price,(int)ceil(length),r,bars,instanceNo)); case ma_lwma : return(iLwma(price,(int)ceil(length),r,bars,instanceNo)); case ma_slwma : return(iSlwma(price,(int)ceil(length),r,bars,instanceNo)); case ma_dsema : return(iDsema(price,length,r,bars,instanceNo)); case ma_tema : return(iTema(price,(int)ceil(length),r,bars,instanceNo)); case ma_lsma : return(iLinr(price,(int)ceil(length),r,bars,instanceNo)); case ma_nlma : return(iNonLagMa(price,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); workSma[r][instanceNo+0] = price; double avg = price; int k=1; for(; k=0; k++) avg += workSma[r-k][instanceNo+0]; return(avg/(double)k); } // // // // // 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); } // // // // // double workSlwma[][_maWorkBufferx2]; double iSlwma(double price, double period, int r, int _bars, int instanceNo=0) { if (ArrayRange(workSlwma,0)!= _bars) ArrayResize(workSlwma,_bars); // // // // // int SqrtPeriod = (int)floor(sqrt(period)); instanceNo *= 2; workSlwma[r][instanceNo] = price; // // // // // double sumw = period; double sum = period*price; for(int k=1; k=0; k++) { double weight = period-k; sumw += weight; sum += weight*workSlwma[r-k][instanceNo]; } workSlwma[r][instanceNo+1] = (sum/sumw); // // // // // sumw = SqrtPeriod; sum = SqrtPeriod*workSlwma[r][instanceNo+1]; for(int k=1; k=0; k++) { double weight = SqrtPeriod-k; sumw += weight; sum += weight*workSlwma[r-k][instanceNo+1]; } return(sum/sumw); } // // // // // double workDsema[][_maWorkBufferx2]; #define _ema1 0 #define _ema2 1 double iDsema(double price, double period, int r, int _bars, int instanceNo=0) { if (ArrayRange(workDsema,0)!= _bars) ArrayResize(workDsema,_bars); instanceNo*=2; // // // // // workDsema[r][_ema1+instanceNo] = price; workDsema[r][_ema2+instanceNo] = price; if (r>0 && period>1) { double alpha = 2.0 /(1.0+sqrt(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 workTema[][_maWorkBufferx3]; #define _tema1 0 #define _tema2 1 #define _tema3 2 double iTema(double price, double period, int r, int bars, int instanceNo=0) { if (ArrayRange(workTema,0)!= bars) ArrayResize(workTema,bars); instanceNo*=3; // // // // // workTema[r][_tema1+instanceNo] = price; workTema[r][_tema2+instanceNo] = price; workTema[r][_tema3+instanceNo] = price; if (r>0 && period>1) { double alpha = 2.0 / (1.0+period); workTema[r][_tema1+instanceNo] = workTema[r-1][_tema1+instanceNo]+alpha*(price -workTema[r-1][_tema1+instanceNo]); workTema[r][_tema2+instanceNo] = workTema[r-1][_tema2+instanceNo]+alpha*(workTema[r][_tema1+instanceNo]-workTema[r-1][_tema2+instanceNo]); workTema[r][_tema3+instanceNo] = workTema[r-1][_tema3+instanceNo]+alpha*(workTema[r][_tema2+instanceNo]-workTema[r-1][_tema3+instanceNo]); } return(workTema[r][_tema3+instanceNo]+3.0*(workTema[r][_tema1+instanceNo]-workTema[r][_tema2+instanceNo])); } // // // // // double workLinr[][_maWorkBufferx1]; double iLinr(double price, int period, int r, int bars, int instanceNo=0) { if (ArrayRange(workLinr,0)!= bars) ArrayResize(workLinr,bars); // // // // // period = MathMax(period,1); workLinr[r][instanceNo] = price; if (r=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); } // // // // // #define _length 0 #define _len 1 #define _weight 2 double nlmvalues[ ][3]; double nlmprices[ ][_maWorkBufferx1]; double nlmalphas[ ][_maWorkBufferx1]; // // // // // double iNonLagMa(double price, double length, int r, int bars, int instanceNo=0) { if (ArrayRange(nlmprices,0) != bars) ArrayResize(nlmprices,bars); if (ArrayRange(nlmvalues,0) < instanceNo+1) ArrayResize(nlmvalues,instanceNo+1); nlmprices[r][instanceNo]=price; if (length<5 || r<3) return(nlmprices[r][instanceNo]); // // // // // if (nlmvalues[instanceNo][_length] != length) { double Cycle = 4.0; double Coeff = 3.0*M_PI; int Phase = (int)(length-1); nlmvalues[instanceNo][_length] = length; nlmvalues[instanceNo][_len ] = (int)(length*4) + Phase; nlmvalues[instanceNo][_weight] = 0; if (ArrayRange(nlmalphas,0) < (int)nlmvalues[instanceNo][_len]) ArrayResize(nlmalphas,(int)nlmvalues[instanceNo][_len]); for (int k=0; k<(int)nlmvalues[instanceNo][_len]; k++) { double t; if (k<=Phase-1) t = 1.0 * k/(Phase-1); else t = 1.0 + (k-Phase+1)*(2.0*Cycle-1.0)/(Cycle*length-1.0); double beta = cos(M_PI*t); double g = 1.0/(Coeff*t+1); if (t <= 0.5 ) g = 1; nlmalphas[k][instanceNo] = g * beta; nlmvalues[instanceNo][_weight] += nlmalphas[k][instanceNo]; } } // // // // // if (nlmvalues[instanceNo][_weight]>0) { double sum = 0; for (int k=0; k < (int)nlmvalues[instanceNo][_len] && (r-k)>=0; k++) sum += nlmalphas[k][instanceNo]*nlmprices[r-k][instanceNo]; return( sum / nlmvalues[instanceNo][_weight]); } else return(0); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // #define _prHABF(_prtype) (_prtype>=pr_habclose && _prtype<=pr_habtbiased2) #define _priceInstances 1 #define _priceInstancesSize 4 double workHa[][_priceInstances*_priceInstancesSize]; 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*=_priceInstancesSize; int r = bars-i-1; // // // // // double haOpen = (r>0) ? (workHa[r-1][instanceNo+2] + workHa[r-1][instanceNo+3])/2.0 : (open[i]+close[i])/2;; double haClose = (open[i]+high[i]+low[i]+close[i]) / 4.0; if (_prHABF(tprice)) if (high[i]!=low[i]) haClose = (open[i]+close[i])/2.0+(((close[i]-open[i])/(high[i]-low[i]))*fabs((close[i]-open[i])/2.0)); else haClose = (open[i]+close[i])/2.0; double haHigh = fmax(high[i],fmax(haOpen,haClose)); double haLow = fmin(low[i] ,fmin(haOpen,haClose)); // // // // // if(haOpenhaOpen) return((haHigh+haClose)/2.0); else return((haLow+haClose)/2.0); case pr_hatbiased2: case pr_habtbiased2: 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]=Bars-3) return; if ((second[i] != EMPTY_VALUE) && (second[i+1] != EMPTY_VALUE)) second[i+1] = EMPTY_VALUE; else if ((first[i] != EMPTY_VALUE) && (first[i+1] != EMPTY_VALUE) && (first[i+2] == EMPTY_VALUE)) first[i+1] = EMPTY_VALUE; } void PlotPoint(int i,double& first[],double& second[],double& from[]) { if (i>=Bars-2) return; if (first[i+1] == EMPTY_VALUE) if (first[i+2] == EMPTY_VALUE) { first[i] = from[i]; first[i+1] = from[i+1]; second[i] = EMPTY_VALUE; } else { second[i] = from[i]; second[i+1] = from[i+1]; first[i] = EMPTY_VALUE; } else { first[i] = from[i]; second[i] = EMPTY_VALUE; } }