From e8c910e52d1807e2fcca3b43d80a9df6acac5387 Mon Sep 17 00:00:00 2001
From: Joel Grunbaum <joelgrun@gmail.com>
Date: Wed, 12 Jan 2022 06:26:46 +0000
Subject: [PATCH] write price level to each book
---
book.py | 177 +++++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 118 insertions(+), 59 deletions(-)
diff --git a/book.py b/book.py
index a506adb..50543ef 100644
--- a/book.py
+++ b/book.py
@@ -10,8 +10,8 @@
class OrderSide(Enum):
"""Order side enum."""
- Buy = 0,
- Sell = 1
+ Buy = "BUY",
+ Sell = "SELL"
class ProductTypeEnum(Enum):
@@ -37,14 +37,18 @@
side: OrderSide
remaining_volume: int
filled_volume: int
+ timestamp: float
+ id: str
def __init__(self, price: decimal.Decimal(3), side: OrderSide,
- volume: int):
+ volume: int, timestamp: float, id: str):
"""Initialise class."""
self.price = price
self.side = side
self.remaining_volume = volume
self.filled_volume = 0
+ self.timestamp = timestamp
+ self.id = id
class Level:
@@ -52,44 +56,97 @@
price: decimal.Decimal
volume: int
+ side: OrderSide
+ timestamp: float
+ id: str
- def __init__(self, price: decimal.Decimal(3), volume):
+ def __init__(self, order: Order):
"""Initialise class."""
- self.priority = int(price)
- self.price = price
- self.volume = volume
+ self.price = order.price
+ self.volume = order.remaining_volume
+ self.side = order.side
+ self.timestamp = order.timestamp
+ self.id = order.id
def __lt__(self, other):
"""Less than comparator."""
- if (self.price < other.price):
- return True
+ if (self.side == OrderSide.Sell):
+ if (self.price < other.price):
+ return True
+ elif (self.price == other.price and
+ self.timestamp < other.timestamp):
+ return True
+ else:
+ return False
else:
- return False
+ if (self.price > other.price):
+ return True
+ elif (self.price == other.price and
+ self.timestamp < other.timestamp):
+ return True
+ else:
+ return False
def __gt__(self, other):
"""Greater than comparator."""
- if (self.price > other.price):
- return True
+ if (self.side == OrderSide.Sell):
+ if (self.price > other.price):
+ return True
+ elif (self.price == other.price and
+ self.timestamp < other.timestamp):
+ return True
+ else:
+ return False
else:
- return False
+ if (self.price < other.price):
+ return True
+ elif (self.price == other.price and
+ self.timestamp < other.timestamp):
+ return True
+ else:
+ return False
def __le__(self, other):
"""Less than or equal compatator."""
- if (self.price <= other.price):
- return True
+ if (self.side == OrderSide.Sell):
+ if (self.price <= other.price):
+ return True
+ elif (self.price == other.price and
+ self.timestamp <= other.timestamp):
+ return True
+ else:
+ return False
else:
- return False
+ if (self.price >= other.price):
+ return True
+ elif (self.price == other.price and
+ self.timestamp <= other.timestamp):
+ return True
+ else:
+ return False
def __ge__(self, other):
"""Greater than or equal comparator."""
- if (self.price >= other.price):
- return True
+ if (self.side == OrderSide.Sell):
+ if (self.price >= other.price):
+ return True
+ elif (self.price == other.price and
+ self.timestamp <= other.timestamp):
+ return True
+ else:
+ return False
else:
- return False
+ if (self.price <= other.price):
+ return True
+ elif (self.price == other.price and
+ self.timestamp <= other.timestamp):
+ return True
+ else:
+ return False
def __eq__(self, other):
"""Equalty compatator."""
- if (self.price == other.price):
+ if (self.price == other.price and self.timestamp == other.timestamp):
return True
else:
return False
@@ -100,7 +157,8 @@
def __str__(self):
"""Turn into str for printing."""
- return "Price: " + str(self.price) + ", volume: " + str(self.volume)
+ return ("Price: " + str(self.price) + ", volume: " + str(self.volume) +
+ ", time: " + str(self.timestamp) + ", id: " + self.id)
class Side:
@@ -112,6 +170,13 @@
"""Initialise class."""
self.levels = []
+ def delete(self, orderId: str):
+ """Delete order from side."""
+ for i in self.levels:
+ if (i.id == orderId):
+ self.levels.remove(i)
+ heapq.heapify(self.levels)
+
class Book:
"""Book class."""
@@ -166,64 +231,58 @@
def ask(self, order: Order):
"""Add ask to book."""
while(len(self.bidSide.levels) > 0 and
- self.bidSide.levels[0][1].price >= order.price):
- if (self.bidSide.levels[0][1].volume > order.remaining_volume):
- temp = self.bidSide.levels[0][1].volume
- order.filled_volume += self.bidSide.levels[0][1].volume
- self.bidSide.levels[0][1].volume -= order.remaining_volume
+ self.bidSide.levels[0].price >= order.price):
+ if (self.bidSide.levels[0].volume > order.remaining_volume):
+ temp = self.bidSide.levels[0].volume
+ order.filled_volume += self.bidSide.levels[0].volume
+ self.bidSide.levels[0].volume -= order.remaining_volume
order.remaining_volume -= temp
break
else:
- order.remaining_volume -= self.bidSide.levels[0][1].volume
- order.filled_volume += self.bidSide.levels[0][1].volume
+ order.remaining_volume -= self.bidSide.levels[0].volume
+ order.filled_volume += self.bidSide.levels[0].volume
heapq.heappop(self.bidSide.levels)
if (order.remaining_volume > 0):
- if (len(self.askSide.levels) > 0 and
- self.askSide.levels[0][1].price == order.price):
- self.askSide.levels[0][1].addVolume(order.remaining_volume)
- else:
- heapq.heappush(self.askSide.levels,
- (order.price,
- Level(order.price, order.remaining_volume)))
+ heapq.heappush(self.askSide.levels, Level(order))
def bid(self, order: Order):
"""Add bid to book."""
while(len(self.askSide.levels) > 0 and
- self.askSide.levels[0][1].price <= order.price):
- if (self.askSide.levels[0][1].volume > order.remaining_volume):
- temp = self.askSide.levels[0][1].volume
- order.filled_volume += self.askSide.levels[0][1].volume
- self.askSide.levels[0][1].volume -= order.remaining_volume
+ self.askSide.levels[0].price <= order.price):
+ if (self.askSide.levels[0].volume > order.remaining_volume):
+ temp = self.askSide.levels[0].volume
+ order.filled_volume += self.askSide.levels[0].volume
+ self.askSide.levels[0].volume -= order.remaining_volume
order.remaining_volume -= temp
break
else:
- order.remaining_volume -= self.askSide.levels[0][1].volume
- order.filled_volume -= self.askSide.levels[0][1].volume
+ order.remaining_volume -= self.askSide.levels[0].volume
+ order.filled_volume -= self.askSide.levels[0].volume
heapq.heappop(self.askSide.levels)
if (order.remaining_volume > 0):
- if (len(self.bidSide.levels) > 0 and
- self.bidSide.levels[0][1].price == order.price):
- self.bidSide.levels[0][1].addVolume(order.remaining_volume)
- else:
- heapq.heappush(self.bidSide.levels,
- (100 - order.price,
- Level(order.price, order.remaining_volume)))
+ heapq.heappush(self.bidSide.levels, Level(order))
def printBook(self):
"""Test print book. Book is a heap so not strictly sorted."""
print("Sell side")
- for i in sorted(self.askSide.levels, reverse=True):
- print(i[1])
+ for i in sorted(self.askSide.levels, reverse=True)[-10:]:
+ print(i)
print("Buy side")
- for i in sorted(self.bidSide.levels):
- print(str(i[1]))
+ for i in sorted(self.bidSide.levels)[:10]:
+ print(str(i))
-def testBook():
+def testBook(orders: int = 10, printBook=True):
"""Test an example book."""
b = Book()
- for i in range(1, 10):
- b.addOrder(Order(i, OrderSide.Buy, 10))
- for i in range(11, 20):
- b.addOrder(Order(i, OrderSide.Sell, 10))
- b.printBook()
+ time = 1
+ for i in range(1, orders):
+ b.addOrder(Order(price=i, side=OrderSide.Buy, volume=10,
+ timestamp=time, id="a"))
+ time += 1
+ for i in range(orders + 1, 2 * orders):
+ b.addOrder(Order(i, OrderSide.Sell, 10, time, "a"))
+ time += 1
+ if (printBook):
+ b.printBook()
+ return b
--
Gitblit v1.10.0