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.FromYears(5); var swap = TestHelpers.CreateZARSwap(rate, payFixed, notional, startDate, tenor, TestHelpers.Jibar3M); // 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(TestHelpers.ZAR, a, vol, flatCurveRate, flatCurveRate); hullWiteSim.AddForecast(TestHelpers.Jibar3M); var coordinator = new Coordinator(hullWiteSim, new List <Simulator>(), 10000); // Run the valuation var value = coordinator.Value(new IProduct[] { swap }, valueDate); var refValue = -41838.32; // See RateProductTest.xlsx Assert.AreEqual(refValue, value, 4000); }
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.FromYears(5); var swap = TestHelpers.CreateZARSwap(rate, payFixed, notional, startDate, tenor, TestHelpers.Jibar3M); // 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(TestHelpers.ZAR, a, vol, flatCurveRate, flatCurveRate); hullWiteSim.AddForecast(TestHelpers.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.FromDays(10)); } var allDetails = coordinator.GetValuePaths(new Product[] { swap }, valueDate, fwdValueDates.ToArray()); allDetails.GetNames(); }
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.FromYears(5); var swap = TestHelpers.CreateZARSwap(rate, payFixed, notional, startDate, tenor, TestHelpers.Jibar3M); // 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(TestHelpers.ZAR, valueDate, dates, rates); IFloatingRateSource forecastCurve = new ForecastCurve(valueDate, TestHelpers.Jibar3M, dates, rates); var curveSim = new DeterministicCurves(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); }
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(TestHelpers.ZAR, a, vol, flatCurveRate, flatCurveRate); hullWiteSim.AddForecast(TestHelpers.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.FromYears(5); swapPay = TestHelpers.CreateZARSwap(rate, payFixed, notional, startDate, tenor, TestHelpers.Jibar3M); swapRec = TestHelpers.CreateZARSwap(rate, !payFixed, notional, startDate, tenor, TestHelpers.Jibar3M); // 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 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 override double[] GetUnderlyingFactors(Date date) { var regressors = new double[3]; var fxRate = GetIndices(_currencyPair, new List <Date> { date })[0]; var defaultIndicator = date < _simDefaultTime ? 0.0 : 1.0; var fwdDefaultP = 1.0 - _survivalProbSource.GetSP(date.AddTenor(Tenor.FromYears(1))) / _survivalProbSource.GetSP(date); regressors[0] = fxRate; regressors[1] = defaultIndicator; regressors[2] = fwdDefaultP; return(regressors); }
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.FromYears(1); var swap = TestHelpers.CreateZARSwap(rate, payFixed, notional, startDate, tenor, TestHelpers.Jibar3M); // 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(TestHelpers.ZAR, paymentDates, new[] { 1e6, 1e6, 1e6, 1e6 }, resetDates, new[] { TestHelpers.Jibar3M, TestHelpers.Jibar3M, TestHelpers.Jibar3M, TestHelpers.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(TestHelpers.ZAR, valueDate, dates, rates); IFloatingRateSource forecastCurve = new ForecastCurve(valueDate, TestHelpers.Jibar3M, dates, rates); var curveSim = new DeterministicCurves(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 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 TestMultiHWAndFXToyCCIRS() { var valueDate = new Date(2016, 9, 17); var zarRatesSim = new HullWhite1F(TestHelpers.ZAR, 0.05, 0.01, 0.07, 0.07); zarRatesSim.AddForecast(TestHelpers.Jibar3M); var usdRatesSim = new HullWhite1F(TestHelpers.USD, 0.05, 0.01, 0.01, 0.01); usdRatesSim.AddForecast(TestHelpers.Libor3M); var eurRatesSim = new HullWhite1F(TestHelpers.EUR, 0.05, 0.01, 0.005, 0.005); eurRatesSim.AddForecast(TestHelpers.Euribor3M); var currencyPairs = new[] { TestHelpers.USDZAR, TestHelpers.EURZAR }; 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, TestHelpers.ZAR, new[] { zarRatesSim, usdRatesSim, eurRatesSim }, currencyPairs, spots, vols, correlations); var portfolio = new List <IProduct> { CreateFloatingLeg(TestHelpers.ZAR, valueDate, -15e6, TestHelpers.Jibar3M, 7), CreateFloatingLeg(TestHelpers.EUR, valueDate, +1e6, TestHelpers.Euribor3M, 7), CreateFloatingLeg(TestHelpers.ZAR, valueDate, 13e6, TestHelpers.Jibar3M, 13), CreateFloatingLeg(TestHelpers.USD, valueDate, -1e6, TestHelpers.Euribor3M, 13), TestHelpers.CreateZARSwap(0.07, true, 20e6, valueDate, Tenor.FromYears(4), TestHelpers.Jibar3M) }; 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(1489695, epe[0], 5000); Assert.AreEqual(2194183, epe[87], 5000); Assert.AreEqual(0, epe[155], 5); //QuantSA.Shared.Debug.Debug.WriteToFile("c:\\dev\\quantsa\\temp\\epeTest_singlethread_10000.csv", epe); }
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 curve. No spreads are added.")] FloatRateIndex forecastIndices) { var anchorDate = baseCurve.GetAnchorDate(); var flatCurveRate = -Math.Log(baseCurve.GetDF(anchorDate.AddTenor(Tenor.FromYears(1)))); var model = new HullWhite1F(baseCurve.GetCurrency(), meanReversion, flatVol, flatCurveRate, flatCurveRate, new[] { forecastIndices }); return(model); }
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.FromYears(5); var swap = TestHelpers.CreateZARSwap(rate, payFixed, notional, startDate, tenor, TestHelpers.Jibar3M); // 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(TestHelpers.ZAR, a, vol, flatCurveRate, flatCurveRate); hullWiteSim.AddForecast(TestHelpers.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.FromDays(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); }
private Product[] GetListOfSwaps() { var N = 50000; var anchorDate = new Date(2016, 11, 21); var rate = 0.08; var payFixed = true; double notional = 1000000; var swapDist = new[, ] { { 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); var cumSum = swapDist.CumulativeSum(1); var allSwaps = new Product[N]; for (var swapNum = 0; swapNum < N; swapNum++) { var x = generator1.Generate(); var years = 0; while (years < cumSum.GetLength(0) && x > cumSum[years, 0]) { years++; } var days = (int)Math.Round(generator365.Generate()); var endDate = anchorDate.AddTenor(new Tenor(days, 0, 0, years)); var startDate = endDate.AddTenor(Tenor.FromYears(-years - 1)); allSwaps[swapNum] = TestHelpers.CreateZARSwap(rate, payFixed, notional, startDate, Tenor.FromYears(years + 1), TestHelpers.Jibar3M); } return(allSwaps); }
/// <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>(); var spot = _fxSource.GetRate(_anchorDate); var simRate = spot; var oldFxFwd = spot; double newFXfwd; // Simulate the default var normal = new NormalDistribution(); var uniform = new UniformContinuousDistribution(); var hazEst = _survivalProbSource.GetSP(_survivalProbSource.getAnchorDate().AddTenor(Tenor.FromYears(1))); hazEst = -Math.Log(hazEst); Generator.Seed = -533776581 * simNumber; // This magic number is: "DeterministicCreditWithFXJump".GetHashCode(); var tau = uniform.Generate(); tau = Math.Log(tau) / -hazEst; _simDefaultTime = _anchorDate.value + tau * 365; for (var 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; var sdt = Math.Sqrt(dt); var 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; } } }