private static double[] DeltaAndConvexity(this BesaJseBond bond, Date settleDate, double ytm) { var N = 100.0; var typicalCoupon = N * bond.annualCouponRate / 2; var t0 = bond.GetLastCouponDateOnOrBefore(settleDate); var t1 = bond.GetNextCouponDate(t0); var v = 1 / (1 + ytm / 2); var n = (int)Math.Round((bond.maturityDate - t1) / 182.625); double brokenPeriod, brokenPeriodDf, dB_dZ; double d2B_dZ2 = 0; if (n > 0) { brokenPeriod = ((double)t1 - settleDate) / (t1 - t0); brokenPeriodDf = Math.Pow(v, brokenPeriod); dB_dZ = brokenPeriod * Math.Pow(v, brokenPeriod - 1); d2B_dZ2 = brokenPeriod * (brokenPeriod - 1) * Math.Pow(v, brokenPeriod - 2); } else { brokenPeriod = ((double)t1 - settleDate) / 182.25; brokenPeriodDf = 1 / (1 + ytm * brokenPeriod / 2); dB_dZ = brokenPeriod / Math.Pow(v + brokenPeriod * (1 - v), 2); } var A1 = bond.UnroundedAIP(settleDate, ytm) / brokenPeriodDf; var dA1_dZ = typicalCoupon * ((1 - (n + 1) * Math.Pow(v, n) + n * Math.Pow(v, n + 1)) / Math.Pow(1 - v, 2)) + n * N * Math.Pow(v, n - 1); var dA_dZ = dB_dZ * A1 + dA1_dZ * brokenPeriodDf; var d2A1_dZ2 = typicalCoupon * ((2 - n * (n + 1) * Math.Pow(v, n - 1) + 2 * (Math.Pow(n, 2) - 1) * Math.Pow(v, n) - n * (n - 1) * Math.Pow(v, n + 1)) / Math.Pow(1 - v, 3)) + n * (n - 1) * N * Math.Pow(v, n - 2); var d2A_dZ2 = d2B_dZ2 * A1 + 2 * dB_dZ * dA1_dZ + d2A1_dZ2 * brokenPeriodDf; var dA_dy = -(Math.Pow(v, 2) / 2) * dA_dZ; var d2A_dy2 = (Math.Pow(v, 4) / 4) * d2A_dZ2 + (Math.Pow(v, 3) / 2) * dA_dZ; var delta = dA_dy / 100; var convexity = d2A_dy2 / bond.UnroundedAIP(settleDate, ytm); double[] measures = new double[2]; measures[0] = delta; measures[1] = convexity; return(measures); }
/// <summary> /// /// </summary> /// <param name="bond"></param> /// <param name="settleDate"></param> /// <param name="ytm"></param> /// <returns></returns> public static ResultStore GetSpotMeasures(this BesaJseBond bond, Date settleDate, double ytm) { var spotmeasures = new ResultStore(); spotmeasures.Add(Keys.RoundedAip, bond.RoundedAIP(settleDate, ytm)); spotmeasures.Add(Keys.RoundedClean, bond.RoundedClean(settleDate, ytm)); spotmeasures.Add(Keys.UnroundedAip, bond.UnroundedAIP(settleDate, ytm)); spotmeasures.Add(Keys.UnroundedClean, bond.UnroundedClean(settleDate, ytm)); spotmeasures.Add(Keys.UnroundedAccrued, bond.UnroundedAccruedInterest(settleDate)); return(spotmeasures); }
/// <summary> /// /// </summary> /// <param name="bond"></param> /// <param name="settleDate"></param> /// <param name="ytm"></param> /// <returns>modified duration of the bond</returns> public static double ModefiedDuration(this BesaJseBond bond, Date settleDate, double ytm) { var dA_dy = bond.RandsPerPoint(settleDate, ytm); return(-dA_dy / bond.UnroundedAIP(settleDate, ytm)); }
/// <summary> /// /// </summary> /// <param name="bond"></param> /// <param name="settleDate"></param> /// <param name="ytm"></param> /// <returns>the unrounded clean price</returns> public static double UnroundedClean(this BesaJseBond bond, Date settleDate, double ytm) { var unroundedClean = bond.UnroundedAIP(settleDate, ytm) - bond.UnroundedAccruedInterest(settleDate); return(unroundedClean); }
/// <summary> /// /// </summary> /// <param name="bond"></param> /// <param name="settleDate"></param> /// <param name="ytm"></param> /// <returns>the rounded all-in price</returns> public static double RoundedAIP(this BesaJseBond bond, Date settleDate, double ytm) { return(Math.Round(bond.UnroundedAIP(settleDate, ytm), 5)); }