//+------------------------------------------------------------------+
//|                                                     US-HEDGE.mq4 |
//|                                        Copyright © 2008, LEGRUPO |
//|                                           http://www.legrupo.com |
//|                                                     Version: 1.0 |
//| History:                                                         |
//| 1.0 => Release version to the public                             |
//+------------------------------------------------------------------+
#include <WinUser32.mqh>
#include <stderror.mqh>
#include <stdlib.mqh>

#property copyright "Copyright © 2007, LEGRUPO"
#property link      "http://www.legrupo.com"

int ExpertID = 282950;
extern double LotSize = 0.01;

extern double TakeProfit = 200.0;
extern bool useTakeProfit = false;

extern double StopLoss = 0.0;
extern bool useStopLoss = false;

extern int Slippage = 1;
extern int OpenTradesHour = 14;
extern int CloseTradesHour = 12;

extern bool UseMoneyManagement = true;
extern bool AccountIsMicro = true;
extern int Risk = 10; // risk in percentage % (10% of risk in this case)

extern string PairsToHedge = "--If you account is mini add m--";
extern string symbol1 = "EURUSDm";
extern string symbol2 = "GBPUSDm";
extern string symbol3 = "USDCHFm";
extern string symbol4 = "USDJPYm";

extern color clOpenBuy = CLR_NONE;
extern color clSellBuy = CLR_NONE;
color ExitLongColor = CLR_NONE;
color ExitShortColor = CLR_NONE;
extern string BuyComment = "US-HEDGE BUY";
extern string SellComment = "US-HEDGE SELL";

int MagicNumber;
double Price[2];
int    giSlippage;
int iOrders, i, ticket_symbol1, ticket_symbol2, ticket_symbol3, ticket_symbol4;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   iOrders=OrdersTotal()-1;
   MagicNumber = MakeMagicNumber();
   if(UseMoneyManagement==true) {
      LotSize = DefineLotSize(); //Adjust the lot size     total
   }
   if (Hour() == OpenTradesHour) {
      Comment("Time to open trades");
         string result = "";
         double buy_price = MarketInfo(symbol1,MODE_ASK);
         result = symbol1+" price: "+buy_price+"\n";
         double sl = 0.0;
         double tp = 0.0;
         
         if (OrderSelect(ticket_symbol1, SELECT_BY_TICKET, MODE_TRADES) == false) {
            if (useStopLoss) {
               sl = buy_price-StopLoss*MarketInfo(symbol1,MODE_POINT);
            } else {
               sl = 0;
            }
            if (useTakeProfit) {
               tp = buy_price+TakeProfit*MarketInfo(symbol1,MODE_POINT);
            } else {
               tp = 0;
            }
            ticket_symbol1 = OrderSend(symbol1,OP_BUY,LotSize,buy_price,Slippage,sl,tp,"",MagicNumber,0,CLR_NONE);
            if(ticket_symbol1<0)
            {
               Alert(symbol1+" OrderSend failed with error #",ErrorDescription(GetLastError()));
            }
         }
         
         if (OrderSelect(ticket_symbol2, SELECT_BY_TICKET, MODE_TRADES) == false) {
            //symbol2 price
            buy_price = MarketInfo(symbol2,MODE_ASK);
            result = StringConcatenate(result,symbol2," price: ",buy_price,"\n");
            if (useStopLoss) {
               sl = buy_price-StopLoss*MarketInfo(symbol2,MODE_POINT);
            } else {
               sl = 0;
            }
            if (useTakeProfit) {
               tp = buy_price+TakeProfit*MarketInfo(symbol2,MODE_POINT);
            } else {
               tp = 0;
            }
         
            ticket_symbol2 = OrderSend(symbol1,OP_BUY,LotSize,buy_price,Slippage,sl,tp,"",MagicNumber,0,CLR_NONE);
            if(ticket_symbol2<0)
            {
               Alert(symbol2+" OrderSend failed with error #",ErrorDescription(GetLastError()));
            }
         }
         
         if (OrderSelect(ticket_symbol3, SELECT_BY_TICKET, MODE_TRADES) == false) {
            //symbol3 price
            buy_price = MarketInfo(symbol3,MODE_ASK);
            result = StringConcatenate(result,symbol3," price: ",buy_price,"\n");
            if (useStopLoss) {
               sl = buy_price-StopLoss*MarketInfo(symbol3,MODE_POINT);
            } else {
               sl = 0;
            }
            if (useTakeProfit) {
               tp = buy_price+TakeProfit*MarketInfo(symbol3,MODE_POINT);
            } else {
               tp = 0;
            }
         
            ticket_symbol3 = OrderSend(symbol1,OP_BUY,LotSize,buy_price,Slippage,sl,tp,"",MagicNumber,0,CLR_NONE);
            if(ticket_symbol3<0)
            {
               Alert(symbol3+" OrderSend failed with error #",ErrorDescription(GetLastError()));
            }
         }
         
         if (OrderSelect(ticket_symbol4, SELECT_BY_TICKET, MODE_TRADES) == false) {
            //symbol4 price
            buy_price = MarketInfo(symbol4,MODE_ASK);
            result = StringConcatenate(result,symbol4," price: ",buy_price,"\n");
            if (useStopLoss) {
               sl = buy_price-StopLoss*MarketInfo(symbol4,MODE_POINT);
            } else {
               sl = 0;
            }
            if (useTakeProfit) {
               tp = buy_price+TakeProfit*MarketInfo(symbol4,MODE_POINT);
            } else {
               tp = 0;
            }
            ticket_symbol4 = OrderSend(symbol1,OP_BUY,LotSize,buy_price,Slippage,sl,tp,"",MagicNumber,0,CLR_NONE);
            if(ticket_symbol4<0)
            {
               Alert(symbol4+" OrderSend failed with error #",ErrorDescription(GetLastError()));
            }
         }
         Comment(result);
   }
   if (Hour() == CloseTradesHour) {
      Comment("Time to close trades");
      CloseOpenedOrders();
   }
//----
   return(0);
  }
//+------------------------------------------------------------------+
void CloseOpenedOrders() {
   //WindowScreenShot(Symbol()+"_closeopenedorders_"+Day()+"."+Hour()+"."+Minute()+"."+Seconds()+".gif",640,480);
   for(i=iOrders; i>=0; i--) {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && (OrderMagicNumber() == MagicNumber)) {
         if((OrderType()<=OP_SELL) && GetMarketInfo()) {
           if(!OrderClose(OrderTicket(),OrderLots(),Price[1-OrderType()],giSlippage)) Alert(ErrorDescription(GetLastError()));
         }
      }
   }
}
//+------------------------------------------------------------------+
//| Calculate concurrent Long position                               |
//+------------------------------------------------------------------+
int CountLongs(int MagicNumber)
{
 int count=0;
 int trade;
 int trades=OrdersTotal();
 for(trade=0;trade<trades;trade++)
 {
  OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);
  
  if( OrderSymbol()!=Symbol() || OrderMagicNumber() != MagicNumber )
   continue;
   
  if(OrderType()==OP_BUY || OrderType()==OP_BUYSTOP || OrderType()==OP_BUYLIMIT)
   count++;
 }//for
 return(count);
}
//+------------------------------------------------------------------+
//| Calculate concurrent short position                              |
//+------------------------------------------------------------------+
int CountShorts(int MagicNumber)
{
 int count=0;
 int trade;
 int trades=OrdersTotal();
 for(trade=0;trade<trades;trade++)
 {
  OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);
  
  if(OrderSymbol()!=Symbol() || OrderMagicNumber() != MagicNumber )
   continue;
   
  if(OrderType()==OP_SELL || OrderType()==OP_SELLSTOP || OrderType()==OP_SELLLIMIT)
  count++;
 }//for
 return(count);
}
//+------------------------------------------------------------------+
//| Function..: GetMarketInfo                                        |
//| Returns...: bool Success.                                        |
//+------------------------------------------------------------------+
bool GetMarketInfo() {
  RefreshRates();
  Price[0]=MarketInfo(OrderSymbol(),MODE_ASK);
  Price[1]=MarketInfo(OrderSymbol(),MODE_BID);
  double dPoint=MarketInfo(OrderSymbol(),MODE_POINT);
  if(dPoint==0) return(false);
  giSlippage=(Price[0]-Price[1])/dPoint;
  return(Price[0]>0.0 && Price[1]>0.0);
}

//+------------------------------------------------------------------+
//| Make Magic Number                                                |
//+------------------------------------------------------------------+
int MakeMagicNumber()
{
   int SymbolCode  = 0;
   int PeriodCode  = 0;
   int MagicNumber = 0; 
   
   //---- Symbol Code
        if( Symbol() == "AUDCAD" || Symbol() == "AUDCADm" ) { SymbolCode = 1000; }
   else if( Symbol() == "AUDJPY" || Symbol() == "AUDJPYm" ) { SymbolCode = 2000; }
   else if( Symbol() == "AUDNZD" || Symbol() == "AUDNZDm" ) { SymbolCode = 3000; }
   else if( Symbol() == "AUDUSD" || Symbol() == "AUDUSDm" ) { SymbolCode = 4000; }
   else if( Symbol() == "CHFJPY" || Symbol() == "CHFJPYm" ) { SymbolCode = 5000; }
   else if( Symbol() == "EURAUD" || Symbol() == "EURAUDm" ) { SymbolCode = 6000; }
   else if( Symbol() == "EURCAD" || Symbol() == "EURCADm" ) { SymbolCode = 7000; }
   else if( Symbol() == "EURCHF" || Symbol() == "EURCHFm" ) { SymbolCode = 8000; }
   else if( Symbol() == "EURGBP" || Symbol() == "EURGBPm" ) { SymbolCode = 9000; }
   else if( Symbol() == "EURJPY" || Symbol() == "EURJPYm" ) { SymbolCode = 1000; }
   else if( Symbol() == "EURUSD" || Symbol() == "EURUSDm" ) { SymbolCode = 1100; }
   else if( Symbol() == "GBPCHF" || Symbol() == "GBPCHFm" ) { SymbolCode = 1200; }
   else if( Symbol() == "GBPJPY" || Symbol() == "GBPJPYm" ) { SymbolCode = 1300; }
   else if( Symbol() == "GBPUSD" || Symbol() == "GBPUSDm" ) { SymbolCode = 1400; }
   else if( Symbol() == "NZDJPY" || Symbol() == "NZDJPYm" ) { SymbolCode = 1500; }
   else if( Symbol() == "NZDUSD" || Symbol() == "NZDUSDm" ) { SymbolCode = 1600; }
   else if( Symbol() == "USDCAD" || Symbol() == "USDCADm" ) { SymbolCode = 1700; }
   else if( Symbol() == "USDCHF" || Symbol() == "USDCHFm" ) { SymbolCode = 1800; }
   else if( Symbol() == "USDJPY" || Symbol() == "USDJPYm" ) { SymbolCode = 1900; }
                     
   //---- Calculate MagicNumber
   MagicNumber = ExpertID+SymbolCode;
   return(MagicNumber);
}

double DefineLotSize() {
   double lotMM = MathCeil(AccountFreeMargin() *  Risk / 1000) / 100;
   if(AccountIsMicro==false) { //normal account
      if (lotMM < 0.1) lotMM = LotSize;
      if ((lotMM > 0.5) && (lotMM < 1)) lotMM=0.5;
      if (lotMM > 1.0) lotMM = MathCeil(lotMM);
      if  (lotMM > 100) lotMM = 100;
   } else { //micro account
      if (lotMM < 0.01) lotMM = LotSize;
      if (lotMM > 1.0) lotMM = MathCeil(lotMM);
      if  (lotMM > 100) lotMM = 100;
   }
   return (lotMM);
}