public void TestValuationCoordinator() { var exerciseDate = new Date(2017, 08, 28); var shareCode = "AAA"; var strike = 100.0; Product p = new EuropeanOption(new Share(shareCode, Currency.ZAR), strike, exerciseDate); var shares = new[] { new Share(shareCode, Currency.ZAR) }; // One needs to know the index that will be required by the product to simulate it. var valueDate = new Date(2016, 08, 28); var divYield = new[] { 0.02 }; var vol = new[] { 0.22 }; var spotPrice = new[] { 100.0 }; var correlations = new[, ] { { 1.0 } }; IDiscountingSource discountCurve = new DatesAndRates(Currency.ZAR, valueDate, new[] { valueDate, valueDate.AddMonths(120) }, new[] { 0.07, 0.07 }); var rateForecastCurves = new IFloatingRateSource[0]; var sim = new EquitySimulator(shares, spotPrice, vol, divYield, correlations, discountCurve, rateForecastCurves); var coordinator = new Coordinator(sim, new List <Simulator>(), 10000); var value = coordinator.Value(new[] { p }, valueDate); var refValue = BlackEtc.BlackScholes(PutOrCall.Call, strike, (exerciseDate - valueDate) / 365.0, spotPrice[0], vol[0], 0.07, divYield[0]); Assert.AreEqual(refValue, value, refValue * 0.05); }
public void TestManySwaps() { Debug.StartTimer(); var allSwaps = GetListOfSwaps(); Debug.WriteLine("Create swaps took: " + Debug.ElapsedTime()); // Set up the model var valueDate = new Date(2016, 11, 21); Date[] datesLong = { new Date(2016, 11, 21), new Date(2018, 11, 21), new Date(2020, 11, 21), new Date(2022, 11, 21), new Date(2024, 11, 21), new Date(2047, 11, 21) }; double[] ratesLong = { 0.07, 0.071, 0.072, 0.073, 0.074, 0.08 }; IDiscountingSource discountCurve = new DatesAndRates(TestHelpers.ZAR, valueDate, datesLong, ratesLong); IFloatingRateSource forecastCurve = new ForecastCurveFromDiscount(discountCurve, TestHelpers.Jibar3M, new FloatingRateFixingCurve1Rate(valueDate, 0.07, TestHelpers.Jibar3M)); var curveSim = new DeterministicCurves(discountCurve); curveSim.AddRateForecast(forecastCurve); var coordinator = new Coordinator(curveSim, new List <Simulator>(), 1); // Run the valuation Debug.StartTimer(); var value = coordinator.Value(allSwaps, valueDate); Debug.WriteLine("Value took: " + Debug.ElapsedTime()); }
public void TestIndexOnlyProvidedOnce() { var exerciseDate = new Date(2017, 08, 28); var shareCode = "AAA"; var strike = 100.0; Product p = new EuropeanOption(new Share(shareCode, Currency.ZAR), strike, exerciseDate); var shares = new[] { new Share("AAA", Currency.ZAR) }; // One needs to know the index that will be required by the product to simulate it. var valueDate = new Date(2016, 08, 28); var divYield = new[] { 0.02 }; var vol = new[] { 0.22 }; var spotPrice = new[] { 100.0 }; var correlations = new[, ] { { 1.0 } }; IDiscountingSource discountCurve = new DatesAndRates(Currency.ZAR, valueDate, new[] { valueDate, valueDate.AddMonths(120) }, new[] { 0.07, 0.07 }); var rateForecastCurves = new IFloatingRateSource[0]; var sim = new EquitySimulator(shares, spotPrice, vol, divYield, correlations, discountCurve, rateForecastCurves); var coordinator = new Coordinator(sim, new List <Simulator> { sim }, 1000); var value = coordinator.Value(new[] { p }, valueDate); }
public void TestProductWrapperEquityValuation() { Product product1 = new ProductWrapperEquitySample1(); Product product2 = new ProductWrapperEquitySample2(); // The model Date anchorDate = new Date(2016, 09, 30); Share[] shares = new Share[] { new Share("ALSI", Currency.ZAR), new Share("AAA", Currency.ZAR), new Share("BBB", Currency.ZAR) }; double[] prices = { 200, 50, 100 }; double[] vols = { 0.22, 0.52, 0.4 }; double[] divYields = { 0.03, 0.0, 0.0 }; double[,] correlations = { { 1.0, 0.5, 0.5 }, { 0.5, 1.0, 0.5 }, { 0.5, 0.5, 1.0 } }; IDiscountingSource discountCurve = new DatesAndRates(Currency.ZAR, anchorDate, new Date[] { anchorDate, anchorDate.AddMonths(36) }, new double[] { 0.07, 0.07 }); EquitySimulator sim = new EquitySimulator(shares, prices, vols, divYields, correlations, discountCurve, new IFloatingRateSource[0]); Coordinator coordinator = new Coordinator(sim, new List <Simulator> { }, 40000); //Valuation double value1 = coordinator.Value(new Product[] { product1 }, anchorDate); double value2 = coordinator.Value(new Product[] { product2 }, anchorDate); Assert.AreEqual(value1, value2, value1 * 0.05); }
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); }
/// <summary> /// Create a curve that linearly interpolates the provided forward rates. Rates are not used to get discount factors. /// </summary> /// <remarks> /// If you want to obtain discount factors from the provided rates rather use: <see cref="DatesAndRates" /> /// </remarks> /// <param name="anchorDate"></param> /// <param name="index"></param> /// <param name="dates"></param> /// <param name="rates"></param> /// <param name="maximumDate"></param> public ForecastCurve(Date anchorDate, FloatRateIndex index, Date[] dates, double[] rates, Date maximumDate = null) { _index = index; _floatingRateSourceDescription = new FloatingRateSourceDescription(index); _dateAndRates = new DatesAndRates(index.Currency, anchorDate, dates, rates, maximumDate); }
private DatesAndRates InitializeCurve(Date calibrationDate, InitialValueCollector initialValueCollector, ObjectiveFunction objective, DiscountingSourceDescription curveToStrip, IEnumerable <FloatRateIndex> indicesToBaseOffCurve) { if (curveToStrip == null) { return(null); } var curveNames = new List <string> { curveToStrip.Name }; var indices = indicesToBaseOffCurve.ToList(); curveNames.AddRange( indices.Select(ind => new FloatingRateSourceDescription(ind).Name)); var initial = initialValueCollector.GetValues(curveNames); var curve = new DatesAndRates(curveToStrip.Currency, calibrationDate, initial.dates, initial.values); foreach (var index in indices) { var name = new FloatingRateSourceDescription(index).Name; _floatingRateSources[name] = new ForecastCurveFromDiscount(curve, index, null); } objective.AddCurve(curve, initial.values); return(curve); }
public void TestManySwaps() { Debug.StartTimer(); Product[] allSwaps = GetListOfSwaps(); Debug.WriteLine("Create swaps took: " + Debug.ElapsedTime().ToString()); // Set up the model Date valueDate = new Date(2016, 11, 21); Date[] dates = { new Date(2016, 11, 21), new Date(2047, 11, 21) }; Date[] datesLong = { new Date(2016, 11, 21), new Date(2018, 11, 21), new Date(2020, 11, 21), new Date(2022, 11, 21), new Date(2024, 11, 21), new Date(2047, 11, 21) }; double[] rates = { 0.07, 0.07 }; double[] ratesLong = { 0.07, 0.071, 0.072, 0.073, 0.074, 0.08 }; IDiscountingSource discountCurve = new DatesAndRates(Currency.ZAR, valueDate, datesLong, ratesLong); IFloatingRateSource forecastCurve = new ForecastCurveFromDiscount(discountCurve, FloatingIndex.JIBAR3M, new FloatingRateFixingCurve1Rate(0.07, FloatingIndex.JIBAR3M)); DeterminsiticCurves curveSim = new DeterminsiticCurves(discountCurve); curveSim.AddRateForecast(forecastCurve); Coordinator coordinator = new Coordinator(curveSim, new List <Simulator>(), 1); // Run the valuation Debug.StartTimer(); double value = coordinator.Value(allSwaps, valueDate); Debug.WriteLine("Value took: " + Debug.ElapsedTime().ToString()); }
public static double[] SwapZeroRisk(IRSwap swap, Date valueDate, Date[] dates, double[] rates, Currency currency) { // set the base curve for (var i = 1; i < dates.Length; i++) { if (dates[i].value <= dates[i - 1].value) { throw new ArgumentException("Dates must be strictly increasing"); } } var basecurve = new DatesAndRates(currency, dates[0], dates, rates); // Calculate the base value of the swap var basevalue = ValueSwap(swap, valueDate, basecurve); double shift = 0.0001; var temp = new double[dates.Length]; var PV01s = new double[dates.Length]; for (int i = 0; i < dates.Length; i++) { rates.CopyTo(temp, 0); temp[i] += shift; PV01s[i] = ValueSwap(swap, valueDate, new DatesAndRates(currency, dates[0], dates, temp)) - basevalue; } return(PV01s); }
public void TestFixedLegsZARUSD() { Date[] cfDates = { new Date(2016, 12, 23), new Date(2017, 03, 23) }; var legZAR = new FixedLeg(TestHelpers.ZAR, cfDates, new double[] { -16000000, -16000000 }, new[] { 0.07, 0.07 }, new[] { 0.25, 0.25 }); var legUSD = new FixedLeg(TestHelpers.USD, cfDates, new double[] { 1000000, 1000000 }, new[] { 0.01, 0.01 }, new[] { 0.25, 0.25 }); // Set up the model var valueDate = new Date(2016, 9, 23); Date[] dates = { new Date(2016, 9, 23), new Date(2026, 9, 23) }; double[] rates = { 0.0725, 0.0725 }; double[] basisRates = { 0.0735, 0.0735 }; double[] usdRates = { 0.01, 0.012 }; IDiscountingSource discountCurve = new DatesAndRates(TestHelpers.ZAR, valueDate, dates, rates); IDiscountingSource zarBasis = new DatesAndRates(TestHelpers.ZAR, valueDate, dates, basisRates); IDiscountingSource usdCurve = new DatesAndRates(TestHelpers.USD, valueDate, dates, usdRates); IFloatingRateSource forecastCurve = new ForecastCurve(valueDate, TestHelpers.Jibar3M, dates, rates); IFXSource fxSource = new FXForecastCurve(TestHelpers.USDZAR, 13.66, usdCurve, zarBasis); var curveSim = new DeterminsiticCurves(discountCurve); curveSim.AddRateForecast(forecastCurve); curveSim.AddFXForecast(fxSource); var coordinator = new Coordinator(curveSim, new List <Simulator>(), 1); // Run the valuation var value = coordinator.Value(new Product[] { legZAR, legUSD }, valueDate); var refValue = -477027.31; // See GeneralSwapTest.xlsx Assert.AreEqual(refValue, value, 0.01); }
public void TestDynamicCallFromFile() { Stopwatch watch; // Make a product at runtime var runtimeProduct = RuntimeProduct.CreateFromScript(@"ScriptEuropeanOption.txt"); // Setup an appropriate simulation var shares = new[] { new Share("AAA", TestHelpers.ZAR) }; // One needs to know the index that will be required by the product to simulate it. var valueDate = new Date(2016, 08, 28); var divYield = new[] { 0.02 }; var vol = new[] { 0.22 }; var spotPrice = new[] { 100.0 }; var correlations = new[, ] { { 1.0 } }; IDiscountingSource discountCurve = new DatesAndRates(TestHelpers.ZAR, valueDate, new[] { valueDate, valueDate.AddMonths(120) }, new[] { 0.07, 0.07 }); var rateForecastCurves = new IFloatingRateSource[0]; var sim = new EquitySimulator(shares, spotPrice, vol, divYield, correlations, discountCurve, rateForecastCurves); // Value the runtime product Coordinator coordinator; coordinator = new Coordinator(sim, new List <Simulator>(), 100000); watch = Stopwatch.StartNew(); var valueRuntime = coordinator.Value(new[] { runtimeProduct }, valueDate); watch.Stop(); var timeRuntime = watch.ElapsedMilliseconds; // Setup the same product statically var exerciseDate = new Date(2017, 08, 28); var strike = 100.0; Product staticProduct = new EuropeanOption(new Share("AAA", TestHelpers.ZAR), strike, exerciseDate); // Value the static product coordinator = new Coordinator(sim, new List <Simulator>(), 100000); watch = Stopwatch.StartNew(); var valueStatic = coordinator.Value(new[] { staticProduct }, valueDate); watch.Stop(); var timeStatic = watch.ElapsedMilliseconds; var refValue = BlackEtc.BlackScholes(PutOrCall.Call, strike, (exerciseDate - valueDate) / 365, spotPrice[0], vol[0], 0.07, divYield[0]); Assert.AreEqual(refValue, valueRuntime, refValue * 0.03); Assert.AreEqual(refValue, valueStatic, refValue * 0.03); }
/// <summary> /// Produce a vector of curves where the element at index i is a realization of a simulation at /// simulationDates i. If you require the rates directly use <see cref="GetSimulatedRates(Date[],Tenor[])"/> /// </summary> /// <param name="simulationDates">Dates on which the simulation is run. Must all be greater than the /// anchor date.</param> /// <returns></returns> public ICurve[] GetSimulatedCurves(Date[] simulationDates) { var results = new ICurve[simulationDates.Length]; var dist = new Normal(); var previousDate = AnchorDate; var previousRates = _initialRates.Clone() as double[]; var currentRates = new double[_initialRates.Length]; // Iterate through the simulation dates for (var simCounter = 0; simCounter < simulationDates.Length; simCounter++) { var currentDate = simulationDates[simCounter]; var dt = (currentDate - previousDate) / 365.0; var sdt = Math.Sqrt(dt); var curveDates = new Date[_initialRates.Length]; // Random realizations to be used in simulation. var eps1 = dist.Sample(); var eps2 = dist.Sample(); var eps3 = dist.Sample(); // Iterate through the dates on the curve for (var i = 0; i < _initialRates.Length; i++) { curveDates[i] = simulationDates[simCounter].AddTenor(_tenors[i]); if (_useRelative) { //TODO: add mean correction. var exponent = _components[0, i] * _vols[0] * sdt * eps1 + _components[1, i] * _vols[1] * sdt * eps2 + _components[2, i] * _vols[2] * sdt * eps3; currentRates[i] = previousRates[i] * Math.Exp(exponent); } else { var change = _components[0, i] * _vols[0] * sdt * eps1 + _components[1, i] * _vols[1] * sdt * eps2 + _components[2, i] * _vols[2] * sdt * eps3; currentRates[i] = previousRates[i] + change; if (_floorAtZero) { currentRates[i] = Math.Max(0.0, currentRates[i]); } } } currentRates = currentRates.Multiply(_multiplier); results[simCounter] = new DatesAndRates(new Currency("IGNORE"), simulationDates[simCounter], curveDates, currentRates, simulationDates[simCounter].AddMonths(360)); previousRates = currentRates.Clone() as double[]; previousDate = new Date(currentDate); } return(results); }
public void TestDynamicCallFromString() { var source = @"Date exerciseDate = new Date(2017, 08, 28); Share share = new Share(""AAA"", new Currency(""ZAR"")); double strike = 100.0; public override List<Cashflow> GetCFs() { double amount = Math.Max(0, Get(share, exerciseDate) - strike); return new List<Cashflow> { new Cashflow(exerciseDate, amount, share.Currency) }; }"; // Make a product at runtime var runtimeProduct = RuntimeProduct.CreateFromString("MyEuropeanOption", source); // Setup an approriate simulation var shares = new[] { new Share("AAA", TestHelpers.ZAR) }; // One needs to know the index that will be required by the product to simulate it. var valueDate = new Date(2016, 08, 28); var divYield = new[] { 0.02 }; var vol = new[] { 0.22 }; var spotPrice = new[] { 100.0 }; var correlations = new[, ] { { 1.0 } }; IDiscountingSource discountCurve = new DatesAndRates(TestHelpers.ZAR, valueDate, new[] { valueDate, valueDate.AddMonths(120) }, new[] { 0.07, 0.07 }); var rateForecastCurves = new IFloatingRateSource[0]; var sim = new EquitySimulator(shares, spotPrice, vol, divYield, correlations, discountCurve, rateForecastCurves); // Value the runtime product Coordinator coordinator; coordinator = new Coordinator(sim, new List <Simulator>(), 100000); var valueRuntime = coordinator.Value(new[] { runtimeProduct }, valueDate); var exerciseDate = new Date(2017, 08, 28); var strike = 100.0; var refValue = BlackEtc.BlackScholes(PutOrCall.Call, strike, (exerciseDate - valueDate) / 365, spotPrice[0], vol[0], 0.07, divYield[0]); Assert.AreEqual(refValue, valueRuntime, refValue * 0.03); }
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 bool TryCalibrate(Date calibrationDate, IMarketDataContainer marketDataContainer) { _calibrationDate = calibrationDate; var initialValues = new InitialValueCollector(_calibrationDate, _instruments); var objective = new ObjectiveFunction(); _curve = InitializeCurve(calibrationDate, initialValues, objective, _curveToStrip, _indicesToBaseOffDiscountCurve); _secondCurve = InitializeCurve(calibrationDate, initialValues, objective, _secondCurveToStrip, _indicesToBaseOffSecondCurve); objective.SetBenchmarkObjectives(_instruments, marketDataContainer); var result = _rootFinder.FindRoot(objective, objective.InitialValues); return(true); }
public void AddCurve(DatesAndRates curve, double[] initialGuess) { if (_curve1 == null) { _curve1 = curve; _curve1Values = (double[])initialGuess.Clone(); } else if (_curve2 == null) { _curve2 = curve; _curve2Values = (double[])initialGuess.Clone(); } else { throw new ArgumentException("Only one or two curves can be added."); } }
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 TestDynamicCallFromStringFRA() { string source = @"Date date = new Date(2017, 08, 28); FloatingIndex jibar = FloatingIndex.JIBAR3M; double dt = 91.0/365.0; double fixedRate = 0.071; double notional = 1000000.0; Currency currency = Currency.ZAR; public override List<Cashflow> GetCFs() { double reset = Get(jibar, date); double cfAmount = notional * (reset - fixedRate)*dt/(1+dt*reset); return new List<Cashflow>() { new Cashflow(date, cfAmount, currency) }; }"; // Make a product at runtime Product runtimeProduct = RuntimeProduct.CreateFromString("MyEuropeanOption", source); // Set up the model Date 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); DeterminsiticCurves curveSim = new DeterminsiticCurves(discountCurve); curveSim.AddRateForecast(forecastCurve); // Run the valuation Coordinator coordinator = new Coordinator(curveSim, new List <Simulator>(), 1); double fraValue = coordinator.Value(new Product[] { runtimeProduct }, valueDate); Date date = new Date(2017, 08, 28); double t = (date - valueDate) / 365.0; double dt = 91.0 / 365.0; double fixedRate = 0.071; double notional = 1000000.0; double fwdRate = 0.07; double refValue = notional * (fwdRate - fixedRate) * dt / (1 + fwdRate * dt) * Math.Exp(-t * 0.07); Assert.AreEqual(refValue, fraValue, 0.01); }
public void TestDynamicCallFromStringFRA() { var source = @"Date date = new Date(2017, 08, 28); FloatRateIndex jibar = new FloatRateIndex(""ZAR.JIBAR.3M"", new Currency(""ZAR""), ""JIBAR"", Tenor.FromMonths(3)); double dt = 91.0/365.0; double fixedRate = 0.071; double notional = 1000000.0; Currency currency = new Currency(""ZAR""); public override List<Cashflow> GetCFs() { double reset = Get(jibar, date); double cfAmount = notional * (reset - fixedRate)*dt/(1+dt*reset); return new List<Cashflow>() { new Cashflow(date, cfAmount, currency) }; }"; // Make a product at runtime var runtimeProduct = RuntimeProduct.CreateFromString("MyEuropeanOption", source); // 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 fraValue = coordinator.Value(new[] { runtimeProduct }, valueDate); var date = new Date(2017, 08, 28); var t = (date - valueDate) / 365.0; var dt = 91.0 / 365.0; var fixedRate = 0.071; var notional = 1000000.0; var fwdRate = 0.07; var refValue = notional * (fwdRate - fixedRate) * dt / (1 + fwdRate * dt) * Math.Exp(-t * 0.07); Assert.AreEqual(refValue, fraValue, 0.01); }
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); }
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); }