classdef OrderBook < handle
properties (SetAccess = private, Hidden)
Heaps % collections of same-type, same-side orders
end
methods (Static)
function[i,j] = index(order)
type = [order.Type ' ' order.Side];
switch type
case 'MKT BUY', i = 1;
case 'MKT SELL', i = 2;
case 'LIM BUY', i = 3;
case 'LIM SELL', i = 4;
end
j = 5-i; % index of contra-side heap (assuming MKT-against-LIM-only crosses)
end
end
methods
function[obj] = OrderBook()
obj.Heaps = [OrderHeap('BUY','MKT') ...
OrderHeap('SELL','MKT') ...
OrderHeap('BUY','LIM') ...
OrderHeap('SELL','LIM')];
end
function put(obj,order)
if Settings.Verbose
disp('--- Order book before order is entered ---')
for i = 1:4
disp(obj.Heaps(i))
end
disp('------------------------------------------')
end
if Settings.Verbose
fprintf('%s passed into crossing engine\n', char(order))
end
[i,j] = OrderBook.index(order);
thisSide = obj.Heaps(i);
othrSide = obj.Heaps(j);
w1 = OrderWrapper(order);
obj.Heaps(i).put(w1);
while w1.SizeLeft > 0
w2 = othrSide.peek();
if ~isempty(w2)
if Settings.Verbose
disp('Best contra order:')
shortdisp(w2)
end
size = min(w1.SizeLeft,w2.SizeLeft);
price = thisSide.TradePrice(w1,w2);
treco = TradeRecord(w1.Order,w2.Order,size,price);
w1.update(treco)
w2.update(treco)
notify(obj,'TradeRecord',treco)
if w2.SizeLeft == 0
othrSide.get;
end
else
if Settings.Verbose
disp('Best contra order: <none>')
end
break
end
end
if w1.SizeLeft == 0
thisSide.get;
end
if Settings.Verbose
disp('--- Order book after order is entered and crossed ---')
for i = 1:4
disp(obj.Heaps(i))
end
disp('-----------------------------------------------------')
end
end
end
events
TradeRecord % listened to by exchange
end
end