Repository navigation
Expand file tree
/
Copy pathaa_core.py
More file actions
331 lines (282 loc) · 12.3 KB
/
Copy pathaa_core.py
File metadata and controls
331 lines (282 loc) · 12.3 KB
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
from __future__ import division
import BSE
import copy
import math
import random
#guesswork comment!
ALPHA_MIN = 0.02;
ALPHA_MAX = 0.16;
THETA_MIN = -8;
THETA_MAX = 2;
class RoundRobinBuffer:
def __init__(self, window_size):
self.buffer = []
self.window_size = window_size
def append(self, hash):
c = copy.copy(hash)
if not c.has_key("age"):
c["age"] = 0
print "buffer append"
self.buffer.append(c)
def age_buffer(self):
removal = []
for hash in self.buffer:
hash["age"] += 1
if hash["age"] > self.window_size:
removal.append(hash)
for hash in removal:
self.buffer.remove(hash)
def __getitem__(self, index):
return self.buffer[index]
def __len__(self):
return len(self.buffer)
def __iter__(self):
return self.buffer.__iter__()
class AACommon:
def __init__(self):
#-1 is most aggressive
# 1 is least aggressive
self.doa = 0
self.learning_rate_beta1 = 0.5
self.learning_rate_beta2 = 0.5
self.orders = []
self.theta = 0
self.last_transaction_price = None
self.tau = 1
self.equilibrium_price = 500
self.lambda_val = 0.05
#this is a magical ass pull by sam
self.N = 10
#these are magical ass pulls by vytelingum
self.weight_decay = 0.9
self.nyan = 3
#this is a magical ass pull by luke
self.squiggle = 2
self.previous_trades = RoundRobinBuffer(self.N)
# DEBUG
self.strval = ""
def interesting_trades(self):
return self.previous_trades
def limit_price(self):
return self.orders[0].price
def long_term_learning(self):
interesting_trades = [x["price"] for x in self.interesting_trades()]
#if len(interesting_trades) >= self.N:
print "aa ltl eqp", self.equilibrium_price
print "aa ltl interesting_trades", interesting_trades
alpha = (sum([(x-self.equilibrium_price)**2 for x in interesting_trades])/self.N)**0.5/self.equilibrium_price
if alpha > ALPHA_MAX:
alpha = ALPHA_MAX
if alpha < ALPHA_MIN:
alpha = ALPHA_MIN
alpha_delta = ALPHA_MAX - ALPHA_MIN
theta_delta = THETA_MAX - THETA_MIN
ts = THETA_MIN + theta_delta * ((1-math.exp(self.squiggle * ((alpha - ALPHA_MIN/alpha_delta) - 1))) / 1-math.exp(-self.squiggle))
print "aa ltl old theta", self.theta
self.theta = self.theta + self.learning_rate_beta2*(ts-self.theta)
print "aa ltl new theta", self.theta
def adaptive_component(self, trade, best_price):
self.lambda_val = self.lambda_value(best_price, trade)
self.adaptive_component2()
def adaptive_component2(self):
self.short_term_learning(self.lambda_val)
self.long_term_learning()
def short_term_learning(self, lambda_value):
#we guessed self.previous_doa in this term but fuck it we're probably right
#because luke and I are genii
delta_t = ((1 + lambda_value) * self.doa) + lambda_value/2
new_doa = self.doa + (self.learning_rate_beta1 * (delta_t - self.doa))
print "aa od", self.doa
self.doa = new_doa
print "aa lbd", lambda_value
print "aa dt", delta_t
print "aa nd", new_doa
# Screw this, capping it.
if self.doa > 1:
self.doa = 1
elif self.doa < -1:
self.doa = -1
assert self.doa >= -1 and self.doa <= 1
def decay_old_trades(self):
for trade in self.previous_trades:
trade["weight"] *= self.weight_decay
def receive_trade(self, trade):
self.decay_old_trades()
trade = trade.copy()
trade["weight"] = 1
self.previous_trades.append(trade)
self.previous_trades.age_buffer()
def equilibrium_estimator(self):
print "aa eq estimator called"
interesting_trades = [x for x in self.previous_trades]
print "aa eq",interesting_trades
n = sum(x["weight"] for x in interesting_trades)
sx = sum(x["price"]*x["weight"] for x in interesting_trades)
mean = sx/n
#print "aa eq", mean
print "aa eq", self.equilibrium_price
self.equilibrium_price = mean
class AABuyer(AACommon):
def __init__(self):
AACommon.__init__(self)
def extramarginal(self):
return self.limit_price() < self.equilibrium_price
def aggressiveness_model(self):
if len(self.orders) > 0:
if self.extramarginal():
r = self.limit_price()
if self.doa >= -1 and self.doa <= 0:
r *= (1+self.doa*math.exp(self.theta*(self.doa-1)))
self.tau = r
self.tau = max(1, self.tau)
self.tau = min(self.limit_price(), self.tau)
assert self.tau >= 1 and self.tau <= self.limit_price()
self.strval = "aab ame tau = " + str(self.tau) + " lp = " + str(self.limit_price())
print "aab ame tau", self.tau
else:
#if doa > 1:
# doa = 1
#elif doa < -1:
# doa = -1
assert self.doa >= -1 and self.doa <= 1
assert not self.extramarginal()
diff_from_equilibrium = self.limit_price() - self.equilibrium_price
print "aab am dfe", diff_from_equilibrium
if self.doa >= -1 and self.doa <= 0:
self.tau = self.equilibrium_price * (1+self.doa*math.exp(self.theta*(self.doa-1)))
elif diff_from_equilibrium == 0:
self.tau = self.equilibrium_price
else:
print self.equilibrium_price
print self.theta
print diff_from_equilibrium
theta_bar = self.equilibrium_price * math.exp(-self.theta)
theta_bar /= diff_from_equilibrium
theta_bar -= 1
print self.doa
print theta_bar
t = diff_from_equilibrium*(1-(self.doa+1)*math.exp(self.doa*theta_bar))
t += self.equilibrium_price
self.tau = t
self.tau = min(1, self.tau)
self.tau = max(self.tau, self.limit_price())
assert self.tau >= 1 and self.tau <= self.limit_price()
self.strval = "aab ami tau = " + str(self.tau) + " lp = " + str(self.limit_price())
print "aab ami tau", self.tau
def lambda_value(self, best_bid_price, trade):
if trade is not None:
#guesswork, flip these if it doesn't beat zip
if self.tau >= trade["price"]:
#become more passive
lambda_value = 0.05
else:
#become more aggressive
lambda_value = -0.05
elif best_bid_price is not None:
if self.tau <= best_bid_price:
print "going down"
#become more aggressive
lambda_value = -0.05
return lambda_value
def bidding_component(self, market_best_ask, market_best_bid, time):
if len(self.orders) > 0:
order = self.orders[0]
assert order.otype == "Bid"
if order.price <= market_best_bid:
print "aab bc case a"
return None
elif len(self.previous_trades) == 0:
print "aab bc case b"
expr = min([order.price, market_best_ask,0], key=lambda x: 1000000 if x == None else x)
bid = market_best_bid + (expr - market_best_bid)/self.nyan
elif market_best_ask <= self.tau:
print "aab bc case c"
bid = market_best_ask
else:
print "aab bc case d"
bid = market_best_bid + (self.tau-market_best_bid)/self.nyan
return BSE.Order(order.tid, "Bid", bid, order.qty, time)
return None
class AASeller(AACommon):
PMAX = 1000
def __init__(self):
AACommon.__init__(self)
def extramarginal(self):
return self.limit_price() >= self.equilibrium_price
def aggressiveness_model(self):
if len(self.orders) > 0:
if self.extramarginal():
r = self.limit_price()
if self.doa >= 0 and self.doa <= 1:
r -= (self.PMAX-self.limit_price())*self.doa*math.exp((self.doa-1)*self.theta)
self.tau = r
print "aas ame doa", self.doa, "theta", self.theta, "tau", self.tau, "lp", self.limit_price()
self.strval = "aas ame tau = " + str(self.tau) + " lp = " + str(self.limit_price())
if self.tau >= self.PMAX:
self.tau = self.PMAX
elif self.tau <= self.limit_price():
self.tau = self.limit_price()
assert self.tau <= self.PMAX and self.tau >= self.limit_price()
else:
assert self.doa >= -1 and self.doa <= 1
assert self.equilibrium_price > 0
assert not self.extramarginal()
theta_bar = self.PMAX-self.equilibrium_price
assert theta_bar >= 0
theta_bar /= self.equilibrium_price - self.limit_price()
assert theta_bar >= 0
theta_bar = math.log(theta_bar)
theta_bar -= self.theta
if theta_bar < 0:
print "tb<0"
theta_bar = 0
if self.doa >= -1 and self.doa <= 0:
self.tau = (self.PMAX - self.equilibrium_price)*(1-((math.exp(-self.doa * theta_bar)-1)/(math.exp(theta_bar)-1)))
else:
#doa -0.9875
print "this maths, not the other maths"
#-77.92 141 141 10 -0.9875 -0.9875 -0.2647
self.tau = self.equilibrium_price + (self.equilibrium_price-self.limit_price())*self.doa*math.exp((self.doa-1)*theta_bar)
print "aas ami doa", self.doa, "theta", self.theta, "tb", theta_bar, "lp", self.limit_price(), "eqp", self.equilibrium_price, "tau", self.tau
self.strval = "aas ami tau = " + str(self.tau) + " lp = " + str(self.limit_price())
assert self.tau <= self.PMAX and self.tau >= self.limit_price()
def lambda_value(self, best_ask_price, trade):
if trade is not None:
#guesswork, flip these if it doesn't beat zip
if self.tau <= trade["price"]:
#become more passive
lambda_value = 0.05
else:
#become more aggressive
lambda_value = -0.05
elif best_ask_price is not None:
if self.tau >= best_ask_price:
print "going down"
#become more aggressive
lambda_value = -0.05
return -lambda_value
def bidding_component(self, market_best_ask, market_best_bid, time):
print "aas -----------------------------"
if len(self.orders) > 0:
print "aas limit price", self.limit_price()
order = self.orders[0]
assert order.otype == "Ask"
print "aas op", order.price, "ba", market_best_ask, "bb", market_best_bid, "tau", self.tau, "eqp", self.equilibrium_price, "lim", self.limit_price()
print self.strval
if order.price >= market_best_ask:
print "aas bc case a"
return None
elif len(self.previous_trades) == 0:
print "aas bc case b"
ask = market_best_ask
mop = max([order.price, market_best_bid,1000], key=lambda x: -100000000 if x == None else x)
ask -= (market_best_ask - mop)/self.nyan
elif market_best_bid >= self.tau:
print "aas bc case c"
ask = market_best_bid
else:
print "aas bc case d"
ask = market_best_ask - (market_best_ask - self.tau)/self.nyan
assert ask >= self.limit_price()
return BSE.Order(order.tid, "Ask", ask, order.qty, time)
return None