//+------------------------------------------------------------------+
//|                Middleastern GBPJPY correlation trading robot.mq4 |
//|                                  Copyright © 2009, Steve Hopwood |
//|                              http://www.hopwood3.freeserve.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Steve Hopwood"
#property link      "http://www.hopwood3.freeserve.co.uk"
#include <WinUser32.mqh>
#include <stdlib.mqh>
#define  NL    "\n"
#define  up "Up"
#define  down "Down"
#define  none "None"

/*
   for (int cc = OrdersTotal(); cc >= 0 ; cc--)
   {
      if (!OrderSelect(cc,SELECT_BY_POS)) continue;
      if (OrderMagicNumber()==MagicNumber)      
      {
            
      }//if (OrderMagicNumber()==MagicNumber)
   }//for (int cc=0; cc<OrdersTotal(); cc++)


void DisplayUserFeedback()
bool DoesTradeExist()
string GetTradeDirection()
bool SendSingleTrade(int type)

*/

extern double           Lot=0.01;
extern int              StopLoss=300;
extern int              TakeProfit=200;
extern int              MagicNumber=39927856;
extern string           TradeComment="ME correlation";
extern bool             CriminalIsECN=false;
extern string           ps="----Pairs----";
extern string           TradePair="GBPJPY";
extern string           CorrPair1="USDJPY";
extern string           CorrPair2="GBPUSD";
extern string           oae="----Odds and ends----";
extern int              DisplayGapSize=30;

//Misc stuff
string            ScreenMessage, Gap;
int               OldTradePairBars;
int               OldCorr1Bars;
int               OldCorr2Bars;
int               MinCandleLength=100;

void DisplayUserFeedback()
{

   ScreenMessage = "";
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "TradePair = ", TradePair, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "CorrPair1 = ", CorrPair1, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "CorrPair2 = ", CorrPair2, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "Lot size = ", Lot, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "TakeProfit = ", TakeProfit, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "StopLoss = ", StopLoss, NL);
   if (CriminalIsECN) ScreenMessage = StringConcatenate(ScreenMessage, Gap, "CriminalIsECN = true          ", NL);
   else ScreenMessage = StringConcatenate(ScreenMessage, Gap, "CriminalIsECN = false          ", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Magic number = ", MagicNumber, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "Trade comment = ", TradeComment, NL);
   
   
   
   //ScreenMessage = StringConcatenate(ScreenMessage, Gap, "--", NL);
   Comment(ScreenMessage);

}//void DisplayUserFeedback()

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//----
   
   
   //Adjust settings for 4 digit crim
   if (Digits == 2 || Digits == 4)
   {
      TakeProfit/= 10;
      StopLoss/= 10;
      MinCandleLength/=10;
   }//if (Digits == 2 || Digits == 4)
   
   //Set up chart suffix
   string AddChar = StringSubstr(Symbol(),6,4);
   TradePair="GBPJPY" + AddChar;
   CorrPair1="USDJPY" + AddChar;
   CorrPair2="GBPUSD" + AddChar;
   
   
   Gap="";
   if (DisplayGapSize >0)
   {
      for (int cc=0; cc< DisplayGapSize; cc++)
      {
         Gap = StringConcatenate(Gap, " ");
      }   
   }

   OldTradePairBars = Bars;
   OldCorr1Bars = iBars(CorrPair1, 0);
   OldCorr2Bars = iBars(CorrPair2, 0);
   
   
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   
//----
   return(0);
}

bool DoesTradeExist()
{
   if (OrdersTotal() == 0) return(false);
   
   for (int cc = OrdersTotal(); cc >= 0 ; cc--)
   {
      if (!OrderSelect(cc,SELECT_BY_POS)) continue;
      if (OrderMagicNumber()==MagicNumber && OrderSymbol() == Symbol() )      
      {
         return(true);   
      }//if (OrderMagicNumber()==MagicNumber)
   }//for (int cc=0; cc<OrdersTotal(); cc++)

   //Got this far, so no trade is open
   return(false);

}//bool DoesTradeExist()

string GetTradeDirection()
{
   //Test the conditions for sending a trade
   

   //Candle length
   double CL = iHigh(CorrPair1, 0, 1) - iLow(CorrPair1, 0, 1);
   if (CL < (MinCandleLength * Point) ) return(none);
   CL = iHigh(CorrPair2, 0, 1) - iLow(CorrPair2, 0, 1);
   if (CL < (MinCandleLength * Point) ) return(none);

   if (iClose(CorrPair1, 0, 1) > iOpen(CorrPair1, 0, 1) && iClose(CorrPair2, 0, 1) > iOpen(CorrPair2, 0, 1) ) return(up);
   if (iClose(CorrPair1, 0, 1) < iOpen(CorrPair1, 0, 1) && iClose(CorrPair2, 0, 1) > iOpen(CorrPair2, 0, 1) ) return(down);
   
   //Got this far, so conditions are wrong for trading
   return(none);
   
}//string GetTradeDirection()

bool SendSingleTrade(int type)
{
   // Attempts to place a trade according to type, i.e.
   // 0 = OP_BUY
   // 1 = OP_SELL
   
   // Check spread
   //if (MarketInfo(Symbol(), MODE_SPREAD) > MaxSpreadAllowed)
   //{
      //return(false);// Spread too large, so abort send
   //}//if (MarketInfo(NULL, MODE_SPREAD) > MaxSpreadAllowed)

 
   
   RefreshRates();
   
   // Buy trade
   if (type == 0)
   {
      double TradePrice=Ask;
      int colour = 32768;//green
      double SL = NormalizeDouble(TradePrice - (StopLoss * Point), Digits);
      double TP = NormalizeDouble(TradePrice + (TakeProfit * Point), Digits);
   }//if (type == 0)   
   
   
   // Sell trade
   if (type == 1)
   {
      TradePrice=Bid;      
      colour = 255;//red
      SL = NormalizeDouble(TradePrice - (StopLoss * Point), Digits);
      TP = NormalizeDouble(TradePrice + (TakeProfit * Point), Digits);
   }//if (type == 1)
   
   int slippage = 10;
   if (Digits == 3 || Digits == 5) slippage = 100;
   slippage*= Point;
   
   //Non ECN crook
   if (!CriminalIsECN) int ticket = OrderSend(Symbol(),type, Lot, TradePrice, slippage, SL, TP, TradeComment, MagicNumber,0, colour);
   
   //Is a 2 stage criminal
   if (CriminalIsECN)
   {
     ticket = OrderSend(Symbol(),type, Lot, TradePrice, slippage, 0, 0, TradeComment, MagicNumber,0, colour);
	  if (StopLoss != 0)
	  {
		  if (ticket > 0)
			  bool result = OrderModify(ticket, OrderOpenPrice(),	SL, TP, 0, CLR_NONE);
			  if (!result)
			  {
			      int err=GetLastError();
               Alert(Symbol(), " ", type," TP order modify failed with error(",err,"): ",ErrorDescription(err));
               Print("Order send failed with error(",err,"): ",ErrorDescription(err));      
			  }//if (!result)			  
	  }//if (Take != 0)
	  else Print("Skipping OrderModify because no SL or TP specified.");
      
   }//if (CriminalIsECN)

   //Error trapping for both
   if (ticket < 0)
   {
      err=GetLastError();
      Alert(Symbol(), " ", type," order send failed with error(",err,"): ",ErrorDescription(err));
      Print("Order send failed with error(",err,"): ",ErrorDescription(err));
      return(false);
   }//if (ticket < 0)
   
   return(true);
}//End void SendSingleTrade(type)


//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
//----
   
   //Is there a trade already open?
   bool TradeExists = DoesTradeExist();
   if (TradeExists)
   {
      DisplayUserFeedback();
      return;
   }//if (TradeExists)
      
   static int Tries = 0;
      
   //New candle?
   if (OldTradePairBars != Bars)
   {
      //Check the new candles have formed in the corellation pairs charts
      if (OldCorr1Bars == iBars(CorrPair1, 0) ) return;
      if (OldCorr2Bars == iBars(CorrPair2, 0) ) return;
      OldTradePairBars = Bars;
      OldCorr1Bars = iBars(CorrPair1, 0);
      OldCorr2Bars = iBars(CorrPair2, 0);
      string direction = GetTradeDirection();
      //Send buy
      if (direction == up)
      {
         bool TradeSuccess = SendSingleTrade(0);
         if (!TradeSuccess && Tries <= 5)
         {
            OldTradePairBars = 0;
            OldCorr1Bars = 0;
            OldCorr2Bars = 0;
            Tries++;            
         }//if (!TradeSuccess) 
      }//if (direction == up)
      
      if (direction == down)
      {
         TradeSuccess = SendSingleTrade(1);
         if (!TradeSuccess) 
         {
            OldTradePairBars = 0;
            OldCorr1Bars = 0;
            OldCorr2Bars = 0;
            Tries++;            
         }//if (!TradeSuccess) 
         
      }//if (direction == down)
      if (Tries == 5)
      {
         OldTradePairBars = Bars;
         OldCorr1Bars = iBars(CorrPair1, 0);
         OldCorr2Bars = iBars(CorrPair2, 0);      
      }//if (Tries == 5)
      
   }//if (OldTradePairBars != Bars)
   
   
   DisplayUserFeedback();
   
   
//----
   return(0);
}
//+------------------------------------------------------------------+