Announcing qtk, a new interface to interact with QuantLib Python
I have blogged about using QuantLib Python in this tutorial series. Learning QuantLib Python involves a knowledge of the various syntax and paying a lot of attention to detail such as the various conventions. I have started to work on the package qtk
that adds a layer on top of QuantLib python by making it data driven. What do I mean by that?
The qtk
package relies on data in the form of Python dict
and then uses this data to form QuantLib objects behind the scenes. Lets take a look at a small example that replicates my example on bond modeling in QuantLib Python
from qtk import Controller, Field as F, Template as T
The Template
class directly maps to the different kinds of QuantLib objects that are supported. For instance the Template.TS_YIELD_ZERO
corresponds to the zero yield term structure. The Field
class has all the properties that are needed by the various Template
s. The Controller
class is what does all the processing to create QuantLib objects behind the scenes. Let us look at a minimal example below, and then explain the different features in detail.
data = [
{
F.LIST_OF_DATES.id: ["1/15/2015", "7/15/2015", "1/15/2016"],
F.LIST_OF_ZERO_RATES.id: [0.0, 0.005, 0.007],
F.DISCOUNT_BASIS.id: "30/360",
F.DISCOUNT_CALENDAR.id: "UnitedStates",
F.COMPOUNDING.id: "Compounded",
F.COMPOUNDING_FREQ.id: "Annual",
F.CURRENCY.id: "USD",
F.TEMPLATE.id: T.TS_YIELD_ZERO.id,
F.OBJECT_ID.id: "USD.Zero.Curve"},
{
F.OBJECT_ID.id: "BondEngine",
F.DISCOUNT_CURVE.id: "->USD.Zero.Curve",
F.TEMPLATE.id: T.ENG_BOND_DISCOUNTING.id},
{
F.ASOF_DATE.id: '2016-01-15',
F.COUPON.id: 0.06,
F.COUPON_FREQ.id: "Semiannual",
F.CURRENCY.id: 'USD',
F.PAYMENT_BASIS.id: '30/360',
F.ISSUE_DATE.id: '2015-01-15',
F.MATURITY_DATE.id: '2016-01-15',
F.ACCRUAL_CALENDAR.id: "UnitedStates",
F.ACCRUAL_DAY_CONVENTION.id: "Unadjusted",
F.DATE_GENERATION.id: "Backward",
F.END_OF_MONTH.id: False,
F.OBJECT_ID.id: "USD.TBond",
F.PRICING_ENGINE.id: "->BondEngine",
F.TEMPLATE.id: T.INST_BOND_TBOND.id}
]
res = Controller(data)
asof_date = "1/15/2015"
ret = res.process(asof_date)
tbond = res.object("USD.TBond")
print tbond.NPV()
Now let us disect the code above to understand the specifics. The Controller
class takes a list
of dict
as input, provided here by the variable data
. In the above example, we have used qtk mnemonics such as Field.TEMPLATE.id
instead of directly using the text "Template". The content of data is as shown below:
data
[{'Compounding': 'Compounded', 'CompoundingFrequency': 'Annual', 'Currency': 'USD', 'DiscountBasis': '30/360', 'DiscountCalendar': 'UnitedStates', 'ListOfDate': ['1/15/2015', '7/15/2015', '1/15/2016'], 'ListOfZeroRate': [0.0, 0.005, 0.007], 'ObjectId': 'USD.Zero.Curve', 'Template': 'TermStructure.Yield.ZeroCurve'}, {'DiscountCurve': '->USD.Zero.Curve', 'ObjectId': 'BondEngine', 'Template': 'Engine.Bond.Discounting'}, {'AccrualCalendar': 'UnitedStates', 'AccrualDayConvention': 'Unadjusted', 'AsOfDate': '2016-01-15', 'Coupon': 0.06, 'CouponFrequency': 'Semiannual', 'Currency': 'USD', 'DateGeneration': 'Backward', 'EndOfMonth': False, 'IssueDate': '2015-01-15', 'MaturityDate': '2016-01-15', 'ObjectId': 'USD.TBond', 'PaymentBasis': '30/360', 'PricingEngine': '->BondEngine', 'Template': 'Instrument.Bond.TreasuryBond'}]
Every dict
corresponds to an object, with the key value pairs being the attributes required in the creation of that object. The value of the key Template
denotes what object is created. So for instance, in the above example the value Engine.Bond.Discounting
denotes
the DiscountingBondEngine
. In the above data, every dict has a key ObjectId
which is a unique name required for every object. Objects can be cross referenced by using the special prefix "->" along with the ObjectId
. You can see this usage in the last dict
where the PricingEngine
references the BondEngine
object, and the BondEngine
object references the USD.Zero.Curve
yield term structure.
Once the data is prepared, the API call to process is extremely simple because qtk
does the major brunt of interfacing with QuantLib.
res = Controller(data)
asof_date = "1/15/2015"
ret = res.process(asof_date)
tbond = res.object("USD.TBond")
print tbond.NPV()
The Controller
accepts the data
and the process
method processes as of the calculation date. Once processed, the QuantLib objects can be accessed and queried for output.
This project is alpha and has a few templates written as of now. Would love to hear your thoughts. Checkout the qtk project page to get involved.