//+------------------------------------------------------------------+
//|                       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"
#include <WinUser32.mqh>
#include <stdlib.mqh>
#define  NL    "\n"
#define  up "Up"
#define  down "Down"
#define  none "None"
#define  changeup "Changed to up"
#define  changedown "Changed to down"
#define  nochange "No change"
#define  notformed "Not formed yet"

/*

bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take, int magic)
void DisplayUserFeedback()
void GetSixths()
void LookForTradingOpportunities()

*/

extern double  Lot = 0.01;
extern int     StopLoss = 50;
extern int     TakeProfit = 50;
extern int     MagicNumber = 9266583;
extern string  TradeComment="Renko";
extern int     BarCount = 50;
extern bool    CriminalIsECN=false;
extern string  mis="----Odds and ends----";
extern int     DisplayGapSize=30;

//6ths variable.
double         BottomGoldLine;//Bottom, gold line
double         BottomGreenLine;//Bottom, green line
double         MiddleWhiteLine;//Middle, white line
double         TopGreenLine;//Top, green line
double         TopGoldLine;//Top, gold line


//Misc
int            OldBars, slippage;
string         Gap, ScreenMessage, GvName;


void DisplayUserFeedback()
{
   if (IsTesting() && !IsVisualMode()) return;

   ScreenMessage = "";
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "YOU TRADE THIS ROBOT AT YOUR OWN RISK. YOU COULD EASILY LOSE A LOT OF MONEY BY DOING SO.", 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, "Sixths: ", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Top, gold line: ", DoubleToStr(TopGoldLine, Digits), NL);
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Top, green line: ", DoubleToStr(TopGreenLine, Digits), NL);
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Middle, white line: ", DoubleToStr(MiddleWhiteLine, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Bottom, gold line: ", DoubleToStr(BottomGoldLine, Digits), NL);
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Bottom, green line: ", DoubleToStr(BottomGreenLine, Digits), 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;   
   StopLoss*= multiplier;
   TakeProfit*= multiplier;
   slippage*= 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");
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   Comment("");
//----
   return(0);
}

void GetSixths()
{
   /*
   These are declared in the general section and count the lines from the bottom upwards
   double         BottomGoldLine;//Bottom, gold line
   double         BottomGreenLine;//Bottom, green line
   double         MiddleWhiteLine;//Middle, white line
   double         TopGreenLine;//Top, green line
   double         TopGoldLine;//Top, gold line

   */

   //double value = WindowPriceMax(0)-WindowPriceMin(0);      //value top of the chart - value buttem
   double value = High[iHighest(NULL,0,MODE_HIGH,BarCount,1)] - Low[iLowest(NULL,0,MODE_LOW,BarCount,1)];      //value top of the chart - value bottom
   double sixth = value/6;
   double valueS = (value*(MathPow(10,Digits)));
   double sixthS = (sixth*(MathPow(10,Digits)));
   
   BottomGoldLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth, Digits);
   BottomGreenLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth, Digits);
   MiddleWhiteLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth+sixth, Digits);
   TopGreenLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth+sixth+sixth, Digits);
   TopGoldLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth+sixth+sixth+sixth, Digits);
   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);
      


}//End void GetSixths()

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 ( OrderMagicNumber() == SendMagicNumber && OrderSymbol() == Symbol() )      
      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)
{
   
   //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)


void LookForTradingOpportunities()
{
   //Called at the start of each new candle
   if (DoesTradeExist()) return;
   
   //Check market is within trading zone
   if (Bid > TopGoldLine || Ask < BottomGoldLine)
   {
      return;   
   }//if (Bid > TopGoldLine || Ask < BottomGoldLine)
   
   double stop, take;
   bool result;
   
   //Look for a buy
   if (Ask > BottomGoldLine && Low[1] < BottomGoldLine)
   {
      //SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take, int magic)
      RefreshRates();
      stop = NormalizeDouble(Ask - (StopLoss + Point), Digits);
      if (StopLoss == 0) stop = 0;
      take = NormalizeDouble(Ask + (StopLoss + Point), Digits);
      if (TakeProfit == 0) take = 0;
      result = SendSingleTrade(OP_BUY, TradeComment, Lot, Ask, stop, take, MagicNumber);
      if (!result) OldBars = 0;
   }//if (Ask > BottomGoldLine && Low[1] < BottomGoldLine)
   
   //Look for a sell
   if (Bid < TopGoldLine && High[1] > TopGoldLine)
   {
      //SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take, int magic)
      RefreshRates();
      stop = NormalizeDouble(Bid + (StopLoss + Point), Digits);
      if (StopLoss == 0) stop = 0;
      take = NormalizeDouble(Bid - (StopLoss + Point), Digits);
      if (TakeProfit == 0) take = 0;
      result = SendSingleTrade(OP_SELL, TradeComment, Lot, Bid, stop, take, MagicNumber);
      if (!result) OldBars = 0;
   }//if (Bid < TopGoldLine && High[1] > TopGoldLine)
   


}//void LookForTradingOpportunities()


//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
//----

   if (OldBars != Bars)
   {
      OldBars = Bars;
      GetSixths();
      LookForTradingOpportunities();
   }//if (OldBars != Bars)
      

   DisplayUserFeedback();

   
//----
   return(0);
}
//+------------------------------------------------------------------+