Using the Quantlab Python interface

All functions available in Quantlab may be called from any Python 2.7 and/or Python 3.X environment. This includes not only the built-in library of financial and mathematical functions, but also user-written functions and classes implemented in Qlang (and saved as a library file). Internally compiled c/c++ binarys implemented as a Dynamic Link Library (DLLs) will also be exported to Python.

Installing the Python Quantlab API

Before getting started you need to ensure that you have the proper Quantlab python library in your local Quantlab setup. The relevant version of python support should be placed directly under the Quantlab root. Both 32-bit and 64-bit Quantlab is currently supported.

../../_images/image3.png

There are two options to load the Quantlab application into Python.

  1. To permanently add a system variable PYTHONPATH to the systems environment variables. It should point to the corresponding Python version folder using either 32-bit or 64-bit Quantlab. This means that any time python is started it will recognize the possibility to load the Quantlab library.

../../_images/image4.png
  1. To dynamically add the Python path using the sys library. Then the Python code will work for any user having a correct Quantlab and Python file-setup regardless of system environment.

../../_images/image5.png

To use Quantlab functions in Python it is enough to use the “import ql” command to have Quantlab available. The session will load all library functions set in the ini-file of the current Quantlab. If the instr31.dll is available and a valid ODBC source is pointing to an instrument and curve database, the instrument definitions will be loaded in the same way as starting a Quantlab session.

Remember that also real-time connections to Bloomberg and Reuters will be available to the Python interface.

Note

Loading of the Quantlab function set including your internal ql/qll library files is automatically done every time the “import ql” command is run in Python. There is no need to export and register tlb files as with the COM connection.

Quantlab to Python - handling of function overloading

Warning

<Obsolete as of Quantlab version 3.1.2016>

Note

Overloading is now allowed from Qlang to Python.

Python examples

There are many ways to write and run Python code. The Quantlab Python API works equally well from both the IDLE command shell as well as from a Jupyter notebook.

../../_images/image6.png

Using the Python Shell

../../_images/image7.png

Using Jupyter Notebook

A few things to be aware of when using Qlang / Quantlab from Python:

  • No vector and matrix function expansion in Python. Must loop in Python.

  • Date type in Python has no overloaded operator +/- which means that ql.today() - 1 does not work.

  • Variables passed as “option nullable” in Qlang can magically be omitted in Python.

  • Variables passed as “out args” in Qlang will be returned in a Python tuple.

Note

In the previous version, class constructors were not exported to Python, unless there existed a create function for the constructor. From this version and onward, if a class has no create function, one will be dynamically created.

A code example calling a set of bonds and extracting some static and pricing data:

../../_images/image8.png
import ql

import datetime

v_i = ql.db_curve("SEKGOVTBOND", datetime.date(2018,9,14), "mid-rr").instruments()

q = []
n = []
d = []
y = []

for i in v_i:
   q.append(round(i.clean_price(),3))

   n.append(i.name())

   d.append(round(i.mac_dur(),2))

   y.append(round(i.quote(),3))

print (n,q,y,d)

A code example calling the database for printing historical price quotes:

../../_images/image9.png
start = datetime.datetime(2018,1,1)
end = datetime.datetime.today()

daterange = [start + datetime.timedelta(days=x) for x in range(0, (end-start).days)]

q = []

for d in daterange:
   tmp = ql.db_instrument("SHB A:XSTO:SEK", d).quote()

   if tmp != None:
       q.append(round(tmp,2))

print(q)

Using the “out arguments” in Qlang

In Qlang it is common to use “out” arguments as function inputs. In Qlang, this results in two things;

  1. That all the out declared arguments are returned and shown in a table in the workspace

  2. That it is possible to alter the incoming data within the function.

    Example with Qlang code:

    out void aa_test_test_py2(out vector(string) n,
                              out vector(number) r,
                              out date d)
    {
       n = ["hello", "goodbye", "see", "you", "later"];
       r = rng_vector(10);
       d = today();
    }
    

    Will return a Python tuple with both variables n, r and d included. If the function also has a return value this will be the first result in the tuple. Such that the following code

    out string aa_test_test_py2(out vector(string) n,
                                out vector(number) r,
                                out date d)
    {
       n = ["hello", "goodbye", "see", "you", "later"];
       r = rng_vector(10);
       d = today();
    
       return "Finished with the function!";
    }
    

    will return the following in Python:

    ../../_images/image12.png

Note

Note! that as all “out arguments” in Qlang are by default option nullable, in Pyhton the user does not have to declare and pass empty variables to the function. This works because Python and Qlang cannot interact with Python native variables by reference. (An exception from this goes for passing Qlang objects to a Qlang function in the Python code, as this object lives inside Qlang and can thus be altered if passed to a function that changes the object’s contents.)

Another example where a Qlang function that take a vector of date and number as input arguments are called in Pyhton with both results returned in a Python tuple:

../../_images/image13.png

What happens if you have overloading of a function with option nullable arguments? In the below construction only the first test will be available from python when calling it using test(None,None) due to ambiguity in calling the function using test() or test(None) as neither of these calls can tell which of the functions you want to address.

void test(out string s, out string t)
{
   s = "test 2";
   t = "t";
}

void test(out string s)
{
   s = "test 1";
}

Exporting modules from Qlang to Python

From version 3.1.2021 of Quantlab, also library modules are exported to Python. They will look and work similar to Quantlab to place its containing classes and functions into private namespace.

module a_roberts_func{

   matrix(number) aa_test_py(integer x, integer y, logical z, = true)
   {
      return transpose([rng_vector(x)]) * [rng_vector(y)];
   }

   out string aa_test_test_py2(out vector(string) n,
                               out vector(number) r,
                               out date d)
   {
      n = ["hello", "goodbye", "see", "you", "later"];
      r = rng_vector(10);
      d = today();

      return "Finished with the function!";
   }

   void test(out string s, out string t)
   {
      s = "test 2";
      t = "t";
   }

   void test(out string s)
   {
      s = "test 1";
   }
}

In the example above, all functions can be found in the module / namespace “a_roberts_func”. See below.

../../_images/image16.png

Debugging Qlang from Python

It is possible to debug a Python session’s Qlang code directly in the Qlang debugger / editor.

First a Python aware Quantlab session must be started using the same Quantlab as is used when running the Python. A debug session is started by running the -Z command at the command line. See example below:

../../_images/image17.png

This opens a Debugger with a “cproxy” process thread started.

../../_images/image18.png

This process listens for Python processes that initialize Quantlab libraries, using the “import ql” command from Python. Multiple Python sessions can be started from different environments such as Jupyter Notebook or the Python IDLE.

We can now set break-points and debug in Quantlab as normal.

../../_images/image19.png

Note

Note! that the Quantlab Editor / Debugger will be in “lock-down” mode. It will not allow for any changes or re-compiles of the Qlang code during the debugging session.