Sensitivity ladders

The purpose of the sensitivity ladder is to increase PnL calculation accuracy by computing the sensitivities at different market configurations. It is used to compute PnL Explain and the Taylor VaR.

Input data

The system is fed with a table of sensitivities shifted from the current market value.

For instance:

Shift Delta
-50% 9,944,227.53
-25% 9,924,531.37
-15% 9,501,104.56
-10% 8,668,816.62
-7% 7,569,003.25
-5% 6,499,116.86
-3% 5,306,289.78
-1% 4,157,778.67
0% 3,633,050.69
1% 3,153,644.65
3% 2,353,529.88
5% 1,765,164.79
7% 1,348,405.85
10% 934,996.82
15% 539,326.70
25% 171,999.71
50% 2,613.78

Calculation theory

The purpose is to calculate the PnL based on the delta ladder for the underlying market price. The ladder is based on price shift, so for PnL explain we first convert the market data pair into a shift.

For PnL explain

The conversion between market data and shift is done with the following formula:

$shift_d=\mathrm{ShiftFromMD}(MD_d,MD_{d-1})$

This formula is defined by the IPnLExplainFormulaProvider::getShiftFromMDFormula method bean, based on the mr.sensi.rules..pnl-explain. property.

Type ShiftFromMD formula
Absolute $shift_d=MD_d-MD_{d-1}$
Relative $shift_d=\frac{MD_d}{MD_{d-1}}-1$
FXRelative $shift_d=\frac{MD_d}{MD_{d-1}}-1$
DHS $shift_d=\frac{MD_d + factorShift}{MD_{d-1} + factorShift}-1$

warning

To keep consistency between ladders and standard sensitivities across PnL Explain and Taylor VaR, the formula provider bean must ensure that $\mathrm{PnlExplain}(sensi,MD_d,MD_{d-1})=\mathrm{VaRExplain}(sensi,\mathrm{ShiftFromMD}(MD_d,MD_{d-1}))$

  • PnlExplain is provided by IPnLExplainFormulaProvider::getPnlExplainFormula
  • VaRExplain is provided by IPnLExplainFormulaProvider::getVaRExplainFormula
  • ShiftFromMD is provided by IPnLExplainFormulaProvider::getShiftFromMDFormula

Ladder computation

We assume that $P(shift)=P(0)+\int_0^{shift}delta(x)\cdot \partial x$. As we are on a discrete distribution (the ladder), this will be transformed into: $PnL(shift)=P(shift)-P(0)=\sum_{shift_i\in]0,shift]}\int_{shift_{i-1}}^{shift_i}delta(x)\cdot \partial x$

So it will lead to the integration of the Red surface:

Ladder integration parts

To compute the $\int_{shift_{i-1}}^{shift_i}delta(x)\cdot \partial x$ part of the formula, several methodologies can be used depending on the way the delta ladder has been computed. The Ladder module will call the partial integration computation for each ladder step. By default, Atoti Market Risk provides the following ways to compute this partial integration:

Formula Name Function Behavior
DeltaShift LadderFromDeltaShift::ladder This function supposes that the ladders are $L(x) = \frac{(P(x) - P(0))}{x} $ so $PnL(x) = x \cdot L(x)$, the ladder is interpolated between the plots.
LinearIntegration LadderLinearIntegration::ladder This function is computing the surface between two ladders plots as a trapeze to perform an integration of $L(x) \cdot \partial x$.
DerivativeRelative LadderFromDerivativeRelative::ladder This function supposes that $L(x) = \frac{\partial P(x)}{\partial x}$ and use it as a constant sensitivity until the next step for integration.
DerivativeAbsolute LadderFromDerivativeAbsolute::ladder This function supposes that $L(x) = \frac{x \cdot \partial P(x)}{\partial x}$ and use it as a constant sensitivity until the next step for integration.

Adding a new formula

To add a new formula, create a new Extended Plugin that complies with the signature:

@AtotiExtendedPluginValue(intf = ILadderFormulaProvider.class, key = MyLadderFormula.PLUGIN_KEY)
public class MyLadderFormula implements ILadderFormulaProvider {

    public static final String PLUGIN_KEY = "MyLadderFormula";

    @Override public ILadderFormula getLadderFormula() {
        return MyLadderFormula::ladder;
    }
    
    public static double ladder(double shift, double shift1, double ladder1, double shift2, double ladder2, DoubleBinaryOperator pnlFormula,
            FormulaStep currentWindow) {
        //
        // Here comes you formula
        //
    }

    @Override public String getType() {
        return PLUGIN_KEY;
    }
}

The formula has to comply with the ILadderFormula interface. The function will be called and the result summed for each ladder step until the target shift is reached.

Parameter Type Meaning
shift double The target shift we curently compute expressed as $shift = \frac{MD_d}{MD_{d-1} - 1}$
shift1 double The shift of the 1rst ladder plot (closest to the center).
ladder1 double The ladder value of the 1rst plot.
shift2 double The shift of the second ladder plot.
ladder2 double The ladder value of the 2nd plot.
pnlFormula DoubleBinaryOperator The function (sensi, shift) -> PNL coming from IPnLExplainFormulaProvider::getVaRExplainFormula
currentWindow FormulaStep This enum provides the position of the shift against the current ladder interval.
- BELOW: shift is between 0 and shift1
- IN: shift is between shift1 and shift2
- ABOVE: shift is above shift2 (only called when the shift is out of the ladder).

Implementation

Input files

Ladder pillar definition

For details on this input file format, see Ladder Definition.

Datastore

The ladder definition is stored as is in a standalone store.

The ladder sensitivities are stored in the TRADE_SENSITIVITIES datastore.

Each line is split by tenor, maturity, and moneyness according to the scalar model of data.

Cube

The Ladder column is populated by native measures in the Sensitivity Cube. The Cube also has an analysis dimension on the ladder definition, so with an Expand post-processor you can view the content of the ladder.

Calculation logic

The logic is customized with the properties under mr.sensi.rules..pnl-explain. For details on these properties, see Sensitivities module properties.

The InputSelector bean is managing the way the Ladders are applied.

The function IInputSelector::getFormulaInput(@NonNull LadderContext context, @NonNull String sensitivityKind, @NonNull String sensitivityName, @NonNull String riskClass) defines whether the Ladder methodology is applied following the SensitivityInput value by reading the ladder properties:

Ladder Calculation
SENSI_ONLY The formula is applied exclusively to sensitivity inputs, excluding ladders.
LADDER_FIRST The formula attempts to use ladders as input, defaulting to sensitivities if ladders are not available.
LADDER_ONLY The formula is applied exclusively to ladder inputs.

The function IInputSelector::getLadderFormula(@NonNull String sensitivityKind, @NonNull String sensitivityName, @NonNull String riskClass) will return the formula used for ladders depending on the selected methodology defined on the ladder-formula properties.