From 3614555b2238adbfde339631918a8e247fe2a554 Mon Sep 17 00:00:00 2001 From: Arash Partow Date: Mon, 1 Jan 2018 00:00:00 +0000 Subject: [PATCH] Bring the PT orderbook in line with reality --- .../trading/server/price_time_order_book.cpp | 79 +++++++++++-------- .../trading/server/price_time_order_book.hpp | 22 +++++- 2 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/examples/trading/server/price_time_order_book.cpp b/src/examples/trading/server/price_time_order_book.cpp index 5c15247..a21ecd4 100644 --- a/src/examples/trading/server/price_time_order_book.cpp +++ b/src/examples/trading/server/price_time_order_book.cpp @@ -39,39 +39,45 @@ void price_time_order_book::process_new_order(order_management::new_order o) bool price_time_order_book::find_match(order_management::new_order& o) { - auto& other_side = (o.side == order_side::buy) ? sell_orders_ : buy_orders_; - - // Is there anything at all to match on the other side? - if (other_side.empty()) - return false; - - // Do we cross the order on the other side of the book? - order passive_order = other_side.top(); - if ((o.side == order_side::buy && o.price < passive_order.price) - || (o.side == order_side::sell && o.price > passive_order.price)) - return false; - - // Work out how much is going to trade and deduct from both orders. - unsigned int trade_quantity = std::min(o.quantity, passive_order.quantity); - o.quantity -= trade_quantity; - passive_order.quantity -= trade_quantity; - - // If the passive order has no remaining quantity, permanently remove it from - // the book. Otherwise, reenter it into the book with its updated quantity. - other_side.pop(); - if (passive_order.quantity > 0) - other_side.push(passive_order); - - // Dispatch the trade to the market data bus. - market_data::trade md_trade; - md_trade.sequence_number = 0; - md_trade.symbol = symbol(); - md_trade.aggressor_side = o.side; - md_trade.price = passive_order.price; - md_trade.quantity = trade_quantity; - market_data_bus_.dispatch_event(md_trade); - - return true; + const auto impl = [&](Side other_side) -> bool + { + // Is there anything at all to match on the other side? + if (other_side.empty()) + return false; + + // Do we cross the order on the other side of the book? + order passive_order = other_side.top(); + if ((o.side == order_side::buy && o.price < passive_order.price) + || (o.side == order_side::sell && o.price > passive_order.price)) + return false; + + // Work out how much is going to trade and deduct from both orders. + unsigned int trade_quantity = std::min(o.quantity, passive_order.quantity); + o.quantity -= trade_quantity; + passive_order.quantity -= trade_quantity; + + // If the passive order has no remaining quantity, permanently remove it from + // the book. Otherwise, reenter it into the book with its updated quantity. + other_side.pop(); + if (passive_order.quantity > 0) + other_side.push(passive_order); + + // Dispatch the trade to the market data bus. + market_data::trade md_trade; + md_trade.sequence_number = 0; + md_trade.symbol = symbol(); + md_trade.aggressor_side = o.side; + md_trade.price = passive_order.price; + md_trade.quantity = trade_quantity; + market_data_bus_.dispatch_event(md_trade); + + return true; + }; + + if (o.side == order_side::buy) + return impl(sell_orders_); + else + return impl(buy_orders_); } void price_time_order_book::add_order(const order_management::new_order& o) @@ -81,8 +87,11 @@ void price_time_order_book::add_order(const order_management::new_order& o) passive_order.price = o.price; passive_order.time = next_time_++; passive_order.quantity = o.quantity; - auto& this_side = (o.side == order_side::buy) ? buy_orders_ : sell_orders_; - this_side.push(passive_order); + + if (o.side == order_side::buy) + buy_orders_.push(passive_order); + else + sell_orders_.push(passive_order); // Dispatch the new order to the market data bus. market_data::new_order md_new_order; diff --git a/src/examples/trading/server/price_time_order_book.hpp b/src/examples/trading/server/price_time_order_book.hpp index d83768c..a632c95 100644 --- a/src/examples/trading/server/price_time_order_book.hpp +++ b/src/examples/trading/server/price_time_order_book.hpp @@ -49,11 +49,29 @@ class price_time_order_book : public order_book bool operator<(const order& other) const; }; + struct buy_comparator + { + bool operator() (const order& o1, const order& o2) + { + if (o1.price > o2.price) return true; + if (o1.price < o2.price) return false; + return (o1.time < o2.time); + } + }; + + struct sell_comparator + { + bool operator() (const order& o1, const order& o2) + { + return std::tie(o1.price,o1.time) < std::tie(o2.price,o2.time); + } + }; + std::experimental::strand strand_; market_data_bus& market_data_bus_; std::uint64_t next_time_; - std::priority_queue buy_orders_; - std::priority_queue sell_orders_; + std::priority_queue, buy_comparator> buy_orders_; + std::priority_queue, sell_comparator> sell_orders_; }; #endif