public QuotedAssetSet Create() { var result = new QuotedAssetSet(); var assets = new List <Asset>(); var quotes = new List <BasicAssetValuation>(); var types = new List <ItemsChoiceType19>(); foreach (Pair <Asset, BasicAssetValuation> assetAndQuote in _assetAndQuotes) { assets.Add(assetAndQuote.First); quotes.Add(assetAndQuote.Second); //Handles the case of tenor curves var id = assetAndQuote.First?.id ?? assetAndQuote.Second?.objectReference?.href; var properties = new PriceableAssetProperties(id); var assetTypeFpML = AssetTypeConvertor.ParseEnumStringToFpML(properties.AssetType.ToString()); types.Add(assetTypeFpML); } var instrumentSet = new InstrumentSet { Items = assets.ToArray(), ItemsElementName = types.ToArray() }; result.instrumentSet = instrumentSet; result.assetQuote = quotes.ToArray(); return(result); }
/// <summary> /// Creates a quoted asset set without the asset type specified. /// </summary> /// <param name="assetType">The asset Type to remove.</param> /// <param name="assetSet">The original assetSet</param> /// <returns></returns> public static QuotedAssetSet RemoveAssetsFromQuotedAssetSet(AssetTypesEnum assetType, QuotedAssetSet assetSet) { var assets = new List <Asset>(); var quotes = new List <BasicAssetValuation>(); var types = new List <ItemsChoiceType19>(); var index = 0; foreach (var asset in assetSet.instrumentSet.Items) { var tempAssetType = new PriceableAssetProperties(asset.id).AssetType; if (tempAssetType != assetType) { assets.Add(asset); quotes.Add(assetSet.assetQuote[index]); if (assetSet.instrumentSet.ItemsElementName != null) { types.Add(assetSet.instrumentSet.ItemsElementName[index]); } else { var assetTypeFpML = AssetTypeConvertor.ParseEnumStringToFpML(tempAssetType.ToString()); types.Add(assetTypeFpML); } } index++; } var instrumentSet = new InstrumentSet { Items = assets.ToArray(), ItemsElementName = types.ToArray() }; return(new QuotedAssetSet { instrumentSet = instrumentSet, assetQuote = quotes.ToArray() }); }
/// <summary> /// Creates a QuotedAssetSet from a set of instrument ids and sides, all with measureType set to MarketQuote /// and QuoteUnits set to DecimalRate (useful for building market data requests). /// </summary> /// <param name="instrIds">The (m) instrument ids.</param> /// <param name="sides">The (n) sides.</param> /// <returns>An M * N matrix of assets/quotes in a QuotedAssetSet</returns> public static QuotedAssetSet Parse(string[] instrIds, string[] sides) { var assetList = new List <Asset>(); var quoteList = new List <BasicAssetValuation>(); var types = new List <ItemsChoiceType19>(); foreach (string instrId in instrIds) { Asset asset = CreateAsset(instrId); assetList.Add(asset); quoteList.AddRange(sides.Select(side => BasicQuotationHelper.Create("MarketQuote", "DecimalRate", side)).Select(quote => new BasicAssetValuation { objectReference = new AnyAssetReference { href = asset.id }, quote = new[] { quote } })); var properties = new PriceableAssetProperties(asset.id); var assetTypeFpML = AssetTypeConvertor.ParseEnumStringToFpML(properties.AssetType.ToString()); types.Add(assetTypeFpML); } var instrumentSet = new InstrumentSet { Items = assetList.ToArray(), ItemsElementName = types.ToArray() }; return(new QuotedAssetSet { instrumentSet = instrumentSet, assetQuote = quoteList.ToArray() }); }
/// <summary> /// Maps from a list of asset pairs to a quoted asset set. /// </summary> /// <param name="assetPairs"></param> /// <returns></returns> internal static QuotedAssetSet MapFromAssetPairs(ICollection <Pair <Asset, BasicAssetValuation> > assetPairs) { var quotedAssetSet = new QuotedAssetSet(); var assets = new Asset[assetPairs.Count]; var basicAssetValuations = new BasicAssetValuation[assetPairs.Count]; var types = new List <ItemsChoiceType19>(); var index = 0; foreach (var pair in assetPairs) { assets[index] = pair.First; basicAssetValuations[index] = pair.Second; var properties = new PriceableAssetProperties(assets[index].id); var assetTypeFpML = AssetTypeConvertor.ParseEnumStringToFpML(properties.AssetType.ToString()); types.Add(assetTypeFpML); index++; } quotedAssetSet.assetQuote = basicAssetValuations; var instrumentSet = new InstrumentSet { Items = assets.ToArray(), ItemsElementName = types.ToArray() }; quotedAssetSet.instrumentSet = instrumentSet; return(quotedAssetSet); }
/// <summary> /// Creates a QuotedAssetSet from a set of instrument ids and sides, all with measureType set to MarketQuote /// and QuoteUnits set to DecimalRate (useful for building market data requests). /// </summary> /// <param name="instrIds">The (m) instrument ids.</param> /// <param name="sides">The (n) sides.</param> /// <returns>An M * N matrix of assets/quotes in a QuotedAssetSet</returns> public static QuotedAssetSet Parse(string[] instrIds, string[] sides) { var assetList = new List <Asset>(); var quoteList = new List <BasicAssetValuation>(); foreach (string instrId in instrIds) { Asset asset = CreateAsset(instrId); assetList.Add(asset); foreach (string side in sides) { BasicQuotation quote = BasicQuotationHelper.Create("MarketQuote", "DecimalRate", side); quoteList.Add(new BasicAssetValuation { objectReference = new AnyAssetReference { href = asset.id }, quote = new[] { quote } }); } } var instrumentSet = new InstrumentSet { Items = assetList.ToArray() }; return(new QuotedAssetSet { instrumentSet = instrumentSet, assetQuote = quoteList.ToArray() }); }
/// <summary> /// availableInstrumentSet에서 name과 type이 모두 일치하는 악기 세트를 찾아 반환합니다. /// 만약 찾지 못하면, name이 null이고 instruments가 비어 있는 InstrumentSet이 반환됩니다. /// </summary> /// <param name="name"></param> /// <param name="type"></param> /// <returns></returns> private InstrumentSet FindInstrumentSet(string name, InstrumentSet.Type type) { InstrumentSet empty = new InstrumentSet(null, null, new Dictionary <int, InstrumentInfo>(), InstrumentSet.Type.character); if (!isInstrumentsReady) { return(empty); } foreach (InstrumentSet i in availableInstrumentSets) { if (i.name.Equals(name) && i.type.Equals(type)) { return(i); } } return(empty); }
public FxRateSet CreateFxRateSet() { var result = new FxRateSet(); var assets = new List <Asset>(); var quotes = new List <BasicAssetValuation>(); foreach (Pair <Asset, BasicAssetValuation> assetAndQuote in _assetAndQuotes) { assets.Add(assetAndQuote.First); quotes.Add(assetAndQuote.Second); } var instrumentSet = new InstrumentSet { Items = assets.ToArray() }; result.instrumentSet = instrumentSet; result.assetQuote = quotes.ToArray(); return(result); }
/// <summary> /// main에 additional의, 채널(Staff)이 겹치지 않는 instruments를 추가합니다. /// </summary> /// <param name="main">기존 악기 목록</param> /// <param name="additional">추가될 악기 세트</param> private void ConcatenateInstrumentSet(Dictionary <int, InstrumentInfo> main, InstrumentSet additional) { foreach (KeyValuePair <int, InstrumentInfo> p in additional.instruments) { if (!main.ContainsKey(p.Key)) { main.Add(p.Key, p.Value); } } if (additional.type == InstrumentSet.Type.character && additional.name != null) { MinOctave = additional.minOctave; MaxOctave = additional.maxOctave; } else if (additional.type == InstrumentSet.Type.accompaniment && additional.name != null) { MinOctaveInAccompaniment = additional.minOctave; MaxOctaveInAccompaniment = additional.maxOctave; } }
public FxRateSet Create() { var result = new FxRateSet(); var assets = new List <Asset>(); var quotes = new List <BasicAssetValuation>(); var types = new List <ItemsChoiceType22>(); foreach (var assetAndQuote in _assetAndQuotes) { assets.Add(assetAndQuote.First); quotes.Add(assetAndQuote.Second); } var instrumenSet = new InstrumentSet { Items = assets.ToArray(), ItemsElementName = types.ToArray() }; result.instrumentSet = instrumenSet; result.assetQuote = quotes.ToArray(); return(result); }
/// <summary> /// Maps from a list of asset pairs to a quoted asset set. /// </summary> /// <param name="assetPairs"></param> /// <returns></returns> internal static QuotedAssetSet MapFromAssetPairs(List <Pair <Asset, BasicAssetValuation> > assetPairs) { var quotedAssetSet = new QuotedAssetSet(); var assets = new Asset[assetPairs.Count]; var bavs = new BasicAssetValuation[assetPairs.Count]; var index = 0; foreach (var pair in assetPairs) { assets[index] = pair.First; bavs[index] = pair.Second; index++; } quotedAssetSet.assetQuote = bavs; var instrumentSet = new InstrumentSet { Items = assets.ToArray() }; quotedAssetSet.instrumentSet = instrumentSet; return(quotedAssetSet); }
public FxRateSet CreateFxRateSet() { var result = new FxRateSet(); var assets = new List <Asset>(); var quotes = new List <BasicAssetValuation>(); var types = new List <ItemsChoiceType19>(); foreach (Pair <Asset, BasicAssetValuation> assetAndQuote in _assetAndQuotes) { assets.Add(assetAndQuote.First); quotes.Add(assetAndQuote.Second); var properties = new PriceableAssetProperties(assetAndQuote.First.id); var assetTypeFpML = AssetTypeConvertor.ParseEnumStringToFpML(properties.AssetType.ToString()); types.Add(assetTypeFpML); } var instrumentSet = new InstrumentSet { Items = assets.ToArray(), ItemsElementName = types.ToArray() }; result.instrumentSet = instrumentSet; result.assetQuote = quotes.ToArray(); return(result); }
public List <Instrument> Create(InstrumentSet instSet, List <SoundManager.Chip> chips, Setting setting, MIDIKbd midiKbd) { Instrument inst; List <Instrument> ret = new List <Instrument>(); switch (instSet) { case InstrumentSet.vgm: case InstrumentSet.zgm: foreach (SoundManager.Chip chip in chips) { inst = Create(chip, setting, midiKbd); ret.Add(inst); } break; case InstrumentSet.xgm: inst = new MMLParameter.YM2612X(chips[0], setting, midiKbd); ret.Add(inst); break; case InstrumentSet.mucom: inst = new MMLParameter.YM2608_mucom(chips[0], setting, midiKbd); ret.Add(inst); break; case InstrumentSet.pmd: inst = new MMLParameter.YM2608_PMD(chips[0], setting, midiKbd); ret.Add(inst); break; default: throw new ArgumentException(); } return(ret); }
/// <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> /// Merges a QuotedAssetSet with this. Note that the referential integrity between the assets /// and valuations is checked and maintained. /// </summary> /// <param name="additional">The additional QuotedAssetSet.</param> /// <param name="checkValuationAssetReferences">if set to <c>true</c> [check valuation asset references].</param> /// <param name="includeEmptyCurrentQuotes">if set to <c>true</c> [include empty current quotes].</param> /// <param name="includeEmptyAdditionalQuotes">if set to <c>true</c> [include empty additional quotes].</param> /// <returns></returns> public QuotedAssetSet Merge(QuotedAssetSet additional, bool checkValuationAssetReferences, bool includeEmptyCurrentQuotes, bool includeEmptyAdditionalQuotes) { var result = new QuotedAssetSet(); // build unique instrumentSet and valuation quote lists var instrumentMap = new Dictionary <string, Asset>(); var valuationMap = new Dictionary <string, BasicAssetValuation>(); if (instrumentSet != null && instrumentSet.Items != null) { foreach (Asset asset in instrumentSet.Items)//The asset type { string assetId = asset.id; //Trace.WriteLine(String.Format("Merge: Existing asset: '{0}'", assetId); instrumentMap[assetId.ToLower()] = asset; } } if (assetQuote != null) { foreach (BasicAssetValuation currentValuation in assetQuote) { string assetId = currentValuation.objectReference.href; if (checkValuationAssetReferences) { Asset asset; if (!instrumentMap.TryGetValue(assetId.ToLower(), out asset)) { throw new ApplicationException(String.Format( "Cannot find asset '{0}' for assetQuote", assetId)); } } // merge the quotes BasicAssetValuation existingValuation; if (valuationMap.TryGetValue(assetId.ToLower(), out existingValuation)) { //Trace.WriteLine(String.Format("Merge: Asset: '{0}' updating existing valuation", assetId); } else { // not found - create a new valuation //Trace.WriteLine(String.Format("Merge: Asset: '{0}' creating existing valuation", assetId); existingValuation = new BasicAssetValuation { objectReference = new AnyAssetReference { href = assetId }, quote = new List <BasicQuotation>().ToArray() }; valuationMap[assetId.ToLower()] = existingValuation; } // append the assetquotes var quotes = new List <BasicQuotation>(existingValuation.quote); foreach (BasicQuotation quote in currentValuation.quote) { if (quote.valueSpecified || includeEmptyCurrentQuotes) { quotes.Add(quote); //if (quote.valueSpecified) //Trace.WriteLine(String.Format("Merge: Asset: '{0}' adding existing quote value '{1}'", assetId, quote.value); //else //Trace.WriteLine(String.Format("Merge: Asset: '{0}' adding existing empty quote", assetId); } else { //Trace.WriteLine(String.Format("Merge; Asset: '{0}' skipping existing empty quote", assetId); } } existingValuation.quote = quotes.ToArray(); } } // add extra instruments if (additional.instrumentSet != null && additional.instrumentSet.Items != null) { foreach (Asset asset in additional.instrumentSet.Items) { string assetId = asset.id; if (!instrumentMap.ContainsKey(assetId.ToLower())) { instrumentMap[assetId.ToLower()] = asset; //Trace.WriteLine(String.Format("Merge: Additional asset: '{0}'", assetId); } } } // append valuation quotes if (additional.assetQuote != null) { foreach (BasicAssetValuation additionalValuation in additional.assetQuote) { string assetId = additionalValuation.objectReference.href; if (checkValuationAssetReferences) { Asset asset; if (!instrumentMap.TryGetValue(assetId.ToLower(), out asset)) { throw new ApplicationException(String.Format( "Cannot find asset '{0}' for assetQuote", assetId)); } } // merge the quotes BasicAssetValuation existingValuation; if (valuationMap.TryGetValue(assetId.ToLower(), out existingValuation)) { //Trace.WriteLine(String.Format("Merge: Asset: '{0}' updating additional valuation", assetId); } else { // not found - just add the valuation existingValuation = new BasicAssetValuation { objectReference = new AnyAssetReference { href = assetId }, quote = new List <BasicQuotation>().ToArray() }; valuationMap[assetId.ToLower()] = existingValuation; //Trace.WriteLine(String.Format("Merge: Asset: '{0}' creating additional valuation", assetId); } // append the assetquotes var quotes = new List <BasicQuotation>(existingValuation.quote); foreach (BasicQuotation quote in additionalValuation.quote) { if (quote.valueSpecified || includeEmptyAdditionalQuotes) { quotes.Add(quote); //if (quote.valueSpecified) //Trace.WriteLine(String.Format("Merge: Asset: '{0}' adding additional quote value '{1}'", assetId, quote.value); //else //Trace.WriteLine(String.Format("Merge: Asset: '{0}' adding additional empty quote", assetId); } else { //Trace.WriteLine(String.Format("Merge; Asset: '{0}' skipping additional empty quote", assetId); } } existingValuation.quote = quotes.ToArray(); } } var instSet = new InstrumentSet { Items = instrumentMap.Values.ToArray() }; result.instrumentSet = instSet; result.assetQuote = valuationMap.Values.ToArray(); return(result); }
/// <summary> /// Merges a QuotedAssetSet with this. Note that the referential integrity between the assets /// and valuations is checked and maintained. /// </summary> /// <param name="additional">The additional QuotedAssetSet.</param> /// <param name="checkValuationAssetReferences">if set to <c>true</c> [check valuation asset references].</param> /// <param name="includeEmptyCurrentQuotes">if set to <c>true</c> [include empty current quotes].</param> /// <param name="includeEmptyAdditionalQuotes">if set to <c>true</c> [include empty additional quotes].</param> /// <returns></returns> public QuotedAssetSet Merge(QuotedAssetSet additional, bool checkValuationAssetReferences, bool includeEmptyCurrentQuotes, bool includeEmptyAdditionalQuotes) { var result = new QuotedAssetSet(); // build unique instrumentSet and valuation quote lists var instrumentMap = new Dictionary <string, Asset>(); var itemsMap = new Dictionary <string, ItemsChoiceType19>(); var valuationMap = new Dictionary <string, BasicAssetValuation>(); if (instrumentSet?.Items != null && instrumentSet.ItemsElementName != null) { if (instrumentSet.Items.Length == instrumentSet.ItemsElementName.Length) { var index = 0; foreach (Asset asset in instrumentSet.Items) //The asset type { string assetId = asset.id; instrumentMap[assetId.ToLower()] = asset; itemsMap[assetId.ToLower()] = instrumentSet.ItemsElementName[index]; index++; } } } if (assetQuote != null) { foreach (BasicAssetValuation currentValuation in assetQuote) { string assetId = currentValuation.objectReference.href; if (checkValuationAssetReferences) { if (!instrumentMap.TryGetValue(assetId.ToLower(), out _)) { throw new ApplicationException($"Cannot find asset '{assetId}' for assetQuote"); } } // merge the quotes if (valuationMap.TryGetValue(assetId.ToLower(), out var existingValuation)) { //Trace.WriteLine(String.Format("Merge: Asset: '{0}' updating existing valuation", assetId); } else { // not found - create a new valuation //Trace.WriteLine(String.Format("Merge: Asset: '{0}' creating existing valuation", assetId); existingValuation = new BasicAssetValuation { objectReference = new AnyAssetReference { href = assetId }, quote = new List <BasicQuotation>().ToArray() }; valuationMap[assetId.ToLower()] = existingValuation; } // append the asset quotes var quotes = new List <BasicQuotation>(existingValuation.quote); quotes.AddRange(currentValuation.quote.Where(quote => quote.valueSpecified || includeEmptyCurrentQuotes)); existingValuation.quote = quotes.ToArray(); } } // add extra instruments if (additional.instrumentSet?.Items != null && additional.instrumentSet.ItemsElementName != null) { if (additional.instrumentSet.Items.Length == additional.instrumentSet.ItemsElementName.Length) { var index = 0; foreach (Asset asset in additional.instrumentSet.Items) { string assetId = asset.id; if (!instrumentMap.ContainsKey(assetId.ToLower())) { instrumentMap[assetId.ToLower()] = asset; itemsMap[assetId.ToLower()] = additional.instrumentSet.ItemsElementName[index]; //Trace.WriteLine(String.Format("Merge: Additional asset: '{0}'", assetId); } index++; } } } // append valuation quotes if (additional.assetQuote != null) { foreach (BasicAssetValuation additionalValuation in additional.assetQuote) { string assetId = additionalValuation.objectReference.href; if (checkValuationAssetReferences) { if (!instrumentMap.TryGetValue(assetId.ToLower(), out _)) { throw new ApplicationException($"Cannot find asset '{assetId}' for assetQuote"); } } // merge the quotes if (valuationMap.TryGetValue(assetId.ToLower(), out var existingValuation)) { //Trace.WriteLine(String.Format("Merge: Asset: '{0}' updating additional valuation", assetId); } else { // not found - just add the valuation existingValuation = new BasicAssetValuation { objectReference = new AnyAssetReference { href = assetId }, quote = new List <BasicQuotation>().ToArray() }; valuationMap[assetId.ToLower()] = existingValuation; //Trace.WriteLine(String.Format("Merge: Asset: '{0}' creating additional valuation", assetId); } // append the asset quotes var quotes = new List <BasicQuotation>(existingValuation.quote); quotes.AddRange(additionalValuation.quote.Where(quote => quote.valueSpecified || includeEmptyAdditionalQuotes)); existingValuation.quote = quotes.ToArray(); } } var instSet = new InstrumentSet { Items = instrumentMap.Values.ToArray(), ItemsElementName = itemsMap.Values.ToArray() }; result.instrumentSet = instSet; result.assetQuote = valuationMap.Values.ToArray(); return(result); }
/// <summary> /// /// </summary> /// <param name="header"></param> /// <param name="v221Provider"></param> /// <param name="requestId"></param> /// <param name="requestParams"></param> /// <param name="zsQuotedAssetSet"></param> /// <returns></returns> public V221OutputQuotedAssetSet GetMarketQuotesV221(V221Header header, V221ProviderId v221Provider, Guid requestId, string requestParams, byte[] zsQuotedAssetSet) { IModuleInfo connection = null; _connectionIndex.Locked(connections => { if (!connections.TryGetValue(header.SessionId, out connection)) { throw new ApplicationException("Ignoring request from unknown client!"); } }); //var errors = new List<V221ErrorDetail>(); var result = new QuotedAssetSet(); string step = "GetMarketQuotesV221: unknown"; try { step = "GetMarketQuotesV221: decompressing"; // deserialise inputs var receivedRequest = XmlSerializerHelper.DeserializeFromString <QuotedAssetSet>(CompressionHelper.DecompressToString(zsQuotedAssetSet)); //debug dump request //this.Logger.LogDebug("Received: {0}", XmlSerializerHelper.SerializeToString<QuotedAssetSet>(receivedRequest)); // end debug step = "GetMarketQuotesV221: splitting"; // split request into provider-specific requests // build unique instrumentSet var instrumentMap = new Dictionary <string, Asset>(); foreach (Asset asset in receivedRequest.instrumentSet.Items) { string assetId = asset.id; instrumentMap[assetId.ToLower()] = asset; } // now split quotes based on provider preferences MDSProviderId defaultProvider = V221Helpers.ToProviderId(v221Provider); int providerCount = Enum.GetValues(typeof(MDSProviderId)).Length; var providerRequests = new RequestContainer[providerCount]; for (int i = 0; i < providerRequests.Length; i++) { providerRequests[i] = new RequestContainer(); } int requestedQuoteCount = 0; foreach (BasicAssetValuation valuation in receivedRequest.assetQuote) { string assetId = valuation.objectReference.href; if (!instrumentMap.TryGetValue(assetId.ToLower(), out var asset)) { throw new ApplicationException($"Cannot find asset '{assetId}' in instrument set"); } foreach (BasicQuotation quote in valuation.quote) { if (!quote.valueSpecified) { requestedQuoteCount++; MDSProviderId quoteProvider = ChooseProvider(quote.informationSource, _activeProviders, defaultProvider); RequestContainer requestContainer = providerRequests[(int)quoteProvider]; requestContainer.InstrumentMap[assetId.ToLower()] = asset; // merge the quotes if (!requestContainer.ValuationMap.TryGetValue(assetId.ToLower(), out var bav)) { // missing - create bav = new BasicAssetValuation { objectReference = new AnyAssetReference { href = assetId } }; requestContainer.ValuationMap[assetId.ToLower()] = bav; } // append the asset quotes var quotes = new List <BasicQuotation>(); if (bav.quote != null) { quotes.AddRange(bav.quote); } quotes.Add(quote); bav.quote = quotes.ToArray(); } } } if (requestedQuoteCount == 0) { throw new ApplicationException("No quotes requested!"); } step = "GetMarketQuotesV221: calling providers"; // run each provider request foreach (MDSProviderId activeProvider in _activeProviders) { RequestContainer requestContainer = providerRequests[(int)activeProvider]; if (requestContainer.InstrumentMap.Count > 0) { // request is not empty - call the MDS provider var types = new List <ItemsChoiceType19>(); foreach (var asset in requestContainer.InstrumentMap.Values) { var assetTypeFpML = AssetTypeConvertor.ParseEnumStringToFpML(asset.id);//TODO The id must contain the asset descriptor. types.Add(assetTypeFpML); } var instrumentSet = new InstrumentSet { Items = requestContainer.InstrumentMap.Values.ToArray(), ItemsElementName = types.ToArray() }; var providerRequest = new QuotedAssetSet { instrumentSet = instrumentSet, assetQuote = requestContainer.ValuationMap.Values.ToArray() }; step = "GetMarketQuotesV221: calling " + activeProvider.ToString(); QuotedAssetSet providerResult = _providers[(int)activeProvider].GetMarketQuotes( activeProvider, connection, requestId, true, new NamedValueSet(requestParams), providerRequest).Result; // combine provider-specific results result = result.Merge(providerResult, false, true, true); } } step = "GetMarketQuotesV221: compressing"; return(new V221OutputQuotedAssetSet( CompressionHelper.CompressToBuffer(XmlSerializerHelper.SerializeToString(result)), null)); } catch (Exception excp) { Logger.LogError("Exception: step='{0}': {1}", step, excp); return(new V221OutputQuotedAssetSet(null, new V221ErrorDetail(excp))); } }