-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathutils.py
183 lines (153 loc) · 6.22 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#
# Jan Gobeli
# 02.2021
# This file contains functions used to analyze tick data fetched by the Bitmex websocket.
#
import pandas as pd
from tqdm import tqdm
import matplotlib.pyplot as plt
def get_lvl_color(value, max_, min_, colmap):
"""
This function creates the colors for the orderbook plots. If the size of the the sum of orders
is big, it will be bright/visible otherwise dark to blend in with the background of the plot.
:param value: (float) the size of the orders waiting to be executed at a specific price level.
:param max_: (float) the maximum size of orders waiting to be executed at one price level.
:param lower_thres: (float) lower threshold to when the size is too small and should not be displayed.
:param upper_thres: (float) upper threshold of when the color should be as bright/visible as possible.
:return: RGB color code used for the plot.
"""
if value == None:
return (0, 0, 0)
elif value <= min_:
return (0, 0, 0)
elif value >= max_:
return colmap(1.0)
lvl = value / max_
return colmap(lvl)
"""
lvl = value / max_
jet = cm.get_cmap('jet', 12)
if lvl >= upper_thres:
return (0, 1, 1)
elif lvl >= mid_thres or lvl < upper_thres:
lvl_inside = lvl / upper_thres
return (0, lvl_inside, lvl_inside)
elif lvl > lower_thres or lvl < mid_thres:
lvl_inside = lvl / mid_thres
return (lvl_inside, lvl_inside, 0)
else:
return (0, 0, 0)
"""
def create_orderbook(tmp):
"""
Recreate the orderbook based on the initial push of the Bitmex websocket.
:param tmp: pandas dataframe containing price levels and sizes.
:return orderbook: dictionary of the orderbook.
"""
orderbook = {'bid': {},'ask': {}}
for n in range(len(tmp)):
if tmp.side[n] == 'Buy':
orderbook['bid'][float(tmp.price[n])] = int(tmp['size'][n])
else:
orderbook['ask'][float(tmp.price[n])] = int(tmp['size'][n])
return orderbook
def get_bid_ask(tmp, orderbook):
"""
Create three lists containing the best bids, asks and timestamp
over the whole dataframe (tmp).
:param tmp: dataframe of changes/orders.
:param orderbook: (dict) inital orderbook created.
:return orderbook: final orderbook after all changes.
:return best_bid: list of all best bids.
:return best_ask: list of all best asks.
:return time: list of all timestamps.
"""
best_bid = [max(orderbook['bid'])]
best_ask = [min(orderbook['ask'])]
time = [tmp.index[0]]
for n in tqdm(range(len(tmp))):
side = tmp.side[n]
price = tmp.price[n]
tmp_size = tmp['size'][n]
tmp_time = tmp.index[n]
if side == 'Buy':
if price > best_bid[-1]:
orderbook['bid'][price] = tmp_size
best_bid.append(price)
best_ask.append(best_ask[-1])
time.append(tmp_time)
elif price == best_bid[-1] and tmp_size != None:
orderbook['bid'][price] = tmp_size
best_bid.append(price)
best_ask.append(best_ask[-1])
time.append(tmp_time)
elif price == best_bid[-1] and tmp_size == None:
del orderbook['bid'][price]
best_bid.append(max(orderbook['bid']))
best_ask.append(best_ask[-1])
time.append(tmp_time)
elif tmp_size == None:
del orderbook['bid'][price]
else:
orderbook['bid'][price] = tmp_size
else:
if price < best_ask[-1]:
orderbook['ask'][price] = tmp_size
best_ask.append(price)
best_bid.append(best_bid[-1])
time.append(tmp_time)
elif price == best_ask[-1] and tmp_size != None:
orderbook['ask'][price] = tmp_size
best_ask.append(price)
best_bid.append(best_bid[-1])
time.append(tmp_time)
elif price == best_ask[-1] and tmp_size == None:
del orderbook['ask'][price]
best_ask.append(min(orderbook['ask']))
best_bid.append(best_bid[-1])
time.append(tmp_time)
elif tmp_size == None:
del orderbook['ask'][price]
else:
orderbook['ask'][price] = tmp_size
return orderbook, best_bid, best_ask, time
def create_levels(df, price_lvl, max_size, min_size, end, colmap):
"""
Create all necessary lists to plot the levels and their size in the orderbook.
:param price_lvl: (list) unique price values within the orderbook.
:param df: (dataframe) events captured by the Bitmex websocket.
:param max_size: (int) max size of orders waiting on a price level.
:param end: (datetime) last datetime object in the df.
:return y: (list) price levels.
:return x_start: (list) datetimes of when a new order is entered and tracked.
:return x_end: (list) datetimes of when the above order ends.
:return col: (list) RGB colors of what color should be allocated.
"""
y = []
x_start = []
x_end = []
col = []
for n in tqdm(range(len(price_lvl))):
plvl = price_lvl[n]
tmp = df[df.price == price_lvl[n]]
if len(tmp) > 1:
for t in range(len(tmp)):
if t == len(tmp)-1:
y.append(plvl)
x_start.append(tmp.index[t])
x_end.append(end)
col.append(get_lvl_color(tmp['size'][t], max_size, min_size, colmap))
else:
y.append(plvl)
x_start.append(tmp.index[t])
x_end.append(tmp.index[t+1])
col.append(get_lvl_color(tmp['size'][t], max_size, min_size, colmap))
else:
y.append(plvl)
x_start.append(tmp.index[0])
x_end.append(end)
col.append(get_lvl_color(tmp['size'][0], max_size, min_size, colmap))
if len(y) == len(x_start) == len(x_end) == len(col):
return y, x_start, x_end, col
else:
print('Something went wrong! Lengths do not match. Check the size of the inputs.')