Categories
Articles

Interactive xVA analytics with Python and atoti

Hello, I’m a quantitative analyst at ActiveViam and in this blog, I’d like to illustrate how to create a BI app for xVA aggregation with Python and atoti.

This notebook will be of particular interest to professionals working with xVA in the finance industry, but other atoti users may find interesting insight on how to set up complex aggregation functions based on continuous data streams.

I will only focus on thve aggregation and analytics part of the challenge, and all the mathematics and techniques for scenario generation are beyond the scope of this post. The BI app we are about to build can complement your Monte Carlo engine and pricing toolkit to enable human consumption of the model output.

At the end of this experiment, we’ll launch an interactive engine for re-aggregation of xVA metrics from simulated risk profiles. We’ll create the expressions for the cVA calculation, and I hope this example can help to implement other types of xVA aggregations when needed.

example-of-dashboard-i-built
Example dashboard I built

Interactive aggregation

xVA calculations are typically Monte Carlo simulations based, with lots of simulation data being summarized to obtain the valuation adjustment. As the aggregation function is essentially non-linear, and positions offset each other, the only way to evaluate impact of a new trade or changes in portfolio attributes — is to re-aggregate the measure.

On-the-fly calculations are handy when you don’t know in advance how you are going to explore the portfolio today and which subsets of data you want to zoom in on. It allows you to change the scope interactively. See, for example, as I include and exclude trades — in this recording I’m selecting and deselecting a desk — all numbers on the screen are recalculated.

Simulations-are-recalculated-interactively-for-different-scopes-of-data
Simulations are recalculated interactively for different scopes of data

We will use atoti to enable interactive aggregation of Monte Carlo simulations. The simulation data will sit in-memory in vectorized format, and we’ll describe the aggregation logic using Python. Scroll down for an overview of the Python implementation.

Real-time xVA and pre-trade xVA

Under the hood, the app we are launching is powered by an in-memory aggregation engine, handling real-time data updates and a reactive UI.

You can see in this recording, when real-time mode is enabled in the UI and we are sending additional Monte Carlo simulations into the engine — valuations blink as underlying contributors change.

real-time-xva
Feeding new trades

This is instrumental to deliver pre-trade xVA analysis, which in turn is essential as it is factored into customer quotes. Here I’m loading a hypothetical trade as a “what-if” scenario and adding it into different netting sets to see where the incremental impact will be bigger:

what-if-impact-of-hedges-under-different-scenarios
What-If impact of hedges under different scenarios

Python implementation

To launch the engine and the UI, first we need to install the atoti Python module. Follow this link for installation instructions.

I’m attaching a Jupyter notebook with the necessary Python code, feel free to run the example on your laptop to launch the prototype. In the notebook, we are going through the following steps:

  1. Load simulations data into in-memory database. For the xVA evaluation, we also load recovery rates, survival probabilities and trade attributes,
  2. Define aggregation functions, for example, the standard CVA formula:
CVA-formula

Using the atoti Python API, the above formula would be described as a summation by counterparty and time point of expected exposure (m[“EE”]), multiplied by the default probability (m[“PD”]) within that time step (and corrected for loss given default (m[“LGD”])):

m["CVA"] = tt.agg.sum(
    -m["LGD"]
    * tt.agg.sum(
        m["EE"] * m["PD"],
        scope=tt.scope.origin(lvl["TimePoint"], lvl["CounterpartyId"]),
    ),
    scope=tt.scope.origin(lvl["CounterpartyId"]),
)
m["CVA"].formatter = "DOUBLE[0.00]"

In the notebook you can also find examples of functions to compute expected positive exposure, probabilities of default from survival probabilities, potential future exposure, expected shortfall and peak exposure.

Finally, browse and visualize xVA and other measures in the atoti UI.

My illustrative example is simplified on purpose, and can definitely be extended to include risk mitigants, collateral model, recovery model, etc.

Conclusion

The problem we were solving today is quite typical for finance, with portfolio data being re-aggregated in a non-linear manner. Check my other post for an example of contributory analysis: How to explain non-additive measures.

Please reach out if you are working on a practical implementation of xVA, I would be happy to connect.