//------------------------------------------------------------------

   #property copyright "mladen"
   #property link      "www.forex-tsd.com"
   
//------------------------------------------------------------------
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1  DeepSkyBlue
#property indicator_width1  2
#property indicator_color2  PaleVioletRed
#property indicator_width2  2
#property indicator_color3  PaleVioletRed
#property indicator_width3  2
#property indicator_color4  Gold
#property indicator_width4  2

//
//
//
//
//

extern int ROCPeriod1     = 14;
extern int ROCPeriod2     = 10;
extern int Smooth         = 11;
extern int Signal         = 5;
extern int SignalMethod   = MODE_SMA;

//
//
//
//
//

double osc[];
double oscda[];
double oscdb[];
double signal[];
double slope[];

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//

int init()
{
      IndicatorBuffers(5);
      SetIndexBuffer(0,osc);    SetIndexLabel(0,"Coppock curve");
      SetIndexBuffer(1,oscda);  SetIndexLabel(1,"Coppock curve");
      SetIndexBuffer(2,oscdb);  SetIndexLabel(2,"Coppock curve"); 
      SetIndexBuffer(3,signal); SetIndexLabel(3,"Coppock curve signal");
      SetIndexBuffer(4,slope);

   IndicatorShortName(" Coppock curve "+" ("+ROCPeriod1+","+ROCPeriod2+","+Smooth+","+Signal+")");
   return(0);
}
int deinit() { return(0); }

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

int start()
{
   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
           int limit=MathMin(Bars-counted_bars,Bars-1);
           if (slope[limit] == -1) CleanPoint(limit,oscda,oscdb);
      
      //
      //
      //
      //
      //
      
      for (int i=limit;i>=0;i--)
      {
         osc[i]   = iLwma(iROC(ROCPeriod1,i)+iROC(ROCPeriod2,i),Smooth,i,0);
         oscda[i] = EMPTY_VALUE;
         oscdb[i] = EMPTY_VALUE;
         slope[i] = slope[i+1];
         if (osc[i] > osc[i+1]) slope[i] =  1;
         if (osc[i] < osc[i+1]) slope[i] = -1;
         if (slope[i] == -1) PlotPoint(i,oscda,oscdb,osc);      
      }
      if (Signal>1) for (i=limit; i>=0; i--) signal[i] = iMAOnArray(osc,0,Signal,0,SignalMethod,i);
return(0);
}      

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

double workLwma[][1];
double iLwma(double price, double period, int r, int instanceNo=0)
{
   if (ArraySize(workLwma)!= Bars) ArrayResize(workLwma,Bars); r = Bars-r-1;
   
   //
   //
   //
   //
   //
   
   workLwma[r][instanceNo] = price;
      double sumw = period;
      double sum  = period*price;

      for(int k=1; k<period && (r-k)>=0; k++)
      {
         double weight = period-k;
                sumw  += weight;
                sum   += weight*workLwma[r-k][instanceNo];  
      }             
return(sum/sumw);
}

//
//
//
//
//

double iROC(int period, int shift)
{
   double ROC;

   if (Close[shift + period] != 0)
          ROC = (Close[shift]-Close[shift + period]) / Close[shift + period];
   else   ROC = 0.00;
   return(ROC*100.00);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

void CleanPoint(int i,double& first[],double& second[])
{
   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 (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;
      }
}


