Пример #1
0
        public static object CreateDiscountCurveFromCCRates(
            [ExcelArgument(Description = "Object name")] string ObjectName,
            [ExcelArgument(Description = "Curve name")] object CurveName,
            [ExcelArgument(Description = "Build date")] DateTime BuildDate,
            [ExcelArgument(Description = "Array of pillar dates")] double[] Pillars,
            [ExcelArgument(Description = "Array of CC zero rates")] double[] ZeroRates,
            [ExcelArgument(Description = "Type of interpolation")] object InterpolationType,
            [ExcelArgument(Description = "Currency - default USD")] object Currency,
            [ExcelArgument(Description = "Collateral Spec - default LIBOR.3M")] object CollateralSpec)
        {
            return(ExcelHelper.Execute(_logger, () =>
            {
                var curveName = CurveName.OptionalExcel(ObjectName);
                var curveTypeStr = InterpolationType.OptionalExcel("Linear");
                var ccyStr = Currency.OptionalExcel("USD");
                var colSpecStr = CollateralSpec.OptionalExcel("LIBOR.3M");

                if (!Enum.TryParse(curveTypeStr, out Interpolator1DType iType))
                {
                    return $"Could not parse interpolator type - {curveTypeStr}";
                }

                var pDates = Pillars.ToDateTimeArray();
                ContainerStores.SessionContainer.GetService <ICalendarProvider>().Collection.TryGetCalendar(ccyStr, out var ccyCal);
                var ccy = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>()[ccyStr];

                var cObj = new IrCurve(pDates, ZeroRates, BuildDate, curveName, iType, ccy, colSpecStr);
                var cache = ContainerStores.GetObjectCache <IIrCurve>();
                cache.PutObject(ObjectName, new SessionItem <IIrCurve> {
                    Name = ObjectName, Value = cObj
                });
                return ObjectName + '¬' + cache.GetObject(ObjectName).Version;
            }));
        }
Пример #2
0
        public static object CreateDiscountCurveFromRates(
            [ExcelArgument(Description = "Object name")] string ObjectName,
            [ExcelArgument(Description = "Curve name")] object CurveName,
            [ExcelArgument(Description = "Build date")] DateTime BuildDate,
            [ExcelArgument(Description = "Array of pillar dates")] double[] Pillars,
            [ExcelArgument(Description = "Array of rates")] double[] ZeroRates,
            [ExcelArgument(Description = "Rate type, e.g. CC or Linear")] object RateType,
            [ExcelArgument(Description = "Type of interpolation, e.g. CubicSpline or Linear")] object InterpolationType,
            [ExcelArgument(Description = "Currency - default USD")] object Currency,
            [ExcelArgument(Description = "Collateral Spec - default LIBOR.3M")] object CollateralSpec)
        {
            return(ExcelHelper.Execute(_logger, () =>
            {
                var curveName = CurveName.OptionalExcel(ObjectName);
                var ccyStr = Currency.OptionalExcel("USD");
                var colSpecStr = CollateralSpec.OptionalExcel("LIBOR.3M");

                if (!Enum.TryParse(InterpolationType.OptionalExcel("Linear"), out Interpolator1DType iType))
                {
                    return $"Could not parse interpolator type - {InterpolationType}";
                }

                if (!Enum.TryParse(RateType.OptionalExcel("CC"), out RateType rType))
                {
                    return $"Could not parse rate type - {RateType}";
                }

                var pDates = Pillars.ToDateTimeArray();
                ContainerStores.SessionContainer.GetService <ICalendarProvider>().Collection.TryGetCalendar(ccyStr, out var ccyCal);
                var ccy = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>().GetCurrency(ccyStr);

                var cObj = new IrCurve(pDates, ZeroRates, BuildDate, curveName, iType, ccy, colSpecStr, rType);
                return ExcelHelper.PushToCache <IIrCurve>(cObj, ObjectName);
            }));
        }
Пример #3
0
        public void StripCrackedCurveSimple()
        {
            var buildDate = new DateTime(2018, 07, 28);

            string[] periods = { "AUG18" };
            double[] strikes = { -10 };

            var cal = TestProviderHelper.CalendarProvider.Collection["LON"];
            var usd = TestProviderHelper.CurrencyProvider["USD"];

            var bPillars   = new[] { buildDate, buildDate.AddDays(100) };
            var brentCurve = new PriceCurve(buildDate, bPillars, new[] { 100.0, 100.0 }, PriceCurveType.Linear, TestProviderHelper.CurrencyProvider)
            {
                AssetId = "Brent"
            };

            var instruments = periods.Select((p, ix) =>
                                             (IAssetInstrument)AssetProductFactory.CreateTermAsianBasisSwap(p, strikes[ix], "Brent", "Sing180", cal, cal, cal, 0.Bd(), usd, 0.Bd(), 0.Bd(), 1000, 1000 / 6.35))
                              .ToList();
            var pillars = instruments.Select(x => ((AsianBasisSwap)x).RecSwaplets.Max(sq => sq.AverageEndDate)).ToList();

            DateTime[] dPillars      = { buildDate, buildDate.AddDays(1000) };
            double[]   dRates        = { 0, 0 };
            var        discountCurve = new IrCurve(dPillars, dRates, buildDate, "zeroDiscount", Interpolator1DType.LinearFlatExtrap, usd);

            var s     = new Calibrators.NewtonRaphsonAssetBasisCurveSolver(TestProviderHelper.CurrencyProvider);
            var curve = s.SolveCurve(instruments, pillars, discountCurve, brentCurve, buildDate, PriceCurveType.Linear);

            Assert.Equal((100.0 - 10.0) * 6.35, curve.GetPriceForDate(buildDate));
            Assert.Equal((100.0 - 10.0) * 6.35, curve.GetPriceForDate(buildDate.AddDays(50)));
        }
Пример #4
0
        public Dictionary <string, IrCurve> ImplyContainedCurves(DateTime buildDate, Interpolator1DType interpType)
        {
            var o = new Dictionary <string, IrCurve>();

            foreach (var curveName in SolveCurves)
            {
                var pillars = this.Where(x => x.SolveCurve == curveName)
                              .Select(x => x.PillarDate)
                              .OrderBy(x => x)
                              .ToArray();
                if (pillars.Distinct().Count() != pillars.Count())
                {
                    throw new Exception($"More than one instrument has the same solve pillar on curve {curveName}");
                }

                var dummyRates = pillars.Select(x => 0.05).ToArray();
                var ccy        = _currencyProvider.GetCurrency(curveName.Split('.')[0]);
                var colSpec    = (curveName.Contains("[")) ? curveName.Split('[').Last().Trim("[]".ToCharArray()) : curveName.Split('.').Last();
                if (o.Values.Any(v => v.CollateralSpec == colSpec))
                {
                    colSpec = colSpec + "_" + curveName;
                }

                var irCurve = new IrCurve(pillars, dummyRates, buildDate, curveName, interpType, ccy, colSpec);
                o.Add(curveName, irCurve);
            }
            return(o);
        }
Пример #5
0
        public void LessComplexCurve()
        {
            var startDate     = new DateTime(2016, 05, 20);
            var depoTenors    = new Frequency[] { 3.Months() };
            var OISdepoTenors = new Frequency[] { 1.Bd() };

            double[] depoPricesZAR = { 0.06 };

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

            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 ZARpillarDates3m   = ZARpillarDatesDepo.Union(ZARpillarDatesFRA).Distinct().OrderBy(x => x).ToArray();



            var ZARdepos = new IrSwap[depoTenors.Length];
            var ZARFRAs  = new ForwardRateAgreement[FRATenors.Length];

            var FIC = new FundingInstrumentCollection();

            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.JIBAR.3M")
                {
                    SolveCurve = "ZAR.JIBAR.3M"
                };
                FIC.Add(ZARFRAs[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.JIBAR.3M")
                {
                    SolveCurve = "ZAR.JIBAR.3M"
                };
                FIC.Add(ZARdepos[i]);
            }



            var ZARcurve3m = new IrCurve(ZARpillarDates3m, new double[ZARpillarDates3m.Length], startDate, "ZAR.JIBAR.3M", Interpolator1DType.LinearFlatExtrap)
            {
                SolveStage = 0
            };

            var engine = new FundingModel(startDate, new IrCurve[] { ZARcurve3m });

            var S = new NewtonRaphsonMultiCurveSolverStagedWithAnalyticJacobian();

            //var S = new NewtonRaphsonMultiCurveSolverStaged();
            S.Solve(engine, FIC);

            foreach (var ins in FIC)
            {
                var pv = ins.Pv(engine, false);
                Assert.Equal(0.0, pv, 7);
            }
        }
Пример #6
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);
        }
Пример #7
0
        public void OISFuture()
        {
            var bd       = DateTime.Today;
            var pillars  = new[] { bd, bd.AddDays(1000) };
            var flatRate = 0.05;
            var rates    = pillars.Select(p => flatRate).ToArray();

            CalendarProvider.Collection.TryGetCalendar("LON", out var cal);
            var usd        = TestProviderHelper.CurrencyProvider["USD"];
            var discoCurve = new IrCurve(pillars, rates, bd, "USD.BLAH", Interpolator1DType.Linear, usd);
            var fModel     = new FundingModel(bd, new[] { discoCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);
            var price      = 93.0;
            var ix         = new FloatRateIndex
            {
                Currency         = usd,
                DayCountBasis    = DayCountBasis.ACT360,
                FixingOffset     = 2.Bd(),
                HolidayCalendars = cal,
                ResetTenor       = 3.Months(),
                RollConvention   = RollType.MF
            };

            var maturity     = bd.AddDays(365);
            var accrualStart = maturity.AddPeriod(RollType.F, ix.HolidayCalendars, ix.FixingOffset);
            var accrualEnd   = accrualStart.AddPeriod(ix.RollConvention, ix.HolidayCalendars, ix.ResetTenor);
            var dcf          = maturity.CalculateYearFraction(accrualEnd, DayCountBasis.ACT360);
            var s            = new OISFuture
            {
                Currency         = usd,
                ContractSize     = 1e6,
                Position         = 1,
                DCF              = dcf,
                AverageStartDate = accrualStart,
                AverageEndDate   = accrualEnd,
                ForecastCurve    = "USD.BLAH",
                Price            = price,
                Index            = ix
            };

            var pv        = s.Pv(fModel, false);
            var rateEst   = discoCurve.GetForwardRate(accrualStart, accrualEnd, RateType.Linear, ix.DayCountBasis);
            var fairPrice = 100.0 - rateEst * 100;

            var expectedPv = (price - fairPrice) * 1e6 * dcf;

            Assert.Equal(expectedPv, pv);

            var ss = s.Sensitivities(fModel);

            Assert.True(ss.Count == 1 && ss.Keys.Single() == "USD.BLAH");
            Assert.True(ss["USD.BLAH"].Count == 2 && ss["USD.BLAH"].Keys.Contains(accrualStart) && ss["USD.BLAH"].Keys.Contains(accrualEnd));

            Assert.Equal(accrualEnd, s.LastSensitivityDate);
            Assert.Empty(s.Dependencies(null));

            var s2 = (OISFuture)s.SetParRate(97);

            Assert.Equal(97, s2.Price);
        }
Пример #8
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);
        }
Пример #9
0
        public void IrSwap()
        {
            var bd         = DateTime.Parse("2018-09-13");
            var pillars    = new[] { bd, bd.AddDays(1000) };
            var flatRate   = 0.05;
            var rates      = pillars.Select(p => flatRate).ToArray();
            var usd        = TestProviderHelper.CurrencyProvider["USD"];
            var discoCurve = new IrCurve(pillars, rates, bd, "USD.BLAH", Interpolator1DType.Linear, usd);
            var fModel     = new FundingModel(bd, new[] { discoCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);

            CalendarProvider.Collection.TryGetCalendar("LON", out var cal);

            var ix = new FloatRateIndex
            {
                Currency           = usd,
                DayCountBasis      = DayCountBasis.ACT360,
                DayCountBasisFixed = DayCountBasis.ACT360,
                FixingOffset       = 2.Bd(),
                HolidayCalendars   = cal,
                ResetTenor         = 3.Months(),
                ResetTenorFixed    = 3.Months(),
                RollConvention     = RollType.MF
            };


            var parRate   = 0.05;
            var notional  = 100e6;
            var startDate = bd.AddPeriod(RollType.F, cal, 2.Bd());
            var maturity  = startDate.AddDays(365);
            var swp       = new IrSwap(startDate, 1.Years(), ix, parRate, SwapPayReceiveType.Pay, "USD.BLAH", "USD.BLAH")
            {
                Notional = notional, RateIndex = ix
            };

            var pv = swp.Pv(fModel, true);

            Assert.Equal(-368.89651349, pv, 8);

            swp = new IrSwap(startDate, 1.Years(), ix, parRate + 0.01, SwapPayReceiveType.Pay, "USD.BLAH", "USD.BLAH")
            {
                Notional = notional, RateIndex = ix
            };
            pv = swp.Pv(fModel, true);
            Assert.Equal(-10217.8229952, pv, 8);

            Assert.Equal(swp.EndDate, swp.LastSensitivityDate);

            var d = swp.Dependencies(null);

            Assert.Single(d);

            Assert.Equal(0.0496254169169585, swp.CalculateParRate(fModel), 10);
            Assert.Equal(0.09, (swp.SetParRate(0.09) as IrSwap).ParRate);

            Assert.Equal(1.0, swp.SupervisoryDelta(null));
            Assert.Equal(1.0, swp.MaturityBucket(startDate));
        }
Пример #10
0
        public void BasicSelfDiscounting()
        {
            var startDate  = new DateTime(2016, 05, 20);
            var swapTenor2 = new Frequency("2y");
            var jhb        = TestProviderHelper.CalendarProvider.Collection["JHB"];

            var pillarDate     = startDate.AddPeriod(RollType.MF, jhb, 1.Years());
            var pillarDate2    = startDate.AddPeriod(RollType.MF, jhb, swapTenor2);
            var pillarDateDepo = startDate.AddPeriod(RollType.MF, jhb, 3.Months());

            var ccyZar = TestProviderHelper.CurrencyProvider["JHB"];

            var zar3m = new FloatRateIndex()
            {
                Currency           = ccyZar,
                DayCountBasis      = DayCountBasis.Act_365F,
                DayCountBasisFixed = DayCountBasis.Act_365F,
                ResetTenor         = 3.Months(),
                FixingOffset       = 0.Bd(),
                HolidayCalendars   = jhb,
                RollConvention     = RollType.MF
            };

            var swap  = new IrSwap(startDate, 1.Years(), zar3m, 0.06, SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.JIBAR.3M");
            var swap2 = new IrSwap(startDate, swapTenor2, zar3m, 0.06, SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.JIBAR.3M");
            var depo  = new IrSwap(startDate, 3.Months(), zar3m, 0.06, SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.JIBAR.3M");

            var fic = new FundingInstrumentCollection(TestProviderHelper.CurrencyProvider)
            {
                swap,
                swap2,
                depo
            };
            var curve = new IrCurve(new [] { pillarDateDepo, pillarDate, pillarDate2 }, new double[3], startDate, "ZAR.JIBAR.3M", Interpolator1DType.LinearFlatExtrap, ccyZar);
            var model = new FundingModel(startDate, new[] { curve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);

            var s = new Calibrators.NewtonRaphsonMultiCurveSolver();

            if (IsCoverageOnly)
            {
                s.Tollerance = 1;
            }

            s.Solve(model, fic);

            var resultSwap1 = swap.Pv(model, false);
            var resultSwap2 = swap2.Pv(model, false);
            var resultDepo  = depo.Pv(model, false);

            if (!IsCoverageOnly)
            {
                Assert.Equal(0, resultSwap1, 6);
                Assert.Equal(0, resultSwap2, 6);
                Assert.Equal(0, resultDepo, 6);
            }
        }
Пример #11
0
        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);
        }
Пример #12
0
        public static IrCurve StripFxBasisCurve(string cmeFwdFileName, FxPair ccyPair, string cmePair, Currency curveCcy, string curveName, DateTime valDate, IrCurve baseCurve, ICurrencyProvider currencyProvider, ICalendarProvider calendarProvider)
        {
            var fwdsDict = GetFwdFxRatesFromFwdFile(cmeFwdFileName, new Dictionary <string, string> {
                { ccyPair.ToString(), cmePair }
            });
            var bc = baseCurve.Clone();

            bc.SolveStage = -1;
            var fwds     = fwdsDict[ccyPair.ToString()];
            var spotDate = ccyPair.SpotDate(valDate);
            var spotRate = fwds[spotDate];

            fwds = Downsample(fwds, spotDate, ccyPair.PrimaryCalendar);

            var fwdObjects = fwds.Select(x => new FxForward
            {
                DomesticCCY          = ccyPair.Domestic,
                DeliveryDate         = x.Key,
                DomesticQuantity     = 1e6,
                ForeignCCY           = ccyPair.Foreign,
                PillarDate           = x.Key,
                SolveCurve           = curveName,
                Strike               = x.Value,
                ForeignDiscountCurve = ccyPair.Foreign == curveCcy ? curveName : baseCurve.Name,
            });

            var fic = new FundingInstrumentCollection(currencyProvider);

            fic.AddRange(fwdObjects);
            var pillars  = fwds.Keys.OrderBy(x => x).ToArray();
            var curve    = new IrCurve(pillars, pillars.Select(p => 0.01).ToArray(), valDate, curveName, Interpolator1DType.Linear, curveCcy);
            var fm       = new FundingModel(valDate, new[] { curve, bc }, currencyProvider, calendarProvider);
            var matrix   = new FxMatrix(currencyProvider);
            var discoMap = new Dictionary <Currency, string> {
                { curveCcy, curveName }, { baseCurve.Currency, baseCurve.Name }
            };

            matrix.Init(ccyPair.Domestic, valDate, new Dictionary <Currency, double> {
                { ccyPair.Foreign, spotRate }
            }, new List <FxPair> {
                ccyPair
            }, discoMap);
            fm.SetupFx(matrix);
            var solver = new NewtonRaphsonMultiCurveSolverStaged()
            {
                InLineCurveGuessing = true
            };

            solver.Solve(fm, fic);

            return(curve);
        }
Пример #13
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));
        }
Пример #14
0
        public double Pv(IrCurve discountCurve, IrCurve forecastCurve, bool updateState, bool updateDF, bool updateEstimate)
        {
            var totalPV = 0.0;

            if (FlowScheduleFra.Flows.Count != 1)
            {
                throw new InvalidOperationException("FRA should have a sinlge flow");
            }

            var flow = FlowScheduleFra.Flows.Single();

            var s = flow.AccrualPeriodStart;
            var e = flow.AccrualPeriodEnd;

            double FV, DF;

            if (updateEstimate)
            {
                var RateFix   = flow.FixedRateOrMargin;
                var RateFloat = forecastCurve.GetForwardRate(s, e, RateType.Linear, Basis);
                var YF        = flow.NotionalByYearFraction;
                FV = ((RateFloat - RateFix) * YF) / (1 + RateFloat * YF) * flow.Notional;

                FV *= (PayRec == SwapPayReceiveType.Payer) ? 1.0 : -1.0;
            }
            else
            {
                FV = flow.Fv;
            }

            if (updateDF)
            {
                DF = discountCurve.Pv(1.0, flow.SettleDate);
            }
            else
            {
                DF = flow.Pv / flow.Fv;
            }

            totalPV = discountCurve.Pv(FV, flow.SettleDate);

            if (!updateState)
            {
                return(totalPV);
            }
            flow.Fv = FV;
            flow.Pv = totalPV;
            return(totalPV);
        }
Пример #15
0
        public static IrCurve StripFxBasisCurve(string cmeFwdFileName, string ccyPair, Currency curveCcy, string curveName, DateTime valDate, IIrCurve baseCurve)
        {
            var fwds = GetFwdFxRatesFromFwdFile(cmeFwdFileName, ccyPair);
            var dfs  = fwds.ToDictionary(f => f.Key, f => fwds[valDate] / f.Value * baseCurve.GetDf(valDate, f.Key));

            if (ccyPair.EndsWith("USD")) //flip dfs
            {
                dfs = dfs.ToDictionary(x => x.Key, x => 1.0 / x.Value);
            }
            var pillars   = dfs.Keys.OrderBy(k => k).ToArray();
            var dfsValues = pillars.Select(p => dfs[p]).ToArray();
            var curve     = new IrCurve(pillars, dfsValues, valDate, curveName, Interpolator1DType.Linear, curveCcy, null, RateType.DF);

            return(curve);
        }
Пример #16
0
        public static object CreateDiscountCurveFromDFs(
            [ExcelArgument(Description = "Object name")] string ObjectName,
            [ExcelArgument(Description = "Curve name")] object CurveName,
            [ExcelArgument(Description = "Build date")] DateTime BuildDate,
            [ExcelArgument(Description = "Array of pillar dates")] double[] Pillars,
            [ExcelArgument(Description = "Array of discount factors")] double[] DiscountFactors,
            [ExcelArgument(Description = "Type of interpolation")] object InterpolationType,
            [ExcelArgument(Description = "Currency - default USD")] object Currency,
            [ExcelArgument(Description = "Collateral Spec - default LIBOR.3M")] object CollateralSpec,
            [ExcelArgument(Description = "Rate storage format - default Exponential")] object RateStorageType)
        {
            return(ExcelHelper.Execute(_logger, () =>
            {
                var curveName = CurveName.OptionalExcel(ObjectName);
                var curveTypeStr = InterpolationType.OptionalExcel("Linear");
                var ccyStr = Currency.OptionalExcel("USD");
                var colSpecStr = CollateralSpec.OptionalExcel("LIBOR.3M");
                var rateTypeStr = RateStorageType.OptionalExcel("CC");

                if (!Enum.TryParse(curveTypeStr, out Interpolator1DType iType))
                {
                    return $"Could not parse interpolator type - {curveTypeStr}";
                }

                if (!Enum.TryParse(rateTypeStr, out RateType rType))
                {
                    return $"Could not parse rate type - {rateTypeStr}";
                }

                var pDates = Pillars.ToDateTimeArray();
                ContainerStores.SessionContainer.GetService <ICalendarProvider>().Collection.TryGetCalendar(ccyStr, out var ccyCal);
                var ccy = ContainerStores.GlobalContainer.GetRequiredService <ICurrencyProvider>()[ccyStr];

                var zeroRates = DiscountFactors
                                .Select((df, ix) =>
                                        DateTime.FromOADate(Pillars[ix]) == BuildDate ? 0.0
                    : IrCurve.RateFromDF(BuildDate.CalculateYearFraction(DateTime.FromOADate(Pillars[ix]), DayCountBasis.ACT365F), df, rType))
                                .ToArray();

                if (DateTime.FromOADate(Pillars[0]) == BuildDate && zeroRates.Length > 1)
                {
                    zeroRates[0] = zeroRates[1];
                }

                var cObj = new IrCurve(pDates, zeroRates, BuildDate, curveName, iType, ccy, colSpecStr, rType);
                return ExcelHelper.PushToCache <IIrCurve>(cObj, ObjectName);
            }));
        }
Пример #17
0
        public void StripCrackedCurve()
        {
            var buildDate = new DateTime(2018, 07, 28);

            string[] futures       = { "COV8", "COX8", "COZ8", "COF9", "COG9" };
            double[] futuresPrices = { 77, 78, 79, 79.5, 79.75 };
            string[] periods       = { "AUG18", "SEP18", "OCT18", "NOV18" };
            double[] strikes       = { -10, -11, -12, -13 };

            var cal = TestProviderHelper.CalendarProvider.Collection["LON"];
            var usd = TestProviderHelper.CurrencyProvider["USD"];

            var bPillars   = futures.Select(x => FutureCode.GetExpiryFromCode(x, TestProviderHelper.FutureSettingsProvider)).ToArray();
            var brentCurve = new PriceCurve(buildDate, bPillars, futuresPrices, PriceCurveType.ICE, TestProviderHelper.CurrencyProvider, futures)
            {
                AssetId = "Brent"
            };


            var instruments = periods.Select((p, ix) =>
                                             (IAssetInstrument)AssetProductFactory.CreateTermAsianBasisSwap(p, strikes[ix], "Brent", "Sing180", cal, cal, cal, 0.Bd(), usd, 0.Bd(), 0.Bd(), 1000, 1000 / 6.35))
                              .ToList();
            var pillars = instruments.Select(x => ((AsianBasisSwap)x).RecSwaplets.Max(sq => sq.AverageEndDate)).ToList();

            DateTime[] dPillars      = { buildDate, buildDate.AddDays(1000) };
            double[]   dRates        = { 0, 0 };
            var        discountCurve = new IrCurve(dPillars, dRates, buildDate, "zeroDiscount", Interpolator1DType.LinearFlatExtrap, usd);

            var s = new Calibrators.NewtonRaphsonAssetBasisCurveSolver(TestProviderHelper.CurrencyProvider);

            if (IsCoverageOnly)
            {
                s.Tollerance = 1.0;
            }

            var curve = s.SolveCurve(instruments, pillars, discountCurve, brentCurve, buildDate, PriceCurveType.ICE);

            if (!IsCoverageOnly)
            {
                for (var i = 0; i < instruments.Count; i++)
                {
                    var resultPV = Calibrators.NewtonRaphsonAssetBasisCurveSolver.BasisSwapPv(curve, instruments[i], discountCurve, brentCurve);
                    Assert.Equal(0, resultPV, 6);
                }
            }
        }
Пример #18
0
        public static IrCurve GetCurveForCode(string cmeId, string cmeFilename, string qwackCode, string curveName, Dictionary <string, FloatRateIndex> indices, Dictionary <string, string> curves, IFutureSettingsProvider futureSettingsProvider, ICurrencyProvider currencyProvider, ICalendarProvider calendarProvider)
        {
            var parsed      = CMEFileParser.Parse(cmeFilename).Where(r => r.ID == cmeId && r.SecTyp == "FUT");
            var q           = parsed.ToDictionary(x => DateTime.ParseExact(x.MatDt, "yyyy-MM-dd", CultureInfo.InvariantCulture), x => x.SettlePrice);
            var origin      = DateTime.ParseExact(parsed.First().BizDt, "yyyy-MM-dd", CultureInfo.InvariantCulture);
            var instruments = parsed.Select(p => ToQwackIns(p, qwackCode, futureSettingsProvider, currencyProvider, indices, curves)).ToList();
            var pillars     = instruments.Select(x => x.PillarDate).OrderBy(x => x).ToArray();
            var fic         = new FundingInstrumentCollection(currencyProvider);

            fic.AddRange(instruments);
            var curve = new IrCurve(pillars, pillars.Select(p => 0.01).ToArray(), origin, curveName, Interpolator1DType.Linear, currencyProvider.GetCurrency("USD"));
            var fm    = new FundingModel(origin, new[] { curve }, currencyProvider, calendarProvider);

            var solver = new NewtonRaphsonMultiCurveSolverStaged();

            solver.Solve(fm, fic);
            return(curve);
        }
Пример #19
0
        public void IrCurveConversionFacts()
        {
            Assert.Equal(1.0, IrCurve.DFFromRate(0.0, 0.1, RateType.Annual));
            Assert.Equal(1.0, IrCurve.DFFromRate(0.0, 0.1, RateType.CC));
            Assert.Equal(1.0, IrCurve.DFFromRate(0.0, 0.1, RateType.Linear));
            Assert.Equal(1.0, IrCurve.DFFromRate(0.0, 0.1, RateType.SemiAnnual));
            Assert.Equal(1.0, IrCurve.DFFromRate(0.0, 0.1, RateType.Quarterly));
            Assert.Equal(1.0, IrCurve.DFFromRate(0.0, 0.1, RateType.Monthly));
            Assert.Equal(0.1, IrCurve.DFFromRate(0.0, 0.1, RateType.DiscountFactor));

            Assert.Equal(0.0, IrCurve.RateFromDF(1.0, 1.0, RateType.Annual));
            Assert.Equal(0.0, IrCurve.RateFromDF(1.0, 1.0, RateType.CC));
            Assert.Equal(0.0, IrCurve.RateFromDF(1.0, 1.0, RateType.Linear));
            Assert.Equal(0.0, IrCurve.RateFromDF(1.0, 1.0, RateType.SemiAnnual));
            Assert.Equal(0.0, IrCurve.RateFromDF(1.0, 1.0, RateType.Quarterly));
            Assert.Equal(0.0, IrCurve.RateFromDF(1.0, 1.0, RateType.Monthly));
            Assert.Equal(1.0, IrCurve.RateFromDF(1.0, 1.0, RateType.DiscountFactor));
        }
Пример #20
0
        public void PastStartingFixedRateLoanDepo()
        {
            var bd         = DateTime.Today;
            var pillars    = new[] { bd, bd.AddDays(1000) };
            var flatRate   = 0.05;
            var rates      = pillars.Select(p => flatRate).ToArray();
            var usd        = TestProviderHelper.CurrencyProvider["USD"];
            var discoCurve = new IrCurve(pillars, rates, bd, "USD.BLAH", Interpolator1DType.Linear, usd);
            var fModel     = new FundingModel(bd, new[] { discoCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);

            var start    = bd.AddDays(-10);
            var maturity = bd.AddDays(365);
            var notional = 100e6;
            var iRate    = 0.07;

            var depo = new FixedRateLoanDeposit(start, maturity, iRate, usd, DayCountBasis.ACT360, notional, "USD.BLAH");

            var pv = depo.Pv(fModel, false);

            var dfEnd      = discoCurve.GetDf(bd, maturity);
            var t          = start.CalculateYearFraction(maturity, DayCountBasis.ACT360);
            var expectedPv = 0.0;                          //initial notional is in the past

            expectedPv += -notional * dfEnd;               //final notional
            expectedPv += -notional * (iRate * t) * dfEnd; //final notional
            Assert.Equal(expectedPv, pv, 8);


            var loan = new FixedRateLoanDeposit(start, maturity, iRate, usd, DayCountBasis.ACT360, -notional, "USD.BLAH");

            pv = loan.Pv(fModel, false);

            expectedPv  = 0.0;                            //initial notional is in the past
            expectedPv += notional * dfEnd;               //final notional
            expectedPv += notional * (iRate * t) * dfEnd; //final notional
            Assert.Equal(expectedPv, pv, 8);
        }
Пример #21
0
        public void StripCoalSparse()
        {
            var startDate = new DateTime(2018, 07, 28);

            string[] periods = { "AUG18", "SEP18", "Q4-18", "Q1-19", "Q2-19", "H2-19", "CAL-20", "CAL-21" };
            double[] strikes = { 100, 99, 98, 97, 96, 95, 94, 93 };

            var cal = TestProviderHelper.CalendarProvider.Collection["LON"];

            var xaf = TestProviderHelper.CurrencyProvider["XAF"];


            var instruments = periods.Select((p, ix) =>
                                             AssetProductFactory.CreateMonthlyAsianSwap(p, strikes[ix], "coalXXX", cal, cal, 0.Bd(), xaf, TradeDirection.Long, 0.Bd(), 1, DateGenerationType.Fridays)
                                             ).ToList();
            var pillars = instruments.Select(x => x.Swaplets.Max(sq => sq.AverageEndDate)).ToList();

            DateTime[] dPillars      = { startDate, startDate.AddDays(1000) };
            double[]   dRates        = { 0, 0 };
            var        discountCurve = new IrCurve(dPillars, dRates, startDate, "zeroDiscount", Interpolator1DType.LinearFlatExtrap, xaf);

            var s = new NewtonRaphsonAssetCurveSolver()
            {
                Tollerance = IsCoverageOnly ? 1 : 0.00000001
            };
            var curve = s.Solve(instruments, pillars, discountCurve, startDate, TestProviderHelper.CurrencyProvider);

            if (!IsCoverageOnly)
            {
                for (var i = 0; i < instruments.Count; i++)
                {
                    var resultPV = NewtonRaphsonAssetCurveSolver.SwapPv(curve, instruments[i], discountCurve);
                    Assert.Equal(0, resultPV, 6);
                }
            }
        }
Пример #22
0
        public void ZeroBond()
        {
            var bd         = DateTime.Today;
            var pillars    = new[] { bd, bd.AddDays(1000) };
            var flatRate   = 0.05;
            var rates      = pillars.Select(p => flatRate).ToArray();
            var usd        = TestProviderHelper.CurrencyProvider["USD"];
            var discoCurve = new IrCurve(pillars, rates, bd, "USD.BLAH", Interpolator1DType.Linear, usd);
            var fModel     = new FundingModel(bd, new[] { discoCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);
            var price      = 0.93;
            var notional   = 100e6;
            var maturity   = bd.AddDays(365);
            var b          = new ZeroBond(price, bd.AddDays(365), "USD.BLAH")
            {
                Notional = notional
            };
            var t = bd.CalculateYearFraction(maturity, DayCountBasis.Act365F);

            var pv         = b.Pv(fModel, false);
            var expectedPv = (Exp(-flatRate * t) - price) * notional;

            Assert.Equal(expectedPv, pv);

            var s = b.Sensitivities(fModel);

            Assert.True(s.Count == 1 && s.Keys.Single() == "USD.BLAH");
            Assert.True(s["USD.BLAH"].Count == 1 && s["USD.BLAH"].Single().Key == maturity);
            Assert.Equal(-t * notional * Exp(-flatRate * t), s["USD.BLAH"][maturity]);

            Assert.Equal(maturity, b.LastSensitivityDate);
            Assert.Empty(b.Dependencies(null));
            Assert.Equal(Exp(-flatRate * t), b.CalculateParRate(fModel));
            var b2 = (ZeroBond)b.SetParRate(0.99);

            Assert.Equal(0.99, b2.Price);
        }
Пример #23
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);
        }
Пример #24
0
        public void BasicOisCurveSolving()
        {
            var startDate  = new DateTime(2016, 05, 20);
            var depoTenors = new Frequency[] { 3.Months() };

            double[] depoPrices = { 0.06 };
            string[] FRATenors  = { "3x6", "6x9", "9x12" };
            double[] FRAPrices  = { 0.065, 0.07, 0.075 };
            var      swapTenors = new Frequency[] { 18.Months(), 2.Years(), 3.Years(), 4.Years(), 5.Years(), 7.Years(), 10.Years(), 15.Years(), 20.Years() };

            double[] swapPrices = { 0.075, 0.08, 0.085, 0.09, 0.095, 0.0975, 0.098, 0.099, 0.1 };
            var      oisTenors  = new Frequency[] { 3.Months(), 6.Months(), 1.Years(), 2.Years(), 3.Years(), 4.Years(), 5.Years(), 7.Years(), 10.Years(), 15.Years(), 20.Years() };
            var      oisPrices  = new double[] { 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004, 0.004 };

            var pillarDatesDepo = depoTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray();
            var pillarDatesFRA  = FRATenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, new Frequency(x.Split('x')[1] + "M"))).ToArray();
            var pillarDatesSwap = swapTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray();
            var pillarDates3m   = pillarDatesDepo.Union(pillarDatesSwap).Union(pillarDatesFRA).Distinct().OrderBy(x => x).ToArray();
            var pillarDatesOIS  = oisTenors.Select(x => startDate.AddPeriod(RollType.MF, JHB, x)).ToArray();

            var swaps    = new IrSwap[swapTenors.Length];
            var depos    = new IrSwap[depoTenors.Length];
            var oisSwaps = new IrBasisSwap[oisTenors.Length];
            var FRAs     = new ForwardRateAgreement[FRATenors.Length];

            var fic = new FundingInstrumentCollection(TestProviderHelper.CurrencyProvider);

            for (var i = 0; i < FRAs.Length; i++)
            {
                FRAs[i] = new ForwardRateAgreement(startDate, FRATenors[i], FRAPrices[i], _zar3m, SwapPayReceiveType.Payer, FraDiscountingType.Isda, "ZAR.JIBAR.3M", "ZAR.OIS.1B");
                fic.Add(FRAs[i]);
            }

            for (var i = 0; i < oisSwaps.Length; i++)
            {
                oisSwaps[i] = new IrBasisSwap(startDate, oisTenors[i], oisPrices[i], true, zaron, _zar3m, "ZAR.JIBAR.3M", "ZAR.OIS.1B", "ZAR.OIS.1B");
                fic.Add(oisSwaps[i]);
            }

            for (var i = 0; i < swaps.Length; i++)
            {
                swaps[i] = new IrSwap(startDate, swapTenors[i], _zar3m, swapPrices[i], SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.OIS.1B");
                fic.Add(swaps[i]);
            }
            for (var i = 0; i < depos.Length; i++)
            {
                depos[i] = new IrSwap(startDate, depoTenors[i], _zar3m, depoPrices[i], SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.OIS.1B");
                fic.Add(depos[i]);
            }

            var curve3m  = new IrCurve(pillarDates3m, new double[pillarDates3m.Length], startDate, "ZAR.JIBAR.3M", Interpolator1DType.LinearFlatExtrap, ccyZar);
            var curveOIS = new IrCurve(pillarDatesOIS, new double[pillarDatesOIS.Length], startDate, "ZAR.OIS.1B", Interpolator1DType.LinearFlatExtrap, ccyZar);
            var model    = new FundingModel(startDate, new IrCurve[] { curve3m, curveOIS }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);

            var S = new NewtonRaphsonMultiCurveSolver
            {
                Tollerance     = IsCoverageOnly ? 1 : 0.00000001,
                MaxItterations = IsCoverageOnly ? 1 : 100,
            };

            S.Solve(model, fic);

            if (!IsCoverageOnly)
            {
                foreach (var ins in fic)
                {
                    var pv = ins.Pv(model, false);
                    Assert.Equal(0.0, pv, 7);
                }
            }
        }
Пример #25
0
        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);
                }
            }
        }
Пример #26
0
        public void FuturesStripWithConvexity()
        {
            var volatility = 0.03;

            var startDate   = new DateTime(2017, 01, 17);
            var nContracts  = 24;
            var currentDate = startDate.GetNextImmDate();
            var expiries    = new DateTime[nContracts];
            var pillars     = new DateTime[nContracts];
            var instruments = new IFundingInstrument[nContracts];

            var nyc    = TestProviderHelper.CalendarProvider.Collection["NYC"];
            var lon    = TestProviderHelper.CalendarProvider.Collection["LON"];
            var ccyUsd = TestProviderHelper.CurrencyProvider["USD"];

            var usd3m = new FloatRateIndex()
            {
                Currency           = ccyUsd,
                DayCountBasis      = DayCountBasis.Act_360,
                DayCountBasisFixed = DayCountBasis.Act_360,
                ResetTenor         = 3.Months(),
                FixingOffset       = 2.Bd(),
                HolidayCalendars   = nyc,
                RollConvention     = RollType.MF
            };

            for (var i = 0; i < nContracts; i++)
            {
                var wed3rd = currentDate.ThirdWednesday();
                expiries[i]    = wed3rd.SubtractPeriod(RollType.P, lon, 2.Bd());
                pillars[i]     = wed3rd.AddPeriod(usd3m.RollConvention, usd3m.HolidayCalendars, usd3m.ResetTenor);
                instruments[i] = new STIRFuture()
                {
                    Currency            = ccyUsd,
                    ContractSize        = 1e6,
                    ConvexityAdjustment = FuturesConvexityUtils.CalculateConvexityAdjustment(startDate, expiries[i], pillars[i], volatility),
                    DCF           = 0.25,
                    Expiry        = expiries[i],
                    ForecastCurve = "USD.LIBOR.3M",
                    Index         = usd3m,
                    Position      = 1.0,
                    Price         = 99.50,
                    SolveCurve    = "USD.LIBOR.3M"
                };

                currentDate = currentDate.AddMonths(3);
            }

            var fic = new FundingInstrumentCollection(TestProviderHelper.CurrencyProvider);

            fic.AddRange(instruments);

            var curve = new IrCurve(pillars, new double[nContracts], startDate, "USD.LIBOR.3M", Interpolator1DType.LinearFlatExtrap, ccyUsd);
            var model = new FundingModel(startDate, new[] { curve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);

            var s = new Calibrators.NewtonRaphsonMultiCurveSolver()
            {
                Tollerance = IsCoverageOnly ? 1 : 0.00000001
            };

            s.Solve(model, fic);

            if (!IsCoverageOnly)
            {
                for (var i = 0; i < nContracts; i++)
                {
                    var resultPV = instruments[i].Pv(model, false);
                    Assert.Equal(0, resultPV, 6);
                }
            }
        }
Пример #27
0
        public void ContangoSwap()
        {
            var bd          = new DateTime(2019, 06, 14);
            var pillars     = new[] { bd, bd.AddDays(1000) };
            var flatRateUsd = 0.05;
            var flatRateXau = 0.01;
            var spotRate    = 1200;
            var ratesUsd    = pillars.Select(p => flatRateUsd).ToArray();
            var ratesXau    = pillars.Select(p => flatRateXau).ToArray();

            var usd = TestProviderHelper.CurrencyProvider["USD"];
            var xau = TestProviderHelper.CurrencyProvider["XAU"];

            CalendarProvider.Collection.TryGetCalendar("LON", out var cal);
            var pair = new FxPair()
            {
                Domestic = xau, Foreign = usd, SettlementCalendar = cal, SpotLag = 2.Bd()
            };

            var discoCurveUsd = new IrCurve(pillars, ratesUsd, bd, "USD.BLAH", Interpolator1DType.Linear, usd);
            var discoCurveXau = new IrCurve(pillars, ratesXau, bd, "XAU.BLAH", Interpolator1DType.Linear, xau);

            var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider);

            fxMatrix.Init(usd, bd, new Dictionary <Currency, double> {
                { xau, 1.0 / spotRate }
            }, new List <FxPair> {
                pair
            }, new Dictionary <Currency, string> {
                { usd, "USD.BLAH" }, { xau, "XAU.BLAH" }
            });
            var fModel = new FundingModel(bd, new[] { discoCurveUsd, discoCurveXau }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);

            fModel.SetupFx(fxMatrix);


            var maturity = bd.AddDays(365);
            var spot     = bd.SpotDate(2.Bd(), cal, cal);
            var c        = 0.022;
            var b        = new ContangoSwap
            {
                CashCCY           = usd,
                MetalCCY          = xau,
                CashDiscountCurve = "USD.BLAH",
                DeliveryDate      = maturity,
                ContangoRate      = c,
                MetalQuantity     = 1,
                SpotDate          = spot
            };

            var t = spot.CalculateYearFraction(maturity, DayCountBasis.Act360);

            var pv = b.Pv(fModel, false);

            var fwdA       = (1.0 + c * t) * spotRate;
            var fwdB       = fModel.GetFxRate(maturity, xau, usd);
            var df         = discoCurveUsd.GetDf(bd, maturity);
            var expectedPv = (fwdB - fwdA) * b.MetalQuantity;

            expectedPv *= df;
            Assert.Equal(expectedPv, pv, 10);
            Assert.Equal(maturity, b.LastSensitivityDate);
            Assert.Equal(usd, b.Currency);

            var s = b.Sensitivities(fModel);

            Assert.True(s.Count == 2 && s.Keys.Contains("USD.BLAH") && s.Keys.Contains("XAU.BLAH"));

            var s2 = b.Dependencies(fModel.FxMatrix);

            Assert.True(s2.Count == 2 && s2.Contains("USD.BLAH") && s2.Contains("XAU.BLAH"));

            Assert.Equal(0.0402428426839156, b.CalculateParRate(fModel), 8);

            var b2 = (ContangoSwap)b.SetParRate(0.05);

            Assert.Equal(0.05, b2.ContangoRate);
        }
Пример #28
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);
        }
Пример #29
0
        public static double PV(this CashFlowSchedule schedule, IrCurve discountCurve, IrCurve forecastCurve, bool updateState, bool updateDf, bool updateEstimate, DayCountBasis basisFloat, DateTime?filterDate)
        {
            double totalPv = 0;

            for (var i = 0; i < schedule.Flows.Count; i++)
            {
                var flow = schedule.Flows[i];

                if (filterDate.HasValue && flow.SettleDate < filterDate.Value)
                {
                    continue;
                }

                double fv, pv, df;

                switch (flow.FlowType)
                {
                case FlowType.FixedRate:
                {
                    if (updateState)
                    {
                        var rateLin = flow.FixedRateOrMargin;
                        var yf      = flow.YearFraction;
                        fv = rateLin * yf * flow.Notional;
                    }
                    else
                    {
                        fv = flow.Fv;
                    }

                    if (updateDf)
                    {
                        df = discountCurve.Pv(1, flow.SettleDate);
                    }
                    else
                    {
                        df = flow.Fv == flow.Pv ? 1.0 : flow.Pv / flow.Fv;
                    }

                    pv = fv * df;

                    totalPv += pv;

                    if (updateState)
                    {
                        flow.Fv = fv;
                        flow.Pv = pv;
                    }
                    break;
                }

                case FlowType.FloatRate:
                {
                    if (updateEstimate)
                    {
                        var s       = flow.AccrualPeriodStart;
                        var e       = flow.AccrualPeriodEnd;
                        var rateLin = forecastCurve.GetForwardRate(s, e, RateType.Linear, basisFloat);
                        rateLin += flow.FixedRateOrMargin;
                        var yf = flow.YearFraction;
                        fv = rateLin * yf * flow.Notional;
                    }
                    else
                    {
                        fv = flow.Fv;
                    }

                    if (updateDf)
                    {
                        df = discountCurve.Pv(1, flow.SettleDate);
                    }
                    else
                    {
                        df = flow.Fv == flow.Pv ? 1.0 : flow.Pv / flow.Fv;
                    }

                    pv       = fv * df;
                    totalPv += pv;

                    if (updateState)
                    {
                        flow.Fv = fv;
                        flow.Pv = pv;
                    }
                    break;
                }

                case FlowType.FixedAmount:
                {
                    fv = flow.Notional;

                    if (updateDf)
                    {
                        df = discountCurve.Pv(1, flow.SettleDate);
                    }
                    else
                    {
                        df = flow.Fv == flow.Pv ? 1.0 : flow.Pv / flow.Fv;
                    }

                    pv       = fv * df;
                    totalPv += pv;

                    if (updateState)
                    {
                        flow.Fv = fv;
                        flow.Pv = pv;
                    }

                    break;
                }
                }
            }

            return(totalPv);
        }
Пример #30
0
        private double PV(IrCurve discountCurve, IrCurve forecastCurve, bool updateState, bool updateDf, bool updateEstimate)
        {
            double totalPv = 0;

            for (var i = 0; i < FlowScheduleFixed.Flows.Count; i++)
            {
                var    flow = FlowScheduleFixed.Flows[i];
                double fv, df;
                if (updateState)
                {
                    var rateLin = flow.FixedRateOrMargin;
                    var yf      = flow.NotionalByYearFraction;
                    fv = rateLin * yf * flow.Notional;
                }
                else
                {
                    fv = flow.Fv;
                }

                if (updateDf)
                {
                    df = discountCurve.Pv(1, flow.SettleDate);
                }
                else
                {
                    df = flow.Fv == flow.Pv ? 1.0 : flow.Pv / flow.Fv;
                }

                var pv = fv * df;

                totalPv += pv;

                if (updateState)
                {
                    flow.Fv = fv;
                    flow.Pv = pv;
                }
            }

            for (var i = 0; i < FlowScheduleFloat.Flows.Count; i++)
            {
                var    flow = FlowScheduleFloat.Flows[i];
                double fv, df;

                if (updateEstimate)
                {
                    var s       = flow.AccrualPeriodStart;
                    var e       = flow.AccrualPeriodEnd;
                    var rateLin = forecastCurve.GetForwardRate(s, e, RateType.Linear, BasisFloat);
                    var yf      = flow.NotionalByYearFraction;
                    fv = rateLin * yf * flow.Notional;
                }
                else
                {
                    fv = flow.Fv;
                }

                if (updateDf)
                {
                    df = discountCurve.Pv(1, flow.SettleDate);
                }
                else
                {
                    df = flow.Fv == flow.Pv ? 1.0 : flow.Pv / flow.Fv;
                }

                var pv = fv * df;
                totalPv += pv;

                if (updateState)
                {
                    flow.Fv = fv;
                    flow.Pv = pv;
                }
            }
            return(totalPv);
        }