Simulating Treasury Bond Futures Delivery Options with Yield Curve Scenarios
Summary
The document describes an attempt to estimate a Treasury bond future’s delivery option by applying principal component analysis (PCA) to yields of deliverable bonds. The author uses the leading components to create yield scenarios, scales them using the option’s implied volatility, reprices the future in each scenario, and estimates which bond is cheapest to deliver. The simulated average future price is reported as close to the observed market price, but one bond is selected for delivery in every scenario.
The questions highlight key modeling uncertainties: whether a dominant parallel-shift component is reasonable for a similar-maturity basket, how to apply annualized implied volatility over the remaining horizon, and why the delivery probabilities are so concentrated. The document provides no resolution or validated method; it is a request for diagnosis. It also omits the underlying data and implementation details, so neither the scenario scaling nor the cheapest-to-deliver results can be independently assessed.
Key ideas
- PCA can represent yield curve movements using a small number of components.
- A basket of similar-maturity bonds may show a dominant parallel-shift component, though the document does not establish whether this is appropriate.
- The author uses implied volatility to scale yield scenarios over the time to delivery.
- The simulated future price is near the observed price, while the estimated delivery outcome is concentrated in one bond.
- The document raises questions about volatility scaling and delivery probabilities but does not answer them.
Tags
Full text
# Delivery option calculation rateslib [multiple questions]
# Delivery option calculation rateslib [multiple questions]
I am using rateslib and I am trying to price the bond future TYZ4 on the 2024-09-23. I want to be able to price the delivery option of that bond future.
The way I am doing is as follow:
`(1)` perform PCA on the yields of the bonds in the basket.
`(2)` generate different yield scenarios at maturity using PC1 and PC2.
To generate the different yield scenarios I am using the implied vol of the option on TYZ4. Then I need to scale PC1, and PC2 accordingly when generating the different scenarios. If $\alpha_1, \alpha_2, \sigma$ is the explained variance of PC1 and PC2 and $\sigma$ is the implied vol then my scalings are: $\frac{\alpha_i}{\alpha_1 + \alpha_2} \times \sigma^2$.
[Q1]: When performing PCA on the bond basket I found that PC1 is a clear parallel shift of the yield curve while PC2 is a steepening. This seems correct. Though I found that the explained variance of PC1 is $0.998$ which basically says that PC2 explains almost no variance. Is that normal? My guess would be that since the bond in the basket are extremely similar in maturities then steepening can't happen too much and all the bonds moves together when rates changes. This then means that when I am generating all my scenarios I am basically just modelling parallel shift scenarios, is that a problem?
All the data needed to perform this analysis on the 2024-09-23 is here ( I define the clean price on 2024-09-23, the repo rate of the bonds, the conversion factors, the PCs, the explained variance of the PCs and the implied vol):
The price of the bond future on 09/23 was 114.75. I can now generate 1000 different scenarios and calculate the bond future price as well as the probability of delivery of each bond:
I then found that future_value / 1000 = 114.18 which is not a bad result since it's quite closed to what's been observed in the market. Yet I found that the probability of delivery of US91282CKW00 is 100%! which is definetely weird here. So I guess there is a problem in what I am doing but I don't know why.
A few guesses:
- On BBG the implied vol is $6.46$. Since it's annualized and there is $99$ days between 2024-09-23 and the delivery date 2024-12-31. Then the implied vol I am using is: $\frac{6.46}{100} \cdot \sqrt{\frac{99}{365}}$. The problem is that this vol is the log-normal vol so I should probably use `np.random.lognormal` but then I get a future price of ~112 which is completely off.
- If instead I put an implied vol of $0.5$ and generate $10000$ samples then I get a probability of 0.9992 for US91282CKW00 and 0.0008 for US91282CLJ89. I found it very weird that even using a high implied vol I get an almost 100% chance of delivery for US91282CKW00.
[Q2] What am I doing wrong here? Shouldn't the other bonds also have a probability of delivery?
Many thanks,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.