How to force EA to check for new values only when a bar is completed and new bar is starting

 

I currently have my EA calculate values on the last x amount of bars - this however creates a huge lag during back testing - because of the "for loop" it looks like it executes on every tick.

This is how the value check stars:

//CHECK ID10T VALUES FOR BUY OR SELL

if(BUY_ORDER   == 0 && SELL_ORDER  == 0 && Bars!=BarCount)

   {

    for(int shift = Bars - ID10Tp; shift >= 0; shift--)

       {

       HighestBar = iHighest(NULL,0,MODE_HIGH,ID10Tp - 1,shift);

       LowestBar  = iLowest (NULL,0,MODE_LOW, ID10Tp - 1,shift);


I already bypass the value checking if any order is open (BUY_ORDER   == 0 && SELL_ORDER  == 0) so that the checking only happens if I want to open a new trade.

If I change the Bars!=BarCount to Bars == BarCount then the for loop is bypassed and I do not get any values :(

So my question to somebody willing to assist: How can I force the EA to check for new values only when a bar is completed and new bar is starting. I need each tick mode for accuracy so that must stay - only this part of the code must execute ONCE per bar.

Thank you in advance

Barry

 
Barry Hendriks:

I currently have my EA calculate values on the last x amount of bars - this however creates a huge lag during back testing - because of the "for loop" it looks like it executes on every tick.

This is how the value check stars:

//CHECK ID10T VALUES FOR BUY OR SELL

if(BUY_ORDER   == 0 && SELL_ORDER  == 0 && Bars!=BarCount)

   {

    for(int shift = Bars - ID10Tp; shift >= 0; shift--)

       {

       HighestBar = iHighest(NULL,0,MODE_HIGH,ID10Tp - 1,shift);

       LowestBar  = iLowest (NULL,0,MODE_LOW, ID10Tp - 1,shift);


I already bypass the value checking if any order is open (BUY_ORDER   == 0 && SELL_ORDER  == 0) so that the checking only happens if I want to open a new trade.

If I change the Bars!=BarCount to Bars == BarCount then the for loop is bypassed and I do not get any values :(

So my question to somebody willing to assist: How can I force the EA to check for new values only when a bar is completed and new bar is starting. I need each tick mode for accuracy so that must stay - only this part of the code must execute ONCE per bar.

Thank you in advance

Barry

Very easy & simple

datetime Last_Candle_Open_Time=0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(Last_Candle_Open_Time!=Time[0])
     {
      //---Put the logic in this space, to calculate the logic only once per bar
      Print(TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES)+", Only print this message once per bar");
      Last_Candle_Open_Time=Time[0];
     }

  }
 
Soheil Kord:

Very easy & simple

Soheil - THANK YOU for your reply! I have tried to copy your solution but I am running into an error I do not know how to solve.

Error:  OnTick function can only be declared in the Global scope


I am no coder/programmer but a brilliant copy & paster :)

So where exactly must I copy & paste your solution?

int Init() section - Gives the Global scope error

int Start() section - Gives the Global scope error


This is how I tried to copy your solution: (Pasted in Init then tried Start but both ways gives an error.

void OnTick()

  { 

  if(CandleTime!=Time[0]){CountedNow = CountedNow + 1;}

  CandleTime=Time[0];

  } 

I will compare 2 values CountedNow and CountedPrev to see if I must execute the value checking loop or not

 

OK - found a solution: This idea in my head sparked the solution ....

                             "I will compare 2 values CountedNow and CountedPrev to see if I must execute the value checking loop or not"

Added  a variable:                                      double Bar0_Open  = iOpen (Symbol(),0,Current + 0);

and on Global declared another variable:   double BarPrevious = 0;

Then changed my original code to this:

   

    if(BUY_ORDER   == 0 && SELL_ORDER  == 0 && BarPrevious!= Bar0_Open)

      {

       for(int shift = Bars - ID10Tp; shift >= 0; shift--)

          {

           HighestBar = iHighest(NULL,0,MODE_HIGH,ID10Tp - 1,shift);

           LowestBar  = iLowest (NULL,0,MODE_LOW, ID10Tp - 1,shift);

And added this after the for loop:

          BarPrevious = Bar0_Open;

Now the code executes only once per bar - additional benefit is that this can be used on any time frame, from M1 to W1 without having to change any code :)


From this horrible time consuming back test result ...


2018.12.11 12:57:56.645 EURUSD,M5: 2286856 tick events (6186 bars, 2287857 bar states) processed in 0:30:25.250 (total time 0:30:31.500)


to this!


2018.12.11 12:25:39.329 EURUSD,M5: 2286856 tick events (6186 bars, 2287857 bar states) processed in 0:01:08.828 (total time 0:01:14.703)


Thanks once again Soheil  - much appreciated!

 

I am an amateur coder too. But a question for the experts, related to the OP's smart solution...

Does the OP need to have the loop now? OR... can he improve or make the loop more efficient?

 for(int shift = Bars - ID10Tp; shift >= 0; shift--)

Does this code continue being executed on every new tick? or only on first tick of new candle, like the OP said?

It seems to me, and please correct me if my statement in incorrect, that this loop should be...

for(int shift = Bars - ID10Tp; shift >= 1; shift--)
 

You have been given the correct solution by @Soheil Kord but you changed it so that it stops working.

 
Revo Trades:

I am an amateur coder too. But a question for the experts, related to the OP's smart solution...

Does the OP need to have the loop now? OR... can he improve or make the loop more efficient?

Does this code continue being executed on every new tick? or only on first tick of new candle, like the OP said?

It seems to me, and please correct me if my statement in incorrect, that this loop should be...

Hi Revo

As I understand it you should almost always start with 0 (zero) - with zero being the current value, one the previous value and so on ... :)

 
Marco vd Heijden:

You have been given the correct solution by @Soheil Kord but you changed it so that it stops working.

Thanks for the reply Marco. As stated I am a copy & paster not a real programmer like most of these guys here. All that I know is from looking at examples of code and trying to understand what the code is trying t achieve, For example I have code to do auto lots but I would never have been able to write that code myself - too stupid :)
 

Copy paste had worked in this case.

But you changed it so that's not exactly copy paste.

 
yes, barry, the thing you did wrong was that you pasted the code between the brackets of your old code. What you should have done, is pasted it outside of all brackets, replacing your Start with Ontick.
 
Barry Hendriks:

Hi Revo

As I understand it you should almost always start with 0 (zero) - with zero being the current value, one the previous value and so on ... :)

yes, i agree, but the first bit of the loop code
int shift = Bars - ID10Tp;

starts from 0, as you say. Or am i wrong? Sorry if I have hijacked your thread.

Marco? is my statement correct?

oops. assuming that ID10Tp is the previous bar.
Reason: