Friday, February 14, 2025

RatesLib as QuantLib Alternative?

    


M 917 536 3378

maksim_kozyarchuk@yahoo.com








In response to my previous articles on building a platform around QuantLib, I received a suggestion to explore RatesLib, created by J. H. M. Darbyshire. Although QuantLib is widely used, it faces criticism for being somewhat dated and limiting compared to commercial solutions. It is also written in C++, making it less straightforward to extend when working primarily in Python.

RatesLib(https://github.com/attack68/rateslib ) was first published around March 2023 by Darbyshire (a core developer of pandas and author of several books on interest-rate pricing)—was originally focused on IR products but has since expanded to cover FX, options, and credit derivatives as well. In this article, I briefly compare how both QuantLib and RatesLib handle OIS curve building and consider the implications for the platform I’ve been developing



Comparison

Coverage and Focus

Reviewing RatesLib’s documentation, I was surprised to find not only extensive coverage of fixed-income products but also references to FX options, CDS, and other derivatives. While it may not match QuantLib in terms of sheer breadth, RatesLib’s functionality seems sufficient for many use cases. In the fixed-income realm, RatesLib functionality is quite deep and goes beyond what QuantLib typically offers out of the box. For instance, an IR Swap in RatesLib includes bucketed DV01, gamma, and analytical_delta (alongside NPV), whereas QuantLib typically provides NPV and legBPS (the latter being roughly equivalent to analytical_delta). Furthermore, RatesLib has native support for calculating PV and risk figures in both local and base currencies, which can streamline multi-currency analyses.

Pythonic Feel and Documentation

QuantLib is written in C++ and accessed in Python via bindings. While this works reasonably well, once often encounters difficulties deciphering method signatures and mapping Python calls to underlying C++ classes. The documentation, while extensive, can feel scattered across reference docs, books, blogs, and videos by the QuantLib community. There isn’t a single, definitive resource for all usage questions, which can make the learning curve steeper.

By contrast, RatesLib was developed in Python from the start, providing a modern, “pythonic” interface. Its tight integration with pandas makes it an appealing choice for people already using Python data stacks. Additionally, its documentation is well-organized, providing clear examples that guide users from basic to advanced features in a straightforward manner

Licensing and Other

QuantLib is distributed under a BSD license, which is permissive, allows commercial use, and imposes few restrictions. This makes it a flexible choice for commercial and open-source projects alike. RatesLib is free for educational use but requires a per-user production license, which can become expensive for teams or organizations needing widespread deployment. From the tests I’ve conducted, both libraries produce results closely aligned with market-standard valuations under identical market data and configurations, usually diverging by fewer than five pips. Such small discrepancies are well within normal tolerance when considering varying interpolation methods or market data sources.



Replicating SWPM Example with QuantLib

The RatesLib documentation demonstrates how to price an OIS swap in a manner similar to Bloomberg’s SWPM screen (see this example). Below is a snippet of QuantLib code aiming to replicate the same result:

from pandas import DataFrame

import QuantLib as ql


data = DataFrame({

    "tenor": ["1W", "2W", "3W", "1M", "2M", "3M", "4M", "5M", "6M", "7M", "8M", "9M", "10M", "11M", "12M", "18M", "2Y", "3Y", "4Y"],

    "rate": [5.30111, 5.30424, 5.30657, 5.31100, 5.34800, 5.38025, 5.40915, 5.43078, 5.44235, 5.44950, 5.44878, 5.44100, 5.42730, 5.40747, 5.3839, 5.09195, 4.85785, 4.51845, 4.31705],

})

data["product"] = 'SWAP'

data["rate"] *= 0.01


curve_data = data.to_dict(orient='records')

ql.Settings.instance().evaluationDate = ql.Date(17, 8, 2023)

yts = ql.RelinkableYieldTermStructureHandle()

index = ql.Sofr(yts)

day_count = ql.Actual360()

helpers = ql.RateHelperVector()

for p in curve_data:

    helpers.append(ql.OISRateHelper(2, ql.Period(p['tenor']), ql.QuoteHandle(ql.SimpleQuote(p['rate'])), index))

curve = ql.PiecewiseLogLinearDiscount(2, index.fixingCalendar(), helpers, day_count)

yts.linkTo(curve)

engine = ql.DiscountingSwapEngine(yts)


schedule = ql.Schedule(ql.Date(21, 11, 2023), ql.Date(21, 2, 2025), ql.Period("1Y"), index.fixingCalendar(), ql.ModifiedFollowing,

    ql.ModifiedFollowing, ql.DateGeneration.Backward, False)


swap = ql.OvernightIndexedSwap(ql.Swap.Receiver, 100e6, schedule, 0.0540, index.dayCounter(), index)        

swap.setPricingEngine(engine)

print(f'Swap NPV: {swap.NPV()}')

print(f'DV01: {swap.legBPS(0)}')



In one test run, the result was:

Swap NPV: 457,068.06

DV01: 11,907.89


This differs from both Bloomberg and RatesLib by approximately $500 on a DV01 of around $12,000.  This is equivalent to less than 5 pips of variation. Changing interpolation methods or adjusting maturity of the swap being priced changes the NPV diffs, but not by more than 10 pips for examples I’ve looked at.


Implication for KupalaNich

KupalaNich is a personal hobby project without a specific commercial objective, which likely qualifies it for a free RatesLib license. Moreover, both RatesLib and QuantLib share similar high-level APIs: each takes in tenors and rates to calibrate OIS swaps to market conventions; each computes pricing and risk via products dynamically linked to a yield curve. This suggests that, from an architecture standpoint, KupalaNich can maintain a consistent external API regardless of whether it calls into QuantLib or RatesLib.

However, for practical deployment reasons, namely, the difficulty in deploying RatesLib as an AWS Lambda function due to its Rust compiler dependency.  I plan to keep QuantLib as the primary library within the KupalaNich platform and will continue to explore it, especially for validating certain FI calculations and ensuring the platform is designed so that its analytics engine and market data layer could be swapped out in the future if necessary