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