extern double Lots              = 0.1;
extern int    PipStep           = 1000;
extern int    CloseBasketProfit = 500;
extern int    BarsCount         = 300;

extern string Curr1       = "EURUSD";
extern string Curr2       = "GBPUSD";
extern string Curr3       = "AUDUSD";
extern string Curr4       = "NZDUSD";
extern string Curr5       = "USDJPY";
extern string Curr6       = "USDCAD";
extern string Curr7       = "USDCHF";

extern double Pair1OpenOn = 2000;
extern double Pair2OpenOn = 2000;
extern double Pair3OpenOn = 2000;
extern double Pair4OpenOn = 2000;
extern double Pair5OpenOn = 2000;
extern double Pair6OpenOn = 2000;
extern double Pair7OpenOn = 2000;
extern double Pair8OpenOn = 2000;
extern double Pair9OpenOn = 2000;

extern int    ClosePipsPair1  = 300;
extern int    ClosePipsPair2  = 300;
extern int    ClosePipsPair3  = 300;
extern int    ClosePipsPair4  = 300;
extern int    ClosePipsPair5  = 300;
extern int    ClosePipsPair6  = 300;
extern int    ClosePipsPair7  = 300;
extern int    ClosePipsPair8  = 300;
extern int    ClosePipsPair9  = 300;

extern int    Pair1Magic  = 111;
extern int    Pair2Magic  = 222;
extern int    Pair3Magic  = 333;
extern int    Pair4Magic  = 444;
extern int    Pair5Magic  = 555;
extern int    Pair6Magic  = 666;
extern int    Pair7Magic  = 777;
extern int    Pair8Magic  = 888;
extern int    Pair9Magic  = 999;

int Bar;
double CurrentProfit, High_Win, Low_Win, H, L, OpenBar,CloseBar,LowBar,HighBar,
       Corel1, Corel2, Corel3, Corel4, Corel5, Corel6, Corel7, Corel8, Corel9;
//+------------------------------------------------------------------+
int init()
{
   return(0);
}
//+------------------------------------------------------------------+
int deinit()
{
   ObjectsDeleteAll(0,OBJ_TREND);
   return(0);
}
//+------------------------------------------------------------------+
double Correlation(string pair1, string pair2)
{
   Bar      = iHighest(pair1, PERIOD_H1, MODE_HIGH, BarsCount,0);
   High_Win = iHigh   (pair1, PERIOD_H1, Bar);
   Bar      = iLowest (pair1, PERIOD_H1, MODE_LOW, BarsCount,0);
   Low_Win  = iLow    (pair1, PERIOD_H1, Bar);
   
   Bar      = iHighest(pair2, PERIOD_H1, MODE_HIGH, BarsCount,0);
   H        = iHigh   (pair2, PERIOD_H1, Bar);
   Bar      = iLowest (pair2, PERIOD_H1, MODE_LOW, BarsCount,0);
   L        = iLow    (pair2, PERIOD_H1, Bar);

   CloseBar = iClose(pair2, PERIOD_H1, 0);
   CloseBar = (CloseBar-L)/(H-L)*(High_Win-Low_Win)+Low_Win;
   return ((CloseBar - iClose(pair1, PERIOD_H1, 0))/MarketInfo(pair1, MODE_POINT));
}
//+------------------------------------------------------------------+
int start()
{
   string str  = "\n========================================" + "\n"+
                 "===========        CorelFX EA ver.1         ===========" + "\n"+
                 "========================================" + "\n" + "\n";
   
   Corel1 = Correlation(Curr1, Curr2);
   Corel2 = Correlation(Curr1, Curr3);
   Corel3 = Correlation(Curr1, Curr4);
   Corel4 = Correlation(Curr2, Curr3);
   Corel5 = Correlation(Curr2, Curr4);
   Corel6 = Correlation(Curr3, Curr4);

   Corel7 = Correlation(Curr5, Curr6);
   Corel8 = Correlation(Curr5, Curr7);
   Corel9 = Correlation(Curr6, Curr7);
   
   str = str + ("1. " + Curr1 + " => " + Curr2 + " = " + DoubleToStr(Corel1, 0) + ", Opens on " + DoubleToStr(Pair1OpenOn, 0) + ", Profit = " + DoubleToStr(CalculateProfit(Pair1Magic),0) + "\n");
   str = str + ("2. " + Curr1 + " => " + Curr3 + " = " + DoubleToStr(Corel2, 0) + ", Opens on " + DoubleToStr(Pair2OpenOn, 0) + ", Profit = " + DoubleToStr(CalculateProfit(Pair2Magic),0) + "\n");
   str = str + ("3. " + Curr1 + " => " + Curr4 + " = " + DoubleToStr(Corel3, 0) + ", Opens on " + DoubleToStr(Pair3OpenOn, 0) + ", Profit = " + DoubleToStr(CalculateProfit(Pair3Magic),0) + "\n");
   str = str + ("4. " + Curr2 + " => " + Curr3 + " = " + DoubleToStr(Corel4, 0) + ", Opens on " + DoubleToStr(Pair4OpenOn, 0) + ", Profit = " + DoubleToStr(CalculateProfit(Pair4Magic),0) + "\n");
   str = str + ("5. " + Curr2 + " => " + Curr4 + " = " + DoubleToStr(Corel5, 0) + ", Opens on " + DoubleToStr(Pair5OpenOn, 0) + ", Profit = " + DoubleToStr(CalculateProfit(Pair5Magic),0) + "\n");
   str = str + ("6. " + Curr3 + " => " + Curr4 + " = " + DoubleToStr(Corel6, 0) + ", Opens on " + DoubleToStr(Pair6OpenOn, 0) + ", Profit = " + DoubleToStr(CalculateProfit(Pair6Magic),0) + "\n");
   str = str + ("7. " + Curr5 + " => " + Curr6 + " = " + DoubleToStr(Corel7, 0) + ", Opens on " + DoubleToStr(Pair7OpenOn, 0) + ", Profit = " + DoubleToStr(CalculateProfit(Pair7Magic),0) + "\n");
   str = str + ("8. " + Curr5 + " => " + Curr7 + " = " + DoubleToStr(Corel8, 0) + ", Opens on " + DoubleToStr(Pair8OpenOn, 0) + ", Profit = " + DoubleToStr(CalculateProfit(Pair8Magic),0) + "\n");
   str = str + ("9. " + Curr6 + " => " + Curr7 + " = " + DoubleToStr(Corel9, 0) + ", Opens on " + DoubleToStr(Pair9OpenOn, 0) + ", Profit = " + DoubleToStr(CalculateProfit(Pair9Magic),0) + "\n");
   
   str = str + "========================================" + "\n";
   str = str + "Current profit : " + DoubleToStr(CurrentProfit, 0) + " pips. Close basket on " + CloseBasketProfit + " pips.\n";
   Comment(str); 
   
   OpenPositions(Curr1, Curr2, Corel1, Pair1OpenOn, Pair1Magic);
   OpenPositions(Curr1, Curr3, Corel2, Pair2OpenOn, Pair2Magic);
   OpenPositions(Curr1, Curr4, Corel3, Pair3OpenOn, Pair3Magic);
   OpenPositions(Curr2, Curr3, Corel4, Pair4OpenOn, Pair4Magic);
   OpenPositions(Curr2, Curr4, Corel5, Pair5OpenOn, Pair5Magic);
   OpenPositions(Curr3, Curr4, Corel6, Pair6OpenOn, Pair6Magic);
   OpenPositions(Curr5, Curr6, Corel7, Pair7OpenOn, Pair7Magic);
   OpenPositions(Curr5, Curr7, Corel8, Pair8OpenOn, Pair8Magic);
   OpenPositions(Curr6, Curr7, Corel9, Pair9OpenOn, Pair9Magic);   
   
   AddPosition(Pair1Magic);
   AddPosition(Pair2Magic);
   AddPosition(Pair3Magic);
   AddPosition(Pair4Magic);
   AddPosition(Pair5Magic);
   AddPosition(Pair6Magic);
   AddPosition(Pair7Magic);
   AddPosition(Pair8Magic);
   AddPosition(Pair9Magic);   

   ClosePositions(Pair1Magic, ClosePipsPair1);
   ClosePositions(Pair2Magic, ClosePipsPair2);
   ClosePositions(Pair3Magic, ClosePipsPair3);
   ClosePositions(Pair4Magic, ClosePipsPair4);
   ClosePositions(Pair5Magic, ClosePipsPair5);
   ClosePositions(Pair6Magic, ClosePipsPair6);
   ClosePositions(Pair7Magic, ClosePipsPair7);
   ClosePositions(Pair8Magic, ClosePipsPair8);
   ClosePositions(Pair9Magic, ClosePipsPair9);
   
   CloseAllPositions();

   return(0);
}
//+------------------------------------------------------------------+
void CloseAllPositions()
{
   double cur_profit = 0;
   cur_profit += CalculateProfit(Pair1Magic);
   cur_profit += CalculateProfit(Pair2Magic);
   cur_profit += CalculateProfit(Pair3Magic);
   cur_profit += CalculateProfit(Pair4Magic);
   cur_profit += CalculateProfit(Pair5Magic);
   cur_profit += CalculateProfit(Pair6Magic);
   cur_profit += CalculateProfit(Pair7Magic);
   cur_profit += CalculateProfit(Pair8Magic);
   cur_profit += CalculateProfit(Pair9Magic);
   
   CurrentProfit = cur_profit;
   
   if (cur_profit >= CloseBasketProfit)
   {
       CloseAll(Pair1Magic);
       CloseAll(Pair2Magic);
       CloseAll(Pair3Magic);
       CloseAll(Pair4Magic);
       CloseAll(Pair5Magic);
       CloseAll(Pair6Magic);
       CloseAll(Pair7Magic);
       CloseAll(Pair8Magic);
       CloseAll(Pair9Magic);
   }
}
//+------------------------------------------------------------------+
void AddPosition(int magic)
{
   double profit, price;
   string Curr = "";       
   int    cmd;
   
   for (int trade = OrdersTotal() - 1; trade >= 0; trade--) 
   {
      OrderSelect(trade, SELECT_BY_POS, MODE_TRADES);
      if (OrderMagicNumber() != magic) continue;
        
      if (OrderProfit() < profit)  
      {
         profit = OrderProfit();
         Curr   = OrderSymbol();
         cmd    = OrderType();
      }
   }
   
   if (Curr == "")
      return;
      
   if (cmd == OP_BUY)
   {
       price = FindLastBuyPrice(magic, Curr);
       if (price - MarketInfo(Curr, MODE_ASK) >= PipStep * MarketInfo(Curr,MODE_POINT))
       {
          OrderSend(Curr, OP_BUY,  Lots, NormalizeDouble(MarketInfo(Curr, MODE_ASK), Digits), 10, 0, 0, "addition: " + magic, magic, 0, Blue);  
       }
         
   }
   else 
   if (cmd == OP_SELL)
   {
       price = FindLastSellPrice(magic, Curr);
       if (MarketInfo(Curr, MODE_BID) - price >= PipStep * MarketInfo(Curr,MODE_POINT))
       {
          OrderSend(Curr, OP_SELL, Lots, NormalizeDouble(MarketInfo(Curr, MODE_BID), Digits), 10, 0, 0, "addition: " + magic, magic, 0, Red);       
       }
         
   }
}
//+------------------------------------------------------------------+
void ClosePositions(int magic, int profit)
{
   double cur_profit = CalculateProfit(magic);
   if (cur_profit >= profit)
      CloseAll(magic);
}
//+------------------------------------------------------------------+
double CalculateProfit(int magic)
{
   double profit = 0;
   for (int trade = OrdersTotal() - 1; trade >= 0; trade--) 
   {
      OrderSelect(trade, SELECT_BY_POS, MODE_TRADES);
      if (OrderMagicNumber() != magic) continue;
      
      if (OrderType() == OP_SELL)
         profit += (OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_ASK))/MarketInfo(OrderSymbol(),MODE_POINT); //(OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_ASK))*MarketInfo(OrderSymbol(), MODE_POINT);
      
      if (OrderType() == OP_BUY)
         profit += (MarketInfo(OrderSymbol(), MODE_BID)-OrderOpenPrice())/MarketInfo(OrderSymbol(),MODE_POINT); //(OrderOpenPrice() + MarketInfo(OrderSymbol(), MODE_BID))*MarketInfo(OrderSymbol(), MODE_POINT);

   }
   
   return (profit);
}
//+------------------------------------------------------------------+
void OpenPositions(string cur1, string cur2, double corel, double open_on, int magic)
{
   if (CountTrades(magic) > 0)
      return;
      
   if (MathAbs(corel) <= open_on)
     return;
    
   if (corel >= open_on)
   {
      OrderSend(cur1, OP_BUY,  Lots, NormalizeDouble(MarketInfo(cur1, MODE_ASK), Digits), 10, 0, 0, "main: " + magic, magic, 0, Blue);  
      Sleep(1000);     
      OrderSend(cur2, OP_SELL, Lots, NormalizeDouble(MarketInfo(cur2, MODE_BID), Digits), 10, 0, 0, "hedge: " + magic, magic, 0, Red);       
   }
   else
   if (corel <= open_on)
   {
      OrderSend(cur2, OP_BUY,  Lots, NormalizeDouble(MarketInfo(cur2, MODE_ASK), Digits), 10, 0, 0, "main: " + magic, magic, 0, Blue);       
      Sleep(1000);     
      OrderSend(cur1, OP_SELL, Lots, NormalizeDouble(MarketInfo(cur1, MODE_BID), Digits), 10, 0, 0, "hedge: " + magic, magic, 0, Red);       
   }
}
//+------------------------------------------------------------------+
int CountTrades(int magic) 
{
   int count = 0;
   for (int trade = OrdersTotal() - 1; trade >= 0; trade--) 
   {
      OrderSelect(trade, SELECT_BY_POS, MODE_TRADES);
      if (OrderMagicNumber() != magic) continue;
      if (OrderType() == OP_SELL || OrderType() == OP_BUY) count++;
   }
   return (count);
}
//+------------------------------------------------------------------+
void CloseAll(int magic) 
{
   for (int trade = OrdersTotal() - 1; trade >= 0; trade--) 
   {
      OrderSelect(trade, SELECT_BY_POS, MODE_TRADES);
      {
         if (OrderMagicNumber() == magic) 
         {
            if (OrderType() == OP_BUY)  OrderClose(OrderTicket(), OrderLots(), NormalizeDouble(MarketInfo(OrderSymbol(), MODE_BID), Digits), 5, Blue);
            if (OrderType() == OP_SELL) OrderClose(OrderTicket(), OrderLots(), NormalizeDouble(MarketInfo(OrderSymbol(), MODE_ASK), Digits), 5, Red);
         }
         Sleep(1000);
      }
   }
}
//+------------------------------------------------------------------+
double FindLastBuyPrice(int magic, string symbol) 
{
   double oldorderopenprice;
   int oldticketnumber;
   double unused = 0;
   int ticketnumber = 0;
   for (int cnt = OrdersTotal() - 1; cnt >= 0; cnt--) 
   {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() != symbol || OrderMagicNumber() != magic) continue;
      if (OrderSymbol() == symbol && OrderMagicNumber() == magic && OrderType() == OP_BUY) 
      {
         oldticketnumber = OrderTicket();
         if (oldticketnumber > ticketnumber) 
         {
            oldorderopenprice = OrderOpenPrice();
            unused = oldorderopenprice;
            ticketnumber = oldticketnumber;
         }
      }
   }
   return (oldorderopenprice);
}
//+------------------------------------------------------------------+
double FindLastSellPrice(int magic, string symbol) 
{
   double oldorderopenprice;
   int oldticketnumber;
   double unused = 0;
   int ticketnumber = 0;
   for (int cnt = OrdersTotal() - 1; cnt >= 0; cnt--) 
   {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() != symbol || OrderMagicNumber() != magic) continue;
      if (OrderSymbol() == symbol && OrderMagicNumber() == magic && OrderType() == OP_SELL) 
      {
         oldticketnumber = OrderTicket();
         if (oldticketnumber > ticketnumber) {
            oldorderopenprice = OrderOpenPrice();
            unused = oldorderopenprice;
            ticketnumber = oldticketnumber;
         }
      }
   }
   return (oldorderopenprice);
}
//+------------------------------------------------------------------+


