Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 44 additions & 35 deletions src/examples/trading/server/price_time_order_book.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [&]<typename Side>(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)
Expand All @@ -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;
Expand Down
20 changes: 18 additions & 2 deletions src/examples/trading/server/price_time_order_book.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,27 @@ 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)
{
return std::tie(o1.price, o1.time) < std::tie(o2.price, 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<std::experimental::system_executor> strand_;
market_data_bus& market_data_bus_;
std::uint64_t next_time_;
std::priority_queue<order> buy_orders_;
std::priority_queue<order> sell_orders_;
std::priority_queue<order, std::vector<order>, buy_comparator> buy_orders_;
std::priority_queue<order, std::vector<order>, sell_comparator> sell_orders_;
};

#endif