//+------------------------------------------------------------------+
//|                       Renko auto-trading EA by Steve Hopwood.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"
//#property strict
#include <WinUser32.mqh>
#include <stdlib.mqh>
#define  NL    "\n"

/*

bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take, int magic)
void DisplayUserFeedback()

*/

extern double  Lot = 0.01;
extern int     StopLoss = 20;
extern int     TakeProfit = 5;
extern int     CheckCandle = 1;    // 1 = check previous candle , 2 = check last two candles
extern int     MagicNumber = 36204;
extern string  TradeComment="RPCT";
extern int     BarCount = 50;
extern int     RenkoBoxSize = 10;
extern bool    CriminalIsECN=false;
extern string  mis="----Odds and ends----";
extern int     DisplayGapSize=0;


//Trade types etc
bool           LongExists, ShortExists;
int            TicketNo;

//Misc
int            OldBars, slippage;
string         Gap, ScreenMessage, GvName;
int            PipsUntilNextCandle;

void DisplayUserFeedback()
{
   if (IsTesting() && !IsVisualMode()) return;

   ScreenMessage = "";
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "YOU TRADE THIS ROBOT AT YOUR OWN RISK.", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Lot size: ", Lot, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Take profit: ", TakeProfit, " pips",  NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Stop loss: ", StopLoss, " pips",  NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Magic number: ", MagicNumber, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trade comment: ", TradeComment, NL);
   if (CriminalIsECN) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CriminalIsECN = true", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CheckCandle: ", CheckCandle, NL);
      
   
   
   Comment(ScreenMessage);
   
}//void DisplayUserFeedback()

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   //Accommodate different quote sizes
   double multiplier;
   if(Digits == 2 || Digits == 4) multiplier = 1;
   if(Digits == 3 || Digits == 5) multiplier = 10;
   if(Digits == 6) multiplier = 100;   
   slippage*= multiplier;
   StopLoss*= multiplier;
   TakeProfit*= multiplier;
   
   if (TradeComment == "") TradeComment = " ";

   Gap="";
   if (DisplayGapSize >0)
   {
      for (int cc=0; cc< DisplayGapSize; cc++)
      {
         Gap = StringConcatenate(Gap, " ");
      }   
   }//if (DisplayGapSize >0)
   
   Comment(".......................Waiting for the first tick");
   //start();
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   Comment("");
//----
   return(0);
}


bool DoesTradeExist()
{
   
   TicketNo = 0;
   LongExists = false;
   ShortExists = false;
   
   if (OrdersTotal() == 0) 
   {
      return(false);
   }//if (OrdersTotal() == 0) 
   
   for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
   {
      if (!OrderSelect(cc,SELECT_BY_POS)) continue;
      
      //if ( OrderMagicNumber() == SendMagicNumber && OrderSymbol() == Symbol() )      
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
      {
         TicketNo = OrderTicket();
         if (OrderType() == OP_BUY) LongExists = true;
         if (OrderType() == OP_SELL) ShortExists = true;
         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)
{
   
   //if (StopTrading) return(true);
   /*
   if (!IsTesting())
   {   
      if (!IsTradeAllowed() ) return(false);
      if (!IsConnected() ) return(false);
      if (!IsExpertEnabled() ) return(false);
      if (!IsTradeContextBusy() ) return(false);
   }//if (!IsTesting)
   */
   
   
   
   color col = Red;
   if (type == OP_BUY || type == OP_BUYSTOP) col = Green;
   
   int expiry = 0;
   //if (SendPendingTrades) expiry = TimeCurrent() + (PendingExpiryMinutes * 60);
   
   
   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 (ticket > -1)
      {
         if (stop >0 && take > 0) bool result = OrderModify(OrderTicket(), OrderOpenPrice(), stop, take, OrderExpiration(), CLR_NONE);
         //Stop loss but no take profit
         if (stop >0 && take == 0) result = OrderModify(OrderTicket(), OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
         //Take profit but no stop loss
         if (stop ==0 && take > 0) result = OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), take, OrderExpiration(), CLR_NONE);
         if (!result)
         {
             int err=GetLastError();
             Print(Symbol(), " ", type," SL or TP order modify failed with error(",err,"): ",ErrorDescription(err));
         }//if (!result)			  
      }//if (ticket > -1)
      
   }//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," Renko order send failed with error(",err,"): ",ErrorDescription(err));
      Print(Symbol(), " ", stype," Renko order send failed with error(",err,"): ",ErrorDescription(err));
      return(false);
   }//if (ticket < 0)  
   
   
   return(true);
   
}//End bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)



//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
//----

   bool result;
   PipsUntilNextCandle--;

   DisplayUserFeedback();
   
   if (OldBars != Bars)
   {
      PipsUntilNextCandle = RenkoBoxSize;
      OldBars = Bars;
      DoesTradeExist();
      double take;
      
      RefreshRates();
      //Have the last  candles risen  , 1=last candle  , 2 = last two candles
      if (Open[0] > Open[CheckCandle])
      {
         if (ShortExists)
         {
            result = OrderClose(TicketNo, OrderLots(), OrderClosePrice(), 100000, Blue);
            if (!result)
            {
               OldBars = 0;
               return(0);
            }//if (!result)        
            Sleep(5000);    
         }//if (ShortExists)
         if (LongExists) return(0);
         if (TakeProfit > 0) take = NormalizeDouble(Ask + (TakeProfit * Point), Digits);
         result = SendSingleTrade(OP_BUY, TradeComment, Lot, Ask, 0, take, MagicNumber);
         if (!result) OldBars = 0;
      }//if (Open[0] > Open[2])
      
      //Have the last  candles fallen , , 1=last candle  , 2 = last two candles
      if (Open[0] < Open[CheckCandle])
      {
         if (LongExists)
         {
            result = OrderClose(TicketNo, OrderLots(), OrderClosePrice(), 100000, Blue);
            if (!result)
            {
               OldBars = 0;
               return(0);
            }//if (!result)      
            Sleep(5000);      
         }//if (LongExists)
         if (ShortExists) return(0);
         if (TakeProfit > 0) take = NormalizeDouble(Bid - (TakeProfit * Point), Digits);
         result = SendSingleTrade(OP_SELL, TradeComment, Lot, Bid, 0, take, MagicNumber);
         if (!result) OldBars = 0;
      }//if (Open[0] > Open[2])
      
      
   }//if (OldBars != Bars)
      


   
//----
   return(0);
}
//+------------------------------------------------------------------+