//+------------------------------------------------------------------+
//|                                         CCI Trendlines ver 4.0   |
//|                                            by Clode The Trader   |
//|                                                                  |
//+------------------------------------------------------------------+

// Annotations:
// In this version traps (trendlines) that cross the zero are moved using zero CCI
// Resistances: are moved to zero CCI at any new LOW of the Price after trap crossing zero
// Suuports: are moved to zero CCI at any new HIGH of the Price after trap crossing zero
// Diferent Trap colors chosen by user

#property copyright "Clode The Trader"

#property indicator_chart_window 

//---- input parameters 
extern int       CCI_Period=110;
extern int       num_bars=250;
extern int       Window=2;
extern string    Check_CCI_Window="**Comment**";
extern string    Use_0_for_Chart_Window="**Comment**";
extern string    Use_1_for_Indicator1_Window="**Comment**";
extern string    Use_2_for_Indi2_Window_etc="**Comment**";
extern string    oooo="****";

extern color     Resistance_1_Color=Red;
extern color     Support_1_Color=Blue;
extern color     Trap_2_Color=Black;
extern color     Trap_3_Color=Brown;
extern string    Number_1_is_Longest_Term="**Comment**";
extern int       TL_Width_1_2_3_4_5=2;
extern string    ooooo="*****";

extern bool      Show_Info=true;
extern int       Info_Size=10;
extern string    ooo="***";

extern bool      Delete_TL_at_Exit=true;

// parameters
bool expired=false;
int bar=0; int i; int cnt;
// bool flag;


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {   
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   if (Delete_TL_at_Exit)
      {
      for(cnt=1; cnt<=3; cnt++)
         {
         ObjectDelete(CCI_Period+"_ResTrapLine_"+cnt);
         ObjectDelete(CCI_Period+"_SuppTrapLine_"+cnt);
         }
      }
   ObjectDelete("Box_Res_"+CCI_Period);  
   ObjectDelete("Box_Supp_"+CCI_Period);
   return(0);
  }
  
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
   {
   
   if (expired) return (0); 
    
   // CHECK
   int counted_bars=IndicatorCounted();
   bar = num_bars -1; 
   
   // difine momentum
   int momentum = DefineMomentum();
   
   
   //Preparing the Objects --Different names for TL on different CCIs
   // At any new cycle reset Trendlines
   for(cnt=1; cnt<=3; cnt++)
         {
         ObjectDelete(CCI_Period+"_ResTrapLine_"+cnt);
         ObjectDelete(CCI_Period+"_SuppTrapLine_"+cnt);
         
         ObjectCreate(CCI_Period+"_ResTrapLine_"+cnt,OBJ_TREND,Window,0,0,0,0);
         if (cnt==1)  ObjectSet(CCI_Period+"_ResTrapLine_"+cnt,OBJPROP_COLOR,Resistance_1_Color); ////Long Term Resistance
         if (cnt==2)  ObjectSet(CCI_Period+"_ResTrapLine_"+cnt,OBJPROP_COLOR,Trap_2_Color); 
         if (cnt==3)  ObjectSet(CCI_Period+"_ResTrapLine_"+cnt,OBJPROP_COLOR,Trap_3_Color);
         ObjectSet(CCI_Period+"_ResTrapLine_"+cnt,OBJPROP_WIDTH,TL_Width_1_2_3_4_5);
                  
         ObjectCreate(CCI_Period+"_SuppTrapLine_"+cnt,OBJ_TREND,Window,0,0,0,0);
         if (cnt==1)  ObjectSet(CCI_Period+"_SuppTrapLine_"+cnt,OBJPROP_COLOR,Support_1_Color); //Long Term Support
         if (cnt==2)  ObjectSet(CCI_Period+"_SuppTrapLine_"+cnt,OBJPROP_COLOR,Trap_2_Color);
         if (cnt==3)  ObjectSet(CCI_Period+"_SuppTrapLine_"+cnt,OBJPROP_COLOR,Trap_3_Color);
         ObjectSet(CCI_Period+"_SuppTrapLine_"+cnt,OBJPROP_WIDTH,TL_Width_1_2_3_4_5);
         }
   
   // parameters
   double Max_1=0,Max_2=0,Max_3=0,Max_4=0;
   double Min_1=0,Min_2=0,Min_3=0,Min_4=0;
   double current,now,prev,next;

   double TL_Value=0, TL_Value_prev=0;
   double Res_Value=0, Supp_Value=0;
   double LowestLowAtCCI=0, PriceLowAtCCI=0;
   double HighestHighAtCCI=0, PriceHighAtCCI=0;
   
   int Max_2_Start=0,Max_3_Start=0; // the start of the cycle will be moved
   int Max_4_Start=0;               // to the histo after any new Max or Min
   int Max_1_Time=0,Max_2_Time=0,Max_3_Time=0,Max_4_Time=0;
   
   int Min_2_Start=0,Min_3_Start=0;
   int Min_4_Start=0;          
   int Min_1_Time=0,Min_2_Time=0,Min_3_Time=0,Min_4_Time=0;

   
 //*********  FIRST MAX and MIN  *******************
   // Find Max_1 and Min_1
   for (i = bar; i > 0; i--)  //cycle until curent bar -1 !!
      { 
      now = iCCI(NULL,0,CCI_Period,PRICE_TYPICAL,i);
      prev = iCCI(NULL,0,CCI_Period,PRICE_TYPICAL,i+1);
      next = iCCI(NULL,0,CCI_Period,PRICE_TYPICAL,i-1);  
      if (now>0 && now>prev && now>next && now>Max_1 && now>momentum)
         {  Max_1=now;
            Max_1_Time = i;
            Max_2_Start = i-1;
         }
      if (now<0 && now<prev && now<next && now<Min_1 && now<-momentum)
         {  Min_1=now;
            Min_1_Time = i;
            Min_2_Start = i-1;
         }   
      }
//**************************************************


   // Draw the Resistance Trendlines
   
   
   //From Max_1 find Max_2 and draw first Trendlines
   for (i = Max_2_Start; i > 0; i--)  //cycle until curent bar -1 !!
         {   
         now = iCCI(NULL,0,CCI_Period,PRICE_TYPICAL,i);
         
         TL_Value_prev=ObjectGetValueByShift(CCI_Period+"_ResTrapLine_1", i+1);
         TL_Value=ObjectGetValueByShift(CCI_Period+"_ResTrapLine_1", i);
         
         if (now>0 && now<Max_1 && now>TL_Value)  // any new positive histo lower than Max_1 and higher than Trendline
             {Max_2=now; Max_2_Time=i;}
                
         // negative CCI histos, move TL to the zero of the histo 
         // corresponding with lower low on Price       
         if (TL_Value_prev>0 && TL_Value<=0) // TL cross zero
             LowestLowAtCCI=Low[i];     
          
         if (TL_Value<0 && now <0)  
            {
            PriceLowAtCCI=Low[i];
            if (PriceLowAtCCI < LowestLowAtCCI) 
                {
                Max_2=0; Max_2_Time=i;
                LowestLowAtCCI = PriceLowAtCCI;
                }
            }
         ObjectMove(CCI_Period+"_ResTrapLine_1",0,Time[Max_1_Time],Max_1);  
         ObjectMove(CCI_Period+"_ResTrapLine_1",1,Time[Max_2_Time],Max_2);   
         
         } // END FOR 
          
   if (Max_2>momentum) 
       Max_3_Start = Max_2_Time-1;  //Trendlines start only from coloured histos
      
      
   //From Max_2 find Max_3 and draw the second Trendline
   for (i = Max_3_Start; i > 0; i--)  //cycle until curent bar -1 !!
         {   
         now = iCCI(NULL,0,CCI_Period,PRICE_TYPICAL,i);
         
         TL_Value_prev=ObjectGetValueByShift(CCI_Period+"_ResTrapLine_2",i+1);
         TL_Value=ObjectGetValueByShift(CCI_Period+"_ResTrapLine_2",i);
         
         if (now>0 && now<Max_2 && now>TL_Value)  // any new positive histo lower than Max_2 and higher than Trendline
             {Max_3=now; Max_3_Time=i;}
                
         // negative CCI histos, move TL to the zero of the histo 
         // corresponding with lower low on Price       
         if (TL_Value_prev>0 && TL_Value<=0) // TL cross zero
             LowestLowAtCCI=Low[i];
          
         if (TL_Value<0 && now <0)  
            {
            PriceLowAtCCI=Low[i];
            if (PriceLowAtCCI < LowestLowAtCCI) 
                {
                Max_3=0; Max_3_Time=i;
                LowestLowAtCCI = PriceLowAtCCI;
                }
            }
         ObjectMove(CCI_Period+"_ResTrapLine_2",0,Time[Max_2_Time],Max_2);  
         ObjectMove(CCI_Period+"_ResTrapLine_2",1,Time[Max_3_Time],Max_3);
         
         } // END FOR
         
   if (Max_3>momentum) 
       Max_4_Start = Max_3_Time-1;   
      
   
   //From Max_3 find Max_4 and draw the third Trendline
   for (i = Max_4_Start; i > 0; i--)  //cycle until curent bar -1 !!
         {   
         now = iCCI(NULL,0,CCI_Period,PRICE_TYPICAL,i);
         
         TL_Value_prev=ObjectGetValueByShift(CCI_Period+"_ResTrapLine_3", i+1);
         TL_Value=ObjectGetValueByShift(CCI_Period+"_ResTrapLine_3", i);
         
         if (now>0 && now<Max_3 && now>TL_Value)  // any new positive histo lower than Max_3 and higher than Trendline
             {Max_4=now; Max_4_Time=i;}
                
         // negative CCI histos, move TL to the zero of the histo 
         // corresponding with lower low on Price       
         if (TL_Value_prev>0 && TL_Value<=0) // TL cross zero
            LowestLowAtCCI=Low[i];

         if (TL_Value<0 && now <0)  
            {
            PriceLowAtCCI=Low[i];
            if (PriceLowAtCCI < LowestLowAtCCI) 
                {
                Max_4=0; Max_4_Time=i;
                LowestLowAtCCI = PriceLowAtCCI;
                }
            }   
         
         ObjectMove(CCI_Period+"_ResTrapLine_3",0,Time[Max_3_Time],Max_3);  
         ObjectMove(CCI_Period+"_ResTrapLine_3",1,Time[Max_4_Time],Max_4);      
         
         } // END FOR
      
      
            
//***********************************************************************
//***********************************************************************
  
 
   // Draw the Support Trendlines

   
   //From Min_1 find Min_2 and draw first Trendline
   for (i = Min_2_Start; i > 0; i--)  //cycle until curent bar -1 !!
        {   
        now = iCCI(NULL,0,CCI_Period,PRICE_TYPICAL,i);
        
        TL_Value_prev=ObjectGetValueByShift(CCI_Period+"_SuppTrapLine_1",i+1); 
        TL_Value=ObjectGetValueByShift(CCI_Period+"_SuppTrapLine_1",i);
        
        if (now<0 && now>Min_1 && now < TL_Value)  // any new low higher than Min_1
            {Min_2=now; Min_2_Time=i;}
        
        // negative CCI histos, move TL to the zero of the histo 
        // corresponding with lower low on Price       
        if (TL_Value_prev<0 && TL_Value>=0) // TL cross zero
            HighestHighAtCCI=High[i];
          
        if (TL_Value>0 && now >0)  
           {
           PriceHighAtCCI=High[i];
           if (PriceHighAtCCI > HighestHighAtCCI) 
               {
               Min_2=0; Min_2_Time=i;
               HighestHighAtCCI = PriceHighAtCCI;
               }
           }
        ObjectMove(CCI_Period+"_SuppTrapLine_1",0,Time[Min_1_Time],Min_1);  
        ObjectMove(CCI_Period+"_SuppTrapLine_1",1,Time[Min_2_Time],Min_2);     
        
        } // END FOR
      
   if (Min_2<-momentum) 
       Min_3_Start = Min_2_Time-1;  //Trendlines start only from coloured histos
                                       
 
   //From Min_2 find Min_3 and draw the second Trendline
   for (i = Min_3_Start; i > 0; i--)  //cycle until curent bar -1 !!
        {   
        now = iCCI(NULL,0,CCI_Period,PRICE_TYPICAL,i);
         
        TL_Value_prev=ObjectGetValueByShift(CCI_Period+"_SuppTrapLine_2",i+1); 
        TL_Value=ObjectGetValueByShift(CCI_Period+"_SuppTrapLine_2",i);
        
        if (now<0 && now>Min_2 && now < TL_Value)  // any new low higher than Min_2
            {Min_3=now; Min_3_Time=i;}
        
        // negative CCI histos, move TL to the zero of the histo 
        // corresponding with lower low on Price       
        if (TL_Value_prev<0 && TL_Value>=0) // TL cross zero
            HighestHighAtCCI=High[i];
  
        if (TL_Value>0 && now >0)  
           {
           PriceHighAtCCI=High[i];
           if (PriceHighAtCCI > HighestHighAtCCI) 
               {
               Min_3=0; Min_3_Time=i;
               HighestHighAtCCI = PriceHighAtCCI;
               }
           }
         
        ObjectMove(CCI_Period+"_SuppTrapLine_2",0,Time[Min_2_Time],Min_2);  
        ObjectMove(CCI_Period+"_SuppTrapLine_2",1,Time[Min_3_Time],Min_3); 
        
        }  //END FOR
   
   if (Min_3<-momentum) 
       Min_4_Start = Min_3_Time-1;
      
   
   //From Min_3 find Min_4 and draw the third Trendline
   for (i = Min_4_Start; i > 0; i--)  //cycle until curent bar -1 !!
        {   
        now = iCCI(NULL,0,CCI_Period,PRICE_TYPICAL,i);
         
        TL_Value_prev=ObjectGetValueByShift(CCI_Period+"_SuppTrapLine_3",i+1); 
        TL_Value=ObjectGetValueByShift(CCI_Period+"_SuppTrapLine_3",i);
        
        if (now<0 && now>Min_3 && now < TL_Value)  // any new low higher than Min_3
            {Min_4=now; Min_4_Time=i;}
        
        // negative CCI histos, move TL to the zero of the histo 
        // corresponding with lower low on Price       
        if (TL_Value_prev<0 && TL_Value>=0) // TL cross zero
            HighestHighAtCCI=High[i];
              
        if (TL_Value>0 && now >0)  
           {
           PriceHighAtCCI=High[i];
           if (PriceHighAtCCI > HighestHighAtCCI) 
               {
               Min_4=0; Min_4_Time=i;
               HighestHighAtCCI = PriceHighAtCCI;
               }
           }
        
        ObjectMove(CCI_Period+"_SuppTrapLine_3",0,Time[Min_3_Time],Min_3);  
        ObjectMove(CCI_Period+"_SuppTrapLine_3",1,Time[Min_4_Time],Min_4);
        
        } // END FOR 


//***************Info Box********************

   if (Show_Info)
      {
      ObjectDelete("Box_Res_"+CCI_Period);  // delete previous Box (if present)
      ObjectDelete("Box_Supp_"+CCI_Period);
      
      bool Info_Flag_Res=false; 
      bool Info_Flag_Supp=false;
      current = iCCI(NULL,0,CCI_Period,PRICE_TYPICAL,0);
      
      for(cnt=1; cnt<=3; cnt++)
            {         
            Res_Value = ObjectGetValueByShift(CCI_Period+"_ResTrapLine_"+cnt, 0);
            if (current > Res_Value && Res_Value != 0)        // Alert: current CCI over his trendline
                {Info_CCI_and_Resistances(cnt); Info_Flag_Res=true; break;} 
            } 
      if (!Info_Flag_Res) Info_CCI_and_Resistances(0);
      
      for(cnt=1; cnt<=3; cnt++)
            {
            Supp_Value = ObjectGetValueByShift(CCI_Period+"_SuppTrapLine_"+cnt, 0); 
            if (current < Supp_Value && Supp_Value != 0)      // Alert: current CCI under his trendline
                {Info_CCI_and_Supports(cnt); Info_Flag_Supp=true; break;}
            }
      if (!Info_Flag_Supp) Info_CCI_and_Supports(0);
      
      } //END Show_Info_Box
   
          
   return(0);
  }  // END START

   
  
  //++++++++Functions++++++++
  
  int DefineMomentum ()
      {
      int momentum = 0;
      if (Period()==1 || Period()==5) //timeframe 1 min or 5 min
          {
          if (CCI_Period==110) momentum=100;
          if (CCI_Period==55) momentum=125;
          if (CCI_Period==13) momentum=125; //CCI 13 momentum is 125 
          }                                 //overbought-oversold is 185
      
       if (Period()>=15) //timeframe 15 min or higher
          {
          if (CCI_Period==110) momentum=85;
          if (CCI_Period==55) momentum=100;
          if (CCI_Period==13) momentum=125; //CCI 13 momentum is 125 
          }                                 //overbought-oversold is 185
       return (momentum);                                   
       }

void Info_CCI_and_Resistances(int res)
     {
     //write a green box with CCI_Period over Resistance number "res"
     ObjectCreate("Box_Res_"+CCI_Period, OBJ_LABEL, Window, 0, 0);
     if (res == 0) ObjectSetText("Box_Res_"+CCI_Period, "Res unbroken",  Info_Size, "Arial", Red);
     else ObjectSetText("Box_Res_"+CCI_Period, "Res "+res+" broken",  Info_Size, "Arial", Green);
     ObjectSet("Box_Res_"+CCI_Period, OBJPROP_CORNER, 1);
     ObjectSet("Box_Res_"+CCI_Period, OBJPROP_XDISTANCE, 15);
     ObjectSet("Box_Res_"+CCI_Period, OBJPROP_YDISTANCE, 15);  
     return (0);
     }  
     
void Info_CCI_and_Supports(int supp)
     {
     //write a red box with CCI_Period under Support number "supp"
     ObjectCreate("Box_Supp_"+CCI_Period, OBJ_LABEL, Window, 0, 0);
     if (supp == 0) ObjectSetText("Box_Supp_"+CCI_Period, "Supp unbroken",  Info_Size, "Arial", Green);
     else ObjectSetText("Box_Supp_"+CCI_Period, "Supp "+supp+" broken",  Info_Size, "Arial", Red);
     ObjectSet("Box_Supp_"+CCI_Period, OBJPROP_CORNER, 3);
     ObjectSet("Box_Supp_"+CCI_Period, OBJPROP_XDISTANCE, 15);
     ObjectSet("Box_Supp_"+CCI_Period, OBJPROP_YDISTANCE, 15);
     return (0);
     }
     

