public Dictionary <string, IPvModel> GenerateScenarios(IPvModel model) { var o = new Dictionary <string, IPvModel>(); var shifts = new double[NScenarios + 1]; var m = model.VanillaModel.Clone(); var d = model.VanillaModel.BuildDate; var pd = d; for (var i = 0; i < NScenarios; i++) { var thisLabel = $"+{i} days"; if (i == 0) { o.Add(thisLabel, model); } else { d = d.AddPeriod(RollType.F, Calendar, 1.Bd()); m = m.RollModel(d, _currencyProvider); var newPvModel = model.Rebuild(m, model.Portfolio.RollWithLifecycle(d, pd)); o.Add(thisLabel, m); pd = d; } } return(o); }
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 static IPvModel FxSpotShift(FxPair pair, double shiftSize, IPvModel model) { var newVanillaModel = FxSpotShift(pair, shiftSize, model.VanillaModel); return(model.Rebuild(newVanillaModel, model.Portfolio)); }
public static IPvModel FxSpotShift(Currency ccy, double shiftSize, IPvModel model) { var newVanillaModel = FxSpotShift(ccy, shiftSize, model.VanillaModel); return(model.Rebuild(newVanillaModel, model.Portfolio)); }
public static IPvModel AssetCurveShift(string assetId, double shiftSize, IPvModel model) { var newVanillaModel = AssetCurveShift(assetId, shiftSize, model.VanillaModel); return(model.Rebuild(newVanillaModel, model.Portfolio)); }