Using the .NET API

  • all you need is c# compiler or IronPython interpreter but you can increase you productivity using MS's Visual studio
  • Visual Studio Express edition is free of charge for C#, IronPython and VB and is more than enough
  • You can use the Visual Studio debugger to inspect the different objects in those all languages
  • for Visual studio Add a Reference to qlnet assembly.
  • Also if you have a streaming feed configure it first using the WinQL application and use it in the examples below instead of MSN.
  • Using just csc (the c# compiler) the command is: csc <file>.cs /r:“c:\Program Files\QuoteLink\bin\qlnet.dll” .

Make sure you have read first QuoteLink data model.

Requesting quotes synchronously

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.

Requesting quotes asynchronously

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 -")

New request format

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();
      }
   }
}
NOTES:

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.

  • For SERIES: You don't need to specify in the request TIME as all bars may be retrieved at once (as above). However you CAN specify the TIME, in which case the event and the node refers to that bar only
  • For all lists. If you don't specify a INDEX of the position you get a node with all items.
  • You typically retrieve all items(expiration or strikes for instance) on the list using a foreach statement.