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 ICube Generate(IPvModel model, Portfolio portfolio = null) { var o = new ResultCube(); o.Initialize(new Dictionary <string, Type> { { "AxisA", typeof(string) }, { "AxisB", typeof(string) } }); var scenarios = GenerateScenarios(model); ICube baseRiskCube = null; if (ReturnDifferential) { var baseModel = model; if (portfolio != null) { baseModel = baseModel.Rebuild(baseModel.VanillaModel, portfolio); } baseRiskCube = GetRisk(baseModel); } var threadLock = new object(); var results = new ICube[scenarios.Count]; var scList = scenarios.ToList(); ParallelUtils.Instance.For(0, scList.Count, 1, i => { var scenario = scList[i]; var pvModel = scenario.Value; if (portfolio != null) { pvModel = pvModel.Rebuild(pvModel.VanillaModel, portfolio); } var result = GetRisk(pvModel); if (ReturnDifferential) { result = result.Difference(baseRiskCube); } results[i] = result; }).Wait(); for (var i = 0; i < results.Length; i++) { o = (ResultCube)o.Merge(results[i], new Dictionary <string, object> { { "AxisA", scList[i].Key.Item1 }, { "AxisB", scList[i].Key.Item2 } }, null, true); } return(o); }
public Dictionary <Tuple <string, string>, IPvModel> GenerateScenarios(IPvModel model) { if (!string.IsNullOrEmpty(AssetId)) { return(GenerateScenariosAssetFx(model)); } else { return(GenerateScenariosFxFx(model)); } }
public Dictionary <string, IPvModel> GenerateScenarios(IPvModel model) { var o = new Dictionary <string, IPvModel>(); var results = new KeyValuePair <string, IPvModel> [NScenarios * 2 + 1]; ParallelUtils.Instance.For(-NScenarios, NScenarios + 1, 1, (i) => { var thisShift = i * ShiftSize; var thisLabel = (string.IsNullOrWhiteSpace(AssetId) ? Ccy.Ccy : AssetId) + "~" + thisShift; if (thisShift == 0) { results[i + NScenarios] = new KeyValuePair <string, IPvModel>(thisLabel, model); } else { if (string.IsNullOrWhiteSpace(AssetId)) { IPvModel shifted; switch (ShiftType) { case MutationType.FlatShift: shifted = FlatShiftMutator.FxSpotShift(Ccy, thisShift, model); break; default: throw new Exception($"Unable to process shift type {ShiftType}"); } results[i + NScenarios] = new KeyValuePair <string, IPvModel>(thisLabel, shifted); } else { IPvModel shifted; switch (ShiftType) { case MutationType.FlatShift: shifted = FlatShiftMutator.AssetCurveShift(AssetId, thisShift, model); break; default: throw new Exception($"Unable to process shift type {ShiftType}"); } results[i + NScenarios] = new KeyValuePair <string, IPvModel>(thisLabel, shifted); } } }).Wait(); foreach (var kv in results) { o.Add(kv.Key, kv.Value); } return(o); }
private ICube GetRisk(IPvModel model) { switch (Metric) { case RiskMetric.AssetCurveDelta: return(model.AssetDelta()); case RiskMetric.FxDelta: return(model.FxDelta(model.VanillaModel.FundingModel.FxMatrix.BaseCurrency, _currencyProvider, false)); default: throw new Exception($"Unable to process risk metric {Metric}"); } }
private ICube GetRisk(IPvModel model) { switch (Metric) { case RiskMetric.AssetCurveDelta: return(model.AssetDeltaSingleCurve(AssetId)); case RiskMetric.AssetVega: return(model.AssetVega(model.VanillaModel.FundingModel.FxMatrix.BaseCurrency)); default: throw new Exception($"Unable to process risk metric {Metric}"); } }
private ICube GetRisk(IPvModel model) { switch (Metric) { case RiskMetric.AssetCurveDelta: return(model.AssetDelta()); //case RiskMetric.AssetCurveDeltaGamma: // return portfolio.AssetDeltaGamma(model); case RiskMetric.FxDelta: return(model.FxDeltaSpecific(_currencyProvider.GetCurrency("ZAR"), FxPairsForDelta, _currencyProvider, false)); //case RiskMetric.FxDeltaGamma: // return portfolio.FxDelta(model, _currencyProvider.GetCurrency("ZAR"), _currencyProvider, true); default: throw new Exception($"Unable to process risk metric {Metric}"); } }
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" })); }
private Dictionary <Tuple <string, string>, IPvModel> GenerateScenariosAssetFx(IPvModel model) { var o = new Dictionary <Tuple <string, string>, IPvModel>(); var axisLength = NScenarios * 2 + 1; var results = new KeyValuePair <Tuple <string, string>, IPvModel> [axisLength * axisLength]; ParallelUtils.Instance.For(-NScenarios, NScenarios + 1, 1, (i) => { var thisShiftAsset = i * ShiftSizeAsset; var thisLabelAsset = AssetId + "~" + thisShiftAsset; var assetIx = i + NScenarios; IPvModel shifted; if (thisShiftAsset == 0) { shifted = model; } else { switch (ShiftType) { case MutationType.FlatShift: shifted = FlatShiftMutator.AssetCurveShift(AssetId, thisShiftAsset, model); break; default: throw new Exception($"Unable to process shift type {ShiftType}"); } } for (var ifx = -NScenarios; ifx < NScenarios + 1; ifx++) { var fxIx = ifx + NScenarios; var thisShiftFx = ifx * ShiftSizeFx; var thisLabelFx = Ccy.Ccy + "~" + thisShiftFx; IPvModel shiftedFx; if (thisShiftAsset == 0) { shiftedFx = shifted; } else { shiftedFx = FlatShiftMutator.FxSpotShift(Ccy, thisShiftFx, shifted); } results[assetIx * axisLength + fxIx] = new KeyValuePair <Tuple <string, string>, IPvModel>( new Tuple <string, string>(thisLabelAsset, thisLabelFx), shiftedFx); } }).Wait(); foreach (var kv in results) { o.Add(kv.Key, kv.Value); } return(o); }
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)); }