from otree.api import * doc = """ In a common value auction game, players simultaneously bid on the item being auctioned.
Prior to bidding, they are given an estimate of the actual value of the item. This actual value is revealed after the bidding.
Bids are private. The player with the highest bid wins the auction, but payoff depends on the bid amount and the actual value.
""" class C(BaseConstants): NAME_IN_URL = 'common_value_auction' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 15 # Baja BID_MIN_B = cu(0) BID_MAX_B = cu(15) # Error margin for the value estimates shown to the players BID_NOISE_B = cu(1) # Media BID_MIN_M = cu(10) BID_MAX_M = cu(20) # Error margin for the value estimates shown to the players BID_NOISE_M = cu(1) # Sinergia SYNERGY = cu(10) # DOT = cu(500) class Subsession(BaseSubsession): pass class Group(BaseGroup): item_value_b = models.CurrencyField( doc="""Common value of the item to be auctioned, random for treatment""" ) highest_bid_b = models.CurrencyField() item_value_m = models.CurrencyField( doc="""Common value of the item to be auctioned, random for treatment""" ) highest_bid_m = models.CurrencyField() synergy = models.CurrencyField() class Player(BasePlayer): item_value_estimate_b = models.CurrencyField( doc="""Estimate of the common value, may be different for each player""" ) item_value_estimate_m = models.CurrencyField( doc="""Estimate of the common value, may be different for each player""" ) bid_amount_B = models.CurrencyField( min=C.BID_MIN_B, max=C.BID_MAX_B, doc="""Amount bidded by the player""", label="Monto de la oferta", ) is_winner_b = models.BooleanField( initial=False, doc="""Indicates whether the player is the winner""" ) bid_amount_M = models.CurrencyField( min=C.BID_MIN_M, max=C.BID_MAX_M, doc="""Amount bidded by the player""", label="Monto de la oferta", ) is_winner_m = models.BooleanField( initial=False, doc="""Indicates whether the player is the winner""" ) payoff_b = models.CurrencyField( doc="""payoff b""", label="Ganancia total B", ) payoff_m = models.CurrencyField( doc="""payoff m""", label="Ganancia total M", ) dot = models.CurrencyField( doc="""dotac""", label="Dotación", ) def other_player(self): return self.get_others_in_group()[0] # FUNCTIONS def creating_session(subsession: Subsession): subsession.group_randomly() for g in subsession.get_groups(): import random item_value_b = random.uniform(C.BID_MIN_B, C.BID_MAX_B) item_value_m = random.uniform(C.BID_MIN_M, C.BID_MAX_M) synergy = random.uniform(0, C.SYNERGY) g.item_value_b = round(item_value_b, 1) g.item_value_m = round(item_value_m, 1) g.synergy = round(synergy, 1) def set_winner_b(group: Group): import random players = group.get_players() group.highest_bid_b = max([p.bid_amount_B for p in players]) players_with_highest_bid_b = [p for p in players if p.bid_amount_B == group.highest_bid_b] winner_b = random.choice( players_with_highest_bid_b ) # if tie, winner is chosen at random winner_b.is_winner_b = True for p in players: set_payoff(p) group.highest_bid_m = max([p.bid_amount_M for p in players]) players_with_highest_bid_m = [p for p in players if p.bid_amount_M == group.highest_bid_m] winner_m = random.choice( players_with_highest_bid_m ) # if tie, winner is chosen at random winner_m.is_winner_m = True for p in players: set_payoff(p) def generate_value_estimate_b(group: Group): import random estimate_b = group.item_value_b + random.uniform(-C.BID_NOISE_B, C.BID_NOISE_B) estimate_b = round(estimate_b, 1) if estimate_b < C.BID_MIN_B: estimate_b = C.BID_MIN_B if estimate_b > C.BID_MAX_B: estimate_b = C.BID_MAX_B return estimate_b def generate_value_estimate_m(group: Group): import random estimate_m = group.item_value_m + random.uniform(-C.BID_NOISE_M, C.BID_NOISE_M) estimate_m = round(estimate_m, 1) if estimate_m < C.BID_MIN_M: estimate_m = C.BID_MIN_M if estimate_m > C.BID_MAX_M: estimate_m = C.BID_MAX_M return estimate_m def set_payoff(player: Player): group_b = player.group if player.is_winner_b: player.payoff_b = group_b.item_value_b - player.bid_amount_B else: player.payoff_b = 0 group_m = player.group if player.is_winner_m: player.payoff_m = group_m.item_value_m - player.bid_amount_M else: player.payoff_m = 0 group = player.group if player.is_winner_b: if player.is_winner_m: player.payoff = player.payoff_b + player.payoff_m + group.synergy else: player.payoff = player.payoff_b else: if player.is_winner_m: player.payoff = player.payoff_m else: player.payoff = 0 # PAGES class Introduction(Page): @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group player.item_value_estimate_b = generate_value_estimate_b(group) player.item_value_estimate_m = generate_value_estimate_m(group) class Bid(Page): form_model = 'player' form_fields = ['bid_amount_B'] class BidM(Page): form_model = 'player' form_fields = ['bid_amount_M'] class ResultsWaitPage(WaitPage): after_all_players_arrive = set_winner_b class Results(Page): @staticmethod def vars_for_template(player: Player): return dict(is_greedy=player.payoff_b + player.payoff_m < 0) page_sequence = [Introduction, Bid, BidM, ResultsWaitPage, Results]