Skip to content

Commit f7963ad

Browse files
author
Caleb Quilley
committed
Add tests/test_market.py
1 parent e8f6317 commit f7963ad

File tree

2 files changed

+84
-13
lines changed

2 files changed

+84
-13
lines changed

cogs/commands/market.py

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616

1717
class Order:
18-
def __init__(self, price, order_type, user_id, qty, order_time=time.time()):
18+
def __init__(self, price, order_type, user_id, qty, order_time):
1919
self.user_id = user_id
2020
self.price = price
2121
self.order_type = order_type
@@ -52,22 +52,17 @@ def __init__(self, stock_name):
5252
self.last_trade = None
5353
self.open = True
5454

55-
def bid(self, price, user_id, qty):
56-
self.bids.append(Order(price, 'bid', user_id, qty))
57-
heapq.heapify(self.bids)
55+
def bid(self, price, user_id, qty, time=time.time()):
56+
heapq.heappush(self.bids, Order(price, 'bid', user_id, qty, time))
5857
return self.match()
5958

60-
def ask(self, price, user_id, qty):
61-
self.asks.append(Order(price, 'ask', user_id, qty))
62-
heapq.heapify(self.asks)
59+
def ask(self, price, user_id, qty, time=time.time()):
60+
heapq.heappush(self.asks, Order(price, 'ask', user_id, qty, time))
6361
return self.match()
6462

6563
def match(self):
66-
if len(self.bids) == 0 or len(self.asks) == 0:
67-
return None
68-
6964
matched = []
70-
while self.bids[0].price >= self.asks[0].price:
65+
while len(self.bids) > 0 and len(self.asks) > 0 and self.bids[0].price >= self.asks[0].price:
7166
bid = heapq.heappop(self.bids)
7267
ask = heapq.heappop(self.asks)
7368
qty = min(bid.qty, ask.qty)
@@ -83,8 +78,8 @@ def match(self):
8378
bid.price = earliest_trade.price
8479
ask.price = earliest_trade.price
8580

86-
bought = Order(earliest_trade.price, 'bid', bid.price, qty)
87-
sold = Order(earliest_trade.price, 'ask', ask.user_id, qty)
81+
bought = Order(earliest_trade.price, 'bid', bid.price, qty, bid.order_time)
82+
sold = Order(earliest_trade.price, 'ask', ask.user_id, qty, ask.order_time)
8883

8984
self.trade_history[bid.user_id].append(bought)
9085
self.trade_history[ask.user_id].append(sold)

tests/test_market.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
from cogs.commands.market import Market
2+
3+
4+
def test_can_place_orders():
5+
m = Market("TEST")
6+
assert m.ask(102, 1, 1, 1) is None
7+
assert m.bid(101, 2, 3, 2) is None
8+
assert m.ask(102, 3, 4, 3) is None
9+
assert len(m.asks) == 2
10+
assert len(m.bids) == 1
11+
12+
assert str(m) == """Market is: OPEN
13+
📊 **TEST Order Book** 📊
14+
Bid Orders | Bid Volume | Price | Ask Volume | Ask Orders
15+
| | 102 | 7 | 2
16+
1 | 3 | 101 | |
17+
"""
18+
19+
def test_single_match():
20+
m = Market("test")
21+
assert m.ask(101, 1, 1) is None
22+
assert (matched := m.bid(101, 2, 1)) is not None
23+
assert matched == "<@2> bought 1 from <@1> at 101"
24+
assert len(m.asks) == 0
25+
assert len(m.bids) == 0
26+
27+
def test_partial_match():
28+
m = Market("test")
29+
assert m.ask(102, 1, 100, 1) is None
30+
assert (o := m.bid(102, 2, 50, 2)) is not None
31+
assert o == "<@2> bought 50 from <@1> at 102"
32+
assert len(m.bids) == 0
33+
assert len(m.asks) == 1
34+
assert m.asks[0].qty == 50
35+
assert m.asks[0].order_time == 1
36+
37+
def test_multi_match():
38+
m = Market("test")
39+
assert m.ask(102, 1, 1, 1) is None
40+
assert m.ask(102, 2, 1, 2) is None
41+
assert m.ask(102, 3, 1, 4) is None
42+
assert m.bid(102, 4, 2, 5) == """<@4> bought 1 from <@1> at 102
43+
<@4> bought 1 from <@2> at 102"""
44+
assert len(m.bids) == 0
45+
assert len(m.asks) == 1
46+
assert m.asks[0].user_id == 3
47+
assert len(m.trade_history[1]) == 1
48+
assert len(m.trade_history[2]) == 1
49+
assert len(m.trade_history[4]) == 2
50+
51+
def test_turning():
52+
m = Market("test")
53+
assert m.ask(102, 1, 1, 1) is None
54+
assert m.bid(102, 2, 100, 2) == """<@2> bought 1 from <@1> at 102"""
55+
assert len(m.asks) == 0
56+
assert len(m.bids) == 1
57+
assert m.bids[0].qty == 99
58+
assert m.bids[0].order_time == 2
59+
60+
def test_multi_level_clear():
61+
m = Market("test")
62+
assert m.ask(100, 1, 1, 1) is None
63+
assert m.ask(101, 1, 1, 2) is None
64+
assert m.ask(102, 1, 1, 3) is None
65+
assert m.ask(103, 1, 100, 4) is None
66+
assert m.bid(103, 2, 10, 4) == """<@2> bought 1 from <@1> at 100
67+
<@2> bought 1 from <@1> at 101
68+
<@2> bought 1 from <@1> at 102
69+
<@2> bought 7 from <@1> at 103
70+
"""
71+
assert len(m.bids) == 0
72+
assert len(m.asks) == 1
73+
assert m.asks[0].qty == 93
74+
assert m.asks[0].price == 103
75+
assert len(m.trade_history[1]) == 4
76+
assert len(m.trade_history[2]) == 4

0 commit comments

Comments
 (0)