-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrades.py
163 lines (137 loc) · 5.89 KB
/
trades.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
from numpy import log as ln
from numpy import e
from math import ceil, floor
import numpy as np
import os, sys, datetime
from django.core.exceptions import ObjectDoesNotExist
reload(sys)
sys.setdefaultencoding('utf8')
from dateutil.parser import parse
sys.path.append("/root/collectiwise/collectiwise_backend/")
sys.path.append("/root/collectiwise/")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "collectiwise_backend.settings")
sys.path.append("/root/collectiwise/collectiwise_backend/collectiwise_core/")
import django
django.setup()
sys.path.append("/root")
from collectiwise_core.models import Event, EventVar, Contract, ContractVar, User, UserBalance, UserContract, Purchase
bigBrother = User("Big Brother")
bigBroBalance = UserBalance(bigBrother, 10000)
def round_up(cont_money):
cents =cont_money*100
return int(ceil(cents))
def round_down(cont_money):
cents = cont_money*100
return int(floor(cents))
class Market(object):
"""
In the future, this class should instantiate by
querying an event and add all of its contracts automatically
to the contract list and fill in the title of the event
for now, I instantiate the class by explicitly feeding
it with a list of contracts.
"""
def __init__(self, title, contracts, b):
"""
title: str
contracts: list
b: float #b is chosen by the market maker so as to govern the
volatility of the price to quantities
"""
self.title= title
self.contracts = contracts
self.b = float(b)
self.volumes = self.quantities
@property
def cost(self):
b = self.b
quantities = self.quantities
return b*ln(sum([e**(qi/b) for qi in quantities]))
def query_cost(self, contract, q):
"""
contract: dict
q : float
"""
b = self.b
index = self.contracts.index(contract)
quantities = self.quantities
quantities[index]+=float(q)
if q>0:
return round_up(b*ln(sum([e**(qi/b) for qi in quantities])) - self.cost)
else:
return -round_down(-b*ln(sum([e**(qi/b) for qi in quantities])) + self.cost)
def buy(self, contract, q, user):
"""
contract: dict
q: float
user: dict #this is the user object
"""
contract.volume +=q
contract.save()
#here, the contract should be updated in the database
user["events"][self.title]["contracts"][contract] += q
user["account"] -= self.query_cost(contract, q)/100.00 #in dollars
#update user here
return {"new_q": contract.volume, contract : user["events"][self.title]["contracts"][contract.name]}
def sell(self, contract, q, user):
return self.buy(contract, -q, user)
def price(self, contract):
b = self.b
index = self.contracts.index(contract)
quantities = [float(contract.volume) for contract in self.contracts]
q = quantities[index]
return e**(q/b)/sum([e**(qi/b) for qi in quantities])
@property
def quantities(self):
#set one of the quantities (here the first one) to b (a good base number)
price_vector = [contract.lastTradePrice for contract in self.contracts]
q1= [contract.volume for contract in self.contracts][0]
if q1<=0:
q1 = self.b
self.contracts[0].volume = b
p1 = price_vector[0]
for contract in self.contracts:
index=self.contracts.index(contract)
if index>0:
contract.volume = b*ln(e**(q1/b)*(contract.lastTradePrice/p1))
return [q1] + [b*ln(e**(q1/b)*(pk/p1)) for pk in price_vector[1:]]
def equilibriate_quantities(self, price_vector, param=2):
bigBrother["events"] = {self.title:{"contracts":{contract["title"]:0 for contract in self.contracts}}}
while np.abs(sum(np.array(self.quants) - np.array(self.quantities(price_vector)))) > param:
diff = np.array(self.quantities(price_vector)) - np.array(self.quants) #the difference of what I should have minus the ones I do have
index = list(diff).index(max(diff))
if int(max(diff)/2.0) > 0:
self.buy(self.contracts[index]["title"], int(max(diff)/2.0), bigBrother)
else:
break
return
def main():
user = {"id": 12345, "events":{"Will I become a billionair in five years?":{"contracts":{"yes":20, "no":0}}}}
user["account"]=500
market =Market("Will I become a billionair in five years?",
[{"title":"yes", "q":300}, {"title":"no", "q":700}],
100)
print "user shares: " + str(user)
print "price of 10 shares of no: " + str(market.query_cost("no", 10)/100.0)
print "yes price: " + str(market.price("yes"))
print "no price: " + str(market.price("no"))
print "buying with user: " +str(market.buy("yes", 20, user))
print "price of 20 shares of yes: " + str(market.query_cost("yes", 20)/100.0)
print "user account: " + str(user)
print "yes price: " + str(market.price("yes"))
print "no price: " + str(market.price("no"))
print "price of selling 20 shares of no: " + str(-market.query_cost("no", -20)/100.0)
print "selling no with user: " +str(market.sell("no", 20, user))
print "user account: " + str(user)
print "yes price: " + str(market.price("yes"))
print "no price: " + str(market.price("no"))
market2 = Market("how many tweets will I sent before next week?", [{"title": 0}, {"title":10}, {"title":25}, {"title":30}], 10)
print "quantities from prices (p1=0.1, p2=0.2, p3=0.2, p4=0.5): " + str(market2.quantities([0.1, 0.2, 0.2, 0.5]))
#query from predictit has prices:
predictit_query = {"yes": 1, "no":99}
market.equilibriate_quantities([1, 99])
print bigBrother
print "yes price: " + str(market.price("yes"))
print "no price: " + str(market.price("no"))
if __name__=="__main__":
main()