Getting the bar opening time (SERIES_LASTBAR_DATE) having the position opening time

 

So what i need to know is the BAR opening time (SERIES_LASTBAR_DATE) by having only the position opening time:


    if (PositionsTotal() > 0 && _LAST_INCPOS_BAR_TIME == 0) {
        if (PositionSelectByTicket(PositionGetTicket(PositionsTotal()-1))) {
            datetime lastPositionOpenTime = (datetime)PositionGetInteger(POSITION_TIME);
            
            _LAST_INCPOS_BAR_TIME = ??? i need this to be the 2H opening bar time, so if the position was opened on 14:30, this variable should be the 14:00 time for that day, if the position was opened at 17:49, the variable should be the datetime for 16:00 etc
        }
        else {
            Print("¡! - Error: cannot select position");
            return(INIT_FAILED);
        }
    }

So the variable

_LAST_INCPOS_BAR_TIME 
needs to be same format as  "SeriesInfoInteger(_Symbol, PERIOD_H2, SERIES_LASTBAR_DATE);"


Thanks in advance!

Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / History Database Properties
Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / History Database Properties
  • www.mql5.com
History Database Properties - Trade Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 

Do you know about iBarShift() and iTime()?

Given a specified time and date, iBarShift() returns to the bar shift for the nearest respective bar.

And you can then use the "shift" to get the opening time of that bar with the iTime() function or use any of the other time-series functions to get the OHLC data for that bar shift.

I hope I understood your question correctly, but if not, let me know.

Documentation on MQL5: Timeseries and Indicators Access / iBarShift
Documentation on MQL5: Timeseries and Indicators Access / iBarShift
  • www.mql5.com
iBarShift - Timeseries and Indicators Access - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Fernando Carreiro #:

Do you know about iBarShift() and iTime()?

Given a specified time and date, iBarShift() returns to the bar shift for the nearest respective bar.

And you can then use the "shift" to get the opening time of that bar with the iTime() function or use any of the other time-series functions to get the OHLC data for that bar shift.

I hope I understood your question correctly, but if not, let me know.

Yes sir, i think i got it, please correct me if i'm wrong :)


    // Last position opening bar time not loaded but the're are positions running
    if (PositionsTotal() > 0 && _LAST_INCPOS_BAR_TIME == 0) {
        if (PositionSelectByTicket(PositionGetTicket(PositionsTotal()-1))) {
            datetime lastPositionOpenTime    = (datetime)PositionGetInteger(POSITION_TIME);
            int lastPositionBarIndex         = iBarShift(_Symbol, PERIOD_H2, lastPositionOpenTime, false);
            datetime lastPositionOpenBarTime = iTime(_Symbol, PERIOD_H2, lastPositionBarIndex);
            
            _LAST_INCPOS_BAR_TIME = lastPositionOpenBarTime;
        }
        else {
            return(INIT_FAILED);
        }
    }
 
Jose Ma Gassin Perez Traverso #: Yes sir, i think i got it, please correct me if i'm wrong :)

Since we don't know anything about the rest of your code, it is difficult for me to say if it is the behaviour you expect. You will have to test and see if it is what you expect.

Please note, that you should not be using this code in the OnInit() handler.

 
Fernando Carreiro #:

Since we don't know anything about the rest of your code, it is difficult for me to say if it is the behaviour you expect. You will have to test and see if it is what you expect.

Please note, that you should not be using this code in the OnInit() handler.

Oh, why? i want to make sure to load the last position 2H bar opening time if the EA has stopped or some reason or i'm just opening metatrader with positions already open.

 
Jose Ma Gassin Perez Traverso #: Oh, why? i want to make sure to load the last position 2H bar opening time if the EA has stopped or some reason or i'm just opening metatrader with positions already open.

Because the OnInit should be used for initialisation only. There are many times when trade data has not even been loaded yet and not available during the initialisation phase.

All data coming from the trade server should be read in either the OnTick (EAs) or OnCalculate (Indicators) event handlers, not the OnInit.

Create a startup routine in OnTick/OnCalculte for this. Don't do it in OnInit.

 
Fernando Carreiro #:

Because the OnInit should be used for initialisation only. There are many times when trade data has not even been loaded yet and not available during the initialisation phase.

All data coming from the trade server should be read in either the OnTick (EAs) or OnCalculate (Indicators) event handlers, not the OnInit.

Create a startup routine in OnTick/OnCalculte for this. Don't do it in OnInit.

It's a really good idea to load ONCE in a handler (OnTick) that happens so many times? even if i use a condition, the script will check the condition EVERY SINGLE TICK... it sounds really inefficient to me...

 
Jose Ma Gassin Perez Traverso #: It's a really good idea to load ONCE in a handler (OnTick) that happens so many times? even if i use a condition, the script will check the condition EVERY SINGLE TICK... it sounds really inefficient to me...

No! Simply use a static boolean variable to detect the first-time use.

void OnTick() {
   static bool bFirstTime = true;
   if( bFirstTime ) {
      bFirstTime = false; 
      
      // ... carry out a start-up procedure
   };

   // ... do other new tick event handling
};
 
Fernando Carreiro #:

No! Simply use a static boolean variable to detect the first-time use.

Yes that's what i mean, the script will checking that if again and again on every tick, something that is meant to be a one-time occurrence will keep checking "first time?" next tick "first time?" next tick "first time?"... BUT you're the boss if you tell me that doing so is not gonna add latency to orders, deal.
 
Jose Ma Gassin Perez Traverso #:
Yes that's what i mean, the script will checking that if again and again on every tick, something that is meant to be a one-time occurrence will keep checking "first time?" next tick "first time?" next tick "first time?"... BUT you're the boss if you tell me that doing so is not gonna add latency to orders, deal.
Well, you could also use an OnTimer event, and instead of using an if-statement in OnTick, just use an assignment to a global bool, informing you of the fact, On timer has already been called.

It all depends on your coding skills. You could also work with error code handling in OnTimer().
 
Jose Ma Gassin Perez Traverso #:
Yes that's what i mean, the script will checking that if again and again on every tick, something that is meant to be a one-time occurrence will keep checking "first time?" next tick "first time?" next tick "first time?"... BUT you're the boss if you tell me that doing so is not gonna add latency to orders, deal.

On my PC it takes about 0.00000000025 s to validate a boolean value in a loop. It's an average calculated on a loop of 1.000.000.000 iterations. The control loop was empty. Now check the ping to your broker's server and the average server execution time of the trade and you will know that you should be much more concerned about other aspects than this. ;)

#property strict
#define ITERS (1000000000)
#define uSeconds2String(x) StringFormat("%d.%03d", (uint)(x / 1000000), (x % 1000000) / 1000)
void OnStart()
  {
   ulong initialGMC = 0;
   ulong runTimeBool = 0;
   ulong runTimeEmpty = 0;
   bool ourBool = false;

   initialGMC = GetMicrosecondCount();
   for(uint i = 0; i <= ITERS; i++)
     {
      if(ourBool)
         ourBool = false;
     }
   runTimeBool = GetMicrosecondCount() - initialGMC;

   initialGMC = GetMicrosecondCount();
   for(uint i = 0; i <= ITERS; i++)
     {
     }
   runTimeEmpty = GetMicrosecondCount() - initialGMC;

   Comment("empty loop total [s]: " + uSeconds2String(runTimeEmpty) +
   "\nbool loop total [s]: "+ uSeconds2String(runTimeBool) +
   "\nbool overhead per 1 iter [us]: " + StringFormat("%f",(runTimeBool-runTimeEmpty)/(double)ITERS)
   );
  }
Reason: