> ## Documentation Index
> Fetch the complete documentation index at: https://docs.activeviam.com/llms.txt
> Use this file to discover all available pages before exploring further.

# PnL Explain

> Guide to PnL Explain in Atoti Market Risk, covering the Taylor expansion methodology, market data selection, shift formulas for absolute, relative, DHS and FXRelative types, and cross-sensitivity handling

## Overview

The PnL Explain process aims to quantify the changes in the PnL from one business day to the next, based on the closing prices for each day and show the impact of each input (each change in the quote) in terms of PnL.

It is intended to be used to validate the sensitivities and the Taylor VaR by comparing it to the actual day to day PnL. It can be seen as a one-scenario VaR from day minus one to day.

For example, the portion of PnL due solely to the change of one particular quote, such as the EUR SWAP LIBOR 3Y.

The process begins with aggregation of the greeks and then uses those values in a Taylor expansion to explain the expected one-day change in PnL using the actual market data shift over one day.

The input formula is the same as the [Taylor VaR](taylor-var):

${\displaystyle f(a+shift)=f(a)+\nabla f(a)\cdot shift+{\frac {1}{2}}shift^{T}\mathbb {H}_f(a)shift+\mathcal{O}(shift^2)}$

In this formula:

* $a$ is the current market state.
* $shift$ is a market shift, it is a vector kind value as multiple market data can be shifted for the day to day.
* $\nabla f(a)$ is the gradient of $f$ at $a$, it's a vector of the first-order risk factors such as delta, vega or correlation.
* $\mathbb {H}_f(a)$ is the Hessian matrix of $f$ at $a$, it's a matrix containing the second-order risk factors such as gamma, cross-gamma, vanna or volga.

Unlike Taylor VaR, the shift is computed from Day-1 and Day market data so we need to define the function $shift_{riskFactor}(MD_{riskFactor,day}, MD_{riskFactor,day-1})$.

## Input data

Atoti Market Risk supports Delta, Gamma, Vega, Volga, Vanna, Correlation, CrossGamma, and Theta sensitivities.

## Market data

If the exact vertices/tenor points referenced by the sensitivities don't coincide with the market data, Atoti Market Risk can apply a mathematical interpolation of the market data quotes between sensitivities and market data tenors.

That interpolation logic can be enabled or disabled based on the risk class and the sensitivity measure. Also, additional computations can be defined for every combination of sensitivity measures and risk classes before and after the interpolation of market data is performed.

The market data must be at the risk-factor level. Atoti Market Risk performs any necessary interpolation and fallback.

See the [Market Data API](/solutions/libraries/market-data/1.3/) for more details about market data retrieval.

### Market Data Selection

Several kinds of market data are available to compute the PnL Explain. The kind of market data will be chosen with the following criteria:

* `sensitivityKind`: The formal name of the current metric chain.
* `sensitivityName`: The name of the sensitivity coming from the [TradeSensitivities](../datastore/sensitivities/trade-sensitivities) store.
* `riskClass`: The risk class coming from the [TradeSensitivities](../datastore/sensitivities/trade-sensitivities) store.

The kind of the market data will be given by the property `mr.sensi.market-data.`*sensitivityKind*`.`*sensitivityName*`.`*riskClass*`.market-data-type`. The keyword `any` can be used as a wildcard.
The following values can be used to wire the market data to an existing metric:

| Value       | MD Next                          | MD Current             |
| ----------- | -------------------------------- | ---------------------- |
| spot        | Spot MD Next                     | Spot MD Current        |
| fx spot     | FX Spot MD Next                  | FX Spot MD Current     |
| eq spot     | Spot MD Next \* Split Ratio Next | Spot MD Current        |
| curve       | Curve MD Next                    | Curve MD Current       |
| surface     | Surface MD Next                  | Surface MD Current     |
| cube        | Cube MD Next                     | Cube MD Current        |
| correlation | Correlation MD Next              | Correlation MD Current |
| dividend    | Dividend Next                    |                        |

For the second axis of cross-sensitivities (Vanna, CrossGamma) the risk factor hierarchy is Risk Factors Secondary with the corresponding measure.

<Note>
  Only specific market data types are supported per sensitivity kind. This can be extended by customization of the chains.

  * **delta, gamma**: fx spot, eq spot, curve
  * **vanna1, vega, volga**: surface, cube
  * **vanna2**: eq spot, curve
  * **correlation**: correlation
  * **dividend**: dividend
  * **cross-gamma1, cross-gamma2**: eq spot
</Note>

#### Theta market data

As Theta represents time decay, the Theta Current MD and Theta Previous MD measures for Theta express the number of days remaining to the maturity of the trade. To correctly compute the losses due to time decay, the terms are now swapped, with the current day's value being subtracted from the previous day's value.

### Methodology

#### Date shifting

The PnL explain is computed with the sensitivities of day-1 and market data of day and day-1. To do such a thing, the PnL explain is computed on the context of day-1.
So the (simplified) metric chain of the PnL explain will look like:

1. `PnL Explain`: Shift from Day-1
2. `PnL Explain Next Date`:  Sum of the metric chain specifics PnLs
3. `Delta PnL Explain Next Date`, ...: FX conversion with Day-1 FX rate
4. `Delta PnL Explain Native Next Date`: Computation of the PnL explain on the Day-1 context
5. `Delta Native`, `Delta Ladder Native`, `Delta Current MD`, `Delta Next MD`: The sensitivity, ladder of Day-1, Market Data of Day-1 and Day.

Please be careful, with the initial date shift, in fact current is day-1 and next is day.

#### Computation

In Atoti Market Risk, the PnL Explain calculations are configurable and extendable. In the decomposition of PnL, the market data impact represents the change in the portfolio value from market data shifts during the day.
Atoti Market Risk supports both relative and absolute market data shifts. This is configurable and extendable. The shift factor default is 1. The following table shows the PnL impact calculations for each risk class, where $q_{n}$ is the market data quote for a given day $n$.

The

$$
\begin{aligned}
PnL_{riskFactor}&(shift_{riskFactor}) = \\
&PnL_{riskFactor}(sensitivity_{riskFactor,day-1},\ shift_{riskFactor}(MD_{riskFactor,day}, MD_{riskFactor,day-1}))
\end{aligned}
$$

is computed by the `ScalarPnLExplainPostProcessor` post-processor.
It will use two different functions, a PnL function that is quite the same as the one used by the [Taylor VaR](taylor-var) computation, and a shift function
that will convert the Market Data pair into a shift.

The formulas are provided by the spring bean of type `IPnLExplainFormulaProvider`, with the functions

```java theme={"languages":{"custom":["/engine/python-sdk/6.2/languages/pycon.tmLanguage.json"]}}
// The PnL function
DoubleBinaryOperator getPnlExplainFormulaForShift(ConcurrentMap<Object, Object> cache, String sensitivityKind, String sensitivityName, String riskClass);

// The shift function
DoubleBinaryOperator getShiftFromMDFormula(ConcurrentMap<Object, Object> cache, String sensitivityKind, String sensitivityName, String riskClass);
```

It uses as parameters:

* `cache`: The query cache.
* `sensitivityKind`: The formal name of the current metric chain.
* `sensitivityName`: The name of the sensitivity coming from the [TradeSensitivities](../datastore/sensitivities/trade-sensitivities) store.
* `riskClass`: The risk class coming from the [TradeSensitivities](../datastore/sensitivities/trade-sensitivities) store.

The following functions can be provided:

| type       | PnL formula                                                                                                                                            | Shift formula                                                           |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------- |
| Absolute   | $PnL(sensitivity, shift)=sensitivity \cdot \frac{(shift \cdot priceFactor)^{derivativeOrder}}{derivativeOrder!}$                                       | $shift(MD_{day}, MD_{day-1})=MD_{day}-MD_{day-1}$                       |
| Relative   | $PnL(sensitivity, shift)=sensitivity \cdot \frac{(shift \cdot priceFactor)^{derivativeOrder}}{derivativeOrder!}$                                       | $shift(MD_{day}, MD_{day-1})=\frac{MD_{day}}{MD_{day-1}}-1$             |
| DHS        | $PnL(sensitivity, shift)=sensitivity \cdot \frac{(shift \cdot priceFactor)^{derivativeOrder}}{derivativeOrder!}$                                       | $shift(MD_{day}, MD_{day-1})=\frac{MD_{day}+shift}{MD_{day-1}+shift}-1$ |
| FXRelative | $PnL(sensitivity, shift)=sensitivity \cdot \frac{\left(\left(1-\frac{1}{1+shift} \right)\cdot priceFactor\right)^{derivativeOrder}}{derivativeOrder!}$ | $shift(MD_{day}, MD_{day-1})=\frac{MD_{day}}{MD_{day-1}}-1$             |

The `type`, `derivative-order`, `price-factor` and `shift` are configured by the properties.
To find the right property set, we will look for the following path:

1. `mr.sensi.rules.`*sensitivityName*`.pnl-explain.`*riskClass*
2. `mr.sensi.rules.`*sensitivityKind*`.pnl-explain.`*riskClass*

In case of the use of a Ladder, the sensitivity is computed from the Ladder and the shift (see [Sensitivity ladders](sensitivity-ladders)), before applying the PnL formula.

#### DHS

For negative interest rates, Atoti Market Risk uses the DHS (Displaced Historical Simulation) computations, where $shift$ is a shift value that can be configured per risk class.

## Cross sensitivity

For Vanna and CrossGamma, the cross sensitivities are handled by applying the shift formula of both risk-factors:

$\text{PnL Explain} = f_{\text{marketData2}}(f_{\text{marketData1}}(\text{sens},q_{1},q_{2}),p_{1},p_{2})$

Where $q_{n}$ and $p_{n}$ are the market data quotes for a given day $n$ for risk-factors $q$ and $p$ respectively.

<Note>
  Currently, cross-bucket sensitivity is not supported.
</Note>
