-
Notifications
You must be signed in to change notification settings - Fork 0
/
simulate_auction.py
71 lines (63 loc) · 2.99 KB
/
simulate_auction.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
"""Run a simulation of a Purple Price Auction
Usage: simulate_auction [options]
Options:
--init_quantity=<num> Available tickets [default: 100000]
--init_price=<$> Starting price [default: 100]
--drop=<$> Price drop interval [default: 1]
--max=<num> Max tickets per user [default: 1]
--users=<i> Number of users [default: 10000]
--floor=<$> Add a floor to each user's WTP [default: 10]
--shape=<p> Probability parameter for WTP distribution [default: .02]
-h, --help Show this screen.
"""
import numpy as np
from operator import itemgetter
import matplotlib.pyplot as plt
from docopt import docopt
from purple_pricing import Bid, User, PurplePriceAuction
if __name__ == "__main__":
arguments = docopt(__doc__)
auction = PurplePriceAuction(init_price=arguments['--init_price'],
init_quantity=arguments['--init_quantity'],
price_drop=arguments['--drop'],
max_quantity=arguments['--max'])
# Create fake users with simulated distribution of WTP
wtp_floor = float(arguments['--floor'])
wtp_shape = float(arguments['--shape'])
user_ids = range(1, int(arguments['--users']) + 1)
users = {i: User(user_id=i, wtp= wtp_floor + np.random.geometric(wtp_shape))\
for i in user_ids}
# Plot willingnesses to pay
font = {'weight' : 'normal',
'size' : 6}
plt.rc('font', **font)
plt.figure(figsize=(2,2), facecolor='white')
plt.hist([x.wtp for x in users.itervalues()], bins=100)
plt.title('Willingness To Pay (histogram)')
plt.show()
# Run simulated auction
while auction.quantity > 0:
price = auction.price
np.random.shuffle(user_ids)
for user_id in user_ids:
users[user_id].make_bid(auction)
print "Price ${:,}: Expected payoff at ${:,} is ${:,}".format(auction.price,
auction.price - auction.price_drop,
auction.calculate_payoff())
auction.set_price()
if auction.price == price:
break
# Compare auction with max revenue auction with perfect information
final_quantity = (auction.init_quantity - auction.quantity)
final_revenue = final_quantity * auction.price
revenue_curve = []
for i in range(1, auction.init_price):
qty = 0
for user in users.itervalues():
if user.wtp >= i:
qty += user.max_quantity
revenue_curve.append((qty, i, qty*i))
flat_rate = max((i for i in revenue_curve), key=itemgetter(2))
print "Revenue: ${:,} from {:,} sold at ${:,}".format(final_revenue, final_quantity, auction.price)
print "Max revenue with perfect information: ${:,} selling {:,} tickets at ${:,} per ticket."\
.format(flat_rate[2], flat_rate[0], flat_rate[1])