//
// SSChannel3 v1.02a - updated by eni in 2015
//

//
// properties
//

#property strict

#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1  clrLightGray
#property indicator_color2  clrLightGray   
#property indicator_color3  clrLightGray
#property indicator_color4  clrLightGray
#property indicator_color5  clrLightGray
#property indicator_color6  clrLightGray
#property indicator_color7  clrFireBrick
#property indicator_color8  clrBlue

#property indicator_width1  2
#property indicator_width2  2
#property indicator_width3  1
#property indicator_width4  1
#property indicator_width5  1
#property indicator_width6  1
#property indicator_width7  12
#property indicator_width8  12

#property indicator_style1  0
#property indicator_style2  0
#property indicator_style3  0
#property indicator_style4  0
#property indicator_style5  0
#property indicator_style6  0
#property indicator_style7  3
#property indicator_style8  3

//
// input section
//

input int  dist_Pri           = 24;      // distance strong signal
input int  dist_Sec           = 14;      // distance minor or exit signal
input int  dist_Big           = 56;      // distance big signal for priority check
input bool processminor       = true;    // process  minor or exit signal
input bool showchannel        = false;    // show channel on chart
input bool alertsOn           = false;   // enable alerts
input bool alertsOnCurrent    = false;    // alert current
input bool alertsMessage      = false;    // send message
input bool alertsNotification = false;   // send notification
input bool alertsEmail        = false;   // send email
input bool alertsSound        = false;   // play sound

//
// global variables section
//

double b1[];
double b2[];
double b3[];
double b4[];
double b5[];
double b6[];
double b7[];
double b8[];

//
// init indicator
//

int init()
  {
    SetIndexBuffer     ( 0, b1          );
    SetIndexBuffer     ( 1, b2          );
    SetIndexBuffer     ( 2, b3          );
    SetIndexBuffer     ( 3, b4          );
    SetIndexBuffer     ( 4, b5          );
    SetIndexBuffer     ( 5, b6          );
    SetIndexBuffer     ( 6, b7          );
    SetIndexBuffer     ( 7, b8          );
   
    SetIndexStyle      ( 0, DRAW_ARROW  ); SetIndexArrow ( 0, 164 );
    SetIndexStyle      ( 1, DRAW_ARROW  ); SetIndexArrow ( 1, 164 );
    SetIndexStyle      ( 2, DRAW_ARROW  ); SetIndexArrow ( 2, 251 );
    SetIndexStyle      ( 3, DRAW_ARROW  ); SetIndexArrow ( 3, 251 );
    SetIndexStyle      ( 4, DRAW_LINE   );
    SetIndexStyle      ( 5, DRAW_LINE   );
    SetIndexStyle      ( 6, DRAW_ARROW  ); SetIndexArrow ( 6, 164 );
    SetIndexStyle      ( 7, DRAW_ARROW  ); SetIndexArrow ( 7, 164 );
   
    if ( !processminor )
       {
         SetIndexStyle ( 2, DRAW_NONE   );
         SetIndexStyle ( 3, DRAW_NONE   );
       }
    
    if ( !showchannel  )
       {
         SetIndexStyle ( 4, DRAW_NONE   );
         SetIndexStyle ( 5, DRAW_NONE   );
       }
   
    SetIndexEmptyValue ( 0, EMPTY_VALUE );
    SetIndexEmptyValue ( 1, EMPTY_VALUE );
    SetIndexEmptyValue ( 2, EMPTY_VALUE );
    SetIndexEmptyValue ( 3, EMPTY_VALUE );
    SetIndexEmptyValue ( 4, EMPTY_VALUE );
    SetIndexEmptyValue ( 5, EMPTY_VALUE );
    SetIndexEmptyValue ( 6, EMPTY_VALUE );
    SetIndexEmptyValue ( 7, EMPTY_VALUE );
   
    return(0);
  }
  
//
// deinit indicator
//

int deinit()
  {
    return(0);
  }
  
//
// indicator loop
//

int start()
{
    int i, limit, counted_bars, hhb, llb, hhb1, llb1, hhbx, llbx;
   
    if ( Bars <= MathMax ( dist_Sec, dist_Pri ) + 1 ) return(0);

    counted_bars = IndicatorCounted();
    if ( counted_bars < 0 ) return(-1);
    if ( counted_bars > 0 ) counted_bars--;
    limit = Bars - counted_bars;
    
    limit = MathMax ( limit , dist_Sec );
    limit = MathMax ( limit , dist_Pri );
    
    //

    for ( i = limit ; i >= 0 ; i-- )
        {
          if ( i > Bars - 1 ) continue;   // no array out of range on indicator start;
         
          hhb1 = Highest ( NULL, 0, MODE_HIGH, dist_Sec, i - dist_Sec / 2 );
          llb1 = Lowest  ( NULL, 0, MODE_LOW , dist_Sec, i - dist_Sec / 2 );
          hhb  = Highest ( NULL, 0, MODE_HIGH, dist_Pri, i - dist_Pri / 2 );
          llb  = Lowest  ( NULL, 0, MODE_LOW , dist_Pri, i - dist_Pri / 2 );
          hhbx = Highest ( NULL, 0, MODE_HIGH, dist_Big, i - dist_Big / 2 );
          llbx = Lowest  ( NULL, 0, MODE_LOW , dist_Big, i - dist_Big / 2 );

          b1[i] = EMPTY_VALUE;
          b2[i] = EMPTY_VALUE;
          b3[i] = EMPTY_VALUE;
          b4[i] = EMPTY_VALUE;
          b5[i] = EMPTY_VALUE;
          b6[i] = EMPTY_VALUE;
          b7[i] = EMPTY_VALUE;
          b8[i] = EMPTY_VALUE;
      
          // double tr = iATR ( NULL, 0, 50, i );
          
          if ( i == hhb  ) b1[i] = High[hhb ];   // + tr;
          if ( i == llb  ) b2[i] = Low [llb ];   // - tr;
          if ( i == hhb1 ) b3[i] = High[hhb1];   // + tr / 2;
          if ( i == llb1 ) b4[i] = Low [llb1];   // - tr / 2;
          if ( i == hhbx ) b7[i] = High[hhbx];   // + tr;
          if ( i == llbx ) b8[i] = Low [llbx];   // - tr;
          
          if ( b1[i] != EMPTY_VALUE ) b3[i] = EMPTY_VALUE;
          if ( b2[i] != EMPTY_VALUE ) b4[i] = EMPTY_VALUE;
          
          if ( b7[i] != EMPTY_VALUE ) b1[i] = EMPTY_VALUE;
          if ( b8[i] != EMPTY_VALUE ) b2[i] = EMPTY_VALUE;
         
          b5[i] = High[hhb];
          b6[i] = Low [llb]; 
        }
      
    //
    
    if ( alertsOn )
       {
         int forBar;
         
         forBar                        = 1;
         if ( alertsOnCurrent ) forBar = 0;
         
         if ( ( b1[forBar] != EMPTY_VALUE || b7[forBar] != EMPTY_VALUE ) && b3[forBar] != EMPTY_VALUE ) doAlert ( "strong sell" );
         if ( ( b1[forBar] != EMPTY_VALUE || b7[forBar] != EMPTY_VALUE ) && b3[forBar] == EMPTY_VALUE ) doAlert ( "sell"        );
         if ( processminor )
            {
              if ( b1[forBar] == EMPTY_VALUE && b3[forBar] != EMPTY_VALUE ) doAlert ( "minor sell or exit buy" );
            }
         if ( ( b2[forBar] != EMPTY_VALUE || b8[forBar] != EMPTY_VALUE )&& b4[forBar] != EMPTY_VALUE ) doAlert ( "strong buy"  );
         if ( ( b2[forBar] != EMPTY_VALUE || b8[forBar] != EMPTY_VALUE )&& b4[forBar] == EMPTY_VALUE ) doAlert ( "buy"         );
         if ( processminor )
            {
              if ( b2[forBar] == EMPTY_VALUE && b4[forBar] != EMPTY_VALUE ) doAlert ( "minor buy or exit sell" );
            }
       }
       
    return(0);
  }

//
// shout alerts
//

void doAlert( string doWhat )
  {
    static string   previousAlert = "nothing";
    static datetime previousTime;
           string   message;
   
    if ( previousAlert != doWhat || previousTime != Time[0] )
       {
         previousAlert  = doWhat;
         previousTime   = Time[0];

         message =  StringConcatenate ( Symbol(), " at ", TimeToStr ( TimeLocal(), TIME_SECONDS ), " SSChannel3 : ", doWhat );
         
         if ( alertsMessage      ) Alert            ( message );
         if ( alertsNotification ) SendNotification ( message );
         if ( alertsEmail        ) SendMail         ( StringConcatenate ( Symbol(), "SSChannel3 " ), message );
         if ( alertsSound        ) PlaySound        ( "alert2.wav" );
       }
       
    return;
  }

//
// end indicator code
//