//------------------------------------------------------------------------- public virtual void test_currencyExposure() { double eps = 1.0e-14; ImmutableRatesProvider prov = ImmutableRatesProvider.builder(VAL_DATE).fxRateProvider(FX_MATRIX).discountCurve(GBP, DISCOUNT_CURVE_GBP).discountCurve(USD, DISCOUNT_CURVE_USD).build(); DiscountingFxResetNotionalExchangePricer test = new DiscountingFxResetNotionalExchangePricer(); // USD MultiCurrencyAmount computedUSD = test.currencyExposure(FX_RESET_NOTIONAL_EXCHANGE_REC_USD, prov); PointSensitivities pointUSD = test.presentValueSensitivity(FX_RESET_NOTIONAL_EXCHANGE_REC_USD, prov).build(); MultiCurrencyAmount expectedUSD = prov.currencyExposure(pointUSD.convertedTo(USD, prov)).plus(CurrencyAmount.of(FX_RESET_NOTIONAL_EXCHANGE_REC_USD.Currency, test.presentValue(FX_RESET_NOTIONAL_EXCHANGE_REC_USD, prov))); assertFalse(computedUSD.contains(GBP)); // 0 GBP assertEquals(computedUSD.getAmount(USD).Amount, expectedUSD.getAmount(USD).Amount, eps * NOTIONAL); // GBP MultiCurrencyAmount computedGBP = test.currencyExposure(FX_RESET_NOTIONAL_EXCHANGE_PAY_GBP, prov); PointSensitivities pointGBP = test.presentValueSensitivity(FX_RESET_NOTIONAL_EXCHANGE_PAY_GBP, prov).build(); MultiCurrencyAmount expectedGBP = prov.currencyExposure(pointGBP.convertedTo(GBP, prov)).plus(CurrencyAmount.of(FX_RESET_NOTIONAL_EXCHANGE_PAY_GBP.Currency, test.presentValue(FX_RESET_NOTIONAL_EXCHANGE_PAY_GBP, prov))); assertFalse(computedGBP.contains(USD)); // 0 USD assertEquals(computedGBP.getAmount(GBP).Amount, expectedGBP.getAmount(GBP).Amount, eps * NOTIONAL); // FD approximation FxMatrix fxMatrixUp = FxMatrix.of(GBP, USD, FX_RATE + EPS_FD); ImmutableRatesProvider provUp = ImmutableRatesProvider.builder(VAL_DATE).fxRateProvider(fxMatrixUp).discountCurve(GBP, DISCOUNT_CURVE_GBP).discountCurve(USD, DISCOUNT_CURVE_USD).build(); double expectedFdUSD = -(test.presentValue(FX_RESET_NOTIONAL_EXCHANGE_REC_USD, provUp) - test.presentValue(FX_RESET_NOTIONAL_EXCHANGE_REC_USD, prov)) * FX_RATE * FX_RATE / EPS_FD; assertEquals(computedUSD.getAmount(USD).Amount, expectedFdUSD, EPS_FD * NOTIONAL); double expectedFdGBP = (test.presentValue(FX_RESET_NOTIONAL_EXCHANGE_PAY_GBP, provUp) - test.presentValue(FX_RESET_NOTIONAL_EXCHANGE_PAY_GBP, prov)) / EPS_FD; assertEquals(computedGBP.getAmount(GBP).Amount, expectedFdGBP, EPS_FD * NOTIONAL); }
public double GetFxRate(DateTime settlementDate, Currency domesticCcy, Currency foreignCcy) { //domestic-per-foreign if (foreignCcy == domesticCcy) { return(1.0); } double spot; if (domesticCcy == FxMatrix.BaseCurrency) { spot = FxMatrix.GetSpotRate(foreignCcy); } else if (foreignCcy == FxMatrix.BaseCurrency) { spot = 1.0 / FxMatrix.GetSpotRate(domesticCcy); } else { var forToBase = GetFxRate(settlementDate, FxMatrix.BaseCurrency, foreignCcy); var domToBase = GetFxRate(settlementDate, FxMatrix.BaseCurrency, domesticCcy); return(forToBase / domToBase); } var fxPair = FxMatrix.GetFxPair(domesticCcy, foreignCcy); var spotDate = BuildDate.AddPeriod(RollType.F, fxPair.PrimaryCalendar, fxPair.SpotLag); var dfDom = GetDf(domesticCcy, spotDate, settlementDate); var dfFor = GetDf(foreignCcy, spotDate, settlementDate); return(spot * dfDom / dfFor); }
public virtual void test_currencyExposureOnFixing_noTimeSeries() { double eps = 1.0e-14; LocalDate valuationDate = date(2014, 6, 27); LocalDate paymentDate = date(2014, 7, 1); LocalDate fixingDate = date(2014, 6, 27); FxResetNotionalExchange resetNotionalUSD = FxResetNotionalExchange.of(CurrencyAmount.of(USD, NOTIONAL), paymentDate, FxIndexObservation.of(GBP_USD_WM, fixingDate, REF_DATA)); FxResetNotionalExchange resetNotionalGBP = FxResetNotionalExchange.of(CurrencyAmount.of(GBP, -NOTIONAL), paymentDate, FxIndexObservation.of(GBP_USD_WM, fixingDate, REF_DATA)); ImmutableRatesProvider prov = ImmutableRatesProvider.builder(valuationDate).fxRateProvider(FX_MATRIX).discountCurve(GBP, DISCOUNT_CURVE_GBP).discountCurve(USD, DISCOUNT_CURVE_USD).build(); DiscountingFxResetNotionalExchangePricer test = new DiscountingFxResetNotionalExchangePricer(); // USD MultiCurrencyAmount computedUSD = test.currencyExposure(resetNotionalUSD, prov); PointSensitivities pointUSD = test.presentValueSensitivity(resetNotionalUSD, prov).build(); MultiCurrencyAmount expectedUSD = prov.currencyExposure(pointUSD.convertedTo(USD, prov)).plus(CurrencyAmount.of(resetNotionalUSD.Currency, test.presentValue(resetNotionalUSD, prov))); assertFalse(computedUSD.contains(GBP)); // 0 GBP assertEquals(computedUSD.getAmount(USD).Amount, expectedUSD.getAmount(USD).Amount, eps * NOTIONAL); // GBP MultiCurrencyAmount computedGBP = test.currencyExposure(resetNotionalGBP, prov); PointSensitivities pointGBP = test.presentValueSensitivity(resetNotionalGBP, prov).build(); MultiCurrencyAmount expectedGBP = prov.currencyExposure(pointGBP.convertedTo(GBP, prov)).plus(CurrencyAmount.of(resetNotionalGBP.Currency, test.presentValue(resetNotionalGBP, prov))); assertFalse(computedGBP.contains(USD)); // 0 USD assertEquals(computedGBP.getAmount(GBP).Amount, expectedGBP.getAmount(GBP).Amount, eps * NOTIONAL); // FD approximation FxMatrix fxMatrixUp = FxMatrix.of(GBP, USD, FX_RATE + EPS_FD); ImmutableRatesProvider provUp = ImmutableRatesProvider.builder(valuationDate).fxRateProvider(fxMatrixUp).discountCurve(GBP, DISCOUNT_CURVE_GBP).discountCurve(USD, DISCOUNT_CURVE_USD).build(); double expectedFdUSD = -(test.presentValue(resetNotionalUSD, provUp) - test.presentValue(resetNotionalUSD, prov)) * FX_RATE * FX_RATE / EPS_FD; assertEquals(computedUSD.getAmount(USD).Amount, expectedFdUSD, EPS_FD * NOTIONAL); double expectedFdGBP = (test.presentValue(resetNotionalGBP, provUp) - test.presentValue(resetNotionalGBP, prov)) / EPS_FD; assertEquals(computedGBP.getAmount(GBP).Amount, expectedFdGBP, EPS_FD * NOTIONAL); }
//------------------------------------------------------------------------- public virtual void test_convertedTo_singleCurrency() { CurveSensitivities @base = sut(); CurveSensitivities test = @base.convertedTo(USD, FxMatrix.empty()); assertEquals(test.TypedSensitivities.get(ZERO_RATE_DELTA).Sensitivities, ImmutableList.of(ENTRY_USD)); }
public static IFundingModel RemapBaseCurrency(IFundingModel input, Currency newBaseCurrency, ICurrencyProvider currencyProvider) { if (newBaseCurrency == input.FxMatrix.BaseCurrency) { return(input.Clone()); } var mf = input.DeepClone(null); var homeToBase = mf.FxMatrix.SpotRates[newBaseCurrency]; var ccys = mf.FxMatrix.SpotRates.Keys.ToList() .Concat(new[] { mf.FxMatrix.BaseCurrency }) .Where(x => x != newBaseCurrency); var newRateDict = new Dictionary <Currency, double>(); foreach (var ccy in ccys) { var spotDate = mf.FxMatrix.GetFxPair(newBaseCurrency, ccy).SpotDate(mf.BuildDate); var newRate = mf.GetFxRate(spotDate, newBaseCurrency, ccy); newRateDict.Add(ccy, newRate); } var newFx = new FxMatrix(currencyProvider); newFx.Init(newBaseCurrency, mf.FxMatrix.BuildDate, newRateDict, mf.FxMatrix.FxPairDefinitions, mf.FxMatrix.DiscountCurveMap); mf.SetupFx(newFx); return(mf); }
public static object CreateFxMatrix( [ExcelArgument(Description = "Fx matrix name")] string ObjectName, [ExcelArgument(Description = "Base currency")] string BaseCurrency, [ExcelArgument(Description = "Build date")] DateTime BuildDate, [ExcelArgument(Description = "Spot rates")] object[,] SpotRateMap, [ExcelArgument(Description = "Fx pair definitions")] object[] FxPairDefinitions, [ExcelArgument(Description = "DiscountCurves")] object[,] DiscountCurves) { return(ExcelHelper.Execute(_logger, () => { var fxPairsCache = ContainerStores.GetObjectCache <FxPair>(); var fxPairs = FxPairDefinitions .Where(s => fxPairsCache.Exists(s as string)) .Select(s => fxPairsCache.GetObject(s as string).Value) .ToList(); var currencies = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>(); var spotRatesRaw = SpotRateMap.RangeToDictionary <string, double>(); var spotRates = spotRatesRaw.ToDictionary(y => currencies[y.Key], y => y.Value); var discountCurvesRaw = DiscountCurves.RangeToDictionary <string, string>(); var discountCurves = discountCurvesRaw.ToDictionary(y => currencies[y.Key], y => y.Value); var matrix = new FxMatrix(currencies); matrix.Init(currencies[BaseCurrency], BuildDate, spotRates, fxPairs, discountCurves); return ExcelHelper.PushToCache(matrix, ObjectName); })); }
private AssetFxMCModel GetSut() { var buildDate = DateTime.Parse("2018-10-04"); var usd = TestProviderHelper.CurrencyProvider["USD"]; TestProviderHelper.CalendarProvider.Collection.TryGetCalendar("NYC", out var usdCal); var dfCurve = new IrCurve(new[] { buildDate, buildDate.AddDays(1000) }, new[] { 0.0, 0.0 }, buildDate, "disco", Interpolator1DType.Linear, usd, "DISCO"); var comCurve = new BasicPriceCurve(buildDate, new[] { buildDate, buildDate.AddDays(15), buildDate.AddDays(100) }, new[] { 100.0, 100.0, 100.0 }, PriceCurveType.NYMEX, TestProviderHelper.CurrencyProvider) { Name = "CL", AssetId = "CL" }; var comSurface = new ConstantVolSurface(buildDate, 0.32) { AssetId = "CL" }; var fModel = new FundingModel(buildDate, new Dictionary <string, IrCurve> { { "DISCO", dfCurve } }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); var fxM = new FxMatrix(TestProviderHelper.CurrencyProvider); fxM.Init(usd, buildDate, new Dictionary <Currency, double>(), new List <FxPair>(), new Dictionary <Currency, string> { { usd, "DISCO" } }); fModel.SetupFx(fxM); var aModel = new AssetFxModel(buildDate, fModel); aModel.AddVolSurface("CL", comSurface); aModel.AddPriceCurve("CL", comCurve); var product = AssetProductFactory.CreateAsianOption(buildDate.AddDays(10), buildDate.AddDays(20), 101, "CL", OptionType.Call, usdCal, buildDate.AddDays(21), usd); product.TradeId = "waaah"; product.DiscountCurve = "DISCO"; var pfolio = new Portfolio { Instruments = new List <IInstrument> { product } }; var settings = new McSettings { Generator = RandomGeneratorType.MersenneTwister, NumberOfPaths = (int)System.Math.Pow(2, 13), NumberOfTimesteps = 1, ReportingCurrency = usd, Parallelize = false, CreditSettings = new CreditSettings { ExposureDates = new DateTime[] { buildDate.AddDays(5), buildDate.AddDays(20), buildDate.AddDays(22) } }, }; var sut = new AssetFxMCModel(buildDate, pfolio, aModel, settings, TestProviderHelper.CurrencyProvider, TestProviderHelper.FutureSettingsProvider, TestProviderHelper.CalendarProvider); return(sut); }
private IPvModel GenerateTestData() { Utils.Parallel.ParallelUtils.Instance.MultiThreaded = false; var usd = TestProviderHelper.CurrencyProvider.GetCurrency("USD"); var zar = TestProviderHelper.CurrencyProvider.GetCurrency("ZAR"); var nyc = TestProviderHelper.CalendarProvider.Collection["NYC"]; var ins = new Forward { TradeId = "TestA", AssetId = "FakeAsset", ExpiryDate = _originDate.AddDays(180), PaymentCurrency = zar, Notional = 1e6, Strike = 1400, DiscountCurve = "DISCO-ZAR" }; var pf = new Portfolio { Instruments = new List <IInstrument> { ins } }; var pillars = new[] { _originDate.AddDays(90), _originDate.AddDays(180) }; var discoUsd = new IrCurve(pillars, pillars.Select(p => 0.02).ToArray(), _originDate, "DISCO-USD", Interpolator1DType.Linear, usd); var discoZar = new IrCurve(pillars, pillars.Select(p => 0.02).ToArray(), _originDate, "DISCO-ZAR", Interpolator1DType.Linear, zar); var fxpairs = new List <FxPair> { new FxPair { Domestic = usd, Foreign = zar, PrimaryCalendar = nyc, SpotLag = 2.Bd() }, new FxPair { Domestic = zar, Foreign = usd, PrimaryCalendar = nyc, SpotLag = 2.Bd() }, }; var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); fxMatrix.Init(usd, _originDate, new Dictionary <Currency, double> { { zar, 14.0 } }, fxpairs, new Dictionary <Currency, string> { { usd, "DISCO-USD" }, { zar, "DISCO-ZAR" } }); var fModel = new FundingModel(_originDate, new[] { discoUsd, discoZar }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); fModel.SetupFx(fxMatrix); var model = new AssetFxModel(_originDate, fModel); var curve = new ConstantPriceCurve(100, _originDate, TestProviderHelper.CurrencyProvider); model.AddPriceCurve("FakeAsset", curve); model.AddFixingDictionary("FakeAsset", new FixingDictionary()); model.AttachPortfolio(pf); return(model); }
public void CompositePriceCurveFact() { var originDate = new DateTime(2019, 05, 28); var zar = TestProviderHelper.CurrencyProvider.GetCurrency("ZAR"); var usd = TestProviderHelper.CurrencyProvider.GetCurrency("USD"); var zarCurve = new ConstantRateIrCurve(0.07, originDate, "ZARCurve", zar); var usdCurve = new ConstantRateIrCurve(0.02, originDate, "USDCurve", usd); var fModel = new FundingModel(originDate, new[] { zarCurve, usdCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); var fxPair = new FxPair { Domestic = zar, Foreign = usd, SpotLag = new Dates.Frequency("0d") }; fxMatrix.Init(zar, originDate, new Dictionary <Currency, double> { { usd, 10.0 } }, new List <FxPair>() { fxPair }, new Dictionary <Currency, string> { { usd, "USDCurve" }, { zar, "ZARCurve" } }); fModel.SetupFx(fxMatrix); var baseCurve = new ConstantPriceCurve(100.0, originDate, TestProviderHelper.CurrencyProvider) { Currency = usd, Name = "gooo", AssetId = "rooo" }; var sut = new CompositePriceCurve(originDate, baseCurve, fModel, zar); var sut2 = new CompositePriceCurve(originDate, () => baseCurve, () => fModel, zar); var fxOrigin = fModel.GetFxRate(originDate, usd, zar); Assert.Equal(baseCurve.GetPriceForDate(originDate) * fxOrigin, sut.GetPriceForDate(originDate)); Assert.Equal(baseCurve.GetPriceForDate(originDate) * fxOrigin, sut2.GetPriceForDate(originDate)); Assert.Equal(baseCurve.GetPriceForDate(originDate) * fxOrigin, sut.GetPriceForFixingDate(originDate)); Assert.Equal(baseCurve.GetPriceForDate(originDate) * fxOrigin, sut.GetAveragePriceForDates(new[] { originDate })); Assert.Equal("gooo", sut.Name); Assert.Throws <Exception>(() => sut.Name = null); Assert.Single(sut.GetDeltaScenarios(0.0, null)); Assert.Equal(PriceCurveType.Linear, sut.CurveType); Assert.False(sut.UnderlyingsAreForwards); Assert.Equal(1, sut.NumberOfPillars); Assert.Equal("rooo", sut.AssetId); Assert.Equal(zar, sut.CompoCurrency); Assert.Equal(zar, sut.Currency); Assert.Throws <Exception>(() => sut.Currency = null); Assert.Equal(usd, sut.CurveCurrency); Assert.Single(sut.PillarDates); Assert.Equal(DateTime.Today.AddDays(1), sut.RebaseDate(DateTime.Today.AddDays(1)).BuildDate); Assert.Equal(originDate, sut.PillarDatesForLabel(originDate.ToString("yyyy-MM-dd"))); Assert.Throws <Exception>(() => sut.PillarDatesForLabel("")); }
public FundingModel(DateTime buildDate, Dictionary <string, IrCurve> curves, ICurrencyProvider currencyProvider, ICalendarProvider calendarProvider) { _currencyProvider = currencyProvider; _calendarProvider = calendarProvider; BuildDate = buildDate; Curves = new Dictionary <string, IrCurve>(curves); FxMatrix = new FxMatrix(_currencyProvider); VolSurfaces = new Dictionary <string, IVolSurface>(); SetupMappings(); }
public static (IrCurve curve, double spotPrice) GetMetalCurveForCode(string cmxSettleFwdFilename, string cmxSymbol, FxPair metalPair, string curveName, DateTime valDate, IrCurve baseCurve, ICurrencyProvider currencyProvider, ICalendarProvider calendarProvider) { var blob = CMEFileParser.Instance.GetBlob(cmxSettleFwdFilename); var fwds = blob.Batch.Where(b => b.Instrmt.Sym == cmxSymbol).ToDictionary(x => x.Instrmt.MatDt, x => Convert.ToDouble(x.Full.Where(x => x.Typ == "6").First().Px)); var curveCcy = metalPair.Domestic; var bc = baseCurve.Clone(); bc.SolveStage = -1; var spotDate = metalPair.SpotDate(valDate); var spotRate = Convert.ToDouble(fwds[spotDate]); fwds = Downsample(fwds, spotDate, metalPair.PrimaryCalendar); var fwdObjects = fwds.Select(x => new FxForward { DomesticCCY = metalPair.Foreign, DeliveryDate = x.Key, DomesticQuantity = 1e6, ForeignCCY = metalPair.Domestic, PillarDate = x.Key, SolveCurve = curveName, Strike = Convert.ToDouble(x.Value), ForeignDiscountCurve = baseCurve.Name, }); var fic = new FundingInstrumentCollection(currencyProvider); fic.AddRange(fwdObjects); var pillars = fwds.Keys.OrderBy(x => x).ToArray(); var curve = new IrCurve(pillars, pillars.Select(p => 0.01).ToArray(), valDate, curveName, Interpolator1DType.Linear, curveCcy); var fm = new FundingModel(valDate, new[] { curve, bc }, currencyProvider, calendarProvider); var matrix = new FxMatrix(currencyProvider); var discoMap = new Dictionary <Currency, string> { { curveCcy, curveName }, { baseCurve.Currency, baseCurve.Name } }; matrix.Init(metalPair.Foreign, valDate, new Dictionary <Currency, double> { { metalPair.Domestic, spotRate } }, new List <FxPair> { metalPair }, discoMap); fm.SetupFx(matrix); var solver = new NewtonRaphsonMultiCurveSolverStaged() { InLineCurveGuessing = true }; solver.Solve(fm, fic); return(curve, spotRate); }
public static IrCurve StripFxBasisCurve(string cmeFwdFileName, FxPair ccyPair, string cmePair, Currency curveCcy, string curveName, DateTime valDate, IrCurve baseCurve, ICurrencyProvider currencyProvider, ICalendarProvider calendarProvider) { var fwdsDict = GetFwdFxRatesFromFwdFile(cmeFwdFileName, new Dictionary <string, string> { { ccyPair.ToString(), cmePair } }); var bc = baseCurve.Clone(); bc.SolveStage = -1; var fwds = fwdsDict[ccyPair.ToString()]; var spotDate = ccyPair.SpotDate(valDate); var spotRate = fwds[spotDate]; fwds = Downsample(fwds, spotDate, ccyPair.PrimaryCalendar); var fwdObjects = fwds.Select(x => new FxForward { DomesticCCY = ccyPair.Domestic, DeliveryDate = x.Key, DomesticQuantity = 1e6, ForeignCCY = ccyPair.Foreign, PillarDate = x.Key, SolveCurve = curveName, Strike = x.Value, ForeignDiscountCurve = ccyPair.Foreign == curveCcy ? curveName : baseCurve.Name, }); var fic = new FundingInstrumentCollection(currencyProvider); fic.AddRange(fwdObjects); var pillars = fwds.Keys.OrderBy(x => x).ToArray(); var curve = new IrCurve(pillars, pillars.Select(p => 0.01).ToArray(), valDate, curveName, Interpolator1DType.Linear, curveCcy); var fm = new FundingModel(valDate, new[] { curve, bc }, currencyProvider, calendarProvider); var matrix = new FxMatrix(currencyProvider); var discoMap = new Dictionary <Currency, string> { { curveCcy, curveName }, { baseCurve.Currency, baseCurve.Name } }; matrix.Init(ccyPair.Domestic, valDate, new Dictionary <Currency, double> { { ccyPair.Foreign, spotRate } }, new List <FxPair> { ccyPair }, discoMap); fm.SetupFx(matrix); var solver = new NewtonRaphsonMultiCurveSolverStaged() { InLineCurveGuessing = true }; solver.Solve(fm, fic); return(curve); }
public IFundingModel DeepClone(DateTime?newBuildDate = null) { var returnValue = new FundingModel(newBuildDate ?? BuildDate, Curves.Values.Select(c => c.Clone()).ToArray(), _currencyProvider, _calendarProvider) { VolSurfaces = VolSurfaces == null ? new Dictionary <string, IVolSurface>() : new Dictionary <string, IVolSurface>(VolSurfaces) }; if (FxMatrix != null) { returnValue.SetupFx(FxMatrix.Clone()); } return(returnValue); }
public void CashBalanceFact() { var bd = new DateTime(2019, 06, 14); var pillars = new[] { bd, bd.AddDays(1000) }; var flatRate = 0.05; var rates = pillars.Select(p => flatRate).ToArray(); var usd = TestProviderHelper.CurrencyProvider["USD"]; var zar = TestProviderHelper.CurrencyProvider["ZAR"]; var discoCurve = new IrCurve(pillars, rates, bd, "USD.BLAH", Interpolator1DType.Linear, usd); var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); fxMatrix.Init(usd, bd, new Dictionary <Currency, double>(), new List <FxPair>(), new Dictionary <Currency, string> { { usd, "X" }, { zar, "Y" } }); var fModel = new FundingModel(bd, new[] { discoCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); fModel.SetupFx(fxMatrix); var aModel = new AssetFxModel(bd, fModel); var notional = 100e6; var maturity = bd.AddDays(365); var b = new CashBalance(usd, notional, null); var t = bd.CalculateYearFraction(maturity, DayCountBasis.Act365F); var pv = b.Pv(fModel, false); Assert.Equal(notional, pv); Assert.Empty(b.Dependencies(null)); Assert.Empty(b.AssetIds); Assert.Empty(b.PastFixingDates(bd)); Assert.Equal(0.0, b.CalculateParRate(null)); Assert.Equal(0.0, b.FlowsT0(null)); Assert.Equal(string.Empty, b.FxPair(null)); Assert.Equal(FxConversionType.None, b.FxType(null)); Assert.Equal(usd, b.Currency); Assert.Equal(DateTime.MinValue, b.LastSensitivityDate); var y = (CashBalance)b.Clone(); Assert.True(b.Equals(y)); y.TradeId = "xxx"; Assert.False(b.Equals(y)); Assert.Throws <NotImplementedException>(() => b.Sensitivities(fModel)); Assert.Throws <NotImplementedException>(() => b.SetStrike(0.0)); Assert.Equal(b, b.SetParRate(0.0)); Assert.Single(b.IrCurves(aModel)); }
public double[] GetFxRates(DateTime[] fixingDates, Currency domesticCcy, Currency foreignCcy) { if (foreignCcy == domesticCcy) { return(Enumerable.Repeat(1.0, fixingDates.Length).ToArray()); } else { var pair = FxMatrix.GetFxPair(domesticCcy, foreignCcy); var settleDates = fixingDates.Select(x => x.AddPeriod(RollType.F, pair.PrimaryCalendar, pair.SpotLag)); var rates = settleDates.Select(d => GetFxRate(d, domesticCcy, foreignCcy)).ToArray(); return(rates); } }
private AssetFxModel GetModel() { var irCurveZar = new ConstantRateIrCurve(0.07, ValDate, "ZAR-IR", zar); var irCurveUsd = new ConstantRateIrCurve(0.02, ValDate, "USD-IR", zar); var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); var fxPair = new FxPair() { Domestic = usd, Foreign = zar, PrimaryCalendar = TestProviderHelper.CalendarProvider.GetCalendar("ZAR"), SecondaryCalendar = TestProviderHelper.CalendarProvider.GetCalendar("USD"), SpotLag = new Frequency("2b") }; fxMatrix.Init(usd, ValDate, new Dictionary <Currency, double> { { zar, 20.0 } }, new List <FxPair> { fxPair }, new Dictionary <Currency, string> { { zar, "ZAR-IR" }, { usd, "USD-IR" } }); var fModel = new FundingModel(ValDate, new[] { irCurveUsd, irCurveZar }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); fModel.SetupFx(fxMatrix); var fxSurface = new ConstantVolSurface(ValDate, 0.16); fModel.VolSurfaces.Add("USD/ZAR", fxSurface); var crudeCurve = new ConstantPriceCurve(100, ValDate, TestProviderHelper.CurrencyProvider) { Name = "OIL", AssetId = "OIL", Currency = usd }; var crudeSurface = new ConstantVolSurface(ValDate, 0.32) { Name = "OIL", AssetId = "OIL", Currency = usd }; var aModel = new AssetFxModel(ValDate, fModel); aModel.AddPriceCurve("OIL", crudeCurve); aModel.AddVolSurface("OIL", crudeSurface); aModel.CorrelationMatrix = new CorrelationMatrix(new[] { "OIL" }, new[] { "USD/ZAR" }, new double[][] { new [] { 0.5 } }); return(aModel); }
public void FxForwardCurveFact() { var originDate = new DateTime(2019, 05, 28); var zar = TestProviderHelper.CurrencyProvider.GetCurrency("ZAR"); var usd = TestProviderHelper.CurrencyProvider.GetCurrency("USD"); var zarCurve = new ConstantRateIrCurve(0.07, originDate, "ZARCurve", zar); var usdCurve = new ConstantRateIrCurve(0.02, originDate, "USDCurve", usd); var fModel = new FundingModel(originDate, new[] { zarCurve, usdCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); var fxPair = new FxPair { Domestic = zar, Foreign = usd, SpotLag = new Dates.Frequency("0d") }; fxMatrix.Init(zar, originDate, new Dictionary <Currency, double> { { usd, 10.0 } }, new List <FxPair>() { fxPair }, new Dictionary <Currency, string> { { usd, "USDCurve" }, { zar, "ZARCurve" } }); fModel.SetupFx(fxMatrix); var sut = new FxForwardCurve(originDate, fModel, zar, usd) { Name = "gooo", }; var sut2 = new FxForwardCurve(originDate, new Func <Models.IFundingModel>(() => fModel), zar, usd); Assert.Equal(10, sut.GetPriceForDate(originDate)); Assert.Equal(10, sut2.GetPriceForDate(originDate)); Assert.Equal(10, sut.GetPriceForFixingDate(originDate)); Assert.Equal(10, sut.GetAveragePriceForDates(new[] { originDate })); Assert.Equal("gooo", sut.Name); Assert.Equal(new Dictionary <string, IPriceCurve>(), sut.GetDeltaScenarios(0.0, null)); Assert.Equal(PriceCurveType.Linear, sut.CurveType); Assert.True(sut.UnderlyingsAreForwards); Assert.Equal(0, sut.NumberOfPillars); Assert.Equal(usd.Ccy, sut.AssetId); Assert.Null(sut.PillarDates); Assert.Throws <NotImplementedException>(() => sut.RebaseDate(DateTime.Today)); Assert.Throws <NotImplementedException>(() => sut.PillarDatesForLabel("")); Assert.Throws <Exception>(() => sut.Currency = null); }
public void AsianCompoSwap() { ParallelUtils.Instance.MultiThreaded = false; var startDate = new DateTime(2018, 07, 28); var cal = TestProviderHelper.CalendarProvider.Collection["LON"]; var xaf = TestProviderHelper.CurrencyProvider["XAF"]; var usd = TestProviderHelper.CurrencyProvider["USD"]; var curvePillars = new[] { "1W", "1M", "3M", "6M", "1Y" }; var curvePillarDates = curvePillars.Select(l => startDate.AddPeriod(RollType.F, cal, new Frequency(l))).ToArray(); var curvePoints = new[] { 100.0, 100, 100, 100, 100 }; var curve = new BasicPriceCurve(startDate, curvePillarDates, curvePoints, PriceCurveType.LME, TestProviderHelper.CurrencyProvider, curvePillars) { Currency = usd, CollateralSpec = "CURVE", Name = "Coconuts", AssetId = "Coconuts" }; var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); var fxSpot = 7; var rates = new Dictionary <Currency, double> { { xaf, fxSpot } }; var discoMap = new Dictionary <Currency, string> { { xaf, "XAF.CURVE" }, { usd, "USD.CURVE" } }; var fxPair = new FxPair() { Domestic = usd, Foreign = xaf, PrimaryCalendar = cal, SpotLag = new Frequency("2b") }; fxMatrix.Init(usd, startDate, rates, new List <FxPair> { fxPair }, discoMap); var irPillars = new[] { startDate, startDate.AddYears(10) }; var xafRates = new[] { 0.1, 0.1 }; var usdRates = new[] { 0.01, 0.01 }; var xafCurve = new IrCurve(irPillars, xafRates, startDate, "XAF.CURVE", Interpolator1DType.Linear, xaf, "CURVE"); var usdCurve = new IrCurve(irPillars, usdRates, startDate, "USD.CURVE", Interpolator1DType.Linear, usd, "CURVE"); var fModel = new FundingModel(startDate, new[] { xafCurve, usdCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); fModel.SetupFx(fxMatrix); var aModel = new AssetFxModel(startDate, fModel); aModel.AddPriceCurve("Coconuts", curve); var periodCode = "SEP-18"; var(Start, End) = periodCode.ParsePeriod(); var fixingDates = Start.BusinessDaysInPeriod(End, cal).ToArray(); var settleDate = fixingDates.Last().AddPeriod(RollType.F, cal, new Frequency("5b")); var fxFwd = aModel.FundingModel.GetFxAverage(fixingDates, usd, xaf); var assetFwd = curve.GetAveragePriceForDates(fixingDates); var fairStrike = fxFwd * assetFwd; var asianSwap = AssetProductFactory.CreateMonthlyAsianSwap(periodCode, fairStrike, "Coconuts", cal, cal, new Frequency("5b"), xaf, TradeDirection.Long, new Frequency("0b"), 1000, DateGenerationType.BusinessDays); asianSwap.TradeId = "aLovelyBunch"; foreach (var sw in asianSwap.Swaplets) { sw.DiscountCurve = "XAF.CURVE"; sw.FxConversionType = FxConversionType.AverageThenConvert; } var pv = asianSwap.PV(aModel, false); Assert.Equal(0, pv, 8); var portfolio = new Portfolio() { Instruments = new List <IInstrument> { asianSwap } }; var pfPvCube = portfolio.PV(aModel); var pfPv = (double)pfPvCube.GetAllRows().First().Value; Assert.Equal(0.0, pfPv, 8); var deltaCube = portfolio.AssetDelta(aModel); var dAgg = deltaCube.Pivot("TradeId", AggregationAction.Sum); var delta = (double)dAgg.GetAllRows().First().Value; var t0Spot = aModel.FundingModel.GetFxRate(startDate, usd, xaf); var df = xafCurve.GetDf(startDate, settleDate); Assert.Equal(995.361065482776, delta, 7); var fxDeltaCube = portfolio.FxDelta(aModel, usd, TestProviderHelper.CurrencyProvider); var dfxAgg = fxDeltaCube.Pivot("TradeId", AggregationAction.Sum); var fxDelta = (double)dfxAgg.GetAllRows().First().Value; Assert.Equal(-1000 * df * fxFwd * 100 / (t0Spot / fxSpot) / usdCurve.GetDf(startDate, fxPair.SpotDate(startDate)), fxDelta, 4); }
public void ForwardFact() { var orgin = new DateTime(2019, 06, 12); var usd = TestProviderHelper.CurrencyProvider.GetCurrency("USD"); var zar = TestProviderHelper.CurrencyProvider.GetCurrency("ZAR"); var fixDates = new[] { orgin }; var x = new Forward() { AssetId = "QS", DiscountCurve = "X", ExpiryDate = orgin, FxConversionType = FxConversionType.None, Notional = 1, PaymentCurrency = usd, PaymentDate = orgin, SpotLag = 0.Bd(), Strike = 1000, }; var xFx = new Forward() { AssetId = "USD/ZAR", DiscountCurve = "Y", ExpiryDate = orgin, FxConversionType = FxConversionType.None, Notional = 1, PaymentCurrency = usd, PaymentDate = orgin, SpotLag = 0.Bd(), Strike = 1000, }; var x2 = new Forward() { AssetId = "QS", DiscountCurve = "X", ExpiryDate = orgin, FxConversionType = FxConversionType.AverageThenConvert, Notional = 1, PaymentCurrency = zar, PaymentDate = orgin, SpotLag = 0.Bd(), Strike = 1000, }; var fakeModel = new Mock <IAssetFxModel>(); var c = new ConstantPriceCurve(100, DateTime.Today, TestProviderHelper.CurrencyProvider) { Currency = usd }; fakeModel.Setup(xx => xx.GetPriceCurve(It.IsAny <string>(), null)).Returns(c); fakeModel.Setup(xx => xx.BuildDate).Returns(DateTime.Today); var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); fxMatrix.Init(usd, orgin, new Dictionary <Currency, double>(), new List <FxPair>(), new Dictionary <Currency, string> { { usd, "X" }, { zar, "Y" } }); var fModel = new Mock <IFundingModel>(); fModel.Setup(xx => xx.FxMatrix).Returns(fxMatrix); fakeModel.Setup(xx => xx.FundingModel).Returns(fModel.Object); Assert.Equal(usd, x.Currency); Assert.Equal(usd, x.PaymentCurrency); var a = x.AssetIds; Assert.Contains("QS", a); Assert.Single(x.IrCurves(fakeModel.Object)); var ir2 = xFx.IrCurves(fakeModel.Object); Assert.Contains("X", ir2); Assert.Contains("Y", ir2); ir2 = x2.IrCurves(fakeModel.Object); Assert.Contains("X", ir2); Assert.Contains("Y", ir2); Assert.Equal(string.Empty, x.FxPair(fakeModel.Object)); Assert.Equal("USD/ZAR", x2.FxPair(fakeModel.Object)); Assert.Equal(FxConversionType.None, x.FxType(fakeModel.Object)); Assert.Equal(orgin, x.LastSensitivityDate); var pf = x.PastFixingDates(orgin.AddDays(1)); Assert.Contains("QS", pf.Keys); var y = (Forward)x.Clone(); Assert.True(x.Equals(y)); y.TradeId = "xxx"; Assert.False(x.Equals(y)); var z = (Forward)x.SetStrike(0); Assert.Equal(0, z.Strike); Assert.Equal(1.0, z.SupervisoryDelta(fakeModel.Object)); }
//------------------------------------------------------------------------- //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @ImmutableDefaults private static void applyDefaults(Builder builder) private static void applyDefaults(Builder builder) { builder.fxRateProvider = FxMatrix.empty(); }
public void MultiPeriodBackpricingOptionFact() { var orgin = new DateTime(2019, 06, 12); var usd = TestProviderHelper.CurrencyProvider.GetCurrency("USD"); var zar = TestProviderHelper.CurrencyProvider.GetCurrency("ZAR"); var fixDates = new[] { orgin }; var x = new MultiPeriodBackpricingOption() { AssetId = "QS", CallPut = OptionType.C, DiscountCurve = "X", FixingDates = new List <DateTime[]>() { fixDates }, FxConversionType = FxConversionType.None, Notional = 1, PaymentCurrency = usd, SpotLag = 0.Bd(), SpotLagRollType = RollType.F, PeriodDates = new [] { new Tuple <DateTime, DateTime> (orgin, orgin) } }; var x2 = new MultiPeriodBackpricingOption() { AssetId = "QS", CallPut = OptionType.C, DiscountCurve = "X", FixingDates = new List <DateTime[]>() { fixDates }, FxConversionType = FxConversionType.AverageThenConvert, Notional = 1, PaymentCurrency = zar, SpotLag = 0.Bd(), SpotLagRollType = RollType.F, PeriodDates = new[] { new Tuple <DateTime, DateTime>(orgin, orgin) } }; var fakeModel = new Mock <IAssetFxModel>(); var c = new ConstantPriceCurve(100, DateTime.Today, TestProviderHelper.CurrencyProvider) { Currency = usd }; fakeModel.Setup(xx => xx.GetPriceCurve(It.IsAny <string>(), null)).Returns(c); var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); fxMatrix.Init(usd, orgin, new Dictionary <Currency, double>(), new List <FxPair>(), new Dictionary <Currency, string> { { usd, "X" }, { zar, "Y" } }); var fModel = new Mock <IFundingModel>(); fModel.Setup(xx => xx.FxMatrix).Returns(fxMatrix); fakeModel.Setup(xx => xx.FundingModel).Returns(fModel.Object); Assert.Equal(usd, x.Currency); Assert.Equal(usd, x.PaymentCurrency); var a = x.AssetIds; Assert.Contains("QS", a); Assert.Single(x.IrCurves(fakeModel.Object)); var ir2 = x2.IrCurves(fakeModel.Object); Assert.Contains("X", ir2); Assert.Contains("Y", ir2); Assert.Equal(FxConversionType.None, x.FxType(fakeModel.Object)); Assert.Equal(orgin, x.LastSensitivityDate); var pf = x.PastFixingDates(orgin.AddDays(1)); Assert.Contains("QS", pf.Keys); Assert.Equal(string.Empty, x.FxPair(fakeModel.Object)); Assert.Throws <InvalidOperationException>(() => x.SetStrike(0)); }
public void ContangoSwap() { var bd = new DateTime(2019, 06, 14); var pillars = new[] { bd, bd.AddDays(1000) }; var flatRateUsd = 0.05; var flatRateXau = 0.01; var spotRate = 1200; var ratesUsd = pillars.Select(p => flatRateUsd).ToArray(); var ratesXau = pillars.Select(p => flatRateXau).ToArray(); var usd = TestProviderHelper.CurrencyProvider["USD"]; var xau = TestProviderHelper.CurrencyProvider["XAU"]; CalendarProvider.Collection.TryGetCalendar("LON", out var cal); var pair = new FxPair() { Domestic = xau, Foreign = usd, SettlementCalendar = cal, SpotLag = 2.Bd() }; var discoCurveUsd = new IrCurve(pillars, ratesUsd, bd, "USD.BLAH", Interpolator1DType.Linear, usd); var discoCurveXau = new IrCurve(pillars, ratesXau, bd, "XAU.BLAH", Interpolator1DType.Linear, xau); var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); fxMatrix.Init(usd, bd, new Dictionary <Currency, double> { { xau, 1.0 / spotRate } }, new List <FxPair> { pair }, new Dictionary <Currency, string> { { usd, "USD.BLAH" }, { xau, "XAU.BLAH" } }); var fModel = new FundingModel(bd, new[] { discoCurveUsd, discoCurveXau }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); fModel.SetupFx(fxMatrix); var maturity = bd.AddDays(365); var spot = bd.SpotDate(2.Bd(), cal, cal); var c = 0.022; var b = new ContangoSwap { CashCCY = usd, MetalCCY = xau, CashDiscountCurve = "USD.BLAH", DeliveryDate = maturity, ContangoRate = c, MetalQuantity = 1, SpotDate = spot }; var t = spot.CalculateYearFraction(maturity, DayCountBasis.Act360); var pv = b.Pv(fModel, false); var fwdA = (1.0 + c * t) * spotRate; var fwdB = fModel.GetFxRate(maturity, xau, usd); var df = discoCurveUsd.GetDf(bd, maturity); var expectedPv = (fwdB - fwdA) * b.MetalQuantity; expectedPv *= df; Assert.Equal(expectedPv, pv, 10); Assert.Equal(maturity, b.LastSensitivityDate); Assert.Equal(usd, b.Currency); var s = b.Sensitivities(fModel); Assert.True(s.Count == 2 && s.Keys.Contains("USD.BLAH") && s.Keys.Contains("XAU.BLAH")); var s2 = b.Dependencies(fModel.FxMatrix); Assert.True(s2.Count == 2 && s2.Contains("USD.BLAH") && s2.Contains("XAU.BLAH")); Assert.Equal(0.0402428426839156, b.CalculateParRate(fModel), 8); var b2 = (ContangoSwap)b.SetParRate(0.05); Assert.Equal(0.05, b2.ContangoRate); }
private AssetFxMCModel GetSut() { var buildDate = DateTime.Parse("2018-10-04"); var usd = TestProviderHelper.CurrencyProvider["USD"]; var zar = TestProviderHelper.CurrencyProvider["ZAR"]; TestProviderHelper.CalendarProvider.Collection.TryGetCalendar("NYC", out var usdCal); var pair = new FxPair() { Domestic = zar, Foreign = usd, PrimaryCalendar = usdCal, SpotLag = 2.Bd() }; var dfCurve = new IrCurve(new[] { buildDate, buildDate.AddDays(1000) }, new[] { 0.0, 0.0 }, buildDate, "disco", Interpolator1DType.Linear, usd, "DISCO"); var dates = new[] { buildDate, buildDate.AddDays(32), buildDate.AddDays(60), buildDate.AddDays(90) }; var times = dates.Select(d => buildDate.CalculateYearFraction(d, DayCountBasis.Act365F)).ToArray(); var vols = new[] { 0.32, 0.30, 0.29, 0.28 }; var comCurve = new PriceCurve(buildDate, dates, new[] { 100.0, 100.0, 100.0, 100.0 }, PriceCurveType.NYMEX, TestProviderHelper.CurrencyProvider) { Name = "CL", AssetId = "CL" }; var comSurface = new GridVolSurface(buildDate, new[] { 0.5 }, dates, vols.Select(x => new double[] { x }).ToArray(), StrikeType.ForwardDelta, Interpolator1DType.Linear, Interpolator1DType.LinearInVariance, DayCountBasis.Act365F) { AssetId = "CL" }; var fxSurface = new ConstantVolSurface(buildDate, 0.16) { AssetId = "USD/ZAR" }; var correlVector = new CorrelationTimeVector("CL", "USD/ZAR", _correls, times); var fModel = new FundingModel(buildDate, new Dictionary <string, IrCurve> { { "DISCO", dfCurve } }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); var fxM = new FxMatrix(TestProviderHelper.CurrencyProvider); fxM.Init(usd, buildDate, new Dictionary <Currency, double>() { { zar, 14.0 } }, new List <FxPair>() { pair }, new Dictionary <Currency, string> { { usd, "DISCO" }, { zar, "DISCO" } }); fModel.SetupFx(fxM); fModel.VolSurfaces.Add("ZAR/USD", fxSurface); fModel.VolSurfaces.Add("USD/ZAR", fxSurface); var aModel = new AssetFxModel(buildDate, fModel); aModel.AddVolSurface("CL", comSurface); aModel.AddPriceCurve("CL", comCurve); aModel.CorrelationMatrix = correlVector; var product1 = AssetProductFactory.CreateAsianOption(dates[1], dates[1], 1400, "CL", OptionType.Call, usdCal, dates[1], zar); product1.TradeId = "P1"; product1.DiscountCurve = "DISCO"; product1.FxConversionType = FxConversionType.AverageThenConvert; var product2 = AssetProductFactory.CreateAsianOption(dates[2], dates[2], 1400, "CL", OptionType.Call, usdCal, dates[2], zar); product2.TradeId = "P2"; product2.DiscountCurve = "DISCO"; product2.FxConversionType = FxConversionType.AverageThenConvert; var product3 = AssetProductFactory.CreateAsianOption(dates[3], dates[3], 1400, "CL", OptionType.Call, usdCal, dates[3], zar); product3.TradeId = "P3"; product3.DiscountCurve = "DISCO"; product3.FxConversionType = FxConversionType.AverageThenConvert; var pfolio = new Portfolio { Instruments = new List <IInstrument> { product1, product2, product3 } }; var settings = new McSettings { Generator = RandomGeneratorType.MersenneTwister, NumberOfPaths = (int)2.0.IntPow(15), NumberOfTimesteps = 1, ReportingCurrency = zar, Parallelize = false, LocalCorrelation = true, }; var sut = new AssetFxMCModel(buildDate, pfolio, aModel, settings, TestProviderHelper.CurrencyProvider, TestProviderHelper.FutureSettingsProvider, TestProviderHelper.CalendarProvider); return(sut); }
public void FxDeltaOnUSDTrade() { ParallelUtils.Instance.MultiThreaded = false; var startDate = new DateTime(2018, 07, 28); var cal = TestProviderHelper.CalendarProvider.Collection["LON"]; var zar = TestProviderHelper.CurrencyProvider["ZAR"]; var usd = TestProviderHelper.CurrencyProvider["USD"]; var curvePillars = new[] { "1W", "1M", "3M", "6M", "1Y" }; var curvePillarDates = curvePillars.Select(l => startDate.AddPeriod(RollType.F, cal, new Frequency(l))).ToArray(); var curvePoints = new[] { 100.0, 100, 100, 100, 100 }; var curve = new PriceCurve(startDate, curvePillarDates, curvePoints, PriceCurveType.LME, TestProviderHelper.CurrencyProvider, curvePillars) { Currency = usd, CollateralSpec = "CURVE", Name = "Coconuts" }; var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); var fxSpot = 15; var rates = new Dictionary <Currency, double> { { zar, fxSpot } }; var discoMap = new Dictionary <Currency, string> { { zar, "ZAR.CURVE" }, { usd, "USD.CURVE" } }; var fxPair = new FxPair() { Domestic = usd, Foreign = zar, SettlementCalendar = cal, SpotLag = new Frequency("0b") }; fxMatrix.Init(usd, startDate, rates, new List <FxPair> { fxPair }, discoMap); var irPillars = new[] { startDate, startDate.AddYears(10) }; var zarRates = new[] { 0.0, 0.0 }; var usdRates = new[] { 0.0, 0.0 }; var zarCurve = new IrCurve(irPillars, zarRates, startDate, "ZAR.CURVE", Interpolator1DType.Linear, zar, "CURVE"); var usdCurve = new IrCurve(irPillars, usdRates, startDate, "USD.CURVE", Interpolator1DType.Linear, usd, "CURVE"); var fModel = new FundingModel(startDate, new[] { zarCurve, usdCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); fModel.SetupFx(fxMatrix); var aModel = new AssetFxModel(startDate, fModel); aModel.AddPriceCurve("Coconuts", curve); var periodCode = "SEP-18"; var(Start, End) = periodCode.ParsePeriod(); var fixingDates = Start.BusinessDaysInPeriod(End, cal).ToArray(); var settleDate = fixingDates.Last().AddPeriod(RollType.F, cal, new Frequency("5b")); var fxFwd = aModel.FundingModel.GetFxAverage(fixingDates, usd, zar); var assetFwd = curve.GetAveragePriceForDates(fixingDates); var fairStrike = assetFwd; var strike = fairStrike - 10; var nominal = 1000; var asianSwap = AssetProductFactory.CreateMonthlyAsianSwap(periodCode, strike, "Coconuts", cal, cal, new Frequency("5b"), usd, TradeDirection.Long, new Frequency("0b"), nominal, DateGenerationType.BusinessDays); asianSwap.TradeId = "aLovelyBunch"; foreach (var sw in asianSwap.Swaplets) { sw.DiscountCurve = "USD.CURVE"; sw.FxConversionType = FxConversionType.None; } var pv = asianSwap.PV(aModel, false); var expectedPV = (fairStrike - strike) * nominal; Assert.Equal(expectedPV, pv, 8); var portfolio = new Portfolio() { Instruments = new List <IInstrument> { asianSwap } }; var pfPvCube = portfolio.PV(aModel, usd); var pfPv = (double)pfPvCube.GetAllRows().First().Value; Assert.Equal(expectedPV, pfPv, 8); //expected fx delta is just PV in USD var deltaCube = portfolio.FxDelta(aModel, zar, TestProviderHelper.CurrencyProvider); var dAgg = deltaCube.Pivot("TradeId", AggregationAction.Sum); var delta = (double)dAgg.GetAllRows().First().Value; Assert.Equal(expectedPV, delta, 4); }
public static object MergeFundingModels( [ExcelArgument(Description = "Output funding model")] string ObjectName, [ExcelArgument(Description = "Funding model A")] string FundingModelA, [ExcelArgument(Description = "Funding model B")] string FundingModelB) { return(ExcelHelper.Execute(_logger, () => { var modelCache = ContainerStores.GetObjectCache <IFundingModel>(); if (!modelCache.TryGetObject(FundingModelA, out var modelA)) { return $"Could not find funding model {FundingModelA}"; } if (!modelCache.TryGetObject(FundingModelB, out var modelB)) { return $"Could not find funding model {FundingModelB}"; } var combinedCurves = modelA.Value.Curves.Values.Concat(modelB.Value.Curves.Values).ToArray(); if (combinedCurves.Length != combinedCurves.Select(x => x.Name).Distinct().Count()) { return $"Not all curves have unique names"; } var outModel = new FundingModel(modelA.Value.BuildDate, combinedCurves, ContainerStores.CurrencyProvider, ContainerStores.CalendarProvider); foreach (var vs in modelA.Value.VolSurfaces) { outModel.VolSurfaces.Add(vs.Key, vs.Value); } foreach (var vs in modelB.Value.VolSurfaces) { outModel.VolSurfaces.Add(vs.Key, vs.Value); } var fxA = modelA.Value.FxMatrix; var fxB = modelB.Value.FxMatrix; var spotRates = new Dictionary <Currency, double>(); foreach (var s in fxA.SpotRates) { spotRates.Add(s.Key, s.Value); } foreach (var s in fxB.SpotRates) { spotRates.Add(s.Key, s.Value); } var discoMap = new Dictionary <Currency, string>(); foreach (var s in fxA.DiscountCurveMap) { discoMap.Add(s.Key, s.Value); } foreach (var s in fxB.DiscountCurveMap) { discoMap.Add(s.Key, s.Value); } var pairs = fxA.FxPairDefinitions.Concat(fxB.FxPairDefinitions).Distinct().ToList(); var fxMatrix = new FxMatrix(ContainerStores.CurrencyProvider); fxMatrix.Init(fxA.BaseCurrency, modelA.Value.BuildDate, spotRates, pairs, discoMap); outModel.SetupFx(fxMatrix); return ExcelHelper.PushToCache <IFundingModel>(outModel, ObjectName); })); }
private (IAssetFxModel startModel, IAssetFxModel endModel, Portfolio portfolio) GenerateTestData() { Utils.Parallel.ParallelUtils.Instance.MultiThreaded = false; var usd = TestProviderHelper.CurrencyProvider.GetCurrency("USD"); var zar = TestProviderHelper.CurrencyProvider.GetCurrency("ZAR"); var nyc = TestProviderHelper.CalendarProvider.Collection["NYC"]; var originDate = DateTime.Parse("2019-04-25"); var ins = new FxForward { TradeId = "TestA", DeliveryDate = originDate.AddDays(30), DomesticCCY = zar, ForeignCCY = usd, DomesticQuantity = 1e6, Strike = 14, ForeignDiscountCurve = "DISCO-USD" }; var pf = new Portfolio { Instruments = new List <IInstrument> { ins } }; var discoUsd = new FlatIrCurve(0.02, usd, "DISCO-USD"); var discoZar = new FlatIrCurve(0.05, zar, "DISCO-ZAR"); var fxpairs = new List <FxPair> { new FxPair { Domestic = usd, Foreign = zar, PrimaryCalendar = nyc, SpotLag = 2.Bd() }, new FxPair { Domestic = zar, Foreign = usd, PrimaryCalendar = nyc, SpotLag = 2.Bd() }, }; var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); fxMatrix.Init(zar, originDate, new Dictionary <Currency, double> { { usd, 14.0 } }, fxpairs, new Dictionary <Currency, string> { { usd, "DISCO-USD" }, { zar, "DISCO-ZAR" } }); var fModel = new FundingModel(originDate, new[] { discoUsd, discoZar }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); fModel.SetupFx(fxMatrix); var startModel = new AssetFxModel(originDate, fModel); startModel.AddFixingDictionary("FakeAsset", new FixingDictionary()); startModel.AddPriceCurve("FakeAsset", new ConstantPriceCurve(100, originDate, TestProviderHelper.CurrencyProvider)); startModel.AddVolSurface("FakeAsset", new ConstantVolSurface(originDate, 1.00) { AssetId = "FakeAsset", Currency = usd }); var endFModel = fModel.DeepClone(); endFModel.FxMatrix.SpotRates[usd] = 15; var endModel = startModel.Clone(endFModel); endModel.AddFixingDictionary("FakeAsset", new FixingDictionary()); endModel.AddPriceCurve("FakeAsset", new ConstantPriceCurve(100, originDate, TestProviderHelper.CurrencyProvider)); endModel.AddVolSurface("FakeAsset", new ConstantVolSurface(originDate, 1.00) { AssetId = "FakeAsset", Currency = usd }); return(startModel, endModel, pf); }
//------------------------------------------------------------------------- public virtual void test_convertedTo_singleCurrency() { CurrencyParameterSensitivities test = SENSI_1.convertedTo(USD, FxMatrix.empty()); assertEquals(test.Sensitivities, ImmutableList.of(ENTRY_USD)); }
//------------------------------------------------------------------------- public virtual void test_total_singleCurrency() { assertEquals(SENSI_1.total(USD, FxMatrix.empty()).Amount, VECTOR_USD1.sum(), 1e-8); }
public AssetFxModel BuildModel(DateTime valDate, ModelBuilderSpec spec, IFutureSettingsProvider futureSettingsProvider, ICurrencyProvider currencyProvider, ICalendarProvider calendarProvider) { var indices = spec.RateIndices.ToDictionary(x => x.Key, x => new FloatRateIndex(x.Value, calendarProvider, currencyProvider)); var fxPairs = spec.FxPairs.Select(x => new FxPair(x, currencyProvider, calendarProvider)).ToList(); var priceCurves = new List <IPriceCurve>(); var surfaces = new List <IVolSurface>(); var fxSurfaces = new List <IVolSurface>(); foreach (var c in spec.NymexSpecs) { var curve = NYMEXModelBuilder.GetCurveForCode(c.NymexCodeFuture, Path.Combine(_filepath, FilenameNymexFuture), c.QwackCode, futureSettingsProvider, currencyProvider); priceCurves.Add(curve); if (!string.IsNullOrWhiteSpace(c.NymexCodeOption)) { var surface = NYMEXModelBuilder.GetSurfaceForCode(c.NymexCodeOption, Path.Combine(_filepath, FilenameNymexOption), c.QwackCode, curve, calendarProvider, currencyProvider, futureSettingsProvider); surface.AssetId = c.QwackCode; surfaces.Add(surface); } } var irCurves = new Dictionary <string, IrCurve>(); foreach (var c in spec.CmeBaseCurveSpecs) { var ixForThis = new Dictionary <string, FloatRateIndex> { { c.QwackCode, indices[c.FloatRateIndex] } }; var curve = CMEModelBuilder.GetCurveForCode(c.CmeCode, Path.Combine(_filepath, c.IsCbot? FilenameCbot:FilenameCme), c.QwackCode, c.CurveName, ixForThis, new Dictionary <string, string>() { { c.QwackCode, c.CurveName } }, futureSettingsProvider, currencyProvider, calendarProvider); irCurves.Add(c.CurveName, curve); } foreach (var c in spec.CmeBasisCurveSpecs) { var fxPair = fxPairs.Single(x => $"{x.Domestic}{x.Foreign}" == c.FxPair); var curve = CMEModelBuilder.StripFxBasisCurve(Path.Combine(_filepath, FilenameCmeFwdsXml), fxPair, c.CmeFxPair, currencyProvider.GetCurrency(c.Currency), c.CurveName, valDate, irCurves[c.BaseCurveName], currencyProvider, calendarProvider); irCurves.Add(c.CurveName, curve); } foreach (var c in spec.CmeFxFutureSpecs) { var curve = CMEModelBuilder.GetFuturesCurveForCode(c.CmeCodeFut, Path.Combine(_filepath, FilenameCme), currencyProvider); var surface = CMEModelBuilder.GetFxSurfaceForCode(c.CmeCodeOpt, Path.Combine(_filepath, FilenameCme), curve, currencyProvider); surface.AssetId = c.FxPair; fxSurfaces.Add(surface); } var pairMap = spec.CmeBasisCurveSpecs.ToDictionary(x => x.FxPair, x => x.CmeFxPair); var pairCcyMap = spec.CmeBasisCurveSpecs.ToDictionary(x => x.FxPair, x => currencyProvider.GetCurrency(x.Currency)); var spotRates = CMEModelBuilder.GetSpotFxRatesFromFwdFile(Path.Combine(_filepath, FilenameCmeFwdsXml), valDate, pairMap, currencyProvider, calendarProvider); var discountMap = spec.CmeBasisCurveSpecs.ToDictionary(x => pairCcyMap[x.FxPair], x => x.CurveName); foreach (var c in spec.CmxMetalCurves) { var fxPair = fxPairs.Single(x => $"{x.Domestic}{x.Foreign}" == c.MetalPair); var(curve, spotPrice) = COMEXModelBuilder.GetMetalCurveForCode(Path.Combine(_filepath, FilenameCmxFwdsXml), c.CmxSymbol, fxPair, c.CurveName, valDate, irCurves[c.BaseCurveName], currencyProvider, calendarProvider); irCurves.Add(c.CurveName, curve); spotRates.Add(c.MetalPair, spotPrice); discountMap.Add(currencyProvider.GetCurrency(c.Currency), c.CurveName); pairCcyMap.Add(c.MetalPair, currencyProvider.GetCurrency(c.Currency)); if (!string.IsNullOrWhiteSpace(c.CmxOptCode)) { var surface = COMEXModelBuilder.GetMetalSurfaceForCode(c.CmxOptCode, Path.Combine(_filepath, FilenameCmxXml), currencyProvider); surface.AssetId = c.MetalPair; fxSurfaces.Add(surface); } } var fm = new FundingModel(valDate, irCurves, currencyProvider, calendarProvider); var spotRatesByCcy = spotRates.ToDictionary(x => pairCcyMap[x.Key], x => x.Key.StartsWith("USD") ? x.Value : 1.0 / x.Value); var fxMatrix = new FxMatrix(currencyProvider); fxMatrix.Init( baseCurrency: currencyProvider.GetCurrency("USD"), buildDate: valDate, spotRates: spotRatesByCcy, fXPairDefinitions: fxPairs, discountCurveMap: discountMap); fm.SetupFx(fxMatrix); foreach (var fxs in fxSurfaces) { fm.VolSurfaces.Add(fxs.AssetId, fxs); } var o = new AssetFxModel(valDate, fm); o.AddVolSurfaces(surfaces.ToDictionary(s => s.AssetId, s => s)); o.AddPriceCurves(priceCurves.ToDictionary(c => c.AssetId, c => c)); return(o); }
public void ComplexerCurve() { var startDate = new DateTime(2016, 05, 20); Frequency[] depoTenors = { 3.Months() }; Frequency[] OISdepoTenors = { 1.Bd() }; double[] depoPricesZAR = { 0.06 }; double[] depoPricesUSD = { 0.01 }; double[] OISdepoPricesZAR = { 0.055 }; double[] OISdepoPricesUSD = { 0.009 }; string[] FRATenors = { "3x6", "6x9", "9x12", "12x15", "15x18", "18x21", "21x24" }; double[] FRAPricesZAR = { 0.065, 0.07, 0.075, 0.077, 0.08, 0.081, 0.082 }; double[] FRAPricesUSD = { 0.012, 0.013, 0.014, 0.015, 0.016, 0.017, 0.018 }; Frequency[] swapTenors = { 3.Years(), 4.Years(), 5.Years(), 6.Years(), 7.Years(), 8.Years(), 9.Years(), 10.Years(), 12.Years(), 15.Years(), 20.Years(), 25.Years(), 30.Years() }; double[] swapPricesZAR = { 0.08, 0.083, 0.085, 0.087, 0.089, 0.091, 0.092, 0.093, 0.094, 0.097, 0.099, 0.099, 0.099 }; double[] swapPricesUSD = { 0.017, 0.018, 0.019, 0.020, 0.021, 0.022, 0.023, 0.024, 0.025, 0.026, 0.027, 0.028, 0.03 }; Frequency[] oisTenors = { 3.Months(), 6.Months(), 1.Years(), 18.Months(), 2.Years(), 3.Years(), 4.Years(), 5.Years(), 6.Years(), 7.Years(), 8.Years(), 9.Years(), 10.Years(), 12.Years(), 15.Years(), 20.Years(), 25.Years(), 30.Years() }; double[] oisPricesZAR = { 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004 }; double[] oisPricesUSD = { 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002 }; var fxSpot = 14.0; Frequency[] fxForwardTenors = { 3.Months(), 6.Months(), 1.Years(), 18.Months(), 2.Years(), 3.Years() }; double[] fxForwardPrices = { 14.10, 14.20, 14.40, 14.60, 14.80, 15.20 }; Frequency[] xcySwapTenors = { 4.Years(), 5.Years(), 6.Years(), 7.Years(), 8.Years(), 9.Years(), 10.Years(), 12.Years(), 15.Years(), 20.Years(), 25.Years(), 30.Years() }; double[] xcySwapPrices = { 0.0055, 0.0050, 0.0045, 0.0040, 0.0035, 0.0030, 0.0025, 0.0020, 0.0015, 0.0010, 0.0005, 0.0000 }; var ZARpillarDatesDepo = depoTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray(); var ZARpillarDatesFRA = FRATenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, new Frequency(x.Split('x')[1] + "M"))).ToArray(); var ZARpillarDatesSwap = swapTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray(); var ZARpillarDates3m = ZARpillarDatesDepo.Union(ZARpillarDatesSwap).Union(ZARpillarDatesFRA).Distinct().OrderBy(x => x).ToArray(); var ZARpillarDatesDepoOIS = OISdepoTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray(); var ZARpillarDatesOISSwap = oisTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray(); var ZARpillarDatesOIS = ZARpillarDatesDepoOIS.Union(ZARpillarDatesOISSwap).Distinct().OrderBy(x => x).ToArray(); var USDpillarDatesDepo = depoTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var USDpillarDatesFRA = FRATenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, new Frequency(x.Split('x')[1] + "M"))).ToArray(); var USDpillarDatesSwap = swapTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var USDpillarDates3m = USDpillarDatesDepo.Union(USDpillarDatesSwap).Union(USDpillarDatesFRA).Distinct().OrderBy(x => x).ToArray(); var USDpillarDatesDepoOIS = OISdepoTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var USDpillarDatesOISSwap = oisTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var USDpillarDatesOIS = USDpillarDatesDepoOIS.Union(USDpillarDatesOISSwap).Distinct().OrderBy(x => x).ToArray(); var fxForwardPillarDates = fxForwardTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var xcySwapDates = xcySwapTenors.Select(x => startDate.AddPeriod(RollType.MF, _usd, x)).ToArray(); var fxPillarDates = fxForwardPillarDates.Union(xcySwapDates).Distinct().OrderBy(x => x).ToArray(); var ZARswaps = new IrSwap[swapTenors.Length]; var ZARdepos = new IrSwap[depoTenors.Length]; var ZARdeposOIS = new IrSwap[OISdepoTenors.Length]; var ZARoisSwaps = new IrBasisSwap[oisTenors.Length]; var ZARFRAs = new ForwardRateAgreement[FRATenors.Length]; var USDswaps = new IrSwap[swapTenors.Length]; var USDdepos = new IrSwap[depoTenors.Length]; var USDdeposOIS = new IrSwap[OISdepoTenors.Length]; var USDoisSwaps = new IrBasisSwap[oisTenors.Length]; var USDFRAs = new ForwardRateAgreement[FRATenors.Length]; var fxForwards = new FxForward[fxForwardTenors.Length]; var xcySwaps = new XccyBasisSwap[xcySwapTenors.Length]; var FIC = new FundingInstrumentCollection(TestProviderHelper.CurrencyProvider); for (var i = 0; i < FRATenors.Length; i++) { ZARFRAs[i] = new ForwardRateAgreement(startDate, FRATenors[i], FRAPricesZAR[i], _zar3m, SwapPayReceiveType.Payer, FraDiscountingType.Isda, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.JIBAR.3M" }; FIC.Add(ZARFRAs[i]); USDFRAs[i] = new ForwardRateAgreement(startDate, FRATenors[i], FRAPricesUSD[i], usd3m, SwapPayReceiveType.Payer, FraDiscountingType.Isda, "USD.LIBOR.3M", "USD.DISC.CSA_USD") { SolveCurve = "USD.LIBOR.3M" }; FIC.Add(USDFRAs[i]); } for (var i = 0; i < oisTenors.Length; i++) { ZARoisSwaps[i] = new IrBasisSwap(startDate, oisTenors[i], oisPricesZAR[i], true, zaron, _zar3m, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.DISC.CSA_ZAR" }; FIC.Add(ZARoisSwaps[i]); USDoisSwaps[i] = new IrBasisSwap(startDate, oisTenors[i], oisPricesUSD[i], true, usdon, usd3m, "USD.LIBOR.3M", "USD.DISC.CSA_USD", "USD.DISC.CSA_USD") { SolveCurve = "USD.DISC.CSA_USD" }; FIC.Add(USDoisSwaps[i]); } for (var i = 0; i < swapTenors.Length; i++) { ZARswaps[i] = new IrSwap(startDate, swapTenors[i], _zar3m, swapPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.JIBAR.3M" }; FIC.Add(ZARswaps[i]); USDswaps[i] = new IrSwap(startDate, swapTenors[i], usd3m, swapPricesUSD[i], SwapPayReceiveType.Payer, "USD.LIBOR.3M", "USD.DISC.CSA_USD") { SolveCurve = "USD.LIBOR.3M" }; FIC.Add(USDswaps[i]); } for (var i = 0; i < depoTenors.Length; i++) { ZARdepos[i] = new IrSwap(startDate, depoTenors[i], _zar3m, depoPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.JIBAR.3M" }; FIC.Add(ZARdepos[i]); USDdepos[i] = new IrSwap(startDate, depoTenors[i], usd3m, depoPricesUSD[i], SwapPayReceiveType.Payer, "USD.LIBOR.3M", "USD.DISC.CSA_USD") { SolveCurve = "USD.LIBOR.3M" }; FIC.Add(USDdepos[i]); } for (var i = 0; i < OISdepoTenors.Length; i++) { ZARdeposOIS[i] = new IrSwap(startDate, OISdepoTenors[i], zaron, OISdepoPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.DISC.CSA_ZAR", "ZAR.DISC.CSA_ZAR") { SolveCurve = "ZAR.DISC.CSA_ZAR" }; FIC.Add(ZARdeposOIS[i]); USDdeposOIS[i] = new IrSwap(startDate, OISdepoTenors[i], usdon, OISdepoPricesUSD[i], SwapPayReceiveType.Payer, "USD.DISC.CSA_USD", "USD.DISC.CSA_USD") { SolveCurve = "USD.DISC.CSA_USD" }; FIC.Add(USDdeposOIS[i]); } for (var i = 0; i < fxForwards.Length; i++) { fxForwards[i] = new FxForward { SolveCurve = "ZAR.DISC.CSA_USD", DeliveryDate = fxForwardPillarDates[i], DomesticCCY = ccyUsd, ForeignCCY = ccyZar, DomesticQuantity = 1e6 / fxForwardPrices[i], Strike = fxForwardPrices[i], ForeignDiscountCurve = "ZAR.DISC.CSA_USD", }; FIC.Add(fxForwards[i]); } for (var i = 0; i < xcySwapTenors.Length; i++) { xcySwaps[i] = new XccyBasisSwap(startDate, xcySwapTenors[i], xcySwapPrices[i], true, usd3m, _zar3m, ExchangeType.Both, MTMSwapType.ReceiveNotionalFixed, "USD.LIBOR.3M", "ZAR.JIBAR.3M", "USD.DISC.CSA_USD", "ZAR.DISC.CSA_USD") { SolveCurve = "ZAR.DISC.CSA_USD" }; FIC.Add(xcySwaps[i]); } var ZARcurve3m = new IrCurve(ZARpillarDates3m, new double[ZARpillarDates3m.Length], startDate, "ZAR.JIBAR.3M", Interpolator1DType.LinearFlatExtrap, ccyZar) { SolveStage = 0 }; var ZARcurveOIS = new IrCurve(ZARpillarDatesOIS, new double[ZARpillarDatesOIS.Length], startDate, "ZAR.DISC.CSA_ZAR", Interpolator1DType.LinearFlatExtrap, ccyZar) { SolveStage = 0 }; var USDcurve3m = new IrCurve(USDpillarDates3m, new double[USDpillarDates3m.Length], startDate, "USD.LIBOR.3M", Interpolator1DType.LinearFlatExtrap, ccyUsd) { SolveStage = 1 }; var USDcurveOIS = new IrCurve(USDpillarDatesOIS, new double[USDpillarDatesOIS.Length], startDate, "USD.DISC.CSA_USD", Interpolator1DType.LinearFlatExtrap, ccyUsd) { SolveStage = 1 }; var fxCurve = new IrCurve(fxPillarDates, new double[fxPillarDates.Length], startDate, "ZAR.DISC.CSA_USD", Interpolator1DType.LinearFlatExtrap, ccyZar) { SolveStage = 2 }; var engine = new FundingModel(startDate, new IrCurve[] { ZARcurve3m, ZARcurveOIS, USDcurve3m, USDcurveOIS, fxCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); var spotRates = new Dictionary <Currency, double> { { ccyZar, fxSpot } }; var fxPairs = new List <FxPair> { new FxPair { Domestic = ccyUsd, Foreign = ccyZar, SettlementCalendar = _usd, SpotLag = new Frequency("2b") } }; var discountMap = new Dictionary <Currency, string> { { ccyUsd, "USD.DISC.CSA_USD" }, { ccyZar, "ZAR.DISC.CSA_USD" }, }; fxMatrix.Init(ccyUsd, startDate, spotRates, fxPairs, discountMap); engine.SetupFx(fxMatrix); var S = new NewtonRaphsonMultiCurveSolverStaged() { Tollerance = IsCoverageOnly ? 1 : 0.00000001, MaxItterations = IsCoverageOnly ? 1 : 100, }; S.Solve(engine, FIC); if (!IsCoverageOnly) { foreach (var ins in FIC) { var pv = ins.Pv(engine, false); Assert.Equal(0.0, pv, 7); } } }