【30 Seconds to Understand: High-performance OrderBook Implemented in Go Language 】*
Go # Cryptocurrency # Order Book # High-frequency Trading
Core function: ** Simulate the matching engine of a centralized exchange **
package main
import (
"fmt"
"sort"
"time"
)
// Match represents a completed trade between a bid and an ask.
type Match struct {
Ask *Order // The ask order that was matched
Bid *Order // The bid order that was matched
SizeFilled float64 // Amount of the order that was filled
Price float64 // Execution price of the match
}
// Order represents a single limit order in the book.
type Order struct {
Size float64 // Order quantity
Bid bool // true = buy (bid), false = sell (ask)
Limit *Limit // Pointer to the price level this order belongs to
Timestamp int64 // Nanosecond timestamp for FIFO ordering
}
// Orders is a slice of Order pointers, used for sorting.
type Orders []*Order
// Len, Swap, Less implement sort.Interface for FIFO ordering (oldest first).
func (o Orders) Len() int { return len(o) }
func (o Orders) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
func (o Orders) Less(i, j int) bool { return o[i].Timestamp < o[j].Timestamp }
// NewOrder creates a new order with the current timestamp.
func NewOrder(bid bool, size float64) *Order {
return &Order{
Size: size,
Bid: bid,
Timestamp: time.Now().UnixNano(),
}
}
// String returns a human-readable representation of the order.
func (o *Order) String() string {
return fmt.Sprintf("[size: %0.2f]", o.Size)
}
// Limit represents a price level in the order book.
type Limit struct {
Price float64 // Price of this level
Orders Orders // FIFO queue of orders at this price
TotalVolume float64 // Sum of all order sizes at this price
}
// Limits is a slice of Limit pointers, used for sorting.
type Limits []*Limit
// ByBestAsk sorts asks from lowest price to highest (best ask first).
type ByBestAsk struct{ Limits }
func (a ByBestAsk) Len() int { return len(a.Limits) }
func (a ByBestAsk) Swap(i, j int) { a.Limits[i], a.Limits[j] = a.Limits[j], a.Limits[i] }
func (a ByBestAsk) Less(i, j int) bool { return a.Limits[i].Price < a.Limits[j].Price }
// ByBestBid sorts bids from highest price to lowest (best bid first).
type ByBestBid struct{ Limits }
func (b ByBestBid) Len() int { return len(b.Limits) }
func (b ByBestBid) Swap(i, j int) { b.Limits[i], b.Limits[j] = b.Limits[j], b.Limits[i] }
func (b ByBestBid) Less(i, j int) bool { return b.Limits[i].Price > b.Limits[j].Price }
// NewLimit creates a new empty price level.
func NewLimit(price float64) *Limit {
return &Limit{
Price: price,
Orders: []*Order{},
}
}
// String returns a human-readable representation of the limit level.
func (l *Limit) String() string {
return fmt.Sprintf("[price: %0.2f | volume: %.2f]", l.Price, l.TotalVolume)
}
// AddOrder appends an order to this price level and updates total volume.
func (l *Limit) AddOrder(o *Order) {
o.Limit = l
l.Orders = append(l.Orders, o)
l.TotalVolume += o.Size
}
// DeleteOrder removes an order from this price level and updates volume.
// The order queue is kept sorted by timestamp (FIFO).
func (l *Limit) DeleteOrder(o *Order) {
for i := 0; i < len(l.Orders); i++ {
if l.Orders[i] == o {
// Swap with last element and truncate slice
l.Orders[i] = l.Orders[len(l.Orders)-1]
l.Orders = l.Orders[:len(l.Orders)-1]
break
}
}
o.Limit = nil
l.TotalVolume -= o.Size
// Re-sort to maintain FIFO order after deletion
sort.Sort(l.Orders)
}
// OrderBook holds the full limit-order book with fast price-level lookup.
type OrderBook struct {
Asks []*Limit // All ask (sell) price levels
Bids []*Limit // All bid (buy) price levels
AskLimits map[float64]*Limit // price → ask limit (O(1) lookup)
BidLimits map[float64]*Limit // price → bid limit (O(1) lookup)
}
// NewOrderBook constructs an empty order book.
func NewOrderBook() *OrderBook {
return &OrderBook{
Asks: []*Limit{},
Bids: []*Limit{},
AskLimits: map[float64]*Limit{},
BidLimits: map[float64]*Limit{},
}
}
// PlaceOrder attempts to match the incoming order with the opposite side.
// Any remaining size is added to the book as a resting limit order.
// Returns a slice of executed matches.
func (ob *OrderBook) PlaceOrder(price float64, o *Order) []Match {
// 1. Try to match against the opposite side
// (matching logic to be implemented)
// 2. If any size remains, add it to the book
if o.Size > 0.0 {
ob.add(price, o)
}
return []Match{} // placeholder – real implementation returns matches
}
// add places a non-matched (or partially matched) order into the book.
// It either extends an existing price level or creates a new one.
func (ob *OrderBook) add(price float64, order *Order) {
var limit *Limit
if order.Bid {
limit = ob.BidLimits[price]
} else {
limit = ob.AskLimits[price]
}
if limit == nil {
limit = NewLimit(price)
limit.AddOrder(order)
if order.Bid {
ob.Bids = append(ob.Bids, limit)
ob.BidLimits[price] = limit
} else {
ob.Asks = append(ob.Asks, limit)
ob.AskLimits[price] = limit
}
} else {
// Existing price level – just add the order
limit.AddOrder(order)
}
}
Top comments (0)