amibroker

HomeKnowledge Base

Calendar day index

Someone asked me recently how to count calendar days (not bars) that passed since first available quote. Here is a sample formula that shows how to do that.



SetBarsRequired(1000000,0);

function 
TotalDays()
{
 
yy Year();
 
dy DayOfYear();

 
leapyear = ( yy ) == AND yy != 2000;

 
yearlen IIfleapyear366365 ); 

 return 
yearlen * (yy yy]) + (dy dy[0]); 
}


td TotalDays();

Plottd"TotalDays"colorRed ); 

This function can be used to create some new interesting functions, for example the function that returns the value of array X calendar days back. I call it RefDays() because the syntax is almost the same as Ref() but it just uses calendar DAYS instead of bars.
Note that the function for simplicity handles only PAST references (‘days’ parameter is negative).



SetBarsRequired(1000000,0);

function 
TotalDays()
{
 
yy Year();
 
dy DayOfYear();

 
leapyear = ( yy ) == AND yy != 2000;

 
yearlen IIfleapyear366365 ); 

 return 
yearlen * (yy yy]) + (dy dy[0]); 
}

function 
RefDays( Array, Days )
{
  
td TotalDays();

  
result Null;

  if( 
Days )
  {
     for( 
BarCount -1>= -Days)
     {
       for( 
0ij++ )
       {
          if( 
td] <= td] + Days )
          {
             
result] = Array[ ]; 
             
i
          }
       }
     }
  }
  return 
result;
}

PlotC"C"colorRed );
PlotRefC, -252 ), "Close 252 bars back"colorBlue );
PlotRefDaysC, -365 ), "Close 365 days back"colorGreen );

As above example shows referencing 365 calendar days back is not very different from referencing 252 trading EOD bars back, so for most applications it seems not worth the effort of using exact calendar day differences.

In the last example I want to show how to calculate number of calendar days in a range selected using begin/end markers (double click to mark begin and double click again to mark end).



function TotalDays()
{
 
yy Year();
 
dy DayOfYear();

 
leapyear = ( yy ) == AND yy != 2000;

 
yearlen IIfleapyear366365 ); 

 return 
yearlen * (yy yy]) + (dy dy[0]); 
}

td TotalDays();

Title "Number of days in selected range = " + ( EndValue(td) - BeginValue(td) );

5 Responses to “Calendar day index”

  1. Cam
    March 28th, 2007 | 9:43 pm

    TJ, the code above creates an error message on the following line:

    for( i = BarCount -1; i >= -Days; i– )

  2. March 29th, 2007 | 3:37 am

    It is this “wordpress” changing the letters. Argghh… should be i – – (i minus minus)

  3. Mark
    June 2nd, 2007 | 9:05 pm

    Thanks for this Tomasz. How can the code below be altered to show trading days as well?

    “In the last example I want to show how to calculate number of calendar days in a range selected using begin/end markers (double click to mark begin and double click again to mark end)”

  4. GP
    June 7th, 2007 | 5:55 pm

    There seems to me to be a slight problem with the leap year calculation here. The statement yearlen*(yy-yy[0]) multiplies all previous years by the number of days in the current year, so on leap years, all previous years are assumed to have had 366 days. This is going to make TotalDays return a few more days than it should on leap years, and a few less days than it should on other years, once yy-yy[0] has spanned a few leap years. It would not make much difference to RefDays though unless the number of days was large (multiple years).

  5. GP
    June 11th, 2007 | 2:45 am

    Here’s a version of TotalDays that handles leap years correctly:

    function TotalDays()
    {
    yy = Year();
    dy = DayOfYear();
    LastLeapYear = (yy % 4) == 1 && yy != 2001;
    YearChg = yy != Ref(yy, -1);
    YearChg = IIf(IsNull(YearChg), False, YearChg);
    YearLen = IIf(YearChg, IIf(LastLeapYear, 366, 365), 0);
    return Cum(YearLen) + dy – dy[0];
    }

Leave a reply