Welcome back.

So, as I said, the QuantLib Python Cookbook is available on Leanpub; thanks to those who bought it so far. Does it mean that C++ users are left out in the cold? Well, no.

My choice of using Python notebooks to demonstrate QuantLib features was due to a number of factors. (I’m speaking for myself, here, but I’m guessing that Goutham thought something similar when he started his series of posts). Notebooks are interactive, and so I can also use them live in my courses (the next of which is in September, thanks for asking); and the platform, more or less out of the box, provides excellent modules like matplotlib for graphing and pandas for data analysis. Add into the mix that I was already familiar with the language, and notebooks were the winners, hands down.

However, it’s easy enough to translate the Python code shown in the book into the corresponding C++ code. As an example, I’ll go through a bit of code from the notebook on instruments and pricing engines (the complete notebook is in the free sample).

In [1]: from QuantLib import *

This line imports the QuantLib module and adds the classes and functions it contains to the global namespace. The C++ equivalent would be:

#include <ql/quantlib.hpp>

using namespace QuantLib;

Of course, the above is for illustration purposes. In production code, you’re not forced (or even advised) to use the using directory; you can keep the names in their namespace and qualify them when you use them. It’s also possible to include more specific headers, instead of the global quantlib.hpp.

In [2]: today = Date(7, March, 2014)
        Settings.instance().evaluationDate = today

The code above has a couple of caveats. The first line is easy enough to translate; you’ll have to declare the type to the variable (or use auto if you’re compiling in C++11 mode). The second line is trickier. To begin with, the syntax to call static methods differs in Python and C++, so you’ll have to replace the first dot by a double colon. Then, evaluationDate is a property in Python but a method in C++; it was changed in the Python module to be more idiomatic, since it’s not that usual in Python to assign to the result of a method. Luckily, you won’t find many such cases. The translated code is:

Date today(7, March, 2014);
Settings::instance().evaluationDate() = today;

Next:

In [3]: option = EuropeanOption(PlainVanillaPayoff(Option.Call, 100.0),
                                EuropeanExercise(Date(7, June, 2014)))

Again, you’ll have to declare the type of the variable. Furthermore, the constructor of EuropeanOption takes its arguments by pointer, or more precisely, by boost::shared_ptr. This is hidden in Python, since there’s no concept of pointer in the language; the SWIG wrappers take care of exporting boost::shared_ptr<T> simply as T. The corresponding C++ code:

EuropeanOption option(
    boost::make_shared<PlainVanillaPayoff>(Option.Call, 100.0),
    boost::make_shared<EuropeanExercise(Date(7, June, 2014)));

(A note: in the remainder of the example, I’ll omit the boost:: namespace for brevity.)

In [4]: u = SimpleQuote(100.0)
        r = SimpleQuote(0.01)
        sigma = SimpleQuote(0.20)

Quotes, too, are stored and passed around as shared_ptr instances; this is the case for most polymorphic classes (when in doubt, you can look at the C++ headers and check the signatures of the functions you want to call). The above becomes:

shared_ptr<SimpleQuote> u = make_shared<SimpleQuote>(100.0);
shared_ptr<SimpleQuote> r = make_shared<SimpleQuote>(0.01);
shared_ptr<SimpleQuote> sigma = make_shared<SimpleQuote>(0.20);

Depending on what you need to do with them, the variables might also be declared as shared_ptr<Quote>. I used the above, since I’ll need to call a method of SimpleQuote in a later part of the code.

In [5]: riskFreeCurve = FlatForward(0, TARGET(),
                                    QuoteHandle(r), Actual360())
        volatility = BlackConstantVol(0, TARGET(),
                                      QuoteHandle(sigma), Actual360())

The Handle template class couldn’t be exported as such, because Python doesn’t have templates. Thus, the SWIG wrappers have to declare separate classes QuoteHandle, YieldTermStructureHandle and so on. In C++, you can go back to the original syntax.

shared_ptr<YieldTermStructure> riskFreeCurve =
    make_shared<FlatForward>(0, TARGET(),
                             Handle<Quote>(r), Actual360());
shared_ptr<BlackVolTermStructure> volatility =
    make_shared<BlackConstantVol>(0, TARGET(),
                                  Handle<Quote>(sigma), Actual360());

Next,

In [6]: process = BlackScholesProcess(QuoteHandle(u),
                                      YieldTermStructureHandle(riskFreeCurve),
                                      BlackVolTermStructureHandle(volatility))

turns into

shared_ptr<BlackScholesProcess> process =
    make_shared<BlackConstantVol>(
        Handle<Quote>(u),
        Handle<YieldTermStructure>(riskFreeCurve),
        Handle<BlackVolTermStructure>(volatility));

and

In [7]: engine = AnalyticEuropeanEngine(process)

into

shared_ptr<PricingEngine> engine =
    make_shared<AnalyticEuropeanEngine>(process);

So far, we’ve been calling constructors. Method invocation works the same in Python and C++, except that in C++ we might be calling methods through a pointer. Therefore,

In [8]: option.setPricingEngine(engine)

In [9]: print option.NPV()

In [10]: print option.delta()
         print option.gamma()
         print option.vega()

becomes

option.setPricingEngine(engine);

cout << option.NPV() << endl;

cout << option.delta() << endl;
cout << option.gamma() << endl;
cout << option.vega() << endl;

whereas

In [11]: u.setValue(105.0)

turns into

u->setValue(105.0);

Of course, the direct translation I’ve been doing only applies to the QuantLib code; I’m not able to point you to libraries that replace the graphing functionality in matplotlib, or the data-analysis facilities in pandas, or the parallel math functions in numpy. However, I hope that the above can still enable you to extract value from the cookbook, even if you’re programming in C++.

Follow me on Twitter if you want to be notified of new posts, or add me to your Google+ circles, or subscribe via RSS: the buttons for that are in the footer. Also, make sure to check my Training page.