OnixS C++ SGX Titan ITCH Market Data Handler  1.2.2
API documentation
BookImpl.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 
22 #include "BookImpl.h"
23 
24 ONIXS_HANDLER_NAMESPACE_BEGIN
25 
26 Order::Order() :
27  id_(0),
28  price_(),
29  quantity_(0)
30 {
31 }
32 
33 Order::Order(const OrderId& inId, const Price& inPrice, Quantity inQuantity) :
34  id_(inId),
35  price_(inPrice),
36  quantity_(inQuantity)
37 {
38 }
39 
40 void Order::addOrder(const Order& order, PriceLevel& level)
41 {
42  BOOST_ASSERT(level.numberOfOrders() == level.orders().size());
43 
44  level.quantity(level.quantity() + order.quantity_);
45  level.addOrderId(order.id_, order.quantity_);
46 
47  BOOST_ASSERT(level.quantity() >= level.numberOfOrders());
48  BOOST_ASSERT(level.numberOfOrders() == level.orders().size());
49 }
50 
51 void Order::removeOrder(const Order& order, PriceLevel& level)
52 {
53  BOOST_ASSERT(level.quantity() >= order.quantity_);
54  BOOST_ASSERT(level.numberOfOrders() > 0);
55  BOOST_ASSERT(level.quantity() >= level.numberOfOrders());
56  BOOST_ASSERT(level.numberOfOrders() == level.orders().size());
57 
58  level.quantity(level.quantity() - order.quantity_);
59  level.removeOrderId(order.id_);
60 
61  BOOST_ASSERT(level.quantity() >= level.numberOfOrders());
62  BOOST_ASSERT(level.numberOfOrders() == level.orders().size());
63 }
64 
66 {
67  return true;
68 }
69 
70 void addOrder(const Order& order, PriceLevel& level)
71 {
72  Order::addOrder(order, level);
73 }
74 
75 void removeOrder(const Order& order, PriceLevel& level)
76 {
77  Order::removeOrder(order, level);
78 }
79 
80 bool isOrderAffectsPriceLevel(const Order& order)
81 {
82  return Order::isOrderAffectsPriceLevel(order);
83 }
84 const OrderId& getOrderId(const Order& order)
85 {
86  return order.id_;
87 }
88 
89 const Price& getPrice(const Order& order)
90 {
91  return order.price_;
92 }
93 
94 
96 (
97  const OrderBookId& id,
98  size_t bookDepth,
99  size_t maxAggregatedPriceLevelsCount,
100  const PoolManagerPtr& poolManager
101  ) :
102  OrderDepthBook(maxAggregatedPriceLevelsCount, bookDepth, poolManager),
103  bookDepth_(bookDepth),
104  id_(id)
105 {
106 }
107 
109 {}
110 
111 size_t OrderBookInternal::doDepth() const
112 {
113  return bookDepth_;
114 }
115 
116 const PriceLevels& OrderBookInternal::doAsks() const
117 {
118  return OrderDepthBook::askOrders().levels().levels();
119 }
120 
121 const PriceLevels& OrderBookInternal::doBids() const
122 {
123  return OrderDepthBook::bidOrders().levels().levels();
124 }
125 
126 bool OrderBookInternal::doBestAsk(Price& price, Quantity& quantity) const
127 {
128  const PriceLevels& levels = doAsks();
129 
130  if(levels.empty())
131  return false;
132 
133  price = levels[0].price();
134  quantity = levels[0].quantity();
135 
136  return true;
137 }
138 
139 bool OrderBookInternal::doBestBid(Price& price, Quantity& quantity) const
140 {
141  const PriceLevels& levels = doBids();
142 
143  if(levels.empty())
144  return false;
145 
146  price = levels[0].price();
147  quantity = levels[0].quantity();
148 
149  return true;
150 }
151 
152 OrderBookId OrderBookInternal::doOrderBookId() const
153 {
154  return id_;
155 }
156 
157 void* OrderBookInternal::operator new (std::size_t)
158 {
159  throw std::bad_alloc();
160 }
161 
162 void OrderBookInternal::operator delete (void*)
163 {
164 }
165 
166 void* OrderBookInternal::operator new (std::size_t, void* p)
167 {
168  return p;
169 }
170 
171 void OrderBookInternal::operator delete (void*, void*)
172 {
173 }
174 
176 {
177  checkAsksSanity();
178  checkBidsSanity();
179 
180  Price bestAskPrice;
181  Quantity bestAskQuantity;
182  const bool hasBestAsk = bestAsk(bestAskPrice, bestAskQuantity);
183 
184  Price bestBidPrice;
185  Quantity bestBidQuantity;
186  const bool hasBestBid = bestBid(bestBidPrice, bestBidQuantity);
187 
188  (void) hasBestAsk;
189  (void) hasBestBid;
190 }
191 
192 void OrderBookInternal::checkAsksSanity() const
193 {
194  const PriceLevels& asksLevels = asks();
195 
196  Price bestAskPrice;
197  Quantity bestAskQuantity;
198  const bool hasBestAsk = bestAsk(bestAskPrice, bestAskQuantity);
199 
200  if(asksLevels.size() == 0)
201  return;
202 
203  if(!hasBestAsk)
204  throw OperationException (__FUNCTION__, "best ask does not exist");
205 
206  if(asksLevels.at(0).price() != bestAskPrice)
207  throw OperationException (__FUNCTION__, "best ask is wrong");
208 
209  for(PriceLevels::const_iterator pos = asksLevels.begin(), end = asksLevels.end(); pos != end; ++pos)
210  {
211  if(pos->quantity() <= 0)
212  throw OperationException (__FUNCTION__, "quantity is not positive number");
213  }
214 
215  for(size_t i = 1; i < asksLevels.size(); ++i)
216  {
217  if(!isValid(asksLevels.at(i)))
218  throw OperationException (__FUNCTION__, "invalid price level");
219  }
220 
221  for(size_t i = 1; i < asksLevels.size(); ++i)
222  {
223  if(asksLevels.at(i).price() != Price(0))
224  {
225  if(asksLevels.at(i - 1).price() >= asksLevels.at(i).price())
226  throw OperationException (__FUNCTION__, "wrong price level order");
227  }
228  }
229 }
230 
231 void OrderBookInternal::checkBidsSanity() const
232 {
233  const PriceLevels& bidsLevels = bids();
234 
235  Price bestBidPrice;
236  Quantity bestBidQuantity;
237  const bool hasBestBid = bestBid(bestBidPrice, bestBidQuantity);
238 
239  if(bidsLevels.size() == 0)
240  return;
241 
242  if(!hasBestBid)
243  throw OperationException (__FUNCTION__, "best bid does not exist");
244 
245  if(bidsLevels.at(0).price() != bestBidPrice)
246  throw OperationException (__FUNCTION__, "best bid is wrong");
247 
248  for(PriceLevels::const_iterator pos = bidsLevels.begin(), end = bidsLevels.end(); pos != end; ++pos)
249  {
250  if(pos->quantity() <= 0)
251  throw OperationException (__FUNCTION__, "quantity is not positive number");
252  }
253 
254  for(size_t i = 1; i < bidsLevels.size(); ++i)
255  {
256  if(!isValid(bidsLevels.at(i)))
257  throw OperationException (__FUNCTION__, "invalid price level");
258  }
259 
260  for(size_t i = 1; i < bidsLevels.size(); ++i)
261  {
262  if(bidsLevels.at(i).price() != Price(0))
263  {
264  if(bidsLevels.at(i - 1).price() <= bidsLevels.at(i).price())
265  throw OperationException (__FUNCTION__, "wrong price level order");
266  }
267  }
268 }
269 
271 {
272  return OrderDepthBook::askOrders();
273 }
274 
276 {
277  return OrderDepthBook::askOrders();
278 }
279 
281 {
282  return OrderDepthBook::bidOrders();
283 }
284 
286 {
287  return OrderDepthBook::bidOrders();
288 }
289 
290 void OrderBookInternal::remove(const OrderId& orderId)
291 {
292  return OrderDepthBook::remove(orderId);
293 }
294 
296 {
297  OrderDepthBook::clear();
298 }
299 
300 
302  poolSize_(objectsAmount * sizeof(OrderBookInternal)),
303  poolPtr_(poolSize_, 0),
304  allocator_(&poolPtr_.front(), poolSize_)
305 {
306 }
307 
309 {
310  allocator_.reset();
311 }
312 
314 {
315  return allocator_.allocate(sizeof(OrderBookInternal));
316 }
317 
319 {
320  allocator_.reset();
321 }
322 
323 size_t hash_value(OrderBookInternal const& book)
324 {
325  size_t seed = 0;
326 
327  const PriceLevels& asks = book.asks();
328  for(PriceLevels::const_iterator i = asks.begin(), end = asks.end(); i < end; ++i)
329  {
330  boost::hash_combine(seed, i->quantity());
331  boost::hash_combine(seed, i->numberOfOrders());
332  boost::hash_combine(seed, (Int64)i->price().value());
333  }
334 
335  const PriceLevels& bids = book.bids();
336  for(PriceLevels::const_iterator i = bids.begin(), end = bids.end(); i < end; ++i)
337  {
338  boost::hash_combine(seed, i->quantity());
339  boost::hash_combine(seed, i->numberOfOrders());
340  boost::hash_combine(seed, (Int64)i->price().value());
341  }
342 
343  return seed;
344 }
345 
346 
347 ONIXS_HANDLER_NAMESPACE_END
size_t hash_value(OrderBookInternal const &book)
Definition: BookImpl.cpp:323
UInt64 OrderId
Alias for OrderId type.
Definition: Defines.h:40
static bool isOrderAffectsPriceLevel(const Order &order)
Definition: BookImpl.cpp:65
const PriceLevels & bids() const
Returns a set of ascending ask prices for the given security.
Definition: Book.cpp:310
static void removeOrder(const Order &order, PriceLevel &level)
Definition: BookImpl.cpp:51
OrderBookInternal(const OrderBookId &id, size_t bookDepth, size_t maxAggregatedPriceLevelsCount=(size_t)-1, const PoolManagerPtr &poolManager=PoolManagerPtr())
Definition: BookImpl.cpp:96
Encapsulates price level concept.
Definition: OrderBook.h:47
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
OrderDepthBook::BidFullOrderDepthMap BidFullOrderDepthMap
Definition: BookImpl.h:66
const OrderId & getOrderId(const Order &order)
Definition: BookImpl.cpp:84
OrderDepthBook::AskFullOrderDepthMap AskFullOrderDepthMap
Definition: BookImpl.h:65
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
OnixS::HandlerCore::MarketData::FullOrderDepthBook< PriceLevel, Order, OrderId, Price, BaseFullOrderDepthBook > OrderDepthBook
Definition: BookImpl.h:60
static void addOrder(const Order &order, PriceLevel &level)
Definition: BookImpl.cpp:40
OrderDepthBook::PoolManagerPtr PoolManagerPtr
Definition: BookImpl.h:68
bool isValid(const PriceLevel &level)
Definition: Book.cpp:218
Quantity numberOfOrders() const
Total number of orders of given price.
Definition: Book.cpp:170