Download MetaTrader 5
To add comments, please log in or register
What is a social trading? Read the article to find that out!
sunshineh
1076
sunshineh 2016.10.25 07:02 

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);
rod178
274
rod178 2016.10.25 08:27  
Print(iOpen(Symbol(),PERIOD_MN1,iBarShift(Symbol(),PERIOD_MN1,StringToTime("01.01.2016")+PERIOD_W1*60)));
whroeder1
14236
whroeder1 2016.10.26 19:13  
  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
Keith Watford
Moderator
9543
Keith Watford 2016.10.26 21:11  

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;
       }
     }

.

Fernando Carreiro
2235
Fernando Carreiro 2016.10.26 21:26  
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?

Keith Watford
Moderator
9543
Keith Watford 2016.10.27 02:34  
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

Fernando Carreiro
2235
Fernando Carreiro 2016.10.27 02:58  
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).

Keith Watford
Moderator
9543
Keith Watford 2016.10.27 05:19  
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.

rod178
274
rod178 2016.10.27 05:57  

  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

/
To add comments, please log in or register