|
1 | 1 | #!/usr/bin/python
|
2 | 2 |
|
3 |
| -import sys |
4 | 3 | from collections import deque
|
5 |
| -from bintrees import FastRBTree |
6 |
| -from order import Order |
7 |
| -from orderList import OrderList |
| 4 | + |
8 | 5 | from tick import Bid, Ask, Trade
|
9 | 6 | from tree import Tree
|
10 | 7 |
|
| 8 | + |
| 9 | +def parseCsv(columns, line): |
| 10 | + """ |
| 11 | + Parse a CSV line that has ',' as a separator. |
| 12 | + Columns is a list of the column names, must match the number of |
| 13 | + comma-separated values in the input line. |
| 14 | + """ |
| 15 | + data = {} |
| 16 | + split = line.split(',') |
| 17 | + for idx, name in enumerate(columns): |
| 18 | + data[name] = split[idx] |
| 19 | + return data |
| 20 | + |
| 21 | + |
11 | 22 | class Book(object):
|
12 |
| - def __init__(self): |
13 |
| - self.trades = deque(maxlen=100) # Index [0] is most recent trade |
14 |
| - self.bids = Tree() |
15 |
| - self.asks = Tree() |
16 |
| - self.lastTick = None |
17 |
| - self.lastTimestamp = 0 |
18 |
| - def parseCsv(self, columns, line): |
19 |
| - ''' |
20 |
| - Parse a CSV line that has ',' as a separator. |
21 |
| - Columns is a list of the column names, must match the number of |
22 |
| - comma-separated values in the input line. |
23 |
| - ''' |
24 |
| - data = {} |
25 |
| - split = line.split(',') |
26 |
| - for idx,name in enumerate(columns): |
27 |
| - data[name] = split[idx] |
28 |
| - return data |
29 |
| - def processBidAsk(self,tick): |
30 |
| - ''' |
31 |
| - Generic method to process bid or ask. |
32 |
| - ''' |
33 |
| - tree = self.asks |
34 |
| - if tick.isBid: |
35 |
| - tree = self.bids |
36 |
| - if tick.qty == 0: |
37 |
| - # Quantity is zero -> remove the entry |
38 |
| - tree.removeOrderById(tick.idNum) |
39 |
| - else: |
40 |
| - if tree.orderExists(tick.idNum): |
41 |
| - tree.updateOrder(tick) |
42 |
| - else: |
43 |
| - # New order |
44 |
| - tree.insertTick(tick) |
45 |
| - def bid(self,tick): |
46 |
| - columns = ['event','symbol','exchange','idNum','qty','price','timestamp'] |
47 |
| - data = self.parseCsv(columns,tick) |
48 |
| - bid = Bid(data) |
49 |
| - if bid.timestamp > self.lastTimestamp: |
50 |
| - self.lastTimestamp = bid.timestamp |
51 |
| - self.lastTick = bid |
52 |
| - self.processBidAsk(bid) |
53 |
| - def ask(self,tick): |
54 |
| - columns = ['event','symbol','exchange','idNum','qty','price','timestamp'] |
55 |
| - data = self.parseCsv(columns,tick) |
56 |
| - ask = Ask(data) |
57 |
| - if ask.timestamp > self.lastTimestamp: |
58 |
| - self.lastTimestamp = ask.timestamp |
59 |
| - self.lastTick = ask |
60 |
| - self.processBidAsk(ask) |
61 |
| - def trade(self,tick): |
62 |
| - columns = ['event','symbol','exchange','qty','price','timestamp'] |
63 |
| - data = self.parseCsv(columns,tick) |
64 |
| - data['idNum'] = 0 |
65 |
| - trade = Trade(data) |
66 |
| - if trade.timestamp > self.lastTimestamp: |
67 |
| - self.lastTimestamp = trade.timestamp |
68 |
| - self.lastTick = trade |
69 |
| - self.trades.appendleft(trade) |
70 |
| - def __str__(self): |
71 |
| - # Efficient string concat |
72 |
| - from cStringIO import StringIO |
73 |
| - file_str = StringIO() |
74 |
| - file_str.write("------ Bids -------\n") |
75 |
| - if self.bids != None and len(self.bids) > 0: |
76 |
| - for k,v in self.bids.priceTree.items(reverse=True): |
77 |
| - file_str.write('%s' % v) |
78 |
| - file_str.write("\n------ Asks -------\n") |
79 |
| - if self.asks != None and len(self.asks) > 0: |
80 |
| - for k,v in self.asks.priceTree.items(): |
81 |
| - file_str.write('%s' % v) |
82 |
| - file_str.write("\n------ Trades ------\n") |
83 |
| - if self.trades != None and len(self.trades) > 0: |
84 |
| - num = 0 |
85 |
| - for entry in self.trades: |
86 |
| - if num < 5: |
87 |
| - file_str.write(str(entry.qty) + " @ " \ |
88 |
| - + str(entry.price / 10000) \ |
89 |
| - + " (" + str(entry.timestamp) + ")\n") |
90 |
| - num += 1 |
91 |
| - else: |
92 |
| - break |
93 |
| - file_str.write("\n") |
94 |
| - return file_str.getvalue() |
| 23 | + def __init__(self): |
| 24 | + self.trades = deque(maxlen=100) # Index [0] is most recent trade |
| 25 | + self.bids = Tree() |
| 26 | + self.asks = Tree() |
| 27 | + self.lastTick = None |
| 28 | + self.lastTimestamp = 0 |
| 29 | + |
| 30 | + def processBidAsk(self, tick): |
| 31 | + """ |
| 32 | + Generic method to process bid or ask. |
| 33 | + """ |
| 34 | + tree = self.asks |
| 35 | + if tick.isBid: |
| 36 | + tree = self.bids |
| 37 | + if tick.qty == 0: |
| 38 | + # Quantity is zero -> remove the entry |
| 39 | + tree.removeOrderById(tick.idNum) |
| 40 | + else: |
| 41 | + if tree.orderExists(tick.idNum): |
| 42 | + tree.updateOrder(tick) |
| 43 | + else: |
| 44 | + # New order |
| 45 | + tree.insertTick(tick) |
| 46 | + |
| 47 | + def bid(self, tick): |
| 48 | + columns = ['event', 'symbol', 'exchange', 'idNum', 'qty', 'price', 'timestamp'] |
| 49 | + data = parseCsv(columns, tick) |
| 50 | + bid = Bid(data) |
| 51 | + if bid.timestamp > self.lastTimestamp: |
| 52 | + self.lastTimestamp = bid.timestamp |
| 53 | + self.lastTick = bid |
| 54 | + self.processBidAsk(bid) |
| 55 | + |
| 56 | + def ask(self, tick): |
| 57 | + columns = ['event', 'symbol', 'exchange', 'idNum', 'qty', 'price', 'timestamp'] |
| 58 | + data = parseCsv(columns, tick) |
| 59 | + ask = Ask(data) |
| 60 | + if ask.timestamp > self.lastTimestamp: |
| 61 | + self.lastTimestamp = ask.timestamp |
| 62 | + self.lastTick = ask |
| 63 | + self.processBidAsk(ask) |
| 64 | + |
| 65 | + def trade(self, tick): |
| 66 | + columns = ['event', 'symbol', 'exchange', 'qty', 'price', 'timestamp'] |
| 67 | + data = parseCsv(columns, tick) |
| 68 | + data['idNum'] = 0 |
| 69 | + trade = Trade(data) |
| 70 | + if trade.timestamp > self.lastTimestamp: |
| 71 | + self.lastTimestamp = trade.timestamp |
| 72 | + self.lastTick = trade |
| 73 | + self.trades.appendleft(trade) |
| 74 | + |
| 75 | + def __str__(self): |
| 76 | + # Efficient string concat |
| 77 | + from cStringIO import StringIO |
| 78 | + |
| 79 | + file_str = StringIO() |
| 80 | + file_str.write("------ Bids -------\n") |
| 81 | + if self.bids != None and len(self.bids) > 0: |
| 82 | + for k, v in self.bids.priceTree.items(reverse=True): |
| 83 | + file_str.write('%s' % v) |
| 84 | + file_str.write("\n------ Asks -------\n") |
| 85 | + if self.asks != None and len(self.asks) > 0: |
| 86 | + for k, v in self.asks.priceTree.items(): |
| 87 | + file_str.write('%s' % v) |
| 88 | + file_str.write("\n------ Trades ------\n") |
| 89 | + if self.trades != None and len(self.trades) > 0: |
| 90 | + num = 0 |
| 91 | + for entry in self.trades: |
| 92 | + if num < 5: |
| 93 | + file_str.write(str(entry.qty) + " @ " \ |
| 94 | + + str(entry.price / 10000) \ |
| 95 | + + " (" + str(entry.timestamp) + ")\n") |
| 96 | + num += 1 |
| 97 | + else: |
| 98 | + break |
| 99 | + file_str.write("\n") |
| 100 | + return file_str.getvalue() |
0 commit comments