Gamma Risk#

Calculation#

Gamma, technically cross-gamma, risks are calculated in rateslib in a very similar manner to delta, albeit the expression of the result is more complicated, since cross-gamma risks are a matrix of values, whereas delta risk is typically a vector.

The output is a DataFrame indexed with a hierarchical index allowing the information to be viewed all at once or sliced using pandas indexing tools.

The below gives a full example of constructing solvers with dependency chains, then constructing a multi-currency portfolio and viewing the gamma risks in local and base currencies.

First we initialise the Curve s. A SOFR, ESTR and cross-currency curve for valuing EUR cashflows collateralized in USD.

In [1]: sofr = Curve(
   ...:     nodes={dt(2022, 1, 1): 1.0, dt(2032, 1, 1): 1.0, dt(2042, 1, 1): 1.0},
   ...:     id="sofr"
   ...: )
   ...: 

In [2]: estr = Curve(
   ...:     nodes={dt(2022, 1, 1): 1.0, dt(2032, 1, 1): 1.0, dt(2042, 1, 1): 1.0},
   ...:     id="estr"
   ...: )
   ...: 

In [3]: eurusd = Curve(
   ...:     nodes={dt(2022, 1, 1): 1.0, dt(2032, 1, 1): 1.0, dt(2042, 1, 1): 1.0},
   ...:     id="eurusd"
   ...: )
   ...: 

Then we define our FXForwards object and associations.

In [4]: fxr = FXRates({"eurusd": 1.05}, settlement=dt(2022, 1, 3))

In [5]: fxf = FXForwards(fxr, {
   ...:     "eureur": estr,
   ...:     "eurusd": eurusd,
   ...:     "usdusd": sofr
   ...: })
   ...: 

Then we define the instruments that will be incorporated into our Solver s.

In [6]: instruments = [
   ...:      IRS(dt(2022, 1, 1), "10y", "A", currency="usd", curves="sofr"),
   ...:      IRS(dt(2032, 1, 1), "10y", "A", currency="usd", curves="sofr"),
   ...:      IRS(dt(2022, 1, 1), "10y", "A", currency="eur", curves="estr"),
   ...:      IRS(dt(2032, 1, 1), "10y", "A", currency="eur", curves="estr"),
   ...:      XCS(dt(2022, 1, 1), "10y", "A", currency="usd", leg2_currency="usd", curves=["estr", "eurusd", "sofr", "sofr"]),
   ...:      XCS(dt(2032, 1, 1), "10y", "A", currency="usd", leg2_currency="eur", curves=["estr", "eurusd", "sofr", "sofr"]),
   ...:  ]
   ...: 

Then we solve the SOFR and ESTR curves independently given local currency swap markets.

In [7]: sofr_solver= Solver(
   ...:     curves=[sofr],
   ...:     instruments=instruments[:2],
   ...:     s=[3.45, 2.85],
   ...:     instrument_labels=["10y", "10y10y"],
   ...:     id="sofr",
   ...:     fx=fxf
   ...: )
   ...: 
SUCCESS: `func_tol` reached after 6 iterations (levenberg_marquardt), `f_val`: 6.1823256691788175e-15, `time`: 0.0231s

In [8]: estr_solver= Solver(
   ...:     curves=[estr],
   ...:     instruments=instruments[2:4],
   ...:     s=[2.25, 0.90],
   ...:     instrument_labels=["10y", "10y10y"],
   ...:     id="estr",
   ...:     fx=fxf
   ...: )
   ...: 
SUCCESS: `func_tol` reached after 6 iterations (levenberg_marquardt), `f_val`: 2.2273797378672649e-13, `time`: 0.0227s

Finally we solve the cross-currency solver with a dependency to the single currency markets, as specified within the pre_solvers argument.

In [9]: solver= Solver(
   ...:     curves=[eurusd],
   ...:     instruments=instruments[4:],
   ...:     s=[-10, -15],
   ...:     instrument_labels=["10y", "10y10y"],
   ...:     id="eurusd",
   ...:     fx=fxf,
   ...:     pre_solvers=[sofr_solver, estr_solver],
   ...: )
   ...: 
SUCCESS: `func_tol` reached after 4 iterations (levenberg_marquardt), `f_val`: 3.01104003064156e-17, `time`: 0.0661s

Now we create a multi-currency Portfolio and calculate its cross-gamma.

In [10]: pf = Portfolio([
   ....:     IRS(dt(2022, 1, 1), "20Y", "A", currency="eur", fixed_rate=2.0, notional=1e8, curves="estr"),
   ....:     IRS(dt(2022, 1, 1), "20Y", "A", currency="usd", fixed_rate=1.5, notional=-1.1e8, curves="sofr")
   ....: ])
   ....: 

In [11]: cgamma = pf.gamma(solver=solver, base="eur")

In [12]: cgamma
Out[12]: 
type                                            instruments                                         fx
solver                                                 sofr           estr        eurusd            fx
label                                                   10y 10y10y     10y 10y10y    10y 10y10y eurusd
local_ccy display_ccy type        solver label                                                        
eur       eur         instruments sofr   10y           0.00   0.00    0.00   0.00   0.00   0.00   0.00
                                         10y10y        0.00   0.00    0.00   0.00   0.00   0.00   0.00
                                  estr   10y           0.00   0.00 -102.97 -81.01   0.00   0.00   0.00
                                         10y10y        0.00   0.00  -81.01 -87.84   0.00   0.00   0.00
                                  eurusd 10y           0.00   0.00    0.00   0.00   0.00   0.00   0.00
                                         10y10y        0.00   0.00    0.00   0.00   0.00   0.00   0.00
                      fx          fx     eurusd        0.00   0.00    0.00   0.00   0.00   0.00   0.00
usd       eur         instruments sofr   10y          74.43  58.88    0.04  -0.00   0.04  -0.00   6.76
                                         10y10y       58.88  63.69    0.03  -0.00   0.03  -0.00   5.72
                                  estr   10y           0.04   0.03   -0.00   0.00  -0.00   0.00  -0.00
                                         10y10y       -0.00  -0.00    0.00  -0.00   0.00  -0.00   0.00
                                  eurusd 10y           0.04   0.03   -0.00   0.00  -0.00   0.00  -0.00
                                         10y10y       -0.00  -0.00    0.00  -0.00   0.00  -0.00   0.00
                      fx          fx     eurusd        6.76   5.72   -0.00   0.00  -0.00   0.00  -0.47
          usd         instruments sofr   10y          78.23  61.85    0.00   0.00   0.00   0.00   0.00
                                         10y10y       61.85  66.87    0.00   0.00   0.00   0.00   0.00
                                  estr   10y           0.00   0.00    0.00   0.00   0.00   0.00   0.00
                                         10y10y        0.00   0.00    0.00   0.00   0.00   0.00   0.00
                                  eurusd 10y           0.00   0.00    0.00   0.00   0.00   0.00   0.00
                                         10y10y        0.00   0.00    0.00   0.00   0.00   0.00   0.00
                      fx          fx     eurusd        0.00   0.00    0.00   0.00   0.00   0.00   0.00
all       eur         instruments sofr   10y          74.43  58.88    0.04  -0.00   0.04  -0.00   6.76
                                         10y10y       58.88  63.69    0.03  -0.00   0.03  -0.00   5.72
                                  estr   10y           0.04   0.03 -102.97 -81.01  -0.00   0.00  -0.00
                                         10y10y       -0.00  -0.00  -81.01 -87.84   0.00  -0.00   0.00
                                  eurusd 10y           0.04   0.03   -0.00   0.00  -0.00   0.00  -0.00
                                         10y10y       -0.00  -0.00    0.00  -0.00   0.00  -0.00   0.00
                      fx          fx     eurusd        6.76   5.72   -0.00   0.00  -0.00   0.00  -0.47

We can slice this to display only the EUR risk.

In [13]: idx = ("eur", "eur", slice(None), ["estr", "fx"], slice(None))

In [14]: cgamma.loc[idx, (slice(None), ["estr", "fx"], slice(None))]
Out[14]: 
type                                            instruments            fx
solver                                                 estr            fx
label                                                   10y 10y10y eurusd
local_ccy display_ccy type        solver label                           
eur       eur         instruments estr   10y        -102.97 -81.01   0.00
                                         10y10y      -81.01 -87.84   0.00
                      fx          fx     eurusd        0.00   0.00   0.00