Skip to content

Instantly share code, notes, and snippets.

@jweinst1
Created January 3, 2026 05:01
Show Gist options
  • Select an option

  • Save jweinst1/28a9810c7de2c3033d54b84e54f3f464 to your computer and use it in GitHub Desktop.

Select an option

Save jweinst1/28a9810c7de2c3033d54b84e54f3f464 to your computer and use it in GitHub Desktop.
minimal LOB simulate
#include <iostream>
#include <map>
#include <deque>
#include <algorithm>
enum class Side { Buy, Sell };
struct Order {
Side side;
double price; // ignored for market orders
int size;
};
using OrderQueue = std::deque<Order>;
// Buy: highest price first
std::map<double, OrderQueue, std::greater<double>> bids;
// Sell: lowest price first
std::map<double, OrderQueue> asks;
double last_price = 100.0;
void match() {
while (!bids.empty() && !asks.empty()) {
auto& bid_level = bids.begin()->second;
auto& ask_level = asks.begin()->second;
double bid_price = bids.begin()->first;
double ask_price = asks.begin()->first;
if (bid_price < ask_price)
break;
Order& bid = bid_level.front();
Order& ask = ask_level.front();
int traded = std::min(bid.size, ask.size);
last_price = ask_price; // price-time priority
bid.size -= traded;
ask.size -= traded;
std::cout << "Trade: " << traded
<< " @ " << last_price << "\n";
if (bid.size == 0) bid_level.pop_front();
if (ask.size == 0) ask_level.pop_front();
if (bid_level.empty()) bids.erase(bids.begin());
if (ask_level.empty()) asks.erase(asks.begin());
}
}
void add_order(Order o) {
if (o.side == Side::Buy)
bids[o.price].push_back(o);
else
asks[o.price].push_back(o);
match();
}
int main() {
add_order({Side::Sell, 101.0, 10});
add_order({Side::Sell, 102.0, 10});
add_order({Side::Buy, 100.0, 5});
add_order({Side::Buy, 101.0, 8});
std::cout << "Last price: " << last_price << "\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment