Tuesday, March 06, 2007

YFQuoteRTD - A Real Time Data Service for Excel

A while back I wrote a little Excel add-in in VBA that pulled back quotes from Yahoo Finance. One of its major draw backs was that it was quite slow and each time you wanted to get updated quotes you had to recalculate the sheet which could take quite a while depending on the number of quotes you were trying to retrieve. The reason for this is that Excel (pre 2007) is single threaded so each quote has to be retrieved in sequence. Yahoo Finance's website can take up to a couple seconds for each request so it was not unusual for Excel to be frozen for up to 30 seconds when trying to pull back 10-20 quotes. Anyone who has used the Reuters suite of Excel add-ins will know that functions like RtGet() do not suffer this problem. They return control of Excel to user immediately after they are called giving a value such as '#NA #NA' and after a number of recalculations the quotes start coming in. This is the sort of behaviour the YF_Price function in the YFQuote add-in really needs.


Real Time Data Servers

A Real Time Data server or RTD is a COM component that implements the Excel.IRTDUpdateEvent interface. They are called from Excel via the RTD function as follows:

=RTD(RTD CLASS, SERVER, PARAM1, PARAM2, PARAM3,...)

The second argument is optional and can be used to call an RTD server on a remote host via DCOM (details) but for our purposes we will be calling a local RTD server so it can be left blank.


How It Works

The RTD behaves a bit like an asynchronous function - Excel calls the RTD server with the specified parameters and the RTD server immediately returns control to Excel. In the background the RTD server is now free to do its own processing and once it has a suitable value to return, it notifies Excel which updates the cell.

Functionally the RTD server is a bit more complicated than your standard asynchronous function as you only get one instance of a particular RTD server per Excel session. This means that this single instance has to be able to handle being called from more than one cell at a time and with different parameters and is achieved by abstracting the parameters as topics.

Each unique set of parameters constitutes a topic to which Excel assigns a numerical ID. When data is first requested, the parameters along with the topic ID are passed to the RTD server which must store them internally so that when updates are passed back to Excel they can be associated with the correct "topic".

The process flow looks like this:
  1. The RTD server is initialized (this only happens once per Excel session).
  2. A topic (a unique set of parameters) is connected to the RTD server which stores this data internally, calls a method to get the quote asynchronously and immediately returns a dummy value to Excel.
  3. Once the asynchronous call returns it notifies Excel that there is an updated value available.
  4. Excel calls the RefreshData method with returns an array containing the full list of topics associated with the RTD plus the corresponding value as a two dimensional array.
  5. Excel updates the cells and recalculates.
The functions defined in the Excel.IRTDUpdateEvent are:
  • ServerStart (effectively the constructor and called only once) - passes the callback to Excel.
  • ServerTerminate (effectively the destructor and called only once).
  • ConnectData - passes a new topic plus the associated parameters.
  • DisconnectData - called when a particular topic is no longer required (e.g. the user has deleted a particular =RTD() function from a cell).
  • Heartbeat - called by Excel to check that the RTD server is still alive.
  • RefreshData - called by Excel when the RTD server calls callback.UpdateNotify() and should return a two dimensional array of topicID,Value plus set the updated topic count value that is passed in by reference.

YFQuoteRTD

YFQuoteRTD uses the process flow and functions described above along with a WinAPI timer to periodically refresh the quotes. Each time the timer ticks it loops through the available topics and fires an asynchronous call to get the quote for that topic. Each asynchronous call has a callback function specified that notifies Excel that an updated quote is available.

Both binaries and source code are available. The source code can be compiled with Visual C# Express which Microsoft has made freely available.

Downloads

Binary
Source

40 comments:

Liam said...

Really awesome Frans. That's a very good job you,ve done there.

Liam said...

I was just wondering...maybe I'm asking too much but wouldn't there be a way to get historic quotes too?

Frans King said...

Yes it is possible but you wouldn't want to use the RTD for this as the data isn't ticking intraday.

You could either code this functionality up as an XLA similar to the YF_Price functions or alternatively write an automation addin for Excel.

I'll try and post an example of the latter shortly. FYI the URL to use is http://ichart.finance.yahoo.com/
table.csv?s=GE&a=00&b=2&c=1962
&d=02&e=13&f=2007&g=d&ignore=.csv

LIam said...

Well, what I'd need would just be a function like the YF_price with variables (ticker, date) and it goes to pick the price of this stock at this day.

But since I might end up with a lot of tickers, I don't want to slow down the spreasheet more than it already is so the strcuture of the YF_Price wouldn't fit.


Anyway I really wish to thank you for the job done here.

Frans King said...

I see what you mean - something like:

=RTD("...RTD","","GOOG","CLOSE","01/01/07")


I was also wondering if some analytical functions might be useful. E.g. give me the correlation between two stocks from date1 to date2 or give me the realized volatility between date 1 and date 2.

Liam said...

Well I don't know about the volatility (I don't use this as a main investment criteria), but you exactly understood what I meant for the historical prices.

Frans King said...

I should have something out today. I'll put another post up when I do.

If you think of anything else that would be useful let me know.

Narayana said...

Dear Frans,
I installed the program after down-loading it from
http://fransking.blogspot.com/2007/03/yfquotertd-real-time-data-service-for.html
It is working fine. This is really a very useful program.
Now, the quotes are updated once in 5 minutes. Can I make it once in 30 sec or 1 min? How to do it?

Also, can we not import the date/time stamp of each quote into MS Excel from the RTD server?
Is there a way of saving all the different RTD values with date/time stamps in a work sheet so that I can plot graph using this for doing technical analysis in Real Time (or quasi real time!)?

Hope I am not bothering you with too many questions.

Regards,

Narayana R
Mumbai, India
Mobile: +91 9322592580

Frans King said...

Narayana,

The reason for the 5 minute delay is because each unique TICKER,FIELD combination is handled as a separate request to Yahoo Finance. What I could do is group these up behind the scenes so that the RTD gets all fields for a particular ticker in one go and places them in a cache. I could then extend this further to allow multiple tickers to be retrieved in one query which would then allow for faster polling times.

As for timestamps and getting an intraday price history. You could do this in VBA by listening for the worksheet_change event and then copy the resulting RTD value to a new row each time along with a timestamp in the next column:

[RTD]

[Quote1],[Timestamp]
[Quote2],[Timestamp]

etc.

JYC said...
This post has been removed by the author.
Jagercola said...

With the ability to pull in historical quotes, YFQuoteRTD will be a great solution!

Thanks for the great work!

Frans King said...

For those of you wanting higher ticker counts and historical prices check out http://fransking.blogspot.com/2007/05/yf-quote-new-batch-mode-historic-prices.html

Don said...

Frans,

YFQuoteRTD is great!

Any way that you would share the source code for the latest version?

Thanks.

John V said...

Just what I needed. But y'know how good software seems to leave you wishing for more of the same? I found myself wanting other Yahoo variables such as Name, 52-week highs and lows etc.

Frans King said...

John, I'm going to release a new version shortly which is extensible as far as the yahoo fields go.

Daniel said...

Hi,

I am using your excellent add-in, but I get an error:
"The operation timed out" from the line
xmlClient.send("");
Any idea what the problem is?

Anonymous said...

Hi Frans,
In addition to my previous question, if I change the call to setTimeouts to the following call:
xmlClient.setTimeouts(100000, 200000, 300000, 400000);
I am getting the following error:
"A connection to the server cannot be established".
Any help on this would be appreciated. Thanks.

Anonymous said...

Hi Frans

I tried to install it and I got registration errors (below). Any idea how to fix it?
I have downloaded all files in a single directory.

Thanks
Jon

Microsoft (R) .NET Framework Assembly Registration Utility 2.0.50727.42
Copyright (C) Microsoft Corporation 1998-2004. All rights reserved.

RegAsm : warning RA0000 : Registering an unsigned assembly with /codebase can ca
use your assembly to interfere with other applications that may be installed on
the same computer. The /codebase switch is intended to be used only with signed
assemblies. Please give your assembly a strong name and re-register it.
RegAsm : error RA0000 : Could not load file or assembly 'Microsoft.Office.Intero
p.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' or
one of its dependencies. The system cannot find the file specified.
Press any key to continue . . .

Frans King said...

For those having difficulty getting YFQuoteRTD to work, I strongly recommend you download and use YFQuote. This has the RTD functionality built in as well as normal UDFs for access Yahoo Finance data.

Emma said...

Hi Frans,
We are trying to use RTD fro our own app and came across your blog whilst searching for more info.
I wonder if you could tell me - when you say "The RTD server is initialized (this only happens once per Excel session)." by session do you mean excel instance - i.e. if we have two spreadsheet open in the same excel instance do they talk to the one RTD server? I assume the answer to this is yes. If so any idea how we could load one RTD server per spreasheet?
Thanks, Emma.

Frans King said...

Hi Emma,

Excel will only ever create a single instance of the RTD server per session of Excel. You can have lots of different RTD servers but you will still only get one instance of each. I don't think it is possible to make Excel instantiate one for each sheet nor can I see why you would want this behaviour.

Anonymous said...

Great idea and very useful!
I'm not a c# programmer, but only a veteran excel user. Once I have the bin file - what do I do to get excel to identify the formula?

Thank you very much
Eli

Frans King said...

Hi Eli,

You should download and install YFQuote which has the RTD and more.

There are installations instructions in the INSTALL.TXT file plus some example spreadsheets.

Don said...

Any ideas why ^DJI would stop producing quotes whille all others are working fine?

Thanks.

Don

Frans King said...

Hi Don,

Are you using YFQuote or YFQuoteRTD? There are some bugs in YFQuoteRTD so I would recommend upgrading. See the link in the comment just above yours.

Don said...

Hello Frans,

Yes, I am using YFQuote. Even the ^DJI entry in your RTDexamples.xls has stopped working. Very strange. It has all been working fine for the past 6 months.

Don

Frans King said...

The reason is because Yahoo Finance can't seem to keep their interface the same from one day to the next.

The url I am using to pull back quotes now doesn't return anything for ^DJI but does for everything else?!

I'll see whether this is an temporary issue on their side but if not I will need to build up some "exception" logic for tickers with funny behaviour.

Don said...

Frans,

I thought that might be the case. Thanks for looking into it.

Don

Mark Miller said...

I have been looking at this and must be honest, it has only been a couple of days and looks like it will require a few hours to get up to speed with the requisite programming as I haven't done it in a while.

I have a PC that have a link to an RTD that is constantly updating info in a spreadsheet, however this is only available on one specific PC. Is is possible to create an RTD to then take this information and broadcast it live over a network that other PCs can access, so the others update as it updates, with minimal delay between the two.

Basically an extension of your program, where one PC gets the data from the net and broadcasts to other PCs connected to that server. If it is possible (which I assume it is), could anyone advise on some good text available on how to build it

pallavi said...

tickers dictionary is getting updated in conectdata() and is used in the timer callback function to read. I believe timer callback would occur in a separate thread. In this scenario, don't you have to synchronize the tickers dictionary?

Frans King said...

Yes it should have a lock on it or a sync object if it doesn't already.

I'd use YF Quote (see newer posts) rather which is thread safe.

Anonymous said...

Hi,

When I try installing this program it is giving me an error "RegAsm: error RA0000: Unable to locate input assemply 'YFQuoteRTD.dll' or one of its dependencies. Do you have any idea how to correct this in order to successfully install this? Any help would be much appreciated.

Shan said...

try www.greenturtle.us for a free real time quote addin for excel implemented as RTD server. tons of configuration options.

richard53 said...

richard53

your answer to a previous question from anonymous was this
For those having difficulty getting YFQuoteRTD to work, I strongly recommend you download and use YFQuote. This has the RTD functionality built in as well as normal UDFs for access Yahoo Finance data.

I am having the same prob -- being a novice to excel -- how does one get YFQuoteRTD to work in YFquote?

I did get YFquote working. now I just want to have the quotes updated. the only data I need from the quote is the last price of the equity

kesk said...

I tried the Ver1 and it doesnt work at all. I get #NA for the all the fields. I am not using anything new, trying with the existing Fields themselves. But not one is working. I have .Net2 installed, no other issues. Could this because of the URL is different from the current one ?
thanks
kesk

Anonymous said...

When I run instal i get this message:

Microsoft (R) .NET Framework Assembly Registration Utility 2.0.50727.1434
Copyright (C) Microsoft Corporation 1998-2004. All rights reserved.

RegAsm : warning RA0000 : Registering an unsigned assembly with /codebase can ca
use your assembly to interfere with other applications that may be installed on
the same computer. The /codebase switch is intended to be used only with signed
assemblies. Please give your assembly a strong name and re-register it.

RegAsm : error RA0000 : An error occurred while writing the registration informa
tion to the registry. You must have administrative credentials to perform this t
ask. Contact your system administrator for assistance
Press any key to continue . . .

Sucks when your own computer tells you that you dont have credentials... Im using Vista Home (32bit) and excell 07. Any suggestions.

Robin Hood said...
This post has been removed by the author.
Robin Hood said...

Hi Frans,
Great add-in thanks. I've been using it quite a bit recently, but today I'm getting the dreaded "#N/A" when I try to pull any live prices. Maybe a problem with Yahoo?
Thanks

Robin Hood said...

Please ignore, all working now. I had made a mistake. Thanks again for the add-in.

goncalvm said...

Hi Frans,

Could you post the download link again? It seems is not working anymore.

Tks

Marco

Post a Comment