Get Last DateTime Stamp from Database

Hi

I've got a local database that stores hourly data for a variety of instruments. I'm trying to get the last DateTime stamp from the hourly database to use in some data retrieval from my provider.

My idea is to setup a ParamTrigger in parameters (and later perhaps a GUI button) that when pressed will run some AFL to get the latest hourly data from my provider. All is working fine except that I cannot retrieve the datetime stamp of the last hourly bar in the database.

My current AFL is using LastValue( DateTime() ) in the ParamTrigger part of the code but if it's selected in a daily chart then it returns the datetime stamp of the last daily bar (which for me is 20181112 00:00:00). If I'm in a 12 hourly chart then it returns the datetime stamp of the last 12 hourly bar (which at the moment is 2018112 17:00:00) even though the last hourly bar might have a datetime stamp of say 20181112 14:00:00.

I've also tried using EndValue( DateTime() ) but it returns the same results. Experimented with TimeFrameSet/Restore but that hasn't helped either (but that could be because I don't know what I'm doing).

Is there a method or some AFL code I can run to always return the datetime stamp of the LAST bar in my hourly database no matter which type of chart it's called from. Ultimately I'd like it to return "20181112 14:00:00" based on my example above regardless of whether it's trigger from a daily, 12 hourly or 3 hourly chart.

If anyone's got any ideas I'd be very grateful if you could share.

Many thanks

Craig

The Default is START time of interval.

Goto Menu > Tols > Preferences > Intraday
Change to "time of LAST tick Inside bar"

1 Like

Relying on changed (non-default) preferences is not recommended.

If you are using real time data source you can use Status function:

http://www.amibroker.com/guide/afl/status.html

// example
Status("lastrtupdate");

Other possibilities:

  • "lastbarend" - returns DateTime of the end of last bar. For example 5 -minute bar at 9:00 will have end time of 9:04:59 (works for time-based bars only) (v5.60)
  • "lastbartimeleft" - returns number of seconds to the completion of current last bar. Works for time-based bars only. Note that for proper operation this requires database timeshift to be set properly (so dates displayed on chart match your local computer time zone). (v5.60)
  • "lastbartimeleftrt" - it works like "lastbartimeleft" but uses the most recent RT stream update time instead of Now(). Also added Status("lastrtupdate") - time of last RT stream update Depends on RT plugin to deliver correct DateUpdate / TimeUpdate data. If plugin or date source sends incorrect datetimestamps or does not send DateUpdate/TimeUpdate correctly this function will not operate properly. Note that most data sources send weird (not current) datetime stamps on weekends. Also IQFeed plugin sends DateUpdate/TimeUpdate only inside regular trading hours. (v5.60)
  • "lastrtupdate" - returns date time of last update sent by RT plugin (see remarks above) (v5.60)
4 Likes

I probably should have been a bit more clear in my original post. I'm not using a RT data source. I'm able to download data from my provider and I'm importing it into the local database.

I tried the Status("lastbarend") but it didn't return the datetime of the last hourly bar in the database (no doubt because I'm not using a RT data source).

Is there anything else I can whip up in AFL that will permit me to retrieve the datetime stamp of the last hourly bar I have in the local database? I'm a bit stumped with this one. Been racking my brains for days.

Did you try the option I suggested to atleast get the LAST Tick bcos it does it very well.
Especially for non-RT local DB.

I didn't mention, which Tomasz correctly pointed out, it won't do any harm but you should be carefully using it as it may break other formulas written that may be designed on START time of bars etc
so far, with All built-in AB functions, i've never had any problems.

This worked very well when I had to scrape data from some different sources.

Yeah I did try that - it gives me results like Tomasz documented above but if I was in a daily chart it gave the last time of the daily, similarly for 12 hourly, 3 hourly. I really just want to get the datetime stamp of the last hourly bar that's in the database regardless of which chart I'm in. I just can't figure out a way to do that.

A picture tells a thousand words so they say …

image

I just want to get the datetime of the highlighted quote using AFL somehow.

Cheers

Craig

There is something definitely different that you are doing which is not obvious.

Firstly, Time resolution is one way going up, that is, a 3H a chart or a 12H chart can't Look into hourly.

While writing this post, I'd sensed the problem and that is why thought of mentioning the Intraday LAST Tick change in settings. This has to work.

Now, can you take out some time and post the code that you are using to test, whether its in the chart or AA. What is the Interval().
Post the DB settings, and any other changes if you've made to the defaults.

Also, post snaps of the output you get, and debug output etc if its there.

OK - think I may have stuffed up my initial testing. Apologies.

I've gone into Tools | Preferences | Intraday and selected "Time of LAST tick inside bar" …

image

My very simple test is to printout the datetime stamp above every bar on the chart using the following AFL …

PlotTextSetFont( "DateTime " + DateTimeFormat( "%Y%m%d %H:%M:%S", LastValue( DateTime() ) ), "Tahoma", 8, i, H[ i ], colorGreen, colorDefault, 450 );

Low and behold I'm now getting the datetime stamp of the last hourly bar. This is good.

image

image

I've never used "time of LAST tick inside bar" before. Usually I've just had the defaults of "time of FIRST tick inside bar". Is there any downside to making that change? Something I should be looking out for?

Many thanks for you help

ok Good, I thought so.

As I've mentioned in above post, it has worked very well with AB and all AFL that comes along with it.

For your own formula or 3rd party ones, just have to make sure they haven't hardcoded anything that works or checks a condition based on fixed time.

For example, in a 5min chart, at time 13:20:00
START Time: LastValue( DateTime() ) after formatting would return 13:20:00 for the whole period of the bar, whereas,
LAST Tick: would keep updating with last time,

so just make sure Time isn't hardcoded anywhere or certain counting using ValueWhen() etc

Edit: Also, just check that reverting back to Default START Time doesn't serve the purpose and all this wasn't because of some other issue.

Yeah I was just doing some checks and changing that setting to LAST tick has stuffed up some automatic trendlines that I'm drawing via AFL. I'll have to look into that and see why it's causing problems.

And from memory I'm using a lot of ValueWhen() in my code :frowning:

I've set it back to the AmiBroker defaults and all my broken stuff is fixed again …

image

I might try and work out another way to get that datetime stamp I'm after.

For what it is worth I've sort of stumbled across a solution to my problem. Posting for the benefit of anyone else that might think like me :wink:

The reason I was trying to find out the last timestamp of the hourly data in my database was to use that date to retrieve hourly bars from my provider since that date. It would make my retrieval just that little bit more efficient. What I didn't notice was that the LastValue( DateTime() ) for higher timeframes which I tend to look at was OLDER than the latest hourly data as I've set my preferences as above to have Intraday data set to "START time of interval (recommended)". So if I'm looking at the 12 hourly chart and I press my button to retrieve data from my provider it uses the LastValue( DateTime() ) for that period which is older than the hourly data. What I hadn't contemplated is "who cares". Basically I'm submitting a request to my provider with more historical data than I require. When I import that extra historical data (which is already in the AmiBroker database) AmiBroker just deals with it. Doesn't create duplicates.

So I've got a workaround but I'm still on the hunt for getting that last timestamp for the hourly data. I'll put it on my list of "Things to Do"!

Thanks to all that responded.

Cheers

Craig

1 Like

There are a few elegant ways of doing it still.
In your case, you didn't discuss your setup elaborately. It was more about the date/time itself.

By logical design of AB, Timeframes can be worked in correct multiple going up.
That is why ideally for example, people prefer the 1 min timeframe for intraday.

You can extrapolate any higher TF from it, like 2m, 12m, 59m and so on.

Another pointer in your case which comes to my mind is very simple and can be part of the automation so nothing manual required.

Simply use the COM/OLE of AB and get datetime of last quote.
Whole doc is here https://www.amibroker.com/guide/objects.html

The object can be called from within AFL or your own application or other bit of code or JScript file running on a timer or a scheduled Task etc, but a pseudocode is like this:

// Create object
var oAB      = new ActiveXObject("Broker.Application");

// Get Stocks
var oStocks      = oAB.Stocks;

// Do a one time search and get the ordinal number of reference Symbol
i = 10;    // example
oStock = oStocks( i );    // or just find it by name property etc

// Get Total Bar count, adjust to zero base.
j = oStock.Quotations.Count - 1;

// That's datetime of last quote
tmpDateNum = oStock.Quotations(j).Date ;

This is part of JScript code used to delete quotes but can used to do anything.

3 Likes

I never thought about using OLE to get the information. That should fit in nicely with an external node.js script I've written to retrieve the data from my provider.

I'll give it a whirl and let you know how I go.

Thanks again for all the help

Just a hint, you can use actual symbol name in the oStocks call:

oStock = oStocks("MSFT"); // instead of ordinal number

Also it can be done directly from AFL, but you need version 6.30 to read Date field since it is in MS OLEDATE format and only 6.30 is able to auto-convert it to text:

Version( 6.30 );
Ab = CreateObject("Broker.Application");
stk = ab.Stocks(Name());
qts = stk.Quotations;
qty = qts.Count;
qt = qts.Item( qty - 1 );
Title = "Last DB timestamp is " + qt.Date;
8 Likes

Excellent - I'll keep an eye out for when 6.30 becomes an official release.

Thanks

Craig

6.30 is already official,
http://www.amibroker.com/download.html

OK - upgraded to 6.30 and the above is working a treat. Just what the doctor ordered. Thanks for everyone's assistance. Learnt a few more things this time round. :smiley:

2 Likes