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_one_realized'
players_per_group = None
num_rounds = 9
min_allowable_bid = c(0)
instructions_template = 'market_rounds_asset_one_realized/instructions.html'
def creating_session(subsession):
pass
class Subsession(BaseSubsession):
creating_session = creating_session
def set_winner_Type1(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_Type1 = 0
if group.round_number == 1:
p.won_type1 = p.owned_type1
firstcount = 0
secondcount = 0
buyoffers1 = 0
selloffers1 = 0
while firstcount < playerbidnumber:
freshplayer = firstcount + 1
currentbuyer = group.get_player_by_id(freshplayer)
numberofbids = 0
personbidnumber = currentbuyer.number_Type1
while numberofbids < personbidnumber:
allbids.append(currentbuyer.buy_amount_type1)
numberofbids = numberofbids + 1
buyoffers1 = buyoffers1 + 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_Type1
while numberofasks < personasknumber:
allasks.append(currentseller.sell_amount_type1)
numberofasks = numberofasks + 1
selloffers1 = selloffers1 + 1
secondcount = secondcount + 1
asksinorder = sorted(allasks, reverse=False)
counter = 0
bidslots = 0
highestbid = 0
lowestask = 30
if buyoffers1 > 0:
highestbid = bidsinorder[0]
if selloffers1 > 0:
lowestask = asksinorder[0]
roundtype1price = 0
sellcheck1 = 1
buycheck1 = 1
if buyoffers1 > 0 and selloffers1 > 0 and highestbid > lowestask:
while counter < 1:
if sellcheck1 < selloffers1 and buycheck1 < buyoffers1:
bidvaluetest = bidsinorder[bidslots]
askvaluetest = asksinorder[bidslots]
if bidvaluetest == askvaluetest:
roundtype1price = bidvaluetest
group.pricetype1 = roundtype1price
group.price1display = str(roundtype1price)
counter = 2
elif bidvaluetest < askvaluetest:
middlevalue = (bidsinorder[bidslots-1] + asksinorder[bidslots-1])/2
step1value = max(middlevalue, bidvaluetest)
step2value = min(step1value, askvaluetest)
roundtype1price = step2value
group.pricetype1 = roundtype1price
group.price1display = str(roundtype1price)
counter = 3
else:
bidslots = bidslots + 1
sellcheck1 = sellcheck1 + 1
buycheck1 = buycheck1 + 1
elif sellcheck1 < selloffers1 and buycheck1 == buyoffers1:
bidvaluetest = bidsinorder[bidslots]
askvaluetest = asksinorder[bidslots]
if bidvaluetest == askvaluetest:
roundtype1price = bidvaluetest
group.pricetype1 = roundtype1price
group.price1display = str(roundtype1price)
counter = 4
elif bidvaluetest > askvaluetest:
nextaskvalue = asksinorder[bidslots+1]
if nextaskvalue == askvaluetest:
roundtype1price = askvaluetest
elif nextaskvalue > bidvaluetest:
roundtype1price = (bidvaluetest + askvaluetest)/2
else:
roundtype1price = nextaskvalue
group.pricetype1 = roundtype1price
group.price1display = str(roundtype1price)
counter = 5
else:
middlevalue = (bidsinorder[bidslots-1] + asksinorder[bidslots-1])/2
step1value = max(middlevalue, bidvaluetest)
step2value = min(step1value, askvaluetest)
roundtype1price = step2value
group.pricetype1 = roundtype1price
group.price1display = str(roundtype1price)
counter = 6
elif sellcheck1 == selloffers1 and buycheck1 < buyoffers1:
bidvaluetest = bidsinorder[bidslots]
askvaluetest = asksinorder[bidslots]
if bidvaluetest == askvaluetest:
roundtype1price = bidvaluetest
group.pricetype1 = roundtype1price
group.price1display = str(roundtype1price)
counter = 7
elif bidvaluetest > askvaluetest:
nextbidvalue = bidsinorder[bidslots+1]
if nextbidvalue == bidvaluetest:
roundtype1price = bidvaluetest
elif nextbidvalue < askvaluetest:
roundtype1price = (bidvaluetest + askvaluetest)/2
else:
roundtype1price = nextbidvalue
group.pricetype1 = roundtype1price
group.price1display = str(roundtype1price)
counter = 5
else:
middlevalue = (bidsinorder[bidslots-1] + asksinorder[bidslots-1])/2
step1value = max(middlevalue, bidvaluetest)
step2value = min(step1value, askvaluetest)
roundtype1price = step2value
group.pricetype1 = roundtype1price
group.price1display = str(roundtype1price)
counter = 9
else:
bidvaluetest = bidsinorder[bidslots]
askvaluetest = asksinorder[bidslots]
if bidvaluetest == askvaluetest:
roundtype1price = bidvaluetest
group.pricetype1 = roundtype1price
group.price1display = str(roundtype1price)
counter = 11
elif bidvaluetest < askvaluetest:
middlevalue = (bidsinorder[bidslots-1] + asksinorder[bidslots-1])/2
step1value = max(middlevalue, bidvaluetest)
step2value = min(step1value, askvaluetest)
roundtype1price = step2value
group.pricetype1 = roundtype1price
group.price1display = str(roundtype1price)
counter = 12
else:
roundtype1price = (bidsinorder[bidslots] + asksinorder[bidslots])/2
group.pricetype1 = roundtype1price
group.price1display = str(roundtype1price)
counter = 13
elif buyoffers1 > 0 and selloffers1 > 0 and highestbid == lowestask:
roundtype1price = highestbid
group.pricetype1 = highestbid
group.price1display = str(roundtype1price)
amountboughttype1 = 0
amountsoldtype1 = 0
if buyoffers1 > 0 and selloffers1 > 0 and highestbid >= lowestask:
for p in players:
if p.buy_amount_type1 >= roundtype1price and p.number_Type1 > 0:
p.owned_type1 = p.owned_type1 + p.number_Type1
p.change_Type1 = p.number_Type1
if p.change_Type1 > 0:
p.asset1change = "bought"
p.displaychange1 = str(p.change_Type1)
amountboughttype1 = amountboughttype1 + p.number_Type1
if buyoffers1 > 0 and selloffers1 > 0 and highestbid >= lowestask:
for p in players:
if p.sell_amount_type1 <= roundtype1price and p.number_sell_Type1 > 0:
p.owned_type1 = p.owned_type1 - p.number_sell_Type1
p.change_Type1 = -p.number_sell_Type1
if p.change_Type1 < 0:
p.asset1change = "sold"
p.displaychange1 = str(p.number_sell_Type1)
amountsoldtype1 = amountsoldtype1 + p.number_sell_Type1
if buyoffers1 > 0 and selloffers1 > 0 and highestbid < lowestask:
roundtype1price = (highestbid + lowestask)/2
group.pricetype1 = roundtype1price
if amountboughttype1 > amountsoldtype1:
players_with_marginal_bid = [
p for p in players if p.buy_amount_type1 == roundtype1price
]
while amountboughttype1 > amountsoldtype1:
winner = random.choice(
players_with_marginal_bid
) # if tie, winner is chosen at random
if winner.change_Type1 > 0:
winner.owned_type1 = winner.owned_type1 - 1
winner.change_Type1 = winner.change_Type1 - 1
winner.displaychange1 = str(winner.change_Type1)
amountboughttype1 = amountboughttype1 - 1
if amountboughttype1 < amountsoldtype1:
players_with_marginal_bid = [
p for p in players if p.sell_amount_type1 == roundtype1price
]
while amountboughttype1 < amountsoldtype1:
winner = random.choice(
players_with_marginal_bid
) # if tie, winner is chosen at random
if winner.change_Type1 < 0:
winner.owned_type1 = winner.owned_type1 + 1
winner.change_Type1 = winner.change_Type1 + 1
if winner.change_Type1 < 0:
positivechange = -winner.change_Type1
winner.displaychange1 = str(positivechange)
else:
winner.displaychange1 = "0"
amountsoldtype1 = amountsoldtype1 - 1
for p in players:
if amountsoldtype1 > 0 and amountboughttype1 > 0:
p.asset1roundprice = str(roundtype1price)
else:
p.asset1roundprice = "None"
if buyoffers1 == 0 and selloffers1 == 0:
group.price1display = "None: no bids or offers"
elif buyoffers1 == 0 and selloffers1 > 0:
group.price1display = "None: no bids"
elif buyoffers1 > 0 and selloffers1 == 0:
group.price1display = "None: no offers"
else:
group.price1display = "None: highest bid = " + str(highestbid) + " and lowest offer = " +str(lowestask)
p.auction_spending1 = roundtype1price*-p.change_Type1
p.available_funds = p.available_funds + p.auction_spending1
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.purchasehistory = "Original auction price = " + str(p.asset1initialprice)
p.purchasehistory = p.purchasehistory + ". You won " + str(p.won_type1) + " assets"
if group.pricetype1 > 0:
p.purchasehistory = p.purchasehistory + ". Period 1 price was " + p.asset1roundprice
else:
p.purchasehistory = p.purchasehistory + ". Period 1 price was None"
p.purchasehistory = p.purchasehistory + ". You " + p.asset1change + " " + p.displaychange1 + " in this round."
else:
for p in players:
if group.pricetype1 > 0:
p.purchasehistory = p.purchasehistory + " Period " + str(p.round_number) + " price was " + p.asset1roundprice
else:
p.purchasehistory = p.purchasehistory + " Period " + str(p.round_number) + " price was None"
p.purchasehistory = p.purchasehistory + ". You " + p.asset1change + " " + p.displaychange1 + " in this round."
asset1gen = random.random()
if asset1gen > .5:
group.asset1outcome = "Assets earned 25 cents."
for p in players:
p.bankedaccount = p.bankedaccount + .25*p.owned_type1
p.asset1earningschange = .25*p.owned_type1
else:
group.asset1outcome = "Assets lost 25 cents."
for p in players:
p.bankedaccount = p.bankedaccount - .25*p.owned_type1
p.asset1earningschange = -.25*p.owned_type1
def set_final_data(group):
players = group.get_players()
for p in players:
set_final_dataround1(p)
class Group(BaseGroup):
pricetype1 = models.CurrencyField(doc='Common value of the item to be auctioned random for treatment', initial=0)
u = models.IntegerField()
price1display = models.StringField(initial='None')
asset1outcome = models.StringField()
set_winner_Type1 = set_winner_Type1
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_type1 = participant.vars['type1']
player.available_funds = participant.vars['funds']
player.bankedaccount = participant.vars['bankedaccount']
player.asset1value = participant.vars['asset1value']
player.asset1initialprice = participant.vars['asset1auctionprice']
player.purchasehistory = participant.vars['purchasehistory']
def set_end_player_values(player):
participant = player.participant
participant.vars['type1'] = player.owned_type1
participant.vars['funds'] = player.available_funds
participant.vars['bankedaccount'] = player.bankedaccount
participant.vars['asset1value'] = player.asset1value
participant.vars['asset1auctionprice'] = player.asset1initialprice
participant.vars['purchasehistory'] = player.purchasehistory
def set_final_dataround1(player):
participant = player.participant
player.round1earnings = player.bankedaccount + player.available_funds + player.owned_type1*player.asset1value
participant.vars['round1earnings'] = player.round1earnings
participant.vars['round1bankedaccount'] = player.bankedaccount
participant.vars['round1availablefunds'] = player.available_funds
participant.vars['round1ownedtype1'] = player.owned_type1
participant.vars['round1asset1value'] = player.asset1value
class Player(BasePlayer):
buy_amount_type1 = models.CurrencyField(doc='Amount bidded by the player', label="Price you're willing to pay for assets", min=0)
number_Type1 = models.IntegerField(label='Number of assets to purchase at your specified price', min=0)
sell_amount_type1 = models.CurrencyField(label="Price you're willing to sell assets for", min=0)
number_sell_Type1 = models.IntegerField(label='Number of units to sell at your specified sale price', min=0)
initial_spending = models.CurrencyField()
owned_type1 = models.IntegerField(initial=0)
auction_spending1 = models.CurrencyField()
available_funds = models.CurrencyField(initial=12.5)
change_Type1 = models.IntegerField(initial=0)
asset1value = models.CurrencyField()
bankedaccount = models.CurrencyField()
purchasehistory = models.LongStringField()
asset1initialprice = models.CurrencyField()
asset1roundprice = models.StringField(initial='None')
asset1change = models.StringField(initial='traded')
displaychange1 = models.StringField(initial='0')
won_type1 = models.IntegerField()
round1earnings = models.CurrencyField()
asset1earningschange = models.CurrencyField(initial=0)
set_initial_player_values = set_initial_player_values
set_end_player_values = set_end_player_values
set_final_dataround1 = set_final_dataround1