//+------------------------------------------------------------------+
//|                                        BBCI v1.0 by Yuritch 2011 |
//|                            based on CycleIdentifier by Roy Kelly |  
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""

#property indicator_separate_window
#property indicator_buffers 8
#property indicator_color1 DarkGray
#property indicator_color2 Lime
#property indicator_color3 Red
#property indicator_color4 Red
#property indicator_color5 Green
#property indicator_color6 Green
#property indicator_color7 Crimson
#property indicator_color8 DarkGray

#property indicator_width1 2
#property indicator_width6 2
#property indicator_width7 2

#property indicator_minimum -2.2
#property indicator_maximum  2.2

extern int TF =0;
extern string Metod = "0-Built-in, 1-ATR,2-StdDev";
extern int     metod = 1; 
extern int     smooth_factor=1;
extern double  Length=1;
extern int     mcs=4;
extern int     mode = 0;
extern int     price = 0;
extern int     depth=100; 
extern bool    show_lines=true;


double lbuff[];
double MajorCycleBuy[];
double MajorCycleSell[];
double MinorCycleBuy[];
double MinorCycleSell[];
double trendup[];
double trenddn[];
double sign[];
int    minor;

double   ma_price = 0.0, scope_a = 0.0, scope_b = 0.0;
double   price_buy_a1 = 0.0, price_buy_a2 = 0.0;
double   price_sell_a1 = 0.0, price_sell_a2 = 0.0, range = 0.0,srange = 0.0;
int      switch1 = 0, switch2 = 0, switch3 = 0, switch4 = 0;
int      price_buy_b1 = 1.0, price_buy_b2 = 1.0;
int      price_sell_b1 = 0.0, price_sell_b2 = 0.0;
int      direct = 1,subwin;
bool     buy_sw_a = 0, buy_sw_b = 0, sell_sw_a = 0, sell_sw_b = 0;
bool     status = 1, status1, status2, reinit;
string   shortname = "BBCI";

/* ***************************************************************** */
int init()  
{
   IndicatorDigits(0); 
   SetIndexStyle(0,DRAW_NONE);
   SetIndexBuffer(0,lbuff);
   SetIndexLabel(0,NULL);
   SetIndexStyle(1,DRAW_HISTOGRAM,STYLE_SOLID,3);
   SetIndexBuffer(1,MajorCycleBuy);
   SetIndexLabel(1,NULL);
   SetIndexStyle(2,DRAW_HISTOGRAM,STYLE_SOLID,3);
   SetIndexBuffer(2,MajorCycleSell);
   SetIndexLabel(2,NULL);
   SetIndexStyle(3,DRAW_ARROW,STYLE_SOLID,2);
   SetIndexBuffer(3,MinorCycleBuy);
   SetIndexLabel(3,"Exit SELL");
   SetIndexArrow(3, 0xFB);
   SetIndexStyle(4,DRAW_ARROW,STYLE_SOLID,2);
   SetIndexBuffer(4,MinorCycleSell);
   SetIndexLabel(4,"Exit BUY");
   SetIndexArrow(4, 0xFB) ;
   SetIndexStyle(5,DRAW_LINE,STYLE_SOLID,3);
   SetIndexBuffer(5,trendup);
   SetIndexLabel(5,"trendup");
   SetIndexStyle(6,DRAW_LINE,STYLE_SOLID,3);
   SetIndexBuffer(6,trenddn);
   SetIndexLabel(6,"trenddn");
   SetIndexStyle(7,DRAW_HISTOGRAM,STYLE_SOLID,1);
   SetIndexBuffer(7,sign);
   SetIndexLabel(7,"Signal");
   
   SetLevelValue(1,1);
   SetLevelValue(2,-1);
      
reinit=true;
return(0);
}
/* ***************************************************************** */
int deinit() {
  for (int i=0;i<=6;i++) SetIndexEmptyValue(i,0.0);  
  ObjectsDeleteAll(subwin,0);
return(0);
}
   
/* ***************************************************************** */
int start() {

   int position=1;
   if (reinit || IsNewBar()) {

      subwin=WindowFind(shortname);   
      deinit();
      position=depth;
     
   }   
   SetIndexDrawBegin(0, depth);
   SetIndexDrawBegin(1, depth);
   SetIndexDrawBegin(2, depth);
   SetIndexDrawBegin(3, depth);
   SetIndexDrawBegin(4, depth);
   SetIndexDrawBegin(5, depth);
   SetIndexDrawBegin(6, depth); 
   SetIndexDrawBegin(7, depth); 
   int rnglength = depth;
   double range = 0.0, srange = 0.0;

   for (int pos = position; pos >=0; pos--) {
   switch (metod){
      case 0:
         srange = 0.0;
         int j = 0;
         for (int i=0;i<rnglength;i++) {
            j++;
            int posr = pos + i;
            if (posr >= depth) break;
            
            srange = srange + (iHigh(Symbol(),TF,posr)-iLow(Symbol(),TF,posr));
         }
         range = srange / j * Length;
         break;
      case 1: range=iATR(Symbol(), TF, depth, pos)*Length; break;
      case 2: range=iStdDev(Symbol(), TF, depth, 0, mode, price, pos)* Length; break;
      default: break;
   }
      IndicatorShortName(shortname+"("+range+")");
      int BarNumber = depth-pos;
      if (BarNumber < 0) BarNumber = 0;
 
		ma_price = iMA(Symbol(), TF, smooth_factor, 0, mode, price, pos);

      if (BarNumber <= 1){
         scope_a = range;   
         price_buy_a1  = ma_price;
         price_sell_a1  = ma_price;
		}

/* ***************************************************************** */

		if (BarNumber > 1){
			if (switch1 > -1){
				if (ma_price < price_buy_a1){
					if (buy_sw_a) {
					 MinorCycleBuy[pos +BarNumber - price_buy_b1] = 0;//***********************
					 lbuff[pos +BarNumber - price_buy_b1] = 0;
					}
					price_buy_a1 = ma_price;
					price_buy_b1 = BarNumber;
					buy_sw_a = 1;
				}
				else if (ma_price > price_buy_a1){
					switch3 = BarNumber - price_buy_b1;
					MinorCycleBuy[pos +switch3] = -1;//***********************
					lbuff[pos +switch3] = -1;
					buy_sw_a = 1;
					double cyclePrice1 = iMA(Symbol(), TF, smooth_factor, 0, mode, price, pos + switch3);
					if (status) status1 = ma_price - cyclePrice1 >= scope_a;
					else        status1 = ma_price >= cyclePrice1 * (1 + scope_a / 1000);
					if (status1 && switch3 >= direct){
						switch1 =  - 1;
						price_sell_a1 = ma_price;
						price_sell_b1 = BarNumber;
						sell_sw_a = 0;
						buy_sw_a = 0;
					}
            }
         }
			if(switch1 < 1){
				if (ma_price > price_sell_a1){
					if (sell_sw_a )  {
					 MinorCycleSell[pos +BarNumber - price_sell_b1] = 0;//***********************
					 lbuff[pos +BarNumber - price_sell_b1] = 0;
					}
					price_sell_a1 = ma_price;
					price_sell_b1 = BarNumber;
					sell_sw_a = 1;
				}
				else if (ma_price < price_sell_a1){
					switch3 = BarNumber - price_sell_b1;
					MinorCycleSell[pos +switch3] = 1;//***********************
					lbuff[pos +switch3] = 1;
					sell_sw_a = 1;
					double cyclePrice2 = iMA(Symbol(), TF, smooth_factor, 0, mode, price, pos + switch3);
					if (status) status1 = (cyclePrice2 - ma_price) >= scope_a;
					else        status1 = ma_price <= (cyclePrice2 * (1 - scope_a / 1000));
					if (status1 && switch3 >= direct){
						switch1 = 1;
						price_buy_a1 = ma_price;
						price_buy_b1 = BarNumber;
						sell_sw_a = 0;
						buy_sw_a = 0;
					}
				}
			}
		}
	 lbuff[pos]=0;	
     MinorCycleBuy[pos] = 0;
     MinorCycleSell[pos] = 0;
     
/* ***************************************************************** */
		if (BarNumber == 1){
			scope_b = range *  mcs;
			price_buy_a2 = ma_price;
			price_sell_a2 = ma_price;
		}
		if (BarNumber > 1){
			if (switch2  >  - 1){
				if (ma_price < price_buy_a2){
					if (buy_sw_b )  {
					 MajorCycleBuy[pos +BarNumber - price_buy_b2] = 0; //******************************
					 lbuff[pos +BarNumber - price_buy_b2] = 0;
					}
					price_buy_a2 = ma_price;
					price_buy_b2 = BarNumber;
					buy_sw_b = 1;
				}
				else if (ma_price > price_buy_a2){
					switch4 = BarNumber - price_buy_b2;
					MajorCycleBuy[pos +switch4] = -1; //***********************
					lbuff[pos +switch4] = -1;
					buy_sw_b = 1;
					double cyclePrice3 = iMA(Symbol(), TF, smooth_factor, 0, mode, price, pos + switch4);
					if (status) status2 = ma_price - cyclePrice3 >= scope_b;
					else        status2 = ma_price >= cyclePrice3 * (1 + scope_b / 1000);
					if (status2 && switch4 >= direct){
						switch2 =  - 1;
						price_sell_a2 = ma_price;
						price_sell_b2 = BarNumber;
						sell_sw_b = 0;
						buy_sw_b = 0;
					}
				}
			}

			if (switch2  < 1){
				if (ma_price  > price_sell_a2 ){
					if (sell_sw_b) {
					 MajorCycleSell[pos +BarNumber - price_sell_b2] = 0;//***********************
					 lbuff[pos +BarNumber - price_sell_b2] = 0;
					}
					price_sell_a2 = ma_price;
					price_sell_b2 = BarNumber;
					sell_sw_b = 1;
				}
				else if (ma_price < price_sell_a2){
					switch4 = BarNumber - price_sell_b2 ;
					MajorCycleSell[pos + switch4] = 1;//***********************
					lbuff[pos + switch4] = 1;
					sell_sw_b = 1;
					double cyclePrice4 = iMA(Symbol(), TF, smooth_factor, 0, mode, price, pos + switch4);
					if (status) status2 = cyclePrice4 - ma_price >= scope_b;
					else        status2 = ma_price <= cyclePrice4 * (1.0 - scope_b / 1000.0);
					if (status2 && switch4 >= direct){
						switch2 = 1;
						price_buy_a2 = ma_price;
						price_buy_b2 = BarNumber;
						sell_sw_b = 0;
						buy_sw_b = 0;
					}
				}
			}
		}
   lbuff[pos]=0;
   MajorCycleSell[pos] = 0;
   MajorCycleBuy[pos] = 0;

   } // for position
//====================================================================== 

   for (pos=Bars-1;pos>=0;pos--)
      {
      trendup[pos]=trendup[pos+1];
      trenddn[pos]=trenddn[pos+1]; 
     // minor=0;
      sign[pos]=sign[pos+1];
      
      if (MajorCycleBuy[pos] == -1) {trendup[pos]=1; trenddn[pos]=0;}
      if (MajorCycleSell[pos] == 1) {trendup[pos]=0; trenddn[pos]=-1;} 
      
      if (MinorCycleBuy[pos] ==-1)  minor = 1;
      if (MinorCycleSell[pos] == 1) minor =-1;
      

      sign[pos]=lbuff[pos]*(-1)+minor;       
   
      string timestamp=TimeToStr(iTime(Symbol(),0,pos));

      if (trendup[pos]==1)
         {
               if (sign[pos]<0) sign[pos]=0;         
         if (sign[pos] == 2 && show_lines)
               {
               if (ObjectFind("BBBuy "+timestamp)==-1) 
                  {
                  ObjectCreate("BBBuy "+timestamp,0,0,iTime(Symbol(),0,pos),0);
                  ObjectSet("BBBuy "+timestamp,OBJPROP_COLOR,Green);
                  ObjectSet("BBBuy "+timestamp,OBJPROP_BACK,true);
                  }
               }
            else {ObjectDelete("BBBuy "+timestamp); WindowRedraw();}
         }         
      
      if (trenddn[pos]==-1)
         {
          if (sign[pos]>0) sign[pos]=0;
          if (sign[pos] ==-2 && show_lines)
               {         
               if (ObjectFind("BBSell "+timestamp)==-1) 
                  {
                  ObjectCreate("BBSell "+timestamp,0,0,iTime(Symbol(),0,pos),0);
                  ObjectSet("BBSell "+timestamp,OBJPROP_COLOR,Red);
                  ObjectSet("BBSell "+timestamp,OBJPROP_BACK,true);
                  }
               }
           else {ObjectDelete("BBSell "+timestamp); WindowRedraw();}
         }        
      } // for  
reinit=false; 
return(0);
}
//=====================================================================
bool IsNewBar(){
   static datetime LastBar = 0;
   if (Time[0] != LastBar) {
      LastBar = Time[0];     
      return (true);
   } 
   else  return(false);
}