Implementing Rebonato’s Swaption Volatility Formula with Piecewise Volatility
Summary
The document asks how to implement Rebonato’s approximation for swaption volatility in C++. The formula combines swap weights, forward rates, correlations, and the integrated products of forward-rate volatilities. With piecewise-constant volatilities, each integral becomes a sum over time intervals, weighting the product of the two rates’ volatility parameters by each interval’s length.
The example code attempts this calculation but places the volatility accumulation outside the rate-pair calculation, allowing values to carry across pairs; it also uses a fixed time increment and does not clearly match the stated time grid. The post adds that “Real” is a double type and gives the piecewise-constant integral expression. No corrected implementation or numerical validation is provided, so index ranges, time units, accrual periods, and the swap-rate normalization still need to be checked against the model’s conventions.
Key ideas
- Rebonato’s approximation combines rate weights, forward rates, correlations, and integrated volatility products.
- Piecewise-constant volatilities turn each time integral into a sum across time intervals.
- The volatility integral should be calculated for each forward-rate pair before applying its correlation and swap weights.
- Time increments and array indices must follow the model’s tenor and time-grid conventions.
Tags
Full text
# Rebonatos's formula in C++
# Rebonatos's formula in C++
I'm trying to code in C++ Rebonato's formula for swaption volatilities
$$ v_{\alpha,\beta}^2=\frac{1}{T_\alpha} \sum_{i,j=\alpha+1}^{\beta} \frac{w_i(0)w_j(0)F_i(0)F_j(0)}{S_{\alpha\beta}^2(0)}\rho_{i,j}\int_{0}^{T_\alpha}\sigma_i(t)\sigma_j(t)dt$$
where the forward rate volatility is a piecewise-constant function $\sigma_i(t)=\sigma_{i,\beta(t)}=\phi_i\psi_{i-(\beta(t)-1)}$. This means that the integral term "reduces to a summation of products of volatility parameters", Brigo&Mercurio pag 316.
Assume the swap's floating leg is a 1-Year Libor rate, resetting every 360 days,while the fixed leg is set to make the IRS fair, i.e. $S_{\alpha\beta}$(t), also resetting every 360 days.
I've come up with the following code, where `vol_m[i][h+1]` represents the quantity $\sigma_{i,h+1}$ and `corr_m[i][j]` is the correlation matrix $\rho_{ij}$.
```
Real sum=0;
Real sum1=0;
Real time_unit = 360;
for (int i=0;i<=beta-1;i++){
for (int j=0;j<=beta-1;j++){
for (int h=0;h<=alpha;h++){
sum1=sum1+time_unit*vol_m[i][h+1]*vol_m[j][h+1];
}
sum=sum+weight[i]*weight[j]*r[i]*r[j]*(corr_m[i][j]))/pow(swaprate,2)*sum1;
}
}
```
However, this code is not working properly. Can anyone help me improve it, please?
EDIT: The `Real` keyword you see in the code is just a QuantLib typedef for `double`
EDIT: In this article Brigo&Morini present how Rebonato's formula reads using the same piecewise-constant volality $\sigma_i(t)=\sigma_{i,\beta(t)}$ as above,
$$\int_{0}^{T_{\alpha}} \sigma_i(t)\sigma_j(t) dt = \sum_{h=0}^{\alpha}(T_h-T_{h-1})\sigma_{i,h+1}\sigma_{j,h+1}$$Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.