/// <summary> /// /// </summary> /// <param name="bond"></param> /// <param name="settleDate"></param> /// <param name="ytm"></param> /// <returns>the unrounded all-in price</returns> public static double UnroundedAIP(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 tradingWithNextCoupon = t1 - settleDate > bond.booksCloseDateDays; var d = tradingWithNextCoupon ? settleDate - t0 : settleDate - t1; var couponAtT1 = tradingWithNextCoupon ? typicalCoupon : 0.0; var v = 1 / (1 + ytm / 2); var n = (int)Math.Round((bond.maturityDate - t1) / 182.625); double brokenPeriod, brokenPeriodDf; if (n > 0) { brokenPeriod = ((double)t1 - settleDate) / (t1 - t0); brokenPeriodDf = Math.Pow(v, brokenPeriod); } else { brokenPeriod = ((double)t1 - settleDate) / 182.25; brokenPeriodDf = 1 / (1 + ytm * brokenPeriod / 2); } var A1 = (couponAtT1 + typicalCoupon * v * (1 - Math.Pow(v, n)) / (1 - v) + N * Math.Pow(v, n)); var unroundedAip = brokenPeriodDf * A1; return(unroundedAip); }
// Get coupon dates for books close dates that lie between settlement date and forward date private static List <Date> GetCouponDates(this BesaJseBond bond, Date settleDate, Date forwardDate) { var BooksCloseDates = new List <Date> (); var CouponDates = new List <Date>(); var yr = settleDate.Year; while (yr >= settleDate.Year && yr < forwardDate.Year + 1) { var BCD1 = (new Date(yr, bond.couponMonth1, bond.couponDay1).AddDays(-bond.booksCloseDateDays)); var BCD2 = (new Date(yr, bond.couponMonth2, bond.couponDay2).AddDays(-bond.booksCloseDateDays)); if (BCD1 > settleDate && BCD1 < forwardDate) { CouponDates.Add(new Date(yr, bond.couponMonth1, bond.couponDay1)); BooksCloseDates.Add(BCD1); } if (BCD2 > settleDate && BCD2 < forwardDate) { CouponDates.Add(new Date(yr, bond.couponMonth2, bond.couponDay2)); BooksCloseDates.Add(BCD2); } yr += 1; } return(CouponDates); }
private static Date GetNextCouponDate(this BesaJseBond bond, Date couponDate) { if (couponDate.Month == bond.couponMonth2) { return(new Date(couponDate.Year + 1, bond.couponMonth1, bond.couponDay1)); } return(new Date(couponDate.Year, bond.couponMonth2, bond.couponDay2)); }
/// <summary> /// /// </summary> /// <param name="bond"></param> /// <param name="settleDate"></param> /// <param name="ytm"></param> /// <returns>the unrounded accrued accrued interest</returns> public static double UnroundedAccruedInterest(this BesaJseBond bond, Date settleDate) { var N = 100.0; var t0 = bond.GetLastCouponDateOnOrBefore(settleDate); var t1 = bond.GetNextCouponDate(t0); var tradingWithNextCoupon = t1 - settleDate > bond.booksCloseDateDays; var d = tradingWithNextCoupon ? settleDate - t0 : settleDate - t1; var unroundedAccrued = N * bond.annualCouponRate * d / 365.0; return(unroundedAccrued); }
public static ResultStore GetRiskMeasures(this BesaJseBond bond, Date settleDate, double ytm) { var riskmeasures = new ResultStore(); riskmeasures.Add(Keys.Delta, bond.Delta(settleDate, ytm)); riskmeasures.Add(Keys.RandsPerPoint, bond.RandsPerPoint(settleDate, ytm)); riskmeasures.Add(Keys.Duration, bond.Duration(settleDate, ytm)); riskmeasures.Add(Keys.ModifiedDuration, bond.ModefiedDuration(settleDate, ytm)); riskmeasures.Add(Keys.Convexity, bond.Convexity(settleDate, ytm)); return(riskmeasures); }
/// <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); }
public AssetSwap(double _payFixed, FloatRateIndex _index, BesaJseBond besaJseBond, List <Date> _indexDates, List <Date> _payDatesFloating, List <Date> _payDatesFixed, double _spread, List <double> _accrualFractions, Calendar _zaCalendar, Currency _ccy) { payFixed = _payFixed; index = _index; underlyingBond = besaJseBond; indexDates = _indexDates; paymentDatesFloating = _payDatesFloating; paymentDatesFixed = _payDatesFixed; spread = _spread; accrualFractions = _accrualFractions; zaCalendar = _zaCalendar; ccy = _ccy; }
private static Date GetLastCouponDateOnOrBefore(this BesaJseBond bond, Date settleDate) { var thisYearCpn1 = new Date(settleDate.Year, bond.couponMonth1, bond.couponDay1); var thisYearCpn2 = new Date(settleDate.Year, bond.couponMonth2, bond.couponDay2); var lastYearCpn2 = new Date(settleDate.Year - 1, bond.couponMonth2, bond.couponDay2); if (settleDate > thisYearCpn2) { return(thisYearCpn2); } if (settleDate > thisYearCpn1) { return(thisYearCpn1); } return(lastYearCpn2); }
public static string[,] BesaJseBondResults( [ExcelArgument(Description = "The underlying bond.")] BesaJseBond besaJseBond, [ExcelArgument(Description = "The settlement date of the bond.")] Date settleDate, [ExcelArgument(Description = "The yield to maturity of the bond.")] double ytm) { var results = besaJseBond.GetSpotMeasures(settleDate, ytm); string[,] measures = { { "roundedAip", results.GetScalar(BesaJseBondEx.Keys.RoundedAip).ToString() }, { "unroundedAip", results.GetScalar(BesaJseBondEx.Keys.UnroundedAip).ToString() }, { "roundedClean", results.GetScalar(BesaJseBondEx.Keys.RoundedClean).ToString() }, { "unroundedClean", results.GetScalar(BesaJseBondEx.Keys.UnroundedClean).ToString() }, { "unroundedAccrued", results.GetScalar(BesaJseBondEx.Keys.UnroundedAccrued).ToString() } }; 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 N = 100.0; var typicalCoupon = N * bond.annualCouponRate / 2; var t0 = bond.GetLastCouponDateOnOrBefore(settleDate); var t1 = bond.GetNextCouponDate(t0); var n = (int)Math.Round((bond.maturityDate - t1) / 182.625); var tradingWithNextCoupon = t1 - settleDate > bond.booksCloseDateDays; var d = tradingWithNextCoupon ? settleDate - t0 : settleDate - t1; var unroundedAccrued = N * bond.annualCouponRate * d / 365.0; var roundedAccrued = Math.Round(unroundedAccrued, 5); var couponAtT1 = tradingWithNextCoupon ? typicalCoupon : 0.0; var v = 1 / (1 + ytm / 2); double brokenPeriodDf; if (n > 0) { brokenPeriodDf = Math.Pow(v, ((double)t1 - settleDate) / (t1 - t0)); } else { brokenPeriodDf = 1 / (1 + ytm * ((double)t1 - settleDate) / 365.0); } var unroundedAip = brokenPeriodDf * (couponAtT1 + typicalCoupon * v * (1 - Math.Pow(v, n)) / (1 - v) + N * Math.Pow(v, n)); var unroundedClean = unroundedAip - unroundedAccrued; var roundedClean = Math.Round(unroundedClean, 5); var roundedAip = roundedClean + roundedAccrued; var results = new ResultStore(); results.Add(Keys.RoundedAip, roundedAip); results.Add(Keys.RoundedClean, roundedClean); results.Add(Keys.UnroundedAip, unroundedAip); results.Add(Keys.UnroundedClean, unroundedClean); results.Add(Keys.UnroundedAccrued, unroundedAccrued); results.Add(Keys.TradingWithNextCoupon, tradingWithNextCoupon ? 1.0 : 0.0); return(results); }
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); }
public void TestAllInPrice() { var settleDate = new Date(2006, 6, 8); var maturityDate = new Date(2026, 12, 21); var notional = 1000000.0; var annualCouponRate = 0.105; var couponMonth1 = 6; var couponDay1 = 21; var couponMonth2 = 12; var couponDay2 = 21; var booksCloseDateDays = 10; var zaCalendar = new Calendar("Test"); var bondR186 = new BesaJseBond(maturityDate, notional, annualCouponRate, couponMonth1, couponDay1, couponMonth2, couponDay2, booksCloseDateDays, zaCalendar, TestHelpers.ZAR); var ytm = 0.0715; var results = bondR186.GetSpotMeasures(settleDate, ytm); Assert.AreEqual(140.65075443, (double)results.GetScalar(BesaJseBondEx.Keys.UnroundedAip), 1e-8); Assert.AreEqual(140.65075, (double)results.GetScalar(BesaJseBondEx.Keys.RoundedAip), 1e-8); }
public void TestAllInPrice() { var settleDate = new Date(2008, 1, 17); var maturityDate = new Date(2009, 8, 1); var notional = 1000000.0; var annualCouponRate = 0.13; var couponMonth1 = 2; var couponDay1 = 28; var couponMonth2 = 8; var couponDay2 = 31; var booksCloseDateDays = 10; var zaCalendar = new Calendar("Test"); var bondR153 = new BesaJseBond(maturityDate, notional, annualCouponRate, couponMonth1, couponDay1, couponMonth2, couponDay2, booksCloseDateDays, zaCalendar, TestHelpers.ZAR); var ytm = 0.0930; var results = bondR153.GetSpotMeasures(settleDate, ytm); Assert.AreEqual(110.400707433627, (double)results.GetScalar(BesaJseBondEx.Keys.UnroundedAip), 1e-8); Assert.AreEqual(110.40071, (double)results.GetScalar(BesaJseBondEx.Keys.RoundedAip), 1e-8); }
public void TestAllInPrice() { Date settleDate = new Date(2016, 3, 3); Date maturityDate = new Date(2030, 1, 31); double notional = 1000000; double annualCouponRate = 0.08; int couponMonth1 = 1; int couponDay1 = 31; int couponMonth2 = 7; int couponDay2 = 31; Calendar zaCalendar = new Calendar("Test"); var bondR2030 = new BesaJseBond(maturityDate, notional, annualCouponRate, couponMonth1, couponDay1, couponMonth2, couponDay2, zaCalendar, TestHelpers.ZAR); double ytm = 0.097; ResultStore results = bondR2030.GetSpotMeasures(settleDate, ytm); Assert.AreEqual(87.85607808, (double)results.GetScalar(BesaJseBondEx.Keys.unroundedAip), 1e-8); Assert.AreEqual(87.85608, (double)results.GetScalar(BesaJseBondEx.Keys.roundedAip), 1e-8); Assert.AreEqual(87.15470822, (double)results.GetScalar(BesaJseBondEx.Keys.unroundedClean), 1e-8); Assert.AreEqual(87.15471, (double)results.GetScalar(BesaJseBondEx.Keys.roundedClean), 1e-8); Assert.AreEqual(0.701369836, (double)results.GetScalar(BesaJseBondEx.Keys.unroundedAccrued), 1e-7); }
public void TestRiskMetrics() { var settleDate = new Date(2016, 3, 3); var maturityDate = new Date(2030, 1, 31); var notional = 1000000.0; var annualCouponRate = 0.08; var couponMonth1 = 1; var couponDay1 = 31; var couponMonth2 = 7; var couponDay2 = 31; var booksCloseDateDays = 10; var zaCalendar = new Calendar("Test"); var bondR2030 = new BesaJseBond(maturityDate, notional, annualCouponRate, couponMonth1, couponDay1, couponMonth2, couponDay2, booksCloseDateDays, zaCalendar, TestHelpers.ZAR); var ytm = 0.097; var results = bondR2030.GetRiskMeasures(settleDate, ytm); Assert.AreEqual(-6.85006370, (double)results.GetScalar(BesaJseBondEx.Keys.Delta), 1e-8); Assert.AreEqual(-685.00637043, (double)results.GetScalar(BesaJseBondEx.Keys.RandsPerPoint), 1e-8); Assert.AreEqual(7.79691497, (double)results.GetScalar(BesaJseBondEx.Keys.ModifiedDuration), 1e-8); Assert.AreEqual(8.17506535, (double)results.GetScalar(BesaJseBondEx.Keys.Duration), 1e-8); Assert.AreEqual(87.10044101, (double)results.GetScalar(BesaJseBondEx.Keys.Convexity), 1e-8); }
public void TestAssetSwap() { var settleDate = new Date(2013, 3, 8); var maturityDate = new Date(2015, 9, 15); var annualCouponRate = 0.135; var couponMonth1 = 3; var couponDay1 = 15; var couponMonth2 = 9; var couponDay2 = 15; var booksCloseDateDays = 10; var notional = 100000000; var payFixed = -1; var ccy = TestHelpers.ZAR; var index = new FloatRateIndex("ZAR.JIBAR.3M", ccy, "JIBAR", Tenor.FromMonths(3)); var ytm = 0.05757; var spread = 0.0; Date[] holidays = { new Date(2013, 1, 1), new Date(2013, 3, 21), new Date(2013, 3, 29), new Date(2013, 4, 1), new Date(2013, 4, 27), new Date(2013, 5, 1), new Date(2013, 6, 17), new Date(2013, 8, 9), new Date(2013, 9, 24), new Date(2013, 12, 16), new Date(2013, 12, 25), new Date(2013, 12, 26), new Date(2014, 1, 1), new Date(2014, 3, 21), new Date(2014, 4, 18), new Date(2014, 4, 21), new Date(2014, 4, 28), new Date(2014, 5, 1), new Date(2014, 5, 7), new Date(2014, 6, 16), new Date(2014, 8, 9), new Date(2014, 9, 24), new Date(2014, 12, 16), new Date(2014, 12, 25), new Date(2014, 12, 26), new Date(2015, 1, 1), new Date(2015, 3, 21), new Date(2015, 4, 3), new Date(2015, 4, 6), new Date(2015, 4, 27), new Date(2015, 5, 1), new Date(2015, 6, 16), new Date(2015, 8, 10), new Date(2015, 9, 24), new Date(2015, 12, 16), new Date(2020, 12, 25), new Date(2020, 12, 26) }; var zaCalendar = new Calendar("Test", holidays); var bond = new BesaJseBond(maturityDate, notional, annualCouponRate, couponMonth1, couponDay1, couponMonth2, couponDay2, booksCloseDateDays, zaCalendar, ccy); Date[] discountDates = { new Date(2013, 3, 6), new Date(2013, 4, 5), new Date(2013, 6, 5), new Date(2013, 9, 5), new Date(2013, 12, 5), new Date(2014, 3, 5), new Date(2014, 6, 5), new Date(2014, 9, 5), new Date(2014, 12, 5), new Date(2015, 3, 5), new Date(2015, 6, 5), new Date(2015, 9, 7), new Date(2015, 12, 7), new Date(2016, 3, 7), new Date(2016, 6, 6), new Date(2016, 9, 5), new Date(2016, 12, 5), new Date(2017, 3, 6), new Date(2017, 6, 5), new Date(2017, 9, 5), new Date(2017, 12, 5), new Date(2018, 3, 5), new Date(2018, 6, 5), new Date(2018, 9, 5), new Date(2018, 12, 5), new Date(2019, 3, 5), new Date(2019, 6, 5), new Date(2019, 9, 5), new Date(2019, 12, 5), new Date(2020, 3, 5), }; double[] discountRates = { 0.0476968834358959, 0.0501430754329056, 0.0509218045201335, 0.0507490287827958, 0.0506113173158310, 0.0506165682297636, 0.0507674467276694, 0.0510331587565828, 0.0513967654284081, 0.0518952383980752, 0.0524896820133486, 0.0530856475345829, 0.0536795171239116, 0.0542763619213055, 0.0550232983685124, 0.0557743840043158, 0.0565215576596013, 0.0572650196269946, 0.0580081291489062, 0.0587559589725926, 0.0595015505438427, 0.0602449665660311, 0.0609574950515419, 0.0616761490635943, 0.0623935543507907, 0.0631097408589442, 0.0637906604035856, 0.0644782668196503, 0.0651654909303646, 0.0658597518938604 }; var effectiveDateDays = 3; var unAdjTradeDate = settleDate.AddDays(-effectiveDateDays); var tradeDate = BusinessDayStore.ModifiedFollowing.Adjust(unAdjTradeDate, zaCalendar); IDiscountingSource discountCurve = new DatesAndRates(ccy, tradeDate, discountDates, discountRates); var swap = AssetSwapEx.CreateAssetSwap(payFixed, bond, settleDate, index, spread, zaCalendar, ccy, discountCurve); var results = swap.AssetSwapMeasures(settleDate, ytm, discountCurve); Assert.AreEqual(117.66281, Math.Round((double)results.GetScalar(AssetSwapEx.Keys.RoundedAip), 5), 1e-8); Assert.AreEqual(17.65586, Math.Round((double)results.GetScalar(AssetSwapEx.Keys.PVFirstCF), 5), 1e-8); Assert.AreEqual(-18.645, Math.Round((double)results.GetScalar(AssetSwapEx.Keys.NumeratorCashFlowsPrice), 3), 1e-8); Assert.AreEqual(-234.909, Math.Round((double)results.GetScalar(AssetSwapEx.Keys.DenominatorCashFlowsPrice), 3), 1e-8); Assert.AreEqual(0.004211, Math.Round((double)results.GetScalar(AssetSwapEx.Keys.AssetSwapSpread), 6), 1e-8); }
/// <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 clean price</returns> public static double RoundedClean(this BesaJseBond bond, Date settleDate, double ytm) { return(Math.Round(bond.UnroundedClean(settleDate, ytm), 5)); }
/// <summary> /// /// </summary> /// <param name="bond"></param> /// <param name="settleDate"></param> /// <param name="ytm"></param> /// <returns>delta of the bond</returns> public static double Delta(this BesaJseBond bond, Date settleDate, double ytm) { var delta = bond.DeltaAndConvexity(settleDate, ytm)[0]; return(delta); }
/// <summary> /// /// </summary> /// <param name="bond"></param> /// <param name="settleDate"></param> /// <param name="ytm"></param> /// <returns>rand per points of the bond</returns> public static double RandsPerPoint(this BesaJseBond bond, Date settleDate, double ytm) { return(100 * bond.Delta(settleDate, ytm)); }
public static AssetSwap CreateAssetSwap(double payFixed, BesaJseBond besaJseBond, Date settleDate, FloatRateIndex index, double spread, Calendar calendar, Currency ccy, IDiscountingSource discountCurve) { //Design floating leg inputs var dayCount = Actual365Fixed.Instance; var unAdjResetDatesFloating = new List <Date>(); var unAdjPaymentDatesFloating = new List <Date>(); var resetDatesFloating = new List <Date>(); var paymentDatesFloating = new List <Date>(); var accrualFractions = new List <double>(); var endDate = besaJseBond.maturityDate; var paymentDateFloating = new Date(endDate); var resetDateFloating = paymentDateFloating.SubtractTenor(index.Tenor); while (resetDateFloating >= settleDate) { unAdjPaymentDatesFloating.Add(paymentDateFloating); unAdjResetDatesFloating.Add(resetDateFloating); resetDatesFloating.Add(BusinessDayStore.ModifiedFollowing.Adjust(resetDateFloating, calendar)); paymentDatesFloating.Add(BusinessDayStore.ModifiedFollowing.Adjust(paymentDateFloating, calendar)); accrualFractions.Add(dayCount.YearFraction(BusinessDayStore.ModifiedFollowing.Adjust(resetDateFloating, calendar), BusinessDayStore.ModifiedFollowing.Adjust(paymentDateFloating, calendar))); paymentDateFloating = new Date(resetDateFloating); resetDateFloating = paymentDateFloating.SubtractTenor(index.Tenor); } resetDatesFloating.Reverse(); paymentDatesFloating.Reverse(); accrualFractions.Reverse(); resetDatesFloating[0] = new Date(settleDate); var firstResetDate = resetDatesFloating.First(); var firstPaymentDate = paymentDatesFloating.First(); accrualFractions[0] = dayCount.YearFraction(firstResetDate, firstPaymentDate); //Design Fixed leg inputs var unAdjPaymentDatesFixed = new List <Date>(); var paymentDatesFixed = new List <Date>(); var thisYearCpn1 = new Date(settleDate.Year, besaJseBond.couponMonth1, besaJseBond.couponDay1); var thisYearCpn2 = new Date(settleDate.Year, besaJseBond.couponMonth2, besaJseBond.couponDay2); var lastYearCpn2 = new Date(settleDate.Year - 1, besaJseBond.couponMonth2, besaJseBond.couponDay2); Date lcd; //lcd stands for last coupon date if (settleDate > thisYearCpn2) { lcd = new Date(thisYearCpn2.Year, thisYearCpn2.Month, thisYearCpn2.Day); } if (settleDate > thisYearCpn1) { lcd = new Date(thisYearCpn1.Year, thisYearCpn1.Month, thisYearCpn1.Day); } lcd = new Date(lastYearCpn2.Year, lastYearCpn2.Month, lastYearCpn2.Day); Date ncd; //ncd stands for next coupon date if (lcd.Month == besaJseBond.couponMonth2) { ncd = new Date(lcd.Year + 1, besaJseBond.couponMonth1, besaJseBond.couponDay1); } else { ncd = new Date(lcd.Year, besaJseBond.couponMonth2, besaJseBond.couponDay2); } var paymentDateFixed = new Date(ncd.AddTenor(Tenor.FromMonths(6))); while (paymentDateFixed <= endDate) { unAdjPaymentDatesFixed.Add(paymentDateFixed); paymentDatesFixed.Add(BusinessDayStore.ModifiedFollowing.Adjust(paymentDateFixed, calendar)); paymentDateFixed = paymentDateFixed.AddTenor(Tenor.FromMonths(6)); } //create new instance of asset swap var assetSwap = new AssetSwap(payFixed, index, besaJseBond, resetDatesFloating, paymentDatesFloating, paymentDatesFixed, spread, accrualFractions, calendar, ccy); //Create trade date of the swap var effectiveDateDays = 3; var unAdjTradeDate = settleDate.AddDays(-effectiveDateDays); var tradeDate = BusinessDayStore.ModifiedFollowing.Adjust(unAdjTradeDate, assetSwap.zaCalendar); //Set value date assetSwap.SetValueDate(tradeDate); // Calculate the first fixing off the curve to use at all past dates. var df1 = discountCurve.GetDF(tradeDate); var laterDate = tradeDate.AddTenor(assetSwap.index.Tenor); var df2 = discountCurve.GetDF(laterDate); var dt = (laterDate - tradeDate) / 365.0; var rate = (df1 / df2 - 1) / dt; // Create the forecast curve from the discount curve IFloatingRateSource forecastCurve = new ForecastCurveFromDiscount(discountCurve, assetSwap.index, new FloatingRateFixingCurve1Rate(tradeDate, rate, assetSwap.index)); //Setting index values var indexValues = new double[assetSwap.indexDates.Count]; for (var i = 0; i < assetSwap.indexDates.Count; i++) { indexValues[i] = forecastCurve.GetForwardRate(assetSwap.indexDates[i]); } assetSwap.SetIndexValues(assetSwap.index, indexValues); return(assetSwap); }
/// <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 rounded accrued interest</returns> public static double RoundedAccruedInterest(this BesaJseBond bond, Date settleDate) { return(Math.Round(bond.UnroundedAccruedInterest(settleDate), 5)); }
/// <summary> /// /// </summary> /// <param name="bond"></param> /// <param name="settleDate"></param> /// <param name="ytm"></param> /// <returns>duration of the bond</returns> public static double Duration(this BesaJseBond bond, Date settleDate, double ytm) { var v = 1 / (1 + ytm / 2); return(bond.ModefiedDuration(settleDate, ytm) / v); }
/// <summary> /// /// </summary> /// <param name="bond"></param> /// <param name="settleDate"></param> /// <param name="ytm"></param> /// <returns>convexity of the bond</returns> public static double Convexity(this BesaJseBond bond, Date settleDate, double ytm) { var convexity = bond.DeltaAndConvexity(settleDate, ytm)[1]; return(convexity); }