Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
 public Dictionary <Tuple <string, string>, IPvModel> GenerateScenarios(IPvModel model)
 {
     if (!string.IsNullOrEmpty(AssetId))
     {
         return(GenerateScenariosAssetFx(model));
     }
     else
     {
         return(GenerateScenariosFxFx(model));
     }
 }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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}");
            }
        }
Beispiel #6
0
        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}");
            }
        }
Beispiel #7
0
        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}");
            }
        }
Beispiel #8
0
        public static ICube BenchmarkRisk(this IPvModel pvModel, FundingInstrumentCollection riskCollection, ICurrencyProvider currencyProvider, Currency reportingCcy)
        {
            var cube      = new ResultCube();
            var dataTypes = new Dictionary <string, Type>
            {
                { "TradeId", typeof(string) },
                { "TradeType", typeof(string) },
                { "Curve", typeof(string) },
                { "RiskDate", typeof(DateTime) },
                { "Benchmark", typeof(string) },
                { "Metric", typeof(string) },
                { "Units", typeof(string) },
                { "BumpSize", typeof(double) },
            };

            cube.Initialize(dataTypes);

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

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

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

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

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


            var insToRisk = new List <IFundingInstrument>();

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

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

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

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

            s.Solve(fModel, newFic);

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

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

            var basePV = newPvModel.PV(reportingCcy);

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

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

                var bumpSize = GetBumpSize(insToRisk[i]);

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

                var fModelb = fModel.DeepClone(null);

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

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

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

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

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

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

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

            return(cube.Sort(new List <string> {
                "Curve", "RiskDate", "TradeId"
            }));
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        public static IPvModel FxSpotShift(FxPair pair, double shiftSize, IPvModel model)
        {
            var newVanillaModel = FxSpotShift(pair, shiftSize, model.VanillaModel);

            return(model.Rebuild(newVanillaModel, model.Portfolio));
        }
Beispiel #11
0
        public static IPvModel FxSpotShift(Currency ccy, double shiftSize, IPvModel model)
        {
            var newVanillaModel = FxSpotShift(ccy, shiftSize, model.VanillaModel);

            return(model.Rebuild(newVanillaModel, model.Portfolio));
        }
Beispiel #12
0
        public static IPvModel AssetCurveShift(string assetId, double shiftSize, IPvModel model)
        {
            var newVanillaModel = AssetCurveShift(assetId, shiftSize, model.VanillaModel);

            return(model.Rebuild(newVanillaModel, model.Portfolio));
        }