Bump and Reprice Vanna ladder

Table of Contents

This page defines one report: Bump and Reprice Vanna ladder. It answers how the vega of a book moves when spot moves, so a reader sees the risk that a currency move turns into a volatility position. The trading desk reads it to keep a delta hedge stable across a spot move, and the market risk function reads it to question a book whose hedges drift. It runs at the close on the end of day cycle, and it leaves the engine's own output archive with sensitivity.csv and scenario.csv in it.

1. Purpose

It answers what the cross term between a spot and a volatility is. A vega figure states how the value moves with the surface. A delta figure states how it moves with spot. The cross term states how the vega figure itself moves when spot moves, which is the risk a desk keeps when it hedges each of the two on its own. The decision it feeds is whether a delta hedge holds after spot moves, and how often it must be rebalanced. A book with no cross term keeps its vega through a spot move. A book with a large cross term does not.

The paired rows are vanna. One factor of the pair is a spot and the other is a volatility, and the row carries both Factor_1 and Factor_2. A row that names one factor states a first order figure and belongs to the delta ladder or to the vega ladder. A row that names two states the cross term, and this page reads it.

2. Audience

The trading desk reads the ladder to decide where a delta hedge must be rebalanced as spot moves. The market risk function reads it to see where a volatility position arrives without a trade.

Role What it takes from the report
trading-desk The pair, expiry and strike where the vega of the book moves with spot.
market-risk Where a spot move creates a volatility position that no trade put there.

3. Frequency

Field Value
Cycle end of day
Frequency scheduled, end of day
Batch none
Owner trading-desk

The cycle is end of day. A ladder is read as the risk statement of record and compared across days. A live ladder would be priced against a body that is not reproducible, so the same row on two runs would not be the same figure.

The family seeds no intraday variant of any ladder. A live ladder would need a definition whose cut selection is LIVE, a run settings row whose market data type is live, and the same sensitivity configuration. The store seeds none of the three for this ladder.

4. Inputs

  • Trades selected by scope. The scope is the book or the portfolio that the definition states, and the run prices the trades the gather step selects.
  • Market data for the valuation date. The risk_report_config row states the market data type. This ladder is end of day, so the type is eod and the valuation date is the weekday before the run date. Holiday calendars are not consulted.
  • The six configuration documents the definition binds, one for each configuration type. The types are conventions, curve_configuration, todays_market, pricing_engines, risk_report_config and engine_settings. A definition that omits one of the first five cannot run, because ORE reads all of them before it prices.
  • A spot and a volatility surface to bump. The dataset holds no FX volatility quote, so this input is the one the environment does not supply.
  • The sensitivity configuration document, sensitivity.xml, which states the shift and the pairs.

5. Outputs

The run produces the engine's own output archive. The archive holds sensitivity.csv with the paired rows and the Delta and Gamma columns, and scenario.csv with the scenario value behind each of them. The run records where the archive landed against the run instance.

The tables that would carry the rows a reader queries are designed on Report post-processing and are not built. So a reader opens the CSV files in the archive, and the columns in the next section are the columns of those files.

6. Measures

The values below are the ones the files carry. The definitions of the measures the catalogue names are on Risk reporting and are not repeated here.

Measure Meaning
Base NPV Present value of the trade in the run's base currency, before the shift.
Delta The value change for one bump of a factor. It is money per shift, and the shift size is already inside it.
Gamma The second order figure for one factor, written when ComputeGamma is on.
Vanna The cross term of a paired row, where one factor is a spot and the other a volatility.
Scenario NPV The value of the trade under the shifted market, as scenario.csv states it.
Difference The scenario value less the base value, on the same row of scenario.csv.

7. Columns and sections

A reader places a vanna figure by the two factors the row names and by the two shift sizes. The bucket columns are the ones that break each factor key into the parts a desk thinks in.

Column File Role What it holds
TradeId sensitivity.csv key The trade the row belongs to.
IsPar sensitivity.csv qualifier Whether the row states a par rate figure.
Factor_1 sensitivity.csv qualifier, bucket The first factor key. On a paired row it is one of the two.
ShiftSize_1 sensitivity.csv qualifier, bucket The shift applied to the first factor.
Factor_2 sensitivity.csv qualifier, bucket The second factor key. Populated on a paired row.
ShiftSize_2 sensitivity.csv qualifier, bucket The shift applied to the second factor.
Currency sensitivity.csv qualifier, bucket The currency of the figures on the row.
Base NPV sensitivity.csv measure The value before the shift.
Delta sensitivity.csv measure The first order figure for the row.
Gamma sensitivity.csv measure The second order figure for the row.
Currency(Trade) sensitivity.csv qualifier The currency of the trade.
Base NPV(Trade) sensitivity.csv measure The value before the shift, in the trade currency.
Delta(Trade) sensitivity.csv measure The first order figure, in the trade currency.
Gamma(Trade) sensitivity.csv measure The second order figure, in the trade currency.
Scenario sensitivity.csv qualifier The scenario the row belongs to.
TradeId scenario.csv key The trade the row belongs to.
Factor scenario.csv key, bucket The factor that was shifted.
Up/Down scenario.csv qualifier, bucket Which side of the shift the row states.
Base NPV scenario.csv measure The value before the shift.
ShiftSize_1 scenario.csv qualifier, bucket The shift applied to the first factor.
ShiftSize_2 scenario.csv qualifier, bucket The shift applied to the second factor.
Scenario NPV scenario.csv measure The value under the shifted market.
Difference scenario.csv measure The scenario value less the base value.
Base Currency scenario.csv qualifier The currency the figures are expressed in.

The spot factor key is written FXSpot/<pair>/<index>, and the output formats page shows one as FXSpot/USDEUR/0. The volatility factor key is written FxVolatility/<pair>/<strike>/<expiry>. A vanna row names one of each, so the currency pair is in both keys while the strike and the expiry are in the volatility key alone. The bucket columns of this page are the pair, the expiry and the strike.

8. ORE configuration

A definition of this report binds the sensitivity analytic. The analytic names the sensitivity configuration document, and that document is the one whose root is SensitivityAnalysis. ORE validates it against external/ore/xsd/sensitivity.xsd. The analytic element in the run document states the parameters below.

<Analytic type="sensitivity">
  <Parameter name="active">Y</Parameter>
  <Parameter name="marketConfigFile">simulation.xml</Parameter>
  <Parameter name="sensitivityConfigFile">sensitivity.xml</Parameter>
  <Parameter name="recalibrateModels">Y</Parameter>
  <Parameter name="parSensitivity">Y</Parameter>
  <Parameter name="outputSensitivityThreshold">0.000001</Parameter>
</Analytic>

The SensitivityAnalysis document carries one block for each group of risk factors. The groups are the discount curves, the index curves, the yield curves, the FX spots, the FX volatilities, the swaption volatilities, the cap and floor volatilities, the CDS volatilities, the default and credit curves, the equity spots and volatilities, the two inflation curve families, the two inflation cap and floor families, the dividend yields, the base correlations, the security spreads, the commodity curves and volatilities, the intraday power curves, the correlations and the bond future volatilities. It also carries four switches that are not factors, and ComputeGamma is one of them.

Every factor block states four things. ShiftType is Relative, Absolute or EqualTo. ShiftSize is a real, with an optional key for an alternative size. ShiftScheme is Forward, Backward or Central. The bucket list is one of ShiftTenors, ShiftExpiries, ShiftStrikes, ShiftLossLevels or ShiftTerms. ShiftType and ShiftScheme are enums in external/ore/xsd/ore_types.xsd.

The fragment below is the FX spot and FX volatility part of the shipped external/ore/examples/MarketRisk/Input/sensitivity.xml, trimmed to the first currency pair of each block.

<FxSpots>
  <FxSpot ccypair="USDEUR">
    <ShiftType>Relative</ShiftType>
    <ShiftSize>0.01</ShiftSize>
    <ShiftScheme>Forward</ShiftScheme>
  </FxSpot>
</FxSpots>

<FxVolatilities>
  <FxVolatility ccypair="USDEUR">
    <ShiftType>Relative</ShiftType>
    <ShiftSize>0.01</ShiftSize>
    <ShiftScheme>Forward</ShiftScheme>
    <ShiftExpiries>1Y,2Y,3Y,5Y</ShiftExpiries>
    <ShiftStrikes/>
  </FxVolatility>
</FxVolatilities>

The spot block shifts the pair by one per cent relative. The volatility block shifts every expiry of the same pair by one per cent relative on the forward scheme. Its strike list is empty, and an empty strike list states the at-the-money point of each expiry alone. The two blocks are separate statements about one pair, and the pair of them is what a cross term needs. This ladder buckets by strike, so the configuration it binds states a strike list rather than the empty one the shipped block carries.

The engine writes sensitivity.csv with the columns TradeId, IsPar, Factor_1, ShiftSize_1, Factor_2, ShiftSize_2, Currency, Base NPV, Delta, Gamma, Currency(Trade), Base NPV(Trade), Delta(Trade), Gamma(Trade) and Scenario. It writes scenario.csv with the columns TradeId, Factor, Up/Down, Base NPV, ShiftSize_1, ShiftSize_2, Scenario NPV, Difference and Base Currency. A cross term arrives as a row with both Factor_1 and Factor_2 populated.

The bump is a setting of the configuration and not the identity of the report. Two reports over one book that differ only in shift size differ only in the document they bind. A 0.1 vol point bump means ShiftSize 0.1 on a surface stored in vol points, or Absolute 0.001 on a surface stored in decimals. The store seeds neither, and the store states no shift size at all today.

9. Parameters

A definition of this report states the rows below. Where the store states no value, the column says so. A parameter is declared with its domain on ore parameter, and a configuration binds it on configuration parameter.

Parameter Domain Seeded value Meaning
cut_kind_code a kind of cut EOD The kind of cut the run mints when it starts.
scope book or portfolio none stated The trade set the run reads.
market_data_type live, eod or date eod The market data the run reads, and so the valuation date.
sensitivity.sensitivityConfigFile a file in the file library sensitivity.xml The document that states the shifts.
sensitivity.recalibrateModels Y or N Y Whether models are recalibrated before the bump.
sensitivity.parSensitivity Y or N Y Whether the figures are also written as par rate values.
sensitivity.outputSensitivityThreshold a real 0.000001 The size below which a figure is not written.
FxSpots.ShiftType Relative, Absolute, EqualTo Relative How the shift size is read against the spot.
FxSpots.ShiftSize a real none stated The size of the spot bump.
FxSpots.ShiftScheme Forward, Backward, Central Forward Which side of the spot the bump is measured from.
FxVolatilities.ShiftType Relative, Absolute, EqualTo Relative How the shift size is read against the volatility.
FxVolatilities.ShiftSize a real none stated The size of the volatility bump.
FxVolatilities.ShiftScheme Forward, Backward, Central Forward Which side of the volatility the bump is measured from.
FxVolatilities.ShiftExpiries a list of periods 1Y,2Y,3Y,5Y The expiries the bump lands on.
FxVolatilities.ShiftStrikes a list of strikes empty The strikes the bump lands on. An empty list states the at-the-money point of each expiry alone.
ComputeGamma a switch none stated Whether the engine writes the second order column.

10. A worked read

  1. Open sensitivity.csv from the run's output archive. Open scenario.csv beside it, because it holds the values behind the columns.
  2. Keep the rows where Factor_2 is populated. A row with one factor is a first order figure and belongs to another ladder.
  3. Read the kind of each factor. One is FXSpot and the other is FxVolatility. If both factors are of one kind, the row is a cross gamma and the cross-gamma page reads it.
  4. Read the currency pair from the spot key. Read the strike and the expiry from the volatility key. These are the buckets of the ladder.
  5. Group the rows by pair, by expiry and by strike, in that order.
  6. Read the Gamma column in each bucket. That figure is the cross term. It says how much the vega of the position moves for the spot shift that ShiftSize_1 states.
  7. Check both shift sizes. A cross term is a figure for one pair of shifts, and it is not comparable with a figure taken at another pair.
  8. For one row you doubt, open scenario.csv on the same TradeId and the same factor. Read Scenario NPV and Difference. The difference is the value change for the shift that row states.
  9. Compare two days only when the two runs bound the same sensitivity configuration. A change of shift size changes the scale of every figure on the ladder.

11. What is not built

  • No mapper reads or writes a SensitivityAnalysis document. The document is a name in a lookup and a row in the file library, not a modelled entity.
  • The run package carries only the four Setup documents, conventions, curve configuration, today's market and pricing engines. An analytic document that no owner exports never reaches the engine.
  • No volatility market data is seeded. The ACME dataset holds 420 seeded quotes and all of them are IR_SWAP/RATE/.... so a volatility factor has nothing to shift, and no volatility sensitivity can be computed until the store holds that data. A cross term needs a volatility on one side of the pair, so this ladder cannot be priced in the seeded environment.
  • No shift size is stated anywhere in the store, so the document that would set this ladder has no stored value to read.
  • No stored shape holds a pair of factors as a key. The paired row exists in the CSV file and in no table.
  • The result store is not built, so a reader opens the CSV files and no table answers a query over them.

12. Test coverage

The report has no smoke test of its own. The smoke test that proves the machinery without gathering anything is Sample bundle smoke test.

A test run of this ladder executes the whole pipeline from the gather step and records the run. It stops before the engine has a volatility to shift, for the two reasons above. The run package carries no analytic document, and the dataset seeds no volatility market data. So the report is exercised by the full-pipeline proof and not by a run that writes rows.

13. Related

14. See also

Emacs 29.3 (Org mode 9.6.15)