//+------------------------------------------------------------------+
//|                                                       EA_ARB.mq4 |
//|                                                               TO |
//|                         http://www.forex-tradexperts-to.narod.ru |
//+------------------------------------------------------------------+
#property copyright "TO"
#property link      "http://www.forex-tradexperts-to.narod.ru"

extern int MA_1 = 20;
extern int MA_2 = 10;
extern int UP_LEVEL = 150;
extern int DOWN_LEVEL = -150;
extern bool inverse = false;
extern double LOTS = 0.1;
extern int ID = 3556;

int init()
{
   return(0);
}

int deinit()
{
   return(0);
}

int start()
{
   if ( !isNewBar() )return(0);
   double ind_1 = iCustom(NULL,0,"ARB_IND","EURUSD","USDCHF",100,MA_1,MA_2,0,0);
   double ind_2 = iCustom(NULL,0,"ARB_IND","EURUSD","USDCHF",100,MA_1,MA_2,0,1);
   double ind_3 = iCustom(NULL,0,"ARB_IND","EURUSD","USDCHF",100,MA_1,MA_2,0,2);
   
   if ( 
         ( ind_3 >= ind_2 && ind_2 < ind_1 && ind_2 < DOWN_LEVEL && orders_kol(inverse) ) || 
         ( ind_2 < 0 && ind_1 >= 0 && order_total_type(inverse) == 0 && order_total_type(!inverse) != 0  ) || 
         ( ind_1 > last_order_indic(!inverse) && ind_1 > 0 && order_total_type(!inverse) != 0 )
      )
   {
      close_type (!inverse);
      open(inverse,LOTS,0,0,DoubleToStr(ind_2,0));
   }
   if ( 
         ( ind_3 <= ind_2 && ind_2 > ind_1 && ind_2 >   UP_LEVEL && orders_kol(!inverse) ) || 
         ( ind_2 > 0 && ind_1 <= 0 && order_total_type(!inverse) == 0 && order_total_type(inverse) != 0 ) || 
         ( ind_1 < last_order_indic(inverse) && ind_1 < 0 && order_total_type(inverse) != 0  )
      )
   {
      close_type (inverse);
      open(!inverse,LOTS,0,0,DoubleToStr(ind_2,0));
   }
   
   return(0);
}

double last_order_indic( int c)
{
   int i;
   double indic = 0;

   for(i=OrdersTotal()-1;i>=0;i--)
   {
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);      
      if(OrderMagicNumber() == ID && OrderType() == c && c == 1 )indic = MathMax(indic,StrToDouble(OrderComment()));
      if(OrderMagicNumber() == ID && OrderType() == c && c == 0 )indic = MathMin(indic,StrToDouble(OrderComment()));
   }
   return(indic);
}

bool orders_kol ( int f )
{
   if ( order_total_type(f) == 0 )return(true);
   if ( order_total_type(f) != 0 && last_trade(f) < 0 )return(true);
}

double last_trade( int c)
{
   int i;
   double profit = 0;
   datetime time=0;
   
   for(i=OrdersTotal()-1;i>=0;i--)
   {
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);      
      if(OrderOpenTime() > time && OrderMagicNumber() == ID && OrderType() == c)
      {
         time = OrderOpenTime();
         profit = OrderProfit();
      }
   }
   return(profit);
}

bool isNewBar()
{
  static datetime BarTime;  
   bool res=false;
    
   if (BarTime!=Time[0]) 
      {
         BarTime=Time[0];  
         res=true;
      } 
   return(res);
}

int order_total_type( int type )
{
   int i;
   int kol=0;
   for(i=OrdersTotal()-1;i>=0;i--)       
   {
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if(OrderMagicNumber()==ID && OrderType() == type )kol++;         
   }
   return(kol);   
}

bool close(int ticket)
{
   bool isClosed = false;
   int try = 0;
   while ( IsTradeContextBusy() ){Sleep(500);}
   RefreshRates();
   OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   isClosed = OrderClose(OrderTicket(), OrderLots(),NormalizeDouble(OrderClosePrice(),Digits), 3, 0);
   while(!isClosed)
   {
      Sleep(1000);
      try++;
      isClosed = OrderClose(OrderTicket(), OrderLots(),NormalizeDouble(OrderClosePrice(),Digits), 3, 0);
      if(try > 5 || isClosed) break;
   }
   if(!isClosed) Print("Order ", ticket, " was NOT closed due to error:", GetLastError());
   return (isClosed);
}

void close_type( int type )
{
   int i;
   for(i=OrdersTotal()-1;i>=0;i--)
   {
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if(OrderMagicNumber() == ID && OrderType() == type)close(OrderTicket());
   }   
}

int open(int type, double l, double sl=0, double tp=0, string comm = "")
{
   int isOpened = 0, try = 0;
   double s,t;
   while ( IsTradeContextBusy() ){Sleep(500);}
   RefreshRates();
   if ( sl != 0 && sl < MarketInfo(Symbol(),MODE_STOPLEVEL) )sl = MarketInfo(Symbol(),MODE_STOPLEVEL);
   if ( tp != 0 && tp < MarketInfo(Symbol(),MODE_STOPLEVEL) )tp = MarketInfo(Symbol(),MODE_STOPLEVEL);
   if ( type == 0 )
   {
      if ( tp == 0 )t = 0;
      if ( tp != 0 )t = Bid + tp * Point;
      if ( sl == 0 )s = 0;
      if ( sl != 0 )s = Bid - sl * Point;
   }
   if ( type == 1 )
   {
      if ( tp == 0 )t = 0;
      if ( tp != 0 )t = Ask - tp * Point;
      if ( sl == 0 )s = 0;
      if ( sl != 0 )s = Ask + sl * Point;
   }
   s = NormalizeDouble(s,Digits);
   t = NormalizeDouble(t,Digits);
   if(type==0)isOpened = OrderSend(Symbol(),type,check_lot(l),NormalizeDouble(Ask,Digits),10,s,t,comm,ID);
   if(type==1)isOpened = OrderSend(Symbol(),type,check_lot(l),NormalizeDouble(Bid,Digits),10,s,t,comm,ID);
   Sleep(500);
   while(isOpened<0)
   {
      while ( IsTradeContextBusy() ){Sleep(500);}
      RefreshRates();
      if ( type == 0 )
      {
         if ( tp == 0 )t = 0;
         if ( tp != 0 )t = Bid + tp * Point;
         if ( sl == 0 )s = 0;
         if ( sl != 0 )s = Bid - sl * Point;
      }
      if ( type == 1 )
      {
         if ( tp == 0 )t = 0;
         if ( tp != 0 )t = Ask - tp * Point;
         if ( sl == 0 )s = 0;
         if ( sl != 0 )s = Ask + sl * Point;
      }
      s = NormalizeDouble(s,Digits);
      t = NormalizeDouble(t,Digits);
      try++;
      if(type==0)isOpened = OrderSend(Symbol(),type,check_lot(l),NormalizeDouble(Ask,Digits),10,s,t,comm,ID);
      if(type==1)isOpened = OrderSend(Symbol(),type,check_lot(l),NormalizeDouble(Bid,Digits),10,s,t,comm,ID);
      if(try > 5) break;
      if(isOpened>=0)break;
      Sleep(500);
   }   
   if(isOpened<0) Alert("Ордер не открыт, ошибка :", GetLastError());
   return (isOpened);
}

double check_lot(double &lo)
{
   double l = MarketInfo(Symbol(),MODE_LOTSTEP);
   int ok = 0;
   while ( l < 1 ){l*=10;ok++;}
   if( lo < MarketInfo(Symbol(),MODE_MINLOT) )lo = MarketInfo(Symbol(),MODE_MINLOT);
   if( lo > MarketInfo(Symbol(),MODE_MAXLOT) )lo = MarketInfo(Symbol(),MODE_MAXLOT);
   return(NormalizeDouble(lo,ok));
}