/// <summary> /// Finds the spread, if it exists, and add to the market quote. Otherwise returns 0. /// </summary> /// <param name="quotations">The quotations.</param> /// <returns></returns> public static BasicQuotation GetInverseMarketQuoteAddSpreadAndNormalise(IList <BasicQuotation> quotations) { //Get the market quote. var normalisedValue = BasicQuotationHelper.Create(0.0m, "MarketQuote", "DecimalRate"); var value = FindQuotationByMeasureType("MarketQuote", quotations); if (value != null) { normalisedValue = NormalisePriceUnits(value, "DecimalRate"); normalisedValue.value = -normalisedValue.value; } //Get the spread. var normalisedspread = BasicQuotationHelper.Create(0.0m, "Spread", "DecimalRate"); var quote = FindQuotationByMeasureType("Spread", quotations); if (quote != null) { normalisedspread = NormalisePriceUnits(quote, "DecimalRate"); } //return the sum. normalisedValue.value = normalisedValue.value + normalisedspread.value; return(normalisedValue); }
/// <summary> /// Gets the spot date relative to the date provided. /// </summary> /// <param name="logger">The logger.</param> /// <param name="cache">The cache.</param> /// <param name="nameSpace"></param> /// <param name="baseDate"></param> /// <param name="fixingCalendar"></param> /// <param name="rollCalendar"></param> /// <returns></returns> public DateTime GetSpotDate(ILogger logger, ICoreCache cache, string nameSpace, DateTime baseDate, IBusinessCalendar fixingCalendar, IBusinessCalendar rollCalendar) { //var bq = BasicQuotationHelper.Create(.79m, "MarketQuote"); no magic constants in code var bq = BasicQuotationHelper.Create(0, "MarketQuote"); var bav = BasicAssetValuationHelper.Create(bq); //var quotedCurrencyPair = commodityCurveId.QuotedCurrencyPair; var quotedCurrencyPair = ((FpML.V5r10.Reporting.FxCurve)GetFpMLData().First).quotedCurrencyPair; var identifier = quotedCurrencyPair.currency1.Value + quotedCurrencyPair.currency2.Value + "-CommoditySpot-SP"; var fxspot = new FxRateAsset { id = identifier, currency = new IdentifiedCurrency { Value = quotedCurrencyPair.currency1.Value }, quotedCurrencyPair = quotedCurrencyPair }; var priceableAsset = (IPriceableCommodityAssetController)PriceableAssetFactory.Create(logger, cache, nameSpace, fxspot.id, baseDate, bav, fixingCalendar, rollCalendar); var spot = priceableAsset.GetRiskMaturityDate(); return(spot); }
/// <summary> /// Creates the specified assets in a quoted asset set. /// </summary> /// <param name="assetIdentifiers">The asset identifiers.</param> /// <param name="values">The adjusted rates.</param> /// <param name="measureTypes">The measure types. Currently supports MarketQuote and Volatility.</param> /// <param name="priceQuoteUnits">The price quote units. Currently supports Rates and LogNormalVolatility.</param> /// <returns></returns> public static QuotedAssetSet Parse(string[] assetIdentifiers, Decimal[] values, String[] measureTypes, String[] priceQuoteUnits) { if (assetIdentifiers.Length != values.Length && assetIdentifiers.Length != priceQuoteUnits.Length && assetIdentifiers.Length != measureTypes.Length) { throw new ArgumentOutOfRangeException(nameof(values), "the rates do not match the number of assets"); } var quotedAssetSetFactory = new QuotedAssetSetFactory(); foreach (string assetIdentifier in assetIdentifiers.Distinct()) { int index = 0; var bav = new BasicAssetValuation { objectReference = new AnyAssetReference { href = assetIdentifier } }; var bqs = new List <BasicQuotation>(); foreach (string ids in assetIdentifiers) { index++; if (ids != assetIdentifier) { continue; } BasicQuotation bq = BasicQuotationHelper.Create(values[index - 1], measureTypes[index - 1], priceQuoteUnits[index - 1]); bqs.Add(bq); } bav.quote = bqs.ToArray(); quotedAssetSetFactory.AddAssetAndQuotes(Parse(assetIdentifier), bav); } return(quotedAssetSetFactory.Create()); }
/// <summary> /// Maps from price units other than decimals, to a decimal for consumption primarily by a rate curve. /// </summary> /// <param name="rateQuotationType">The rate quotation type. eg MarketQuote, Spread or Volatility.</param> /// <param name="fromQuote">The basic quotation to be mapped from ie normalised.</param> /// <param name="convertToType">The type to convert to: only implemented for decimals.</param> /// <returns></returns> public static BasicQuotation NormaliseGeneralPriceUnits(String rateQuotationType, BasicQuotation fromQuote, String convertToType) { if (fromQuote.measureType.Value != "MarketQuote" || convertToType != "DecimalRate" && convertToType != "DecimalValue") { return(BasicQuotationHelper.Clone(fromQuote)); } switch (fromQuote.quoteUnits.Value) { case "IRFuturesPrice": //Format for this is 9500. { return(BasicQuotationHelper.Create((100 - fromQuote.value) / 100, rateQuotationType, convertToType)); } case "Volatility": //Format for this is 7.00 { return(BasicQuotationHelper.Create(fromQuote.value / 100, rateQuotationType, convertToType)); } case "Rate": //Format for this is 7.00 { return(BasicQuotationHelper.Create(fromQuote.value / 100, rateQuotationType, convertToType)); } case "DecimalValue": case "DecimalVolatility": case "LognormalVolatility": case "NormalVolatility": case "DecimalRate": //Format is .07 { return(BasicQuotationHelper.Create(fromQuote.value, rateQuotationType, convertToType)); } case "DecimalSpread": //Format is .07 { return(BasicQuotationHelper.Create(fromQuote.value, rateQuotationType, convertToType)); } case "FuturesPrice": //Format is 95.00 { return(BasicQuotationHelper.Create((100 - fromQuote.value) / 100, rateQuotationType, convertToType)); } case "Premium": case "DirtyPrice": case "Price": //Format is .07 { return(BasicQuotationHelper.Create(fromQuote.value, rateQuotationType, convertToType)); } case "ForwardValue": //Format is .07 { return(BasicQuotationHelper.Create(fromQuote.value, rateQuotationType, convertToType)); } case "FxRate": //Format is in units. { return(BasicQuotationHelper.Create(fromQuote.value, rateQuotationType, convertToType)); } default: { return(BasicQuotationHelper.Create(fromQuote.value, rateQuotationType, convertToType)); } } }
/// <summary> /// Maps from decimal price units to a other types, mainly for display purposes.. /// </summary> /// <param name="toQuote">The basic quotation to be mapped to ie de-normalised.</param> /// <param name="convertFromType">The type to convert from: only implemented for decimals.</param> /// <returns></returns> public static BasicQuotation DeNormalisePriceUnits(BasicQuotation toQuote, string convertFromType) { const string rateQuotationType = PriceableSimpleRateAsset.RateQuotationType; if (toQuote.measureType.Value != rateQuotationType || (convertFromType != "DecimalRate" && convertFromType != "DecimalValue")) { return(BasicQuotationHelper.Clone(toQuote)); } switch (toQuote.quoteUnits.Value) { case "IRFuturesPrice": //Format for this is 9500. { return(BasicQuotationHelper.Create(100 - toQuote.value * 100, rateQuotationType, toQuote.quoteUnits.Value)); } case "Volatility": //Format for this is 7.00 { return(BasicQuotationHelper.Create(toQuote.value * 100, rateQuotationType, toQuote.quoteUnits.Value)); } case "Rate": //Format for this is 7.00 { return(BasicQuotationHelper.Create(toQuote.value * 100, rateQuotationType, toQuote.quoteUnits.Value)); } case "DecimalValue": case "DecimalVolatility": case "LognormalVolatility": case "NormalVolatility": case "DecimalRate": //Format is .07 { return(BasicQuotationHelper.Create(toQuote.value, rateQuotationType, toQuote.quoteUnits.Value)); } case "DecimalSpread": //Format is .07 { return(BasicQuotationHelper.Create(toQuote.value, rateQuotationType, toQuote.quoteUnits.Value)); } case "FuturesPrice": //Format is 95.00 { return(BasicQuotationHelper.Create(100 - toQuote.value * 100, rateQuotationType, toQuote.quoteUnits.Value)); } case "Premium": case "DirtyPrice": case "Price": //Format is in units. { return(BasicQuotationHelper.Create(toQuote.value, rateQuotationType, toQuote.quoteUnits.Value)); } case "ForwardValue": //Format is in units. { return(BasicQuotationHelper.Create(toQuote.value, rateQuotationType, toQuote.quoteUnits.Value)); } case "FxRate": //Format is in units. { return(BasicQuotationHelper.Create(toQuote.value, rateQuotationType, toQuote.quoteUnits.Value)); } default: { return(BasicQuotationHelper.Create(toQuote.value, rateQuotationType, toQuote.quoteUnits.Value)); } } }
/// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="cache"></param> /// <param name="nameSpace"></param> /// <param name="properties"></param> /// <param name="expiries"></param> /// <param name="vols"></param> /// <param name="inputInstruments"></param> /// <param name="inputSwapRates"></param> /// <param name="inputBlackVolRates"></param> protected ExpiryTermStrikeVolatilitySurface(ILogger logger, ICoreCache cache, String nameSpace, NamedValueSet properties, DateTime[] expiries, double[] vols, string[] inputInstruments, double[] inputSwapRates, double[] inputBlackVolRates) { Algorithm = PropertyHelper.ExtractAlgorithm(properties); PricingStructureIdentifier = new VolatilitySurfaceIdentifier(properties); var surfaceId = (VolatilitySurfaceIdentifier)PricingStructureIdentifier; var expiryLength = expiries.Length; var pointIndex = 0; var points = new PricingStructurePoint[expiryLength]; _matrixIndexHelper = new SortedList <ExpiryTenorStrikeKey, int>(new ExpiryTenorStrikeKey()); for (var expiryIndex = 0; expiryIndex < expiryLength; expiryIndex++) { // extract the current expiry var expiryKeyPart = expiries[expiryIndex]; var key = new ExpiryTenorStrikeKey(expiryKeyPart.ToString(CultureInfo.InvariantCulture), 0); _matrixIndexHelper.Add(key, pointIndex); // Add the value to the points array (dataPoints entry in the matrix) var coordinates = new PricingDataPointCoordinate[1]; coordinates[0] = new PricingDataPointCoordinate { expiration = new TimeDimension[1] }; coordinates[0].expiration[0] = new TimeDimension { Items = new object[] { expiries[expiryIndex] } }; var pt = new PricingStructurePoint { value = (decimal)vols[expiryIndex], valueSpecified = true, coordinate = coordinates, }; points[pointIndex++] = pt; } // Record the row/column sizes of the inputs _matrixRowCount = expiries.Length; _matrixColumnCount = 1; PricingStructure = CreateVolatilityRepresentation(surfaceId); PricingStructureValuation = CreateDataPoints(points, surfaceId); if (inputInstruments != null) { int inputCount = inputInstruments.GetUpperBound(0); var assetQuotes = new List <BasicAssetValuation>(); var assetSet = new List <Asset>(); var itemsList = new List <ItemsChoiceType19>(); for (int i = 0; i <= inputCount; i++) { var assetProperties = new PriceableAssetProperties(inputInstruments[i]); assetSet.Add(new SimpleIRSwap { id = inputInstruments[i], term = assetProperties.TermTenor }); var rateQuote = BasicQuotationHelper.Create((decimal)inputSwapRates[i], AssetMeasureEnum.MarketQuote, PriceQuoteUnitsEnum.DecimalRate); var volQuote = BasicQuotationHelper.Create((decimal)inputBlackVolRates[i], AssetMeasureEnum.Volatility, PriceQuoteUnitsEnum.LogNormalVolatility); assetQuotes.Add(new BasicAssetValuation { objectReference = new AnyAssetReference { href = inputInstruments[i] }, definitionRef = assetProperties.TermTenor.ToString(), quote = new[] { rateQuote, volQuote } }); itemsList.Add(ItemsChoiceType19.simpleIrSwap);//TODO NOt actually correct. } var instrumentSet = new InstrumentSet { Items = assetSet.ToArray(), ItemsElementName = itemsList.ToArray() }; ((VolatilityMatrix)PricingStructureValuation).inputs = new QuotedAssetSet { assetQuote = assetQuotes.ToArray(), instrumentSet = instrumentSet }; } // Generate an interpolator to use double[] expiryTerms = expiries.Select(a => (surfaceId.BaseDate - a).TotalDays / 365d).ToArray(); var holder = new PricingStructureAlgorithmsHolder(logger, cache, nameSpace, surfaceId.PricingStructureType, surfaceId.Algorithm); var curveInterpolationMethod = InterpolationMethodHelper.Parse(holder.GetValue("CurveInterpolation")); Interpolator = new VolSurfaceInterpolator(expiryTerms, new double[] { 1 }, new Matrix(vols), curveInterpolationMethod, true); }
/// <summary> /// Calculates the specified model data. /// </summary> /// <param name="modelData">The model data.</param> /// <returns></returns> public override BasicAssetValuation Calculate(IAssetControllerData modelData) { ModelData = modelData; AnalyticsModel = new BondAssetAnalytic(); var metrics = MetricsHelper.GetMetricsToEvaluate(Metrics, AnalyticsModel.Metrics); // Determine if DFAM has been requested - if so that's all we evaluate - every other metric is ignored var metricsToEvaluate = metrics.ToArray(); var analyticModelParameters = new BondAssetParameters(); CalculationResults = new BondAssetResults(); var marketEnvironment = modelData.MarketEnvironment; //IRateCurve rate forecast curve = null; IRateCurve rateDiscountCurve = null; //0. Set the valuation date and recalculate the settlement date. This could mean regenerating all the coupon dates as well //Alternatively the bond can be recreated with a different base date = valuation date. //TODO Check that the dates are correct and that the last coupon date is used. //Set the purchase price. analyticModelParameters.PurchasePrice = PurchasePrice; //1. instantiate curve if (marketEnvironment.GetType() == typeof(SimpleMarketEnvironment)) { rateDiscountCurve = (IRateCurve)((ISimpleMarketEnvironment)marketEnvironment).GetPricingStructure(); SwapDiscountCurveName = rateDiscountCurve.GetPricingStructureId().UniqueIdentifier; } if (marketEnvironment.GetType() == typeof(SimpleRateMarketEnvironment)) { rateDiscountCurve = ((ISimpleRateMarketEnvironment)marketEnvironment).GetRateCurve(); SwapDiscountCurveName = rateDiscountCurve.GetPricingStructureId().UniqueIdentifier; } if (marketEnvironment.GetType() == typeof(SwapLegEnvironment)) { rateDiscountCurve = ((ISwapLegEnvironment)marketEnvironment).GetDiscountRateCurve(); SwapDiscountCurveName = rateDiscountCurve.GetPricingStructureId().UniqueIdentifier; } if (marketEnvironment.GetType() == typeof(MarketEnvironment)) { var bondCurve = (IBondCurve)modelData.MarketEnvironment.GetPricingStructure(BondCurveName); if (bondCurve != null) { var marketDataType = bondCurve.GetPricingStructureId().Properties.GetValue <string>(AssetMeasureEnum.MarketQuote.ToString(), false); if (marketDataType != null && marketDataType == BondPriceEnum.YieldToMaturity.ToString()) { IsYTMQuote = true; } //TODO handle the other cases like: AssetSwapSpread; DirtyPrice and ZSpread. var mq = (decimal)bondCurve.GetYieldToMaturity(modelData.ValuationDate, SettlementDate); Quote = BasicQuotationHelper.Create(mq, AssetMeasureEnum.MarketQuote.ToString(), PriceQuoteUnitsEnum.DecimalRate.ToString()); } //The forecast rate curve will need to be set if it is a floating rate note. rateDiscountCurve = (IRateCurve)modelData.MarketEnvironment.GetPricingStructure(SwapDiscountCurveName); } //2. Set the rate and the Multiplier analyticModelParameters.Multiplier = Multiplier; analyticModelParameters.Quote = QuoteValue; analyticModelParameters.CouponRate = GetCouponRate(); analyticModelParameters.NotionalAmount = Notional; analyticModelParameters.Frequency = Frequency; analyticModelParameters.IsYTMQuote = IsYTMQuote; analyticModelParameters.AccruedFactor = GetAccruedFactor(); analyticModelParameters.RemainingAccruedFactor = GetRemainingAccruedFactor(); //3. Get the discount factors analyticModelParameters.PaymentDiscountFactors = GetDiscountFactors(rateDiscountCurve, AdjustedPeriodDates, modelData.ValuationDate); //4. Get the respective year fractions analyticModelParameters.AccrualYearFractions = GetYearFractions(); //5. Get the Weightings Weightings = CreateWeightings(CDefaultWeightingValue, analyticModelParameters.PaymentDiscountFactors.Length); analyticModelParameters.Weightings = Weightings; //6. Set the analytic input parameters and Calculate the respective metrics AnalyticModelParameters = analyticModelParameters; CalculationResults = AnalyticsModel.Calculate <IBondAssetResults, BondAssetResults>(analyticModelParameters, metricsToEvaluate); return(GetValue(CalculationResults)); }
protected RequestContext ConvertStandardAssetQuotesToProviderInstrFieldCodes( MDSRequestType requestType, QuotedAssetSet standardQuotedAssetSet) { // extract assets/quotes that require market quotes var standardAssets = new List <Asset>(); var standardQuotes = new List <BasicQuotation>(); { // build a request/response map (indexed by instrument id) var instrumentMap = new Dictionary <string, Asset>(); //List<Pair<Asset, BasicQuotation>> completeAssetQuotes = new List<Pair<Asset, BasicQuotation>>(); foreach (Asset asset in standardQuotedAssetSet.instrumentSet.Items) { instrumentMap[asset.id.ToLower()] = asset; } foreach (BasicAssetValuation quoteInstr in standardQuotedAssetSet.assetQuote) { string instrId = quoteInstr.objectReference.href; if (!instrumentMap.TryGetValue(instrId.ToLower(), out var asset)) { throw new ApplicationException($"Cannot find instrument '{instrId}' for assetQuote"); } foreach (BasicQuotation quoteField in quoteInstr.quote) { if (quoteField.valueSpecified) { // value provided - don't get from market //completeAssetQuotes.Add(new Pair<Asset, BasicQuotation>(asset, quoteField)); } else { // value not supplied - get from market BasicQuotation quote = BasicQuotationHelper.Clone(quoteField); standardAssets.Add(asset); standardQuotes.Add(quote); } } } } var requestItems = new List <RequestItem>(); var instrConversionMap = new Dictionary <string, string>(); var instrUniquenessMap = new Dictionary <string, string>(); var internalInstrIds = new List <string>(); var fieldConversionMap = new Dictionary <string, string>(); var fieldUniquenessMap = new Dictionary <string, string>(); var internalFieldIds = new List <string>(); Logger.LogDebug(" Mappings :"); for (int i = 0; i < standardAssets.Count; i++) { // map asset to provider instrument id Asset standardAsset = standardAssets[i]; string internalInstrId = standardAsset.id; internalInstrIds.Add(internalInstrId); string providerInstrId = _marketDataMap.Convert( MDSDictionaryType.Instrument, requestType, MDSProviderId.GlobalIB, ProviderId, internalInstrId, ConvertFailMode.ThrowException); // update 1-way map instrConversionMap[internalInstrId.ToLower()] = providerInstrId; instrUniquenessMap[providerInstrId.ToLower()] = providerInstrId; // map quote to provider field name BasicQuotation standardQuote = standardQuotes[i]; string internalFieldId = standardQuote.GetStandardFieldName(); internalFieldIds.Add(internalFieldId); string providerFieldId = _marketDataMap.Convert( MDSDictionaryType.FieldName, requestType, MDSProviderId.GlobalIB, ProviderId, internalFieldId, ConvertFailMode.ThrowException); // update 1-way map fieldConversionMap[internalFieldId.ToLower()] = providerFieldId; fieldUniquenessMap[providerFieldId.ToLower()] = providerFieldId; // get provider units string providerUnitsId = _marketDataMap.Convert( MDSDictionaryType.QuoteUnits, requestType, MDSProviderId.GlobalIB, ProviderId, String.Format("{0}/{1}", internalInstrId, internalFieldId), ConvertFailMode.ThrowException); var requestItem = new RequestItem { StandardAsset = standardAsset, StandardQuote = standardQuote, StandardUnits = PriceQuoteUnitsScheme.ParseEnumString(standardQuote.quoteUnits.Value), ProviderInstrumentId = providerInstrId, ProviderFieldName = providerFieldId, ProviderUnits = PriceQuoteUnitsScheme.ParseEnumString(providerUnitsId) }; requestItems.Add(requestItem); // debug Logger.LogDebug(" [{0}] '{1}/{2}' ({3}) --> '{4}/{5}' ({6})", i, internalInstrIds[i], internalFieldIds[i], standardQuote.quoteUnits.Value, instrConversionMap[internalInstrIds[i].ToLower()], fieldConversionMap[internalFieldIds[i].ToLower()], providerUnitsId); // end debug } var providerInstrIds = new List <string>(instrUniquenessMap.Values); var providerFieldIds = new List <string>(fieldUniquenessMap.Values); // build provider instr/field code sets - todo - for now just build 1 var results = new List <ProviderInstrFieldCodeSet>(); var result = new ProviderInstrFieldCodeSet(providerInstrIds, providerFieldIds); results.Add(result); return(new RequestContext { RequestItems = requestItems, ProviderInstrFieldCodeSets = results, InstrConversionMap = instrConversionMap, FieldConversionMap = fieldConversionMap }); }
/// <summary> /// Parses the string info into an asset. /// </summary> /// <param name="instrumentId"></param> /// <param name="value"></param> /// <param name="adjustment"></param> /// <returns></returns> public static Pair <Asset, BasicAssetValuation> Parse(string instrumentId, decimal value, decimal?adjustment) { const string rateQuotationType = PriceableSimpleRateAsset.RateQuotationType; const string volatilityQuotationType = PriceableCapRateAsset.VolatilityQuotationType; Asset underlyingAsset; decimal additional = 0.0m; if (adjustment != null) { additional = (decimal)adjustment; } var listBasicQuotations = new List <BasicQuotation>(); var properties = new PriceableAssetProperties(instrumentId); switch (properties.AssetType) { //This is in place to handle volatility curves where the tenor is the expiry. case AssetTypesEnum.Period: { //There is no underlying asset. underlyingAsset = null; listBasicQuotations.Add(BasicQuotationHelper.Create(instrumentId, value, volatilityQuotationType, "LognormalVolatility")); break; } case AssetTypesEnum.ZeroRate: { underlyingAsset = new Cash { id = instrumentId }; listBasicQuotations.Add(BasicQuotationHelper.Create(value, rateQuotationType, "DecimalRate")); break; } case AssetTypesEnum.Xibor: case AssetTypesEnum.OIS: { underlyingAsset = new RateIndex { id = instrumentId, term = properties.TermTenor }; listBasicQuotations.Add(BasicQuotationHelper.Create(value + additional, rateQuotationType, "DecimalRate")); break; } case AssetTypesEnum.IRSwap: case AssetTypesEnum.ClearedIRSwap: case AssetTypesEnum.OISSwap: case AssetTypesEnum.XccySwap: case AssetTypesEnum.SimpleIRSwap: case AssetTypesEnum.XccyBasisSwap: case AssetTypesEnum.BasisSwap: case AssetTypesEnum.ResettableXccyBasisSwap: { underlyingAsset = new SimpleIRSwap { id = instrumentId, term = properties.TermTenor }; listBasicQuotations.Add(BasicQuotationHelper.Create(value + additional, rateQuotationType, "DecimalRate")); break; } case AssetTypesEnum.Caplet: case AssetTypesEnum.Floorlet: case AssetTypesEnum.BillCaplet: case AssetTypesEnum.BillFloorlet: { underlyingAsset = new SimpleFra { id = instrumentId, startTerm = properties.TermTenor, endTerm = properties.TermTenor.Sum(properties.ForwardIndex) }; listBasicQuotations.Add(BasicQuotationHelper.Create(value, volatilityQuotationType, "LognormalVolatility")); if (adjustment != null) { listBasicQuotations.Add(BasicQuotationHelper.Create(additional, "Strike", "DecimalRate")); } break; } case AssetTypesEnum.Deposit: case AssetTypesEnum.SpreadDeposit: case AssetTypesEnum.XccyDepo: case AssetTypesEnum.BankBill: case AssetTypesEnum.Repo: case AssetTypesEnum.RepoSpread: { underlyingAsset = new Deposit { id = instrumentId, term = properties.TermTenor }; listBasicQuotations.Add(BasicQuotationHelper.Create(value + additional, rateQuotationType, "DecimalRate")); break; } case AssetTypesEnum.SimpleFra: case AssetTypesEnum.Fra: case AssetTypesEnum.BillFra: case AssetTypesEnum.SpreadFra: { underlyingAsset = new SimpleFra { id = instrumentId, startTerm = properties.TermTenor, endTerm = properties.TermTenor.Sum(properties.ForwardIndex) //TODO this restricts the perios to be the same!!! }; listBasicQuotations.Add(BasicQuotationHelper.Create(value + additional, rateQuotationType, "DecimalRate")); break; } case AssetTypesEnum.Swaption: { underlyingAsset = new SimpleIRSwap { id = instrumentId, term = properties.TermTenor }; listBasicQuotations.Add(BasicQuotationHelper.Create(value, volatilityQuotationType, "LognormalVolatility")); if (adjustment != null) { listBasicQuotations.Add(BasicQuotationHelper.Create(additional, "Strike", "DecimalRate")); } break; } case AssetTypesEnum.IRFloor: case AssetTypesEnum.IRCap: { underlyingAsset = new SimpleIRSwap { id = instrumentId, term = properties.TermTenor }; listBasicQuotations.Add(BasicQuotationHelper.Create(value, volatilityQuotationType, "LognormalVolatility")); if (adjustment != null) { listBasicQuotations.Add(BasicQuotationHelper.Create(additional, "Strike", "DecimalRate")); } break; } case AssetTypesEnum.IRFutureOption: case AssetTypesEnum.IRCallFutureOption: case AssetTypesEnum.IRPutFutureOption: { underlyingAsset = new Future { id = instrumentId }; listBasicQuotations.Add(BasicQuotationHelper.Create(value, volatilityQuotationType, "LognormalVolatility")); if (adjustment != null) { listBasicQuotations.Add(BasicQuotationHelper.Create(additional, "Strike", "DecimalRate")); } break; } case AssetTypesEnum.IRFuture: { underlyingAsset = new Future { id = instrumentId }; listBasicQuotations.Add(BasicQuotationHelper.Create(value, rateQuotationType, "DecimalRate")); if (adjustment != null) { listBasicQuotations.Add(BasicQuotationHelper.Create(additional, "Volatility", "LognormalVolatility")); } break; } case AssetTypesEnum.CommodityFuture: case AssetTypesEnum.CommodityFutureSpread: { underlyingAsset = new Future { id = instrumentId }; listBasicQuotations.Add(BasicQuotationHelper.Create(value, rateQuotationType, "DecimalRate")); break; } case AssetTypesEnum.CPIndex: { underlyingAsset = new RateIndex { id = instrumentId, term = properties.TermTenor }; listBasicQuotations.Add(BasicQuotationHelper.Create(value + additional, rateQuotationType, "DecimalRate")); break; } case AssetTypesEnum.SimpleCPISwap: case AssetTypesEnum.CPISwap: case AssetTypesEnum.ZCCPISwap: { underlyingAsset = new SimpleIRSwap { id = instrumentId, term = properties.TermTenor }; listBasicQuotations.Add(BasicQuotationHelper.Create(value + additional, rateQuotationType, "DecimalRate")); break; } case AssetTypesEnum.FxSpot: case AssetTypesEnum.FxForward: { underlyingAsset = new FxRateAsset { id = instrumentId }; listBasicQuotations.Add(BasicQuotationHelper.Create(value + additional, rateQuotationType, "FxRate")); break; } case AssetTypesEnum.Equity: case AssetTypesEnum.EquityForward: { underlyingAsset = new EquityAsset { id = instrumentId }; listBasicQuotations.Add(BasicQuotationHelper.Create(value + additional, rateQuotationType, "Price")); break; } case AssetTypesEnum.CommoditySpot: case AssetTypesEnum.CommodityForward: case AssetTypesEnum.CommodityAverageForward: case AssetTypesEnum.CommoditySpread: { underlyingAsset = new Commodity { id = instrumentId }; listBasicQuotations.Add(BasicQuotationHelper.Create(value + additional, rateQuotationType, "Price")); break; } case AssetTypesEnum.Bond: case AssetTypesEnum.BondSpot: case AssetTypesEnum.BondForward: { underlyingAsset = new Bond { id = instrumentId }; listBasicQuotations.Add(BasicQuotationHelper.Create(value, rateQuotationType, "DecimalRate")); //Changed from DirtyPrice. break; } case AssetTypesEnum.Lease: { underlyingAsset = new Lease { id = instrumentId }; listBasicQuotations.Add(BasicQuotationHelper.Create(value + additional, rateQuotationType, "Price")); break; } default: throw new NotSupportedException($"Asset type {properties.AssetType} is not supported"); } var id = underlyingAsset?.id; if (underlyingAsset == null) { id = listBasicQuotations[0].id; } return(new Pair <Asset, BasicAssetValuation>(underlyingAsset, BasicAssetValuationHelper.Create(id, listBasicQuotations.ToArray()))); }
/// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="cache"></param> /// <param name="nameSpace"></param> /// <param name="tradeDate"></param> /// <param name="settlementDate">The payment settlement date.</param> /// <param name="settlementCalendar"></param> /// <param name="paymentCalendar"></param> /// <param name="bondFpML"></param> /// <param name="basePartyReference"></param> /// <param name="bondType"></param> /// <param name="forecastRateInterpolation"></param> public BondTransactionPricer(ILogger logger, ICoreCache cache, string nameSpace, DateTime tradeDate, DateTime settlementDate, IBusinessCalendar settlementCalendar, IBusinessCalendar paymentCalendar, BondTransaction bondFpML, string basePartyReference, string bondType, Boolean forecastRateInterpolation) { Multiplier = 1.0m; TradeDate = tradeDate; BondType = EnumHelper.Parse <BondTypesEnum>(bondType); logger.LogInfo("BondType set. Commence to build a bond transaction."); if (bondFpML == null) { return; } BuyerReference = bondFpML.buyerPartyReference.href; PaymentCurrencies = new List <string> { bondFpML.notionalAmount.currency.Value }; SellerReference = bondFpML.sellerPartyReference.href; BasePartyBuyer = basePartyReference == bondFpML.buyerPartyReference.href; if (!BasePartyBuyer) { Multiplier = -1.0m; } ForecastRateInterpolation = forecastRateInterpolation; SettlementCalendar = settlementCalendar; PaymentCalendar = paymentCalendar; //Set the bond price information BondPrice = new BondPrice(); if (bondFpML.price.accrualsSpecified) { BondPrice.accrualsSpecified = true; BondPrice.accruals = bondFpML.price.accruals; } if (bondFpML.price.dirtyPriceSpecified) { BondPrice.dirtyPriceSpecified = true; BondPrice.dirtyPrice = bondFpML.price.dirtyPrice; } BondPrice.cleanOfAccruedInterest = bondFpML.price.cleanOfAccruedInterest; BondPrice.cleanPrice = bondFpML.price.cleanPrice; //Set the notional information NotionalAmount = MoneyHelper.GetAmount(bondFpML.notionalAmount.amount, bondFpML.notionalAmount.currency.Value); //Determines the quotation and units QuoteType = BondPriceEnum.YieldToMaturity; //We need to get the ytm in until there is a bond market price/spread. if (BondPrice.dirtyPriceSpecified) { QuoteType = BondPriceEnum.DirtyPrice; Quote = BasicQuotationHelper.Create(BondPrice.dirtyPrice, RateQuotationType); } //Get the insturment configuration information. var assetIdentifier = bondFpML.bond.currency.Value + "-Bond-" + BondType; BondNodeStruct bondTypeInfo = null; var instrument = InstrumentDataHelper.GetInstrumentConfigurationData(cache, nameSpace, assetIdentifier); if (instrument != null) { bondTypeInfo = instrument.InstrumentNodeItem as BondNodeStruct; } if (bondFpML.bond != null && bondTypeInfo != null) { if (SettlementCalendar == null) { SettlementCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, bondTypeInfo.SettlementDate.businessCenters, nameSpace); } if (PaymentCalendar == null) { PaymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, bondTypeInfo.BusinessDayAdjustments.businessCenters, nameSpace); } //Preprocesses the data for the priceableasset. var bond = XmlSerializerHelper.Clone(bondFpML.bond); BondTypeInfo = XmlSerializerHelper.Clone(bondTypeInfo); BondTypeInfo.Bond = bond; //This is done because the config data is not stored in the ciorrect way. Need to add a price quote units. if (bond.couponRateSpecified) { var coupon = bond.couponRate; BondTypeInfo.Bond.couponRate = coupon; } BondTypeInfo.Bond.faceAmount = NotionalAmount.amount; if (BondTypeInfo.Bond.maturitySpecified) { RiskMaturityDate = BondTypeInfo.Bond.maturity; } SettlementDate = settlementDate; if (!PaymentCurrencies.Contains(bondFpML.bond.currency.Value)) { PaymentCurrencies.Add(bondFpML.bond.currency.Value); } logger.LogInfo("Bond transaction has been successfully created."); } else { logger.LogInfo("Bond type data not available."); } //Add payments like the settlement price if (!BondPrice.dirtyPriceSpecified) { return; } var amount = BondPrice.dirtyPrice * NotionalAmount.amount / 100; var settlementPayment = PaymentHelper.Create("BondSettlemetAmount", BuyerReference, SellerReference, amount, SettlementDate); AdditionalPayments = PriceableInstrumentsFactory.CreatePriceablePayments(basePartyReference, new[] { settlementPayment }, SettlementCalendar); if (!PaymentCurrencies.Contains(settlementPayment.paymentAmount.currency.Value)) { PaymentCurrencies.Add(settlementPayment.paymentAmount.currency.Value); } }
public override AssetValuation Calculate(IInstrumentControllerData modelData) { ModelData = modelData; AnalyticModelParameters = null; // 1. First derive the analytics to be evaluated via the stream controller model // NOTE: These take precedence of the child model metrics if (AnalyticsModel == null) { AnalyticsModel = new BondTransactionAnalytic(); } var bondControllerMetrics = ResolveModelMetrics(AnalyticsModel.Metrics); AssetValuation bondValuation; var quotes = ModelData.AssetValuation.quote.ToList(); if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.AccrualFactor.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.AccrualFactor.ToString(), "DecimalValue"); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.FloatingNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.FloatingNPV.ToString(), "DecimalValue"); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.NPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.NPV.ToString(), "DecimalValue"); quotes.Add(quote); } ModelData.AssetValuation.quote = quotes.ToArray(); var marketEnvironment = modelData.MarketEnvironment; IRateCurve rateDiscountCurve = null; //2. Sets the evolution type for coupon and payment calculations. Coupons.PricingStructureEvolutionType = PricingStructureEvolutionType; Coupons.BucketedDates = BucketedDates; Coupons.Multiplier = Multiplier; if (AdditionalPayments != null) { foreach (var payment in AdditionalPayments) { payment.PricingStructureEvolutionType = PricingStructureEvolutionType; payment.BucketedDates = BucketedDates; payment.Multiplier = Multiplier; } } //3. Aggregate the child metrics. List <AssetValuation> childValuations = new List <AssetValuation> { Coupons?.Calculate(modelData) }; if (GetAdditionalPayments() != null) { var paymentControllers = new List <InstrumentControllerBase>(GetAdditionalPayments()); childValuations.AddRange(paymentControllers.Select(payment => payment.Calculate(modelData))); } var childControllerValuations = AssetValuationHelper.AggregateMetrics(childValuations, new List <string>(Metrics), PaymentCurrencies); childControllerValuations.id = Id + ".BondCouponRateStreams"; //4. Calc the asset as a little extra var metrics = ResolveModelMetrics(AnalyticsModel.Metrics); var metricsAsString = metrics.Select(metric => metric.ToString()).ToList(); var controllerData = PriceableAssetFactory.CreateAssetControllerData(metricsAsString.ToArray(), modelData.ValuationDate, modelData.MarketEnvironment); UnderlyingBond.Multiplier = Multiplier; UnderlyingBond.Calculate(controllerData); //5. Now do the bond calculations. if (bondControllerMetrics.Count > 0) { CalculationResults = new BondTransactionResults(); if (marketEnvironment.GetType() == typeof(MarketEnvironment)) { var bondCurve = (IBondCurve)modelData.MarketEnvironment.GetPricingStructure(BondCurveName); if (bondCurve != null) { var marketDataType = bondCurve.GetPricingStructureId().Properties.GetValue <string>(AssetMeasureEnum.MarketQuote.ToString(), false); if (marketDataType != null && marketDataType == BondPriceEnum.YieldToMaturity.ToString()) { IsYTMQuote = true; } //TODO handle the other cases like: AssetSwapSpread; DirtyPrice and ZSpread. var mq = (decimal)bondCurve.GetYieldToMaturity(modelData.ValuationDate, SettlementDate); Quote = BasicQuotationHelper.Create(mq, AssetMeasureEnum.MarketQuote.ToString(), PriceQuoteUnitsEnum.DecimalRate.ToString()); } rateDiscountCurve = (IRateCurve)modelData.MarketEnvironment.GetPricingStructure(DiscountCurveName); } //Generate the vectors const bool isBuyerInd = true; var analyticModelParameters = new BondTransactionParameters { IsBuyerInd = isBuyerInd, AccrualYearFractions = GetCouponAccrualFactors(), Multiplier = Multiplier, Quote = QuoteValue, CouponRate = UnderlyingBond.GetCouponRate(), NotionalAmount = UnderlyingBond.Notional, Frequency = UnderlyingBond.Frequency, IsYTMQuote = IsYTMQuote, AccruedFactor = UnderlyingBond.GetAccruedFactor(), RemainingAccruedFactor = UnderlyingBond.GetRemainingAccruedFactor(), PaymentDiscountFactors = GetDiscountFactors(rateDiscountCurve, Coupons.StreamPaymentDates.ToArray(), modelData.ValuationDate), }; //5. Get the Weightings analyticModelParameters.Weightings = CreateWeightings(CDefaultWeightingValue, analyticModelParameters.PaymentDiscountFactors.Length); //6. Set the analytic input parameters and Calculate the respective metrics AnalyticModelParameters = analyticModelParameters; CalculationResults = AnalyticsModel.Calculate <IBondTransactionResults, BondTransactionResults>(analyticModelParameters, metrics.ToArray()); // Now merge back into the overall stream valuation var bondControllerValuation = GetValue(CalculationResults, modelData.ValuationDate); bondValuation = AssetValuationHelper.UpdateValuation(bondControllerValuation, childControllerValuations, ConvertMetrics(bondControllerMetrics), new List <string>(Metrics)); } else { bondValuation = childControllerValuations; } // store inputs and results from this run CalculationPerformedIndicator = true; bondValuation.id = Id; return(bondValuation); }
/// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="cache"></param> /// <param name="nameSpace"></param> /// <param name="tradeDate"></param> /// <param name="settlementDate">The payment settlement date.</param> /// <param name="settlementCalendar"></param> /// <param name="paymentCalendar"></param> /// <param name="bondFpML"></param> /// <param name="basePartyReference"></param> /// <param name="bondType"></param> /// <param name="forecastRateInterpolation"></param> public BondTransactionPricer(ILogger logger, ICoreCache cache, string nameSpace, DateTime tradeDate, DateTime settlementDate, IBusinessCalendar settlementCalendar, IBusinessCalendar paymentCalendar, BondTransaction bondFpML, string basePartyReference, string bondType, bool forecastRateInterpolation) { Multiplier = 1.0m; TradeDate = tradeDate; BondType = EnumHelper.Parse <BondTypesEnum>(bondType); logger.LogInfo("BondType set. Commence to build a bond transaction."); if (bondFpML == null) { return; } BuyerReference = bondFpML.buyerPartyReference.href; PaymentCurrencies = new List <string> { bondFpML.notionalAmount.currency.Value }; SellerReference = bondFpML.sellerPartyReference.href; BasePartyBuyer = basePartyReference == bondFpML.buyerPartyReference.href; if (!BasePartyBuyer) { Multiplier = -1.0m; } ForecastRateInterpolation = forecastRateInterpolation; SettlementCalendar = settlementCalendar; PaymentCalendar = paymentCalendar; //Set the bond price information BondPrice = new BondPrice(); if (bondFpML.price.accrualsSpecified) { BondPrice.accrualsSpecified = true; BondPrice.accruals = bondFpML.price.accruals; } if (bondFpML.price.dirtyPriceSpecified) { BondPrice.dirtyPriceSpecified = true; BondPrice.dirtyPrice = bondFpML.price.dirtyPrice; } BondPrice.cleanOfAccruedInterest = bondFpML.price.cleanOfAccruedInterest; BondPrice.cleanPrice = bondFpML.price.cleanPrice; //Set the currencies CouponCurrency = bondFpML.notionalAmount.currency; PaymentCurrency = bondFpML.notionalAmount.currency;//This could be another currency! //Set the notional information NotionalAmount = MoneyHelper.GetAmount(bondFpML.notionalAmount.amount, bondFpML.notionalAmount.currency.Value); //Determines the quotation and units QuoteType = BondPriceEnum.YieldToMaturity; //We need to get the ytm in until there is a bond market price/spread. if (BondPrice.dirtyPriceSpecified) { QuoteType = BondPriceEnum.DirtyPrice; Quote = BasicQuotationHelper.Create(BondPrice.dirtyPrice, RateQuotationType); } //Get the instrument configuration information. var assetIdentifier = bondFpML.bond.currency.Value + "-Bond-" + BondType; BondNodeStruct bondTypeInfo = null; //TODO Set the swap curves for asset swap valuation. // //Gets the template bond type var instrument = InstrumentDataHelper.GetInstrumentConfigurationData(cache, nameSpace, assetIdentifier); if (instrument != null) { bondTypeInfo = instrument.InstrumentNodeItem as BondNodeStruct; } if (bondFpML.bond != null && bondTypeInfo != null) { if (SettlementCalendar == null) { SettlementCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, bondTypeInfo.SettlementDate.businessCenters, nameSpace); } if (PaymentCalendar == null) { PaymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, bondTypeInfo.BusinessDayAdjustments.businessCenters, nameSpace); } //Pre-processes the data for the priceable asset. var bond = XmlSerializerHelper.Clone(bondFpML.bond); Bond = bond; bondTypeInfo.Bond = Bond; //Set the curves to use for valuations. BondCurveName = CurveNameHelpers.GetBondCurveName(Bond.currency.Value, Bond.id); //THe discount curve is only for credit calculations. DiscountCurveName = CurveNameHelpers.GetDiscountCurveName(Bond.currency.Value, true); if (bond.maturitySpecified) { MaturityDate = bond.maturity; } SettlementDateConvention = bondTypeInfo.SettlementDate; BusinessDayAdjustments = bondTypeInfo.BusinessDayAdjustments; ExDivDateConvention = bondTypeInfo.ExDivDate; //This is done because the config data is not stored in the correct way. Need to add a price quote units. if (bond.couponRateSpecified) { var coupon = bond.couponRate; Bond.couponRate = coupon; } bondTypeInfo.Bond.faceAmount = NotionalAmount.amount; bondTypeInfo.Bond.faceAmountSpecified = true; Bond.faceAmount = NotionalAmount.amount; if (Bond.maturitySpecified) { RiskMaturityDate = Bond.maturity; } SettlementDate = settlementDate; if (!PaymentCurrencies.Contains(bondFpML.bond.currency.Value)) { PaymentCurrencies.Add(bondFpML.bond.currency.Value); } logger.LogInfo("Bond transaction has been successfully created."); } else { logger.LogInfo("Bond type data not available."); } //Set the underlying bond UnderlyingBond = new PriceableSimpleBond(tradeDate, bondTypeInfo, SettlementCalendar, PaymentCalendar, Quote, QuoteType); BondIssuer = UnderlyingBond.Issuer; if (BondPrice.dirtyPriceSpecified) { UnderlyingBond.PurchasePrice = BondPrice.dirtyPrice / 100; //PriceQuoteUnits } //Set the coupons var bondId = Bond.id;//Could use one of the instrumentIds //bondStream is an interest Rate Stream but needs to be converted to a bond stream. //It automatically contains the coupon currency. Coupons = new PriceableBondCouponRateStream(logger, cache, nameSpace, bondId, tradeDate, bondFpML.notionalAmount.amount, CouponStreamType.GenericFixedRate, Bond, BusinessDayAdjustments, ForecastRateInterpolation, null, PaymentCalendar); //Add payments like the settlement price if (!BondPrice.dirtyPriceSpecified) { return; } var amount = BondPrice.dirtyPrice * NotionalAmount.amount / 100; var settlementPayment = PaymentHelper.Create(BuyerReference, SellerReference, PaymentCurrency.Value, amount, SettlementDate); AdditionalPayments = PriceableInstrumentsFactory.CreatePriceablePayments(basePartyReference, new[] { settlementPayment }, SettlementCalendar); // var finalPayment = PaymentHelper.Create(BondIssuer, BuyerReference, CouponCurrency.Value, NotionalAmount.amount, RiskMaturityDate); FinalRedemption = PriceableInstrumentsFactory.CreatePriceablePayment(basePartyReference, finalPayment, PaymentCalendar); AdditionalPayments.Add(FinalRedemption); if (!PaymentCurrencies.Contains(settlementPayment.paymentAmount.currency.Value)) { PaymentCurrencies.Add(settlementPayment.paymentAmount.currency.Value); } }
/// <summary> /// Parses the data. /// </summary> /// <param name="instrumentIds"></param> /// <returns></returns> public static QuotedAssetSet Parse(string[] instrumentIds) { var quotedAssetSetFactory = new QuotedAssetSetFactory(); const string rateQuotationType = "MarketQuote"; for (var i = 0; i < instrumentIds.Length; i++) { Asset underlyingAsset; var instrumentId = instrumentIds[i]; var results = instrumentIds[i].Split('-'); var instrument = results[1]; var listBasicQuotations = new List <BasicQuotation>(); const string priceUnitDecimalRate = "DecimalRate"; switch (instrument) { case "ZeroRate": { underlyingAsset = new Cash { id = instrumentId }; listBasicQuotations.Add(BasicQuotationHelper.Create(rateQuotationType, priceUnitDecimalRate)); break; } case "Xibor": case "OIS": { var tenor = results[2]; underlyingAsset = new RateIndex { id = instrumentId, term = Period.Parse(tenor) }; listBasicQuotations.Add(BasicQuotationHelper.Create(rateQuotationType, priceUnitDecimalRate)); break; } case "IRSwap": case "XccySwap": case "SimpleIRSwap": { underlyingAsset = new SimpleIRSwap { id = instrumentId, term = Period.Parse(results[2]) }; listBasicQuotations.Add(BasicQuotationHelper.Create(rateQuotationType, priceUnitDecimalRate)); break; } case "Deposit": case "XccyDepo": case "BankBill": { underlyingAsset = new Deposit { id = instrumentId, term = Period.Parse(results[2]) }; listBasicQuotations.Add(BasicQuotationHelper.Create(rateQuotationType, priceUnitDecimalRate)); break; } case "SimpleFra": case "Fra": case "BillFra": { var index = results[3]; var asset = new SimpleFra { id = instrumentId, startTerm = Period.Parse(results[2]) }; asset.endTerm = asset.startTerm.Sum(Period.Parse(index)); underlyingAsset = asset; listBasicQuotations.Add(BasicQuotationHelper.Create(rateQuotationType, priceUnitDecimalRate)); break; } case "IRFuture": { underlyingAsset = new Future { id = instrumentId }; listBasicQuotations.Add(BasicQuotationHelper.Create(rateQuotationType, priceUnitDecimalRate)); listBasicQuotations.Add(BasicQuotationHelper.Create("Volatility", "LognormalVolatility")); break; } case "CPIndex": { var tenor = results[2]; underlyingAsset = new RateIndex { id = instrumentId, term = Period.Parse(tenor) }; listBasicQuotations.Add(BasicQuotationHelper.Create(rateQuotationType, priceUnitDecimalRate)); break; } case "SimpleCPISwap": case "CPISwap": case "ZCCPISwap": { underlyingAsset = new SimpleIRSwap { id = instrumentId, term = Period.Parse(results[2]) }; listBasicQuotations.Add(BasicQuotationHelper.Create(rateQuotationType, priceUnitDecimalRate)); break; } default: throw new NotSupportedException(string.Format("Asset type {0} is not supported", instrument)); } quotedAssetSetFactory.AddAssetAndQuotes(underlyingAsset, BasicAssetValuationHelper.Create(underlyingAsset.id, listBasicQuotations.ToArray())); } return(quotedAssetSetFactory.Create()); }
/// <summary> /// Parses the string info into an asset. /// </summary> /// <param name="instrumentId"></param> /// <param name="value"></param> /// <param name="adjustment"></param> /// <returns></returns> public static Pair <Asset, BasicAssetValuation> Parse(string instrumentId, decimal value, decimal adjustment) { const string rateQuotationType = "MarketQuote"; Asset underlyingAsset; var results = instrumentId.Split('-'); var instrument = results[1]; var listBasicQuotations = new List <BasicQuotation>(); switch (instrument) { case "ZeroRate": { var zeroRate = new Cash { id = instrumentId }; underlyingAsset = zeroRate; listBasicQuotations.Add(BasicQuotationHelper.Create(value, rateQuotationType, "DecimalRate")); break; } case "Xibor": case "OIS": { var tenor = results[2]; var rateIndex = new RateIndex { id = instrumentId, term = Period.Parse(tenor) }; underlyingAsset = rateIndex; listBasicQuotations.Add(BasicQuotationHelper.Create(value + adjustment, rateQuotationType, "DecimalRate")); break; } case "IRSwap": case "XccySwap": case "SimpleIRSwap": { var simpleIRSwap = new SimpleIRSwap { id = instrumentId, term = Period.Parse(results[2]) }; underlyingAsset = simpleIRSwap; listBasicQuotations.Add(BasicQuotationHelper.Create(value + adjustment, rateQuotationType, "DecimalRate")); break; } case "Deposit": case "XccyDepo": case "BankBill": { var deposit = new Deposit { id = instrumentId, term = Period.Parse(results[2]) }; underlyingAsset = deposit; listBasicQuotations.Add(BasicQuotationHelper.Create(value + adjustment, rateQuotationType, "DecimalRate")); break; } case "SimpleFra": case "Fra": case "BillFra": case "SpreadFra": { var index = results[3]; var asset = new SimpleFra { id = instrumentId, startTerm = Period.Parse(results[2]) }; asset.endTerm = asset.startTerm.Sum(Period.Parse(index)); underlyingAsset = asset; listBasicQuotations.Add(BasicQuotationHelper.Create(value + adjustment, rateQuotationType, "DecimalRate")); break; } case "IRCap": { var simpleIRCap = new SimpleIRSwap { id = instrumentId, term = Period.Parse(results[2]) }; underlyingAsset = simpleIRCap; listBasicQuotations.Add(BasicQuotationHelper.Create(value, "Premium", "Amount")); break; } case "IRFuture": { var future = new Future { id = instrumentId }; underlyingAsset = future; listBasicQuotations.Add(BasicQuotationHelper.Create(value, rateQuotationType, "DecimalRate")); listBasicQuotations.Add(BasicQuotationHelper.Create(adjustment, "Volatility", "LognormalVolatility")); break; } case "CommodityFuture": { var future = new Future { id = instrumentId }; underlyingAsset = future; listBasicQuotations.Add(BasicQuotationHelper.Create(value, rateQuotationType, "DecimalRate")); break; } case "CPIndex": { var tenor = results[2]; var rateIndex = new RateIndex { id = instrumentId, term = Period.Parse(tenor) }; underlyingAsset = rateIndex; listBasicQuotations.Add(BasicQuotationHelper.Create(value + adjustment, rateQuotationType, "DecimalRate")); break; } case "SimpleCPISwap": case "CPISwap": case "ZCCPISwap": { var simpleIRSwap = new SimpleIRSwap { id = instrumentId, term = Period.Parse(results[2]) }; underlyingAsset = simpleIRSwap; listBasicQuotations.Add(BasicQuotationHelper.Create(value + adjustment, rateQuotationType, "DecimalRate")); break; } case "FxSpot": case "FxForward": { // var tenor = results[2]; var fxRateAsset = new FxRateAsset { id = instrumentId }; underlyingAsset = fxRateAsset; listBasicQuotations.Add(BasicQuotationHelper.Create(value + adjustment, rateQuotationType, "FxRate")); break; } case "CommoditySpot": case "CommodityForward": { var commodityAsset = new FxRateAsset { id = instrumentId }; underlyingAsset = commodityAsset; listBasicQuotations.Add(BasicQuotationHelper.Create(value, rateQuotationType, "Price")); break; } case "Bond": { var asset = new Bond { id = instrumentId }; underlyingAsset = asset; listBasicQuotations.Add(BasicQuotationHelper.Create(value, rateQuotationType, "DirtyPrice")); break; } default: throw new NotSupportedException(string.Format("Asset type {0} is not supported", instrument)); } return(new Pair <Asset, BasicAssetValuation>(underlyingAsset, BasicAssetValuationHelper.Create(underlyingAsset.id, listBasicQuotations.ToArray()))); }
protected List <BasicAssetValuation> ConvertProviderResultsToStandardValuations( Dictionary <string, BasicQuotation> providerResults, RequestContext requestContext) { var results = new List <BasicAssetValuation>(); // build standard results (and convert quote units) Logger.LogDebug(" Results :"); for (int i = 0; i < requestContext.RequestItems.Count; i++) { RequestItem requestItem = requestContext.RequestItems[i]; Asset standardAsset = requestItem.StandardAsset; BasicQuotation standardQuote = requestItem.StandardQuote; string standardInstrId = standardAsset.id; string standardFieldId = standardQuote.GetStandardFieldName(); PriceQuoteUnitsEnum standardQuoteUnit = requestItem.StandardUnits; PriceQuoteUnitsEnum providerQuoteUnit = requestItem.ProviderUnits; string providerInstrId = requestContext.InstrConversionMap[standardInstrId.ToLower()]; string providerFieldId = requestContext.FieldConversionMap[standardFieldId.ToLower()]; string providerQuoteKey = FormatProviderQuoteKey(providerInstrId, providerFieldId); if (providerResults.TryGetValue(providerQuoteKey, out var providerQuote)) { BasicQuotation convertedQuote; if (providerQuote.valueSpecified) { // valid value returned decimal convertedValue = PriceQuoteUnitsHelper.ConvertPriceQuoteUnitsValue(providerQuoteUnit, standardQuoteUnit, providerQuote.value); convertedQuote = BasicQuotationHelper.Create(standardQuote, convertedValue); // debug Logger.LogDebug(" [{0}] '{1}/{2}' ({3}/{4}) [{5}] --> '{6}/{7}' ({8}/{9}) [{10}]", i, providerInstrId, providerFieldId, AssetMeasureEnum.MarketQuote, providerQuoteUnit, providerQuote.value, standardInstrId, standardFieldId, AssetMeasureEnum.MarketQuote, standardQuoteUnit, convertedQuote.value); // enddebug } else { // no value - copy error details convertedQuote = providerQuote; // debug Logger.LogDebug(" [{0}] '{1}/{2}' ({3}/{4}) [{5}] --> '{6}/{7}' ({8}/{9}) [{10}]", i, providerInstrId, providerFieldId, providerQuote.measureType.Value, providerQuote.quoteUnits.Value, providerQuote.value, standardInstrId, standardFieldId, convertedQuote.measureType.Value, convertedQuote.quoteUnits.Value, convertedQuote.value); // enddebug } // add other provider info convertedQuote.timeSpecified = providerQuote.timeSpecified; convertedQuote.time = providerQuote.time; convertedQuote.valuationDateSpecified = providerQuote.valuationDateSpecified; convertedQuote.valuationDate = providerQuote.valuationDate; convertedQuote.informationSource = providerQuote.informationSource; results.Add(new BasicAssetValuation { objectReference = new AnyAssetReference { href = standardAsset.id }, quote = new[] { convertedQuote } }); } } return(results); }