Functional Scope (In-Scope)
- Sorted Bid/Ask Order Books: Manage isolated order books per ticker symbol using double sorted priority queues (Price-time priority matching).
- Price-Time Execution Engine: Match orders deterministically when Bid limit price >= Ask limit price.
- Command Transactions (Command Pattern): Encapsulate order actions (PLACE, CANCEL, MODIFY) systematically for unified auditing and transaction history.
- Observer Notifications: Enable observers to listen to matched trade executions and notify users dynamically.
Explicit Boundaries (Out-of-Scope)
- No Real Exchange Connectivity (FIX Protocol): Bypasses direct network socket links to NASDAQ, NYSE, or external clearing firms.
- No Advanced Margin Lending Algorithms: Bypasses complex margin interest rates or automatic collateral liquidation sweeps.
Clean reference designs demonstrating order-matching engines in Java and Python:
// ─── JAVA BLUEPRINT ──────────────────────────────────────────────────────────
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
enum OrderType { MARKET, LIMIT }
enum OrderSide { BUY, SELL }
class Order {
private final String id;
private final String userId;
private final String symbol;
private final OrderType type;
private final OrderSide side;
private int quantity;
private final double limitPrice;
private final long timestamp;
public Order(String id, String userId, String symbol, OrderType type, OrderSide side, int quantity, double limitPrice) {
this.id = id;
this.userId = userId;
this.symbol = symbol;
this.type = type;
this.side = side;
this.quantity = quantity;
this.limitPrice = limitPrice;
this.timestamp = System.nanoTime();
}
public String getId() { return id; }
public String getUserId() { return userId; }
public String getSymbol() { return symbol; }
public OrderType getType() { return type; }
public OrderSide getSide() { return side; }
public int getQuantity() { return quantity; }
public double getLimitPrice() { return limitPrice; }
public long getTimestamp() { return timestamp; }
public void deductQuantity(int qty) { this.quantity -= qty; }
public boolean isFilled() { return quantity == 0; }
}
interface TradeObserver {
void onTradeExecuted(Order buyOrder, Order sellOrder, int quantity, double price);
}
class TransactionLogger implements TradeObserver {
@Override
public void onTradeExecuted(Order buyOrder, Order sellOrder, int quantity, double price) {
System.out.println(String.format("[Trade Executed] %d shares of %s matched between User %s and User %s at $%.2f",
quantity, buyOrder.getSymbol(), buyOrder.getUserId(), sellOrder.getUserId(), price));
}
}
// ─── COMMAND PATTERN (TRADING TRANSACTION) ──────────────────────────────────
interface OrderCommand {
boolean execute();
void undo();
}
class PlaceOrderCommand implements OrderCommand {
private final BrokerageSystem system;
private final Order order;
public PlaceOrderCommand(BrokerageSystem system, Order order) {
this.system = system;
this.order = order;
}
@Override
public boolean execute() {
system.placeOrder(order);
return true;
}
@Override
public void undo() {
system.cancelOrder(order.getSymbol(), order.getId());
}
}
class OrderBook {
private final String symbol;
// Bids sorted descending by limit price. For matching timestamps, earlier order has priority.
private final PriorityQueue<Order> bids = new PriorityQueue<>((o1, o2) -> {
int priceCompare = Double.compare(o2.getLimitPrice(), o1.getLimitPrice());
if (priceCompare != 0) return priceCompare;
return Long.compare(o1.getTimestamp(), o2.getTimestamp());
});
// Asks sorted ascending by limit price. For matching timestamps, earlier order has priority.
private final PriorityQueue<Order> asks = new PriorityQueue<>((o1, o2) -> {
int priceCompare = Double.compare(o1.getLimitPrice(), o2.getLimitPrice());
if (priceCompare != 0) return priceCompare;
return Long.compare(o1.getTimestamp(), o2.getTimestamp());
});
private final ReentrantLock bookLock = new ReentrantLock();
private final List<TradeObserver> observers = new CopyOnWriteArrayList<>();
public OrderBook(String symbol) {
this.symbol = symbol;
}
public void addObserver(TradeObserver obs) { observers.add(obs); }
public void addOrder(Order order) {
bookLock.lock();
try {
if (order.getSide() == OrderSide.BUY) {
bids.add(order);
} else {
asks.add(order);
}
matchOrders();
} finally {
bookLock.unlock();
}
}
public void cancelOrder(String orderId) {
bookLock.lock();
try {
bids.removeIf(o -> o.getId().equals(orderId));
asks.removeIf(o -> o.getId().equals(orderId));
} finally {
bookLock.unlock();
}
}
private void matchOrders() {
while (!bids.isEmpty() && !asks.isEmpty()) {
Order bid = bids.peek();
Order ask = asks.peek();
// Match limit overlapping pricing
if (bid.getLimitPrice() >= ask.getLimitPrice()) {
int matchQty = Math.min(bid.getQuantity(), ask.getQuantity());
double executionPrice = ask.getLimitPrice(); // Price of standing order
bid.deductQuantity(matchQty);
ask.deductQuantity(matchQty);
for (TradeObserver obs : observers) {
obs.onTradeExecuted(bid, ask, matchQty, executionPrice);
}
if (bid.isFilled()) bids.poll();
if (ask.isFilled()) asks.poll();
} else {
break;
}
}
}
}
class BrokerageSystem {
private final Map<String, OrderBook> orderBooks = new ConcurrentHashMap<>();
private final TransactionLogger logger = new TransactionLogger();
public void placeOrder(Order order) {
OrderBook book = orderBooks.computeIfAbsent(order.getSymbol(), k -> {
OrderBook newBook = new OrderBook(k);
newBook.addObserver(logger);
return newBook;
});
book.addOrder(order);
}
public void cancelOrder(String symbol, String orderId) {
OrderBook book = orderBooks.get(symbol);
if (book != null) {
book.cancelOrder(orderId);
System.out.println("[Service] Order Canceled: " + orderId);
}
}
}
public class Main {
public static void main(String[] args) {
System.out.println("=== Stock Brokerage Matching Engine ===");
BrokerageSystem system = new BrokerageSystem();
// Placing matching limit orders
System.out.println("\n--- Client places Limit Bid ---");
Order buyOrder = new Order("ORD-1", "User-A", "AAPL", OrderType.LIMIT, OrderSide.BUY, 50, 150.00);
OrderCommand cmd1 = new PlaceOrderCommand(system, buyOrder);
cmd1.execute();
System.out.println("\n--- Client places overlapping Limit Ask (Causes Match) ---");
Order sellOrder = new Order("ORD-2", "User-B", "AAPL", OrderType.LIMIT, OrderSide.SELL, 30, 149.50);
OrderCommand cmd2 = new PlaceOrderCommand(system, sellOrder);
cmd2.execute();
}
}