iBarShift first price every YEAR

 

Hi,

how can I get the first price of every YEAR out of my D1-Quotes?

I tried something like that, but it isn't working

datetime tm = StringToTime(StringConcatenate("D'",TimeYear(iTime(NULL,PERIOD_M1,i_mn1)),".01.01 00:00'"));
iLastClose = iBarShift(NULL,PERIOD_D1,tm);
 
Print(iOpen(Symbol(),PERIOD_MN1,iBarShift(Symbol(),PERIOD_MN1,StringToTime("01.01.2016")+PERIOD_W1*60)));
 
  1. sunshineh: I tried something like that, but it isn't working
    datetime tm = StringToTime(StringConcatenate("D'",TimeYear(iTime(NULL,PERIOD_M1,i_mn1)),".01.01 00:00'"));
    iLastClose = iBarShift(NULL,PERIOD_D1,tm);
    Of course not. D'2016.01.01 is a constant interpreted by the compiler. Read the documentation. StringToTime requires a string formated "YYYY.MM.DD HH:MM" and "D'...'" doesn't fit.
    datetime when = TimeCurrent();
    datetime first = StringToTime( (string)TimeYear(when) + ".01.01 00:00");
    iLastClose = iBarShift(NULL,PERIOD_D1,first);

  2. rod178: shift(MN1)
    Sorry Rod, that solution means you have to handle errors 4066/4071
 

I don't know if this is the best solution

   int year=TimeYear(Time[0]);
   for(int index=1;index<Bars;index++)
     {
     int bar_year=TimeYear(Time[index]);
     if(year!=bar_year)
       {
       Print(TimeToStr(Time[index-1])," Open Price=",DoubleToStr(Open[index-1],Digits),", Shift=",index-1);
       year=bar_year;
       }
     }

.

 
GumRai: I don't know if this is the best solution

If it were for MQL5, where there is no built-in iBarShift function, I could understand your approach, but in MQL4 the iBarShift function does exist, produces less code and is probably faster to execute as well.

So, I have to ask - is there a particular reason, that I am not aware of, for the solution you present as an alternative to iBarShift?

 
FMIC:

If it were for MQL5, where there is no built-in iBarShift function, I could understand your approach, but in MQL4 the iBarShift function does exist, produces less code and is probably faster to execute as well.

So, I have to ask - is there a particular reason, that I am not aware of, for the solution you present as an alternative to iBarShift?

I don't know about speed, but I imagine that any differences in speed would be negligable.

Although it is probably certain (in this case) that using iBarShift will return the last day of December, generally when searching for the shift of a particular time, iBarShift may have to be called twice. The first time with bool exact. Then the result must be checked etc.

I wrote a test script

void OnStart()
  {
   uint tc=GetTickCount();
   
   int year=TimeYear(Time[0]);
   for(int index=1;index<Bars;index++)
     {
      int bar_year=TimeYear(Time[index]);
      if(year!=bar_year)
        {
         Print(TimeToStr(Time[index-1])," Open Price=",DoubleToStr(Open[index-1],Digits),", Shift=",index-1);
         year=bar_year;
        }
     }
   uint tc2=GetTickCount();
   
   year=TimeYear(TimeCurrent());
   while(true)
     {
      datetime first=StringToTime((string)year+".01.01 00:00");
      int shift=iBarShift(NULL,PERIOD_D1,first,true);
      if(shift==-1)
         shift=iBarShift(NULL,PERIOD_D1,first,false)-1;
      if(shift>=iBars(NULL,PERIOD_D1)-2)
         break;
      Print(TimeToStr(iTime(NULL,PERIOD_D1,shift))," Open Price=",DoubleToStr(iOpen(NULL,PERIOD_D1,shift),Digits),
            ", Shift=",shift);
      year--;
     }
   uint tc3=GetTickCount();
   
   Print("TickCount 1=",tc2-tc);
   Print("TickCount 2=",tc3-tc2);
   Print("Total TickCount=",tc3-tc);


  }

and the tick count for both was 0 so less than 1 millisecond

 
GumRai: I don't know about speed, but I imagine that any differences in speed would be negligable. Although it is probably certain (in this case) that using iBarShift will return the last day of December, generally when searching for the shift of a particular time, iBarShift may have to be called twice. The first time with bool exact. Then the result must be checked etc.

I wrote a test script and the tick count for both was 0 so less than 1 millisecond

You could still use iBarShift only once with non-exact search and if it happened to be the last day of the previous year, all one would need to do is use the adjacent index (shift - 1).

 
FMIC:

You could still use iBarShift only once with non-exact search and if it happened to be the last day of the previous year, all one would need to do is use the adjacent index (shift - 1).

Whichever way it is done, it still involves checks

Anyway, I added some extra loops and you are correct, the iBarShift code is faster.

 

  1. Sorry Rod, that solution means you have to handle errors 4066/4071

 

True, although I merely suggested the simplest solution.

Also, checking whether or not the required Monthly data exists, either manually or via code, would solve any potential issue, such as 4066

My assumption would be that if Daily data existed then so would the Monthly.  

Actually the Monthly would usually be more available, going into the distant past than the Daily. 

 

The slightly more involved solution would be to test whether or not the Trading day is 'active'  eg 01 Jan obviously not.

There are also potential issues with that solution, eg data gaps, which require some error checking  and introduce additional complexity.

All require iBarShift imho

Reason: