//+------------------------------------------------------------------+
//|                                            ColorWave-Channel.mq4 |
//|                      Copyright © 2014, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
//
//------------------------------------------------------------------
#property copyright "Copyright © 2014 ColorWave"
#property link      "http://www.metaquotes.net"
//------------------------------------------------------------------
//
#property indicator_chart_window
#property indicator_buffers 7

/* Colors of the buffers -------------------------------------- */
#property indicator_color1 MidnightBlue
#property indicator_color2 Maroon
#property indicator_color3 Maroon
#property indicator_color4 Maroon
#property indicator_color5 DarkGreen
#property indicator_color6 DarkGreen
#property indicator_color7 DarkGreen

/* User parameters ------------------------------------------- */
extern int NumBars = 120;
extern int RegressionDegree = 3;
extern double Dev1 = 0.7236;
extern double Dev2 = 1.1708;
extern double Dev3 = 1.618;

/* Sound parameters ------------------------------------------ */
extern string    SoundStopSell ="stopsell.wav";
extern string    SoundStopBuy="stopbuy.wav";
extern bool      ActiveSignal=true;
extern bool      ActiveAlert=true;
extern bool      SendMailPossible = false;

int prevtime;
/* Buffers --------------------------------------------------- */
double centerline[];
double upper_gray[];
double upper_red_1[];
double upper_red_2[];
double lower_gray[];
double lower_green_1[];
double lower_green_2[];

/* Initialization -------------------------------------------- */
int init() {
   SetIndexStyle(0, DRAW_LINE);
   SetIndexStyle(1, DRAW_LINE);
   SetIndexStyle(2, DRAW_LINE);
   SetIndexStyle(3, DRAW_LINE);
   SetIndexStyle(4, DRAW_LINE);
   SetIndexStyle(5, DRAW_LINE);
   SetIndexStyle(6, DRAW_LINE);

   SetIndexBuffer(0, centerline);
   SetIndexBuffer(1, upper_gray);
   SetIndexBuffer(2, upper_red_1);
   SetIndexBuffer(3, upper_red_2);
   SetIndexBuffer(4, lower_gray);
   SetIndexBuffer(5, lower_green_1);
   SetIndexBuffer(6, lower_green_2);

   return (0);
}

/* Entry point ---------------------------------------------- */
int start()
{
   int i, j, k;

   int n;
   double sum;
   double std_dev;

   double a[20][20];
   double sx[20];
   double b[20];
   double x[20];

   n = RegressionDegree + 1;
   sx[1] = NumBars + 1;

   // ---- sx ------------------------------------------------
   for (j = 1; j <= n * 2 - 2; j++)
   {
      sum = 0;
      for (i = 0; i <= NumBars; i++)
      {
         sum += MathPow(i, j);
      }
      sx[j + 1] = sum;
   }

   // ---- vector b -------------------------------------------
   for (j = 1; j <= n; j++)
   {
      sum = 0;
      for (i = 0; i <= NumBars; i++)
      {
         if (j == 1)
         {
            sum += (High[i] + Low[i]) / 2.0;
         }
         else
         {
            sum += (High[i] + Low[i]) / 2.0 * MathPow(i, j - 1);
         }
      }
      b[j] = sum;
   }

   // ---- matrix a ------------------------------------------
   for (i = 1; i <= n; i++)
   {
      for (j = 1; j <= n; j++)
      {
         k = i + j - 1;
         a[i][j] = sx[k];
      }
   }

   // ---- Gauss ---------------------------------------------
   GaussElimination(a, b, n, x);

   // ---- SQ ---------------------------------------------
   for (i = 0; i <= NumBars; i++)
   {
      sum = 0;
      for (k = 1; k <= RegressionDegree; k++)
      {
         sum += (x[k+1]) * MathPow(i, k);
      }
      centerline[i] = x[1] + sum;
   }

   std_dev = iStdDev(NULL, 0, NumBars, 0, MODE_SMA, PRICE_HIGH, 0);

   for (i = 0; i <= NumBars; i++)
   {
      upper_red_2[i] = centerline[i] + std_dev * Dev3;
      upper_red_1[i] = centerline[i] + std_dev * Dev2;
      upper_gray[i] = centerline[i] + std_dev * Dev1;
      lower_green_2[i] = centerline[i] - std_dev * Dev3;
      lower_green_1[i] = centerline[i] - std_dev* Dev2;
      lower_gray[i] = centerline[i] - std_dev * Dev1;
   }

   Comment("COG: " + (Close[0] - centerline[0]) / std_dev);

   // Drawing settings
   SetIndexDrawBegin(0, Bars - NumBars - 1);
   SetIndexDrawBegin(1, Bars - NumBars - 1);
   SetIndexDrawBegin(2, Bars - NumBars - 1);
   SetIndexDrawBegin(3, Bars - NumBars - 1);
   SetIndexDrawBegin(4, Bars - NumBars - 1);
   SetIndexDrawBegin(5, Bars - NumBars - 1);
   SetIndexDrawBegin(6, Bars - NumBars - 1);
 double min=MathMin(High[1],Low[0]);
 double max=MathMax(Low[1],High[0]);
 string  message  =  StringConcatenate(Symbol() + "  ЗАКРЫВАЕМ  ( SELL ) !!!"); 
 string  message2 =  StringConcatenate(Symbol() + "  ЗАКРЫВАЕМ  ( BUY ) !!!"); 
//----
if (Time[0] == prevtime) return(0);
   
   if ( ActiveSignal && min <= lower_gray[0])
     {
      if (ActiveAlert) Alert (message); // Предупреждение на экран
      if(SoundStopSell!="" ) PlaySound( SoundStopSell ); // Звуковой сигнал
      if (SendMailPossible) SendMail(Symbol(),message); 
      prevtime = Time[0];
     }
  
   if (ActiveSignal && max >= upper_gray[0])
     {
      if (ActiveAlert) Alert (message2); // Предупреждение на экран
      if(SoundStopBuy!="" ) PlaySound( SoundStopBuy ); // Звуковой сигнал
      if (SendMailPossible) SendMail(Symbol(),message2); 
      prevtime = Time[0];
     }
   return (0);
}

/* Housekeeping --------------------------------------------- */
int deinit() {
   Comment("");

   return (0);
}

/**
* This function solves a system of max_linear equations using
* the Gauss elimination method.
*
* a: square matrix of size (n+1)x(n+1) containing the coefficients of
*    the equations. max_line/column 0 of the matrix are not considered so
*    that the matrix effective size is nxn.
* b: vector of size n containing the results of each equation composing
*    the system.
* n: size of the n x n matrix containing the coefficients.
* x (OUT): vector of size n receiving the solutions of the system.
*
* return: the fonction returns the value 1 if an error occurent. The value
*         o is returned if no error occured.
*/
int GaussElimination(double & a[][], double & b[], int n, double & x[])
{
    int err = 0;

    int i, j, k; // Matrix indices

    double max_value;
    int max_line;
    double quotient;
    double temp;
    double sum;

    /* First, transfort matrix a in its row echelon form */
    for(k = 1; k <= n-1; k++)
    {
        max_line = 0;
        max_value = 0;

        /* looking for the maximum coefficient in each column */
        for(i = k; i <= n; i++)
        {
            if (MathAbs(a[i,k]) > max_value)
            {
                max_value = MathAbs(a[i,k]);
                max_line = i;
            }
        }

        if (max_line == 0)
        {
            // Error
            err = 1;
            return(err);
        }

        if (max_line != k)
        {
            for(j = 1; j <= n; j++)
            {
                /* max_lines k and max_line of the matrix are swaped */
                temp = a[k,j];
                a[k,j] = a[max_line,j];
                a[max_line,j] = temp;
            }

            /* elements k and max_line of the vector are swaped */
            temp = b[k];
            b[k] = b[max_line];
            b[max_line] = temp;
        }

        for(i = k+1; i <= n; i++)
        {
            quotient = a[i,k] / a[k,k];

            for(j=1; j <= n; j++)
            {
                if (j==k)
                {
                    a[i,j] = 0;
                }
                else
                {
                    a[i,j] = a[i,j] - quotient * a[k,j];
                }
            }

            b[i] = b[i] - quotient * b[k];
        }
    }

    /* Computes the solutions of the system of linar equations
       from the row echelon matrix b */
    x[n] = b[n] / a[n,n];

    for(i = n - 1; i >= 1; i--)
    {
        sum = 0;

        for(j = 1; j <= n - i ; j++)
        {
            sum += a[i,i+j] * x[i+j];
            x[i] = (1/a[i,i]) * (b[i] - sum);
        }
    }

    return(err);
}


