from otree.api import (
models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer,
Currency as c, currency_range, Page, WaitPage
)
cu = c
doc = '\nIn a common value auction game, players simultaneously bid on the item being\nauctioned.
\nPrior to bidding, they are given an estimate of the actual value of the item.\nThis actual value is revealed after the bidding.
\nBids are private. The player with the highest bid wins the auction, but\npayoff depends on the bid amount and the actual value.
\n'
class Constants(BaseConstants):
name_in_url = 'market_rounds_asset_two_realized'
players_per_group = None
num_rounds = 9
min_allowable_bid = c(0)
instructions_template = 'market_rounds_asset_two_realized/instructions.html'
def creating_session(subsession):
pass
class Subsession(BaseSubsession):
creating_session = creating_session
def set_winner_Type2(group):
import random
players = group.get_players()
playerbidnumber = max([p.id_in_group for p in players])
allbids = []
allasks = []
for p in players:
p.change_Type2 = 0
if group.round_number == 1:
p.won_type2 = p.owned_type2
firstcount = 0
secondcount = 0
buyoffers2 = 0
selloffers2 = 0
while firstcount < playerbidnumber:
freshplayer = firstcount + 1
currentbuyer = group.get_player_by_id(freshplayer)
numberofbids = 0
personbidnumber = currentbuyer.number_Type2
while numberofbids < personbidnumber:
allbids.append(currentbuyer.buy_amount_type2)
numberofbids = numberofbids + 1
buyoffers2 = buyoffers2 + 1
firstcount = firstcount + 1
bidsinorder = sorted(allbids, reverse=True)
while secondcount < playerbidnumber:
newestplayer = secondcount + 1
currentseller = group.get_player_by_id(newestplayer)
numberofasks = 0
personasknumber = currentseller.number_sell_Type2
while numberofasks < personasknumber:
allasks.append(currentseller.sell_amount_type2)
numberofasks = numberofasks + 1
selloffers2 = selloffers2 + 1
secondcount = secondcount + 1
asksinorder = sorted(allasks, reverse=False)
highestbid = 0
lowestask = 30
if buyoffers2 > 0:
highestbid = bidsinorder[0]
if selloffers2 > 0:
lowestask = asksinorder[0]
counter = 0
bidslots = 0
roundtype2price = 0
sellcheck2 = 1
buycheck2 = 1
if buyoffers2 > 0 and selloffers2 > 0 and highestbid > lowestask:
while counter < 1:
if sellcheck2 < selloffers2 and buycheck2 < buyoffers2:
bidvaluetest = bidsinorder[bidslots]
askvaluetest = asksinorder[bidslots]
if bidvaluetest == askvaluetest:
roundtype2price = bidvaluetest
group.pricetype2 = roundtype2price
group.price2display = str(roundtype2price)
counter = 2
elif bidvaluetest < askvaluetest:
middlevalue = (bidsinorder[bidslots-1] + asksinorder[bidslots-1])/2
step1value = max(middlevalue, bidvaluetest)
step2value = min(step1value, askvaluetest)
roundtype2price = step2value
group.pricetype2 = roundtype2price
group.price2display = str(roundtype2price)
counter = 3
else:
bidslots = bidslots + 1
sellcheck2 = sellcheck2 + 1
buycheck2 = buycheck2 + 1
elif sellcheck2 < selloffers2 and buycheck2 == buyoffers2:
bidvaluetest = bidsinorder[bidslots]
askvaluetest = asksinorder[bidslots]
if bidvaluetest == askvaluetest:
roundtype2price = bidvaluetest
group.pricetype2 = roundtype2price
group.price2display = str(roundtype2price)
counter = 4
elif bidvaluetest > askvaluetest:
nextaskvalue = asksinorder[bidslots+1]
if nextaskvalue == askvaluetest:
roundtype2price = askvaluetest
elif nextaskvalue > bidvaluetest:
roundtype2price = (bidvaluetest + askvaluetest)/2
else:
roundtype2price = nextaskvalue
group.pricetype2 = roundtype2price
group.price2display = str(roundtype2price)
counter = 5
else:
middlevalue = (bidsinorder[bidslots-1] + asksinorder[bidslots-1])/2
step1value = max(middlevalue, bidvaluetest)
step2value = min(step1value, askvaluetest)
roundtype2price = step2value
group.pricetype2 = roundtype2price
group.price2display = str(roundtype2price)
counter = 6
elif sellcheck2 == selloffers2 and buycheck2 < buyoffers2:
bidvaluetest = bidsinorder[bidslots]
askvaluetest = asksinorder[bidslots]
if bidvaluetest == askvaluetest:
roundtype2price = bidvaluetest
group.pricetype2 = roundtype2price
group.price2display = str(roundtype2price)
counter = 7
elif bidvaluetest > askvaluetest:
nextbidvalue = bidsinorder[bidslots+1]
if nextbidvalue == bidvaluetest:
roundtype2price = bidvaluetest
elif nextbidvalue < askvaluetest:
roundtype2price = (bidvaluetest + askvaluetest)/2
else:
roundtype2price = nextbidvalue
group.pricetype2 = roundtype2price
group.price2display = str(roundtype2price)
counter = 5
else:
middlevalue = (bidsinorder[bidslots-1] + asksinorder[bidslots-1])/2
step1value = max(middlevalue, bidvaluetest)
step2value = min(step1value, askvaluetest)
roundtype2price = step2value
group.pricetype2 = roundtype2price
group.price2display = str(roundtype2price)
counter = 9
else:
bidvaluetest = bidsinorder[bidslots]
askvaluetest = asksinorder[bidslots]
if bidvaluetest == askvaluetest:
roundtype2price = bidvaluetest
group.pricetype2 = roundtype2price
group.price2display = str(roundtype2price)
counter = 11
elif bidvaluetest < askvaluetest:
middlevalue = (bidsinorder[bidslots-1] + asksinorder[bidslots-1])/2
step1value = max(middlevalue, bidvaluetest)
step2value = min(step1value, askvaluetest)
roundtype2price = step2value
group.pricetype2 = roundtype2price
group.price2display = str(roundtype2price)
counter = 12
else:
roundtype2price = (bidsinorder[bidslots] + asksinorder[bidslots])/2
group.pricetype2 = roundtype2price
group.price2display = str(roundtype2price)
counter = 13
elif buyoffers2 > 0 and selloffers2 > 0 and highestbid == lowestask:
roundtype2price = highestbid
group.pricetype2 = highestbid
group.price2display = str(roundtype2price)
amountboughttype2 = 0
amountsoldtype2 = 0
if buyoffers2 > 0 and selloffers2 > 0 and highestbid >= lowestask:
for p in players:
if p.buy_amount_type2 >= roundtype2price and p.number_Type2 > 0:
p.owned_type2 = p.owned_type2 + p.number_Type2
p.change_Type2 = p.number_Type2
if p.change_Type2 > 0:
p.asset2change = "bought"
p.displaychange2 = str(p.change_Type2)
amountboughttype2 = amountboughttype2 + p.number_Type2
if buyoffers2 > 0 and selloffers2 > 0 and highestbid >= lowestask:
for p in players:
if p.sell_amount_type2 <= roundtype2price and p.number_sell_Type2 > 0:
p.owned_type2 = p.owned_type2 - p.number_sell_Type2
p.change_Type2 = -p.number_sell_Type2
if p.change_Type2 < 0:
p.asset2change = "sold"
p.displaychange2 = str(p.number_sell_Type2)
amountsoldtype2 = amountsoldtype2 + p.number_sell_Type2
if buyoffers2 > 0 and selloffers2 > 0 and highestbid < lowestask:
roundtype2price = (highestbid + lowestask)/2
group.pricetype2 = roundtype2price
if amountboughttype2 > amountsoldtype2:
players_with_marginal_bid = [
p for p in players if p.buy_amount_type2 == roundtype2price
]
while amountboughttype2 > amountsoldtype2:
winner = random.choice(
players_with_marginal_bid
) # if tie, winner is chosen at random
if winner.change_Type2 > 0:
winner.owned_type2 = winner.owned_type2 - 1
winner.change_Type2 = winner.change_Type2 - 1
winner.displaychange2 = str(winner.change_Type2)
amountboughttype2 = amountboughttype2 - 1
if amountboughttype2 < amountsoldtype2:
players_with_marginal_bid = [
p for p in players if p.sell_amount_type2 == roundtype2price
]
while amountboughttype2 < amountsoldtype2:
winner = random.choice(
players_with_marginal_bid
) # if tie, winner is chosen at random
if winner.change_Type2 < 0:
winner.owned_type2 = winner.owned_type2 + 1
winner.change_Type2 = winner.change_Type2 + 1
if winner.change_Type2 < 0:
positivechange = -winner.change_Type2
winner.displaychange2 = str(positivechange)
else:
winner.displaychange2 = "0"
amountsoldtype2 = amountsoldtype2 - 1
for p in players:
if amountsoldtype2 > 0 and amountboughttype2 > 0:
p.asset2roundprice = str(roundtype2price)
else:
p.asset2roundprice = "None"
if buyoffers2 == 0 and selloffers2 == 0:
group.price2display = "None: no bids or offers"
elif buyoffers2 == 0 and selloffers2 > 0:
group.price2display = "None: no bids"
elif buyoffers2 > 0 and selloffers2 == 0:
group.price2display = "None: no offers"
else:
group.price2display = "None: highest bid = " + str(highestbid) + " and lowest offer = " +str(lowestask)
p.auction_spending2 = roundtype2price*-p.change_Type2
p.available_funds = p.available_funds + p.auction_spending2
def set_end_data(group):
players = group.get_players()
for p in players:
set_end_player_values(p)
def set_start_data(group):
players = group.get_players()
for p in players:
set_initial_player_values(p)
def create_outcome(group):
import random
players = group.get_players()
if group.round_number == 1:
for p in players:
p.purchasehistory2 = "Original auction price = " + str(p.asset2initialprice)
p.purchasehistory2 = p.purchasehistory2 + ". You won " + str(p.won_type2) + " units"
if group.pricetype2 > 0:
p.purchasehistory2 = p.purchasehistory2 + ". Period 1 price was " + p.asset2roundprice
else:
p.purchasehistory2 = p.purchasehistory2 + ". Period 1 price was None."
p.purchasehistory2 = p.purchasehistory2 + ". You " + p.asset2change + " " + p.displaychange2 + " in this round."
else:
for p in players:
if group.pricetype2 > 0:
p.purchasehistory2 = p.purchasehistory2 + " Period " + str(p.round_number) + " price was " + p.asset2roundprice
else:
p.purchasehistory2 = p.purchasehistory2 + " Period " + str(p.round_number) + " price was None"
p.purchasehistory2 = p.purchasehistory2 + ". You " + p.asset2change + " " + p.displaychange2 + " in this round."
asset2gen = random.random()
if asset2gen < .1:
group.asset2outcome = "Assets gained 90 cents."
for p in players:
p.bankedaccount = p.bankedaccount + .9*p.owned_type2
p.asset2earningschange = .9*p.owned_type2
else:
group.asset2outcome = "Assets lost 10 cents."
for p in players:
p.bankedaccount = p.bankedaccount + -.1*p.owned_type2
p.asset2earningschange = -.1*p.owned_type2
def set_final_data(group):
players = group.get_players()
for p in players:
set_final_round2data(p)
class Group(BaseGroup):
pricetype2 = models.CurrencyField(initial=0)
u = models.IntegerField()
price2display = models.StringField(initial='None')
asset2outcome = models.StringField()
set_winner_Type2 = set_winner_Type2
set_end_data = set_end_data
set_start_data = set_start_data
create_outcome = create_outcome
set_final_data = set_final_data
def set_initial_player_values(player):
participant = player.participant
player.owned_type2 = participant.vars['type2']
player.available_funds = participant.vars['funds']
player.bankedaccount = participant.vars['bankedaccount']
player.asset2value = participant.vars['asset2value']
player.asset2initialprice = participant.vars['asset2auctionprice']
player.purchasehistory2 = participant.vars['purchasehistory2']
def set_end_player_values(player):
participant = player.participant
participant.vars['type2'] = player.owned_type2
participant.vars['funds'] = player.available_funds
participant.vars['bankedaccount'] = player.bankedaccount
participant.vars['asset2value'] = player.asset2value
participant.vars['asset2auctionprice'] = player.asset2initialprice
participant.vars['purchasehistory2'] = player.purchasehistory2
def set_final_round2data(player):
participant = player.participant
player.round2earnings = player.bankedaccount + player.available_funds + player.owned_type2*player.asset2value
participant.vars['round2earnings'] = player.round2earnings
participant.vars['round2bankedaccount'] = player.bankedaccount
participant.vars['round2availablefunds'] = player.available_funds
participant.vars['round2ownedtype2'] = player.owned_type2
participant.vars['round2asset2value'] = player.asset2value
class Player(BasePlayer):
buy_amount_type2 = models.CurrencyField(doc='Amount bidded by the player', label="Price you're willing to pay for assets", min=0)
number_Type2 = models.IntegerField(label='Number of assets to purchase at your specified price', min=0)
initial_spending = models.CurrencyField()
owned_type2 = models.IntegerField(initial=0)
auction_spending2 = models.CurrencyField()
available_funds = models.CurrencyField(initial=12.5)
sell_amount_type2 = models.CurrencyField(label="Price you're willing to sell assets for", min=0)
number_sell_Type2 = models.IntegerField(label='Number of assets to sell at your specified sale price', min=0)
change_Type2 = models.IntegerField(initial=0)
asset2value = models.CurrencyField()
bankedaccount = models.CurrencyField()
purchasehistory = models.LongStringField()
asset2initialprice = models.CurrencyField()
asset2roundprice = models.StringField(initial='None')
asset2change = models.StringField(initial='traded')
displaychange2 = models.StringField(initial='0')
purchasehistory2 = models.LongStringField()
won_type2 = models.IntegerField()
round2earnings = models.CurrencyField()
asset2earningschange = models.CurrencyField(initial=0)
set_initial_player_values = set_initial_player_values
set_end_player_values = set_end_player_values
set_final_round2data = set_final_round2data