Skip to content

Instantly share code, notes, and snippets.

@prystupa
Last active February 25, 2018 15:29
Show Gist options
  • Save prystupa/4376018 to your computer and use it in GitHub Desktop.
Save prystupa/4376018 to your computer and use it in GitHub Desktop.
OrderBook implementation with support for Market Orders price and time priority
class OrderBook(side: Side, orderTypes: (Order => OrderType)) {
private var marketBook: List[Order] = Nil
private var limitBook: List[(Double, List[Order])] = Nil
private val priceOrdering = if (side == Sell) Ordering[Double] else Ordering[Double].reverse
def add(order: Order) {
orderTypes(order).price match {
case MarketPrice => marketBook = marketBook :+ order
case LimitPrice(limit) => addLimit(limit, order)
}
}
def top: Option[Order] = marketBook match {
case head :: _ => Some(head)
case _ => limitBook.headOption.map({
case (_, orders) => orders.head
})
}
def decreaseTopBy(qty: Double) {
marketBook match {
case top :: tail => marketBook = if (qty == top.qty) tail else orderTypes(top).decreasedBy(qty) :: tail
case _ => limitBook match {
case ((level, orders) :: tail) => {
val (top :: rest) = orders
limitBook = (qty == top.qty, rest.isEmpty) match {
case (true, true) => tail
case (true, false) => (level, rest) :: tail
case _ => (level, orderTypes(top).decreasedBy(qty) :: rest) :: tail
}
}
case Nil => throw new IllegalStateException("No top order in the empty book")
}
}
}
def orders(): List[Order] = marketBook ::: limitBook.flatMap({
case (_, orders) => orders
})
private def addLimit(limit: Double, order: Order) {
def insert(list: List[(Double, List[Order])]): List[(Double, List[Order])] = list match {
case Nil => List((limit, List(order)))
case (head@(bookLevel, orders)) :: tail => priceOrdering.compare(limit, bookLevel) match {
case 0 => (bookLevel, orders :+ order) :: tail
case n if n < 0 => (limit, List(order)) :: list
case _ => head :: insert(tail)
}
}
limitBook = insert(limitBook)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment