Exemple #1
0
        public void ConstVol()
        {
            var constVolA       = 0.32;
            var constVolB       = 0.16;
            var originDate      = new DateTime(2017, 02, 21);
            var impliedSurfaceA = new ConstantVolSurface(originDate, constVolA)
            {
                AssetId = "A"
            };
            var impliedSurfaceB = new ConstantVolSurface(originDate, constVolB)
            {
                AssetId = "B"
            };

            var model = new AssetFxModel(originDate, null);

            model.AddVolSurface("A", impliedSurfaceA);
            model.AddVolSurface("B", impliedSurfaceB);

            var timesteps    = Enumerable.Range(1, 4).Select(x => x / 4.0).ToArray();
            var termCorrels  = new[] { 0.9, 0.85, 0.8, 0.75 };
            var correlVector = new CorrelationTimeVector("A", "B", termCorrels, timesteps);

            model.CorrelationMatrix = correlVector;

            var lc    = model.LocalCorrelationRaw(timesteps);
            var lcVec = lc.Select(x => x[0][0]).ToArray();

            for (var i = 0; i < termCorrels.Length; i++)
            {
                var expected = lcVec.Take(i + 1).Average();
                Assert.Equal(expected, termCorrels[i], 8);
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        public static void WriteModelToFile(AssetFxModel model, string fileName)
        {
            var tw = new StringWriter();
            var js = JsonSerializer.Create();
            var to = model.ToTransportObject();

            js.Serialize(tw, to);
            File.WriteAllText(fileName, tw.ToString());
        }
Exemple #5
0
        public void RoundTrip()
        {
            var aModel  = GetModel();
            var to      = aModel.ToTransportObject();
            var aModel2 = new AssetFxModel(to, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);

            Assert.Equal(aModel.GetPriceCurve("OIL").GetPriceForDate(ValDate.AddDays(100)), aModel2.GetPriceCurve("OIL").GetPriceForDate(ValDate.AddDays(100)));
            Assert.Equal(aModel.GetPriceCurve("OIL", zar).GetPriceForDate(ValDate.AddDays(100)), aModel2.GetPriceCurve("OIL", zar).GetPriceForDate(ValDate.AddDays(100)));
            Assert.Equal(aModel.GetCompositeVolForStrikeAndDate("OIL", ValDate.AddDays(100), 1000, zar), aModel2.GetCompositeVolForStrikeAndDate("OIL", ValDate.AddDays(100), 1000, zar));
        }
Exemple #6
0
        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));
        }
Exemple #7
0
        public void RoundTripViaProtoBuf()
        {
            var aModel = GetModel();
            var to     = aModel.ToTransportObject();
            var ms     = new MemoryStream();

            ProtoBuf.Serializer.Serialize(ms, to);
            //ms.Flush();
            ms.Seek(0, SeekOrigin.Begin);
            var to2     = ProtoBuf.Serializer.Deserialize <TO_AssetFxModel>(ms);
            var aModel2 = new AssetFxModel(to2, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);

            Assert.Equal(aModel.GetPriceCurve("OIL").GetPriceForDate(ValDate.AddDays(100)), aModel2.GetPriceCurve("OIL").GetPriceForDate(ValDate.AddDays(100)));
            Assert.Equal(aModel.GetPriceCurve("OIL", zar).GetPriceForDate(ValDate.AddDays(100)), aModel2.GetPriceCurve("OIL", zar).GetPriceForDate(ValDate.AddDays(100)));
            Assert.Equal(aModel.GetCompositeVolForStrikeAndDate("OIL", ValDate.AddDays(100), 1000, zar), aModel2.GetCompositeVolForStrikeAndDate("OIL", ValDate.AddDays(100), 1000, zar));
        }
Exemple #8
0
        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);
        }
Exemple #9
0
        public static object CreateAssetFxModel(
            [ExcelArgument(Description = "Object name")] string ObjectName,
            [ExcelArgument(Description = "Build date")] DateTime BuildDate,
            [ExcelArgument(Description = "Price curves")] object[] PriceCurves,
            [ExcelArgument(Description = "Vol surfaces")] object[] VolSurfaces,
            [ExcelArgument(Description = "Funding model")] object[] FundingModel,
            [ExcelArgument(Description = "Fixing dictionaries")] object[] Fixings,
            [ExcelArgument(Description = "Correlation matrix")] object[] CorrelationMatrix)
        {
            return(ExcelHelper.Execute(_logger, () =>
            {
                var curves = PriceCurves.GetAnyFromCache <IPriceCurve>();
                var fundingModel = FundingModel.GetAnyFromCache <IFundingModel>().First();
                var fixings = Fixings.GetAnyFromCache <IFixingDictionary>();
                var volSurfaces = VolSurfaces.GetAnyFromCache <IVolSurface>();
                var correlatinMatrix = CorrelationMatrix.GetAnyFromCache <ICorrelationMatrix>();

                var model = new AssetFxModel(BuildDate, fundingModel);

                foreach (var curve in curves)
                {
                    model.AddPriceCurve(curve.Name, curve);
                }
                foreach (var vs in volSurfaces)
                {
                    model.AddVolSurface(vs.Name, vs);
                }
                foreach (var f in fixings)
                {
                    model.AddFixingDictionary(f.Name, f);
                }

                if (correlatinMatrix.Any())
                {
                    model.CorrelationMatrix = correlatinMatrix.First();
                }

                return ExcelHelper.PushToCache <IAssetFxModel>(model, ObjectName);
            }));
        }
Exemple #10
0
        private AssetFxModel GetModel()
        {
            var vol = new ConstantVolSurface(valDate, assetVol)
            {
                AssetId = assetId,
                Name    = assetId
            };

            var fwd = new ConstantPriceCurve(assetPrice, valDate, TestProviderHelper.CurrencyProvider)
            {
                AssetId = assetId,
                Name    = assetId
            };
            var ir = new FlatIrCurve(0.0, usd, "USD");
            var fm = new FundingModel(valDate, new[] { ir }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);
            var am = new AssetFxModel(valDate, fm);

            am.AddPriceCurve(assetId, fwd);
            am.AddVolSurface(assetId, vol);

            return(am);
        }
Exemple #11
0
        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);
        }
Exemple #12
0
        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);
        }
Exemple #13
0
        //https://www.moodysanalytics.com/-/media/whitepaper/2014/2014-20-05-standardized-approach-for-capitalizing-counterparty-credit-risk-exposures.pdf
        //Example netting set #3
        public void MoodysTest1()
        {
            var usd       = TestProviderHelper.CurrencyProvider.GetCurrency("USD");
            var origin    = DateTime.Parse("2019-02-05");
            var zeroCurve = new ConstantRateIrCurve(0.0, origin, "zero", usd);
            var fm        = new FundingModel(origin, new[] { zeroCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);

            var model = new AssetFxModel(origin, fm);

            model.AddPriceCurve("Crude", new ConstantPriceCurve(100, origin, TestProviderHelper.CurrencyProvider));
            model.AddPriceCurve("Silver", new ConstantPriceCurve(10, origin, TestProviderHelper.CurrencyProvider));

            var assetToSetMap = new Dictionary <string, string>
            {
                { "Crude", "Energy" },
                { "Silver", "Metals" },
            };

            var tradeA = new Forward()
            {
                AssetId         = "Crude",
                ExpiryDate      = origin.AddDays(9 * 365 / 12.0),
                PaymentDate     = origin.AddDays(9 * 365 / 12.0),
                Notional        = 100000,
                Strike          = 100.5,
                PaymentCurrency = usd,
                DiscountCurve   = "zero",
                TradeId         = "tradeA"
            };
            var tradeB = new Forward()
            {
                AssetId         = "Crude",
                ExpiryDate      = origin.AddDays(2 * 365),
                PaymentDate     = origin.AddDays(2 * 365),
                Notional        = -200000,
                Strike          = 99.85,
                PaymentCurrency = usd,
                DiscountCurve   = "zero",
                TradeId         = "tradeB"
            };
            var tradeC = new Forward()
            {
                AssetId         = "Silver",
                ExpiryDate      = origin.AddDays(5 * 365),
                PaymentDate     = origin.AddDays(5 * 365),
                Notional        = 1000000,
                Strike          = 9.9,
                PaymentCurrency = usd,
                DiscountCurve   = "zero",
                TradeId         = "tradeC"
            };

            var pvA = tradeA.PV(model, false);
            var pvB = tradeB.PV(model, false);
            var pvC = tradeC.PV(model, false);

            var pf = new Portfolio()
            {
                Instruments = new List <IInstrument> {
                    tradeA, tradeB, tradeC
                }
            };
            var pvPf = pf.PV(model);

            Assert.Equal(20000.0, pvPf.GetAllRows().Sum(x => x.Value), 8);
            var epe = System.Math.Max(0, pvPf.SumOfAllRows);
            var ead = pf.SaCcrEAD(epe, model, usd, assetToSetMap);

            Assert.Equal(5408608, ead, 0);
        }
Exemple #14
0
        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);
        }
Exemple #15
0
        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);
        }
Exemple #16
0
        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);
        }
Exemple #17
0
        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);
        }