//+------------------------------------------------------------------+
//|                                                 SSA of price.mq4 |
//|                                                           mladen |
//+------------------------------------------------------------------+
#property copyright "mladen"
#property link      "mladenfx@gmail.com"

//
//
//    max arraySize - 5000
//    max lag - 200 (but will be slow for big lags)
//    max numberOfComputations - 20 (it just makes it "fit" more precise to source array)
//
//

#import "libSSA.dll"
   void fastSingular(double& sourceArray[],int arraySize, int lag, int numberOfComputationLoops, double& destinationArray[]);
#import

//
//
//
//
//

#property indicator_separate_window
#property indicator_buffers    3
#property indicator_minimum    -100
#property indicator_maximum    0
#property indicator_label1     "SSA Wpr"
#property indicator_type1      DRAW_LINE
#property indicator_color1     clrMediumSeaGreen
#property indicator_width1     2
#property indicator_label2     "SSA Wpr"
#property indicator_type2      DRAW_LINE
#property indicator_color2     clrOrangeRed
#property indicator_width2     2
#property indicator_label3     "SSA Wpr"
#property indicator_type3      DRAW_LINE
#property indicator_color3     clrOrangeRed
#property indicator_width3     2
#property indicator_level1     -80
#property indicator_level2     -20
#property indicator_levelcolor clrWhite
#property indicator_levelstyle STYLE_DOT



//
//
//
//
//

   extern int Lag                  =  25;
   extern int NumberOfComputations =   2;
   extern int NumberOfBars         = 500;
   extern int Price                = PRICE_CLOSE;
   extern double WprPeriod         = 14;
//
//
//
//
//

double SSA[],vala[],valb[],valc[],sourceValues[],calcValues[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int init()
{
   IndicatorBuffers(4);
   SetIndexBuffer(0,SSA,INDICATOR_DATA);
   SetIndexBuffer(1,vala,INDICATOR_DATA);
   SetIndexBuffer(2,valb,INDICATOR_DATA);
   SetIndexBuffer(3,valc);
   
   NumberOfBars = MathMin(NumberOfBars,5000);
   ArrayResize(sourceValues,NumberOfBars);
   ArrayResize(calcValues,NumberOfBars);
   
return(0);
}
int deinit() { return(0); }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int start()
{
   static datetime barTime;
   int counted_bars=IndicatorCounted();
   int i,n,limit;

   //
   //
   //
   //
   //
      
   n = NumberOfBars;
      if (n > Bars)
      {
         n = Bars;
         if (ArraySize(sourceValues) != n) { ArrayResize(sourceValues,n); ArrayResize(calcValues,n); }
      }                     
      if(counted_bars < 0) return(-1);
      if(counted_bars > 0) counted_bars--;
           limit = MathMin(Bars-counted_bars,n-1);
                   SetIndexDrawBegin(0,Bars-n);
                   if (barTime!=Time[0])
                   {
                        barTime=Time[0];
                        limit=n-1;
                   }                        

   //
   //
   //
   //
   //
   
   
   for(i=limit; i>=0; i--)  
      sourceValues[i]=iWPR(NULL, 0,WprPeriod,i); 
      fastSingular(sourceValues,n,Lag,NumberOfComputations,calcValues); ArrayCopy(SSA,calcValues);
   if (valc[limit]==-1) iCleanPoint(limit,Bars,vala,valb);
   for(i=limit; i>=0; i--) 
   {   
      valc[i] = (i<Bars-1) ? (SSA[i]>SSA[i+1]) ? 1 : (SSA[i]<SSA[i+1]) ? -1 : valc[i+1] : 0;
      if (valc[i] == -1) iPlotPoint(i,Bars,vala,valb,SSA); else vala[i] = valb[i] = EMPTY_VALUE;
   }
return(0);
}

//
//
//

void iCleanPoint(int i,int bars,double& first[],double& second[])
{
   if (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 iPlotPoint(int i,int bars,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; }
}
