public void constructor_hasProperCurrencies_ifCurrencyIdsAreGiven() { //Arrange. injectMockedServiceToCurrency(); //Act. var pair = new FxPair(DEFAULT_ID, DEFAULT_SYMBOL, DEFAULT_BASE_CURRENCY_ID, DEFAULT_QUOTE_CURRENCY_ID); //Assert. Assert.AreSame(Currency.ById(DEFAULT_BASE_CURRENCY_ID), pair.GetBaseCurrency()); Assert.AreSame(Currency.ById(DEFAULT_QUOTE_CURRENCY_ID), pair.GetQuoteCurrency()); //Clear Currency.RestoreDefaultService(); }
public void Equals_returnFalse_forObjectOfOtherType() { //Arrange injectMockedServiceToCurrency(); //Act var baseObject = new FxPair(DEFAULT_ID, DEFAULT_SYMBOL, DEFAULT_BASE_CURRENCY_ID, DEFAULT_QUOTE_CURRENCY_ID); var comparedObject = new { Id = 1, Value = 2 }; bool areEqual = baseObject.Equals(comparedObject); //Assert Assert.IsFalse(areEqual); //Clear Currency.RestoreDefaultService(); }
public void ById_returnsTheSameInstance_afterAddingNewItem() { //Arrange Mock <ICurrencyService> mockService = new Mock <ICurrencyService>(); FxPair expectedPair = defaultFxPair(); mockService.Setup(c => c.GetFxPairById(DEFAULT_ID)).Returns(expectedPair); FxPair.injectService(mockService.Object); //Act FxPair pair1 = FxPair.ById(1); FxPair pair2 = FxPair.ById(1); //Assert Assert.AreSame(pair1, pair2); }
public void Equals_returnTrue_ifCurrenciesEqual() { //Arrange injectMockedServiceToCurrency(); //Act var baseObject = new FxPair(DEFAULT_ID, DEFAULT_SYMBOL, 1, 2); var comparedObject = new FxPair(DEFAULT_ID, DEFAULT_SYMBOL, 1, 2); bool areEqual = baseObject.Equals(comparedObject); //Assert Assert.IsTrue(areEqual); //Clear Currency.RestoreDefaultService(); }
public void Equals_returnFalse_ifSymbolDifferent() { //Arrange injectMockedServiceToCurrency(); //Act var baseObject = new FxPair(DEFAULT_ID, DEFAULT_SYMBOL, DEFAULT_BASE_CURRENCY_ID, DEFAULT_QUOTE_CURRENCY_ID); var comparedObject = new FxPair(DEFAULT_ID, DEFAULT_SYMBOL + 'a', DEFAULT_BASE_CURRENCY_ID, DEFAULT_QUOTE_CURRENCY_ID); bool areEqual = baseObject.Equals(comparedObject); //Assert Assert.IsFalse(areEqual); //Clear Currency.RestoreDefaultService(); }
public void Equals_returnFalse_ifQuoteCurrencyIsDifferent() { //Arrange injectMockedServiceToCurrency(); //Act var baseObject = new FxPair(DEFAULT_ID, DEFAULT_SYMBOL, 3, 1); var comparedObject = new FxPair(DEFAULT_ID, DEFAULT_SYMBOL, 3, 2); bool areEqual = baseObject.Equals(comparedObject); //Assert Assert.IsFalse(areEqual); //Clear Currency.RestoreDefaultService(); }
public void GetFilteredFxPairs_returnsProperCollection() { //Arrange Mock <ICurrencyService> mockService = new Mock <ICurrencyService>(); var expectedPairs = defaultFxPairsCollection(); mockService.Setup(c => c.GetFxPairs(It.IsAny <string>(), It.IsAny <int>())).Returns(expectedPairs); FxPair.injectService(mockService.Object); //Act. IEnumerable <FxPair> pairs = FxPair.GetFxPairs("a", 1); //Assert. bool areEqual = pairs.HasTheSameItems(expectedPairs); Assert.IsTrue(areEqual); }
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 GetFxPair_ReturnsAlwaysTheSameInstance() { //Arrange Mock <ICurrencyRepository> mockedRepository = mockedCurrencyRepositoryForFxPairUnitTests(); injectMockedServiceToCurrency(); //Act ICurrencyService service = testServiceInstance(mockedRepository); FxPair pair1 = service.GetFxPairById(DEFAULT_ID); FxPair pair2 = service.GetFxPairBySymbol(DEFAULT_PAIR_SYMBOL); //Assert Assert.AreSame(pair1, pair2); //Clear Currency.RestoreDefaultService(); }
public void GetFxPairBySymbol_ReturnsFxPair_IfExists() { //Arrange Mock <ICurrencyRepository> mockedRepository = mockedCurrencyRepositoryForFxPairUnitTests(); injectMockedServiceToCurrency(); //Act FxPair expectedPair = new FxPair(DEFAULT_ID, DEFAULT_PAIR_SYMBOL, DEFAULT_BASE_CURRENCY_ID, DEFAULT_QUOTE_CURRENCY_ID); ICurrencyService service = testServiceInstance(mockedRepository); FxPair pair = service.GetFxPairBySymbol(DEFAULT_PAIR_SYMBOL); //Assert Assert.AreEqual(expectedPair, pair); //Clear Currency.RestoreDefaultService(); }
public void constructor_newInstance_hasProperIdNameAndCurrencies() { //Arrange. injectMockedServiceToCurrency(); //Act. var baseCurrency = Currency.ById(DEFAULT_BASE_CURRENCY_ID); var quoteCurrency = Currency.ById(DEFAULT_QUOTE_CURRENCY_ID); var pair = new FxPair(DEFAULT_ID, DEFAULT_SYMBOL, baseCurrency, quoteCurrency); //Assert. Assert.AreEqual(DEFAULT_ID, pair.GetId()); Assert.AreEqual(DEFAULT_SYMBOL, pair.GetName()); Assert.AreSame(baseCurrency, pair.GetBaseCurrency()); Assert.AreSame(quoteCurrency, pair.GetQuoteCurrency()); //Clear Currency.RestoreDefaultService(); }
public static IAssetFxModel FxSpotShift(FxPair pair, double shiftSize, IAssetFxModel model) { var o = model.Clone(); if (pair.Domestic == model.FundingModel.FxMatrix.BaseCurrency) { var spot = model.FundingModel.FxMatrix.GetSpotRate(pair.Foreign); o.FundingModel.FxMatrix.SpotRates[pair.Foreign] = spot + shiftSize; } else if (pair.Foreign == model.FundingModel.FxMatrix.BaseCurrency) { var spot = model.FundingModel.FxMatrix.GetSpotRate(pair.Domestic); o.FundingModel.FxMatrix.SpotRates[pair.Domestic] = 1 / (1 / spot + shiftSize); } else { throw new Exception("Shifted FX pair must contain base currency of model"); } return(o); }
public void FxPairFact() { var z = new FxPair { Domestic = TestProviderHelper.CurrencyProvider.GetCurrency("USD"), Foreign = TestProviderHelper.CurrencyProvider.GetCurrency("ZAR"), SettlementCalendar = TestProviderHelper.CalendarProvider.Collection["NYC"], SpotLag = new Dates.Frequency("2d") }; var zz = new FxPair { Domestic = TestProviderHelper.CurrencyProvider.GetCurrency("ZAR"), Foreign = TestProviderHelper.CurrencyProvider.GetCurrency("USD"), SettlementCalendar = TestProviderHelper.CalendarProvider.Collection["NYC"], SpotLag = new Dates.Frequency("2d") }; Assert.False(z.Equals((object)"woooo")); Assert.False(z.Equals(zz)); Assert.True(z.Equals(z)); Assert.Equal(z.GetHashCode(), z.GetHashCode()); }
public void fxPair_fromDto_hasCorrectProperties() { //Arrange. injectMockedServiceToCurrency(); //Act. FxPairDto dto = new FxPairDto { Id = DEFAULT_ID, Name = DEFAULT_SYMBOL, BaseCurrency = DEFAULT_BASE_CURRENCY_ID, QuoteCurrency = DEFAULT_QUOTE_CURRENCY_ID, IsActive = DEFAULT_IS_ACTIVE }; var pair = FxPair.FromDto(dto); //Assert. Assert.AreEqual(DEFAULT_ID, pair.GetId()); Assert.AreEqual(DEFAULT_SYMBOL, pair.GetName()); Assert.AreSame(Currency.ById(1), pair.GetBaseCurrency()); Assert.AreSame(Currency.ById(2), pair.GetQuoteCurrency()); //Clear Currency.RestoreDefaultService(); }
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 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); }
public override FxSymbolsContainer ReadJson( JsonReader reader, Type objectType, FxSymbolsContainer existingValue, bool hasExistingValue, JsonSerializer serializer) { var container = JObject.Load(reader); if (!container.ContainsKey(CurrenciesName) || container[CurrenciesName] == null) { throw new InvalidOperationException("FX symbols json does not contain currencies."); } if (!container.ContainsKey(PairsName) || container[PairsName] == null) { throw new InvalidOperationException("FX symbols json does not contain currency pairs."); } var currencies = new Dictionary <string, FxCurrency>(); foreach (var token in container[CurrenciesName]) { var currency = token.ToObject <FxCurrency>(); if (currency != null) { currencies.Add(currency.Code, currency); } } var pairs = new List <FxPair>(); foreach (var token in container[PairsName]) { if (!token.HasValues) { continue; } var fromCurrencyCode = token.Value <string>("fromCurrency"); var toCurrencyCode = token.Value <string>("toCurrency"); var symbol = token.Value <string>("symbol"); if (string.IsNullOrWhiteSpace(fromCurrencyCode) || string.IsNullOrWhiteSpace(toCurrencyCode) || string.IsNullOrWhiteSpace(symbol)) { continue; } if (!currencies.TryGetValue(fromCurrencyCode, out var fromCurrency) || !currencies.TryGetValue(toCurrencyCode, out var toCurrency)) { continue; } var pair = new FxPair { FromCurrency = fromCurrency, ToCurrency = toCurrency, Symbol = symbol }; pairs.Add(pair); } return(new FxSymbolsContainer { Currencies = currencies.Values.ToList(), Pairs = pairs }); }
public static IPvModel FxSpotShift(FxPair pair, double shiftSize, IPvModel model) { var newVanillaModel = FxSpotShift(pair, shiftSize, model.VanillaModel); return(model.Rebuild(newVanillaModel, model.Portfolio)); }
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); })); }
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 void FixingsVolsCurvesFacts() { var fModel = new Mock <IFundingModel>(); var matrix = new Mock <IFxMatrix>(); var pair = new FxPair(); var dict = new Mock <IFixingDictionary>(); var surface = new Mock <IVolSurface>(); var surface2 = new Mock <IVolSurface>(); var surfaceFx = new Mock <IVolSurface>(); var curve = new Mock <IPriceCurve>(); curve.Setup(c => c.GetPriceForDate(DateTime.Today)).Returns(456.0); curve.Setup(c => c.GetPriceForFixingDate(DateTime.Today)).Returns(457.0); surface.Setup(s => s.AssetId).Returns("blah"); surface2.Setup(s => s.AssetId).Returns("blah2"); matrix.Setup(f => f.GetFxPair(It.IsAny <string>())).Returns(pair); fModel.Setup(f => f.GetFxRate(It.IsAny <DateTime>(), It.IsAny <Currency>(), It.IsAny <Currency>())).Returns(77.0); fModel.Setup(f => f.FxMatrix).Returns(matrix.Object); fModel.Setup(f => f.VolSurfaces).Returns(new Dictionary <string, IVolSurface> { { "bla/haa", surfaceFx.Object } }); var sut = new AssetFxModel(DateTime.Today, fModel.Object); sut.AddPriceCurve("blah", curve.Object); sut.AddPriceCurves(new Dictionary <string, IPriceCurve> { { "blah2", curve.Object } }); Assert.Same(curve.Object, sut.GetPriceCurve("blah")); Assert.Same(curve.Object, sut.GetPriceCurve("blah2")); sut.AddFixingDictionary("blah", dict.Object); sut.AddFixingDictionaries(new Dictionary <string, IFixingDictionary> { { "blah2", dict.Object } }); Assert.Same(dict.Object, sut.GetFixingDictionary("blah")); Assert.Same(dict.Object, sut.GetFixingDictionary("blah2")); Assert.False(sut.TryGetFixingDictionary("wooo", out var flob)); sut.AddVolSurface("blah", surface.Object); sut.AddVolSurfaces(new Dictionary <string, IVolSurface> { { "blah2", surface2.Object } }); Assert.Same(surface.Object, sut.GetVolSurface("blah")); Assert.Same(surface2.Object, sut.GetVolSurface("blah2")); sut.GetVolForStrikeAndDate("blah", DateTime.Today, 123); surface.Verify(s => s.GetVolForAbsoluteStrike(123, DateTime.Today, 456), Times.Once); sut.GetVolForDeltaStrikeAndDate("blah", DateTime.Today, 123); surface.Verify(s => s.GetVolForDeltaStrike(123, DateTime.Today, 457.0), Times.Once); sut.GetAverageVolForStrikeAndDates("blah", new[] { DateTime.Today }, 123); surface.Verify(s => s.GetVolForAbsoluteStrike(123, DateTime.Today, 456), Times.Exactly(2)); sut.GetAverageVolForMoneynessAndDates("blah", new[] { DateTime.Today }, 1.0); surface.Verify(s => s.GetVolForAbsoluteStrike(456, DateTime.Today, 456), Times.Exactly(2)); sut.GetFxVolForStrikeAndDate("bla/haa", DateTime.Today, 123); surfaceFx.Verify(s => s.GetVolForAbsoluteStrike(123, DateTime.Today, 77), Times.Once); sut.GetFxVolForDeltaStrikeAndDate("bla/haa", DateTime.Today, 123); surfaceFx.Verify(s => s.GetVolForDeltaStrike(123, DateTime.Today, 77), Times.Once); sut.OverrideBuildDate(DateTime.MinValue); Assert.Equal(DateTime.MinValue, sut.BuildDate); sut.OverrideBuildDate(DateTime.Today); }
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 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); }