public void DemonstrateCreationOfFxForward() { // CREATE an Fx-Forward (that can then be upserted into LUSID) var usdJpyFxRate = 109m; // Assume 1 USD is worth 109m as contract is struck. USD is domestic, JPY is foreign. var fxForward = new FxForward( domAmount: -1m, fgnAmount: usdJpyFxRate, domCcy: "USD", fgnCcy: "JPY", startDate: new DateTimeOffset(2020, 2, 7, 0, 0, 0, TimeSpan.Zero), maturityDate: new DateTimeOffset(2020, 9, 18, 0, 0, 0, TimeSpan.Zero), instrumentType: LusidInstrument.InstrumentTypeEnum.FxForward ); // ASSERT that it was created Assert.That(fxForward, Is.Not.Null); // CAN NOW UPSERT TO LUSID string uniqueId = "id-fxfwd-1"; UpsertOtcToLusid(fxForward, "some-name-for-this-fxforward", uniqueId); // CAN NOW QUERY FROM LUSID var retrieved = QueryOtcFromLusid(uniqueId); Assert.That(retrieved.InstrumentType == LusidInstrument.InstrumentTypeEnum.FxForward); var retrFxFwd = retrieved as FxForward; Assert.That(retrFxFwd, Is.Not.Null); Assert.That(retrFxFwd.DomAmount, Is.EqualTo(fxForward.DomAmount)); Assert.That(retrFxFwd.FgnAmount, Is.EqualTo(fxForward.FgnAmount)); Assert.That(retrFxFwd.DomCcy, Is.EqualTo(fxForward.DomCcy)); Assert.That(retrFxFwd.FgnCcy, Is.EqualTo(fxForward.FgnCcy)); }
public static object CreateFxForward( [ExcelArgument(Description = "Object name")] string ObjectName, [ExcelArgument(Description = "Settle Date")] DateTime SettleDate, [ExcelArgument(Description = "Domestic Currency")] string DomesticCcy, [ExcelArgument(Description = "Foreign Currency")] string ForeignCcy, [ExcelArgument(Description = "Domestic Notional")] double DomesticNotional, [ExcelArgument(Description = "Strike")] double Strike, [ExcelArgument(Description = "Foreign Discount Curve")] string DiscountCurve, [ExcelArgument(Description = "Solve Curve name ")] string SolveCurve, [ExcelArgument(Description = "Solve Pillar Date")] object SolvePillarDate) { return(ExcelHelper.Execute(_logger, () => { var solvePillarDate = DateTime.FromOADate(SolvePillarDate.OptionalExcel(SettleDate.ToOADate())); ContainerStores.SessionContainer.GetService <ICalendarProvider>().Collection.TryGetCalendar(DomesticCcy, out var domesticCal); ContainerStores.SessionContainer.GetService <ICalendarProvider>().Collection.TryGetCalendar(ForeignCcy, out var foreignCal); var product = new FxForward { DomesticCCY = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(DomesticCcy), ForeignCCY = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(ForeignCcy), DomesticQuantity = DomesticNotional, DeliveryDate = SettleDate, ForeignDiscountCurve = DiscountCurve, SolveCurve = SolveCurve, PillarDate = solvePillarDate, Strike = Strike, TradeId = ObjectName }; return ExcelHelper.PushToCache(product, ObjectName); })); }
public override void Build(EngineFactory engineFactory) { Currency boughtCcy = Parsers.ParseCurrency(_boughtCurrency); Currency soldCcy = Parsers.ParseCurrency(_soldCurrency); Date maturityDate = Parsers.ParseDate(_maturityDate); //QL_REQUIRE(tradeActions().empty(), "TradeActions not supported for FxForward"); try { //DLOG("Build FxForward with maturity date " << QuantLib::io::iso_date(maturityDate)); QLNet.Instrument instrument = new FxForward(_boughtAmount, boughtCcy, _soldAmount, soldCcy, maturityDate, false); //instrument_.reset(new VanillaInstrument(instrument)); _npvCurrency = _soldCurrency; _notional = _soldAmount; _maturity = maturityDate; } catch (Exception ex) { //_instrument.reset(); throw; } SimpleCashFlow cf1 = new SimpleCashFlow(_boughtAmount, maturityDate); SimpleCashFlow cf2 = new SimpleCashFlow(_soldAmount, maturityDate); _legs = new List <List <CashFlow> >() { new List <CashFlow> { cf1, cf2 } }; _legCurrencies = new List <string> { _boughtCurrency, _soldCurrency }; _legPayers = new List <bool> { false, true }; // set Pricing engine EngineBuilder builder = engineFactory.Builder(_tradeType); QLNet.Utils.QL_REQUIRE(builder != null, () => "No builder found for " + _tradeType); FxForwardEngineBuilder fxBuilder = builder as FxForwardEngineBuilder; _instrument.setPricingEngine(fxBuilder.Engine(boughtCcy, soldCcy)); //DLOG("FxForward leg 0: " << legs_[0][0]->date() << " " << legs_[0][0]->amount()); //DLOG("FxForward leg 1: " << legs_[1][0]->date() << " " << legs_[1][0]->amount()); }
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); } } }
public static object CreateFxSwap( [ExcelArgument(Description = "Object name")] string ObjectName, [ExcelArgument(Description = "Value Date")] DateTime ValDate, [ExcelArgument(Description = "Tenor")] string Tenor, [ExcelArgument(Description = "Spot Price")] double SpotPrice, [ExcelArgument(Description = "Domestic Currency")] string DomesticCcy, [ExcelArgument(Description = "Foreign Currency")] string ForeignCcy, [ExcelArgument(Description = "Domestic Notional")] double DomesticNotional, [ExcelArgument(Description = "Swap Points")] double SwapPoints, [ExcelArgument(Description = "Foreign Discount Curve")] string DiscountCurve, [ExcelArgument(Description = "Solve Curve name ")] string SolveCurve, [ExcelArgument(Description = "Solve Pillar Date")] object SolvePillarDate, [ExcelArgument(Description = "Divisor, defualt 10,000")] object Divisor, [ExcelArgument(Description = "Spot lag, defualt 2b")] object SpotLag) { return(ExcelHelper.Execute(_logger, () => { var spotLag = SpotLag.OptionalExcel("2b"); var divisor = Divisor.OptionalExcel(10000.0); ContainerStores.SessionContainer.GetService <ICalendarProvider>().Collection.TryGetCalendar(DomesticCcy, out var domesticCal); ContainerStores.SessionContainer.GetService <ICalendarProvider>().Collection.TryGetCalendar(ForeignCcy, out var foreignCal); var domesticCCY = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(DomesticCcy); var foreignCCY = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(ForeignCcy); var pair = new FxPair() { Domestic = domesticCCY, Foreign = foreignCCY, SpotLag = new Frequency(spotLag), PrimaryCalendar = domesticCal, SecondaryCalendar = foreignCal }; var SettleDate = new DateTime(); var SolveDate = new DateTime(); var fwd = SpotPrice; switch (Tenor.ToUpper()) { case "ON": case "O/N": case "OVERNIGHT": SettleDate = ValDate.AddPeriod(RollType.F, domesticCal, 1.Bd()); SettleDate = SettleDate.IfHolidayRollForward(foreignCal); var swapProduct = new FxSwap(SwapPoints, ValDate, SettleDate, DomesticNotional, ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(DomesticCcy), ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(ForeignCcy)) { SolveCurve = SolveCurve, PillarDate = DateTime.FromOADate(SolvePillarDate.OptionalExcel(SettleDate.ToOADate())), }; return ExcelHelper.PushToCache(swapProduct, ObjectName); case "T/N": case "TN": SettleDate = pair.SpotDate(ValDate).SubtractPeriod(RollType.P, domesticCal, 1.Bd()); var startDate = SettleDate.IfHolidayRollBack(foreignCal); SolveDate = DateTime.FromOADate(SolvePillarDate.OptionalExcel(pair.SpotDate(ValDate).ToOADate())); fwd -= SwapPoints / divisor; break; default: SettleDate = pair.SpotDate(ValDate); var rt = Tenor.EndsWith("M") || Tenor.EndsWith("Y") ? RollType.MF : RollType.F; SettleDate = SettleDate.AddPeriod(rt, domesticCal, new Frequency(Tenor)); SettleDate = SettleDate.IfHolidayRollForward(foreignCal); fwd += SwapPoints / divisor; SolveDate = DateTime.FromOADate(SolvePillarDate.OptionalExcel(SettleDate.ToOADate()));; break; } var product = new FxForward { DomesticCCY = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(DomesticCcy), ForeignCCY = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(ForeignCcy), DomesticQuantity = DomesticNotional, DeliveryDate = SettleDate, ForeignDiscountCurve = DiscountCurve, SolveCurve = SolveCurve, PillarDate = SolveDate, Strike = fwd, TradeId = ObjectName }; return ExcelHelper.PushToCache(product, 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); }