QuantLib: setting up QuantLib-Python and pricing an option

It has been a while since my last post series, today is the first post in a mini-series on the fantastic QuantLib-Python library, where I will present an investigation of various instruments, pricing models and calibration choices, along with the code to generate them yourselves. My thanks to everyone in the QuantLib team who have been supporting and extending this library now for most of 20 years. I’m going to assume a working knowledge of python and that you have a Python 3 setup installed locally. Later posts will also assume some familiarity with the wonderful Pandas library (and possibly numpy and matplotlib…)

First thing you will to do is install the library, which should be as easy as typing pip install QuantLib==1.19 in the command line (this is the current latest version, released July 20th 2020).

QuantLib does a great job of separating out all of the components of a pricing problem, and also of helping to deal with annoying things like interpolation, day count conventions, calibration of discount curves and so on. A typical pricing script will have a few pieces:

  1. Setting up the world state, with asset prices, curves, dates and calendars etc.
  2. Choosing a pricing engine for your product which determines how the pricing is done (eg. Monte Carlo, Analytic…)
  3. Setting up the instrument to price (eg. payment dates, strike, contract type)
  4. Linking the engine and the security, and pricing!

In this first post, I’m going to illustrate the process by showing how to price a fixed coupon bond and a vanilla option in a world with constant rates and a single asset following a constant vol BS process. In future posts we’ll look at some more exciting applications of QuantLib.

First, we set up the world state:

import QuantLib as ql

# Setting up our universe with a single asset and rates curves
spot = 100
vol = 0.1
rate, divi_rate = 0.01, 0.0
today = ql.Date(2, 7, 2020)
day_count = ql.Actual365Fixed()
calendar = ql.NullCalendar()

volatility = ql.BlackConstantVol(today, calendar, vol, day_count)
riskFreeCurve = ql.FlatForward(today, rate, day_count)
diviCurve = ql.FlatForward(today, divi_rate, day_count)

flat_ts = ql.YieldTermStructureHandle(riskFreeCurve)
dividend_ts = ql.YieldTermStructureHandle(riskFreeCurve)
flat_vol = ql.BlackVolTermStructureHandle(volatility)

Hopefully this should all be quite self-explanatory – we use the ql.BlackConstantVol and ql.FlatForward classes to create constant vol and constant rates curves. Perhaps the only slightly mysterious lines are ql.YieldTermStructureHandle and ql.BlackVolTermStructureHandle – we will see classes of the Handle again and again, they act as packaging for the underlying curves which might be of different types depending upon how they were calibrated (eg. from ZCBs? from rates or swap curves?), and give the curves a common interface for the pricer to use later.

Now, let’s set up a bond and bond pricing engine (just an analytic discount engine), and price the bond:

# Create a bond instrument
start_date, end_date = ql.Date(1, 1, 2016), ql.Date(1, 1, 2022)
coupons = [0.02]
coupon_freq = ql.Period(ql.Semiannual)
settlement_days = 0
face_value = 100

bond_instrument = ql.FixedRateBond(settlement_days, calendar, face_value, start_date, end_date, coupon_freq, coupons, day_count)

# Put the yield curve into a curve handler, pass to a bond pricing engine
bond_engine = ql.DiscountingBondEngine(flat_ts)

# Pair the bond engine and the bond, and price!


print("Cashflows remaining: ")
for c in bond_instrument.cashflows():
    print('%20s %12f' % (c.date(), c.amount()))

Here is what I see… the analytic price of the bond’s remaining cashflows (plus accrued interest, if relevant), and also the cashflow termsheet for the bond:

Price and cashflows for a simple bond

And now I calculate the price and delta for a vanilla call option in the same way, this time using an analytic BS pricer:

expiry_date = ql.Date(1, 7, 2021)
strike = 100

# Set up the option payoff
option = ql.EuropeanOption(ql.PlainVanillaPayoff(ql.Option.Call, strike), ql.EuropeanExercise(expiry_date))

# Run pricing
process = ql.BlackScholesProcess(ql.QuoteHandle(ql.SimpleQuote(spot)), flat_ts, flat_vol)
engine = ql.AnalyticEuropeanEngine(process)


Which should create the following prices:

Price and delta for vanilla call

Bond Pricing: Roll PnL

This is a series of short posts examining the bond markets and some of the key pricing, risk and quoting concepts (with EXAMPLES!) –
        The Yield Curve
        Duration/Convexity and DV01
        Spread Quoting
        Roll PnL

Holding bonds leads to several sources of PnL. Bonds pay coupons periodically, and this must be set against your cost of financing (generally a cost if you are borrowing to buy, and a benefit if you sell short and take cash – although shorts will incur a borrowing cost). As we have seen before, interest rate and credit spread moves in the market will cause positional PnL according to your DV01. There are several other factors to think about (I’ll do a full ‘PnL Explain’ post soon), but one of the most interesting is what dealers call ‘Roll PnL’, since it comes from a position rolling down the yield curve (in this piece I discuss Roll PnL for bonds, but exactly the same principle applies for CDS contracts, which are effectively just a portfolio that is long a credit-risky bond and short the corresponding risk-free bond).

Holding a position with an upward-sloping yield curve causes market yield of the asset to fall, realising a cash PnL

Consider the yield curve above. The YtM for 3y is 3%, and the YtM for 2y is 2.2%. If we buy a bond with 3y to maturity and hold it for a year, its maturity will of course fall to 2y – so assuming the yield curve stays fixed, the yield of the bond set by the market will now be 2.2%, and as we’ve seen before a fall in yield means an increase in price.

Concretely, considering for simplicity a ZCB, ets imagine we borrow $100 at the 3y risk-free rate of 3% and buy a risk-free ZCB, which we hold for a year. The PnL over the year will be

(1)   \begin{align*} = & \frac{100}{(1 + 0.022)^2} - \frac{100}{(1 + 0.03)^3} - 3 \nonumber \\ = & \Bigl( \frac{100}{(1 + 0.022)^2} - \frac{100}{(1 + 0.03)^2} \Bigr) + \Bigl( \frac{100}{(1 + 0.03)^2} - \frac{100}{(1 + 0.03)^3} \Bigr) - 3 \nonumber \\ = & \Bigl( \frac{100}{(1 + 0.022)^2} - \frac{100}{(1 + 0.03)^2} \Bigr) + \Bigl( \frac{3}{(1 + 0.03)^3} \Bigr) - 3 \nonumber \\ \simeq & 100 * 2 * (0.03 - 0.022) \nonumber \end{align*}

leading to a Roll PnL of about $1.50 (after financing costs – on the tenuous assumption that we can borrow at the risk-free rate!)

Mathematically, increasing value with decreasing time means that a bond has a positive theta. We can calculate this using the chain rule

(2)   \begin{align*} \Theta = -\frac{\delta C(t)}{\delta t} & = \frac{\delta}{\delta t} \sum_{i=1}^N \frac{CF(t_i) }{(1 + r_y)^{t_i}} \nonumber \\ & = -\sum_{i=1}^N CF(t_i) \cdot \frac{\delta}{\delta t} \frac{1}{(1 + r_y)^{t_i}} \nonumber \\ & = -\sum_{i=1}^N CF(t_i) \cdot \Bigl( \frac{-\ln{(1 + r_y)}}{(1 + r_y)^{t_i}} - \frac{t_i}{1+r_y} \cdot \frac{\delta r_y}{\delta t_i} \Bigr) \nonumber \\ & \simeq \sum_{i=1}^N \frac{CF(t_i) \cdot r_y}{(1 + r_y)^{t_i}} + \sum_{i=1}^N \frac{CF(t_i) \cdot t_i}{1+r_y} \cdot \frac{\delta r_y}{\delta t_i}  \end{align*}

and from our concrete example in Eq. 1, we recognise the first of these terms as the ‘financing cost’ of the portfolio, and the second term as the Roll PnL (ie. proportional to the local derivative in the yield curve for each payment)

Bond Pricing: Z-Spread

This is a series of short posts examining the bond markets and some of the key pricing, risk and quoting concepts (with EXAMPLES!) –
        The Yield Curve
        Duration/Convexity and DV01
        Spread Quoting
        Roll PnL

An alternative to the spread-to-benchmark for a credit-risky bond that tries to capture the full shape of the yield curve is the Z-Spread.

Since govvies are ‘risk-free’, we should be able to recover the market price of a govvie by discounting each of its cashflows using the discount factor coming from the point on the yield curve that the payment occurs*. If we perform the same calculation for a higher-yielding corporate bond, but offset the yield curve that we use for discounting by a fixed amount \Delta at each cashflow payment such that the sum of the PVs of the cashflows matches the bond’s traded price, then this \Delta is the bond’s Z-Spread (in this case, interpolation IS used to find discount factors at each time).

A yield curve implied from govvies, and another offset by a constant Z-Spread of 1.1%. On the right axis, the corresponding discount curves

In the graph above, we show the effect of this parallel shift of the yield curve on the discount factors that we use to discount the payments at each time coming from the risky coupon. A larger spread between the two yield curves leads to a more rapidly falling discount curve and lower prices for credit bonds.

Putting this together, we can find the Z-Spread by fixing \Delta to solve the equality

(1)   \begin{align*} C(t) &= \sum^{N}_{i=1} CF(t_i) \cdot \frac{1}{\Bigl(1 + ( r_{gy}(t_i) + \Delta ) \Bigr)^{t_i}} \end{align*}

where C(t) is the market price of the bond, CF(t_i) are the cashflows at each time t_i, and r_{gy}(t_i) is the govvie yield at time t_i interpolated from the yield curve (compare this to the equality we had to solve to calculate YtM, discussed in an earlier post).

What is the advantage of the Z-Spread over the plain spread to benchmark? Firstly, as we interpolate discount factors to each coupon payment date, we come up with a measure that behaves continuously as maturity and coupon payment dates increase, where spreads jump as benchmarks bonds change along the curve. Secondly, the Z-Spread gives us some measure of how much pickup we are getting over the risk-free payment we would receive for our bond, so Z-Spread gives us a good quantity for comparing similar maturity bonds from different issuers or bonds at different points on the curve from a single issuer (‘Relative Value’ ideas involving going long one bond and short another are often quoted in terms of the Z-Spread pickup that the Asset Manager will achieve). Practically, as seen below, spread and Z-Spread are typically fairly similar when maturity date and payment date of the benchmark and the corp bond are close to overlapping.

*Note the subtle implication here – the yield curve shows the return for a zero coupon bond, coupon-bearing bonds will display a slightly different yield than the yield curve implies for their maturity, as discussed in an earlier post. This effect is very, very small except for long-dated bonds with large coupons, as shown in the example.

Example: assuming the yield curve for USD has the values shown in the table in the image below, calculate the Z-Spread for a BB-rated corp bond paying a 6% coupon with 4 years left to maturity and trading at $104 (paying biannual coupons, assume it recently paid a coupon and this is reflected in the pricing).

Data to go with the Z-Spread example

Answer: Since the bond pays bi-annual coupons, we’ll need to discount a $3 payment at each 6m interval out to 4 years. The table is missing a 3.5y point so let’s interpolate linearly between 3y and 4y, giving 3.1% ytm for that point. Discount factors can be approximated as (1+r_y+\Delta)^t where t is time in years, and the sum-product of these with the relevant cashflow payments should be the traded price of $104, which hopefully leads you to a calibrated Z-Spread of \Delta=1.804%

Bonus: Consider the govvies used to build the yield curve. Imagine that they all paid 5% coupons (biannual payments). Discount each payment according to the yield curve to determine what their traded price should be today, and then use the YtM formula from the Yield Curve post to determine their yield to maturity. Observe that is is close to, but not the same as, the yield curve’s yield (eg. for the bond maturing in 3y, the YtM should be 2.96% – so note that coupon bearing bonds should have a YtM BELOW that of a ZCB for an upward-sloping yield curve, reflecting that these bonds return a portion of your investment earlier than maturity as coupons, which the market is pricing ass less risky).

Bond Pricing: Spread Quoting

This is a series of short posts examining the bond markets and some of the key pricing, risk and quoting concepts (with EXAMPLES!) –
        The Yield Curve
        Duration/Convexity and DV01
        Spread Quoting
        Roll PnL

Corporate bonds give a higher yield than govvies, reflecting their increased credit risk – the chance that the company defaults before the investor receives – their payment on the bond. The difference between these two is called the ‘Credit Spread’ – and typically the lower the credit rating of the company, the higher the yield investors will demand to purchase the bonds, so this spread will be larger. Because of this, corporate bonds are sensitive to two risk factors – interest rates in the bond’s currency, and the credit risk of the issuer.

If govvie yields (and hence interest rates) in a given currency increase, existing fixed rate bonds will be less valuable and the price will fall in order to increase yields to reflect the new govvie yield. Similarly, if the credit rating of the issuer declines, bonds it has issued see price declines as the spread to govvie bonds increases to reflect the new, increased credit riskiness of the bonds.

Investors seeking exposure to interest rates will typically buy govvies – and some will go long corporate bonds to gain an additional yield pickup over the risk-free govvies. On the other hand, specialist credit investors often seek exposure only to the credit riskiness of corporate bonds, and for these investors the sensitivity to interest rate risk is unwanted. To hedge this risk out, they will often trade bond ‘switches’, going long a corporate bond and simultaneously short the govvie benchmark bond with the closest maturity to the corporate bond in question, to neutralise the interest rate risk.

An example corp curve showing the spread over govvies, which typically increases with maturity, and is steeper for lower-rated bonds

Because switches are traded so often, for most highly-rated investment grade bond, dealers will quote them not by price or by yield, but instead by the spread between a bond and its govvie benchmark. The investor typically transacts both legs of the switch simultaneously with the dealer. A practical advantage of this way of quoting is that even if there are interest rate movements between the time of quoting and the time the trade is transacted, the spread between the two bonds is highly insensitive to them and rarely needs requoting (interest rates typically move much more frequently than credit spreads).

An example corp curve is shown above with the corresponding govvie curve in the diagram. Note that no interpolation is performed – a govvie with a nearby maturity is chosen as a benchmark, which can lead to small maturity mismatch.

Once a deal is agreed, the investor and the dealer must still agree on the Spread-to-Price conversion. This is done in two steps – the spread between the corporate bond and the govvie bond, plus the yield of the govvie, gives the equivalent YtM r_y for the corporate bond. This is then converted into a price by discounting all of the bonds payments using r_y as a risky discount factor.

Example: an AAA-rated corporate bond with three remaining annual coupon payments of 4%, which also returns notional of $100 at maturity (assume the most recent coupon was paid recently and the price already reflects this), is quoted bid-offer at 65-60 bps spread to the govvie benchmark which is quoted at 2.2% YtM, expires in 2.75 years, and pays biannual coupons at 1.8%. What is the approximate cash price to buy the corporate bond?

The only relevant quantities here are the corp spread to govvie, the govvie YtM, and the payments remaining on the corp. Since the govvie has a YtM of 2.2%, and the corp ask-quote is 60 bps (we’re buying the bond*, so the ask price is the relevant spread), we pay a price that implies a YtM of 2.8%

    \[\text{Price} = \frac{\$4}{(1 + 0.028)} + \frac{\$4}{(1 + 0.028)^2} + \frac{\$104}{(1 + 0.028)^3}\]

Performing the calculation this way round doesn’t require a solver – plugging in the r_y value from the quotes, we get a price of $103.41.

Note that the govvie here has a YtM higher than its coupon payments so is trading below par – despite its credit riskiness, the corp bond is more valuable due to its higher coupon payments. In yield terms the relative price relationship is much clearer.

*An interesting point to note from this example is that we typically think of dealer bid prices being lower than offer prices. This is of course true with spread-priced bonds, but as a lower price corresponds to a larger yield/spread, the larger spread is actually the bid price (ie. the YtM/spread that the trader would receive if she buys the bond from you)

Bond Pricing: Duration/Convexity and DV01

This is a series of short posts examining the bond markets and some of the key pricing, risk and quoting concepts (with EXAMPLES!) –
        The Yield Curve
        Duration/Convexity and DV01
        Spread Quoting
        Roll PnL

For dealers who buy and sell bonds, the change of a value of a portfolio as market rates change will be extremely important. As we discussed in the previous post, yields of bonds will typically rise and fall along with market-implied yields coming from risk-free treasuries, and having some quantities that capture the first-order magnitude of this change is useful – such first order measures are especially easy to handle as they sum linearly across a portfolio.

If market yields fall, the price of already-issued bonds will typically rise. To measure this, we define the ‘Duration’ of a bond to be the percentage decrease in a bond’s price as yields rise by 1%. From before, the value of a bond expressed in terms of YtM is

(1)   \begin{align*} C(t) &= \sum_{i=1}^N CF(t_i) \cdot \frac{1}{(1 + r_y)^{t_i}} \nonumber \\ \text{Duration} = \frac{1}{V} \frac{\delta C(t)}{\delta r_y} &= \frac{1}{V} \sum_{i=1}^N CF(t_i) \cdot \frac{\delta}{\delta r_y} \Bigl( \frac{1}{(1 + r_y)^{t_i}} \Bigr) \nonumber \\ & = \frac{1}{V \cdot (1 + r_y)} \sum_{i=1}^N \frac{CF(t_i) \cdot t_i}{(1 + r_y)^{t_i}} \nonumber \end{align*}

This last term looks complicated, but all it is is the duration-weighted sum of cash-flows, discounted by the YtM (and divided by 1+r_y, but this is likely to be very close to 1), so we see why ‘Duration’ is a sensible name for this risk measure!

Very often, rather than the relative change in the bond price due to the yield change, we will be interested in the absolute, dollar-value of the change (ie. the PnL of the portfolio). The measure often used here is DV01 – the dollar value of a 1bp (ie \frac{1}{100} of 1%) move in YtM

(2)   \begin{align*} \text{DV01} &= V \cdot \text{Duration} \cdot \frac{1}{10000} \nonumber \\ & = \frac{1}{10000 \cdot (1 + r_y)} \sum_{i=1}^N \frac{CF(t_i) \cdot t_i}{(1 + r_y)^{t_i}}\nonumber \end{align*}

which is very close to the discounted duration-weighted present value of the cashflows.

If a portfolio is constructed with DV01 close to 0, it will be fairly insensitive to YtM changes. However, note that we haven’t specified where the yield change came from – it could be coming from a change in the yield curve coming from govvie prices changing, or from a widening credit spread for corporate bonds. Changes in just the credit spread, for example, will affect the yields of some bonds more than others and a crudely hedged portfolio might suddenly show PnL.

Example: a portfolio is constructed made up of positions on two bonds A and B, both United States Treasuries paying bi-annual coupons. A has 3.5 years left to run, pays 2.5% annually and is priced at $99 on the market; B has 2 years left to run, pays 3% annually and is priced at $101 on the market. The portfolio is made up of $1MM face value of bond A. How large a short position should the portfolio manager hold in position B for the portfolio to be DV01-flat? What risk remains in the portfolio? (as usual, assume bonds have recently paid a coupon and that’s already reflected in the pricing)

First, we calculate the yield for each bond as described in the previous post (not forgetting that as coupons are bi-annual, they are each half of the annual total). A trades at YtM of 2.82%, and B trades at YtM of 2.5%.

Next we use these YtMs to calculate the unit DV01 of the bonds fromthe equation above. A has a DV01 of 0.00325 $/bp, while bond B has a DV01 of 0.00193. Since the ratio of these is 1.68, a short position of $1.68MM face value of bond B is required to flatten the DV01 of the portfolio.

Because we have used DV01 with bonds of different maturity to flatten the risk, we are immune to parallel shifts in the yield curve – ie. those that increase or decrease the yield of both bonds by the same amount. However, if the yield moves to become steeper or shallower, this will increase/decrease the yield of one bond more than the other, and our simple hedge will not be sufficient to prevent PnL.

Bond Pricing: The Yield Curve

This is a series of short posts examining the bond markets and some of the key pricing, risk and quoting concepts (with EXAMPLES!) –
        The Yield Curve
        Duration/Convexity and DV01
        Spread Quoting
        Roll PnL

As discussed in a previous post, bonds give investors a way to lock up their capital in return for a stream of coupon payments, with the full initial payment returned at maturity. Mathematically, the undiscounted payoff is very straightforward:

    \[\text{Payoff} = \sum_{i=1}^N CF(t_i)\]

where the cashflows CF(t_i) are typically annual or bi-annual, fixed percentages of the notional – and include the return of the notional at expiry.

After issuance, bond markets set the prices of bonds at each maturity. Typically government bonds – ‘govvies’ – in each currency set the overall ‘Yield Curve’ for the currency, which is the relationship between the rate of return against the length of investment (govvies are usually thought to be ‘risk free’ if denominated in the local currency as the government can print money to make repayments). Corporate bonds in each currency will trade at higher prices than govvies, with the ‘spread’ between a bond and a govvie determined by the market’s view of its credit-riskyness.

Bonds with higher coupons will typically be worth more to investors as they result in larger payments. However, if markets are efficient we expect that regardless of the coupons, $100 invested in two bonds from the same issuer that mature at the same time should yield the same return (otherwise, investors would pile out of one and into the other). The ‘Yield-to-Maturity’ (YtM) is a concept that captures this – it is the annually compounded rate of return expected from buying a given bond:

    \[C(t) = \sum_{i=1}^N CF(t_i) \cdot \frac{1}{(1 + r_y)^{t_i}}\]

Where C(t) is the market price of the bond, and r_y is the YtM of the bond, calibrated to satisfy the equality. Note that if the price of a bond traded on the market goes up, its calibrated YtM will fall, and vice versa.

Example: a United States Treasury (UST) has 2 years remaining until maturity, pays bi-annual 3% coupons and returns $100 at maturity. It is currently trading at $102.50. What is its YtM (assume it has already paid out its most recent coupon)?

This bond generates four payments of $1.5 in 6m, 12m 18m and 24m, and additionally returns $100 notional at 24m. The YtM is chosen to satisfy this equality:

    \[\$101.50 = \frac{\$1.50}{(1 + r_y)^{0.5}} + \frac{\$1.50}{(1 + r_y)} + \frac{\$1.50}{(1 + r_y)^{1.5}} + \frac{\$101.50}{(1 + r_y)^2}\]

Plugging this in to a root solver (eg. via excel) we find that this price implies a r_y of 1.731%. Note that, if this bond was trading at par (ie. $100) its YtM would equal its coupon rate of 3%. As the price is above par, the calculated YtM is below this.

When trading govvies, rather than quoting the price of a particular bond, dealers will usually quote the price in terms of its YtM, so that the return expected from a bond is more easily compared to other securities. Typically bonds with longer maturities will trade with a higher YtM, and for each currency we can use the liquidly-traded govvies to create a yield curve for this currency.

Because of this relationship, one way a portfolio manager can increase the yield of her portfolio is to increase its maturity profile by trading shorter-dated bonds for longer-dated bonds which will have a higher yield (although as we will see later, this also increases the interest rate risk of the portfolio).

An example Yield Curve is shown below for USD as of 22nd December 2017 from the US Treasury website:

Yield curves for USTs in early and late December 2017, built from US Treasury data

Calibrating time-dependent volatility to swaption prices

We have seen in a previous post how to fit initial discount curves to swap rates in a model-independent way. What if we want to control the volatility parameter to match vanilla rates derivatives as well? Just as we found for vanilla calls and puts, we will need to chose a model, for example the Hull-White extended Vasicek (HWeV) model that we’ve seen before (there are a few reasons why this isn’t a great choice, discussed later).

    \[dr = \Bigl( \theta(t) - ar(t) \Bigr) dt + \sigma(t) dW_t\]

Our next choice is which vanilla rates options we want to use for the calibration. A common choice is the interest rate swaption, which is the right to enter a swap at some future time T with fixed payment dates \{T_i\} > T and a strike X. These are fairly liquid contracts so present a good choice for our calibration. A ‘payer swaption’ is one in which we pay fixed and recieve floating, and a ‘receiver swaption’ is the opposite. For simplicity, for the rest of this post we will assume all payments are annual, so year fractions \tau are ignored.

A reciever swaption can be seen as a call option on a coupon-paying bond with fixed payments equal to X at the same payment dates as the swap. To see this, consider the price of a swap discussed before:

    \[S(t,\{T_i\}, X) = P(t,T_N) - P(t,T_0) + \sum^N_{i=1} X \cdot P(t,T_i)\]

where t is the time now. This is exactly the same as the price of buying a unit of bond at time T_0 for $1, receiving the fixed coupons X at each payment period, and receiving the original notional back at time T_N.

So, the price of a swaption is an option on receiving a portfolio of coupon payments, each of which can be thought of as a zero-coupon bond paid at that time, and the value of the swaption is the positive part of the expected value of these:

    \[C(t, T_0, T_N, K, X) = P(t,T_0) \cdot {\mathbb E}\Bigl[ \Bigl( K - \sum^N_{i=1} X \cdot P(t,T_i) \Bigr)^+ \Bigr]\]

where the cash payments have been replaced by the strike of the option (the only ‘notional’ payment that will be paid)

This isn’t readily tractable, but we make use of Jamshidian’s decomposition (I won’t go further here – this is worth it’s own post!) to re-write this with the max inside the summation:

    \[C(t, T_0, T_N, K, X) = P(t,T_0) \cdot {\mathbb E}\Bigl[ \sum^N_{i=1} \Bigl( K_i - \cdot P(t,T_i) \Bigr)^+ \Bigr]\]

where K_i is the price of a ZCB at time T_0 expiring at T_i if rates at T_0 make the value of the coupon-bearing bond equal to X.

Looking at this expression, we see that each term is simply the present value of an option to buy a ZCB at time T that expires at one of the payment dates T_i with strike K_i. So the price of a swaption has been expressed entirely as the price of a portfolio of options on ZCBs!

For the HWeV model, these are deterministic and depend only on the initial rate, and calibrated time dependent parameters in the model. Since rates are gaussian in HWeV this can be done analytically. Calculating these for time-varying parameters is algebra-intensive and I leave it for a later post, but for constant parameters the calculation is described in Brigo and Mercurio pg 75-76 and gives a price of

    \begin{align*} ZBC(t,T_0,T_i,K) &= P(t,T_0) {\mathbb E}\Bigl[ K - X \cdot P(t,T_i) \Bigr]^+ \nonumber \\ &= P(t,T_i) \cdot \Phi(h) - X \cdot P(t,T_0) \cdot \Phi(h-\sigma_p) \nonumber \end{align*}


    \begin{align*} \sigma_p &= \sigma \sqrt{\frac {1-e^{-2a(T_0 - t)}} {2a}} B(T_0,T_N) \nonumber \\ h &= {\frac 1 {\sigma_p}} \ln{\frac {P(t,T_N)} {X \cdot P(t,T_0)}} + {\frac {\sigma_p} 2} \nonumber \\ B(T_0,T_N) &= {\frac 1 a} \Bigl[ 1 - e^{-a(T_N - T_0)}\Bigr] \nonumber \end{align*}

We can see how we could use the above to calibrate the volatility parameter to match a single market-observed swaption price. When several are visible, the challenge becomes to choose a piecewise continuous function to match several of them. In HWeV this can be done analytically, but for more general models some sort of optimisation would be required.

Since these contracts have an exercise date T when the swap starts and the swaps themselves will have another termination date T_N which define a 2-dimensinal space \{T,T_N\}, it will not be possible to fit all market-observable swaptions with a one factor model. Many alternatives are discussed in the literature to deal with this concern, but the general procedure is the same. Practically, we should choose the most liquid swaptions and bootstrap to these, and only a few (5Y, 10Y etc) will practically be tradable in any case.

Interview Questions VII: Integrated Brownian Motion

For a standard Weiner process denoted W_t, calculate

    \[{\mathbb E} \Bigl[ \Bigl( \int^T_0 W_t dt \Bigr)^2 \Bigr]\]

This integral is the limit of the sum of W_t at each infinitessimal time slice dt from 0 to T, it is called Integrated Brownian Motion.

We see immediately that this will be a random variable with expectation zero, so the result of the squared expectation will simply be the variance of the random variable, which is what we need to calculate. Here I show two ways to solve this, first by taking the limit of the sum and second using stochastic integration by parts

Need help? Discuss this in the Interview Questions forum!

1) Limit of a sum

(1)   \begin{align*} I &= \int^T_0 W_t dt \nonumber \\ &= \lim_{n \to \infty}{\frac T n}\sum^n_{i=1} W_{\frac {Ti} n} \nonumber \end{align*}

This sum of values along the Wenier process is not independent of one-another, since only the increments are independent. However, we can re-write them in terms of sums of these independent increments

(2)   \begin{align*} W_{\frac {Ti} n} &= \sum^i_{j=1} ( W_{\frac {Tj} n} - W_{\frac {T(j-1)} n} ) \nonumber \\ &= \sum^i_{j=1} \overline{W}_{\frac {Tj} n} \nonumber \end{align*}

where \overline{W}_{\frac {T(j-1)} n} \sim {\mathbb N}(0,{\frac T n}) are the individual independent increments of the brownian motion. Substituting into our previous equation and reversing the order of the summation

(3)   \begin{align*} \lim_{n \to \infty}{\frac T n}\sum^n_{i=1} W_{\frac {Ti} n} &= \lim_{n \to \infty}{\frac T n} \sum^n_{i=1} \sum^i_{j=1} \overline{W}_{\frac {Tj} n} \nonumber \\ &= \lim_{n \to \infty}{\frac T n} \sum^n_{j=1} \sum^n_{i=j} \overline{W}_{\frac {Tj} n} \nonumber \\ &= \lim_{n \to \infty}{\frac T n} \sum^n_{j=1} (n-j+1) \overline{W}_{\frac {Tj} n} \nonumber \\ \end{align*}

which is simply a weighted sum of independent gaussians. To calculate the total variance, we sum the individual variances using the summation formula for \sum_1^N n^2

(4)   \begin{align*} {\mathbb V}[I] &= \lim_{n \to \infty} {\frac {T^2} {n^2}} \sum^n_{j=1} (n-j+1)^2 {\frac T n} \nonumber \\ &= \lim_{n \to \infty} {\frac {T^3} {n^3}} \Bigl( {\frac 1 3} n^3 + O(n^2) \Bigr) \nonumber \\ &= {\frac 1 3} T^3 \end{align*}

which is the solution.

2) Stochastic integration by parts

The stochastic version of integration by parts for potentially stochastic variables X_t, Y_t looks like this:

    \[X_T \cdot Y_T = X_0 \cdot Y_0 + \int^T_0 X_t dY_t + \int^T_0 Y_t dX_t\]

Re-arranging this gives

    \[\int^T_0 Y_t dX_t = \Bigl[ X_t \cdot Y_t \Bigr]^T_0 - \int^T_0 X_t dY_t\]

Now setting Y_t = -W_t and X_t = (T-t) we have

(5)   \begin{align*} \int^T_0 W_t dt &= \Bigl[ -W_t \cdot (T-t) \Bigr]^T_0 + \int^T_0 (T-t) dW_t \nonumber \\ &= \int^T_0 (T-t) dW_t \nonumber \end{align*}

We recognise this as a weighted sum of independent gaussian increments, which is (as expected) a gaussian variable with expectation 0 and variance that we can calculate with the Ito isometry

(6)   \begin{align*} {\mathbb E}\Bigl[ \Bigl( \int^T_0 (T-t) dW_t \Bigr)^2 \Bigr] &= {\mathbb E}\Bigl[ \int^T_0 (T-t)^2 dt \Bigr] \nonumber \\ &= \Bigl[ T^2t - Tt^2 + {\frac 1 3} t^3 \Bigr]^T_0 \nonumber \\ &= {\frac 1 3} T^3 \end{align*}

which is the solution.

Credit Valuation Adjustment (CVA)

Now that we’ve covered a basic model for the default of firms and the pricing of Credit Default Swaps, we’re ready to consider the implication of your counterparty’s credit risk on the price of a derivative contract signed with them – this is called the ‘Credit Valuation Adjustment’ or CVA, and is the amount that one should change the value of an uncollatorised credit-risk-free derivative to reflect the counterparty’s risk of default.

When we have priced derivatives under Black-Scholes assumptions, we’ve implicitly assumed that the contract runs to expiry. However, if our counterparty defaults before the end of the contract, this won’t happen (typically, in the event of default a liquidator will attempt to collect everything the firm is owed from counterparties, and use the finite resources collected to pay back creditors as much as possible).

If we hold a single derivative contract against a defaulting counterparty and it’s out-of-the-money (ie. the value is negative – we owe them money), we will still be required to hold the position. On the other hand, if we’re in-the-money, we won’t necessarily get all of our contract value back – as with CDS contracts, we assume that of the true value of the contract, we will only receive a fraction R, the ‘Recovery Rate’. If we gain nothing if the value is negative, but lose something when the value is positive, then to calculate the pricing impact we need to calculate expected value of the contract at a future point if it is positive, and ignore the price impact coming from the chance that it is negative, which we call the Expected Positive Exposure (EPE).

For a contract depending on underlier S with value C(S,t) at future time t, we can calculate this by integrating across all possible underlier values that generate a positive contract value at that time

    \[EPE(t) = \int_{C(s) \textgreater 0} C(S,t) \cdot p(S) dS\]

this will be larger for contracts whose values have a higher volatility, which are more likely to have a high positive or negative value at some point in the future.

Our loss due to a counterparty default event at time t is the discounted expectation of our loss due to a default accounting for the finite recovery value

    \[(1 - R) \cdot EPE(t) \cdot P(0,t)\]

where P(0,t) is the discount factor to time t as usual.

In order to calculate the CVA for a whole contract, we need to sum the product of the loss-given-default at t time and the probability of default at time t

    \[CVA = (1-R) \int_0^{T_f} EPE(t) \cdot P(0,t) \cdot S'(t) \; dt\]

where T_F is the time of the final cashflow due to the contract and S'(t) is the probability of default at time t as discussed in the previous post on firm default models, and if this is uncorrelated to the value of the contract, this integral is relatively straightforward to calculate. Default probabilities can be calibrated from observed CDS prices on the counterparties, most major counterparties (typically large investment banks) will have CDS contracts available on the market to use for calibration.

It’s worth mentioning that CVA is a pricing problem – we’re treating the pricing adjustment as the price of an exotic derivative and hedging it with a portfolio of CDS contracts. This means we’re calculating an actual dollar value, and when a trader quotes a derivative price to a counterparty he should also quote a ‘CVA adjustment’ to represent the counterparty’s chance of default. Internally, the trader will often have to pass this straight through to a ‘CVA Desk’, which internally manages the risk the bank faces due to the risk of default of any given counterparty – and will then reimburse the trader if she faces a loss due to such an event!

It’s worth noting that many simple products like ZCBs, forwards and FRAs have model-independent prices, so we can calculate their value independent of any assumptions about the market’s future behaviour. However, we’ve had to make some assumptions about the underlying volatility in the market to calculate EPEs, so the CVA for these products is model-dependent – we need to make some assumptions about the model driving the market and can’t enforce a price today purely by no-arbitrage considerations (although it will be informed by the prices of other model-dependent products whose prices we can see).

We’ve also discussed only the CVA adjustment from an individual contract, which is already quite computationally complex (in a future post, I’ll calculate this for some simple products in a simple model). If we have a portfolio of products in place against a specific counterparty, these should all be considered together and may lead to some offsetting exposures that reduce the CVA adjustment on a portfolio basis (although even this isn’t always the case, depending upon ‘netting agreements’ in the Credit Support Annex – CSA – that you have in place with the given counterparty…).

Further, CVA only applies to non-collaterised positions. Many positions (like futures) require the deposit of margin in an escrow account, exactly to try and cover for the risk of counterparty default. This leads instead to ‘gap risk’ (ie. that the margin might not be sufficient) but also to the related ‘Funding Valuation Adjustment’ (or FVA, essentially the cost of funding the margin you provide).

Hedging in a finite-state model (Binary Trees)

Today’s post is about hedging in a world where there are only a few outcomes. It demonstrates a lot of principles that are important in asset pricing, and it’s also a frequent topic for interview questions so almost got included as one of those!

A very basic approximation for a stock is a binary tree, as in the diagram shown below. The stock is worth 100 today, and after some time (say a year) it will be worth either 110 with probability p or 90 with probability (1-p). In this very basic model, we assume no other values are possible – the stock either does well and goes up by 10, or it does badly and goes down by 10. Furthermore, we assume that there is a risk-free yearly interest rate r at which we can deposit money in the bank and receive (1+r) times our initial deposit in a year.

The two possibilities for a stock's evolution in the binary tree model
The two possibilities for a stock’s evolution in the binary tree model

We’re going to try and price options in this model. Let’s say we’ve got a call option to buy the stock in a year’s time for 100. How much is this worth? Because of the simple state of the world, we can enumerate the two possibilities – either the stock is worth 110, in which case the call option to buy it for 100 is worth 10, or the stock is worth 90, and the option is worthless. We’ll try and simulate that payoff using a combination of cash-in-the-bank and the stock itself, and then by no-arbitrage the price must be the same today.

Our portfolio consists of \alpha stocks S and \beta cash-in-the-bank. The value of the cash will certainly be (1+r)\beta in a year, while the stock will be 110 \alpha or 90 \alpha depending on the state, and we want the sum of these two to equal the option payoff (in either the up or the down scenario), which gives us two simultaneous equations

    \[(1+r) \beta + 110 \alpha = 10\]

    \[(1+r) \beta + 90 \alpha = 0\]


    \[\alpha = 0.5\]

    \[\beta = {-45 \over (1+r)}\]

This says that a portfolio containing half of a stock and minus 45 pounds in the bank will exactly replicate the payoff of the option in either world state. The value of this portfolio today is just 0.5*100 – 45/(1+r), and I’ve plotted that as a function of r below.

The price of a call option on a stock in the two-state world given above
The price of a call option on a stock as a function of the risk-free rate in the two-state world given above

This gives meaningless prices if r > 0.1 (the price of the option must be between 0 and 10/(1+r) as these are the discounted values of the least/most that it can pay out at expiry). What does this mean intuitively? Well, if r > 0.1 then we have an arbitrage: 100 in the bank will *always* yield more than the stock at expiry, so we should short the stock as much as possible and put the proceeds in the bank. If r < -0.1 the situation is exactly reversed

The important point about all of this was that the option price DOESN’T depend on the relative chances of the stock increasing to 110 or falling to 90. As long as both of these are strictly greater than zero and less than one, then ANY set of probabilities will lead to the same price for the option. This is the discrete analogue of a result I presented before (here) – that the expected growth of the stock in the real world doesn’t matter to the option’s price, it is the risk-free rate that affects its price. Indeed, it is possible to derive the continuous result using a binary tree by letting the time period go to zero, I won’t attempt it here but the derivation can be found in many textbooks (eg. on wikipedia).

Things really get interesting when we try to extend the model in a slightly different way. Often banks will be interested in models that have not just a diffusive component, but also a ‘jump’ component, which gives a finite chance that a price will fall suddenly by a large amount (I’ll present one such model in the near future). Unlike a straight-forward Black-Scholes model, because these jumps happen suddenly and unexpectedly they are very difficult to hedge, and are meant to represent market crashes that can result in sudden sharp losses for banks.

In our simple tree model, this can be incorporated by moving to a three-branch model, shown below

The three possibilities for a stock's evolution in the three-branch tree model
The three possibilities for a stock’s evolution in the three-branch tree model

We have the same two branches as before, but an additional state now exists in which the stock price crashes to 50 with probability q. In this case, again trying to price an option to buy the stock for 100 gives three simultaneous equations

    \[(1+r) \beta + 110 \alpha = 10\]

    \[(1+r) \beta + 90 \alpha = 0\]

    \[(1+r) \beta + 50 \alpha = 0\]

Unlike before, we can’t find a single alpha and beta that will replicate the payoff in all three world states, as we have three equations and only two unknowns. Consequently, the best we will be able to to is sub-replicate or super-replicate the payoff. That is, find portfolios that either always pay equal to or greater than the option, or always pay less than or equal to the option. These will give bounds on the lowest and highest arbitrage-free option prices, but that’s as far as arbitrage-free prices will take us (in fact ANY of the prices between this limit is arbitrage-free) – choosing an actual price will require knowing the probabilities of p and q and deciding on our personal risk-premium.

In the simple three-state model, lower and upper bounds can be calculated by ignoring the second and third equation respectively above, and they give the limits shown in the graph below. Once again, as r \to 0.1 they converge, but note that a case where r < -0.1 is now possible, as the ‘crash’ option means that the stock can still pay out less than the bank account

The limiting values given by the no-arbitrage requirement on the price of a call option as a function of the risk-free rate in the three-branch tree model given above
The limiting values given by the no-arbitrage requirement on the price of a call option as a function of the risk-free rate in the three-branch tree model given above

This is what’s called an incomplete market. The securities that exist in the market aren’t sufficient to hedge us against all future possible states of the universe. In this case, we can’t uniquely determine prices by risk-neutral pricing – sice we can’t hedge out all of the risk, risk preferences of investors will play a part in determining the market-clearing prices of securities. Most models that are used in the industry are incomplete in this way – I’ll be looking at some examples of this soon which will include models involving jump processes and stochastic volatility.