Ever felt like you need a PhD just to navigate Open Risk Engine/QuantLib's labyrinthine C++ hierarchy? You're not alone!
I'm excited to share my new blog post and Jupyter notebook demonstrating how we treated ORE as a complete black box and transformed it from a complexity monster into a lightning-fast LiveRisk service for FX linear products using AADC.
The results? 1 million FX trades priced 100X FASTER - in just 0.4 seconds with complete delta risk in under 1 second! No need to understand the full C++ hierarchy - we simply identify the inputs and outputs and let AADC handle everything in between.
This isn't AI magic or approximation - AADC delivers results accurate to machine precision while dramatically accelerating calculations. We've simply eliminated the computational overhead while preserving the mathematical integrity of the models.
No more hair-pulling sessions trying to connect all the dots in ORE - just a streamlined black box where market rates go in, and prices + sensitivities come out faster than you can say "template metaprogramming nightmare."
The Challenge
ORE (Open Risk Engine) built on top of QuantLib presents a formidable challenge for quants and developers. While powerful, its complexity can make even seemingly simple tasks like setting up a Monte Carlo model quite daunting. This blog post demonstrates how we can transform ORE into a streamlined LiveRisk service for basic FX linear products using AADC.
When working with ORE, we often face a steep learning curve:
- Complex C++ class hierarchies
- Intricate XML configuration requirements
- Elaborate initialization sequences
- Interconnected objects that must be precisely orchestrated
Our goal is simple: create a black box where market rates go in and trade prices come out as quickly as possible, with first-order sensitivities to all market rates via AAD.
Finding the Input/Output Points
Creating a TodaysMarket
object in ORE typically requires extensive setup code. However, for
our purposes, we need to identify where market data actually enters the system and where trade
valuations exit.
After investigation, we found that market data enters through CSVLoader::loadFile
: with this
simple pattern:
const string key = tokens[1]; Real value = parseReal(tokens[2]);
This is where we can hook into AADC by marking these values as inputs:
if (idouble::isRecording()) { auto aadc_arg = value.markAsInput(); AADCKernelInputOutputRegistryInstance().inputs.push_back((key, aadc_arg)); AADCKernelInputOutputRegistryInstance().input_values.push_back(value.val); }
For outputs, the ReportWriter::writeNpv
method provides access to trade NPVs:
Real npv = trade->instrument()->NPV();
Which we can mark as outputs:
auto npv_res = (npv * fx).markAsOutput(); AADCKernelInputOutputRegistryInstance().outputs.push_back((trade->id(), npv_res));
Handling Control Flow Branches
When recording with AADC, it’s crucial to identify any branches that depend on input values, as these can create discontinuities leading to unstable risk calculations and PnL jumps.
In our setup, AADC identified a potential issue in
Rounding::operator()
:
Decimal Rounding::operator()(Decimal value) const { if (type_ == None) return value; Real mult = std::pow(10.0,precision_); bool neg = AAD_PASSIVE((value < 0.0)); // ... }
To resolve this, we modified the method to bypass rounding when running under AADC:
if (idouble::isRecording()) return value;
Number active to passive conversions: 0 while recording OREApp::run()
The code is available here.
Performance Results
We tested the solution with 1 million randomly generated FX linear trades:
Operation | Time (seconds) |
Standard ORE NPV calculation | 98 |
AADC recording | 350 |
NPV recalculation after recording | 0.40 |
NPV + all portfolio delta risks | <1.0 |
The LiveRisk Approach
The beauty of this approach lies in its efficiency and flexibility:
- Recording can be done before the trading day begins
- The computational graph can be serialized and cached
- The resulting AADC kernel can be deployed to a cloud API
- Each market data update triggers rapid recalculation (<1 second)
- You get both prices AND sensitivities almost instantaneously
- For new trades, only incremental recording is needed
- For trade cancellations, weight parameters can be adjusted without re-recording
Although this demonstration uses ORE/QuantLib, the same technique can be applied to proprietary quant libraries. AADC’s AVX2 vectorization capabilities can further accelerate calculations for delta ladders or what-if scenarios.