public void TestCurveStripTwoZARDiscount() { var valueDate = new Date(2017, 1, 13); var zar = Currency.ZAR; // Empty curves var zarDiscUSDColl = new ZeroRatesCurveForStripping(valueDate, zar); var zarDisc = new ZeroRatesCurveForStripping(valueDate, zar); var jibarCurve = new ForwardRatesCurveForStripping(valueDate, FloatingIndex.JIBAR3M); // Models var modelZARDiscUSDColl = new DeterminsiticCurves(zarDiscUSDColl); modelZARDiscUSDColl.AddRateForecast(jibarCurve); var coordZARDiscUSDColl = new Coordinator(modelZARDiscUSDColl, new List <Simulator>(), 1); coordZARDiscUSDColl.SetThreadedness(false); var modelZARDisc = new DeterminsiticCurves(zarDisc); modelZARDisc.AddRateForecast(jibarCurve); // same jibar curve in both coordinators. var coordZARDisc = new Coordinator(modelZARDisc, new List <Simulator>(), 1); coordZARDisc.SetThreadedness(false); //Instruments for USDColl discounting curve. var mcs = new MultiCurveStripper(valueDate); var depo1 = MakeDepo(valueDate, 0.07, 24); var depo2 = MakeDepo(valueDate, 0.072, 48); mcs.AddDiscounting(depo1, () => coordZARDiscUSDColl.Value(depo1, valueDate), 1.0, 1.0, zarDiscUSDColl); mcs.AddDiscounting(depo2, () => coordZARDiscUSDColl.Value(depo2, valueDate), 1.0, 1.0, zarDiscUSDColl); Product swapUSDColl1 = IRSwap.CreateZARSwap(0.07, true, 1.0, valueDate, Tenor.Months(24)); Product swapUSDColl2 = IRSwap.CreateZARSwap(0.072, true, 1.0, valueDate, Tenor.Months(48)); mcs.AddForecast(swapUSDColl1, () => coordZARDiscUSDColl.Value(swapUSDColl1, valueDate), 0, 1, jibarCurve, FloatingIndex.JIBAR3M); mcs.AddForecast(swapUSDColl2, () => coordZARDiscUSDColl.Value(swapUSDColl2, valueDate), 0, 1, jibarCurve, FloatingIndex.JIBAR3M); Product swapNoColl1 = IRSwap.CreateZARSwap(0.0709, true, 1.0, valueDate, Tenor.Months(36)); Product swapNoColl2 = IRSwap.CreateZARSwap(0.0719, true, 1.0, valueDate, Tenor.Months(48)); mcs.AddDiscounting(swapNoColl1, () => coordZARDisc.Value(swapNoColl1, valueDate), 0, 1, zarDisc); mcs.AddDiscounting(swapNoColl2, () => coordZARDisc.Value(swapNoColl2, valueDate), 0, 1, zarDisc); mcs.Strip(); Assert.AreEqual(1.0, coordZARDiscUSDColl.Value(depo1, valueDate), 1e-6); Assert.AreEqual(1.0, coordZARDiscUSDColl.Value(depo2, valueDate), 1e-6); Assert.AreEqual(0.0, coordZARDiscUSDColl.Value(swapUSDColl2, valueDate), 1e-6); Assert.AreEqual(0.0, coordZARDiscUSDColl.Value(swapUSDColl2, valueDate), 1e-6); //Assert.AreNotEqual(0.0, coordZARDisc.Value(swapUSDColl1, valueDate), 1e-6); No discount sensitivity Assert.AreNotEqual(0.0, coordZARDisc.Value(swapUSDColl2, valueDate), 1e-6); Assert.AreEqual(0.0, coordZARDisc.Value(swapNoColl1, valueDate), 1e-6); Assert.AreEqual(0.0, coordZARDisc.Value(swapNoColl2, valueDate), 1e-6); }
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 = new ReferenceEntity("ABC"); Date[] paymentDates; double[] accrualFractions; DateGenerators.CreateDatesNoHolidays(Tenor.Months(3), anchorDate, 20, out paymentDates, out accrualFractions); var zarNotionals = Vector.Ones(paymentDates.Length).Multiply(1000000.0); var usdNotionals = zarNotionals.Divide(spot); 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, Currency.ZAR, paymentDates, zarNotionals, zarSpreads, accrualFractions, boughtProtection); var cdsUSD = new CDS(refEntity, Currency.USD, paymentDates, zarNotionals, usdSpreads, accrualFractions, boughtProtection); // Model var curveDates = new[] { anchorDate, anchorDate.AddTenor(Tenor.Years(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 }; IDiscountingSource usdDiscountCurve = new DatesAndRates(Currency.USD, anchorDate, curveDates, usdRates); IDiscountingSource zarDiscountCurve = new DatesAndRates(Currency.ZAR, anchorDate, curveDates, zarRates); ISurvivalProbabilitySource abcHazardCurve = new HazardCurve(refEntity, anchorDate, curveDates, hazardRates); var otherCurrency = Currency.USD; var fxSource = new FXForecastCurve(otherCurrency, Currency.ZAR, spot, usdDiscountCurve, zarDiscountCurve); var fxVol = 0.15; NumeraireSimulator model = new DeterministicCreditWithFXJump(abcHazardCurve, otherCurrency, fxSource, zarDiscountCurve, fxVol, relJumpSizeInDefault, expectedRecovery); // Valuation var N = 5000; var coord = new Coordinator(model, new List <Simulator>(), N); var zarValue = coord.Value(new Product[] { cdsZAR }, anchorDate); var usdValue = coord.Value(new Product[] { cdsUSD }, anchorDate); Assert.AreEqual(0.0, zarValue, 800.0); // about 2bp Assert.AreEqual(0.0, usdValue, 800.0); // about 2bp }
public void TestCurveStripSeparateForecastAndDiscount() { var valueDate = new Date(2017, 1, 13); var zar = Currency.ZAR; var N = 1.0; var r1 = 0.12; var r2 = 0.08; var date1 = valueDate.AddMonths(6); var date2 = valueDate.AddMonths(12); var zarDisc = new ZeroRatesCurveForStripping(valueDate, zar); var jibar3mForecast = new ForwardRatesCurveForStripping(valueDate, FloatingIndex.JIBAR3M, zarDisc); Product depo1 = new CashLeg(new[] { valueDate, date1 }, new[] { -N, N * (1 + r1 * 0.5) }, new[] { zar, zar }); Product depo2 = new CashLeg(new[] { valueDate, date2 }, new[] { -N, N * (1 + r2 * 1) }, new[] { zar, zar }); Product swap = IRSwap.CreateZARSwap(0.08, true, 1.0, valueDate, Tenor.Months(9)); var modelZARDisc = new DeterminsiticCurves(zarDisc); modelZARDisc.AddRateForecast(jibar3mForecast); var coordZARDisc = new Coordinator(modelZARDisc, new List <Simulator>(), 1); coordZARDisc.SetThreadedness(false); var mcs = new MultiCurveStripper(valueDate); mcs.AddDiscounting(depo1, () => coordZARDisc.Value(depo1, valueDate), N, 1.0, zarDisc); mcs.AddDiscounting(depo2, () => coordZARDisc.Value(depo2, valueDate), N, 1.0, zarDisc); mcs.AddForecast(swap, () => coordZARDisc.Value(swap, valueDate), 0.0, 1.0, jibar3mForecast, FloatingIndex.JIBAR3M); mcs.Strip(); Assert.AreEqual(N, coordZARDisc.Value(depo1, valueDate), 1e-6); Assert.AreEqual(N, coordZARDisc.Value(depo2, valueDate), 1e-6); Assert.AreEqual(0, coordZARDisc.Value(swap, valueDate), 1e-6); /*double[] fwdRates = new double[180]; * for (int i=0; i<180; i++ ) * { * fwdRates[i] = jibar3mForecast.GetForwardRate(valueDate.AddTenor(Tenor.Days(i))); * } * Debug.WriteToFile("c:\\dev\\quantsa\\temp\\fwdRates.csv", fwdRates); */ }