public void RateCurveCalibrator_CanCalibrateTwoCurves() { var instruments = new List <IRateCurveInstrument>(); var zarCsaCurveDescription = new DiscountingSourceDescription(_zar, new BankAccountNumeraire(_zar)); var jibarDiscountDescription = new DiscountingSourceDescription(_zar, _jibar3M); instruments.Add(new DepoCurveInstrument(Tenor.FromMonths(3), 0.071, jibarDiscountDescription)); instruments.Add(new FixedFloatSwapCurveInstrument(Tenor.FromMonths(6), _jibar3M, 0.0, 0.07, zarCsaCurveDescription, FixedFloatSwapCurveInstrument.CurveToStrip.Forecast)); instruments.Add(new FixedFloatSwapCurveInstrument(Tenor.FromYears(2), _jibar3M, 0.0, 0.07, zarCsaCurveDescription, FixedFloatSwapCurveInstrument.CurveToStrip.Forecast)); instruments.Add(new DepoCurveInstrument(Tenor.FromDays(1), 0.06, zarCsaCurveDescription)); instruments.Add(new BasisSwapCurveInstrument(Tenor.FromYears(1), _jibar3M, _jibar1D, 0.0, 0.01, zarCsaCurveDescription, BasisSwapCurveInstrument.CurveToStrip.DiscountCurve)); instruments.Add(new BasisSwapCurveInstrument(Tenor.FromYears(2), _jibar3M, _jibar1D, 0.0, 0.01, zarCsaCurveDescription, BasisSwapCurveInstrument.CurveToStrip.DiscountCurve)); var calib = new RateCurveCalibrator(instruments, new MultiDimNewton(1e-8, 100), zarCsaCurveDescription, new FloatRateIndex[] { _jibar1D }, jibarDiscountDescription, new FloatRateIndex[] { _jibar3M }); var mdc = new MarketDataContainer(); mdc.Set(calib); calib.TryCalibrate(_calibrationDate, mdc); var testValues = instruments.Select(inst => Math.Abs(inst.Objective())); var maxTestValue = testValues.Max(); Assert.AreEqual(0.0, maxTestValue, 1e-8); }
public void TestInflationLinkedSwap() { //Testing the zero-coupon inflation swap //Parameterise test inputs below var payFixed = -1; var startDate = new Date(2005, 8, 31); var nominal = (double)5000000; var tenor = Tenor.FromYears(2); var fixedRate = 0.036; var ccy = TestHelpers.ZAR; var index = new FloatRateIndex("ZAR.JIBAR.3M", ccy, "JIBAR", Tenor.FromMonths(3)); var spread = 0.0; Date[] cpiDates = { new Date(2005, 3, 1), new Date(2005, 4, 1), new Date(2005, 5, 1), new Date(2005, 6, 1), new Date(2005, 7, 1), new Date(2005, 8, 1), new Date(2005, 9, 1), new Date(2005, 10, 1), new Date(2005, 11, 1), new Date(2005, 12, 1), new Date(2006, 1, 1), new Date(2006, 2, 1), new Date(2006, 3, 1), new Date(2006, 4, 1), new Date(2006, 5, 1), new Date(2006, 6, 1), new Date(2006, 7, 1), new Date(2006, 8, 1), new Date(2006, 9, 1), new Date(2006, 10, 1), new Date(2006, 11, 1), new Date(2006, 12, 1), new Date(2007, 1, 1), new Date(2007, 2, 1), new Date(2007, 3, 1), new Date(2007, 4, 1), new Date(2007, 5, 1), new Date(2007, 6, 1), new Date(2007, 7, 1), new Date(2007, 8, 1), new Date(2007, 9, 1), new Date(2007, 10, 1) , }; double[] cpiRates = { 126.90, 127.60, 127.60, 127.40, 128.50, 129.0, 129.50, 129.60, 129.50, 129.50, 130.40, 130.50, 131.20, 131.80, 132.60, 133.60, 134.90, 136.0, 136.30, 136.60, 136.50, 137.0, 138.20, 139.20, 138.0, 141.0, 141.80, 143.0, 144.40, 145.10, 146.10, 147.40 }; var zaCalendar = new Calendar("Test"); Date[] curveDates = { new Date(2005, 8, 31), new Date(2005, 11, 30), new Date(2006, 2, 28), new Date(2006, 5, 31), new Date(2006, 8, 31), new Date(2006, 11, 30), new Date(2007, 2, 28), new Date(2007, 5, 31) }; double[] curveRates = { 0.07004, 0.07164, 0.07092, 0.07079, 0.08224, 0.08918, 0.09075, 0.09354 }; //Create curve used to determine swap cash flows IFloatingRateSource forecastCurve = new ForecastCurve(startDate, index, curveDates, curveRates); //Create instance of an inflation swap var inflationSwap = InflationLinkedSwapEx.CreateInflationLinkedSwap(payFixed, startDate, nominal, tenor, fixedRate, index, spread, zaCalendar, ccy); //Get results var results = inflationSwap.InflationLinkedSwapMeasures(cpiDates, cpiRates, forecastCurve); Assert.AreEqual(5856959.45, Math.Round((double)results.GetScalar(InflationLinkedSwapEx.Keys.FloatingLegCashFlows), 2), 1e-8); Assert.AreEqual(-5966334.90, Math.Round((double)results.GetScalar(InflationLinkedSwapEx.Keys.FixedLegCashFlows), 2), 1e-8); Assert.AreEqual(-109375.45, Math.Round((double)results.GetScalar(InflationLinkedSwapEx.Keys.NetCashFlows), 2), 1e-8); }
public void TestQuantoCDS() { var spot = 1.00; var relJumpSizeInDefault = -0.2; var cdsSpread = 0.025; // Trades var anchorDate = new Date(2016, 11, 25); var refEntity = TestHelpers.TestCp; DateGenerators.CreateDatesNoHolidays(Tenor.FromMonths(3), anchorDate, 20, out var paymentDates, out var accrualFractions); var zarNotionals = Vector.Ones(paymentDates.Length).Multiply(1000000.0); var zarSpreads = Vector.Ones(paymentDates.Length).Multiply(cdsSpread); var usdSpreads = zarSpreads.Multiply(1 + relJumpSizeInDefault); // Adjusted for the FX jump size. var boughtProtection = true; var cdsZAR = new CDS(refEntity, TestHelpers.ZAR, paymentDates, zarNotionals, zarSpreads, accrualFractions, boughtProtection); var cdsUSD = new CDS(refEntity, TestHelpers.USD, paymentDates, zarNotionals, usdSpreads, accrualFractions, boughtProtection); // Model var curveDates = new[] { anchorDate, anchorDate.AddTenor(Tenor.FromYears(10)) }; var expectedRecovery = 0.4; var hazardRates = new[] { cdsSpread / (1 - expectedRecovery), cdsSpread / (1 - expectedRecovery) }; var usdRates = new[] { 0.01, 0.02 }; var zarRates = new[] { 0.07, 0.08 }; var usdDiscountCurve = new DatesAndRates(TestHelpers.USD, anchorDate, curveDates, usdRates); var zarDiscountCurve = new DatesAndRates(TestHelpers.ZAR, anchorDate, curveDates, zarRates); var abcHazardCurve = new HazardCurve(refEntity, anchorDate, curveDates, hazardRates); var fxSource = new FXForecastCurve(TestHelpers.USDZAR, spot, usdDiscountCurve, zarDiscountCurve); var fxVol = 0.15; var model = new DeterministicCreditWithFXJump(abcHazardCurve, TestHelpers.USDZAR, fxSource, zarDiscountCurve, fxVol, relJumpSizeInDefault, expectedRecovery); // Valuation var N = 5000; var coord = new Coordinator(model, new List <Simulator>(), N); var zarValue = coord.Value(new[] { cdsZAR }, anchorDate); var usdValue = coord.Value(new[] { cdsUSD }, anchorDate); Assert.AreEqual(0.0, zarValue, 800.0); // about 2bp Assert.AreEqual(0.0, usdValue, 800.0); // about 2bp }
public void RateCurveCalibrator_CanCalibrateSingleCurve() { var instruments = new List <IRateCurveInstrument>(); var discountCurve = new DiscountingSourceDescription(TestHelpers.ZAR); instruments.Add(new DepoCurveInstrument(Tenor.FromMonths(1), 0.071, discountCurve)); instruments.Add(new DepoCurveInstrument(Tenor.FromMonths(3), 0.072, discountCurve)); instruments.Add(new DepoCurveInstrument(Tenor.FromMonths(6), 0.073, discountCurve)); instruments.Add(new FRACurveInstrument(Tenor.FromMonths(6), Tenor.FromMonths(9), TestHelpers.Jibar3M, 0.073)); var calib = new RateCurveCalibrator(instruments, new MultiDimNewton(1e-8, 100), discountCurve, new FloatRateIndex[] { TestHelpers.Jibar3M }); var mdc = new MarketDataContainer(); mdc.Set(calib); calib.TryCalibrate(_calibrationDate, mdc); var testValues = instruments.Select(inst => Math.Abs(inst.Objective())); var maxTestValue = testValues.Max(); Assert.AreEqual(0.0, maxTestValue, 1e-8); }
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); }
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); }