Renko Charts + MindHero = Almost Holy Grail

 

Hi everyone,

 

I have one trading system which I'd like to have as EA. This system is based on renko charts and mindhero indicator. 

Why am I using renko charts? The reason is simple. Renko simply filters choppy market. Also it is very useful during news (I'll show you what I mean in example below). The most important reason is that renko ignores time, just movement/pips are important.  

Why am I using mindhero? Honestly, I hate mindhero on normal candle charts, simply on any chart based on time not on pips. However mindhero works fantastically on renko charts. 

 

What setting am I using?

For renko I am using 5 pips per brick/candle (in setting it is 50). Mindhero is in the basic setting as you can download it from mql4.com (https://www.mql5.com/en/code/8299).

 

In my system I also have EMA 5 and SMA 21. SMA has to same effect as 15 minut pivot point on M1 chart.

 

How do I imagine the EA?

 

It should be very simple EA where you can set TP, SL and trailing SL, pips per candle. Those averages or not as important I just use them for manual trading.

 

Now examples:

 

I have very recent example of GY  14:30cet 6/8/2010, during news. I think it is kind of impossible to catch this candle for more than 20%. 

 

 

 

HOWEVER, with renko and mindhero you can catch almost 80% of the movement. It is because the candle from M1 is divided it 16 candles

 

 

It looks great and it is great, also for manual trading but as you 10 candles were in one minute. it is almost impossible to open short. 

The solution for this prom should be EA.

 So please help if you can.

 

If you have any questions do not hesitate and ask me. If you have any direct questions about the system you can write me at thomasfr05(at)gmail(dot)com 

Files:
 

Is there a trick to getting the RenkoLiveChart EA to run? I have 2 versions of it and neither seem to do anything.

 

reganbw, this (RenkoLiveChart.mq4) is actually file-writer, not an EA. It's purpose is to get the data from the chart that is loaded to, and automatically write another chart (offline, virtual chart) that you can load via File -> Open Offline -> YourCurrency,M7. This offline chart contains Renko Bars. And it's actually live chart... as long as the EA works on the normal candlestick chart and feeds the Renko chart with data. It's also good to load that EA to M1 candlestick chart for best accuracy.

 

Attached below is an updated EA RenkoLiveChart_v3.3-Labels_1.mq4

To assist testing and use when ticks are far a few between here is a - FREE Tick Generator Tool - (not referral spam) - also helps in normal hours as well.

EA Chart (M1) - more label options available.


Renko Offline Chart (M2, M3, M6 etc)

If you are new to this, see below.

1. Attach EA to a new M1 chart.

2. Set box size (default is 5 pips) and offline chart time frame (default is M2). If more Renko charts for the same Symbol are required allocate different non standard MT4 time frames - eg, M3, M4, M6 etc.

3. Create and save templates as required - eg. Renko-M2-05, Renko-M2-10, Renko-M3-10.

4. Open offline charts (File -> Open Offline) and find relevant Symbol against matching time frame - this will be the actual Renko chart.

5. Note: The M1 EA chart must remain open for the offline Renko chart to update in real time - the M1 chart can be minimized for convenience.

6. Note: EAs are tick dependent and if ticks are not happening the associated offline chart will not respond to new EA settings or update unprinted bar history - the above Tick Generator Tool solves this problem.

7. Add relevant indicators to offline Renko chart.

Check these

- face in the top right corner of the M1 EA chart must be smiling.

More useful indicators can be got - HERE

 

Renko is great but I am having one small issue...!

I have the normal chart open with the renko ea and the off line chart for the renko bars chart.

But it sometimes needs refreshing to see what is happening with the bars. and I see it repainting quite often...!

 Is this common problem or is there a fix for this?

 
hi all,I'm having a problem,my broker doesn't have m2,what can be done?if there is any solution...thank you
 
sunmetal:
hi all,I'm having a problem,my broker doesn't have m2,what can be done?if there is any solution...thank you
What are you using to make your renko bars ?
 
sunmetal: hi all,I'm having a problem,my broker doesn't have m2,what can be done?if there is any solution...thank you
No brokers do. The offline generator (renko, constant range bars, etc) runs on the m1 and creates the m2 (renko, constant range bar, etc) chart.
 

hello everyone,

been programming forex strategies for a while, mostly in my own system. I was investigating and running some test cases and found Renko bars to be quite interesting and looking promissing. I like MindHeroe indicator, been using it for manual trading for a while and had good results, I think it's a good indicator that worth to be tried.

So when I saw this topic I said, why not? Will program this strategy and see how it goes. I haven't run long term backtesting, just programmed it and there might be bugs and lots of things to be improved so if you want to go ahead and write new versions of it that would be great.

For the Renko bars structures, two arrays (RinkoOpen, RinkoClose) are used - the two values of each array for a given index position represent a RenoBar. What I'm doing is receiving a ball signal from MindHeroe custom indicator and confirm SELL with a decreasing RenkoBar and BUY with an increasing RenkoBar.

Attached file RenkoMindHeroEA contains both indicator and expert advisor.

Files:
 
enicolasgomez:

hello everyone,

been programming forex strategies for a while, mostly in my own system. I was investigating and running some test cases and found Renko bars to be quite interesting and looking promissing. I like MindHeroe indicator, been using it for manual trading for a while and had good results, I think it's a good indicator that worth to be tried.

So when I saw this topic I said, why not? Will program this strategy and see how it goes. I haven't run long term backtesting, just programmed it and there might be bugs and lots of things to be improved so if you want to go ahead and write new versions of it that would be great.

I think you have a problem in your code . . .

            Ticket=OrderSend(Symbol(),OP_BUY,Lts,Ask,2,SL,TP);//Opening Buy
            if (Ticket < 0)                        // Success :)
              {
               Alert ("Opened order Buy ",Ticket);
               return;                             // Exit start()
              }

if Ticket is less than zero your OrderSend() failed and you should report the error and all associated variables . . . What are Function return values ? How do I use them ?

 
//+------------------------------------------------------------------+
//|                                                 MindaHeroeEA.mq4 |
//|                           Copyright 2014, Eduardo Nicolas Gomez. |
//|                                          enicolasgomez@gmail.com |
//+------------------------------------------------------------------+

#property copyright "Copyright 2014, Eduardo Nicolas Gomez"
#property link      "enicolasgomez@gmail.com"
#property version   "1.00"
#property strict

extern double StopLoss   =150;     // SL for an opened order
extern double TakeProfit =30;      // ТР for an opened order 
extern double Lots       =0.1;     // Strictly set amount of lots
extern double Prots      =0.07;    // Percent of free margin
extern int NumBars=500;
extern int RinkoSize=150;
extern int MaxOrders = 1;
extern double BollingerBandwidth = 0.75;
extern int Magic=2009;//|------------------------magic number

string Symb;                       // Security name

#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

double LastRinkoValue = 0;
double RinkoOpen[100000];
double RinkoClose[100000];
int ArrayIndex = 0;

double MHB=0;
double MHR=0;
double BBPER=0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {

   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {

  }

void OnTick()
  {
   int 
   Ticket;
   double
   Free,                            // Current free margin
   Lts,
   SL,                              // SL of a selected order
   TP;                              // TP за a selected order
   
   double Delta = 0;
   RefreshRates();
   
   if (LastRinkoValue == 0)
   {
      LastRinkoValue = Bid;
   }else{
      Delta=NormalizeDouble((Bid-LastRinkoValue)/Point,0);
   }
   
   if (MathAbs(Delta) > RinkoSize)
   {
      //add to open close bar arrays
      RinkoOpen[ArrayIndex]  = LastRinkoValue;
      RinkoClose[ArrayIndex] = Bid;
      LastRinkoValue = 0;
      ArrayIndex++;
   }
   
   bool BUY  = false;
   bool SELL = false;
   bool RINKO_GROWING = false;
   
   Lts = Lots;
   double LastClosedProfit = LastClosedProfit();
   
   if(LastClosedProfit < 0)
   {
      Lts = ((StopLoss / TakeProfit) * Lots) * 1.35;
      MHB=0;
      MHR=0;
   }

   if(Bars > NumBars)
   {
      MHB=iCustom(NULL,0,"mindherosound",NumBars,false, 5, "expert.wav", false, true, 0, 0);
      MHR=iCustom(NULL,0,"mindherosound",NumBars,false, 5, "expert.wav", false, true, 1, 0);
      //BBPER=iCustom(NULL,0,"BollingerBandsPer",20, 2.0, 0, 0);
      BBPER=iCustom(NULL,0,"BollingerBanwidth",20, 0, 2.0, 0, 0);
   }
   
   if(MHB>0)BUY= true;
   if(MHR>0)SELL= true;
   
   if (ArrayIndex > 0)
   {   
      if (RinkoClose[ArrayIndex-1] > RinkoOpen[ArrayIndex-1])
         RINKO_GROWING = true;
      else
         RINKO_GROWING = false;
         
      if((OpenOrders(Symbol())<MaxOrders) && (MathAbs(BBPER) > BollingerBandwidth))
      {  
         if((BUY == true) && (RINKO_GROWING == true))
         {
            RefreshRates();                        // Refresh rates
            SL=Bid - StopLoss*Point;     // Calculating SL of opened
            TP=Bid + TakeProfit*Point;   // Calculating TP of opened
            Alert("Attempt to open Buy. Waiting for response..");
            Ticket=OrderSend(Symbol(),OP_BUY,Lts,Ask,2,SL,TP);//Opening Buy
            if (Ticket > 0)                        // Success :)
              {
               Alert(MHB, MHR, RINKO_GROWING, BBPER);
               Alert ("Opened order Buy ",Ticket);
               return;                             // Exit start()
              }
         }
         
         if ((SELL == true) && (RINKO_GROWING == false))
         {
            RefreshRates();                        // Refresh rates
            SL=Ask + StopLoss*Point;     // Calculating SL of opened
            TP=Ask - TakeProfit*Point;   // Calculating TP of opened
            Alert("Attempt to open Sell. Waiting for response..");
            Ticket=OrderSend(Symbol(),OP_SELL,Lts,Bid,2,SL,TP);//Opening Sell
            if (Ticket > 0)                        // Success :)
              {
               Alert(MHB, MHR, RINKO_GROWING, BBPER);
               Alert ("Opened order Sell ",Ticket);
               return;                             // Exit start()
              }                        // Retrying
         }
      }
    }
  }
  
  int Fun_Error(int Error)                        // Function of processing errors
  {
   switch(Error)
     {                                          // Not crucial errors            
      case  4: Alert("Trade server is busy. Trying once again..");
         Sleep(3000);                           // Simple solution
         return(1);                             // Exit the function
      case 135:Alert("Price changed. Trying once again..");
         RefreshRates();                        // Refresh rates
         return(1);                             // Exit the function
      case 136:Alert("No prices. Waiting for a new tick..");
         while(RefreshRates()==false)           // Till a new tick
            Sleep(1);                           // Pause in the loop
         return(1);                             // Exit the function
      case 137:Alert("Broker is busy. Trying once again..");
         Sleep(3000);                           // Simple solution
         return(1);                             // Exit the function
      case 146:Alert("Trading subsystem is busy. Trying once again..");
         Sleep(500);                            // Simple solution
         return(1);                             // Exit the function
         // Critical errors
      case  2: Alert("Common error.");
         return(0);                             // Exit the function
      case  5: Alert("Old terminal version.");                           // Terminate operation
         return(0);                             // Exit the function
      case 64: Alert("Account blocked.");                      // Terminate operation
         return(0);                             // Exit the function
      case 133:Alert("Trading forbidden.");
         return(0);                             // Exit the function
      case 134:Alert("Not enough money to execute operation.");
         return(0);                             // Exit the function
      default: Alert("Error occurred: ",Error);  // Other variants   
         return(0);                             // Exit the function
     }
  }
int OpenOrders(string strSymbol)
{
   int nOrderCount=0;
   for (int i=OrdersTotal()-1 ; i>=0 ; i--)
   {
      if (!OrderSelect(i,SELECT_BY_POS)) continue;
            if (OrderSymbol() == strSymbol)
               nOrderCount++;
   }
   return(nOrderCount);
}
// return last closed ticket (returns -1 if not found)
int LastClosedTicket()
{
   datetime last_closed = 0;           // close time of last closed order
   int last_ticket = -1;               // ticket number of last closed order  
   
   // loop on all orders in history pool and filter
   for (int i=0; i<OrdersHistoryTotal(); i++) {  
      if (!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) continue;
      //if (OrderMagicNumber() != MAGIC) continue;
      
      if (OrderType()<=1) {
         if (OrderCloseTime() > last_closed) {        // here we filter the last closed order
            last_closed = OrderCloseTime();           // save close time and ticket for next iteration
            last_ticket = OrderTicket();
         }
      }
   }
   
   return(last_ticket);
}
double LastClosedProfit()
{
   int last_ticket = LastClosedTicket();
   
   if (last_ticket > 0) {
      if (OrderSelect(last_ticket,SELECT_BY_TICKET,MODE_HISTORY))
         return(OrderProfit());
   }
   
   return(0.0);
}

int areWeRanging(int period=0) 
{
 double WelchBBWidth_Green = iCustom(NULL, 0, "WelchBBWidth", 20, 0, 2.0, 20, "x", 100, "x", false, 0, period);
 double WelchBBWidth_Yellow = iCustom(NULL, 0, "WelchBBWidth", 20, 0, 2.0, 20, "x", 100, "x", false, 1, period);

 if ( WelchBBWidth_Green > 0 ) 
 {
   return (1);
 } 
 else if ( WelchBBWidth_Yellow > 0) 
 {
   return (-1);
 }

 return (0);
}
Reason: