-
Notifications
You must be signed in to change notification settings - Fork 2
/
market.py
180 lines (139 loc) · 6.2 KB
/
market.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
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
# (C) Copyright 2018
# Georg Link <[email protected]>
#
# SPDX-License-Identifier: MPL-2.0
#####
# market.py
#
# Simulated Bugmark market
#####
class Contract():
positions = []
def __init__(self, issue, maturation_date):
self.issue = issue # issue this contract is on
self.maturation_date = maturation_date # end of contract
self.escrow = 0 # money paid into contract
def set_issue(self, issue):
self.issue = issue
def set_maturation_date(self, maturation_date):
self.maturation_date = maturation_date
def add_position(self, position):
self.positions.append(position)
def add_escrow(self, add_escrow):
self.escrow += add_escrow
class Position():
def __init__(self, user, contract, units, unit_price, un_fixed):
self.user = user # owner of the contract position
self.contract = contract # ownership in this contract
self.units = units # number of units this position has
self.unit_price = unit_price # price paid per unit
self.un_fixed = un_fixed # type of position: fixed or unfixed
self.contract.add_position(self)
class Offer():
def __init__(self, user, contract, units, unit_price, expiration_date,
un_fixed, buy_sell, position=None):
self.user = user #user who made this offer
self.contract = contract # contract this offer is for
self.units = units # number of units to by of a contract
self.unit_price = unit_price # unit price
self.expiration_date = expiration_date # day the offer expires
self.un_fixed = un_fixed # or unfixed
self.sell_buy = buy_sell # offer is for selling or buying
self.position = position # references position that is being sold
self.status = 'open' # status of offer
class Market():
offers = []
open_offers = []
contracts = []
active_contracts = []
positions = []
active_positions = []
def make_unfixed_offer(self, issue, maturation_date, units, unit_price,
user, expiration_date):
# user can offer to buy an unfixed position in a contract
# check that user has enough money
if user.get_money() < (units * unit_price):
return {0, "insufficient funds"}
# TODO:
contract = self.find_or_create_Contract(issue, maturation_date)
# create a new offer
new_offer = Offer(user, contract, units, unit_price, expiration_date,
"unfixed", "buy")
# attatch new offer to offers list
self.offers.append(new_offer)
# attatch new offer to open offers list
self.open_offers.append(new_offer)
self.cross_offers()
return new_offer
def make_fixed_offer(self, issue, maturation_date, units, unit_price, user,
expiration_date):
if user.get_money() < units * unit_price:
return {0, "insufficient funds"}
# user can offer to buy a fixed position in a contract
# TODO:
contract = self.find_or_create_Contract(issue, maturation_date)
# create a new offer
new_offer = Offer(user, contract, units, unit_price, expiration_date,
"fixed", "buy")
# attatch new offer to offers list
self.offers.append(new_offer)
# attatch new offer to open offers list
self.open_offers.append(new_offer)
self.cross_offers()
return None
def make_sell_offer(self, issue, position, units, unit_price, user):
# allow a user to sell (partial) positions
# TODO:
# create a new offer
# attatch new offer to offers list
# attatch new offer to open offers list
self.cross_offers()
return None
def cross_offers(self):
# find matching offers
for i in range(len(self.open_offers)):
for j in range(i):
if self.open_offers[i].un_fixed != self.open_offers[j].un_fixed:
# create positions
new_position1 = Position(self.open_offers[i].user,
self.open_offers[i].contract, self.open_offers[i].units,
self.open_offers[i].unit_price, self.open_offers[i].un_fixed)
new_position2 = Position(self.open_offers[j].user,
self.open_offers[j].contract, self.open_offers[j].units,
self.open_offers[j].unit_price, self.open_offers[j].un_fixed)
#add the positions in lists
self.positions.append(new_position1)
self.positions.append(new_position2)
self.active_positions.append(new_position1)
self.active_positions.append(new_position2)
minus_money_user1 = self.open_offers[i].units * self.open_offers[i].unit_price
minus_money_user2 = self.open_offers[j].units * self.open_offers[j].unit_price
self.open_offers[i].user.minus_money(minus_money_user1)
self.open_offers[j].user.minus_money(minus_money_user2)
self.open_offers[i].contract.add_escrow(self.open_offers[i].units)
self.contracts.append(self.open_offers[i].contract)
self.active_contracts.append(self.open_offers[i].contract)
break
# TODO: matching and crossing algorithm
return None
def find_or_create_Contract(self, issue, maturation_date):
#find existing contract in contracts[]
for i in range(len(self.contracts)):
if ((self.contracts[i].issue == issue) and
(self.contracts[i].maturation_date == maturation_date)):
return self.contracts[i]
#or create new contract
contract = Contract(issue, maturation_date)
self.contracts.append(contract)
return contract
def payout_contracts(self):
# pay users for contracts that matured
# TODO: payout algorithm
return None
def list_offers(self):
# print("bmx list offers:")
for o in self.offers:
print(o)
return None