The data model specifies how the the data is represented internally by the platform. QuoteLink uses a tree consisting of nodes which have one or more leafs each leaf may contain other nodes. A data provider for instance is represented by a node whose leafs are symbols, each symbol has a number of Node fields.
Here is how it looks using C#
using System; using qlnet; ... Link l = new Link(); Node node = l.Request('CSCO', 'IQ'); for each field in node { //...do something
Here is a full working example using IronPython.
import clr clr.AddReference("qlnet") from qlnet import Link from qlnet import Node ql = Link() for symbol in ['CSCO', 'IBM', 'SUNW']: n = ql.Request(symbol, 'MSN') for field in n: print field.Name, field.Value
These statements look natural for users of those languages because they use standard collections methods properties and those languages offer a easy and natural ways to access that data.
Typicaly most programs will use an API function to request data from the platform and once the data is available they will access it using the collections methods. There are two modes of requesting data: the synchronous way and the asynchronous way. The best method mode depends on the application. The synchronous method is the simplest to use as the word synchronous implies you request the data and the caller function waits that the answer comes back before returning.
The asynchronous method works in 3 phases:
If a symbol is already being monitored by some other application the answer is almost instantaneous because QuoteLink has it in its internal cache if the symbol has never been request however there is a delay while the request goes though the internet and comes back.
When using the asynchronous mode QuoteLink uses Node events to notify that the data is available.
Nodes can be 'read' and 'written' and 'watched'
you read a node when you read its value or by directly from its parent.
... v = n.Value k = n.Name // gives the name (or key) of the Node p['LAST'] // is also valid if 'p' is the parent and 'LAST' was the key ...
you can write the node by assigning it p['LAST'] = 3.4 or nValue = 3.4
you can 'watch' or listen a node. When you watch a Node you mean that you are interested in that node and you will be notified when that node changes. To remove the watch or unsubscribe you just have to delete the node
Here is a IronPython full example. The statement
n.Update += n.UpdateHandler(Update)
adds the function Update to the list of interested clients on that Node
Note the Update method the nImage argument contains the node as it is before the update contains just the update (which is a set of the fields that have changed)
import clr clr.AddReference("qlnet") from qlnet import Link from qlnet import Node def Update(nImage, nUpdate): for field in nUpdate: print field.Name, field.Value ql = Link() n = ql.Listen('CSCO', 'MSN') ql.Commit() n.Update += n.UpdateHandler(Update) #the line below makes program wait forever a that key is typed raw_input("\n -I'm here Waiting for eventos -")
When you modify a 'Node' value by assigning something to it, you are doing exactly what a built-in feed adapter does when updates come. Consequently all interested clients that are watching that node will thus be notified. This opens the door to create custom streamers and calculation modules.
Finally it is important to note that when QuoteLink is enabled across a LAN network the data model tree is visible in all machines across the lan and events will cross the LAN as well.
As an example of this structure we can have in a one application that watches data from a real time feed and computes for instance theoretical option pricing and writes the result in a set of structure nodes. The results tree with is set of Nodes will be automatically visible for any application (including Excel) in the same machine and other machines. These applications are called 'Calculation Modules'