How do I correctly obtain date / time of a given bar that is comparable

Hello

After browsing through the ADK documentaion, I have found more than one way to obtain dates and they are enumerated here. Ideally I want one function that returns me date value that is comparable wtih one another and code is not cumbersome to use / debug. These are following approaches tried
thus far.

Approach one: Use gSite.GetDateTimeArray

unsigned long long *dateArray = gSite.GetDateTimeArray();

The values that I get are typically like 19 digit numbers but I am unable to find any documentation on how to use them. They seem comparable, but are they?

9090133071771992064 supposedly represents 13:14 on 19 June 2018 but how to translate this back and forth.

This had seemed to be the most promising approach but stumped for my inability to find proper documentation

Approach two: Use gSite.CallFunction and retrieve values of built in AFL function, DateTime

Amivar dateTimeArray = gSite.CallFunction("DateTime", 0, NULL);

Again values returned are typically 19 digit numbers and I did find article about how amibroker fits datetime in 4 bytes whereas Microsoft took 8 bytes.

Put this approach to rest after the DateTime documentation clearly says that this values are not directly comparable and one is meant to use DateTimeDiff function

Approach three: Use gSite.CallFunction and retrieve values of built in AFL function, DateNum and TimeNum.

Discounting the absence of century in datenum, this is by far the easiest approach

Approach four: Use gSite.CallFunction and retrieve values of built in AFL function, Year, Month, Day, Hour, Minute, Second ... etc....

This approach works OK but it is cumbersome (and definitely slow) to compare two sets of date.
One another anomaly that I noticed is that array holding Seconds often contain values other than zero. Chart time frame (and database resolution) both are 1 minute. Could this be reason for Seconds array to have inappropriate values?

Use Approach 1. See the ADK Plugin.h header file. There you will find description/definition of 64-bit date time structure (AmiDate/PackedDate). Once you do this, you will easily find fields for seconds, minutes, hours, etc.

2 Likes

Hello Tomasz

Thanks. That worked like a charm. I looked all over the google and help document but did not scroll into the .h file that was sitting right before me. My mistake!

Setting the date in AmiDate variable unravels the encoding.

Few more sub-questions

Q1) Will time data present returrned by GetDateTimearray() correspond exactly to a bar? i.e. if user has selected interval as hourly, I'd expect minute and seconds to remain zero.

Q2) To correctly compare two AmiDates to obtain "greater than" "less " resulttant states, I would have to compare all of the elements of PackDate in inverted manner i.e. year, month, day, hour, minute, second.... ?

Q3) If I wanted to store AmiDate into a Static variable from the Plugin, how would I do it?

1 Like
  1. Yes

  2. As you might noticed 64-bit datetime can be treated as struct or as just 64-bit integer. It is defined so, when you treat it as integer you can do normal comparisions >, <. = and they all work correctly so there is no need to compare fields, just compare one 64-bit integer to another.

  3. gSite.CallFunction("StaticVarSet"....)

2 Likes

AmiDate is 8 byte structure and staticvarset accepts AmiVar which is combination of 4 bytes for type and 4 bytes for value or pointer to float or pointer to string.

That is true. You can't use AmiDate directly for that purpose. You need to use function like _DT() or StrToDateTime to generate 32-bit float representing value that you could pass as argument to CallFunction.

2 Likes
struct PackedDate {
    // lower 32 bits
    unsigned int IsFuturePad : 1;   // bit marking "future data"
    unsigned int Reserved : 5;     // reserved set to zero
    unsigned int MicroSec : 10;    // microseconds    0..999
    unsigned int MilliSec : 10;    // milliseconds    0..999
    unsigned int Second : 6;       // 0..59

    // higher 32 bits
    unsigned int Minute : 6;       // 0..59                       63 is reserved as EOD marker
    unsigned int Hour : 5;         // 0..23                       31 is reserved as EOD marker
    unsigned int Day : 5;          // 1..31
    unsigned int Month : 4;        // 1..12
    unsigned int Year : 12;        // 0..4095
};

// 8 byte (64 bit) date time stamp
union AmiDate {
    DATE_TIME_INT Date;
    struct PackedDate PackDate;
};

int main() {
    // set date and time values
    AmiDate dt;   
//dt.Date = 9090133071771992064 ;   // value specified by other user in post.
    dt.Date =  9111489710752006166; //value  to check reverse conversion 
    
	/*
    dt.PackDate.Year = 2023;
    dt.PackDate.Month = 2;
    dt.PackDate.Day = 16;
    dt.PackDate.Hour = 14;
    dt.PackDate.Minute = 30;
    dt.PackDate.Second = 0;
*/

    // retrieve date and time values
    printf("Year: %d\n", dt.PackDate.Year);
    printf("Month: %d\n", dt.PackDate.Month);
    printf("Day: %d\n", dt.PackDate.Day);
    printf("Hour: %d\n", dt.PackDate.Hour);
    printf("Minute: %d\n", dt.PackDate.Minute);
    printf("Second: %d\n", dt.PackDate.Second);
    printf("Date: %llu\n", dt.Date);

    return 0;
}

image_2023-03-01_082128727

Has dt.Date correctly stored data as per output ?
Is this correct way to see datetime() array data held in it's element ?
How do I see it in watch window of AFL ?

Re read the thread from the beginning. AFL does NOT use this format. It is internal use only (only data plugins use that)