예제 #1
0
        public IPvModel Rebuild(IAssetFxModel newVanillaModel, Portfolio portfolio)
        {
            var m = newVanillaModel.Clone();

            m.AttachPortfolio(portfolio);
            return(m);
        }
예제 #2
0
        public static IAssetFxModel FxSpotShift(Currency ccy, double shiftSize, IAssetFxModel model)
        {
            var o    = model.Clone();
            var spot = model.FundingModel.FxMatrix.GetSpotRate(ccy);

            o.FundingModel.FxMatrix.SpotRates[ccy] = spot + shiftSize;
            return(o);
        }
예제 #3
0
        public static IAssetFxModel FxSpotShift(FxPair pair, double shiftSize, IAssetFxModel model)
        {
            var o = model.Clone();

            if (pair.Domestic == model.FundingModel.FxMatrix.BaseCurrency)
            {
                var spot = model.FundingModel.FxMatrix.GetSpotRate(pair.Foreign);
                o.FundingModel.FxMatrix.SpotRates[pair.Foreign] = spot + shiftSize;
            }
            else if (pair.Foreign == model.FundingModel.FxMatrix.BaseCurrency)
            {
                var spot = model.FundingModel.FxMatrix.GetSpotRate(pair.Domestic);
                o.FundingModel.FxMatrix.SpotRates[pair.Domestic] = 1 / (1 / spot + shiftSize);
            }
            else
            {
                throw new Exception("Shifted FX pair must contain base currency of model");
            }

            return(o);
        }
예제 #4
0
        public void Process()
        {
            var currentFixingDate = _assetFxModel.BuildDate;

            while (currentFixingDate <= _endDate)
            {
                currentFixingDate = currentFixingDate.AddDays(1);
                _assetFxModel     = _assetFxModel.RollModel(currentFixingDate, _currencyProvider);
            }

            ParallelUtils.Instance.For(0, _calculationDates.Length, 1, i =>
            {
                var d        = _calculationDates[i];
                var epe      = _epeValues[i];
                var newModel = _assetFxModel.Clone();
                newModel.OverrideBuildDate(d);

                var ead     = _portfolio.SaCcrEAD(epe, newModel, _reportingCurrency, _assetIdToGroupMap);
                var capital = _counterpartyRiskWeight * ead;
                if (!_ead.ContainsKey(d))
                {
                    lock (_threadLock)
                    {
                        if (!_ead.ContainsKey(d))
                        {
                            _ead.Add(d, 0.0);
                        }
                    }
                }
                if (double.IsNaN(capital) || double.IsInfinity(capital))
                {
                    throw new Exception("Invalid capital generated");
                }

                lock (_threadLock)
                {
                    _ead[d] += capital;
                }
            }).Wait();
        }
예제 #5
0
        public static IAssetFxModel AssetCurveShift(string assetId, double shiftSize, IAssetFxModel model)
        {
            var o     = model.Clone();
            var curve = model.GetPriceCurve(assetId);

            switch (curve)
            {
            case PriceCurve pc:
                var npc = new PriceCurve(pc.BuildDate, pc.PillarDates, pc.Prices.Select(p => p + shiftSize).ToArray(), pc.CurveType, pc.CurrencyProvider, pc.PillarLabels)
                {
                    AssetId        = pc.AssetId,
                    Name           = pc.Name,
                    CollateralSpec = pc.CollateralSpec,
                    Currency       = pc.Currency,
                };
                o.AddPriceCurve(assetId, npc);
                break;

            default:
                throw new Exception("Unable to mutate curve type");
            }
            return(o);
        }
예제 #6
0
        public static double[] EPE_Approx(DateTime[] exposureDates, Portfolio portfolio, IAssetFxModel model, Currency reportingCurrency, ICurrencyProvider currencyProvider, Dictionary <DateTime, IAssetFxModel> models = null)
        {
            var pfu = portfolio.UnWrapWrappers();
            var pf  = pfu.UnStripStrips();

            //if (pf.AssetIds().Length != 1 || pf.FxPairs(model).Length != 0)
            //    throw new Exception("Portfolio can only contain a single asset and no FX indices for approximate CVA");

            if (!pf.Instruments.All(x => x is AsianSwap))
            {
                throw new Exception("Approximate CVA only works for Asian Swap instruments");
            }

            if (pf.Instruments
                .Select(x => Sign((x as AsianSwap).Notional))
                .Distinct()
                .Count() != 1)
            {
                throw new Exception("All swaps must be in same direction");
            }

            var cp = (pf.Instruments
                      .Select(x => Sign((x as AsianSwap).Notional))
                      .Distinct().First() == 1.0) ? OptionType.C : OptionType.P;

            var replicatingPF = new Portfolio
            {
                Instruments = pf.Instruments
                              .Select(s => s as AsianSwap)
                              .Select(s =>
                                      new AsianOption
                {
                    AssetId            = s.AssetId,
                    AssetFixingId      = s.AssetFixingId,
                    AverageStartDate   = s.AverageStartDate,
                    AverageEndDate     = s.AverageEndDate,
                    CallPut            = cp,
                    Strike             = s.Strike,
                    Counterparty       = s.Counterparty,
                    DiscountCurve      = s.DiscountCurve,
                    FixingCalendar     = s.FixingCalendar,
                    FixingDates        = s.FixingDates,
                    HedgingSet         = s.HedgingSet,
                    Notional           = Abs(s.Notional),
                    PaymentCalendar    = s.PaymentCalendar,
                    PaymentCurrency    = s.PaymentCurrency,
                    PaymentDate        = s.PaymentDate,
                    PaymentLag         = s.PaymentLag,
                    PaymentLagRollType = s.PaymentLagRollType,
                    SpotLag            = s.SpotLag,
                    SpotLagRollType    = s.SpotLagRollType,
                    PortfolioName      = s.PortfolioName,
                    TradeId            = s.TradeId ?? Guid.NewGuid().ToString(),
                    FxConversionType   = s.FxConversionType,
                    FxFixingDates      = s.FxFixingDates,
                    FxFixingId         = s.FxFixingId
                } as IInstrument).ToList()
            };

            var exposures = new double[exposureDates.Length];
            var m         = model.Clone();

            for (var i = 0; i < exposures.Length; i++)
            {
                if (models != null)
                {
                    m = models[exposureDates[i]];
                }
                else
                {
                    m = m.RollModel(exposureDates[i], currencyProvider);
                }

                var pvCube = replicatingPF.PV(m, reportingCurrency);
                foreach (var row in pvCube.GetAllRows())
                {
                    var tradeId = (string)row.MetaData[0];
                    var ins     = replicatingPF.Instruments.Single(x => x.TradeId == tradeId) as AsianOption;
                    var df      = m.FundingModel.GetCurve(ins.DiscountCurve).GetDf(m.BuildDate, ins.PaymentDate);
                    exposures[i] += row.Value / df;
                }
                exposures[i] = Max(0, exposures[i]);
            }

            return(exposures);
        }
예제 #7
0
        public void Process(IPathBlock block)
        {
            for (var path = 0; path < block.NumberOfPaths; path += Vector <double> .Count)
            {
                var stepsByFactor = new Dictionary <int, Vector <double>[]>();
                foreach (var ix in _assetIndices)
                {
                    stepsByFactor.Add(ix, block.GetStepsForFactor(path, ix).ToArray());
                }

                var indexCounter = 0;
                var nextIndex    = _calculationDateIndices[indexCounter];

                var steps = stepsByFactor.First().Value;
                var fixingDictionaries = _assetFxModel.FixingDictionaryNames.ToDictionary(x => x, x => (IFixingDictionary) new FixingDictionary(_assetFxModel.GetFixingDictionary(x)));

                for (var i = 0; i < steps.Length; i++)
                {
                    var d = _timeFeature.Dates[i];
                    for (var j = 0; j < Vector <double> .Count; j++)
                    {
                        for (var a = 0; a < _assetIndices.Length; a++)
                        {
                            if (!fixingDictionaries.TryGetValue(_assetIds[a], out var fd))
                            {
                                throw new Exception($"Fixing dictionary not found for asset {_assetIds[a]} ");
                            }
                            fd[d] = stepsByFactor[a][i][j];
                        }
                    }

                    if (i == nextIndex)
                    {
                        var currentDate = _calculationDates[indexCounter];
                        var newModel    = _assetFxModel.Clone();
                        newModel.OverrideBuildDate(currentDate);
                        newModel.AddFixingDictionaries(fixingDictionaries);

                        var spotsByAsset = stepsByFactor.ToDictionary(x => x.Key, x => x.Value[i]);
                        for (var j = 0; j < Vector <double> .Count; j++)
                        {
                            //build on-path price curves in model
                            foreach (var spot in spotsByAsset)
                            {
                                var assetId     = _assetIds[spot.Key];
                                var baseCurve   = _assetFxModel.GetPriceCurve(assetId);
                                var spotOnCurve = baseCurve.GetPriceForFixingDate(currentDate);
                                var ratio       = spot.Value[j] / spotOnCurve;
                                var newCurve    = new FactorPriceCurve(baseCurve, ratio);
                                newModel.AddPriceCurve(assetId, newCurve);
                            }

                            var ead     = _portfolio.SaCcrEAD(newModel, _reportingCurrency, _assetIdToGroupMap);
                            var capital = _counterpartyRiskWeight * ead;
                            if (!_expectedCapital.ContainsKey(currentDate))
                            {
                                lock (_threadLock)
                                {
                                    if (!_expectedCapital.ContainsKey(currentDate))
                                    {
                                        _expectedCapital.Add(currentDate, 0.0);
                                    }
                                }
                            }
                            if (double.IsNaN(capital) || double.IsInfinity(capital))
                            {
                                throw new Exception("Invalid capital generated");
                            }

                            _expectedCapital[currentDate] += capital;
                        }

                        indexCounter++;
                        nextIndex = indexCounter < _calculationDateIndices.Length
                            ? _calculationDateIndices[indexCounter] : int.MaxValue;
                    }
                }
            }
        }