//+------------------------------------------------------------------+
//| ASCTrend1i.mq4 
//| Ramdass - Conversion only
//| Updates:
//|  2013-04-15, v1.1, X
//|    - Bug fix. Check array bounds in loops
//|    - Bug fix. Set correct nr of counted bars on first run
//|  2012-10-23, X, Performance enhancements. About 500x improvement.
//|    - Removed redundant code and variables
//|    - Cleaned up and modified code for improved performance
//|    - Update only the new bars instead of the full buffer.
//|    - Commented code
//|    - Option to use full buffer size.
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 10
#property indicator_color1 Black
#property indicator_color2 Black
#property indicator_color3 Black
#property indicator_color4 Black
#property  indicator_width1  1 
#property  indicator_width2  1

#define VERSION "1.1"

#define RANGE_FACTOR 4.6
#define ALT_PERIOD 4
#define HIGH_LEVEL 67
#define LOW_LEVEL 33

//---- input parameters
extern int   Risk=6;       // Risk level. WPR_Period=3+Risk*2 or WPR_Period=ALT_PERIOD for a large move 
extern int   BarCount=0;   // 0 for full chart buffer

double CrossUp[];
double CrossDown[];
double syg[],dnSyg[],upSyg[];

extern int FasterEMA = 5;
extern int SlowerEMA = 12;
extern bool SoundON=false;

extern int   Rectangle_Size=10;
extern color Rectangle_Color_Up=clrLightGray;
extern color Rectangle_Color_Down=clrDarkGray;

extern bool  Rectangle_Use=true;

double alertTag;
double control=2147483647;

//---- buffers
double dn_sig[];
double up_sig[];
double signal[];
double dn_sig_2[];
double up_sig_2[];
string Name;
int first=0;
int last=1;
int sigA=1;
int sigB=1;
datetime bar;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
  bar=-1;
  Name="ASCTren+Ema";//MQLInfoString(MQL_PROGRAM_NAME)+IntegerToString(Risk)+IntegerToString(BarCount);
//Init buffers
   IndicatorBuffers(10);
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,234);
   SetIndexBuffer(0,dn_sig);
   SetIndexLabel(0,"Down");
   SetIndexDrawBegin(0,3+Risk*2+1);
   
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,233);
   SetIndexBuffer(1,up_sig);
   SetIndexLabel(1,"Up");
   SetIndexDrawBegin(1,3+Risk*2+1);
   
   SetIndexStyle(2,DRAW_ARROW,EMPTY,1);
   SetIndexArrow(2,233);
   SetIndexBuffer(2,CrossUp);
   
   SetIndexStyle(3,DRAW_ARROW,EMPTY,1);
   SetIndexArrow(3,234);
   SetIndexBuffer(3,CrossDown);
   
   SetIndexStyle(4,DRAW_NONE); 
   SetIndexBuffer(4,signal);
   SetIndexLabel(4,"Signal");
   
   SetIndexBuffer(5,dn_sig_2);
   SetIndexStyle(5,DRAW_NONE);

   SetIndexBuffer(6,up_sig_2);
   SetIndexStyle(6,DRAW_NONE);

   SetIndexBuffer(7,syg);
   SetIndexStyle(7,DRAW_NONE);
   
   SetIndexBuffer(8,dnSyg);
   SetIndexStyle(8,DRAW_NONE);
   
   SetIndexBuffer(9,upSyg);
   SetIndexStyle(9,DRAW_NONE);


// Set max bars to draw
   if(BarCount<1 || BarCount>Bars)
      BarCount=Bars-12;
     
   return(0);
  }
//+------------------------------------------------------------------+
int deinit()
  {
   ObjectsDeleteAll(0,Name);
   return(0);
  }
//+------------------------------------------------------------------+
//| ASCTrend1sig                                                     |
//+------------------------------------------------------------------+
int start()
  {
  if(bar==Time[0])return -1;
  bar=Time[0];
   int counter;
   double fasterEMAnow,slowerEMAnow,fasterEMAprevious,slowerEMAprevious,fasterEMAafter,slowerEMAafter;
   double Range,AvgRange;
   int i,shift,counted_bars,min_bars,wpr_period;
   double wpr_value,avg_range,high_level,low_level;

// Set levels 
   high_level=HIGH_LEVEL+Risk;
   low_level=LOW_LEVEL-Risk;

// Check for enough bars
   min_bars=3+Risk*2+1;
   if(Bars<=min_bars)
      return(0);

// Get new bars
   counted_bars=IndicatorCounted();
   if(counted_bars<0)
      return (-1);
   if(counted_bars>0)
      counted_bars--;
   shift=Bars-counted_bars;
   if(BarCount>0 && shift>BarCount)
      shift=BarCount;
   if(shift>Bars-min_bars)
      shift=Bars-min_bars;
   shift=Bars;
   while(shift>=0)
     {
      // Calc Avg range for 10 bars
      i=shift;
      avg_range=0.0;
      for(i=shift; i<shift+10; i++)
        {
         if(i>=Bars) break;
         avg_range=avg_range+MathAbs(High[i]-Low[i]);
        }
      avg_range=avg_range/10.0;

      // Set period for WPR calculation.
      wpr_period=3+Risk*2;

      // Use alternative period if there has been a large move.
      i=shift;
      while(i<shift+6)
        {
         if(i>=Bars-3) break;
         if(MathAbs(Close[i+3]-Close[i])>=avg_range*RANGE_FACTOR)
           {
            wpr_period=ALT_PERIOD;
            break;
           }
         i++;
        }

      // Calc WPR 
      wpr_value=100-MathAbs(iWPR(NULL,0,wpr_period,shift));

      // Set current signal
      if(wpr_value>=high_level)
         signal[shift]=1;
      else if(wpr_value<=low_level)
                         signal[shift]=-1;
      else if(wpr_value>low_level && signal[shift+1]==1)
         signal[shift]=1;
      else if(wpr_value<high_level && signal[shift+1]==-1)
         signal[shift]=-1;
      else
         signal[shift]=0;

      // Draw arrows
      dn_sig[shift]=0;
      up_sig[shift]=0;
      
      
      if(signal[shift]==-1 && signal[shift+1]==1){
      
      if (last==2){
         dn_sig[shift]=High[shift]+avg_range*1;
         last=1;
         sigA=1;
         sigB=0;
         }}
         
      
      if(signal[shift]==1 && signal[shift+1]==-1){
      if (last==1){
         up_sig[shift]=Low[shift]-avg_range*1;
         last=2;
         sigA=1;
         sigB=0;
         }}
         
         
//---------------------------------------------------------------------------------------------------
      i=shift;
      syg[i]=syg[i+1];
      dnSyg[i]=dnSyg[i+1];
      upSyg[i]=upSyg[i+1];
      counter=i;
      Range=0;
      AvgRange=0;
      for(counter=i;counter<=i+9;counter++)
        {
         AvgRange=AvgRange+MathAbs(High[counter]-Low[counter]);
        }
      Range=AvgRange/10;

      fasterEMAnow=iMA(NULL,0,FasterEMA,0,MODE_EMA,PRICE_CLOSE,i);
      fasterEMAprevious=iMA(NULL,0,FasterEMA,0,MODE_EMA,PRICE_CLOSE,i+1);
      fasterEMAafter=iMA(NULL,0,FasterEMA,0,MODE_EMA,PRICE_CLOSE,i-1);

      slowerEMAnow=iMA(NULL,0,SlowerEMA,0,MODE_EMA,PRICE_CLOSE,i);
      slowerEMAprevious=iMA(NULL,0,SlowerEMA,0,MODE_EMA,PRICE_CLOSE,i+1);
      slowerEMAafter=iMA(NULL,0,SlowerEMA,0,MODE_EMA,PRICE_CLOSE,i-1);
      
      //Crossown[i]=EMPTY;
      //CrossUp[i]=EMPTY;

      if((fasterEMAnow>slowerEMAnow) && (fasterEMAprevious<slowerEMAprevious) && (fasterEMAafter>slowerEMAafter))
        {
           
           if (last==1){
            CrossUp[i]=Low[i]-Range*0.5;
            last=2;
            upSyg[i]=Close[i];
            syg[i]=1;
            sigA=0;
            sigB=1;
           }
        }
      else if((fasterEMAnow<slowerEMAnow) && (fasterEMAprevious>slowerEMAprevious) && (fasterEMAafter<slowerEMAafter))
        {
           
           if (last==2){
            CrossDown[i]=High[i]+Range*0.5;
            last=1;
            dnSyg[i]=Close[i];
            syg[i]=-1;
            sigA=0;
            sigB=1;
           }
        }

      if(Rectangle_Use && sigB && !sigA)
        {
         if(i>0)
           {
            if(syg[i]<0)
              {
              if (last==1){
               ObjectCreate(0,Name+"dn"+Time[i],OBJ_RECTANGLE,0,Time[i],dnSyg[i],Time[i-1],dnSyg[i]-Rectangle_Size*Point);
               ObjectSetInteger(0,Name+"dn"+Time[i],OBJPROP_COLOR,Rectangle_Color_Down);}
              }
            else
              {
              if (last==2){
               ObjectCreate(0,Name+"up"+Time[i],OBJ_RECTANGLE,0,Time[i],upSyg[i],Time[i-1],upSyg[i]+Rectangle_Size*Point);
               ObjectSetInteger(0,Name+"up"+Time[i],OBJPROP_COLOR,Rectangle_Color_Up);}
              }
           }
        }
      if(SoundON==true && i==1 && CrossUp[i]>CrossDown[i] && alertTag!=Time[0])
        {
         Alert("EMA Cross Trend going Down on ",Symbol()," ",Period());
         alertTag=Time[0];
        }
      if(SoundON==true && i==1 && CrossUp[i]<CrossDown[i] && alertTag!=Time[0])
        {
         Alert("EMA Cross Trend going Up on ",Symbol()," ",Period());
         alertTag=Time[0];
        }
        
        //****************************************************************************************
        
        if(Rectangle_Use && sigA && !sigB )
      {
      if(dn_sig[shift]>0)
         dn_sig_2[shift]=Close[shift];
      else
         dn_sig_2[shift]=dn_sig_2[shift+1];
      if(up_sig[shift]>0)dn_sig_2[shift]=0;

      if(dn_sig_2[shift]>0)
        {
         if(shift>0 && last==1)
            ObjectCreate(0,Name+"dn"+Time[shift],OBJ_RECTANGLE,0,Time[shift],dn_sig_2[shift],Time[shift-1],dn_sig_2[shift]-Rectangle_Size*Point);
            ObjectSetInteger(0,Name+"dn"+Time[shift],OBJPROP_COLOR,Rectangle_Color_Down);
        }

      if(up_sig[shift]>0)
         up_sig_2[shift]=Close[shift];
      else
        up_sig_2[shift]=up_sig_2[shift+1];
      if(dn_sig[shift]>0)up_sig_2[shift]=0; 

      if(up_sig_2[shift]>0)
        {
         if(shift>0 && last==2)
            ObjectCreate(0,Name+"up"+Time[shift],OBJ_RECTANGLE,0,Time[shift],up_sig_2[shift],Time[shift-1],up_sig_2[shift]+Rectangle_Size*Point);
            ObjectSetInteger(0,Name+"up"+Time[shift],OBJPROP_COLOR,Rectangle_Color_Up);
        }
      }


      shift--;
     }
     
//   return(0);
  }
//+------------------------------------------------------------------+

//  Remove the // from 340