Why Jamshidian Decomposition Can Fail with Black-76 Bond Options
Summary
The document presents a numerical attempt to apply Jamshidian’s trick to a European put on a coupon bond. It compares the bond option’s Black-76 value with the sum of Black-76 values for options on the bond’s individual cash flows. In the example, intrinsic values agree to numerical precision, while the volatility-based prices differ.
That discrepancy illustrates a key modeling requirement: Jamshidian decomposition relies on a one-factor setup in which the bond’s cash flows move with a common underlying state, so the component option strikes must be derived consistently from that state. Pricing each discounted cash flow as a separate Black-76 option with the same quoted volatility does not generally preserve the distribution of the aggregate bond price. The document supplies code and a specific example, but no accepted correction or general derivation; its numerical output is best treated as a question about model assumptions and implementation rather than a validated result.
Key ideas
- The example compares a coupon-bond put with a sum of options on its cash flows.
- The intrinsic values match, but the Black-76 prices differ when the same volatility is assigned to each component.
- Jamshidian decomposition requires a consistent common factor linking the cash flows and the bond price.
- The document offers an implementation example but does not resolve the modeling issue.
Tags
Full text
# Jamshidian trick in Black-76 for bond options
# Jamshidian trick in Black-76 for bond options
I am struggling with application of Jamshidian's trick to the Black-76 model for bond options. I made a simple example to demonstrate my problem.
I value the european put bond option at 95 on the 2Y semi-annual bond with coupon = 5 and redemption at 100. Volatility of F is set to 0.04. Then I compare value of option on the coupon bond with sum of values of options on coupons.
Intrinsic values [max(sum)-sum(max)] match exactly, but Black-76 values differ.
What am I doing wrong? – My python code is below.
```
# -*- coding: utf-8 -*-
"""
Created on Mon Jan 6 14:13:34 2025
Attept at applying Jamshidian trick to the bond option, priced by Black-76
"""
import numpy as np
import scipy.stats as st
import scipy.optimize as opt
def black76(CP, F, K, sigma, t, r):
d1 = (np.log(F/K)+0.5*t*sigma**2)/(np.sqrt(t)*sigma)
d2 = d1-np.sqrt(t)*sigma
if CP == 1: # call
return np.exp(-r*t)*(st.norm.cdf(d1)*F-st.norm.cdf(d2)*K)
else:
return np.exp(-r*t)*(st.norm.cdf(-d2)*K-st.norm.cdf(-d1)*F)
def intrinsic(CP, F, K, tex, r):
if CP == 1:
return max(F-K,0)*np.exp(-r*tex)
else:
return max(K-F,0)*np.exp(-r*tex)
def jam(bondF, K, r, tex):
func = lambda r: np.sum(bondF[:,1]*np.exp(-r*(bondF[:,0]-tex)))-K
return opt.newton(func, r, tol=1e-15)
# =============================================================================
# PARAMETERS
# =============================================================================
r = 0.17
bond = np.array([[0.5, 5],[1, 5],[1.5, 5],[2, 105]]) # t, CF
tex = 1 # option expiration
CP = -1
K = 95
sigma = 0.04
# =============================================================================
# MAIN
# =============================================================================
P0T = np.sum(bond[:,1]*np.exp(-r*bond[:,0]))
bondF = bond[bond[:,0]>tex]
F = np.sum(bondF[:,1]*np.exp(-r*(bondF[:,0]-tex)))
Pin = intrinsic(CP, F, K, tex, r)
Err = Pin-black76(CP, F, K, 1e-9, tex, r)
P = black76(CP, F, K, sigma, tex, r)
rj = jam(bondF, K, r, tex) # Jamshidian rj
Kj = bondF[:,1]*np.exp(-rj*(bondF[:,0]-tex)) # Jamshidian strikes
Fj = bondF[:,1]*np.exp(-r*(bondF[:,0]-tex)) # F of strips
Pinj = np.zeros(Kj.shape[0]) # intrinsic value of options on coupons
for j, k in enumerate(Kj):
Pinj[j] = intrinsic(CP, Fj[j], k, tex, r)
print('Bond option put intrinsic value difference \nmax(sum)-sum(max)', Pin-np.sum(Pinj))
Pj = np.zeros(Kj.shape[0]) # black value of options on coupons
for j, k in enumerate(Kj):
Pj[j] = black76(CP, Fj[j], k, sigma, tex, r)
print('\nBond option put black value difference\nmax(sum)-sum(max)', P-np.sum(Pj))
```
Bond option put intrinsic value difference max(sum)-sum(max) -8.881784197001252e-16
Bond option put black value difference max(sum)-sum(max) -0.0016714330263845056Shown 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.