public static object CreateFundingInstrumentCollection(
            [ExcelArgument(Description = "Object name")] string ObjectName,
            [ExcelArgument(Description = "Instruments")] object[] InstrumentsA,
            [ExcelArgument(Description = "Instruments")] object[] InstrumentsB,
            [ExcelArgument(Description = "Instruments")] object[] InstrumentsC,
            [ExcelArgument(Description = "Instruments")] object[] InstrumentsD,
            [ExcelArgument(Description = "Instruments")] object[] InstrumentsE,
            [ExcelArgument(Description = "Instruments")] object[] InstrumentsF,
            [ExcelArgument(Description = "Instruments")] object[] InstrumentsG,
            [ExcelArgument(Description = "Instruments")] object[] InstrumentsH,
            [ExcelArgument(Description = "Instruments")] object[] InstrumentsI)
        {
            return(ExcelHelper.Execute(_logger, () =>
            {
                var Instruments = InstrumentsA
                                  .Concat(InstrumentsB)
                                  .Concat(InstrumentsC)
                                  .Concat(InstrumentsD)
                                  .Concat(InstrumentsE)
                                  .Concat(InstrumentsF)
                                  .Concat(InstrumentsG)
                                  .Concat(InstrumentsH)
                                  .Concat(InstrumentsI)
                                  .ToArray();

                var swaps = Instruments.GetAnyFromCache <IrSwap>();
                var fras = Instruments.GetAnyFromCache <ForwardRateAgreement>();
                var futures = Instruments.GetAnyFromCache <STIRFuture>();
                var oisFutures = Instruments.GetAnyFromCache <OISFuture>();
                var fxFwds = Instruments.GetAnyFromCache <FxForward>();
                var xccySwaps = Instruments.GetAnyFromCache <XccyBasisSwap>();
                var basisSwaps = Instruments.GetAnyFromCache <IrBasisSwap>();
                var loanDepos = Instruments.GetAnyFromCache <FixedRateLoanDeposit>();
                var ctgoSwaps = Instruments.GetAnyFromCache <ContangoSwap>();

                //allows merging of FICs into portfolios
                var ficInstruments = Instruments.GetAnyFromCache <FundingInstrumentCollection>()
                                     .SelectMany(s => s);

                var fic = new FundingInstrumentCollection(ContainerStores.CurrencyProvider);
                fic.AddRange(swaps);
                fic.AddRange(fras);
                fic.AddRange(futures);
                fic.AddRange(oisFutures);
                fic.AddRange(fxFwds);
                fic.AddRange(xccySwaps);
                fic.AddRange(basisSwaps);
                fic.AddRange(ficInstruments);
                fic.AddRange(loanDepos);
                fic.AddRange(ctgoSwaps);

                return ExcelHelper.PushToCache(fic, ObjectName);
            }));
        }
Beispiel #2
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);
        }
Beispiel #3
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);
        }
Beispiel #4
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);
        }
Beispiel #5
0
        public static ICube BenchmarkRisk(this IPvModel pvModel, FundingInstrumentCollection riskCollection, ICurrencyProvider currencyProvider, Currency reportingCcy)
        {
            var cube      = new ResultCube();
            var dataTypes = new Dictionary <string, Type>
            {
                { "TradeId", typeof(string) },
                { "TradeType", typeof(string) },
                { "Curve", typeof(string) },
                { "RiskDate", typeof(DateTime) },
                { "Benchmark", typeof(string) },
                { "Metric", typeof(string) },
                { "Units", typeof(string) },
                { "BumpSize", typeof(double) },
            };

            cube.Initialize(dataTypes);

            //var lastDate = pvModel.Portfolio.LastSensitivityDate;
            var insByCurve      = riskCollection.GroupBy(x => x.SolveCurve);
            var dependencies    = riskCollection.FindDependenciesInverse(pvModel.VanillaModel.FundingModel.FxMatrix);
            var lastDateByCurve = insByCurve.ToDictionary(x => x.Key, x => DateTime.MinValue);

            foreach (var ins in pvModel.Portfolio.UnWrapWrappers().Instruments)
            {
                if (ins is IFundingInstrument fins)
                {
                    var cvs = fins.Dependencies(pvModel.VanillaModel.FundingModel.FxMatrix);
                    foreach (var c in cvs)
                    {
                        if (!lastDateByCurve.ContainsKey(c))
                        {
                            lastDateByCurve[c] = DateTime.MinValue;
                        }

                        lastDateByCurve[c] = lastDateByCurve[c].Max(ins.LastSensitivityDate);
                    }
                }
                else if (ins is IAssetInstrument ains)
                {
                    var cvs = ains.IrCurves(pvModel.VanillaModel);
                    foreach (var c in cvs)
                    {
                        if (!lastDateByCurve.ContainsKey(c))
                        {
                            lastDateByCurve[c] = DateTime.MinValue;
                        }

                        lastDateByCurve[c] = lastDateByCurve[c].Max(ins.LastSensitivityDate);
                    }
                }
            }

            foreach (var c in lastDateByCurve.Keys.ToArray())
            {
                if (dependencies.ContainsKey(c))
                {
                    foreach (var d in dependencies[c])
                    {
                        lastDateByCurve[c] = lastDateByCurve[c].Max(lastDateByCurve[d]);
                    }
                }
            }


            var insToRisk = new List <IFundingInstrument>();

            foreach (var gp in insByCurve)
            {
                var lastDate = lastDateByCurve[gp.Key];
                var sorted   = gp.OrderBy(x => x.LastSensitivityDate).ToList();
                if (sorted.Last().LastSensitivityDate <= lastDate)
                {
                    insToRisk.AddRange(sorted);
                }
                else
                {
                    var lastIns = sorted.First(x => x.LastSensitivityDate > lastDate);
                    var lastIx  = sorted.IndexOf(lastIns);
                    lastIx = System.Math.Min(lastIx + 1, sorted.Count);
                    insToRisk.AddRange(sorted.Take(lastIx));
                }
            }

            var parRates = insToRisk.Select(x => x.CalculateParRate(pvModel.VanillaModel.FundingModel)).ToList();
            var newIns   = insToRisk.Select((x, ix) => x.SetParRate(parRates[ix]));
            var newFic   = new FundingInstrumentCollection(currencyProvider);

            newFic.AddRange(newIns.OrderBy(x => x.SolveCurve).ThenBy(x => x.PillarDate));

            var fModel = pvModel.VanillaModel.FundingModel.DeepClone(null);
            var s      = new NewtonRaphsonMultiCurveSolverStaged();

            s.Solve(fModel, newFic);

            var vModel     = pvModel.VanillaModel.Clone(fModel);
            var newPvModel = pvModel.Rebuild(vModel, pvModel.Portfolio);

            //var basePVbyCurrency = new Dictionary<Currency, ICube>();

            var basePV = newPvModel.PV(reportingCcy);

            ParallelUtils.Instance.For(0, newIns.Count(), 1, i =>
                                       //for (var i = 0; i < newIns.Count(); i++)
            {
                //if (!basePVbyCurrency.TryGetValue(insToRisk[i].Currency, out var basePV))
                //{
                //    basePV = newPvModel.PV(insToRisk[i].Currency);
                //    basePVbyCurrency[insToRisk[i].Currency] = basePV;
                //}

                var tIdIx   = basePV.GetColumnIndex("TradeId");
                var tTypeIx = basePV.GetColumnIndex("TradeType");

                var bumpSize = GetBumpSize(insToRisk[i]);

                var bumpedIns = newIns.Select((x, ix) => x.SetParRate(parRates[ix] + (ix == i ? bumpSize : 0.0)));
                var newFicb   = new FundingInstrumentCollection(currencyProvider);
                newFicb.AddRange(bumpedIns);

                var fModelb = fModel.DeepClone(null);

                var sb = new NewtonRaphsonMultiCurveSolverStaged();
                sb.Solve(fModelb, newFicb);

                var vModelb     = pvModel.VanillaModel.Clone(fModelb);
                var newPvModelb = pvModel.Rebuild(vModelb, pvModel.Portfolio);

                //var bumpedPV = newPvModelb.PV(insToRisk[i].Currency);
                var bumpedPV = newPvModelb.PV(reportingCcy);

                var bumpName  = insToRisk[i].TradeId;
                var riskDate  = insToRisk[i].PillarDate;
                var riskCurve = insToRisk[i].SolveCurve;
                var riskUnits = GetRiskUnits(insToRisk[i]);

                var deltaCube    = bumpedPV.QuickDifference(basePV);
                var deltaScale   = GetScaleFactor(insToRisk[i], parRates[i], parRates[i] + bumpSize, fModel);
                var fxToCurveCcy = fModel.GetFxRate(fModel.BuildDate, reportingCcy, insToRisk[i].Currency);

                foreach (var dRow in deltaCube.GetAllRows())
                {
                    if (dRow.Value == 0.0)
                    {
                        continue;
                    }

                    var row = new Dictionary <string, object>
                    {
                        { "TradeId", dRow.MetaData[tIdIx] },
                        { "TradeType", dRow.MetaData[tTypeIx] },
                        { "Benchmark", bumpName },
                        { "RiskDate", riskDate },
                        { "Curve", riskCurve },
                        { "Metric", "IrBenchmarkDelta" },
                        { "Units", riskUnits },
                        { "BumpSize", bumpSize },
                    };
                    cube.AddRow(row, dRow.Value * deltaScale * fxToCurveCcy);
                }
            }).Wait();

            return(cube.Sort(new List <string> {
                "Curve", "RiskDate", "TradeId"
            }));
        }
Beispiel #6
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);
                }
            }
        }