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 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); }