Download MetaTrader 5

Analyzing Bars backwards in EA - page 3

To add comments, please log in or register
Fernando Carreiro
2202
Fernando Carreiro  
paranoyakX:

thanks for the advice, here is a very simple version of my code, this is not my real code but I hope this will be more clear.

 as I said this is not the real code, finding pattern etc is just an example. the reason I opened this thread is DetectExistingPattern() function

I have already given you sample code on how to run code on the first run of OnTick(), so now update your code post accordingly so that your DetectExistingPattern() runs in the first call of OnTick() and not in the OnInit().

Also, you cannot use "Bars" to detect a New Bar. That is incorrect. You should use either "Time[0]" or "SeriesInfoInteger( _Symbol, _Period, SERIES_LASTBAR_DATE )". Here is an example:

bool isNewBar()
{
   static datetime last_time = WRONG_VALUE;
   datetime lastbar_time = (datetime) SeriesInfoInteger( _Symbol, _Period, SERIES_LASTBAR_DATE ); // to be compatible with MQL5

   if( last_time != WRONG_VALUE )
   {
      if( last_time != lastbar_time )
      {
         last_time = lastbar_time;
         return( true );
      }
   }
   else
      last_time = lastbar_time;

   return( false );
}
paranoyakX
133
paranoyakX  
FMIC:

I have already given you sample code on how to run code on the first run of OnTick(), so now update your code post accordingly so that your DetectExistingPattern() runs in the first call of OnTick() and not in the OnInit().

Also, you cannot use "Bars" to detect a New Bar. That is incorrect. You should use either "Time[0]" or "SeriesInfoInteger( _Symbol, _Period, SERIES_LASTBAR_DATE )". Here is an example:

thanks @FMIC, I added the simple code because @jjc asked for it. By the way, I learned using Bars from the from as I remember, everybody was writing that way so I did. Why it is wrong ? Does it can work improperly ?

ps: I use metatrader 4, so it is mql4 right ? 

Fernando Carreiro
2202
Fernando Carreiro  
paranoyakX:

thanks @FMIC, I added the simple code because @jjc asked for it. By the way, I learned using Bars from the from as I remember, everybody was writing that way so I did. Why it is wrong ? Does it can work improperly ?

ps: I use metatrader 4, so it is mql4 right ? 

No! On the forum, you will find that many users have shown that the "Bars" method is very old and unreliable because the number of bars can be changed by the "Options" for charts or it can be constant when the maximum number of bars per chart has been reached. So, it is wrong to use it. Use either "Time[0]" or if you want it to be compatible with MQL5 as well, use "SeriesInfoInteger( _Symbol, _Period, SERIES_LASTBAR_DATE )". Please see my example.
paranoyakX
133
paranoyakX  

FMIC:
No! On the forum, you will find that many users have shown that the "Bars" method is very old and unreliable because the number of bars can be changed by the "Options" for charts or it can be constant when the maximum number of bars per chart has been reached. So, it is wrong to use it. Use either "Time[0]" or if you want it to be compatible with MQL5 as well, use "SeriesInfoInteger( _Symbol, _Period, SERIES_LASTBAR_DATE )". Please see my example.

wow I did not know that I will use your code thank you very much.
whroeder1
15573
whroeder1  
Bars is unreliable (a refresh/reconnect can change number of bars on chart) volume is unreliable (miss ticks) Always use time. New candle - MQL4 forum
JC
1499
JC  
paranoyakX:

as I said this is not the real code, finding pattern etc is just an example. the reason I opened this thread is DetectExistingPattern() function

Returning to your original question... In this example, one option would be that you change your CheckTrendPattern() function so that it can be told to start at a specific bar. Instead of using the fixed range of bars 1 to 10, you instead use an offset of 1 to 10 from a specified start point.

bool CheckTrendPattern(int StartAtBar){
 
  for(int i=StartAtBar + 10; i>=StartAtBar + 1; i--) {
    if (High[i]>High[i-1])
      return false;
  };
  HighestValue = High[StartAtBar + 10];
  LowestValue  = Low[StartAtBar + 1];
  
  return true;
};

When there is no existing order, and you want to check whether the pattern is currently met, you then use CheckTrendPattern(0) instead of CheckTrendPattern().

When starting up, if you have an existing order then you can look for the pattern which triggered it as follows. This is the same suggestion which I made at outset: you get the bar index which is equivalent to the open time of the existing order, and start looking backwards from there.

int BarShiftOfOrderOpen = iBarShift(Symbol(), Period(), OrderOpenTime(), false);
CheckTrendPattern(BarShiftOfOrderOpen);

However, as FMIC says, it is preferable to do this check in the first call to OnTick() rather than in OnInit(). My own reasons for suggesting this have nothing to do with "holding up the initialisation". Instead, I would be concerned that, when MT4 is re-starting with the EA already attached to a chart, you don't yet 100% reliably have an order list from the broker or an updated bar history. 

Another consideration which you may want to bear in mind is the following scenario, all happening during the time covered by a single bar:

  • You find a pattern and place a trade
  • Your open trade is closed, e.g. because it hits a stop-loss
  • MT4 closes (whether deliberately or not)
  • MT4 restarts
  • The EA re-finds the current pattern, and takes another trade in the same bar because there is no open trade

You may want to check closed orders as well as open orders, to prevent this.

paranoyakX
133
paranoyakX  
@jjc, your suggestions are very good. thanks for sharing your experience.
jjc:

Returning to your original question... In this example, one option would be that you change your CheckTrendPattern() function so that it can be told to start at a specific bar. Instead of using the fixed range of bars 1 to 10, you instead use an offset of 1 to 10 from a specified start point.

When there is no existing order, and you want to check whether the pattern is currently met, you then use CheckTrendPattern(0) instead of CheckTrendPattern().

My real pattern is not this, so there is not fixed numbers (as 10 example) it is dynamic but my pattern check method is different so I couldn't recall it and this is really bothers me because I wrote a similar code to find pattern again. problem is while EA is running, I just check the last bar if my pattern is still continuing and if it is then I do nothing, when the pattern is broken then I open an order. So I can not use that code while finding the pattern again because this time, I have to go back on bars not forward. I also did not want to search pattern backward because, on this case I will be checking same bars over and over again. I just concerned about performance issue but as I see it won't be a problem, so I am thinking changing my pattern finding method so I can use it on both startup and while running as you said. this will also prevent possible problems like if I change my pattern, I would have to change re-finding pattern procedure which I can forgot.thanks for that. Also as @FMIC said, maybe I should make this part as an indicator (which I did not write much) so it won't be a problem finding and finding again.
jjc:

When starting up, if you have an existing order then you can look for the pattern which triggered it as follows. This is the same suggestion which I made at outset: you get the bar index which is equivalent to the open time of the existing order, and start looking backwards from there. However, as FMIC says, it is preferable to do this check in the first call to OnTick() rather than in OnInit(). My own reasons for suggesting this have nothing to do with "holding up the initialisation". Instead, I would be concerned that, when MT4 is re-starting with the EA already attached to a chart, you don't yet 100% reliably have an order list from the broker or an updated bar history.

Another consideration which you may want to bear in mind is the following scenario, all happening during the time covered by a single bar:

  • You find a pattern and place a trade
  • Your open trade is closed, e.g. because it hits a stop-loss
  • MT4 closes (whether deliberately or not)
  • MT4 restarts
  • The EA re-finds the current pattern, and takes another trade in the same bar because there is no open trade

Now it is more clear why I should do it in OnInit, reliability is the most important point of course  and I did not think about your consideration warning. this part is really important, I could open redundant orders, maybe rare but possible. I have to handle this in some ways. really thank you so much.

 @WHRoeder your new bar check control is so simple and beautiful. I added your method to my code, thank you. 

paranoyakX
133
paranoyakX  

Hello everyone,

 as @FMIC adviced, I write and indicator that finds my pattern, give a signal and a few more data that will use for my orders (I might open more than one order at difference prices). Now I want to use it in my EA but I have a question, I need your experience actually. When I get a signal from my indicator, I will open an order or put an order (sell limit or buy limit etc) if my mt4 crashes for any reason when I reopen it, how can I find that opened order is belong to which signal in my indicator. is it Ok to use bar shift for that ? as we talked before, I can find order creation time, then find that bar shift and should I try to get indicator value by using this shift ? How can I match this order and indicator shift

 

thanks. 

Fernando Carreiro
2202
Fernando Carreiro  
paranoyakX: Hello everyone, as @FMIC adviced, I write and indicator that finds my pattern, give a signal and a few more data that will use for my orders (I might open more than one order at difference prices). Now I want to use it in my EA but I have a question, I need your experience actually. When I get a signal from my indicator, I will open an order or put an order (sell limit or buy limit etc) if my mt4 crashes for any reason when I reopen it, how can I find that opened order is belong to which signal in my indicator. is it Ok to use bar shift for that ? as we talked before, I can find order creation time, then find that bar shift and should I try to get indicator value by using this shift ? How can I match this order and indicator shift ?
Yes, you can use iBarShift(), just as jjc has explained to you in an earlier post to then reference your indicator's data via iCustom() function.
paranoyakX
133
paranoyakX  
FMIC:
Yes, you can use iBarShift(), just as jjc has explained to you in an earlier post to then reference your indicator's data via iCustom() function.
Thank you very much @FMIC, so using shift is a good solution then. Making my pattern as indicator was a really good advice. I will change my whole code of course but it will be more consistent.
123
To add comments, please log in or register