Swap calculation anomaly when using discount factors

Hey Strata team,

I’m seeing some strange results when loading DF-based curves (as opposed to zero rates).
I might be misunderstanding something here - but shouldn’t I be getting the exact same results if I swap my zero curves with their “twin” df curves?

Here is a full reproduction using the “SwapPricingExample” as reference (this is on the v1.0.0 commit):

  1. Create DiscountTest.java next to SwapPricingExample - http://pastebin.com/raw/u9ALL6cZ
  2. Create bug-report.ini next to swap-report-template.ini - http://pastebin.com/raw/pYJK4p2Y
  3. In example-marketdata/curves/2014-01-22.csv replace the values for USD-Disc and USD-3ML with their discount factor replacements (produced via df = exp(-rT)) - http://pastebin.com/raw/bcambJh8
  4. In example-marketdata/curves/settings.csv replace the Value Type for both from Zero to df

Running the test gives me the following:

with zero rates:
| Id |          NPV |      PV01 |
| 1  | 5,965,705.04 | 62,626.50 |

with discount factors:
| Id |          NPV |       PV01 |
| 1  | 6,047,308.43 | (1,067.91) |

Any idea what’s happening? Is this a bug or am I misunderstanding the value types?

I see you’re using the same interpolator (Linear) on the zero and discount factor curves. This will cause some difference when projecting rates and discounting cashflows.

To illustrate, I ran some quick and dirty analysis via our Strata Excel integration to visualise the impact.

The example sheet plots zero rates from a simple linearly-interpolated zero curve (blue) along with those from a DF curve built using corresponding DFs at the pillar points (red). A DF curve instance is created and then sampled at biannual intervals. The resulting DFs are then converted back into zero space and plotted. (Continuous compounding is used throughout).

Strata doesn’t currently have a DF interpolator whose resulting DFs map to linearly interpolated zero rates. It wouldn’t be too difficult to add one of your own though by extending the CurveInterpolator interface.

Regarding the PV01 result, PV01 reports sensitivity to a positive 1BP shift in the underlying curve. You would expect the discount factor sensitivities to be in the opposite direction to the zero rate sensitivities since they are inversely correlated with each other. (i.e. DF decreases as the rate increases).

1 Like

Thanks Tim.
I always thought that PV01 is the sensitivity to the underlying rates curve (not the literal underlying curve) - I guess that’s the root misunderstanding.

If you use Measures.PV01_MARKET_QUOTE_SUM instead of Measures.PV01_CALIBRATED_SUM you will get sensitivity to the par rates even when you use a discount factor based curve (in the report template this would be referred to as “Measures.PV01MarketQuoteSum”).

Internally, the class MarketQuoteSensitivityCalculator is used to convert the calibrated form to the market quote form.