Make sure you have read first QuoteLink data model.
using System; using System.Collections.Generic; using System.Text; using qlnet; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { Link lnk = new Link(); Node n = lnk.Request("MSFT", "MSN"); Console.WriteLine(n["LAST"]); } } }
The communication with QuoteLinks starts with a Link object. The link object represents the infrastructure and everything will happen through its methods. QuoteLink applications need to have at least one (and one is enough for most cases).
Link's object Request method takes a symbol and a feed as arguments and returns when the data is received. The return value is a Node containing all fields. To access the LAST field we simply index the Node with the file name it.
Below an example using Python. By adding our event function we say to the platform that we are interested on all updates for that Node (in this case 'CSCO' from 'MSN' feed)
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) raw_input("\n - Waiting eventos -")
From version 0.78.* the following system can be used for ALL types of requests the key /value pair values are the same used on worksheet functions.
There is a new method Listen that takes a Node as argument.
... Node answerNode = ql.Listen(requestNode); ...
where requestNode holds all key / value pairs needed for a particular request. You create the request node by simply adding new key value pairs;
Node requestNode = new Node; requestNode["TYPE"] = "LIST"; requestNode["WHAT"] = "SYMBOLS"; requestNode["WANT"] = "EXPIRATIONS"; requestNode["SYMBOL"] = "CSCO"; requestNode["CLASS"] = "IEOPTION"; requestNode["FEED"] = "IQ"; // send the request Node answerNode = ql.Listen(requestNode);
The answer is ready when the Update event is called. Below is a simple example for SERIES type of request.
using qlnet; namespace Series { class Program { static void DumpNode(string indent, Node node) { //recursive foreach (Node subNode in node) { string s = indent + " "; DumpNode(s, subNode); Console.WriteLine(indent + subNode.Name + "=" + subNode.Value); } } static void EventHandler(Node image, Node dt) { Console.WriteLine("--------------------------------"); for (int n = 0; n < 10; ++n) { Node a; a = image[-n]; DumpNode(" ", a); } } static void Main(string[] args) { Console.WriteLine("--------------------------------"); Link l = new Link(); Node n = new Node(); n["TYPE"] = "SERIES"; n["SYMBOL"] = "CSCO"; n["PERIOD"] = 1; n["FEED"] = "IQ"; n["DAYS"] = 10; int nFields = n.Count(); Node node = l.Listen(n); node.Update += new Node.UpdateHandler(EventHandler); // updates are sent to Event Handler l.Commit(); DumpNode(" ", n); Console.WriteLine(" --- Press any key to exit ---"); Console.Read(); } } }
You can always use a foreach statetement on a Node (Node implements IEnumerable). That is a handy way to list all items on a Node. There is an exception which is the case of the Node that holds the SERIES bars. To use foreach would be very inefficient so it is not supported. For SERIES you need to address specifically the bars using the time of the bar or (0, -1, -2) like in the example above. The restriction does not apply to the subnodes of a bar which are typically Open, High, Close, Volume the example above uses that.