//+------------------------------------------------------------------+ //| Repulse Indicator | //+------------------------------------------------------------------+ #property copyright "www.forex-tsd.com" #property link "www.forex-tsd.com" #property indicator_separate_window #property indicator_buffers 4 #property indicator_plots 1 #property indicator_label1 "Repulse" #property indicator_type1 DRAW_LINE #property indicator_color1 clrDeepSkyBlue #property indicator_width1 2 input int RepulsePeriod = 9; input int xbars = 1; double repulse[]; double Positive[]; double Negative[]; double rep[]; int OnInit() { SetIndexBuffer(0,repulse ,INDICATOR_DATA); SetIndexBuffer(1,Positive ,INDICATOR_CALCULATIONS); SetIndexBuffer(2,Negative ,INDICATOR_CALCULATIONS); SetIndexBuffer(3,rep,INDICATOR_CALCULATIONS); 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[]) { int counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; int limit=MathMin(Bars-counted_bars,Bars-1); for (int i=limit; i>=0; i--) { double max = high[i]; double min = low[i]; for (int k=1; k< RepulsePeriod && (i+k)>=0; k++) { max = MathMax(max,high[i+k]); min = MathMin(min, low[i+k]); } Positive[i] = 100.0 * (3*close[i] - 2*min - open[i]) / close[i]; Negative[i] = 100.0 * ( open[i] + 2*max - 3*close[i]) / close[i]; double Bull = iEma(Positive[i],RepulsePeriod*5,i,rates_total,0); double Bear = iEma(Negative[i],RepulsePeriod*5,i,rates_total,1); repulse[i] = Bull-Bear; rep[i]=Bull-Bear; } Run_Alerts(xbars); // index number as input return(rates_total); } double workEma[][2]; double iEma(double price, double period, int r, int totalBars, int instanceNo=0) { if (ArrayRange(workEma,0)!= totalBars) ArrayResize(workEma,totalBars); r=Bars-r-1; double alpha = 2.0 / (1.0+period); if (r<1) workEma[r][instanceNo] = price; else workEma[r][instanceNo] = workEma[r-1][instanceNo]+alpha*(price-workEma[r-1][instanceNo]); return(workEma[r][instanceNo]); } void Run_Alerts(int g) { if(rep[g+1]>0 && rep[g]<0) Show_Alert(g,"CROSSING DOWN"); if(rep[g+1]<0 && rep[g]>0) Show_Alert(g,"CROSSING UP"); Comment("rep [1] = ",NormalizeDouble(rep[g],5)," rep [2] = ",NormalizeDouble(rep[g+1],5)); } void Show_Alert(int indx, string alert_str) { static string prevAlert="none"; static datetime prevTime; string prefix=Symbol()+" "+IntegerToString(Period())+" at "+TimeToString(TimeLocal(),TIME_SECONDS)+" "; string message; if (prevAlert != alert_str || prevTime != Time[indx]) { prevAlert = alert_str; prevTime = Time[indx]; message = prefix+alert_str; Alert(message); Alert("repulse[2] = ",rep[indx+1]," repulse[1]=",rep[indx]); } }