public BlackFuturesCurve(IATMVolSurface volSurface, DateTime startDate, DateTime expiryDate, int nTimeSteps, Func <DateTime, double> forwardCurve, string name, IFutureSettingsProvider futureSettingsProvider, Dictionary <DateTime, double> pastFixings = null) { _surface = volSurface; _startDate = startDate; _expiryDate = expiryDate; _numberOfSteps = nTimeSteps; _name = name; _forwardCurve = forwardCurve; _pastFixings = pastFixings ?? (new Dictionary <DateTime, double>()); _futureSettingsProvider = futureSettingsProvider; if (startDate > expiryDate) { throw new Exception("Start date must be before expiry date"); } _codes = new List <string>(); _futuresExpiries = new List <DateTime>(); var fCode = new FutureCode(name, _futureSettingsProvider); var currentCode = fCode.GetFrontMonth(startDate); _codes.Add(currentCode); fCode = new FutureCode(currentCode, DateTime.Today.Year - 2, _futureSettingsProvider); _futuresExpiries.Add(fCode.GetRollDate()); fCode = new FutureCode(currentCode, DateTime.Today.Year - 2, _futureSettingsProvider); var targetCode = fCode.GetFrontMonth(expiryDate); while (currentCode != targetCode) { currentCode = fCode.GetNextCode(false); _futuresExpiries.Add(fCode.GetRollDate()); _codes.Add(currentCode); } }
public FutureCode(string futureCode, int yearBeforeWhich2DigitDatesAreUsed, IFutureSettingsProvider futureSettings) { OriginalCode = futureCode; YearBeforeWhich2DigitDatesAreUsed = yearBeforeWhich2DigitDatesAreUsed; _futureSettingsProvider = futureSettings; //Find the last number var i = 0; int tempNumber; for (i = futureCode.Length; i >= 0; i--) { if (int.TryParse(futureCode[i - 1].ToString(), out tempNumber)) { break; } } //Now we have the index we can hack the end off Postfix = futureCode.Substring(i); futureCode = futureCode.Substring(0, i); //Find when the numbers end for (i = futureCode.Length; i >= 0; i--) { if (!int.TryParse(futureCode[i - 1].ToString(), out tempNumber)) { break; } } YearCode = futureCode.Substring(i); YearNumber = int.Parse(YearCode); YearNumberShort = YearNumber; futureCode = futureCode.Substring(0, i); MonthCode = futureCode[futureCode.Length - 1].ToString(); Prefix = futureCode.Substring(0, futureCode.Length - 1); if (!futureSettings.TryGet(Prefix, out _settings)) { ContractCode = Prefix.ToUpper().Trim(); _settings = futureSettings[ContractCode]; } MonthNumber12 = s_futureMonths.ToList().IndexOf(MonthCode) + 1; MonthNumber = _settings.Months.IndexOf(MonthCode) + 1; ConvertYearCode(); }
public static RiskyFlySurface GetSurfaceForCode(string nymexSymbol, string nymexOptionFilename, string qwackCode, BasicPriceCurve priceCurve, ICalendarProvider calendarProvider, ICurrencyProvider currency, IFutureSettingsProvider futureSettingsProvider) { var parsed = NYMEXOptionParser.Instance.Parse(nymexOptionFilename).Where(r => r.Symbol == nymexSymbol); var(optionExerciseType, optionMarginingType) = OptionTypeFromCode(nymexSymbol); var origin = DateTime.ParseExact(parsed.First().TradeDate, "MM/dd/yyyy", CultureInfo.InvariantCulture); var q = parsed.Where(x => x.Settle > 0).Select(x => new ListedOptionSettlementRecord { CallPut = x.PutCall == "C"?OptionType.C:OptionType.P, ExerciseType = optionExerciseType, MarginType = optionMarginingType, PV = x.Settle, Strike = x.Strike, UnderlyingFuturesCode = Year2to1(x.Contract.Split(' ')[0].Replace(nymexSymbol, qwackCode)), ExpiryDate = OptionExpiryFromNymexRecord(x, calendarProvider), ValDate = origin }).Where(z => z.ExpiryDate > origin).ToList(); var priceDict = priceCurve.PillarLabels.ToDictionary(x => x, x => priceCurve.GetPriceForDate(priceCurve.PillarDatesForLabel(x))); ListedSurfaceHelper.ImplyVols(q, priceDict, new ConstantRateIrCurve(0.0, origin, "dummy", currency.GetCurrency("USD"))); var smiles = ListedSurfaceHelper.ToDeltaSmiles(q, priceDict); var allOptionExpiries = new List <DateTime>(); var lastDate = q.Max(x => x.ExpiryDate); var dummyFutureCode = $"{qwackCode}Z{DateExtensions.SingleDigitYear(DateTime.Today.Year + 2)}"; var c = new FutureCode(dummyFutureCode, DateTime.Today.Year - 2, futureSettingsProvider); var contract = c.GetFrontMonth(origin, false); var lastContract = c.GetFrontMonth(lastDate, false); while (contract != lastContract) { var cc = new FutureCode(contract, origin.Year, futureSettingsProvider); var exp = ListedUtils.FuturesCodeToDateTime(contract); var record = new NYMEXOptionRecord { ContractMonth = exp.Month, ContractYear = exp.Year, Symbol = nymexSymbol }; var optExpiry = OptionExpiryFromNymexRecord(record, calendarProvider); if (optExpiry > origin) { allOptionExpiries.Add(optExpiry); } contract = cc.GetNextCode(false); } var surface = ListedSurfaceHelper.ToRiskyFlySurfaceStepFlat(smiles, origin, priceCurve, allOptionExpiries, currency); return(surface); }
public static BasicPriceCurve GetCurveForCode(string nymexSymbol, string nymexFutureFilename, string qwackCode, IFutureSettingsProvider provider, ICurrencyProvider currency) { var parsed = NYMEXFutureParser.Instance.Parse(nymexFutureFilename).Where(r => r.Symbol == nymexSymbol); var q = parsed.Where(x => x.Settle.HasValue).ToDictionary(x => Year2to1(x.Contract.Replace(nymexSymbol, qwackCode)), x => x.Settle); var datesDict = q.ToDictionary(x => FutureCode.GetExpiryFromCode(x.Key, provider), x => x.Key); var datesVec = datesDict.Keys.OrderBy(x => x).ToArray(); var labelsVec = datesVec.Select(d => datesDict[d]).ToArray(); var pricesVec = labelsVec.Select(l => System.Math.Max(q[l].Value, MinPrice)).ToArray(); var origin = DateTime.ParseExact(parsed.First().TradeDate, "MM/dd/yyyy", CultureInfo.InvariantCulture); var curve = new BasicPriceCurve(origin, datesVec, pricesVec, PriceCurveType.NYMEX, currency, labelsVec) { AssetId = qwackCode, Name = qwackCode, SpotLag = 0.Bd() }; return(curve); }
private static IFundingInstrument ToQwackIns(this CMEFileRecord record, string qwackCode, IFutureSettingsProvider futureSettingsProvider, ICurrencyProvider currencyProvider, Dictionary <string, FloatRateIndex> indices, Dictionary <string, string> forecastCurves) { switch (qwackCode) { case "ED": var edExp = FutureCode.GetExpiryFromCode(MmmYtoCode(record.MMY, qwackCode), futureSettingsProvider); return(new STIRFuture { ContractSize = 1e6, Currency = currencyProvider.GetCurrency("USD"), DCF = 0.25, ConvexityAdjustment = 0, Price = record.SettlePrice.Value, Index = indices["ED"], Expiry = edExp, PillarDate = edExp.AddMonths(3), TradeId = qwackCode + record.MMY, Position = 1, SolveCurve = forecastCurves["ED"], ForecastCurve = forecastCurves["ED"], }); case "FF": var ffEnd = FutureCode.GetExpiryFromCode(MmmYtoCode(record.MMY, qwackCode), futureSettingsProvider); var ffStart = ffEnd.FirstDayOfMonth(); return(new OISFuture { ContractSize = 1e6, Currency = currencyProvider.GetCurrency("USD"), DCF = ffStart.CalculateYearFraction(ffEnd, DayCountBasis.ACT360), Price = record.SettlePrice.Value, Index = indices["FF"], PillarDate = ffEnd, TradeId = qwackCode + record.MMY, Position = 1, SolveCurve = forecastCurves["FF"], ForecastCurve = forecastCurves["FF"], AverageStartDate = ffStart, AverageEndDate = ffEnd, }); default: throw new Exception($"No mapping found for code {qwackCode}"); } }
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 AssetFxMCModel(DateTime originDate, Portfolio portfolio, IAssetFxModel model, McSettings settings, ICurrencyProvider currencyProvider, IFutureSettingsProvider futureSettingsProvider, ICalendarProvider calendarProvider) { if (settings.CompactMemoryMode && settings.AveragePathCorrection) { throw new Exception("Can't use both CompactMemoryMode and PathCorrection"); } _currencyProvider = currencyProvider; _futureSettingsProvider = futureSettingsProvider; _calendarProvider = calendarProvider; Engine = new PathEngine(settings.NumberOfPaths) { Parallelize = settings.Parallelize, CompactMemoryMode = settings.CompactMemoryMode }; OriginDate = originDate; Portfolio = portfolio; Model = model; Settings = settings; switch (settings.Generator) { case RandomGeneratorType.MersenneTwister: Engine.AddPathProcess(new Random.MersenneTwister.MersenneTwister64() { UseNormalInverse = true, UseAnthithetic = false }); break; case RandomGeneratorType.Sobol: var directionNumers = new Random.Sobol.SobolDirectionNumbers(GetSobolFilename()); Engine.AddPathProcess(new Random.Sobol.SobolPathGenerator(directionNumers, 1000) { UseNormalInverse = true }); break; case RandomGeneratorType.Constant: Engine.AddPathProcess(new Random.Constant.Constant() { UseNormalInverse = true, }); break; case RandomGeneratorType.FlipFlop: Engine.AddPathProcess(new Random.Constant.FlipFlop(settings.CreditSettings.ConfidenceInterval, true)); break; } Engine.IncrementDepth(); if (model.CorrelationMatrix != null) { if (settings.LocalCorrelation) { Engine.AddPathProcess(new CholeskyWithTime(model.CorrelationMatrix, model)); } else { Engine.AddPathProcess(new Cholesky(model.CorrelationMatrix)); } Engine.IncrementDepth(); } var lastDate = portfolio.LastSensitivityDate; var assetIds = portfolio.AssetIds(); var assetInstruments = portfolio.Instruments .Where(x => x is IAssetInstrument) .Select(x => x as IAssetInstrument); var fixingsNeeded = new Dictionary <string, List <DateTime> >(); foreach (var ins in assetInstruments) { var fixingsForIns = ins.PastFixingDates(originDate); if (fixingsForIns.Any()) { foreach (var kv in fixingsForIns) { if (!fixingsNeeded.ContainsKey(kv.Key)) { fixingsNeeded.Add(kv.Key, new List <DateTime>()); } fixingsNeeded[kv.Key] = fixingsNeeded[kv.Key].Concat(kv.Value).Distinct().ToList(); } } } //asset processes var fxAssetsToAdd = new List <string>(); var corrections = new Dictionary <string, SimpleAveragePathCorrector>(); foreach (var assetId in assetIds) { if (assetId.Length == 7 && assetId[3] == '/') { fxAssetsToAdd.Add(assetId); continue; } if (!(model.GetVolSurface(assetId) is IATMVolSurface surface)) { throw new Exception($"Vol surface for asset {assetId} could not be cast to IATMVolSurface"); } var fixingDict = fixingsNeeded.ContainsKey(assetId) ? model.GetFixingDictionary(assetId) : null; var fixings = fixingDict != null ? fixingsNeeded[assetId].ToDictionary(x => x, x => fixingDict.GetFixing(x)) : new Dictionary <DateTime, double>(); var futuresSim = settings.ExpensiveFuturesSimulation && (model.GetPriceCurve(assetId).CurveType == PriceCurveType.ICE || model.GetPriceCurve(assetId).CurveType == PriceCurveType.NYMEX); if (futuresSim) { var fwdCurve = new Func <DateTime, double>(t => { return(model.GetPriceCurve(assetId).GetPriceForDate(t)); }); var asset = new BlackFuturesCurve ( startDate: originDate, expiryDate: lastDate, volSurface: surface, forwardCurve: fwdCurve, nTimeSteps: settings.NumberOfTimesteps, name: Settings.FuturesMappingTable[assetId], pastFixings: fixings, futureSettingsProvider: _futureSettingsProvider ); Engine.AddPathProcess(asset); } else { var fwdCurve = new Func <double, double>(t => { var c = model.GetPriceCurve(assetId); var d = originDate.AddYearFraction(t, DayCountBasis.ACT365F); if (c is PriceCurve pc) { d = d.AddPeriod(RollType.F, pc.SpotCalendar, pc.SpotLag); } else if (c is ContangoPriceCurve cc) { d = d.AddPeriod(RollType.F, cc.SpotCalendar, cc.SpotLag); } return(c.GetPriceForDate(d)); }); IATMVolSurface adjSurface = null; var correlation = 0.0; if (settings.ReportingCurrency != model.GetPriceCurve(assetId).Currency) { var fxAdjPair = settings.ReportingCurrency + "/" + model.GetPriceCurve(assetId).Currency; var fxAdjPairInv = model.GetPriceCurve(assetId).Currency + "/" + settings.ReportingCurrency; if (!(model.FundingModel.GetVolSurface(fxAdjPair) is IATMVolSurface adjSurface2)) { throw new Exception($"Vol surface for fx pair {fxAdjPair} could not be cast to IATMVolSurface"); } adjSurface = adjSurface2; if (model.CorrelationMatrix != null) { if (model.CorrelationMatrix.TryGetCorrelation(fxAdjPair, assetId, out var correl)) { correlation = correl; } else if (model.CorrelationMatrix.TryGetCorrelation(fxAdjPairInv, assetId, out var correl2)) { correlation = -correl2; } } } if (settings.McModelType == McModelType.LocalVol) { var asset = new LVSingleAsset ( startDate: originDate, expiryDate: lastDate, volSurface: surface, forwardCurve: fwdCurve, nTimeSteps: settings.NumberOfTimesteps, name: assetId, pastFixings: fixings, fxAdjustSurface: adjSurface, fxAssetCorrelation: correlation ); Engine.AddPathProcess(asset); } else if (settings.McModelType == McModelType.TurboSkew) { var asset = new TurboSkewSingleAsset ( startDate: originDate, expiryDate: lastDate, volSurface: surface, forwardCurve: fwdCurve, nTimeSteps: settings.NumberOfTimesteps, name: assetId, pastFixings: fixings, fxAdjustSurface: adjSurface, fxAssetCorrelation: correlation ); Engine.AddPathProcess(asset); } else { var asset = new BlackSingleAsset ( startDate: originDate, expiryDate: lastDate, volSurface: surface, forwardCurve: fwdCurve, nTimeSteps: settings.NumberOfTimesteps, name: assetId, pastFixings: fixings, fxAdjustSurface: adjSurface, fxAssetCorrelation: correlation ); Engine.AddPathProcess(asset); } if (settings.AveragePathCorrection) { corrections.Add(assetId, new SimpleAveragePathCorrector(new SimpleAveragePathCalculator(assetId) { CompactMode = settings.CompactMemoryMode }, surface, fwdCurve, assetId, fixings, adjSurface, correlation)); } } } //fx pairs var pairsAdded = new List <string>(); var fxPairs = portfolio.FxPairs(model).Concat(fxAssetsToAdd); var payoutCcys = portfolio.Instruments.Select(i => i.Currency); if (payoutCcys.Any(p => p != settings.ReportingCurrency)) { var ccysToAdd = payoutCcys.Where(p => p != settings.ReportingCurrency).Distinct(); var pairsToAdd = ccysToAdd.Select(c => $"{c.Ccy}/{settings.ReportingCurrency}"); fxPairs = fxPairs.Concat(pairsToAdd).Distinct(); } foreach (var fxPair in fxPairs) { var fxPairName = fxPair; var pair = fxPairName.FxPairFromString(_currencyProvider, _calendarProvider); if (pairsAdded.Contains(pair.ToString())) { continue; } if (!(model.FundingModel.VolSurfaces[fxPairName] is IATMVolSurface surface)) { throw new Exception($"Vol surface for fx pair {fxPairName} could not be cast to IATMVolSurface"); } var fwdCurve = new Func <double, double>(t => { var date = originDate.AddYearFraction(t, DayCountBasis.ACT365F); var spotDate = pair.SpotDate(date); return(model.FundingModel.GetFxRate(spotDate, fxPairName)); }); pairsAdded.Add(pair.ToString()); if (settings.McModelType == McModelType.LocalVol) { var asset = new LVSingleAsset ( startDate: originDate, expiryDate: lastDate, volSurface: surface, forwardCurve: fwdCurve, nTimeSteps: settings.NumberOfTimesteps, name: fxPairName ); Engine.AddPathProcess(asset); if (settings.AveragePathCorrection) { corrections.Add(fxPairName, new SimpleAveragePathCorrector(new SimpleAveragePathCalculator(fxPairName) { CompactMode = settings.CompactMemoryMode }, surface, fwdCurve, fxPairName)); } } else if (settings.McModelType == McModelType.TurboSkew) { if (fxPairName.Substring(fxPairName.Length - 3, 3) != settings.ReportingCurrency) {//needs to be drift-adjusted var fxAdjPair = settings.ReportingCurrency + "/" + fxPairName.Substring(fxPairName.Length - 3, 3); if (!(model.FundingModel.VolSurfaces[fxAdjPair] is IATMVolSurface adjSurface)) { throw new Exception($"Vol surface for fx pair {fxAdjPair} could not be cast to IATMVolSurface"); } var correlation = fxPair == fxAdjPair ? -1.0 : 0.0; if (correlation != -1.0 && model.CorrelationMatrix != null) { if (model.CorrelationMatrix.TryGetCorrelation(fxAdjPair, fxPair, out var correl)) { correlation = correl; } } var asset = new TurboSkewSingleAsset ( startDate: originDate, expiryDate: lastDate, volSurface: surface, forwardCurve: fwdCurve, nTimeSteps: settings.NumberOfTimesteps, name: fxPairName, fxAdjustSurface: adjSurface, fxAssetCorrelation: correlation ); Engine.AddPathProcess(asset); if (settings.AveragePathCorrection) { corrections.Add(fxPairName, new SimpleAveragePathCorrector(new SimpleAveragePathCalculator(fxPairName) { CompactMode = settings.CompactMemoryMode }, surface, fwdCurve, fxPairName, null, adjSurface, correlation)); } } else { var asset = new TurboSkewSingleAsset ( startDate: originDate, expiryDate: lastDate, volSurface: surface, forwardCurve: fwdCurve, nTimeSteps: settings.NumberOfTimesteps, name: fxPairName ); Engine.AddPathProcess(asset); if (settings.AveragePathCorrection) { corrections.Add(fxPairName, new SimpleAveragePathCorrector(new SimpleAveragePathCalculator(fxPairName) { CompactMode = settings.CompactMemoryMode }, surface, fwdCurve, fxPairName)); } } } else { if (fxPairName.Substring(fxPairName.Length - 3, 3) != settings.ReportingCurrency) {//needs to be drift-adjusted var fxAdjPair = settings.ReportingCurrency + "/" + fxPairName.Substring(fxPairName.Length - 3, 3); if (!(model.FundingModel.VolSurfaces[fxAdjPair] is IATMVolSurface adjSurface)) { throw new Exception($"Vol surface for fx pair {fxAdjPair} could not be cast to IATMVolSurface"); } var correlation = fxPair == fxAdjPair ? -1.0 : 0.0; if (correlation != -1.0 && model.CorrelationMatrix != null) { if (model.CorrelationMatrix.TryGetCorrelation(fxAdjPair, fxPair, out var correl)) { correlation = correl; } } var asset = new BlackSingleAsset ( startDate: originDate, expiryDate: lastDate, volSurface: surface, forwardCurve: fwdCurve, nTimeSteps: settings.NumberOfTimesteps, name: fxPairName, fxAdjustSurface: adjSurface, fxAssetCorrelation: correlation ); Engine.AddPathProcess(asset); if (settings.AveragePathCorrection) { corrections.Add(fxPairName, new SimpleAveragePathCorrector(new SimpleAveragePathCalculator(fxPairName) { CompactMode = settings.CompactMemoryMode }, surface, fwdCurve, fxPairName, null, adjSurface, correlation)); } } else { var asset = new BlackSingleAsset ( startDate: originDate, expiryDate: lastDate, volSurface: surface, forwardCurve: fwdCurve, nTimeSteps: settings.NumberOfTimesteps, name: fxPairName ); Engine.AddPathProcess(asset); if (settings.AveragePathCorrection) { corrections.Add(fxPairName, new SimpleAveragePathCorrector(new SimpleAveragePathCalculator(fxPairName) { CompactMode = settings.CompactMemoryMode }, surface, fwdCurve, fxPairName)); } } } } //apply path correctin if (settings.AveragePathCorrection && corrections.Any()) { Engine.IncrementDepth(); foreach (var pc in corrections) { Engine.AddPathProcess(pc.Value.PathCalc); } Engine.IncrementDepth(); foreach (var pc in corrections) { Engine.AddPathProcess(pc.Value); } } //payoffs Engine.IncrementDepth(); _payoffs = assetInstruments.ToDictionary(x => x.TradeId, y => new AssetPathPayoff(y, _currencyProvider, _calendarProvider, settings.ReportingCurrency)); if (!settings.AvoidRegressionForBackPricing && _payoffs.Any(x => x.Value.Regressors != null)) { var regressorsToAdd = _payoffs.Where(x => x.Value.Regressors != null) .SelectMany(x => x.Value.Regressors) .Distinct(); foreach (var regressor in regressorsToAdd) { Engine.AddPathProcess(regressor); foreach (var payoff in _payoffs.Where(x => x.Value.Regressors != null)) { if (payoff.Value.Regressors.Any(x => x == regressor)) { payoff.Value.SetRegressor(regressor); } } } Engine.IncrementDepth(); } foreach (var product in _payoffs) { if (settings.AvoidRegressionForBackPricing && (product.Value.AssetInstrument is BackPricingOption || product.Value.AssetInstrument is MultiPeriodBackpricingOption)) { product.Value.VanillaModel = VanillaModel; } Engine.AddPathProcess(product.Value); } var metricsNeedRegression = new[] { BaseMetric.PFE, BaseMetric.KVA, BaseMetric.CVA, BaseMetric.FVA, BaseMetric.EPE }; //Need to calculate PFE if (settings.CreditSettings != null && settings.CreditSettings.ExposureDates != null && settings.ReportingCurrency != null && metricsNeedRegression.Contains(settings.CreditSettings.Metric))//setup for PFE, etc { Engine.IncrementDepth(); switch (settings.CreditSettings.PfeRegressorType) { case PFERegressorType.MultiLinear: _regressor = new LinearPortfolioValueRegressor(settings.CreditSettings.ExposureDates, _payoffs.Values.ToArray(), settings); break; case PFERegressorType.MonoLinear: _regressor = new MonoIndexRegressor(settings.CreditSettings.ExposureDates, _payoffs.Values.ToArray(), settings, true); break; } Engine.AddPathProcess(_regressor); } //Need to calculate expected capital if (settings.CreditSettings != null && settings.CreditSettings.ExposureDates != null && settings.ReportingCurrency != null && settings.CreditSettings.Metric == BaseMetric.ExpectedCapital) { Engine.IncrementDepth(); _capitalCalc = new ExpectedCapitalCalculator(Portfolio, settings.CreditSettings.CounterpartyRiskWeighting, settings.CreditSettings.AssetIdToHedgeGroupMap, settings.ReportingCurrency, VanillaModel, settings.CreditSettings.ExposureDates); Engine.AddPathProcess(_capitalCalc); } Engine.SetupFeatures(); }
public AssetFxModel BuildModel(DateTime valDate, ModelBuilderSpec spec, IFutureSettingsProvider futureSettingsProvider, ICurrencyProvider currencyProvider, ICalendarProvider calendarProvider) { var indices = spec.RateIndices.ToDictionary(x => x.Key, x => new FloatRateIndex(x.Value, calendarProvider, currencyProvider)); var fxPairs = spec.FxPairs.Select(x => new FxPair(x, currencyProvider, calendarProvider)).ToList(); var priceCurves = new List <IPriceCurve>(); var surfaces = new List <IVolSurface>(); var fxSurfaces = new List <IVolSurface>(); foreach (var c in spec.NymexSpecs) { var curve = NYMEXModelBuilder.GetCurveForCode(c.NymexCodeFuture, Path.Combine(_filepath, FilenameNymexFuture), c.QwackCode, futureSettingsProvider, currencyProvider); priceCurves.Add(curve); if (!string.IsNullOrWhiteSpace(c.NymexCodeOption)) { var surface = NYMEXModelBuilder.GetSurfaceForCode(c.NymexCodeOption, Path.Combine(_filepath, FilenameNymexOption), c.QwackCode, curve, calendarProvider, currencyProvider, futureSettingsProvider); surface.AssetId = c.QwackCode; surfaces.Add(surface); } } var irCurves = new Dictionary <string, IrCurve>(); foreach (var c in spec.CmeBaseCurveSpecs) { var ixForThis = new Dictionary <string, FloatRateIndex> { { c.QwackCode, indices[c.FloatRateIndex] } }; var curve = CMEModelBuilder.GetCurveForCode(c.CmeCode, Path.Combine(_filepath, c.IsCbot? FilenameCbot:FilenameCme), c.QwackCode, c.CurveName, ixForThis, new Dictionary <string, string>() { { c.QwackCode, c.CurveName } }, futureSettingsProvider, currencyProvider, calendarProvider); irCurves.Add(c.CurveName, curve); } foreach (var c in spec.CmeBasisCurveSpecs) { var fxPair = fxPairs.Single(x => $"{x.Domestic}{x.Foreign}" == c.FxPair); var curve = CMEModelBuilder.StripFxBasisCurve(Path.Combine(_filepath, FilenameCmeFwdsXml), fxPair, c.CmeFxPair, currencyProvider.GetCurrency(c.Currency), c.CurveName, valDate, irCurves[c.BaseCurveName], currencyProvider, calendarProvider); irCurves.Add(c.CurveName, curve); } foreach (var c in spec.CmeFxFutureSpecs) { var curve = CMEModelBuilder.GetFuturesCurveForCode(c.CmeCodeFut, Path.Combine(_filepath, FilenameCme), currencyProvider); var surface = CMEModelBuilder.GetFxSurfaceForCode(c.CmeCodeOpt, Path.Combine(_filepath, FilenameCme), curve, currencyProvider); surface.AssetId = c.FxPair; fxSurfaces.Add(surface); } var pairMap = spec.CmeBasisCurveSpecs.ToDictionary(x => x.FxPair, x => x.CmeFxPair); var pairCcyMap = spec.CmeBasisCurveSpecs.ToDictionary(x => x.FxPair, x => currencyProvider.GetCurrency(x.Currency)); var spotRates = CMEModelBuilder.GetSpotFxRatesFromFwdFile(Path.Combine(_filepath, FilenameCmeFwdsXml), valDate, pairMap, currencyProvider, calendarProvider); var discountMap = spec.CmeBasisCurveSpecs.ToDictionary(x => pairCcyMap[x.FxPair], x => x.CurveName); foreach (var c in spec.CmxMetalCurves) { var fxPair = fxPairs.Single(x => $"{x.Domestic}{x.Foreign}" == c.MetalPair); var(curve, spotPrice) = COMEXModelBuilder.GetMetalCurveForCode(Path.Combine(_filepath, FilenameCmxFwdsXml), c.CmxSymbol, fxPair, c.CurveName, valDate, irCurves[c.BaseCurveName], currencyProvider, calendarProvider); irCurves.Add(c.CurveName, curve); spotRates.Add(c.MetalPair, spotPrice); discountMap.Add(currencyProvider.GetCurrency(c.Currency), c.CurveName); pairCcyMap.Add(c.MetalPair, currencyProvider.GetCurrency(c.Currency)); if (!string.IsNullOrWhiteSpace(c.CmxOptCode)) { var surface = COMEXModelBuilder.GetMetalSurfaceForCode(c.CmxOptCode, Path.Combine(_filepath, FilenameCmxXml), currencyProvider); surface.AssetId = c.MetalPair; fxSurfaces.Add(surface); } } var fm = new FundingModel(valDate, irCurves, currencyProvider, calendarProvider); var spotRatesByCcy = spotRates.ToDictionary(x => pairCcyMap[x.Key], x => x.Key.StartsWith("USD") ? x.Value : 1.0 / x.Value); var fxMatrix = new FxMatrix(currencyProvider); fxMatrix.Init( baseCurrency: currencyProvider.GetCurrency("USD"), buildDate: valDate, spotRates: spotRatesByCcy, fXPairDefinitions: fxPairs, discountCurveMap: discountMap); fm.SetupFx(fxMatrix); foreach (var fxs in fxSurfaces) { fm.VolSurfaces.Add(fxs.AssetId, fxs); } var o = new AssetFxModel(valDate, fm); o.AddVolSurfaces(surfaces.ToDictionary(s => s.AssetId, s => s)); o.AddPriceCurves(priceCurves.ToDictionary(c => c.AssetId, c => c)); return(o); }
public FutureCode(string futureCodeRoot, IFutureSettingsProvider futureSettings) { _settings = futureSettings[futureCodeRoot]; _futureSettingsProvider = futureSettings; Prefix = futureCodeRoot; }
public static DateTime GetRollFromCode(string code, IFutureSettingsProvider futureSettingsProvider) { var c = new FutureCode(code, DateTime.Today.Year - 2, futureSettingsProvider); return(c.GetRollDate()); }