
extern int    NumberName   = 1;
extern int    iPeriod      = 21;
extern double MAShoot      = 50;
extern bool   DrawVertical = True;
extern bool   DrawText     = True;
extern bool   ShowMA       = True;
extern int    LineWeight   = 2;
extern int    BarsCount    = 0;

extern int BaseTFrame = PERIOD_H1;

extern int dDay = 0;

double MABuffer[];

void init() 
{
   ObjectCreate("Regression_middle"+NumberName, OBJ_TREND, 0, 0,0, 0,0);
   ObjectSet("Regression_middle"+NumberName, OBJPROP_COLOR, Yellow);
   ObjectSet("Regression_middle"+NumberName, OBJPROP_STYLE, STYLE_SOLID);
   ObjectSet("Regression_middle"+NumberName, OBJPROP_WIDTH, LineWeight);
   ObjectCreate("Regression_upper" +NumberName, OBJ_TREND, 0, 0,0, 0,0);
   ObjectSet("Regression_upper"+NumberName, OBJPROP_STYLE, STYLE_SOLID);
   ObjectSet("Regression_upper"+NumberName, OBJPROP_WIDTH, LineWeight);
   ObjectCreate("Regression_lower" +NumberName, OBJ_TREND, 0, 0,0, 0,0);
   ObjectSet("Regression_lower"+NumberName, OBJPROP_STYLE, STYLE_SOLID);
   ObjectSet("Regression_lower"+NumberName, OBJPROP_WIDTH, LineWeight);
   if (DrawText) 
   {
      ObjectCreate("Regression_bars_begin"+NumberName, OBJ_TEXT, 0, 0,0, 0,0, 0,0);
      ObjectCreate("Regression_bars_end"  +NumberName, OBJ_TEXT, 0, 0,0, 0,0, 0,0);
   }
   if (DrawVertical) 
   {
      ObjectCreate("Regression_begin"+NumberName, OBJ_VLINE, 0, 0,0);
      ObjectSet("Regression_begin"+NumberName, OBJPROP_COLOR, Silver);
      ObjectSet("Regression_begin"+NumberName, OBJPROP_STYLE, STYLE_DOT);
      ObjectSet("Regression_begin"+NumberName, OBJPROP_WIDTH, 1);
      ObjectCreate("Regression_end"  +NumberName, OBJ_VLINE, 0, 0,0);
      ObjectSet("Regression_end"+NumberName, OBJPROP_COLOR, Silver);
      ObjectSet("Regression_end"+NumberName, OBJPROP_STYLE, STYLE_DOT);
      ObjectSet("Regression_end"+NumberName, OBJPROP_WIDTH, 1);
   }

   SetIndexBuffer(0, MABuffer);
   SetIndexStyle (0, DRAW_LINE, STYLE_SOLID, 1);
   Comment("Auto Regression channel");
}

void deinit() 
{
   ObjectDelete("Regression_middle"+NumberName);
   ObjectDelete("Regression_upper" +NumberName);
   ObjectDelete("Regression_lower" +NumberName);
   ObjectDelete("Regression_bars_begin"+NumberName);
   ObjectDelete("Regression_bars_end"  +NumberName);
   ObjectDelete("Regressin_begin"+NumberName);
   ObjectDelete("Regressin_end"  +NumberName);
   Comment("");
}

void start() 
{
   bool   check_low, check_high;
   bool   check_upper_chanel;
   color  color_1, color_2;
   double save_low, save_high;
   double MA, a1, a2, a3, b1, a_, b_, y1, y2, price;
   double stddiv_low, stddiv_high, tmp_div;
   double x_n_up, x_1_up, x_n_down, x_1_down;
   double ratio_currency;
   int    Bars_, shift;
   int    n, n_begin, n_end;
   int    MAType, MAPrice;
   int    save_shift_low, save_shift_high;

   Bars_ = 100;
   
   

   save_low = -1;
   save_high = -1;
   save_shift_low = -1;
   save_shift_high = -1;

   check_low = false;	
   check_high = false;	

   MAType = MODE_SMA;
   MAPrice = PRICE_CLOSE;

   if (iClose(NULL,BaseTFrame,1)>80) ratio_currency = 100;
   else ratio_currency = 10000;

   for (shift=Bars_-1; shift>=0; shift--) 
   {
      MA = iMA(NULL, BaseTFrame, iPeriod, 0, MAType, MAPrice, shift);
      if (ShowMA) MABuffer[shift] = MA;
      if (MA-MAShoot/ratio_currency>iClose(NULL,BaseTFrame,shift))	
      {
         if (iClose(NULL,BaseTFrame,shift)<save_low || save_low==-1) 
         {
            check_low = true;
            save_low = iClose(NULL,BaseTFrame,shift);
            save_shift_low = shift;
         }
      }

      if (MA+MAShoot/ratio_currency<iClose(NULL,BaseTFrame,shift)) 
      {
         if (save_high<iClose(NULL,BaseTFrame,shift) || save_high==-1) 
         {
            check_high = true;	
            save_high = iClose(NULL,BaseTFrame,shift);
            save_shift_high = shift;
         }
      }

      if (check_low) 
      {
         if (MA+MAShoot/ratio_currency<iClose(NULL,BaseTFrame,shift))	
         {
            check_low = false;	
            save_low = -1;
         }
      }

      if (check_high) 
      {
         if (MA-MAShoot/ratio_currency>iClose(NULL,BaseTFrame,shift)) 
         {
            check_high = false;	
            save_high = -1;
         }
      }
   }

   if (save_shift_low>save_shift_high) 
   {
      n_begin = save_shift_low;
      n_end = save_shift_high;
   } 
   else 
   {
      n_begin = save_shift_high;
      n_end = save_shift_low;
   }

   if (n_end==0) n_end = 1; // Нулевой бар не использовать
   n = n_begin - n_end + 1; // длина канала

   a1 = 0;
   a2 = 0;
   a3 = 0;
   b1 = 0;
   a_ = 0;
   b_ = 0;
   y1 = 0;
   y2 = 0;
   tmp_div = 0;

   if (iClose(NULL,BaseTFrame,n_begin)<iClose(NULL,BaseTFrame,n_end)) check_upper_chanel = true;
   else check_upper_chanel = false;

   for (shift=n_begin; shift>=n_end; shift--) 
   {
      if (check_upper_chanel) price = iLow(NULL,BaseTFrame,shift);
      else price = iHigh(NULL,BaseTFrame,shift);

      a1 = a1 + shift*price;
      a2 = a2 + shift;
      a3 = a3 + price;
      b1 = b1 + shift*shift;
   }

   b_ = (n*a1 - a2*a3)/(n*b1 - a2*a2);
   a_ = (a3 - b_*a2)/n;
   y1 = a_ + b_*n_begin;
   y2 = a_ + b_*n_end;

   ObjectSet("Regression_middle"+NumberName, OBJPROP_TIME1, iTime(NULL,BaseTFrame,n_begin));
   ObjectSet("Regression_middle"+NumberName, OBJPROP_TIME2, iTime(NULL,BaseTFrame,n_end));
   ObjectSet("Regression_middle"+NumberName, OBJPROP_PRICE1, y1);
   ObjectSet("Regression_middle"+NumberName, OBJPROP_PRICE2, y2);

   for (shift=n_begin; shift>=n_end; shift--) 
   {
      if (check_upper_chanel) price = iLow(NULL,BaseTFrame,shift);
      else price = iHigh(NULL,BaseTFrame,shift);

      tmp_div = tmp_div + (price - (a_ + b_*shift))*(price - (a_ + b_*shift));	
   }

   stddiv_low = MathSqrt(tmp_div/n);
   stddiv_high = MathSqrt(tmp_div/n);

   x_n_up = y1 + 3*stddiv_high;
   x_1_up = y2 + 3*stddiv_high;

   x_n_down = y1 - 3*stddiv_low;
   x_1_down = y2 - 3*stddiv_low;

   if (check_upper_chanel) 
   {
      color_1 = Blue;
      color_2 = Red;
   } 
   else 
   {
      color_1 = Red;
      color_2 = Blue;
   }
	
 	ObjectSet("Regression_upper"+NumberName, OBJPROP_TIME1, iTime(NULL,BaseTFrame,n_begin));
 	ObjectSet("Regression_upper"+NumberName, OBJPROP_TIME2, iTime(NULL,BaseTFrame,n_end));
 	ObjectSet("Regression_upper"+NumberName, OBJPROP_PRICE1, x_n_up);
 	ObjectSet("Regression_upper"+NumberName, OBJPROP_PRICE2, x_1_up);
	ObjectSet("Regression_upper"+NumberName, OBJPROP_COLOR, color_1);

 	ObjectSet("Regression_lower"+NumberName, OBJPROP_TIME1, iTime(NULL,BaseTFrame,n_begin));
 	ObjectSet("Regression_lower"+NumberName, OBJPROP_TIME2, iTime(NULL,BaseTFrame,n_end));
 	ObjectSet("Regression_lower"+NumberName, OBJPROP_PRICE1, x_n_down);
 	ObjectSet("Regression_lower"+NumberName, OBJPROP_PRICE2, x_1_down);
 	ObjectSet("Regression_lower"+NumberName, OBJPROP_COLOR, color_2);

   if (DrawText) 
   {	
      ObjectSet("Regression_bars_begin"+NumberName, OBJPROP_TIME1, iTime(NULL,BaseTFrame,n_begin));
      ObjectSet("Regression_bars_begin"+NumberName, OBJPROP_PRICE1, x_n_down);
      ObjectSetText("Regression_bars_begin"+NumberName, DoubleToStr(n_begin,0), 10, "System", White);	

      ObjectSet("Regression_bars_end"+NumberName, OBJPROP_TIME1, iTime(NULL,BaseTFrame,n_end));
      ObjectSet("Regression_bars_end"+NumberName, OBJPROP_PRICE1, x_1_up);
      ObjectSetText("Regression_bars_end"+NumberName, DoubleToStr(n_end,0), 10, "System", White);	
   } 
   else 
   {
      ObjectDelete("Regression_bars_begin" + NumberName);
      ObjectDelete("Regression_bars_end" + NumberName);
   }

   if (DrawVertical) 
   {
      ObjectSet("Regression_begin"+NumberName, OBJPROP_TIME1, iTime(NULL,BaseTFrame,n_begin));
      ObjectSet("Regression_end"+NumberName, OBJPROP_TIME1, iTime(NULL,BaseTFrame,n_end));
   } 
   else 
   {
      ObjectDelete("Regression_begin" + NumberName);
      ObjectDelete("Regression_end" + NumberName);
   }


   // переменные эксперта
   double x1_1 = x_n_down;
   double x1_2 = x_1_down;
   int n_end_1 = n_end;
   int n_begin_1 = n_begin;
   
   int total,cnt;


   if((Hour() >= 8) && (Hour() <= 21))
   {
      if((n_end_1 >= 2) && (x1_1 < x1_2) && (dDay != Day())) // BUY
      {
         total = OrdersTotal();
         for(cnt=0;cnt<total;cnt++)
         {  
            OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
            if(OrderType()==OP_BUY)
            {
               OrderClose(OrderTicket(), OrderLots(), Bid, 3, Yellow);   
            }
         }
         
         if(OrdersTotal() == 0) OrderSend(Symbol(),OP_SELL,0.1,Bid,3,0,Bid-0.0025,"",0,0,Red);   
         dDay = Day();
      }
   
      if((n_end_1 >= 2) && (x1_1 > x1_2) && (dDay != Day())) // SELL
      {
         total = OrdersTotal();
         for(cnt=0;cnt<total;cnt++)
         {  
            OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
            if(OrderType()==OP_SELL)
            {
               OrderClose(OrderTicket(), OrderLots(), Ask, 3, Red);
            }
         }
         
         if(OrdersTotal() == 0) OrderSend(Symbol(),OP_BUY,0.1,Ask,3,0,Ask+0.00025,"",0,0,Blue);
         dDay = Day();
      }
   }


   /*int total,cnt;
   total = OrdersTotal();
   for(cnt=0;cnt<total;cnt++)
   {  
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      double p = OrderProfit() / 10;
      if(p >= 5)
      {
         if(OrderType()==OP_BUY)
         {
            OrderClose(OrderTicket(), OrderLots(), Bid, 3, Yellow);   
         }
         if(OrderType()==OP_SELL)
         {
            OrderClose(OrderTicket(), OrderLots(), Ask, 3, Red);
         }
      }
   }*/
   
   return(0);   
}


