//+------------------------------------------------------------------+
//|                                                Corr_Diver_01.mq5 |
//|                                  Copyright 2015, Khalil Abokwaik |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Khalil Abokwaik"
#property link      "http://www.forexfactory.com/abokwaik"
#property description "Correlation Divergence Trasing Robot for MT5"
#property version   "1.00"

#include <Trade\Trade.mqh>
input int    Magic_Number       = 500001;    // Magic Number
input string First_Pair         = "EURUSD";  // First Pair
input string Second_Pair        = "GBPUSD";  // Second Pair
input double Fixed_Lot_Size     = 0.1;       // Fixed Lot Size
input double Profit_EQ_Perc_Inc = 0.01;      // Close at Profit as Equity%Increase
input double Loss_EQ_Perc_Dec   = 0.01;      // Close at Loss as Equity%Decrease
input int    CCIPeriod          = 2;         // CCI period
input int    tp_pips            = 20000;     // Take Profit Pips
input int    sl_pips            = 50000;     // Stop Loss Pips

//---
int   ExtHandle1=0,ExtHandle2=0;
datetime p1_ord_time=0,p2_ord_time=0;
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double TradeSizeOptimized(void)
  {
//--- return trading volume
   return(Fixed_Lot_Size);
  }
//+------------------------------------------------------------------+
//| Check for open position conditions                               |
//+------------------------------------------------------------------+
void CheckForOpen(void)
{

   MqlRates rt1[2],rt2[2];
//--- go trading only for first ticks of new bar
   if(CopyRates(First_Pair,_Period,0,2,rt1)!=2)
     {
      Print("CopyRates of ",First_Pair," failed, no history");
      return;
     }
   if(CopyRates(Second_Pair,_Period,0,2,rt2)!=2)
     {
      Print("CopyRates of ",Second_Pair," failed, no history");
      return;
     }

/*   if(rt1[1].tick_volume>1)
      return;
   if(rt2[1].tick_volume>1)
      return;
*/
   double   cci_1[3],cci_2[3];
   if(CopyBuffer(ExtHandle1,0,0,3,cci_1)!=3 ||CopyBuffer(ExtHandle2,0,0,3,cci_2)!=3)
     {
      Print("CopyBuffer from iCCI failed, no data");
      return;
     }
//--- check signals

   if(cci_1[2]<0 && cci_2[2]<0)
   {
      if(cci_1[1]<0 && cci_2[1]>0 
      //&& !PositionSelect(First_Pair)
      ) Buy(First_Pair);
      if(cci_1[1]>0 && cci_2[1]<0 
      //&& !PositionSelect(Second_Pair)
      ) Buy(Second_Pair);
   }
   if(cci_1[2]>0 && cci_2[2]>0)
   {
      if(cci_1[1]>0 && cci_2[1]<0 
      //&& !PositionSelect(First_Pair)
      ) Sell(First_Pair);
      if(cci_1[1]<0 && cci_2[1]>0 
      //&& !PositionSelect(Second_Pair)
      ) Sell(Second_Pair);
   }
   
//---
}
void Buy(string pair)
{
   if(pair==First_Pair) 
   {
      if((TimeCurrent()-p1_ord_time)/60<ChartPeriod()) return;
   }
   if(pair==Second_Pair) 
   {
      if((TimeCurrent()-p2_ord_time)/60<ChartPeriod()) return;
   }

   CTrade trade;
   trade.SetExpertMagicNumber(Magic_Number);
   trade.PositionOpen(pair,ORDER_TYPE_BUY,TradeSizeOptimized(),SymbolInfoDouble(pair,SYMBOL_ASK),
   SymbolInfoDouble(pair,SYMBOL_BID)-sl_pips*_Point,
   SymbolInfoDouble(pair,SYMBOL_ASK)+tp_pips*_Point,
   "CD_01");
   if(pair==First_Pair) p1_ord_time=TimeCurrent();
   if(pair==Second_Pair) p2_ord_time=TimeCurrent();
}
void Sell(string pair)
{
   if(pair==First_Pair) 
   {
      if((TimeCurrent()-p1_ord_time)/60<ChartPeriod()) return;
   }
   if(pair==Second_Pair) 
   {
      if((TimeCurrent()-p2_ord_time)/60<ChartPeriod()) return;
   }

   CTrade trade;
   trade.SetExpertMagicNumber(Magic_Number);
   trade.PositionOpen(pair,ORDER_TYPE_SELL,TradeSizeOptimized(),SymbolInfoDouble(pair,SYMBOL_BID),
   SymbolInfoDouble(pair,SYMBOL_ASK)+sl_pips*_Point,
   SymbolInfoDouble(pair,SYMBOL_BID)-tp_pips*_Point,
   "CD_01");
   if(pair==First_Pair) p1_ord_time=TimeCurrent();
   if(pair==Second_Pair) p2_ord_time=TimeCurrent();

}

//+------------------------------------------------------------------+
//| Check for close position conditions                              |
//+------------------------------------------------------------------+
void CheckForClose(void)
{
   if (MathAbs((AccountInfoDouble(ACCOUNT_EQUITY)-AccountInfoDouble(ACCOUNT_BALANCE))/AccountInfoDouble(ACCOUNT_BALANCE))
    > Profit_EQ_Perc_Inc)
    {
     close_all_orders();
    }
   if (MathAbs((AccountInfoDouble(ACCOUNT_BALANCE)-AccountInfoDouble(ACCOUNT_EQUITY))/AccountInfoDouble(ACCOUNT_BALANCE))
    > Loss_EQ_Perc_Dec)
    {
     close_all_orders();
    }
   
//---
}
void close_all_orders()
{
   CTrade trade;
   while (PositionSelect(First_Pair))
   { trade.PositionClose(First_Pair);     
   }
   while (PositionSelect(Second_Pair))
   { trade.PositionClose(Second_Pair);     
   }

}

int total_orders()
  {
   ulong order_ticket;
   int total=0;
//--- go through all pending orders
   for(int i=0;i<OrdersTotal();i++)
      if((order_ticket=OrderGetTicket(i))>0)
         if(Magic_Number==OrderGetInteger(ORDER_MAGIC)) total++;
//---
   return(total);
  }
  
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//---
   ExtHandle1=iCCI(First_Pair,0,CCIPeriod,PRICE_CLOSE);
   ExtHandle2=iCCI(Second_Pair,0,CCIPeriod,PRICE_CLOSE);
   if(ExtHandle1==INVALID_HANDLE || ExtHandle2==INVALID_HANDLE)
     {
      printf("Error creating CCI indicator");
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(void)
  {
//---
   if(PositionSelect(First_Pair)||PositionSelect(Second_Pair))
      CheckForClose();
   CheckForOpen();
//---
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }
//+------------------------------------------------------------------+
