iClose returning wrong value - page 2

 
Douglas Eiras:
Any other idea guys? :(

I hope it'll work properly:

bool Refresh(string symbol=NULL,ENUM_TIMEFRAMES tf=PERIOD_CURRENT,const uint timeOut=1000)
  {
   if(symbol==NULL || symbol=="") symbol=_Symbol;
   if(tf==PERIOD_CURRENT) tf=(ENUM_TIMEFRAMES)_Period;
   datetime lastBarTime[1];
   uint startCount=GetTickCount();
   while((CopyTime(symbol,tf,0,1,lastBarTime)!=1 || lastBarTime[0]<TimeCurrent()-TimeCurrent()%PeriodSeconds(tf)) && GetTickCount()-startCount<timeOut && !IsStopped());
   return(lastBarTime[0]>=TimeCurrent()-TimeCurrent()%PeriodSeconds(tf));
  }
EDIT: see https://www.mql5.com/en/forum/231717/page2#comment_6809758
 
whroeder1:

Error zero mean NO error! Obviously the start of the week is not equal to the start of the day. Try removing that second condition.

Hi! i did it once. 90% of the times the values came right, but i'm still getting some wrong values. :/

 
Petr Nosek:

I hope it'll work properly:

I've also edited my previous post https://www.mql5.com/en/forum/231717#comment_6791188

Hi! Not yet..


#property strict
input ENUM_TIMEFRAMES     UseTimeFrame  = PERIOD_MN1;

void OnTick()
{
   while (true)
   {
      if (Refresh(Symbol(),UseTimeFrame,1000))
      {
         Print(iClose(Symbol(),UseTimeFrame,1));
         break;
      }
      Print("Waiting...");
   }
   
   ExpertRemove();
   
}

bool Refresh(string symbol=NULL,ENUM_TIMEFRAMES tf=PERIOD_CURRENT,const uint timeOut=1000)
  {
   if(symbol==NULL || symbol=="") symbol=_Symbol;
   if(tf==PERIOD_CURRENT) tf=(ENUM_TIMEFRAMES)_Period;
   datetime lastBarTime[1];
   uint startCount=GetTickCount();
   while((CopyTime(symbol,tf,0,1,lastBarTime)!=1 || lastBarTime[0]<TimeCurrent()-TimeCurrent()%PeriodSeconds(tf)) && GetTickCount()-startCount<timeOut && !IsStopped());
   return(lastBarTime[0]>=TimeCurrent()-TimeCurrent()%PeriodSeconds(tf));
  }
Files:
 
Douglas Eiras:

Hi! Not yet..

I'm sorry, from your screenshot I can't find out where the problem is. I tried this code on my side and I got 100% true values. I need some information. I've edited your EA to get information about iTime[1], current time, connection and trade allowing. If you run this EA then post the screenshot.

#property strict
input ENUM_TIMEFRAMES     UseTimeFrame  = PERIOD_MN1;

void OnTick()
{
   string priceFormat=StringFormat("%%.%df",SymbolInfoInteger(_Symbol,SYMBOL_DIGITS));
   while (!Refresh(Symbol(),UseTimeFrame,1000) && !IsStopped()) Print("Waiting...");
   printf("iClose[1]="+priceFormat+" ; iTime[1]=%s ; TimeCurrent=%s ; Connected=%s ; Trade allowed=%s",
      iClose(_Symbol,UseTimeFrame,1),
      TimeToString(iTime(_Symbol,UseTimeFrame,1),TIME_DATE|TIME_MINUTES|TIME_SECONDS),
      TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS),
      string((bool)TerminalInfoInteger(TERMINAL_CONNECTED)),
      string((bool)MarketInfo(_Symbol,MODE_TRADEALLOWED))
      );
   ExpertRemove();
}

bool Refresh(string symbol=NULL,ENUM_TIMEFRAMES tf=PERIOD_CURRENT,const uint timeOut=1000)
  {
   if(symbol==NULL || symbol=="") symbol=_Symbol;
   if(tf==PERIOD_CURRENT) tf=(ENUM_TIMEFRAMES)_Period;
   datetime lastBarTime[1];
   uint startCount=GetTickCount();
   while((CopyTime(symbol,tf,0,1,lastBarTime)!=1 || lastBarTime[0]<TimeCurrent()-TimeCurrent()%PeriodSeconds(tf)) && GetTickCount()-startCount<timeOut && !IsStopped());
   return(lastBarTime[0]>=TimeCurrent()-TimeCurrent()%PeriodSeconds(tf));
  }

My screenshot:

Screenshot

 
Petr Nosek:

I'm sorry, from your screenshot I can't find out where the problem is. I tried this code on my side and I got 100% true values. I need some information. I've edited your EA to get information about iTime[1], current time, connection and trade allowing. If you run this EA then post the screenshot.

My screenshot:

Hi! First of all, thank you for your patience in helping.

I tried to use your code (I did not change anything, just copied and pasted), one of the times the EA spent almost 5 minutes writing "Waiting" in the log. The moment I removed the Expert manually the message appeared, with the right value. Are we close to a solution? I tried on weekly TF this time.

Files:
 
Douglas Eiras:

Hi! First of all, thank you for your patience in helping.

I tried to use your code (I did not change anything, just copied and pasted), one of the times the EA spent almost 5 minutes writing "Waiting" in the log. The moment I removed the Expert manually the message appeared, with the right value. Are we close to a solution? I tried on weekly TF this time.

OK. There was a bug in my last logic in a weekly and monthly period. I think and hope I've fixed it. Try it and let me know. BTW Inserting function Refresh() into another "while" loop isn't a good idea in my opinion because the function Refresh() contain a loop and you can set the maximum time by the parameter "timeOut".
#property strict
input ENUM_TIMEFRAMES     UseTimeFrame  = PERIOD_MN1;

void OnTick()
{
   string priceFormat=StringFormat("%%.%df",SymbolInfoInteger(_Symbol,SYMBOL_DIGITS));
   while (!Refresh(Symbol(),UseTimeFrame,1000) && !IsStopped()) Print("Waiting...");
   printf("iClose[1]="+priceFormat+" ; iTime[1]=%s ; TimeCurrent=%s ; Period=%s ; Connected=%s ; Trade allowed=%s",
      iClose(_Symbol,UseTimeFrame,1),
      TimeToString(iTime(_Symbol,UseTimeFrame,1),TIME_DATE|TIME_MINUTES|TIME_SECONDS),
      TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS),
      EnumToString(UseTimeFrame),
      string((bool)TerminalInfoInteger(TERMINAL_CONNECTED)),
      string((bool)MarketInfo(_Symbol,MODE_TRADEALLOWED))
      );
   ExpertRemove();
}

bool Refresh(string symbol=NULL,ENUM_TIMEFRAMES tf=PERIOD_CURRENT,const uint timeOut=1000)
  {
   if(symbol==NULL || symbol=="") symbol=_Symbol;
   if(tf==PERIOD_CURRENT) tf=(ENUM_TIMEFRAMES)_Period;
   datetime lastBarTime[1];
   uint startCount=GetTickCount();
   while((CopyTime(symbol,tf,0,1,lastBarTime)!=1 || lastBarTime[0]<PreviousPeriod(tf)) && GetTickCount()-startCount<timeOut && !IsStopped());
   return(lastBarTime[0]>=PreviousPeriod(tf));
  }

datetime PreviousPeriod(const ENUM_TIMEFRAMES tf)
  {
   if(tf==PERIOD_MN1)
     {
      MqlDateTime mqlDT;
      TimeToStruct(TimeCurrent(),mqlDT);
      if(mqlDT.mon==1)
        {
         mqlDT.mon=12;
         mqlDT.year--;
        }
      else
        {
         mqlDT.mon--;
         mqlDT.day=28;
        }
      return(StructToTime(mqlDT));
     }
   return(TimeCurrent()-PeriodSeconds(tf));
  }
 
Petr Nosek:
OK. There was a bug in my last logic in a weekly and monthly period. I think and hope I've fixed it. Try it and let me know. BTW Inserting function Refresh() into another "while" loop isn't a good idea in my opinion because the function Refresh() contain a loop and you can set the maximum time by the parameter "timeOut".

Hi! I tried again, on the daily chart and it happened again. The funny thing is that the timestamp came right, but the close value did not! Its so absurd! :|

Files:
 
Douglas Eiras:

Hi! First of all, thank you for your patience in helping.

I tried to use your code (I did not change anything, just copied and pasted), one of the times the EA spent almost 5 minutes writing "Waiting" in the log. The moment I removed the Expert manually the message appeared, with the right value. Are we close to a solution? I tried on weekly TF this time.

Due to the loops, at least add a Sleep(1) inside it.

Or don't use a loop at all. Check for error and wait next tick.

 
Douglas Eiras:

Hi! I tried again, on the daily chart and it happened again. The funny thing is that the timestamp came right, but the close value did not! Its so absurd! :|

It is strange. I thought if the iTime is correct then all data were refreshed. And on my side it works so. I've tried it many times and I always got correct result. Maybe you could try to add Sleep behind the loop.

void OnTick()
{
   string priceFormat=StringFormat("%%.%df",SymbolInfoInteger(_Symbol,SYMBOL_DIGITS));
   while (!Refresh(Symbol(),UseTimeFrame,1000) && !IsStopped()) Print("Waiting...");
   Sleep(50);
   printf("iClose[1]="+priceFormat+" ; iTime[1]=%s ; TimeCurrent=%s ; Period=%s ; Connected=%s ; Trade allowed=%s",
      iClose(_Symbol,UseTimeFrame,1),
      TimeToString(iTime(_Symbol,UseTimeFrame,1),TIME_DATE|TIME_MINUTES|TIME_SECONDS),
      TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS),
      EnumToString(UseTimeFrame),
      string((bool)TerminalInfoInteger(TERMINAL_CONNECTED)),
      string((bool)MarketInfo(_Symbol,MODE_TRADEALLOWED))
      );
   ExpertRemove();
}
 
Petr Nosek:

It is strange. I thought if the iTime is correct then all data were refreshed. And on my side it works so. I've tried it many times and I always got correct result. Maybe you could try to add Sleep behind the loop.

Hi! I tried with Sleep, but it didn't solve the problem.


I'm out of MT4, but thanks a lot for your help.

Reason: