#!/usr/bin/python import collections # Track queues. Simulate executing our orders partially if the order # in front of us in the queue gets executed, or fully if the order # behind us gets executed. # XXX add, modify, execution need to execute fake orders # XXX don't execute future orders (due to latency) with current real orders class Buy: pass class Sell: pass Order = collections.namedtuple('Order', 'quantity price side timestamp'.split()) class Book: def __init__(self): self.orders, self.fake_orders = {}, {} def add_order(self, order_id, order): assert order_id not in self.orders self.orders[order_id] = order def modify_order(self, order_id, new_order): if quantity == 0: del self.orders[order_id] return orig = self.orders[order_id] if new_order.quantity <= orig.quantity and new_order.price == orig.price: new_order.timestamp = orig.timestamp self.orders[order_id] = new_order def execution_event(self, (order_id, quantity_executed)): order = self.orders[order_id] order.quantity -= quantity_executed if order.quantity == 0: del self.orders[order_id] def receive_order(self, order_id, order): "Receive an order from our simulated trader." if side is Buy: sell_price = min(order.price for order in self.orders.values() if order.side is Sell) if price >= sell_price: self.emit_transaction(quantity, sell_price, side) else: self.fake_orders[order_id] = order else: buy_price = max(order.price for order in self.orders.values() if order.side is Buy) if price <= buy_price: self.emit_transaction(quantity, buy_price, side) else: self.fake_orders[order_id] = order