//+------------------------------------------------------------------+
//|                                                Corr_Diver_02.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   "2.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.4;       // Fixed Lot Size
input double Profit_EQ_Perc_Inc = 0.3;      // Close at Profit as Equity%Increase
input double Loss_EQ_Perc_Dec   = 0.2;      // Close at Loss as Equity%Decrease
input int    CCIPeriod          = 2;         // CCI period
input int    ATRPeriod          = 50;         // ATR period
input int    tp_pips            = 50000;     // Take Profit Pips
input int    sl_pips            = 50000;     // Stop Loss Pips

//---
int   cciHandle1=0,cciHandle2=0,atrHandle1=0,atrHandle2=0;
datetime p1_ord_time=0,p2_ord_time=0;
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double TradeSizeOptimized(string pair)
  { double rate=0,margin=0;
//--- return trading volume
   double lot=0;
   double   atr_1[3],atr_2[3];
   if(CopyBuffer(atrHandle1,0,0,3,atr_1)!=3 ||CopyBuffer(atrHandle2,0,0,3,atr_2)!=3)
     {
      Print("CopyBuffer from iATR failed, no data");
      return(0.0);
     }

   //rate=SymbolInfoDouble(First_Pair,SYMBOL_BID)/SymbolInfoDouble(Second_Pair,SYMBOL_BID);
   rate=atr_1[1]/atr_2[1];
   if(pair==First_Pair) return(Fixed_Lot_Size);
   if(pair==Second_Pair) return(NormalizeDouble(Fixed_Lot_Size*rate,2));
   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;
     }

   double   cci_1[3],cci_2[3];
   if(CopyBuffer(cciHandle1,0,0,3,cci_1)!=3 ||CopyBuffer(cciHandle2,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)      Buy(First_Pair);
      if(cci_1[1]>0 && cci_2[1]<0)      Buy(Second_Pair);
   }
   if(cci_1[2]>0 && cci_2[2]>0)
   {
      if(cci_1[1]>0 && cci_2[1]<0)      Sell(First_Pair);
      if(cci_1[1]<0 && cci_2[1]>0)      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(pair),SymbolInfoDouble(pair,SYMBOL_ASK),
   SymbolInfoDouble(pair,SYMBOL_BID)-sl_pips*_Point,
   SymbolInfoDouble(pair,SYMBOL_ASK)+tp_pips*_Point,
   "Corr_Diver_02");
   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(pair),SymbolInfoDouble(pair,SYMBOL_BID),
   SymbolInfoDouble(pair,SYMBOL_ASK)+sl_pips*_Point,
   SymbolInfoDouble(pair,SYMBOL_BID)-tp_pips*_Point,
   "Corr_Diver_02");
   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(AccountInfoDouble(ACCOUNT_EQUITY)>AccountInfoDouble(ACCOUNT_BALANCE)
      && MathAbs((AccountInfoDouble(ACCOUNT_EQUITY)-AccountInfoDouble(ACCOUNT_BALANCE))/AccountInfoDouble(ACCOUNT_BALANCE))
    > Profit_EQ_Perc_Inc)  
     close_all_orders();

    if(AccountInfoDouble(ACCOUNT_EQUITY)<AccountInfoDouble(ACCOUNT_BALANCE)
      && MathAbs((AccountInfoDouble(ACCOUNT_EQUITY)-AccountInfoDouble(ACCOUNT_BALANCE))/AccountInfoDouble(ACCOUNT_BALANCE))
    > Loss_EQ_Perc_Dec)
      close_all_orders();
    
    
   
//---
}
void close_all_orders()
{
   CTrade trade; 
   if(PositionSelect(First_Pair)) trade.PositionClose(First_Pair);     
   if(PositionSelect(Second_Pair)) trade.PositionClose(Second_Pair);     

}

  
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//---
   cciHandle1=iCCI(First_Pair,0,CCIPeriod,PRICE_CLOSE);
   cciHandle2=iCCI(Second_Pair,0,CCIPeriod,PRICE_CLOSE);
   if(cciHandle1==INVALID_HANDLE || cciHandle2==INVALID_HANDLE)
     {
      printf("Error creating CCI indicator");
      return(INIT_FAILED);
     }
   atrHandle1=iATR(First_Pair,0,ATRPeriod);
   atrHandle2=iATR(Second_Pair,0,ATRPeriod);
   if(atrHandle1==INVALID_HANDLE || atrHandle2==INVALID_HANDLE)
     {
      printf("Error creating ATR 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)
  {
  }
//+------------------------------------------------------------------+
