Ejemplo n.º 1
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);
            }
        }
Ejemplo n.º 2
0
        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.Flatten2d <object>()
                                  .Concat(InstrumentsB.Flatten2d <object>())
                                  .Concat(InstrumentsC.Flatten2d <object>())
                                  .Concat(InstrumentsD.Flatten2d <object>())
                                  .Concat(InstrumentsE.Flatten2d <object>())
                                  .Concat(InstrumentsF.Flatten2d <object>())
                                  .Concat(InstrumentsG.Flatten2d <object>())
                                  .Concat(InstrumentsH.Flatten2d <object>())
                                  .Concat(InstrumentsI.Flatten2d <object>())
                                  .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 fxSwaps = Instruments.GetAnyFromCache <FxSwap>();
                var xccySwaps = Instruments.GetAnyFromCache <XccyBasisSwap>();
                var basisSwaps = Instruments.GetAnyFromCache <IrBasisSwap>();
                var loanDepos = Instruments.GetAnyFromCache <FixedRateLoanDeposit>();
                var ctgoSwaps = Instruments.GetAnyFromCache <ContangoSwap>();
                var flrDepos = Instruments.GetAnyFromCache <FloatingRateLoanDepo>();

                //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(fxSwaps);
                fic.AddRange(xccySwaps);
                fic.AddRange(basisSwaps);
                fic.AddRange(ficInstruments);
                fic.AddRange(loanDepos);
                fic.AddRange(ctgoSwaps);
                fic.AddRange(flrDepos);

                return ExcelHelper.PushToCache(fic, ObjectName);
            }));
        }
Ejemplo n.º 3
0
        public void BasicRiskMatrixFacts()
        {
            var model = GenerateTestData();
            var zar   = TestProviderHelper.CurrencyProvider.GetCurrency("ZAR");
            var usd   = TestProviderHelper.CurrencyProvider.GetCurrency("USD");
            var ix    = new FloatRateIndex
            {
                Currency           = usd,
                DayCountBasis      = DayCountBasis.Act365F,
                DayCountBasisFixed = DayCountBasis.Act365F,
                FixingOffset       = 0.Bd(),
                ResetTenor         = 3.Months(),
                ResetTenorFixed    = 3.Months(),
                RollConvention     = RollType.F
            };

            var f1 = new STIRFuture
            {
                ContractSize  = 1e6,
                Currency      = usd,
                DCF           = 0.25,
                Expiry        = _originDate.AddDays(1),
                Position      = 1.0,
                Index         = ix,
                ForecastCurve = "DISCO-USD",
                SolveCurve    = "DISCO-USD",
                TradeId       = "f1",
                Price         = 95,
                PillarDate    = _originDate.AddDays(90)
            };

            var f2 = new STIRFuture
            {
                ContractSize  = 1e6,
                Currency      = usd,
                DCF           = 0.25,
                Expiry        = _originDate.AddDays(90),
                Position      = 1.0,
                Index         = ix,
                ForecastCurve = "DISCO-USD",
                SolveCurve    = "DISCO-USD",
                TradeId       = "f2",
                Price         = 95,
                PillarDate    = _originDate.AddDays(180),
            };
            var fic = new FundingInstrumentCollection(TestProviderHelper.CurrencyProvider)
            {
                f1,
                f2
            };

            var cube = model.BenchmarkRisk(fic, TestProviderHelper.CurrencyProvider, usd);

            var riskSum = cube.SumOfAllRows;

            Assert.Equal(-13.0, riskSum, 0);
        }
Ejemplo n.º 4
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);
            }
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
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);
        }
Ejemplo n.º 8
0
        public void ImplySolveStagesTest()
        {
            var f = new FundingInstrumentCollection(TestProviderHelper.CurrencyProvider)
            {
                new IrSwap
                {
                    SolveCurve    = "usd.forecast",
                    DiscountCurve = "usd.discount",
                    ForecastCurve = "usd.forecast"
                },
                new IrBasisSwap
                {
                    SolveCurve       = "usd.discount",
                    DiscountCurve    = "usd.discount",
                    ForecastCurvePay = "usd.forecast",
                    ForecastCurveRec = "usd.discount"
                },
                new XccyBasisSwap
                {
                    SolveCurve       = "zar.discount.usd",
                    DiscountCurvePay = "zar.discount.usd",
                    ForecastCurvePay = "zar.discount.usd",
                    DiscountCurveRec = "usd.discount",
                    ForecastCurveRec = "usd.forecast"
                }
            };

            var x = f.ImplySolveStages(null);

            Assert.Equal(3, x.Count);
            Assert.Equal(2, x.Where(xx => xx.Value == 0).Count());
            Assert.Equal("zar.discount.usd", x.Single(xx => xx.Value == 1).Key);

            f.Add(new IrBasisSwap
            {
                SolveCurve       = "usd.discount2",
                DiscountCurve    = "usd.discount2",
                ForecastCurvePay = "usd.forecast2",
                ForecastCurveRec = "usd.discount2"
            });

            Assert.Throws <Exception>(() => f.ImplySolveStages(null));
        }
        public void Solve(FundingModel fundingModel, FundingInstrumentCollection instruments)
        {
            var maxStage           = fundingModel.Curves.Max(x => x.Value.SolveStage);
            var curvesForStage     = new List <ICurve>();
            var fundingInstruments = new List <IFundingInstrument>();

            for (var stage = 0; stage <= maxStage; stage++)
            {
                curvesForStage.Clear();
                fundingInstruments.Clear();
                foreach (var kv in fundingModel.Curves)
                {
                    if (kv.Value.SolveStage == stage)
                    {
                        curvesForStage.Add(kv.Value);
                        foreach (var inst in instruments)
                        {
                            if (inst.SolveCurve == kv.Value.Name)
                            {
                                fundingInstruments.Add(inst);
                            }
                        }
                    }
                }
                var currentGuess = new double[fundingInstruments.Count];
                _currentPvs = new double[fundingInstruments.Count];
                var bumpedPvs = new double[fundingInstruments.Count];
                _jacobian = Math.Matrix.DoubleArrayFunctions.MatrixCreate(fundingInstruments.Count, fundingInstruments.Count);

                for (var i = 0; i < MaxItterations; i++)
                {
                    ComputePVs(true, fundingInstruments, fundingModel, _currentPvs);
                    if (_currentPvs.Max(x => System.Math.Abs(x)) < Tollerance)
                    {
                        UsedItterations = i + 1;
                        break;
                    }
                    ComputeJacobian(fundingInstruments, fundingModel, curvesForStage, currentGuess, bumpedPvs);
                    ComputeNextGuess(currentGuess, fundingInstruments.Count, curvesForStage);
                }
            }
        }
Ejemplo n.º 10
0
        public void Solve(FundingModel fundingModel, FundingInstrumentCollection instruments)
        {
            _curveEngine         = fundingModel;
            _fundingInstruments  = instruments;
            _numberOfInstruments = _fundingInstruments.Count;
            _numberOfPillars     = _curveEngine.Curves.Select(kv => kv.Value.NumberOfPillars).Sum();
            _numberOfCurves      = _curveEngine.Curves.Count;
            _currentGuess        = new double[_numberOfPillars];
            _currentPVs          = ComputePVs();
            _curveNames          = fundingModel.Curves.Keys.ToArray();
            if (_numberOfPillars != _numberOfInstruments)
            {
                throw new ArgumentException();
            }

            var pillarToCurveMap = new List <Tuple <int, int> >();

            for (var i = 0; i < _numberOfCurves; i++)
            {
                var currentCurve    = _curveEngine.Curves[_curveNames[i]];
                var nPillarsOnCurve = currentCurve.NumberOfPillars;
                var i1 = i;
                pillarToCurveMap.AddRange(Enumerable.Range(0, nPillarsOnCurve).Select(x => new Tuple <int, int>(i1, x)));
            }
            _pillarToCurveMapping = pillarToCurveMap.ToArray();


            ComputeJacobian();

            for (var i = 0; i < MaxItterations; i++)
            {
                ComputeNextGuess();
                _currentPVs = ComputePVs();
                if (_currentPVs.Max(x => System.Math.Abs(x)) < Tollerance)
                {
                    UsedItterations = i + 1;
                    break;
                }
                ComputeJacobian();
            }
        }
Ejemplo n.º 11
0
        public void FundingInstrumentCollection()
        {
            var f = new FundingInstrumentCollection(TestProviderHelper.CurrencyProvider)
            {
                new FxForward {
                    SolveCurve = "1.blah"
                },
                new FxForward {
                    SolveCurve = "1.blah"
                },
                new FxForward {
                    SolveCurve = "2.blah"
                }
            };

            Assert.True(Enumerable.SequenceEqual(f.SolveCurves, new[] { "1.blah", "2.blah" }));

            var f2 = f.Clone();

            Assert.True(Enumerable.SequenceEqual(f, f2));
        }
Ejemplo n.º 12
0
        public void PillarDatesTest()
        {
            var f = new FundingInstrumentCollection(TestProviderHelper.CurrencyProvider)
            {
                new FxForward {
                    SolveCurve = "usd.1blah", PillarDate = DateTime.Today
                },
                new FxForward {
                    SolveCurve = "usd.2blah", PillarDate = DateTime.Today.AddDays(1)
                },
                new FxForward {
                    SolveCurve = "usd.2blah", PillarDate = DateTime.Today
                }
            };

            var x = f.ImplyContainedCurves(DateTime.Today, Interpolator1DType.Linear);

            //double up on one pillar on the same curve
            f.Add(new FxForward {
                SolveCurve = "usd.2blah", PillarDate = DateTime.Today
            });

            Assert.Throws <Exception>(() => f.ImplyContainedCurves(DateTime.Today, Interpolator1DType.Linear));
        }
Ejemplo n.º 13
0
        public void ComplexCurve()
        {
            var startDate     = new DateTime(2016, 05, 20);
            var depoTenors    = new Frequency[] { 3.Months() };
            var OISdepoTenors = new Frequency[] { 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 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 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 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]);
            }

            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 engine = new FundingModel(startDate, new IrCurve[] { ZARcurve3m, ZARcurveOIS, USDcurve3m, USDcurveOIS }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);

            var ZARcurve3m0 = new IrCurve(ZARpillarDates3m, new double[ZARpillarDates3m.Length], startDate, "ZAR.JIBAR.3M", Interpolator1DType.LinearFlatExtrap, ccyZar)
            {
                SolveStage = 0
            };
            var ZARcurveOIS0 = new IrCurve(ZARpillarDatesOIS, new double[ZARpillarDatesOIS.Length], startDate, "ZAR.DISC.CSA_ZAR", Interpolator1DType.LinearFlatExtrap, ccyZar)
            {
                SolveStage = 0
            };
            var USDcurve3m0 = new IrCurve(USDpillarDates3m, new double[USDpillarDates3m.Length], startDate, "USD.LIBOR.3M", Interpolator1DType.LinearFlatExtrap, ccyUsd)
            {
                SolveStage = 1
            };
            var USDcurveOIS0 = new IrCurve(USDpillarDatesOIS, new double[USDpillarDatesOIS.Length], startDate, "USD.DISC.CSA_USD", Interpolator1DType.LinearFlatExtrap, ccyUsd)
            {
                SolveStage = 1
            };

            var engine0 = new FundingModel(startDate, new IrCurve[] { ZARcurve3m0, ZARcurveOIS0, USDcurve3m0, USDcurveOIS0 }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);


            var S = new NewtonRaphsonMultiCurveSolverStagedWithAnalyticJacobian()
            {
                Tollerance     = IsCoverageOnly ? 1 : 0.00000001,
                MaxItterations = IsCoverageOnly ? 1 : 100,
            };
            var S0 = new NewtonRaphsonMultiCurveSolverStaged()
            {
                Tollerance     = IsCoverageOnly ? 1 : 0.00000001,
                MaxItterations = IsCoverageOnly ? 1 : 100,
            };

            S.Solve(engine, FIC);
            S0.Solve(engine0, FIC);

            if (!IsCoverageOnly)
            {
                foreach (var ins in FIC)
                {
                    var pv = ins.Pv(engine, false);
                    Assert.Equal(0.0, pv, 7);
                }

                foreach (var curve in engine.Curves)
                {
                    var otherCurve = engine0.Curves[curve.Key];
                    Assert.Equal(curve.Value.NumberOfPillars, otherCurve.NumberOfPillars);
                    var otherRates = otherCurve.GetRates();
                    var rates      = curve.Value.GetRates();
                    for (var i = 0; i < otherRates.Length; i++)
                    {
                        Assert.Equal(otherRates[i], rates[i], 10);
                    }
                }
            }
        }
Ejemplo n.º 14
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);
                }
            }
        }
Ejemplo n.º 15
0
        public static void Setup()
        {
            var startDate     = new DateTime(2016, 05, 20);
            var depoTenors    = new Frequency[] { 3.Months() };
            var OISdepoTenors = new Frequency[] { 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 };
            double[]    crossxPrices  = { 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 ZARpillarDatesDepo    = depoTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._jhb, x)).ToArray();
            var ZARpillarDatesFRA     = FRATenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._jhb, new Frequency(x.Split('x')[1] + "M"))).ToArray();
            var ZARpillarDatesSwap    = swapTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._jhb, x)).ToArray();
            var ZARpillarDates3m      = ZARpillarDatesDepo.Union(ZARpillarDatesSwap).Union(ZARpillarDatesFRA).Distinct().OrderBy(x => x).ToArray();
            var ZARpillarDatesDepoOIS = OISdepoTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._jhb, x)).ToArray();
            var ZARpillarDatesOISSwap = oisTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._jhb, x)).ToArray();
            var ZARpillarDatesOIS     = ZARpillarDatesDepoOIS.Union(ZARpillarDatesOISSwap).Distinct().OrderBy(x => x).ToArray();


            var USDpillarDatesDepo    = depoTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._usd, x)).ToArray();
            var USDpillarDatesFRA     = FRATenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._usd, new Frequency(x.Split('x')[1] + "M"))).ToArray();
            var USDpillarDatesSwap    = swapTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._usd, x)).ToArray();
            var USDpillarDates3m      = USDpillarDatesDepo.Union(USDpillarDatesSwap).Union(USDpillarDatesFRA).Distinct().OrderBy(x => x).ToArray();
            var USDpillarDatesDepoOIS = OISdepoTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._usd, x)).ToArray();
            var USDpillarDatesOISSwap = oisTenors.Select(x => startDate.AddPeriod(RollType.MF, CurveDataSetup._usd, x)).ToArray();
            var USDpillarDatesOIS     = USDpillarDatesDepoOIS.Union(USDpillarDatesOISSwap).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 ccySwaps = new XccyBasisSwap[oisTenors.Length];

            _instruments = new FundingInstrumentCollection();

            for (var i = 0; i < FRATenors.Length; i++)
            {
                ZARFRAs[i] = new ForwardRateAgreement(startDate, FRATenors[i], FRAPricesZAR[i], CurveDataSetup._zar3m, SwapPayReceiveType.Payer, FraDiscountingType.Isda, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR")
                {
                    SolveCurve = "ZAR.JIBAR.3M"
                };
                _instruments.Add(ZARFRAs[i]);
                USDFRAs[i] = new ForwardRateAgreement(startDate, FRATenors[i], FRAPricesUSD[i], CurveDataSetup.usd3m, SwapPayReceiveType.Payer, FraDiscountingType.Isda, "USD.LIBOR.3M", "USD.DISC.CSA_USD")
                {
                    SolveCurve = "USD.LIBOR.3M"
                };
                _instruments.Add(USDFRAs[i]);
            }

            for (var i = 0; i < oisTenors.Length; i++)
            {
                ZARoisSwaps[i] = new IrBasisSwap(startDate, oisTenors[i], oisPricesZAR[i], true, CurveDataSetup.zaron, CurveDataSetup._zar3m, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR", "ZAR.DISC.CSA_ZAR")
                {
                    SolveCurve = "ZAR.DISC.CSA_ZAR"
                };
                _instruments.Add(ZARoisSwaps[i]);
                USDoisSwaps[i] = new IrBasisSwap(startDate, oisTenors[i], oisPricesUSD[i], true, CurveDataSetup.usdon, CurveDataSetup.usd3m, "USD.LIBOR.3M", "USD.DISC.CSA_USD", "USD.DISC.CSA_USD")
                {
                    SolveCurve = "USD.DISC.CSA_USD"
                };
                _instruments.Add(USDoisSwaps[i]);
                ccySwaps[i] = new XccyBasisSwap(startDate, oisTenors[i], crossxPrices[i], true, CurveDataSetup.usd3m, CurveDataSetup._zar3m, ExchangeType.Both, MTMSwapType.ReceiveNotionalFixed, "USD.LIBOR.3M", "ZAR.JIBAR.3M", "USD.DISC.CSA_USD", "ZAR.DISC.CSA_USD");
                //_instruments.Add(ccySwaps[i]);
            }

            for (var i = 0; i < swapTenors.Length; i++)
            {
                ZARswaps[i] = new IrSwap(startDate, swapTenors[i], CurveDataSetup._zar3m, swapPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR")
                {
                    SolveCurve = "ZAR.JIBAR.3M"
                };
                _instruments.Add(ZARswaps[i]);
                USDswaps[i] = new IrSwap(startDate, swapTenors[i], CurveDataSetup.usd3m, swapPricesUSD[i], SwapPayReceiveType.Payer, "USD.LIBOR.3M", "USD.DISC.CSA_USD")
                {
                    SolveCurve = "USD.LIBOR.3M"
                };
                _instruments.Add(USDswaps[i]);
            }

            for (var i = 0; i < depoTenors.Length; i++)
            {
                ZARdepos[i] = new IrSwap(startDate, depoTenors[i], CurveDataSetup._zar3m, depoPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.JIBAR.3M", "ZAR.DISC.CSA_ZAR")
                {
                    SolveCurve = "ZAR.JIBAR.3M"
                };
                _instruments.Add(ZARdepos[i]);
                USDdepos[i] = new IrSwap(startDate, depoTenors[i], CurveDataSetup.usd3m, depoPricesUSD[i], SwapPayReceiveType.Payer, "USD.LIBOR.3M", "USD.DISC.CSA_USD")
                {
                    SolveCurve = "USD.LIBOR.3M"
                };
                _instruments.Add(USDdepos[i]);
            }

            for (var i = 0; i < OISdepoTenors.Length; i++)
            {
                ZARdeposOIS[i] = new IrSwap(startDate, OISdepoTenors[i], CurveDataSetup.zaron, OISdepoPricesZAR[i], SwapPayReceiveType.Payer, "ZAR.DISC.CSA_ZAR", "ZAR.DISC.CSA_ZAR")
                {
                    SolveCurve = "ZAR.DISC.CSA_ZAR"
                };
                _instruments.Add(ZARdeposOIS[i]);
                USDdeposOIS[i] = new IrSwap(startDate, OISdepoTenors[i], CurveDataSetup.usdon, OISdepoPricesUSD[i], SwapPayReceiveType.Payer, "USD.DISC.CSA_USD", "USD.DISC.CSA_USD")
                {
                    SolveCurve = "USD.DISC.CSA_USD"
                };
                _instruments.Add(USDdeposOIS[i]);
            }

            var ZARcurve3m = new IrCurve(ZARpillarDates3m, new double[ZARpillarDates3m.Length], startDate, "ZAR.JIBAR.3M", Interpolator1DType.LinearFlatExtrap)
            {
                SolveStage = 0
            };
            var ZARcurveOIS = new IrCurve(ZARpillarDatesOIS, new double[ZARpillarDatesOIS.Length], startDate, "ZAR.DISC.CSA_ZAR", Interpolator1DType.LinearFlatExtrap)
            {
                SolveStage = 0
            };
            var USDcurve3m = new IrCurve(USDpillarDates3m, new double[USDpillarDates3m.Length], startDate, "USD.LIBOR.3M", Interpolator1DType.LinearFlatExtrap)
            {
                SolveStage = 1
            };
            var USDcurveOIS = new IrCurve(USDpillarDatesOIS, new double[USDpillarDatesOIS.Length], startDate, "USD.DISC.CSA_USD", Interpolator1DType.LinearFlatExtrap)
            {
                SolveStage = 1
            };

            // var ZARccyBasisCurve = new IrCurve(USDpillarDatesOIS, new double[USDpillarDatesOIS.Length], startDate, "ZAR.DISC.CSA_USD", Interpolator1DType.LinearFlatExtrap) { SolveStage = 2 };

            _fundingModel = new FundingModel(startDate, new IrCurve[] { ZARcurve3m, ZARcurveOIS, USDcurve3m, USDcurveOIS });
        }
Ejemplo n.º 16
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);
                }
            }
        }
Ejemplo n.º 17
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);
                }
            }
        }
        //private double[][] _jacobian;
        //double[] _currentPvs;

        public void Solve(IFundingModel fundingModel, FundingInstrumentCollection instruments)
        {
            var sw = new Stopwatch();

            sw.Start();
            var itterationsPerStage = new Dictionary <int, int>();
            var curvesPerStange     = new Dictionary <int, string>();

            var maxStage           = fundingModel.Curves.Max(x => x.Value.SolveStage);
            var curvesForStage     = new List <IIrCurve>();
            var fundingInstruments = new List <IFundingInstrument>();

            for (var stage = 0; stage <= maxStage; stage++)
            {
                curvesForStage.Clear();
                fundingInstruments.Clear();

                foreach (var kv in fundingModel.Curves)
                {
                    if (kv.Value.SolveStage == stage)
                    {
                        var insForCurve = new List <IFundingInstrument>();
                        curvesForStage.Add(kv.Value);
                        foreach (var inst in instruments)
                        {
                            if (inst.SolveCurve == kv.Value.Name)
                            {
                                insForCurve.Add(inst);
                                fundingInstruments.Add(inst);
                            }
                        }

                        if (InLineCurveGuessing)
                        {
                            var points = insForCurve.ToDictionary(x => x.PillarDate, x => x.SuggestPillarValue(fundingModel));
                            for (var i = 0; i < kv.Value.NumberOfPillars; i++)
                            {
                                kv.Value.SetRate(i, points[kv.Value.PillarDates[i]], true);
                            }
                        }
                    }
                }
                curvesPerStange[stage] = string.Join(",", curvesForStage.Select(c => c.Name).ToArray());
                var currentGuess = new double[fundingInstruments.Count];
                var currentPvs   = new double[fundingInstruments.Count];
                var bumpedPvs    = new double[fundingInstruments.Count];
                var jacobian     = Math.Matrix.DoubleArrayFunctions.MatrixCreate(fundingInstruments.Count, fundingInstruments.Count);

                for (var i = 0; i < MaxItterations; i++)
                {
                    ComputePVs(true, fundingInstruments, fundingModel, currentPvs);
                    if (currentPvs.Max(x => System.Math.Abs(x)) < Tollerance)
                    {
                        UsedItterations           += i + 1;
                        itterationsPerStage[stage] = i + 1;
                        break;
                    }
                    ComputeJacobian(fundingInstruments, fundingModel, curvesForStage, currentGuess, bumpedPvs, currentPvs, ref jacobian);
                    ComputeNextGuess(currentGuess, fundingInstruments.Count, curvesForStage, jacobian, currentPvs);
                }
            }

            fundingModel.CalibrationItterations = itterationsPerStage;
            fundingModel.CalibrationTimeMs      = sw.ElapsedMilliseconds;
            fundingModel.CalibrationCurves      = curvesPerStange;
            sw.Stop();
        }
Ejemplo n.º 19
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"
            }));
        }
        public void Solve(IFundingModel fundingModel, FundingInstrumentCollection instruments, Dictionary <string, SolveStage> stages)
        {
            var sw = new Stopwatch();

            sw.Start();
            var itterationsPerStage = new Dictionary <SolveStage, int>();

            var maxStage = stages.Values.Max(x => x.Stage);

            for (var stage = 0; stage <= maxStage; stage++)
            {
                var inThisStage = stages.Where(x => x.Value.Stage == stage)
                                  .GroupBy(x => x.Value.SubStage)
                                  .ToDictionary(x => x.Key, x => x.Select(y => y.Key).ToArray());

                ParallelUtils.Instance.Foreach(inThisStage.Keys.ToList(), subStage =>
                {
                    var curvesForStage     = inThisStage[subStage].Select(c => (IIrCurve)fundingModel.GetCurve(c)).ToList();
                    var fundingInstruments = new List <IFundingInstrument>();
                    var insForCurve        = new List <IFundingInstrument>();
                    foreach (var curve in curvesForStage)
                    {
                        foreach (var inst in instruments)
                        {
                            if (inst.SolveCurve == curve.Name)
                            {
                                insForCurve.Add(inst);
                                fundingInstruments.Add(inst);
                            }
                        }

                        if (InLineCurveGuessing)
                        {
                            var points = insForCurve.ToDictionary(x => x.PillarDate, x => x.SuggestPillarValue(fundingModel));
                            for (var i = 0; i < curve.NumberOfPillars; i++)
                            {
                                curve.SetRate(i, points[((IrCurve)curve).PillarDates[i]], true);
                            }
                        }
                    }
                    var currentGuess = new double[fundingInstruments.Count];
                    var currentPvs   = new double[fundingInstruments.Count];
                    var bumpedPvs    = new double[fundingInstruments.Count];
                    var jacobian     = Math.Matrix.DoubleArrayFunctions.MatrixCreate(fundingInstruments.Count, fundingInstruments.Count);

                    for (var i = 0; i < MaxItterations; i++)
                    {
                        ComputePVs(true, fundingInstruments, fundingModel, currentPvs);
                        if (currentPvs.Max(x => System.Math.Abs(x)) < Tollerance)
                        {
                            UsedItterations += i + 1;
                            break;
                        }
                        ComputeJacobian(fundingInstruments, fundingModel, curvesForStage, currentGuess, bumpedPvs, currentPvs, ref jacobian);
                        ComputeNextGuess(currentGuess, fundingInstruments.Count, curvesForStage, jacobian, currentPvs);
                    }
                }).Wait();
            }
            //fundingModel.CalibrationItterations = itterationsPerStage;
            fundingModel.CalibrationTimeMs = sw.ElapsedMilliseconds;
            sw.Stop();
        }