//+-------------------------------------------------------------------+
//|   Basket ARB-O-MAT                                                |
//+-------------------------------------------------------------------+

#define  NL    "\n"
#property copyright "symware@tin.it"
 
//--------- input parameters
extern int     Slippage            = 2;
extern double  Target              = 30; //dollar or your valute
extern int     Magic               = 1;
extern bool    CloseAll            = false; 
  
extern double  AUDUSD              = 0;
extern double  EURUSD              = 0;
extern double  GBPUSD              = 0;
extern double  NZDUSD              = 0;
extern double  USDCAD              = 0;
extern double  USDCHF              = 0;
extern double  USDJPY              = 0;

extern double  START               = 0;
extern string  Suffix              = "";
extern string  div                 = "";
extern int     DisplayGapSize      = 5;


string         Gap, ScreenMessage, TradeComment;
int            iOrder, MaxOpened, errore, x;  
static double  dAccountBalance, dAccountBalanceInizio, dTotalProfit, MMHour, MMDay, MMWeek; 
static double  dProfit, dTotale, MaxLoss, MaxProfit, PREZZO; 
string         PAIR;
double         Lots; 


 
// **********************************************************************
// expert initialization function                                       |
// **********************************************************************
 
int init()
{
   if (Period() != PERIOD_H1) 
   	{
      MessageBox("Basket arb-o-mate is designed to run on 1h chart");
   	}

    ObjectsDeleteAll(0,EMPTY);



   Gap="";
   if (DisplayGapSize >0)
   {
      for (int cc=0; cc< DisplayGapSize; cc++) { Gap = StringConcatenate(Gap, " "); }   
   }
   dAccountBalanceInizio=AccountBalance();
   
   for (int i=OrdersTotal()-1; i>=0; i--)
         {
         OrderSelect(i,SELECT_BY_POS);
            if (OrderMagicNumber()==Magic) iOrder++; 
         }
   if (iOrder > 0 ) return(0);        
   if (CloseAll==true) return(0);        
   
   x=0;
   if (AUDUSD < 0) {PAIR="AUDUSD"+Suffix; Lots=NormalizeDouble(MathAbs(AUDUSD/100),2); Buy(); }
   if (AUDUSD > 0) {PAIR="AUDUSD"+Suffix; Lots=NormalizeDouble(MathAbs(AUDUSD/100),2); Sell();}

   x=0;
   if (EURUSD < 0) {PAIR="EURUSD"+Suffix; Lots=NormalizeDouble(MathAbs(EURUSD/100),2); Buy(); }
   if (EURUSD > 0) {PAIR="EURUSD"+Suffix; Lots=NormalizeDouble(MathAbs(EURUSD/100),2); Sell();}

   x=0;
   if (GBPUSD < 0) {PAIR="GBPUSD"+Suffix; Lots=NormalizeDouble(MathAbs(GBPUSD/100),2); Buy(); }
   if (GBPUSD > 0) {PAIR="GBPUSD"+Suffix; Lots=NormalizeDouble(MathAbs(GBPUSD/100),2); Sell();}

   x=0;
   if (NZDUSD < 0) {PAIR="NZDUSD"+Suffix; Lots=NormalizeDouble(MathAbs(NZDUSD/100),2); Buy(); }
   if (NZDUSD > 0) {PAIR="NZDUSD"+Suffix; Lots=NormalizeDouble(MathAbs(NZDUSD/100),2); Sell();}   
   
   x=0;
   if (USDCAD < 0) {PAIR="USDCAD"+Suffix; Lots=NormalizeDouble(MathAbs(USDCAD/100),2); Buy(); }
   if (USDCAD > 0) {PAIR="USDCAD"+Suffix; Lots=NormalizeDouble(MathAbs(USDCAD/100),2); Sell();}
   
   x=0;
   if (USDCHF < 0) {PAIR="USDCHF"+Suffix; Lots=NormalizeDouble(MathAbs(USDCHF/100),2); Buy(); }
   if (USDCHF > 0) {PAIR="USDCHF"+Suffix; Lots=NormalizeDouble(MathAbs(USDCHF/100),2); Sell();}
   
   x=0;
   if (USDJPY < 0) {PAIR="USDJPY"+Suffix; Lots=NormalizeDouble(MathAbs(USDJPY/100),2); Buy(); }
   if (USDJPY > 0) {PAIR="USDJPY"+Suffix; Lots=NormalizeDouble(MathAbs(USDJPY/100),2); Sell();}            
         
return(0);
}




//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
 
int start()
{
   iOrder=0; dProfit=0;  
   
         for (int i=OrdersTotal()-1; i>=0; i--)
               {
               OrderSelect(i,SELECT_BY_POS);
                  if (OrderMagicNumber()==Magic) {iOrder++; dProfit=dProfit+OrderProfit()+OrderCommission()+OrderSwap();}
               }
   
   if (dProfit>=Target)  CloseAll();
   if (dProfit<MaxLoss)  MaxLoss=dProfit;
   if (dProfit>0 && dProfit>MaxProfit)  MaxProfit=dProfit;
   if (iOrder>MaxOpened) MaxOpened=iOrder;
   if (CloseAll==true) CloseAll();
      
   Report(); 

return(0);
}

 
 
//****************************************************************************************************************
//*********************************                    ORDERS              ***************************************
//****************************************************************************************************************
 
void Buy()
{
            PREZZO = MarketInfo(PAIR, MODE_ASK); 
            int ticket = OrderSend(PAIR, OP_BUY, Lots, PREZZO, Slippage, 0, 0, "Basket o-mat "+Magic, Magic, 0,Blue); //---  buy 
            errore = GetLastError(); x++;
            if (ticket ==-1 && errore > 1 && x < 20) {Buy();}
  return(0);
}

void Sell()
{
            PREZZO = MarketInfo(PAIR, MODE_BID);             
            int ticket = OrderSend(PAIR, OP_SELL, Lots, PREZZO, Slippage, 0, 0, "Basket o-mat "+Magic, Magic, 0, Red); //---  buy 
            errore = GetLastError(); x++;
            if (ticket ==-1 && errore > 1 && x < 20) {Sell();} 
  return(0);            
}
 

 

//****************************************************************************************************************
//***********************************************     REPORT   ***************************************************
//****************************************************************************************************************
 
void Report()
{
   if (IsTesting() && !IsVisualMode()) return(0);
   ScreenMessage = "";
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS), NL );
 
   double i;
   int m,s,k;
   m=Time[0]+Period()*60-CurTime();
   i=m/60.0;
   s=m%60;
   m=(m-m%60)/60;
   dTotalProfit = NormalizeDouble(AccountBalance()-dAccountBalanceInizio,2);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, m + " minutes " + s + " seconds left to bar end", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Gain: ", DoubleToStr(dProfit,2), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Max loss: ", DoubleToStr(MaxLoss,2), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Max profit: ", DoubleToStr(MaxProfit,2), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Open orders: ", iOrder, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Start arbomat (just a remind): ", START, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "-----------------------------------", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Spread AUDUSD: ", MarketInfo("AUDUSD"+Suffix, MODE_SPREAD)/10, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Spread EURUSD: ", MarketInfo("EURUSD"+Suffix, MODE_SPREAD)/10, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Spread GBPUSD: ", MarketInfo("GBPUSD"+Suffix, MODE_SPREAD)/10, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Spread NZDUSD: ", MarketInfo("NZDUSD"+Suffix, MODE_SPREAD)/10, NL);   
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Spread USDCAD: ", MarketInfo("USDCAD"+Suffix, MODE_SPREAD)/10, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Spread USDCHF: ", MarketInfo("USDCHF"+Suffix, MODE_SPREAD)/10, NL);   
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Spread USDJPY: ", MarketInfo("USDJPY"+Suffix, MODE_SPREAD)/10, NL);   
                  
   Comment(ScreenMessage);

 return(0);
   
}//report()











//****************************************************************************************************************
//*******************************                  CloseAll            *******************************************
//****************************************************************************************************************

void CloseAll()
{
   int i; iOrder=0;
 
   for (i=OrdersTotal()-1;i>=0;i--)
      {
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
         if (OrderType()== OP_BUY  && OrderMagicNumber()==Magic)  OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),Slippage,Violet);
         if (OrderType()== OP_SELL && OrderMagicNumber()==Magic)  OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),Slippage,Violet);
      }
   
   for (i=OrdersTotal()-1; i>=0; i--)
         {
         OrderSelect(i,SELECT_BY_POS);
            if (OrderMagicNumber()==Magic) iOrder++; 
         }
   if (iOrder > 0 ) CloseAll();        


return(0);
}
   




