8#include <order_book/feed.hpp>
22 std::optional<Level>
bid;
23 std::optional<Level>
ask;
46 std::vector<LevelEntry>
bids;
47 std::vector<LevelEntry>
asks;
73 bool reduce(
BookLevels& book, std::uint32_t level, Shares quantity,
bool removed);
80 return m_records[level];
83 [[nodiscard]] std::size_t
size()
const {
return m_records.size() - 1 - m_free.size(); }
88 Added create(std::vector<LevelEntry>& levels, std::size_t index,
const AddOrder& order,
89 std::uint16_t locate);
91 [[nodiscard]]
static bool worse(Side side, Price lhs, Price rhs)
93 return side == Side::Buy ? lhs < rhs : lhs > rhs;
97 [[nodiscard]]
static std::size_t position(
const std::vector<LevelEntry>& levels, Side side,
100 std::vector<LevelRecord> m_records = std::vector<LevelRecord>(1);
101 std::vector<std::uint32_t> m_free;
105 std::uint16_t locate)
107 auto& levels = order.
side == Side::Buy ? book.
bids : book.
asks;
108 const auto index = position(levels, order.
side, order.
price);
109 if (index == 0 || levels[index - 1].price != order.
price) {
110 return create(levels, index, order, locate);
112 const auto handle = levels[index - 1].level;
113 auto& level = m_records[handle];
114 level.total += order.
shares;
116 return {.level = handle, .changed = index == levels.size() && order.
shares != 0};
123 auto& record = m_records[level];
124 auto& levels = record.side == Side::Buy ? book.
bids : book.
asks;
125 const auto best = levels.back().level == level;
127 auto changed = best && quantity != 0;
128 record.total -= quantity;
129 if (removed && --record.orders == 0) {
137 auto index = levels.size() - 2;
138 while (levels[index].level != level) {
141 levels.erase(levels.begin() +
static_cast<std::ptrdiff_t
>(index));
143 m_free.push_back(level);
151 if (!book.
bids.empty()) {
152 const auto& best = book.
bids.back();
153 bbo.bid =
Level{.price = best.price, .quantity = m_records[best.level].total};
155 if (!book.
asks.empty()) {
156 const auto& best = book.
asks.back();
157 bbo.ask =
Level{.price = best.price, .quantity = m_records[best.level].total};
162inline std::size_t LevelPool::position(
const std::vector<LevelEntry>& levels, Side side,
166 auto index = levels.size();
167 while (index > 0 && worse(side, price, levels[index - 1].price)) {
Bbo bbo(const BookLevels &book) const
Best bid and offer of book.
Added add(BookLevels &book, const AddOrder &order, std::uint16_t locate=0)
const LevelRecord & operator[](std::uint32_t level) const
The record of level level.
bool reduce(BookLevels &book, std::uint32_t level, Shares quantity, bool removed)
std::size_t size() const
Number of levels in every book.
B or S: add a resting order.
Side side
Side the order rests on.
Best bid and offer; an empty side has no level.
std::optional< Level > bid
Highest bid level.
friend bool operator==(const Bbo &, const Bbo &)=default
Same levels on both sides.
std::optional< Level > ask
std::vector< LevelEntry > asks
Ask levels, lowest price last.
std::vector< LevelEntry > bids
Bid levels, highest price last.
std::uint32_t level
Handle of the level in its pool.
The level an add went to, and whether it changed its book's best bid or offer.
bool changed
Whether the best bid or offer changed.
std::uint32_t level
Handle of the level.
The orders resting at one price: their total, their count, and the book and side they are in.
Side side
Side the level is on.
std::uint16_t locate
Book the level belongs to, where a pool serves several; 0 otherwise.
std::uint32_t orders
Number of orders at the level.
Quantity total
Sum of the remaining quantity of the level's orders.
Price and total resting quantity of one level.
friend bool operator==(const Level &, const Level &)=default
Same price and quantity.