OnixS C++ SGX Titan ITCH Market Data Handler  1.2.2
API documentation
Book.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 
21 #include "BookImpl.h"
22 
23 #include <algorithm>
24 #include <sstream>
25 
26 #include <boost/format.hpp>
27 #include <boost/foreach.hpp>
28 
29 #include "NamespaceHelper.h"
30 
31 ONIXS_HANDLER_NAMESPACE_BEGIN
32 
33 namespace
34 {
35 
36 void bestBid2string(std::stringstream& ss, Price price, Quantity quantity)
37 {
38  ss << boost::format(" - | %9d | %20d |") % quantity % price.value();
39 }
40 
41 void bestAsk2string(std::stringstream& ss, Price price, Quantity quantity)
42 {
43  ss << boost::format("%20d | %9d | - |") % price.value() % quantity ;
44 }
45 
46 void bid2string(std::stringstream& ss, const PriceLevel& bid)
47 {
48  ss << boost::format(" %9d | %9d | %20d |") % bid.numberOfOrders() % bid.quantity() % bid.price().value();
49 }
50 
51 void ask2string(std::stringstream& ss, const PriceLevel& ask)
52 {
53  ss << boost::format("%20d | %9d | %9d |") % ask.price().value() % ask.quantity() % ask.numberOfOrders();
54 }
55 
56 void printLevels(std::stringstream& presentation, const PriceLevels& levels)
57 {
58  if (!levels.empty())
59  {
60  PriceLevelsConstEntry lastLevel = --levels.end();
61 
62  for (PriceLevelsConstEntry level = levels.begin();
63  level != levels.end();
64  ++level)
65  {
66  presentation << level->toString();
67 
68  if (level != lastLevel)
69  presentation << ", ";
70  }
71  }
72 }
73 
74 } // namespace
75 
76 
77 OrderInfo::OrderInfo() :
78  orderId_(0),
79  quantity_(0)
80 {
81 }
82 
84  orderId_(orderId),
85  quantity_(quantity)
86 {
87 }
88 
89 PriceLevel::PriceLevel (const Price& price, Quantity quantity, Quantity numberOfOrders, const OrderInfos& orders) :
90  price_(price),
91  qty_(quantity),
92  orders_(orders)
93 {
94  (void) numberOfOrders;
95 }
96 
97 const size_t OrderIdsDefaultSize = 10;
98 
100  price_(),
101  qty_(0)
102 {
103  orders_.reserve(OrderIdsDefaultSize); // \todo:
104 }
105 
106 PriceLevel&
108  const PriceLevel& other)
109 {
110  if (this == &other)
111  return *this;
112 
113  PriceLevel tmp(other);
114  tmp.swap(*this);
115  return *this;
116 }
117 
119  : price_(other.price_)
120  , qty_(other.qty_)
121  , orders_(other.orders_)
122 {
123 }
124 
125 #if defined(ONIXS_SGXTITAN_ITCH_COMPILER_CXX_RVALUE_REFERENCES) && ONIXS_SGXTITAN_ITCH_COMPILER_CXX_RVALUE_REFERENCES
126 
129  : price_(std::move(other.price_))
130  , qty_(std::move(other.qty_))
131  , orders_(std::move(other.orders_))
132 {
133 }
134 
135 PriceLevel&
137  PriceLevel&& other)
139 {
140  if (this == &other)
141  return *this;
142 
143  other.swap(*this);
144  return *this;
145 }
146 
147 #endif
148 
149 
150 const Price& PriceLevel::price() const
151 {
152  return price_;
153 }
154 
155 void PriceLevel::price(const Price& value)
156 {
157  price_ = value;
158 }
159 
161 {
162  return qty_;
163 }
164 
165 void PriceLevel::quantity (Quantity value)
166 {
167  qty_ = value;
168 }
169 
171 {
172  return static_cast<Quantity>(orders_.size());
173 }
174 
176 {
177  return orders_;
178 }
179 
181 {
182  std::swap(price_, obj.price_);
183  std::swap(qty_, obj.qty_);
184  std::swap(orders_, obj.orders_);
185 }
186 
187 void PriceLevel::addOrderId(OrderId id, Quantity quantity)
188 {
189  BOOST_ASSERT(id != 0);
190  BOOST_ASSERT(quantity != 0);
191 
192  orders_.push_back(OrderInfo(id, quantity));
193 }
194 
195 struct FindById : public std::binary_function<OrderInfo, OrderId, bool>
196 {
197  bool operator()(const OrderInfo& oInf, OrderId id) const
198  {
199  BOOST_ASSERT(id != 0);
200  BOOST_ASSERT(oInf.orderId_ != 0);
201  BOOST_ASSERT(oInf.quantity_ != 0);
202 
203  return (oInf.orderId_ == id);
204  }
205 };
206 
207 void PriceLevel::removeOrderId(OrderId id)
208 {
209  BOOST_ASSERT(std::find_if(orders_.begin(), orders_.end(), std::bind2nd(FindById(), id)) != orders_.end());
210  orders_.erase(std::remove_if(orders_.begin(), orders_.end(), std::bind2nd(FindById(), id)), orders_.end());
211 }
212 
213 const Price& getPrice (const PriceLevel& level)
214 {
215  return level.price();
216 }
217 
219 {
220  BOOST_ASSERT(level.quantity() >= level.numberOfOrders());
221  BOOST_ASSERT(level.numberOfOrders() == level.orders().size());
222 
223  return (level.quantity() != 0);
224 }
225 
226 std::string PriceLevel::toString() const
227 {
228  std::string str;
229  toString (str);
230  return str;
231 }
232 
233 void PriceLevel::toString (std::string& str) const
234 {
235  std::stringstream ss;
236 
237  ss << "PriceLevel [price="
238  << price_/*.toString()*/
239  << ", quantity="
240  << qty_
241  << ", numberOfOrders="
242  << numberOfOrders()
243  << ", orders= [";
244 
245  BOOST_FOREACH(OrderInfo info, orders_)
246  {
247  ss << info.orderId_ << " - " << info.quantity_ << ", ";
248  }
249 
250  ss << "] ]";
251 
252  str = ss.str();
253 };
254 
255 std::ostream& operator << (std::ostream& stream, const PriceLevel& value)
256 {
257  stream << value.toString();
258  return stream;
259 }
260 
262  userPointer_(nullptr)
263 {
264 }
265 
267 {
268 }
269 
270 void OrderBook::setUserPointer(void* pointer)
271 {
272  userPointer_ = pointer;
273 }
274 
276 {
277  return userPointer_;
278 }
279 
280 bool OrderBook::bestAsk (Price& price, Quantity& quantity) const
281 {
282  return doBestAsk(price, quantity);
283 }
284 
285 bool OrderBook::bestBid (Price& price, Quantity& quantity) const
286 {
287  return doBestBid(price, quantity);
288 }
289 
290 size_t OrderBook::depth() const
291 {
292  return doDepth();
293 }
294 
296 {
297  return doOrderBookId();
298 }
299 
300 bool OrderBook::empty() const
301 {
302  return doAsks().empty() && doBids().empty();
303 }
304 
306 {
307  return doAsks();
308 }
309 
311 {
312  return doBids();
313 }
314 
315 std::string OrderBook::toString() const
316 {
317  std::string str;
318 
319  toString(str);
320 
321  return str;
322 }
323 
324 void OrderBook::toString (std::string& str) const
325 {
326  std::stringstream ss;
327  ss
328  << "Book [securityId="
329  << orderBookId()
330  << ", depth="
331  << depth();
332 
333  ss << ", bids: ";
334  printLevels(ss, bids());
335 
336  ss << ", asks: ";
337  printLevels(ss, asks());
338 
339  ss << ']';
340 
341  str = ss.str();
342 }
343 
344 std::string OrderBook::toShortString() const
345 {
346  std::string str;
347 
348  toShortString(str);
349 
350  return str;
351 }
352 
353 void OrderBook::toShortString (std::string& str) const
354 {
355  std::stringstream ss;
356  ss << "Book ["
357  << orderBookId()
358  << ", depth=" << depth() << "]";
359  str = ss.str();
360 }
361 
362 std::string OrderBook::toFormattedString() const
363 {
364  std::string str;
365 
366  toFormattedString (str);
367 
368  return str;
369 }
370 
371 void OrderBook::toFormattedString (std::string& str) const
372 {
373  std::stringstream ss;
374 
375  const std::string briefInfo = toShortString();
376 
377  ss << briefInfo << "\n";
378 
379 
380  ss << " |-------------------------------------------------------------------------------------------------|\n";
381  ss << " | BID | | ASC |\n";
382  ss << " |-----------------------------------------------+-+-----------------------------------------------|\n";
383  ss << " | OrderCount | Quantity | Price | | Price | Quantity | OrderCount |\n";
384  ss << " |------------+-----------+----------------------+-+----------------------+-----------+------------|\n";
385 
386  Price bestBidPrice(0);
387  Quantity bestBidQuantity = 0;
388  bool bestBidAvailable = bestBid(bestBidPrice, bestBidQuantity);
389 
390  Price bestAskPrice(0);
391  Quantity bestAskQuantity = 0;
392  bool bestAskAvailable = bestAsk(bestAskPrice, bestAskQuantity);
393 
394  if( bestBidAvailable || bestAskAvailable )
395  {
396  ss
397  << " "
398  << "b"
399  << " | ";
400 
401  bestBid2string(ss, bestBidPrice, bestBidQuantity);
402 
403  ss << " | ";
404 
405  bestAsk2string(ss, bestAskPrice, bestAskQuantity);
406 
407  ss << "\n";
408 
409  ss
410  << " "
411  << "-"
412  << " |";
413 
414  ss << "------------+-----------+----------------------+-+----------------------+-----------+------------|\n";
415  }
416 
417  static const PriceLevel zeroPriceLevel(Price(0), 0, 0);
418 
419  using namespace std;
420 
421  const size_t depth = max(bids().size(), asks().size());
422 
423  for (size_t level = 0; level < depth; ++level)
424  {
425  ss
426  << ((level < 9) ? " " : " ")
427  << level + 1
428  << " | ";
429 
430  bid2string(
431  ss,
432  level < bids().size()
433  ? bids().at(level) : zeroPriceLevel);
434 
435  ss << " | ";
436 
437 
438  ask2string(
439  ss,
440  level < asks().size()
441  ? asks().at(level) : zeroPriceLevel);
442 
443 
444  if (level + 1 != depth)
445  ss << "\n";
446  }
447 
448  ss << "\n";
449  ss << " |-------------------------------------------------------------------------------------------------|\n";
450 
451  str = ss.str();
452 }
453 
454 
455 void checkSanity(const OrderBook& book)
456 {
457  static_cast<const OrderBookInternal&>(book).checkSanity();
458 }
459 
460 
461 ONIXS_HANDLER_NAMESPACE_END
UInt64 OrderId
Alias for OrderId type.
Definition: Defines.h:40
const Price & price() const
Price value.
Definition: Book.cpp:150
void checkSanity(const OrderBook &book)
checks whether the given book is properly built
Definition: Book.cpp:455
bool operator()(const OrderInfo &oInf, OrderId id) const
Definition: Book.cpp:197
const PriceLevels & bids() const
Returns a set of ascending ask prices for the given security.
Definition: Book.cpp:310
bool bestBid(Price &price, Quantity &quantity) const
Definition: Book.cpp:285
void swap(PriceLevel &)
swap values
Definition: Book.cpp:180
STL namespace.
OrderBookId orderBookId() const
Unique instrument Id as qualified.
Definition: Book.cpp:295
std::string toShortString() const
Returns brief book info.
Definition: Book.cpp:344
Encapsulates price level concept.
Definition: OrderBook.h:47
#define ONIXS_SGXTITAN_ITCH_NOTHROW
Definition: Compiler.h:27
const PriceLevels & asks() const
Returns a set of descending bid prices for the given security.
Definition: Book.cpp:305
UInt64 Quantity
Alias for Quantity type.
Definition: Defines.h:46
UInt32 OrderBookId
Alias for Security Id type.
Definition: Defines.h:43
PriceLevelCollections::Array PriceLevels
Sequence of price levels.
Definition: OrderBook.h:135
const size_t OrderIdsDefaultSize
Definition: Book.cpp:97
const Price & getPrice(const PriceLevel &level)
Definition: Book.cpp:213
const OrderInfos & orders() const
orders ids for a given level
Definition: Book.cpp:175
Quantity quantity() const
Quantify for the given price.
Definition: Book.cpp:160
std::vector< OrderInfo > OrderInfos
Definition: OrderBook.h:44
void setUserPointer(void *pointer)
sets user data pointer
Definition: Book.cpp:270
void * getUserPointer() const
returns kept user data pointer
Definition: Book.cpp:275
size_t depth() const
Returns the maximum book depth.
Definition: Book.cpp:290
std::string toString() const
String presentation of the book.
Definition: Book.cpp:315
ONIXS_SGXTITAN_ITCH_API std::ostream & operator<<(std::ostream &stream, const ServiceDescriptor &descriptor)
bool empty() const
Indicates whether book has no bids & asks.
Definition: Book.cpp:300
bool bestAsk(Price &price, Quantity &quantity) const
Definition: Book.cpp:280
virtual ~OrderBook()
Destruction interface.
Definition: Book.cpp:266
bool isValid(const PriceLevel &level)
Definition: Book.cpp:218
PriceLevel & operator=(const PriceLevel &other)
Definition: Book.cpp:107
Quantity numberOfOrders() const
Total number of orders of given price.
Definition: Book.cpp:170
std::string toString() const
Returns string representation of the instance.
Definition: Book.cpp:226
PriceLevelCollections::ArrayConstEntry PriceLevelsConstEntry
Iterator over read-only collection of price levels.
Definition: OrderBook.h:141
std::string toFormattedString() const
Returns formatted presentation of the book.
Definition: Book.cpp:362