//+------------------------------------------------------------------+
//|                                                       Louise.mq4 |
//|                                  Copyright © 2010, Steve Hopwood |
//|                              http://www.hopwood3.freeserve.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, Steve Hopwood"
#property link      "http://www.hopwood3.freeserve.co.uk"
#include <WinUser32.mqh>
#include <stdlib.mqh>
#define  NL    "\n"

/*
void DisplayUserFeedback()
void LookForTrendTrades()
bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take, int magic)
double GetTrendRsi(int tf, int period)
void GetTrendAtr()

*/

extern string  rsii="----Rsi----";
extern int     RsiPeriod=21;
extern int     RsiTimeFrame=0;
extern int     RsiOverbought=85;
extern int     RsiOversold=15;
extern string  stri="----Atr inputs----";
extern int     FastTrendAtr=5;
extern int     SlowTrendAtr=200;
extern string  gs="----General inputs----";
extern double  Lot=0.01;
extern int     MagicNumber=48032;
extern string  TradeComment="Louise";
extern bool    CriminalIsECN=false;
extern int     TrendTakeProfit=100;
extern int     TrendStopLoss=50;
extern string  drsii="----D1 Rsi trend filter----";
extern bool    UseD1Rsi=false;
extern string  mis="----Odds and ends----";
extern int     DisplayGapSize=30;


//Trading
int            TicketNo;

//Trend Atr
double         fTrendAtr, sTrendAtr;

//Rsi
double         TrendRsi, D1Rsi;

//Misc stuff
string         Gap, ScreenMessage;


void DisplayUserFeedback()
{
   if (IsTesting() && !IsVisualMode()) return;

   ScreenMessage = "";
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Lot size: ", Lot, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Magic number: ", MagicNumber, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trade comment: ", TradeComment, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Take profit: ", TrendTakeProfit, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Rsi: ", TrendRsi, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Daily Rsi: ", D1Rsi, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Fast Atr: ", fTrendAtr, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Slow Atr: ", sTrendAtr, NL);

   Comment(ScreenMessage);
   
   
}//End void DisplayUserFeedback()



//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
   
   int multiplier;
   if(Digits == 2 || Digits == 4) multiplier = 1;
   if(Digits == 3 || Digits == 5) multiplier = 10;
   if(Digits == 6) multiplier = 100;   
   if(Digits == 7) multiplier = 1000;   
   TrendTakeProfit*= multiplier;
   TrendStopLoss*= multiplier;
   
   Gap="";
   if (DisplayGapSize >0)
   {
      for (int cc=0; cc< DisplayGapSize; cc++)
      {
         Gap = StringConcatenate(Gap, " ");
      }   
   }//if (DisplayGapSize >0)

   if (TradeComment == "") TradeComment = " ";
   //start();
   
   //start();
   
}

//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
   Comment("");

}//End int deinit()

bool DoesTradeExist()
{
   
   TicketNo = 0;
   
   if (OrdersTotal() == 0) 
   {
      return(false);
   }//if (OrdersTotal() == 0) 
   
   for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
   {
      if (!OrderSelect(cc,SELECT_BY_POS)) continue;
      
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)      
      {
         TicketNo = OrderTicket();
         return(true);         
      }//if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)      
   }//for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)

   return(false);

}//End bool DoesTradeExist()





bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take, int magic)
{
   

   int slippage = 10;
   if (Digits == 3 || Digits == 5) slippage = 100;
   
   color col = Red;
   if (type == OP_BUY || type == OP_BUYSTOP) col = Green;
   
   int expiry = 0;
   
   
   if (!CriminalIsECN) int ticket = OrderSend(Symbol(),type, lotsize, price, slippage, stop, take, comment, magic, expiry, col);
   
   
   //Is a 2 stage criminal
   if (CriminalIsECN)
   {
      ticket = OrderSend(Symbol(),type, lotsize, price, slippage, 0, 0, comment, magic, expiry, col);
	   if (stop != 0)
	   {
		   if (ticket > 0)
		   bool result = OrderModify(ticket, OrderOpenPrice(), stop, take, 0, CLR_NONE);
		   if (!result)
		   {
		       int err=GetLastError();
             Print(Symbol(), " ", type," SL  order modify failed with error(",err,"): ",ErrorDescription(err));               
		   }//if (!result)			  
	   }//if (Sl != 0)
      
      
   }//if (CriminalIsECN)
   
   //Error trapping for both
   if (ticket < 0)
   {
      string stype;
      if (type == OP_BUY) stype = "OP_BUY";
      if (type == OP_BUYSTOP) stype = "OP_BUYSTOP";
      if (type == OP_SELL) stype = "OP_SELL";
      if (type == OP_SELLSTOP) stype = "OP_SELLSTOP";
      err=GetLastError();
      Alert(Symbol(), " ", stype," Louise order send failed with error(",err,"): ",ErrorDescription(err));
      Print(Symbol(), " ", stype," Louise order send failed with error(",err,"): ",ErrorDescription(err));
      return(false);
   }//if (ticket < 0)  
   
   //Got this far, so trade send succeeded
   Comment(".........................Sleeping for 2 minutes after a successful order send");
   Sleep(120000);
   
   return(true);
   
}//End bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)

void LookForTrendTrades()
{

   bool SendTrade = false;
   int type;
   double price, take, stop;

   RefreshRates();
   
   //Look for buy opportunity
   if (TrendRsi < RsiOversold && fTrendAtr > sTrendAtr)
   {
      if (UseD1Rsi && D1Rsi < 55) return;
      SendTrade = true;
      type = OP_BUY;
      price = Ask;      
      take = NormalizeDouble(Ask + (TrendTakeProfit * Point), Digits);
      stop = NormalizeDouble(Ask - (TrendStopLoss * Point), Digits);
   }//if (TrendRsi < RsiBoxTop && fTrendAtr > sTrendAtr)
   

   //Look for sell opportunity
   if (TrendRsi > RsiOverbought && sTrendAtr < sTrendAtr)
   {
      if (UseD1Rsi && D1Rsi > 45) return;
      SendTrade = true;
      type = OP_SELL;
      price = Bid;      
      take = NormalizeDouble(Bid - (TrendTakeProfit * Point), Digits);
      stop = NormalizeDouble(Bid + (TrendStopLoss * Point), Digits);
   }//if (TrendRsi > RsiBoxBottom && sTrendAtr < sTrendAtr)
   
   if (TrendTakeProfit == 0) take = 0;
   if (TrendStopLoss == 0) stop = 0;
   

   //Send trade if conditions are right
   if (SendTrade)
   {
      SendSingleTrade(type, TradeComment, Lot, price, stop, take, MagicNumber);
   }//if (SendTrade)
   

}//End void LookForTrendTrades()

double GetTrendRsi(int tf, int period)
{
   double val = iRSI(NULL, tf, period, PRICE_CLOSE, 0);

   return(val);
   
}//double GetTrendRsi(int tf, int period)
/*
void DoesTradeNeedClosing()
{

   bool CloseTrade = false;
   
   if (OrderType() == OP_BUY && (TrendRsi >= RsiOverbought || fTrendAtr < sTrendAtr) )
   {
      CloseTrade = true;
   }//if (OrderType() == OP_BUY && Atr >= 70)
   
   if (OrderType() == OP_SELL && (TrendRsi <= RsiOversold || fTrendAtr > sTrendAtr) )
   {
      CloseTrade = true;      
   }//if (OrderType() == OP_BUY && TrendRsi >= 70)
   

   if (CloseTrade)
   {
      OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 1000, CLR_NONE);
   }//if (CloseTrade)
   
      
}//void DoesTradeNeedClosing()
*/
void GetTrendAtr()
{
   fTrendAtr = iATR(NULL, 0, FastTrendAtr, 0);
   sTrendAtr = iATR(NULL, 0, SlowTrendAtr, 0);

}//void GetTrendAtr()


//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{

   TrendRsi = GetTrendRsi(RsiTimeFrame, RsiPeriod);
   D1Rsi = GetTrendRsi(PERIOD_D1, 21);
   GetTrendAtr();
   DisplayUserFeedback();   

   //Is there already a trade open
   bool TradeExists= DoesTradeExist();
   
   //No need to go further it there is already a trade Open   
   if (TradeExists)
   {
      //DoesTradeNeedClosing();
      return;
   }//if (DoesTradeExist)
   
   //No trade open, so see if one is possible
   LookForTrendTrades();
   

}
//+------------------------------------------------------------------+