from otree.api import * import random doc = """ In this Vickrey auction, 3 players bid for an object with private values. Each player can only submit one bid. See: Vickrey, William. "Counterspeculation, auctions, and competitive ' sealed tenders." The Journal of finance 16.1 (1961): 8-37. """ class Constants(BaseConstants): name_in_url = 'second_price_auction' players_per_group = 3 num_rounds = 1 endowment = 5 INSTRUCTIONS_TEMPLATE = 'second_price_auction/instructions.html' class Subsession(BaseSubsession): pass class Group(BaseGroup): highest_bid = models.IntegerField() second_highest_bid = models.IntegerField() def set_payoffs(group: Group): players = group.get_players() bids = sorted([p.bid_amount for p in players], reverse=True) group.highest_bid = bids[0] group.second_highest_bid = bids[1] players_with_highest_bid = [ p for p in players if p.bid_amount == group.highest_bid ] # if tie, winner is chosen at random winner = random.choice(players_with_highest_bid) winner.is_winner = True for p in players: p.payoff_float = Constants.endowment if p.is_winner: p.payoff_float += (p.private_value - group.second_highest_bid) class Player(BasePlayer): private_value = models.IntegerField() payoff_float = models.IntegerField() bid_amount = models.IntegerField( choices=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) is_winner = models.BooleanField( initial=False, doc="""Indicates whether the player is the winner""" ) #pages class Bid(Page): form_model = 'player' form_fields = ['bid_amount'] class ResultWaitPgae(WaitPage): after_all_players_arrive = set_payoffs class Results(Page): pass class Introduction1(Page): @staticmethod def before_next_page(player, timeout_happened): if player.id_in_group % 4 == 1: player.private_value = 6 elif player.id_in_group % 4 == 2: player.private_value = 9 elif player.id_in_group % 4 == 3: player.private_value = 12 else: player.private_value = 4 page_sequence = [ Introduction1, Bid, ResultWaitPgae, Results ]