public void TestCoordinatorAllData() { // Make the swap var rate = 0.07; var payFixed = true; double notional = 1000000; var startDate = new Date(2016, 9, 17); var tenor = Tenor.Years(5); var swap = IRSwap.CreateZARSwap(rate, payFixed, notional, startDate, tenor); // Set up the model var valueDate = new Date(2016, 9, 17); var a = 0.05; var vol = 0.01; var flatCurveRate = 0.07; var hullWiteSim = new HullWhite1F(Currency.ZAR, a, vol, flatCurveRate, flatCurveRate, valueDate); hullWiteSim.AddForecast(FloatingIndex.JIBAR3M); var coordinator = new Coordinator(hullWiteSim, new List <Simulator>(), 5000); var date = valueDate; var endDate = valueDate.AddTenor(tenor); var fwdValueDates = new List <Date>(); while (date < endDate) { fwdValueDates.Add(date); date = date.AddTenor(Tenor.Days(10)); } var allDetails = coordinator.GetValuePaths(new Product[] { swap }, valueDate, fwdValueDates.ToArray()); allDetails.GetNames(); }
public void TestSwapHW() { // Make the swap var rate = 0.08; var payFixed = true; double notional = 1000000; var startDate = new Date(2016, 9, 17); var tenor = Tenor.Years(5); var swap = IRSwap.CreateZARSwap(rate, payFixed, notional, startDate, tenor); // Set up the model var valueDate = new Date(2016, 9, 17); var a = 0.05; var vol = 0.01; var flatCurveRate = 0.07; var hullWiteSim = new HullWhite1F(Currency.ZAR, a, vol, flatCurveRate, flatCurveRate, valueDate); hullWiteSim.AddForecast(FloatingIndex.JIBAR3M); var coordinator = new Coordinator(hullWiteSim, new List <Simulator>(), 10000); // Run the valuation var value = coordinator.Value(new Product[] { swap }, valueDate); var refValue = -41838.32; // See RateProductTest.xlsx Assert.AreEqual(refValue, value, 4000); }
public void Init() { // Set up the model valueDate = new Date(2016, 9, 17); var a = 0.05; var vol = 0.01; var flatCurveRate = 0.07; hullWiteSim = new HullWhite1F(Currency.ZAR, a, vol, flatCurveRate, flatCurveRate, valueDate); hullWiteSim.AddForecast(FloatingIndex.JIBAR3M); // Make the underlying swap var rate = 0.07; var payFixed = true; double notional = 1000000; var startDate = new Date(2016, 9, 17); var tenor = Tenor.Years(5); swapPay = IRSwap.CreateZARSwap(rate, payFixed, notional, startDate, tenor); swapRec = IRSwap.CreateZARSwap(rate, !payFixed, notional, startDate, tenor); // Full set of exercise dates exDates = new List <Date> { new Date(2017, 9, 17), new Date(2018, 9, 17), new Date(2019, 9, 17), new Date(2020, 9, 17) }; }
public void TestSwap() { // Make the swap var rate = 0.08; var payFixed = true; double notional = 1000000; var startDate = new Date(2016, 9, 17); var tenor = Tenor.Years(5); var swap = IRSwap.CreateZARSwap(rate, payFixed, notional, startDate, tenor); // Set up the model var valueDate = new Date(2016, 9, 17); Date[] dates = { new Date(2016, 9, 17), new Date(2026, 9, 17) }; double[] rates = { 0.07, 0.07 }; IDiscountingSource discountCurve = new DatesAndRates(Currency.ZAR, valueDate, dates, rates); IFloatingRateSource forecastCurve = new ForecastCurve(valueDate, FloatingIndex.JIBAR3M, dates, rates); var curveSim = new DeterminsiticCurves(discountCurve); curveSim.AddRateForecast(forecastCurve); var coordinator = new Coordinator(curveSim, new List <Simulator>(), 1); // Run the valuation var value = coordinator.Value(new Product[] { swap }, valueDate); var refValue = -41838.32; // See RateProductTest.xlsx Assert.AreEqual(refValue, value, 0.01); }
private Product[] GetListOfSwaps() { int N = 50000; Date anchorDate = new Date(2016, 11, 21); double rate = 0.08; bool payFixed = true; double notional = 1000000; double[,] swapDist = new double[, ] { { 0.171 }, { 0.148 }, { 0.101 }, { 0.094 }, { 0.108 }, { 0.056 }, { 0.041 }, { 0.049 }, { 0.047 }, { 0.056 }, { 0.013 }, { 0.013 }, { 0.010 }, { 0.011 }, { 0.011 }, { 0.004 }, { 0.003 }, { 0.005 }, { 0.007 }, { 0.006 }, { 0.004 }, { 0.004 }, { 0.007 }, { 0.005 }, { 0.006 }, { 0.006 }, { 0.003 }, { 0.003 }, { 0.002 }, { 0.005 } }; IRandomNumberGenerator <double> generator1 = new ZigguratUniformGenerator(0, 1); IRandomNumberGenerator <double> generator365 = new ZigguratUniformGenerator(1, 365); double[,] cumSum = swapDist.CumulativeSum(1); Product[] allSwaps = new Product[N]; for (int swapNum = 0; swapNum < N; swapNum++) { double x = generator1.Generate(); int years = 0; while (years < cumSum.GetLength(0) && x > cumSum[years, 0]) { years++; } int days = (int)Math.Round(generator365.Generate()); Date endDate = anchorDate.AddTenor(new Tenor(days, 0, 0, years)); Date startDate = endDate.AddTenor(Tenor.Years(-years - 1)); allSwaps[swapNum] = IRSwap.CreateZARSwap(rate, payFixed, notional, startDate, Tenor.Years(years + 1)); } return(allSwaps); }
public override double[] GetUnderlyingFactors(Date date) { double[] regressors = new double[3]; double fxRate = GetIndices(currencyPair, new List <Date> { date })[0]; double defaultIndicator = date < simDefaultTime ? 0.0 : 1.0; double fwdDefaultP = (1.0 - survivalProbSource.GetSP(date.AddTenor(Tenor.Years(1))) / survivalProbSource.GetSP(date)); regressors[0] = fxRate; regressors[1] = defaultIndicator; regressors[2] = fwdDefaultP; return(regressors); }
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 TestFloatLeg() { // Make the reference swap var rate = 0.0; var payFixed = true; double notional = 1000000; var startDate = new Date(2016, 9, 17); var tenor = Tenor.Years(1); var swap = IRSwap.CreateZARSwap(rate, payFixed, notional, startDate, tenor); // Make a FloatLeg var resetDates = new Date[4]; var paymentDates = new Date[4]; var accrualFractions = new double[4]; var runningDate = new Date(2016, 9, 17); for (var i = 0; i < 4; i++) { resetDates[i] = new Date(runningDate); paymentDates[i] = resetDates[i].AddMonths(3); accrualFractions[i] = (paymentDates[i] - resetDates[i]) / 365.0; runningDate = paymentDates[i]; } var floatLeg = new FloatLeg(Currency.ZAR, paymentDates, new[] { 1e6, 1e6, 1e6, 1e6 }, resetDates, new[] { FloatingIndex.JIBAR3M, FloatingIndex.JIBAR3M, FloatingIndex.JIBAR3M, FloatingIndex.JIBAR3M }, new double[] { 0, 0, 0, 0 }, accrualFractions); // Set up the model var valueDate = new Date(2016, 9, 17); Date[] dates = { new Date(2016, 9, 17), new Date(2026, 9, 17) }; double[] rates = { 0.07, 0.07 }; IDiscountingSource discountCurve = new DatesAndRates(Currency.ZAR, valueDate, dates, rates); IFloatingRateSource forecastCurve = new ForecastCurve(valueDate, FloatingIndex.JIBAR3M, dates, rates); var curveSim = new DeterminsiticCurves(discountCurve); curveSim.AddRateForecast(forecastCurve); // Run the valuation var coordinator = new Coordinator(curveSim, new List <Simulator>(), 1); var swapValue = coordinator.Value(new Product[] { swap }, valueDate); var floatLegValue = coordinator.Value(new Product[] { floatLeg }, valueDate); Assert.AreEqual(swapValue, floatLegValue, 0.01); }
public void TestMultiHWAndFXToyCCIRS() { var valueDate = new Date(2016, 9, 17); var zarRatesSim = new HullWhite1F(Currency.ZAR, 0.05, 0.01, 0.07, 0.07, valueDate); zarRatesSim.AddForecast(FloatingIndex.JIBAR3M); var usdRatesSim = new HullWhite1F(Currency.USD, 0.05, 0.01, 0.01, 0.01, valueDate); usdRatesSim.AddForecast(FloatingIndex.LIBOR3M); var eurRatesSim = new HullWhite1F(Currency.EUR, 0.05, 0.01, 0.005, 0.005, valueDate); eurRatesSim.AddForecast(FloatingIndex.EURIBOR3M); var currencyPairs = new[] { new CurrencyPair(Currency.USD, Currency.ZAR), new CurrencyPair(Currency.EUR, Currency.ZAR) }; var spots = new[] { 13.6, 15.0 }; var vols = new[] { 0.15, 0.15 }; var correlations = new[, ] { { 1.0, 0.0 }, { 0.0, 1.0 } }; var model = new MultiHWAndFXToy(valueDate, Currency.ZAR, new[] { zarRatesSim, usdRatesSim, eurRatesSim }, currencyPairs, spots, vols, correlations); var portfolio = new List <Product>(); portfolio.Add(CreateFloatingLeg(Currency.ZAR, valueDate, -15e6, FloatingIndex.JIBAR3M, 7)); portfolio.Add(CreateFloatingLeg(Currency.EUR, valueDate, +1e6, FloatingIndex.EURIBOR3M, 7)); portfolio.Add(CreateFloatingLeg(Currency.ZAR, valueDate, 13e6, FloatingIndex.JIBAR3M, 13)); portfolio.Add(CreateFloatingLeg(Currency.USD, valueDate, -1e6, FloatingIndex.EURIBOR3M, 13)); portfolio.Add(IRSwap.CreateZARSwap(0.07, true, 20e6, valueDate, Tenor.Years(4))); var stepInMonths = 1; var fwdValueDates = Enumerable.Range(1, 13 * 12 / stepInMonths) .Select(i => valueDate.AddMonths(stepInMonths * i)).ToArray(); var coord = new Coordinator(model, new List <Simulator>(), 1000); //coord.SetThreadedness(false); var epe = coord.EPE(portfolio.ToArray(), valueDate, fwdValueDates); Assert.AreEqual(1555002, epe[0], 5000); Assert.AreEqual(2170370, epe[87], 5000); Assert.AreEqual(0, epe[155], 5); //Debug.WriteToFile("c:\\dev\\quantsa\\temp\\epeTest_singlethread_10000.csv", epe); }
public void TestCoordinatorEPESwap() { // Make the swap var rate = 0.07; var payFixed = true; double notional = 1000000; var startDate = new Date(2016, 9, 17); var tenor = Tenor.Years(5); var swap = IRSwap.CreateZARSwap(rate, payFixed, notional, startDate, tenor); // Set up the model var valueDate = new Date(2016, 9, 17); var a = 0.05; var vol = 0.005; var flatCurveRate = 0.07; var hullWiteSim = new HullWhite1F(Currency.ZAR, a, vol, flatCurveRate, flatCurveRate, valueDate); hullWiteSim.AddForecast(FloatingIndex.JIBAR3M); var coordinator = new Coordinator(hullWiteSim, new List <Simulator>(), 5000); var date = valueDate; var endDate = valueDate.AddTenor(tenor); var fwdValueDates = new List <Date>(); while (date < endDate) { fwdValueDates.Add(date); date = date.AddTenor(Tenor.Days(10)); } var epe = coordinator.EPE(new Product[] { swap }, valueDate, fwdValueDates.ToArray()); //Debug.WriteToFile(@"c:\dev\temp\epe_rate08_vol005.csv", epe); Assert.AreEqual(2560, epe[0], 100.0); Assert.AreEqual(6630, epe[90], 100.0); Assert.AreEqual(734, epe[182], 30); }
public static HullWhite1F CreateHWModelDemo([ExcelArgument(Description = "The constant rate of mean reversion.")] double meanReversion, [ExcelArgument(Description = "The constant short rate volatility. Note that this is a Gaussian vol and will in general be lower than the vol that would be used in Black.")] double flatVol, [ExcelArgument(Description = "The curve to which zero coupon bond prices will be calibrated.")] IDiscountingSource baseCurve, [ExcelArgument(Description = "The indices that should be forecast with this same cuve. No spreads are added.")] FloatingIndex forecastIndices) { Date anchorDate = baseCurve.GetAnchorDate(); double flatCurveRate = -Math.Log(baseCurve.GetDF(anchorDate.AddTenor(Tenor.Years(1)))); HullWhite1F model = new HullWhite1F(baseCurve.GetCurrency(), meanReversion, flatVol, flatCurveRate, flatCurveRate, anchorDate); model.AddForecast(forecastIndices); return(model); }
public void TestMultiHWAndFXToyCCIRSAltConstructor() { var valueDate = new Date(2016, 9, 17); var spots = new List <double> { 13.6, 15.0 }; var vols = new List <double> { 0.15, 0.15 }; var correlations = new[, ] { { 1.0, 0.0 }, { 0.0, 1.0 } }; // ZAR HW specs IDiscountingSource zarCurve = new DatesAndRates(Currency.ZAR, valueDate, new[] { valueDate, valueDate.AddMonths(240) }, new[] { 0.07, 0.07 }); var zarHWParams = new HWParams { vol = 0.01, meanReversionSpeed = 0.05 }; var zarRequiredIndices = new List <FloatingIndex> { FloatingIndex.JIBAR3M }; // Lists to be populated for other currencies var otherCcys = new List <Currency>(); var otherCcyCurves = new List <IDiscountingSource>(); var otherCcyHwParams = new List <HWParams>(); var otherCcyRequiredIndices = new List <List <FloatingIndex> >(); // USD HW specs otherCcys.Add(Currency.USD); otherCcyCurves.Add(new DatesAndRates(Currency.USD, valueDate, new[] { valueDate, valueDate.AddMonths(240) }, new[] { 0.01, 0.01 })); otherCcyHwParams.Add(new HWParams { vol = 0.01, meanReversionSpeed = 0.05 }); otherCcyRequiredIndices.Add(new List <FloatingIndex> { FloatingIndex.LIBOR3M }); // EUR HW specs otherCcys.Add(Currency.EUR); otherCcyCurves.Add(new DatesAndRates(Currency.EUR, valueDate, new[] { valueDate, valueDate.AddMonths(240) }, new[] { 0.005, 0.005 })); otherCcyHwParams.Add(new HWParams { vol = 0.01, meanReversionSpeed = 0.05 }); otherCcyRequiredIndices.Add(new List <FloatingIndex> { FloatingIndex.EURIBOR3M }); // Construct the model var model = new MultiHWAndFXToy(valueDate, zarCurve, zarRequiredIndices, zarHWParams, otherCcys, spots, vols, otherCcyCurves, otherCcyRequiredIndices, otherCcyHwParams, correlations); var portfolio = new List <Product>(); portfolio.Add(CreateFloatingLeg(Currency.ZAR, valueDate, -15e6, FloatingIndex.JIBAR3M, 7)); portfolio.Add(CreateFloatingLeg(Currency.EUR, valueDate, +1e6, FloatingIndex.EURIBOR3M, 7)); portfolio.Add(CreateFloatingLeg(Currency.ZAR, valueDate, 13e6, FloatingIndex.JIBAR3M, 13)); portfolio.Add(CreateFloatingLeg(Currency.USD, valueDate, -1e6, FloatingIndex.EURIBOR3M, 13)); portfolio.Add(IRSwap.CreateZARSwap(0.07, true, 20e6, valueDate, Tenor.Years(4))); var stepInMonths = 1; var fwdValueDates = Enumerable.Range(1, 13 * 12 / stepInMonths) .Select(i => valueDate.AddMonths(stepInMonths * i)).ToArray(); var coord = new Coordinator(model, new List <Simulator>(), 1000); //coord.SetThreadedness(false); var epe = coord.EPE(portfolio.ToArray(), valueDate, fwdValueDates); Assert.AreEqual(1555002, epe[0], 5000); Assert.AreEqual(2170370, epe[87], 5000); Assert.AreEqual(0, epe[155], 5); //Debug.WriteToFile("c:\\dev\\quantsa\\temp\\epeTest_2.csv", epe); }
/// <summary> /// Run a simulation and store the results for later use by <see cref="GetIndices(MarketObservable, List{Date})"/> /// </summary> /// <param name="simNumber"></param> public override void RunSimulation(int simNumber) { simulation = new Dictionary <int, double>(); double simRate = spot; double oldFxFwd = spot; double newFXfwd; // Simulate the default NormalDistribution normal = new NormalDistribution(); UniformContinuousDistribution uniform = new UniformContinuousDistribution(); double hazEst = survivalProbSource.GetSP(survivalProbSource.getAnchorDate().AddTenor(Tenor.Years(1))); hazEst = -Math.Log(hazEst); Generator.Seed = -533776581 * simNumber; // This magic number is: "DeterministicCreditWithFXJump".GetHashCode(); double tau = uniform.Generate(); tau = Math.Log(tau) / (-hazEst); simDefaultTime = anchorDate.value + tau * 365; for (int timeCounter = 0; timeCounter < allRequiredDates.Count; timeCounter++) { double dt = timeCounter > 0 ? allRequiredDates[timeCounter] - allRequiredDates[timeCounter - 1] : allRequiredDates[timeCounter] - anchorDate.value; newFXfwd = fxSource.GetRate(new Date(anchorDate.value + dt)); dt = dt / 365.0; double sdt = Math.Sqrt(dt); double dW = normal.Generate(); // TODO: drift needs to be adjusted for default rate * jump size simRate = simRate * newFXfwd / oldFxFwd * Math.Exp((-0.5 * fxVol * fxVol) * dt + fxVol * sdt * dW); if (simDefaultTime < allRequiredDates[timeCounter]) { simulation[allRequiredDates[timeCounter]] = simRate * (1 + relJumpSizeInDefault); } else { simulation[allRequiredDates[timeCounter]] = simRate; } } }