OnixS C++ Eurex T7 Market and Reference Data Interface (EMDI, RDI, EOBI) Handlers  8.1.0
API documentation
InterfaceDescriptorBuilder.cpp
Go to the documentation of this file.
1 /*
2 * Copyright Onix Solutions Limited [OnixS]. All rights reserved.
3 *
4 * This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
5 * and international copyright treaties.
6 *
7 * Access to and use of the software is governed by the terms of the applicable ONIXS Software
8 * Services Agreement (the Agreement) and Customer end user license agreements granting
9 * a non-assignable, non-transferable and non-exclusive license to use the software
10 * for it's own data processing purposes under the terms defined in the Agreement.
11 *
12 * Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
13 * of this source code or associated reference material to any other location for further reproduction
14 * or redistribution, and any amendments to this copyright notice, are expressly prohibited.
15 *
16 * Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17 * the terms of the Agreement is a violation of copyright law.
18 */
19 #include <boost/assert.hpp>
20 #include <boost/foreach.hpp>
21 
23 
24 #include "Formatting.h"
26 
27 
28 namespace OnixS {
29 namespace Eurex {
30 namespace MarketData {
31 namespace Implementation {
32 
33 
34 void fillFeedDescriptor(const Feed& feed, FeedDescriptor& descriptor)
35 {
36  descriptor.serviceA.address =
38 
39  descriptor.serviceA.port =
41 
42  StringRef mdSecondaryFeedLineID;
43  if(feed.mdSecondaryFeedLineID(mdSecondaryFeedLineID))
44  {
45  descriptor.serviceB.address = mdSecondaryFeedLineID.toString();
46  feed.mdSecondaryFeedLineSubID(descriptor.serviceB.port);
47  }
48 }
49 
50 void fillMarketDepth(const Feed& feed, UInt32& highMarketDepth)
51 {
52  UInt32 marketDepth = 0;
53  const bool result = feed.marketDepth(marketDepth);
54 
55  BOOST_ASSERT(result);
56  (void) result;
57 
58  highMarketDepth = (std::max)(marketDepth, highMarketDepth);
59 }
60 
61 void fillDescriptor(const ProductSnapshot& msg, EmdiDescriptor& descriptor, UInt32& depth)
62 {
63  UInt32 highIncrementalMarketDepth = 0;
64  UInt32 highSnapshotMarketDepth = 0;
65 
66  const Feeds& feeds = msg.feeds();
67 
68  for(size_t i = 0, size = feeds.size(); i < size; ++i)
69  {
70  const Feed& feed = feeds[i];
71 
72  if(feed.mdBookType() == BookType::PriceDepth)
73  {
75  {
76  fillFeedDescriptor(feed, descriptor.incrementalFeed);
77  fillMarketDepth(feed, highIncrementalMarketDepth);
78  }
79  else if( feed.mdFeedType() == FeedType::HighSnapshot )
80  {
81  fillFeedDescriptor(feed, descriptor.snapshotFeed);
82  fillMarketDepth(feed, highSnapshotMarketDepth);
83  }
84  }
85  }
86 
87  depth = (std::max)(highSnapshotMarketDepth, highIncrementalMarketDepth);
88 }
89 
90 void fillDescriptor(const ProductSnapshot& msg, MdiDescriptor& descriptor, UInt32& depth)
91 {
92  UInt32 highIncrementalMarketDepth = 0;
93 
94  const Feeds& feeds = msg.feeds();
95 
96  for (size_t i = 0, size = feeds.size(); i < size; ++i)
97  {
98  const Feed& feed = feeds[i];
99 
100  if (feed.mdBookType() == BookType::PriceDepth)
101  {
102  if (feed.mdFeedType() == FeedType::Low)
103  {
104  fillFeedDescriptor(feed, descriptor.incrementalFeed);
105  fillMarketDepth(feed, highIncrementalMarketDepth);
106  }
107  }
108  }
109 
110  depth = highIncrementalMarketDepth;
111 }
112 
113 void fillDescriptor(const ProductSnapshot& msg, EobiDescriptor& descriptor)
114 {
115  const Feeds& feeds = msg.feeds();
116 
117  for(size_t i = 0, size = feeds.size(); i < size; ++i)
118  {
119  const Feed& feed = feeds[i];
120 
121  if(feed.mdBookType() == BookType::OrderDepth)
122  {
124  {
125  fillFeedDescriptor(feed, descriptor.incrementalFeed);
126  }
127  else if( feed.mdFeedType() == FeedType::HighSnapshot )
128  {
129  fillFeedDescriptor(feed, descriptor.snapshotFeed);
130  }
131  }
132  }
133 }
134 
135 const size_t InterfaceDescriptorPresetSize = 100;
136 
138  referenceDataReady_(false)
139 {
140  emdiDescriptors_.reserve(InterfaceDescriptorPresetSize);
141  mdiDescriptors_.reserve(InterfaceDescriptorPresetSize);
142  eobiDescriptors_.reserve(InterfaceDescriptorPresetSize);
143 }
144 
146 {
147 }
148 
150 {
151  referenceDataReady_ = true;
152 }
153 
155 {
156  Guard guard(lock_);
157 
158  emdiDescriptors_.clear();
159  mdiDescriptors_.clear();
160  eobiDescriptors_.clear();
161 
162  referenceDataReady_ = false;
163 }
164 
166 {
168  return;
169 
170  ProductInfo productInfo;
171 
172  productInfo.marketSegment = msg.marketSegment().toString();
173  productInfo.marketSegmentId = msg.marketSegmentId();
174  productInfo.partitionId = msg.partitionId();
175 
176  EmdiDescriptor newEmdiDescriptor;
177  MdiDescriptor newMdiDescriptor;
178  EobiDescriptor newEobiDescriptor;
179 
180  fillDescriptor(msg, newEmdiDescriptor, productInfo.marketDepth);
181  fillDescriptor(msg, newMdiDescriptor, productInfo.mdiMarketDepth);
182  fillDescriptor(msg, newEobiDescriptor);
183 
184  applyDescriptor(newEmdiDescriptor, productInfo);
185  applyDescriptor(newMdiDescriptor, productInfo);
186  applyDescriptor(newEobiDescriptor, productInfo);
187 }
188 
189 void InterfaceDescriptorBuilder::applyDescriptor(const EmdiDescriptor& descriptor, const ProductInfo& productInfo)
190 {
191  bool foundFlag = false;
192 
193  EmdiDescriptor* changingDescriptor = nullptr;
194 
195  BOOST_FOREACH(EmdiDescriptor& emdiDescriptor, emdiDescriptors_)
196  {
197  if(emdiDescriptor.incrementalFeed == descriptor.incrementalFeed &&
198  emdiDescriptor.snapshotFeed == descriptor.snapshotFeed)
199  {
200  changingDescriptor = &emdiDescriptor;
201 
202  foundFlag = true;
203  break;
204  }
205  }
206 
207  Guard guard(lock_);
208 
209  if(!foundFlag)
210  {
211  emdiDescriptors_.push_back(descriptor);
212  changingDescriptor = &emdiDescriptors_.back();
213  }
214 
215  BOOST_ASSERT(changingDescriptor);
216  changingDescriptor->productInfos.push_back(productInfo);
217  changingDescriptor->marketSegmentId2Depth[productInfo.marketSegmentId] = productInfo.marketDepth;
218 }
219 
220 void InterfaceDescriptorBuilder::applyDescriptor(const MdiDescriptor& descriptor, const ProductInfo& productInfo)
221 {
222  bool foundFlag = false;
223 
224  MdiDescriptor* changingDescriptor = nullptr;
225 
226  BOOST_FOREACH(MdiDescriptor& emdiDescriptor, mdiDescriptors_)
227  {
228  if (emdiDescriptor.incrementalFeed == descriptor.incrementalFeed &&
229  emdiDescriptor.snapshotFeed == descriptor.snapshotFeed)
230  {
231  changingDescriptor = &emdiDescriptor;
232 
233  foundFlag = true;
234  break;
235  }
236  }
237 
238  Guard guard(lock_);
239 
240  if (!foundFlag)
241  {
242  mdiDescriptors_.push_back(descriptor);
243  changingDescriptor = &mdiDescriptors_.back();
244  }
245 
246  BOOST_ASSERT(changingDescriptor);
247  changingDescriptor->productInfos.push_back(productInfo);
248  changingDescriptor->marketSegmentId2Depth[productInfo.marketSegmentId] = productInfo.mdiMarketDepth;
249 }
250 
251 void InterfaceDescriptorBuilder::applyDescriptor(const EobiDescriptor& descriptor, const ProductInfo& productInfo)
252 {
253  if(descriptor.incrementalFeed.serviceA.port != 0)
254  {
255  bool foundFlag = false;
256  EobiDescriptor* changingDescriptor = nullptr;
257 
258  BOOST_FOREACH(EobiDescriptor& eobiDescriptor, eobiDescriptors_)
259  {
260  if(eobiDescriptor.incrementalFeed == descriptor.incrementalFeed &&
261  eobiDescriptor.snapshotFeed == descriptor.snapshotFeed )
262  {
263  changingDescriptor = &eobiDescriptor;
264 
265  foundFlag = true;
266  break;
267  }
268  }
269 
270  Guard guard(lock_);
271 
272  if(!foundFlag)
273  {
274  eobiDescriptors_.push_back(descriptor);
275  changingDescriptor = &eobiDescriptors_.back();
276  }
277 
278  BOOST_ASSERT(changingDescriptor);
279  changingDescriptor->productInfos.push_back(productInfo);
280  }
281 }
282 
284 {
285  if(!referenceDataReady_)
286  return EmdiDescriptors();
287 
288  Guard guard(lock_);
289 
290  const EmdiDescriptors tmpDescriptors(emdiDescriptors_);
291  return tmpDescriptors;
292 }
293 
295 {
296  if(!referenceDataReady_)
297  return EmdiDescriptors();
298 
299  EmdiDescriptors tmpEmdiDescriptors;
300  MarketSegments tmpProductNames(productNames);
301 
302  Guard guard(lock_);
303 
304  BOOST_FOREACH(const EmdiDescriptor& emdiDescriptor, emdiDescriptors_)
305  {
306  EmdiDescriptor tmpEmdiDescriptor(emdiDescriptor);
307 
308  BOOST_FOREACH(const ProductInfo& info, tmpEmdiDescriptor.productInfos)
309  {
310  MarketSegments::const_iterator it = tmpProductNames.find(info.marketSegment);
311  if(it != tmpProductNames.end())
312  {
313  tmpEmdiDescriptor.partitionIdFilters.insert(info.partitionId);
314  tmpEmdiDescriptor.marketSegmentIdFilters.insert(info.marketSegmentId);
315  tmpProductNames.erase(it);
316  }
317  }
318 
319  if(!tmpEmdiDescriptor.partitionIdFilters.empty())
320  tmpEmdiDescriptors.push_back(tmpEmdiDescriptor);
321 
322  if(tmpProductNames.empty())
323  break;
324  }
325 
326  return tmpEmdiDescriptors;
327 }
328 
330 {
331  if (!referenceDataReady_)
332  return MdiDescriptors();
333 
334  Guard guard(lock_);
335 
336  const MdiDescriptors tmpDescriptors(mdiDescriptors_);
337  return tmpDescriptors;
338 }
339 
341 {
342  if (!referenceDataReady_)
343  return MdiDescriptors();
344 
345  MdiDescriptors tmpMdiDescriptors;
346  MarketSegments tmpProductNames(productNames);
347 
348  Guard guard(lock_);
349 
350  BOOST_FOREACH(const MdiDescriptor& emdiDescriptor, mdiDescriptors_)
351  {
352  MdiDescriptor tmpMdiDescriptor(emdiDescriptor);
353 
354  BOOST_FOREACH(const ProductInfo& info, tmpMdiDescriptor.productInfos)
355  {
356  MarketSegments::const_iterator it = tmpProductNames.find(info.marketSegment);
357  if (it != tmpProductNames.end())
358  {
359  tmpMdiDescriptor.partitionIdFilters.insert(info.partitionId);
360  tmpMdiDescriptor.marketSegmentIdFilters.insert(info.marketSegmentId);
361  tmpProductNames.erase(it);
362  }
363  }
364 
365  if (!tmpMdiDescriptor.partitionIdFilters.empty())
366  tmpMdiDescriptors.push_back(tmpMdiDescriptor);
367 
368  if (tmpProductNames.empty())
369  break;
370  }
371 
372  return tmpMdiDescriptors;
373 }
374 
376 {
377  if(!referenceDataReady_)
378  return EobiDescriptors();
379 
380  Guard guard(lock_);
381 
382  const EobiDescriptors tmpDescriptors(eobiDescriptors_);
383  return tmpDescriptors;
384 }
385 
387 {
388  if(!referenceDataReady_)
389  return EobiDescriptors();
390 
391  EobiDescriptors tmpEobiDescriptors;
392 
393  MarketSegments tmpProductNames(productNames);
394 
395  Guard guard(lock_);
396 
397  BOOST_FOREACH(const EobiDescriptor& eobiDescriptor, eobiDescriptors_)
398  {
399  EobiDescriptor tmpEobiDescriptor(eobiDescriptor);
400 
401  BOOST_FOREACH(const ProductInfo& info, tmpEobiDescriptor.productInfos)
402  {
403  MarketSegments::const_iterator it = tmpProductNames.find(info.marketSegment);
404  if( it != tmpProductNames.end() )
405  {
406  tmpEobiDescriptor.partitionIdFilters.insert(info.partitionId);
407  tmpEobiDescriptor.marketSegmentIdFilters.insert(info.marketSegmentId);
408  tmpProductNames.erase(it);
409  }
410  }
411 
412  if( !tmpEobiDescriptor.partitionIdFilters.empty() )
413  tmpEobiDescriptors.push_back(tmpEobiDescriptor);
414 
415  if( tmpProductNames.empty() )
416  break;
417  }
418 
419  return tmpEobiDescriptors;
420 }
421 
423 {
424  OnixS::Util::TextBuilder textBuilder;
425 
426  Guard guard(lock_);
427 
428  BOOST_FOREACH(const EmdiDescriptor& emdiDescriptor, emdiDescriptors_)
429  {
430  textBuilder << emdiDescriptor;
431  }
432 
433  BOOST_FOREACH(const MdiDescriptor& mdiDescriptor, mdiDescriptors_)
434  {
435  textBuilder << mdiDescriptor;
436  }
437 
438  BOOST_FOREACH(const EobiDescriptor& eobiDescriptor, eobiDescriptors_)
439  {
440  textBuilder << eobiDescriptor;
441  }
442 
443  return textBuilder.toString();
444 }
445 
446 }}}}
MarketSegmentIdFilters marketSegmentIdFilters
Contains list of market segment ids.
StringRef mdPrimaryFeedLineID() const
IP Address for Service A.
UInt32 mdiMarketDepth
Maximum number of price levels for the product in MDI.
void fillMarketDepth(const Feed &feed, UInt32 &highMarketDepth)
void fillDescriptor(const ProductSnapshot &msg, EmdiDescriptor &descriptor, UInt32 &depth)
ServiceDescriptor serviceA
Service A.
EobiDescriptor::Collection EobiDescriptors
FeedType::Enum mdFeedType() const
Feed type.
ServiceDescriptor serviceB
Service B.
PartitionIdFilters partitionIdFilters
Contains list of interface partition ids.
MarketSegmentId2Depth marketSegmentId2Depth
Contains market segment to maximum number of price levels for the product map.
MarketSegmentId marketSegmentId() const
Product identifier.
Util::TextBuilder TextBuilder
Definition: Formatting.h:43
UInt32 marketDepth
Maximum number of price levels for the product in EMDI.
MarketSegmentSubType::Enum marketSegmentSubType() const
Market Segment subtype.
size_t size() const
Return number of instances in repeating group.
Definition: Group.h:123
unsigned int UInt32
Definition: Numeric.h:41
Definition: Defines.h:30
ProductInfos productInfos
Contains information about all products for the interface.
Defines if product is still traded on "Eurex classic".
bool marketDepth(UInt32 &depth) const
Maximum number of price levels for the product.
MarketSegmentId marketSegmentId
Market segment id.
Defines if product is still traded on "Eurex classic".
PartitionIdFilters partitionIdFilters
Contains list of interface partition ids.
ProductInfos productInfos
Contains information about all products for the interface.
EmdiDescriptor::Collection EmdiDescriptors
MdiDescriptor::Collection MdiDescriptors
void fillFeedDescriptor(const Feed &feed, FeedDescriptor &descriptor)
MarketSegmentIdFilters marketSegmentIdFilters
Contains list of market segment ids.
UInt32 mdPrimaryFeedLineSubID() const
Port number for IP address Service A.
StringRef marketSegment() const
Product name.
Defines if product is traded on on NTA.
PartitionIdFilters partitionIdFilters
Contains list of interface partition ids.
MarketSegmentId2Depth marketSegmentId2Depth
Contains market segment to maximum number of price levels for the product map.
bool mdSecondaryFeedLineSubID(UInt32 &subId) const
Port number for IP address Service B.
void toString(std::string &str) const
Definition: StringRef.h:175
MarketSegment marketSegment
Market segment (product name).
MarketSegmentIdFilters marketSegmentIdFilters
Contains list of market segment ids.
IInterfaceDescriptorProvider::MarketSegments MarketSegments
ProductInfos productInfos
Contains information about all products for the interface.
bool mdSecondaryFeedLineID(StringRef &id) const
IP Address for Service B.
BookType::Enum mdBookType() const
Book type.
PartitionId partitionId() const
Partition of the product.