//+------------------------------------------------------------------+
//|                                             SHI_Channel_true.mq4 |
//|                                 Copyright � 2004, Shurka & Kevin |
//|                                                                  |
//+------------------------------------------------------------------+
//| SHI_Channel_true_TRO_MODIFIED_VERSION                            |
//| MODIFIED BY AVERY T. HORTON, JR. AKA THERUMPLEDONE@GMAIL.COM     |
//| I am NOT the ORIGINAL author 
//  and I am not claiming authorship of this indicator. 
//  All I did was modify it. I hope you find my modifications useful.|
//|                                                                  |
//+------------------------------------------------------------------+


#property copyright "Copyright � 2004, Shurka & Kevin"
#property link      ""
//----
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Pink

 
//+--------- TRO MODIFICATION ---------------------------------------+ 

extern bool   Sound.Alert    = false ;
extern bool   Show.MidLine   = true ;
extern bool   Show.PriceBox  = true ;
extern int    myBoxWidth     = 3;

extern bool   Show.Comment   = false ;

double ExtMapBuffer1[];
//---- input parameters
extern int AllBars = 240;
extern int BarsForFract = 0;
int CurrentBar = 0;
double Step = 0;
int B1 = -1, B2 = -1;
int UpDown = 0;
double P1 = 0, P2 = 0, PP = 0;
int i = 0, AB = 300, BFF = 0;
int ishift = 0;
double iprice = 0;
datetime T1, T2;

//+--------- TRO MODIFICATION ---------------------------------------+ 
string symbol, tChartPeriod,  tShortName ;  
int    digits, period  ; 

datetime Trigger ;

int OldBars = -1 ;

color tColor = Yellow ;
color TL1color      = White ;
double UpperLR, LowerLR, MiddleLR ; 
 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {

//+--------- TRO MODIFICATION ---------------------------------------+  

   period       = Period() ;     
   tChartPeriod =  TimeFrameToString(period) ;
   symbol       =  Symbol() ;
   digits       =  Digits ;   

   tShortName = "shict"+ symbol + tChartPeriod  ;
    
//+--------- TRO MODIFICATION ---------------------------------------+   
  
//---- indicators
   SetIndexStyle(0, DRAW_ARROW);
   SetIndexArrow(0, 164);
   SetIndexBuffer(0, ExtMapBuffer1);
   SetIndexEmptyValue(0, 0.0);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
  
  
   DelObj();
   
   Comment(" ");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DelObj()
  {
      ObjectDelete("TL1");
      ObjectDelete("TL2");
      ObjectDelete("MIDL");


//+--------- TRO MODIFICATION ---------------------------------------+ 
   ObjectDelete(tShortName+"01"); 
   ObjectDelete(tShortName+"02"); 
   ObjectDelete(tShortName+"03"); 
         
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {

//+--------- TRO MODIFICATION ---------------------------------------+   
//   if( Bars != OldBars ) { Trigger = True ; }
 

   int counted_bars = IndicatorCounted();
//---- 
      if((AllBars == 0) || (Bars < AllBars)) 
          AB = Bars; 
      else AB = AllBars; //AB-?????????? ????????????? ?????
      if(BarsForFract > 0) 
             BFF = BarsForFract; 
      else
             switch (Period())
               {
                    case     1: BFF = 12; break;
                    case     5: BFF = 48; break;
                    case    15: BFF = 24; break;
                    case    30: BFF = 24; break;
                    case    60: BFF = 12; break;
                    case   240: BFF = 15; break;
                    case  1440: BFF = 10; break;
                    case 10080: BFF = 6;  break;
                    default: DelObj(); return(-1); break;
               }
   CurrentBar = 2; //??????? ? ???????? ????, ????? ??????? "??????????
   B1 = -1; 
   B2 = -1; 
   UpDown = 0;
   while(((B1 == -1) || (B2==-1)) && (CurrentBar<AB))
     {
             //UpDown = 1 ?????? ?????? ??????? ?????? ??????, UpDown = -1 ?????? ?????? ???????
             //?????? ?????, UpDown = 0 ?????? ??????? ??? ?? ??????.
             //?1 ? ?2 - ?????? ????? ? ??????????, ????? ??? ?????? ??????? ?????.
             //?1 ? ?2 - ?????????????? ???? ????? ??????? ????? ????? ?????????
             if((UpDown < 1) && (CurrentBar == Lowest(Symbol(), Period(), MODE_LOW, BFF*2 + 1,
                CurrentBar - BFF))) 
               {
                    if(UpDown == 0) 
                      { 
                        UpDown = -1; 
                        B1 = CurrentBar; 
                        P1 = Low[B1]; 
                      }
                    else 
                      { 
                        B2 = CurrentBar; 
                        P2 = Low[B2];
                      }
               }
             if((UpDown > -1) && (CurrentBar == Highest(Symbol(), Period(), MODE_HIGH, BFF*2 + 1,
                CurrentBar - BFF))) 
               {
                    if(UpDown == 0) 
                      { 
                        UpDown = 1; 
                        B1 = CurrentBar; 
                        P1 = High[B1]; 
                      }
                    else 
                      { 
                        B2 = CurrentBar; 
                        P2 = High[B2]; 
                      }
               }
             CurrentBar++;
        }
      if((B1 == -1) || (B2 == -1)) 
        {
          DelObj(); 
          return(-1);
        } // ?????? ?? ????? ????????? ????? 300 ????? 8-)
      Step = (P2 - P1) / (B2 - B1); //????????? ???, ???? ?? ?????????????, ?? ????? ??????????
      P1 = P1 - B1*Step; 
      B1 = 0; //???????????? ???? ? ?????? ??? ? ????
//? ?????? ??????? ????? ??????????????? ????? ??????.
      ishift = 0; 
      iprice = 0;
      if(UpDown == 1)
        { 
             PP = Low[2] - 2*Step;
             for(i = 3; i <= B2; i++) 
               {
                    if(Low[i] < PP + Step*i) 
                        PP = Low[i] - i*Step; 
               }
             if(Low[0] < PP) 
               {
                 ishift = 0; 
                 iprice = PP;
               }
             if(Low[1] < PP + Step) 
               {
                 ishift = 1; 
                 iprice = PP + Step;
               }
             if(High[0] > P1) 
               {
                 ishift = 0; 
                 iprice = P1;
               }
             if(High[1] > P1 + Step) 
               {
                 ishift = 1; 
                 iprice = P1 + Step;
               }
        } 
      else
        { 
             PP = High[2] - 2*Step;
             for(i = 3; i <= B2; i++) 
               {
                    if(High[i] > PP + Step*i) 
                        PP = High[i] - i*Step;
               }
             if(Low[0] < P1) 
               {
                 ishift = 0; 
                 iprice = P1;
               }
             if(Low[1] < P1 + Step) 
               {
                 ishift = 1; 
                 iprice = P1 + Step;
               }
             if(High[0] > PP) 
               {
                 ishift = 0; 
                 iprice = PP;
               }
             if(High[1] > PP + Step) 
               {
                 ishift = 1; 
                 iprice = PP + Step;
               }
        }
//?????? ?????????? ???????? ???? ? ??? ?? ??, ????? ????? ?????? ?????????? ?????????
      P2 = P1 + AB*Step;
      T1 = Time[B1]; 
      T2 = Time[AB];
//???? ?? ???? ??????????? ??????, ?? 0, ????? ?????? ?????.


//+--------- TRO MODIFICATION ---------------------------------------+  
double xChannelSize = MathAbs(PP - P1) / Point ;
double xSlope       = -Step / Point ;


double qq1 = NormalizeDouble(PP,digits) ;
double qq2 = NormalizeDouble(P1,digits) ;

      LowerLR  = MathMin(qq1,qq2) ;
      UpperLR  = MathMax(qq1,qq2) ;
      MiddleLR = NormalizeDouble((P1 + PP) / 2 ,digits) ;     
                     
      if(xSlope > 0) { TL1color = Lime ; } else {
      if(xSlope < 0) { TL1color = Red ;  } else { TL1color = Yellow ;  }  }    
      
      if( Show.Comment )
      {
         Comment(" Channel size = ", DoubleToStr(xChannelSize, 0), " Slope = ", DoubleToStr(xSlope, 2) , "\n",
                 " LowerLR = ", DoubleToStr(LowerLR, digits), " UpperLR = ", DoubleToStr(UpperLR, digits) , "\n",
                 " LinReg  = ", DoubleToStr(MiddleLR, digits),  " Close[0] = ", DoubleToStr(Close[0], digits) , "\n",
         "");
      }        

//+--------- TRO MODIFICATION ---------------------------------------+             
           
                 
      if(iprice != 0) 
          ExtMapBuffer1[ishift] = iprice;
      DelObj();
      
      
      ObjectCreate("TL1", OBJ_TREND, 0, T2, PP + Step*AB, T1, PP);  // lower line
         ObjectSet("TL1", OBJPROP_COLOR, TL1color); 
         ObjectSet("TL1", OBJPROP_WIDTH, 2); 
         ObjectSet("TL1", OBJPROP_STYLE, STYLE_SOLID); 
         ObjectSet("TL1", OBJPROP_RAY, false) ; 
         ObjectSet("TL1", OBJPROP_BACK, true) ;
         
      ObjectCreate("TL2", OBJ_TREND, 0, T2, P2, T1, P1); // upper line
         ObjectSet("TL2", OBJPROP_COLOR, TL1color); 
         ObjectSet("TL2", OBJPROP_WIDTH, 2); 
         ObjectSet("TL2", OBJPROP_STYLE, STYLE_SOLID); 
         ObjectSet("TL2", OBJPROP_RAY, false) ; 
         ObjectSet("TL2", OBJPROP_BACK, true) ;     
         
      if(Show.MidLine) 
      {             
      ObjectCreate("MIDL", OBJ_TREND, 0, T2, (P2 + PP + Step*AB) / 2, T1, (P1 + PP) / 2);
         ObjectSet("MIDL", OBJPROP_COLOR, TL1color); 
         ObjectSet("MIDL", OBJPROP_WIDTH, 1); 
         ObjectSet("MIDL", OBJPROP_STYLE, STYLE_DOT);
         ObjectSet("MIDL", OBJPROP_RAY, false) ; 
         ObjectSet("MIDL", OBJPROP_BACK, true) ;
      }        



//+--------- TRO MODIFICATION ---------------------------------------+  
      
      if ( Trigger != Time[0] &&  Sound.Alert ) 
      {
        if( Close[0] >= UpperLR ) { Trigger = Time[0] ; Alert(symbol,"  ", tChartPeriod, " Price at/above UpperLR "+ DoubleToStr(UpperLR ,digits)); }
        if( Close[0] <= LowerLR ) { Trigger = Time[0] ; Alert(symbol,"  ", tChartPeriod, " Price at/below LowerLR "+ DoubleToStr(LowerLR ,digits)); }     
      }

   if(Show.PriceBox) { DoBox() ; }
    
   OldBars = Bars ;   

   WindowRedraw() ;

//+--------- TRO MODIFICATION ---------------------------------------+                  
   return(0);
}

//+--------- TRO MODIFICATION ---------------------------------------+  
void DoBox()    
{


       if (ObjectFind(tShortName+"01") != 0)
      {
          ObjectCreate(tShortName+"01",OBJ_ARROW,0,Time[0],UpperLR);
          ObjectSet(tShortName+"01",OBJPROP_ARROWCODE,SYMBOL_RIGHTPRICE);
          ObjectSet(tShortName+"01",OBJPROP_COLOR,TL1color);  
          ObjectSet(tShortName+"01",OBJPROP_WIDTH,myBoxWidth);  
      } 
      else
      {
         ObjectMove(tShortName+"01",0,Time[0],UpperLR);
         ObjectSet(tShortName+"01",OBJPROP_COLOR,TL1color);  
      }

       if (ObjectFind(tShortName+"02") != 0)
      {
          ObjectCreate(tShortName+"02",OBJ_ARROW,0,Time[0],LowerLR);
          ObjectSet(tShortName+"02",OBJPROP_ARROWCODE,SYMBOL_RIGHTPRICE);
          ObjectSet(tShortName+"02",OBJPROP_COLOR,TL1color);  
          ObjectSet(tShortName+"02",OBJPROP_WIDTH,myBoxWidth);  
      } 
      else
      {
         ObjectMove(tShortName+"02",0,Time[0],LowerLR);
         ObjectSet(tShortName+"02",OBJPROP_COLOR,TL1color);  
      }

       if(Show.MidLine) {
       if (ObjectFind(tShortName+"03") != 0)
      {
          ObjectCreate(tShortName+"03",OBJ_ARROW,0,Time[0],MiddleLR);
          ObjectSet(tShortName+"03",OBJPROP_ARROWCODE,SYMBOL_RIGHTPRICE);
          ObjectSet(tShortName+"03",OBJPROP_COLOR,TL1color);  
          ObjectSet(tShortName+"03",OBJPROP_WIDTH,myBoxWidth);  
      } 
      else
      {
         ObjectMove(tShortName+"03",0,Time[0],MiddleLR);
         ObjectSet(tShortName+"03",OBJPROP_COLOR,TL1color);  
      }
      } //if(Show.MidLine) {


      

                
   return(0);
}


//+--------- TRO MODIFICATION ---------------------------------------+  

string TimeFrameToString(int tf)
{
   string tfs;
   switch(tf) {
      case PERIOD_M1:  tfs="M1"  ; break;
      case PERIOD_M5:  tfs="M5"  ; break;
      case PERIOD_M15: tfs="M15" ; break;
      case PERIOD_M30: tfs="M30" ; break;
      case PERIOD_H1:  tfs="H1"  ; break;
      case PERIOD_H4:  tfs="H4"  ; break;
      case PERIOD_D1:  tfs="D1"  ; break;
      case PERIOD_W1:  tfs="W1"  ; break;
      case PERIOD_MN1: tfs="MN";
   }
   return(tfs);
}