Coding towards CFA (13) – Swaption Valuation

Coding towards CFA (13) – Swaption Valuation

A swaption is an option on an interest rate swap. As previously discussed, an interest rate swap involves two parties: the fixed-rate payer (who receives the floating rate) and the fixed-rate receiver (who pays the floating rate). A swaption grants the holder the right, but not the obligation, to enter into a swap contract as the fixed-rate payer at a pre-agreed fixed rate. If, at expiration, the market’s fixed rate for the swap is higher than the strike rate, the swaption holder profits. Conversely, if the market’s fixed rate is lower than the strike rate, the swaption holder incurs a loss.

Similar to futures options and interest rate options, the Black model can be applied to price a swaption. However, swaptions have their own unique characteristics that differentiate them from other types of options. While futures contracts and FRA contracts typically involve a single payment term, an interest rate swap involves multiple payments at different time points. Since a swaption gives the right to enter into an interest rate swap, the payoffs of the swaption contract need to consider the present value of all future fixed and floating payments under the swap.

Therefore, the Black model needs to be adjusted to account for the multiple cash flow characteristics of the underlying swap contract when pricing the swaption. Here, we can break the swaption pricing into two steps

  • Step 1 – Calculate the expected option payoff at option expiration
  • Step 2 – Discount the payoff to the present value at option initiation

At step 1, we adjust the Black model formula to account for the multiple payments in order to calculate the expected option payoff at the option expiration. At this point, the payoff value is the value at the time of option expiration, time T. For a swaption contract, the call option is termed a “Payer Swaption” and the put option is termed a “Receiver Swaption”.

Compared to the classic Black model formula, we can see that the fixed swap rate R(FIX)​ is used as the underlying component in the formula. The multiple payoffs of the option are discounted and summarised at the time of option expiration. Please refer to the previous blog posts for more details on the Black model formula.

At step 2, we discount the expected option payoff to the option initiation, time 0. Since the rates used in the formula so far are annualised, we also need to convert the calculated swaption payer rate to match the swap payment period.

here is the code implementation in Python.

Full Code – Python

import numpy as np
from scipy.stats import norm

def value_swaption(notional_amount, r_fix, k, T, swap_terms, 
                   swap_payment_freq, r, sigma, option_type="payer"):
    
    # Calculate d1 and d2
    d1 = (np.log(r_fix/k) + 0.5*sigma**2*T) / (sigma*np.sqrt(T))
    d2 = d1 - sigma * np.sqrt(T)

    # Calculate the swap discount factors
    pva = sum([1/(1+r*t) for t in swap_terms])

    # Calculate swaption premium rate
    if option_type == "payer":
        premium_rate = (np.exp(-r*T)*pva*(r_fix*norm.cdf(d1)-k*norm.cdf(d2))
                            /swap_payment_freq)
    else:
        premium_rate = (np.exp(-r*T)*pva*(k*norm.cdf(-d2)-r_fix*norm.cdf(-d1))
                            / swap_payment_freq)
 
    # Calculate swaption price 
    swaption_price = notional_amount * premium_rate

    return swaption_price


swap_terms = [.25, .5, .75, 1]
notional_amount = 1000000
k= 0.025    
r_fix = 0.03
T = 1 
swap_payment_freq = 4
sigma = 0.2 
r = 0.05

payer_swaption_price = value_swaption(notional_amount, r_fix, k, T, swap_terms, swap_payment_freq, r, sigma, option_type="payer")
receiver_swaption_price = value_swaption(notional_amount, r_fix, k, T, swap_terms, swap_payment_freq, r, sigma,  option_type="receiver")

print("Payer Swaption Price: "+str(payer_swaption_price))
print("Receiver Swaption Price: "+str(receiver_swaption_price))

Full Code – DolphinDB

def value_swaption(notional_amount, r_fix, k, T, swap_terms, swap_payment_freq, r, sigma, option_type="payer"){
    
    // Calculate d1 and d2
    d1 = (log(r_fix/k) + 0.5*pow(sigma, 2)*T) / (sigma*sqrt(T))
    d2 = d1 - sigma * sqrt(T)

    // Calculate the swap discount factors
    pva = sum(each(def(t): 1/(1+r*t), swap_terms))

    // Calculate swaption premium rate
    if (option_type == "payer") 
        premium_rate = exp(-r * T) * pva * (r_fix*cdfNormal(0, 1, d1) - k*cdfNormal(0, 1, d2)) / swap_payment_freq
    else
        premium_rate = exp(-r * T) * pva * (k*cdfNormal(0, 1, -d2) - r_fix*cdfNormal(0, 1, -d1)) / swap_payment_freq
 
    // Calculate swaption price 
    swaption_price = notional_amount * premium_rate

    return swaption_price
}

swap_terms = [0.25, 0.5, 0.75, 1]
notional_amount = 1000000
k= 0.025    
r_fix = 0.03
T = 1 
swap_payment_freq = 4
sigma = 0.2 
r = 0.05

payer_swaption_price = value_swaption(notional_amount, r_fix, k, T, swap_terms, swap_payment_freq, r, sigma, option_type="payer")
receiver_swaption_price = value_swaption(notional_amount, r_fix, k, T, swap_terms, swap_payment_freq, r, sigma,  option_type="receiver")

print("Payer Swaption Price: "+payer_swaption_price)
print("Receiver Swaption Price: "+receiver_swaption_price)

Leave a comment