Class BondPricer
frequency
compounding (the bond's coupon frequency); coupons are assumed on a regular
schedule with the last payment at maturity.
The risk numbers and what each is for: Macaulay duration is the
cash-flow-weighted average time to payment (years; an intuition number);
modified duration = Macaulay / (1 + y/f) is the first-order price
sensitivity, dP/P ≈ -modDur · dy; DV01 is the same
derivative in money terms per 1bp, the number the desk actually hedges,
because DV01s add across positions while durations must be
value-weighted. Convexity is the second-order term that makes the
duration hedge wrong for large moves. It is always in the long
bondholder's favor (price rises more than duration predicts when yields
fall, drops less when they rise), which is why long-convexity positions
cost carry.
The yearsToMaturity functions work in whole coupon periods
(no accrued interest, no settlement inside a period): the textbook bond.
The date-based functions (dirtyPrice, cleanPrice,
accruedInterest, yieldFromCleanPrice) use the street
convention with real day counts, including ACT/ACT ICMA. Pricing off a full curve (each cash flow
at its own zero rate) is YieldCurve's job; hedging a position
against non-parallel curve moves is KeyRateDurations'.
-
Method Summary
Modifier and TypeMethodDescriptionstatic doubleaccruedInterest(double face, double couponRate, int frequency, LocalDate settlement, LocalDate maturity, DayCount dayCount) static doubleaccruedInterest(double face, double couponRate, int frequency, LocalDate settlement, LocalDate maturity, DayCount dayCount, boolean endOfMonth) Accrued interest at settlement: the current period's coupon times the elapsed fraction (ACT/ACT ICMA: actual days over actual days in the period; 30/360 family: 30/360 days over 360/f).static doubleaccruedInterestExact(double face, double couponRate, int frequency, double yearsToMaturity) Accrued interest on the quasi-coupon grid ofpriceFromYieldExact(double, double, int, double, double):C (1 - w); zero when the maturity is a whole number of periods.static doublecleanPrice(double face, double couponRate, int frequency, LocalDate settlement, LocalDate maturity, double yield, DayCount dayCount) static doublecleanPrice(double face, double couponRate, int frequency, LocalDate settlement, LocalDate maturity, double yield, DayCount dayCount, boolean endOfMonth) Clean price = dirty price minus accrued interest.static doubleconvexity(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Convexity (numeric second derivative of price w.r.t. yield, normalized by price).static doubleconvexityAnalytic(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Analytic convexity on the same whole-period schedule asconvexity(double, double, int, double, double):(1/P) d^2P/dy^2withstatic doubleconvexityExact(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Analytic convexity on the exact grid,(1/P) sum_k CF_k e_k (e_k + 1) / (f^2 (1 + y/f)^(e_k + 2)),e_k = k - 1 + w.static doubledirtyPrice(double face, double couponRate, int frequency, LocalDate settlement, LocalDate maturity, double yield, DayCount dayCount) static doubledirtyPrice(double face, double couponRate, int frequency, LocalDate settlement, LocalDate maturity, double yield, DayCount dayCount, boolean endOfMonth) Dirty price perfacefrom a yield, street convention (the formula behind the SIFMA/Bloomberg "street" yield and Excel's price):static doubledv01(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Price change for a one-basis-point yield move (positive number).static booleanisWholePeriods(int frequency, double yearsToMaturity) WhetheryearsToMaturity * frequencyis a whole number of coupon periods (to 1e-9).static doublemacaulayDuration(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Macaulay duration in years: PV-weighted average time to cash flow.static doublemacaulayDurationExact(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Macaulay duration in years on the exact grid ofpriceFromYieldExact(double, double, int, double, double).static doublemodifiedDuration(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Modified duration: price sensitivity per unit yield change.static doublemodifiedDurationExact(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Modified duration on the exact grid: Macaulay / (1 + y/f).static doublepriceFromCurve(double face, double couponRate, int frequency, double yearsToMaturity, YieldCurve curve) Price by discounting each cash flow on a zero curve.static doublepriceFromYield(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Dirty price perfacefrom a yield (regular schedule, whole periods).static doublepriceFromYieldExact(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Dirty price from a yield for any (also non-integral) time to maturity, by the street convention: coupons sit on the regular quasi-coupon grid counted back from maturity, the first onewperiods away, and a full coupon is paid on it.static LocalDatesettlementDate(LocalDate tradeDate, int lagDays, BusinessCalendar calendar) Settlement date from a trade date and settlement lag (e.g.static doubleyieldFromCleanPrice(double cleanPrice, double face, double couponRate, int frequency, LocalDate settlement, LocalDate maturity, DayCount dayCount, boolean endOfMonth) Street-convention yield from a clean price (inverse ofcleanPrice(double, double, int, java.time.LocalDate, java.time.LocalDate, double, DayCount, boolean)), by bisection on [−90%, 1000%] to full double precision.static doubleyieldToMaturity(double price, double face, double couponRate, int frequency, double yearsToMaturity) Yield to maturity by bisection (price must be positive).static doubleyieldToMaturityExact(double dirtyPrice, double face, double couponRate, int frequency, double yearsToMaturity) Yield from a dirty price on the exact grid, by bisection on [-90%, 1000%].
-
Method Details
-
priceFromYield
public static double priceFromYield(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Dirty price perfacefrom a yield (regular schedule, whole periods). -
priceFromCurve
public static double priceFromCurve(double face, double couponRate, int frequency, double yearsToMaturity, YieldCurve curve) Price by discounting each cash flow on a zero curve. -
yieldToMaturity
public static double yieldToMaturity(double price, double face, double couponRate, int frequency, double yearsToMaturity) Yield to maturity by bisection (price must be positive). -
macaulayDuration
public static double macaulayDuration(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Macaulay duration in years: PV-weighted average time to cash flow. -
modifiedDuration
public static double modifiedDuration(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Modified duration: price sensitivity per unit yield change. -
convexity
public static double convexity(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Convexity (numeric second derivative of price w.r.t. yield, normalized by price). -
dv01
public static double dv01(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Price change for a one-basis-point yield move (positive number). -
convexityAnalytic
public static double convexityAnalytic(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Analytic convexity on the same whole-period schedule asconvexity(double, double, int, double, double):(1/P) d^2P/dy^2withd^2P/dy^2 = sum_i CF_i i (i + 1) / (f^2 (1 + y/f)^(i+2))
The existing
convexity(double, double, int, double, double)is a central difference with step 1e-4 and keeps its results; this is the closed form it approximates (they agree to about 1e-7 relative, pinned in the tests).- Parameters:
face- face valuecouponRate- annual coupon ratefrequency- coupons per yearyearsToMaturity- years to maturity (rounded to whole periods, as inpriceFromYield(double, double, int, double, double))yield- yield, compoundedfrequencytimes a year- Returns:
- convexity in years squared
-
isWholePeriods
public static boolean isWholePeriods(int frequency, double yearsToMaturity) WhetheryearsToMaturity * frequencyis a whole number of coupon periods (to 1e-9). When it is not, the whole-period functions (priceFromYield(double, double, int, double, double),macaulayDuration(double, double, int, double, double),convexity(double, double, int, double, double),dv01(double, double, int, double, double),yieldToMaturity(double, double, double, int, double),priceFromCurve(double, double, int, double, YieldCurve)) round to the nearest period: a 2.3-year semi-annual bond is priced as 2.5 years. That rounding is kept for compatibility (release policy: no behaviour changes in 3.x) but its use with non-integral maturities is deprecated since 3.1.0; use the...Exactfunctions instead.- Parameters:
frequency- coupons per yearyearsToMaturity- years to maturity- Returns:
- true when the maturity is a whole number of periods
-
priceFromYieldExact
public static double priceFromYieldExact(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Dirty price from a yield for any (also non-integral) time to maturity, by the street convention: coupons sit on the regular quasi-coupon grid counted back from maturity, the first onewperiods away, and a full coupon is paid on it.With
x = yearsToMaturity * f,n = ceil(x)coupons remain andw = x - (n - 1)in (0, 1]:P = sum_{k=1..n} C / (1 + y/f)^(k - 1 + w) + face / (1 + y/f)^(n - 1 + w), C = face c / fWhen
xis whole,w = 1and this is exactlypriceFromYield(double, double, int, double, double). Worked example: 2.3 years semi-annual givesx = 4.6, five coupons, the first 0.6 periods (0.3 years) away; the clean price is this minusaccruedInterestExact(double, double, int, double).- Parameters:
face- face valuecouponRate- annual coupon ratefrequency- coupons per yearyearsToMaturity- years to maturity, any positive valueyield- yield, compoundedfrequencytimes a year- Returns:
- dirty price
-
accruedInterestExact
public static double accruedInterestExact(double face, double couponRate, int frequency, double yearsToMaturity) Accrued interest on the quasi-coupon grid ofpriceFromYieldExact(double, double, int, double, double):C (1 - w); zero when the maturity is a whole number of periods.- Parameters:
face- face valuecouponRate- annual coupon ratefrequency- coupons per yearyearsToMaturity- years to maturity- Returns:
- accrued interest
-
macaulayDurationExact
public static double macaulayDurationExact(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Macaulay duration in years on the exact grid ofpriceFromYieldExact(double, double, int, double, double).- Parameters:
face- face valuecouponRate- annual coupon ratefrequency- coupons per yearyearsToMaturity- years to maturityyield- yield, compoundedfrequencytimes a year- Returns:
- Macaulay duration
-
modifiedDurationExact
public static double modifiedDurationExact(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Modified duration on the exact grid: Macaulay / (1 + y/f).- Parameters:
face- face valuecouponRate- annual coupon ratefrequency- coupons per yearyearsToMaturity- years to maturityyield- yield, compoundedfrequencytimes a year- Returns:
- modified duration
-
convexityExact
public static double convexityExact(double face, double couponRate, int frequency, double yearsToMaturity, double yield) Analytic convexity on the exact grid,(1/P) sum_k CF_k e_k (e_k + 1) / (f^2 (1 + y/f)^(e_k + 2)),e_k = k - 1 + w.- Parameters:
face- face valuecouponRate- annual coupon ratefrequency- coupons per yearyearsToMaturity- years to maturityyield- yield, compoundedfrequencytimes a year- Returns:
- convexity in years squared
-
yieldToMaturityExact
public static double yieldToMaturityExact(double dirtyPrice, double face, double couponRate, int frequency, double yearsToMaturity) Yield from a dirty price on the exact grid, by bisection on [-90%, 1000%].- Parameters:
dirtyPrice- dirty priceface- face valuecouponRate- annual coupon ratefrequency- coupons per yearyearsToMaturity- years to maturity- Returns:
- the yield
-
dirtyPrice
public static double dirtyPrice(double face, double couponRate, int frequency, LocalDate settlement, LocalDate maturity, double yield, DayCount dayCount, boolean endOfMonth) Dirty price perfacefrom a yield, street convention (the formula behind the SIFMA/Bloomberg "street" yield and Excel's price):P = Σ_{k=0}^{N−1} C_k / (1 + y/f)^{k + w} + face / (1 + y/f)^{N − 1 + w}with w = 1 − (elapsed fraction of the current coupon period) and N the number of coupons left. Coupons are
face·c/ffor the bond conventions THIRTY_360, THIRTY_E_360, THIRTY_E_360_ISDA and ACT_ACT_ICMA (US Treasuries and most government bonds use ACT/ACT ICMA, where the elapsed fraction is actual days over actual days in the period). Discounting uses the unadjusted coupon dates, as the street convention does: a coupon delayed by a weekend is not discounted for the extra days.The schedule is regular, generated backward from maturity (with the end-of-month rule when
endOfMonth); odd first coupons are not modelled, so settlement must be after the first coupon's regular period start. -
dirtyPrice
-
accruedInterest
public static double accruedInterest(double face, double couponRate, int frequency, LocalDate settlement, LocalDate maturity, DayCount dayCount, boolean endOfMonth) Accrued interest at settlement: the current period's coupon times the elapsed fraction (ACT/ACT ICMA: actual days over actual days in the period; 30/360 family: 30/360 days over 360/f). -
accruedInterest
-
cleanPrice
-
cleanPrice
-
yieldFromCleanPrice
public static double yieldFromCleanPrice(double cleanPrice, double face, double couponRate, int frequency, LocalDate settlement, LocalDate maturity, DayCount dayCount, boolean endOfMonth) Street-convention yield from a clean price (inverse ofcleanPrice(double, double, int, java.time.LocalDate, java.time.LocalDate, double, DayCount, boolean)), by bisection on [−90%, 1000%] to full double precision. Throws when the price has no yield in that range. -
settlementDate
Settlement date from a trade date and settlement lag (e.g. T+2).
-