from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random doc = """ Здесь воспроизводим модель аукциона функций предложения. """ class Constants(BaseConstants): name_in_url = 'parks_auction' players_per_group = 5 num_rounds = 5 instructions_template = 'parks_auction/Instructions.html' # Total production capacity of all players total_capacity = 1000 marginal_price = 2 #D(p) = 500-2*p; class Subsession(BaseSubsession): def creating_session(self): playrs = self.get_players() for p in playrs: if self.round_number == 1: for p in playrs: p.marginal_cost = 10 * random.randint(1, 20) p.maximal_capacity = random.randint(1, 300) p.participant.vars['marginal_cost'] = p.marginal_cost p.participant.vars['maximal_capacity'] = p.maximal_capacity else: for p in playrs: p.marginal_cost = p.participant.vars.get('marginal_cost') p.maximal_capacity = p.participant.vars.get('maximal_capacity') pass class Group(BaseGroup): price = models.CurrencyField( doc="""Единая цена, которая установится на рынке""" ) total_units = models.PositiveIntegerField( doc="""Общий объем производства всех участников вашего рынка""" ) def set_payoffs(self): #self.session.vars['r_lower'] = [0] #self.session.vars['r_higher'] = [0] self.total_units = sum([p.maximal_capacity for p in self.get_players()]) #self.price = (Constants.total_capacity - self.total_units )/Constants.marginal_price #if self.price < 0: # self.price = 0 i = 0 jumps = [0] capacities = [0] r_plus = [0] r_minus = [0] added_supply = 0 for p in self.get_players(): jumps.append(p.reserve_price) capacities.append(p.chosen_capacity) for i in range(5): for j in range(5 - i): if jumps[j] > jumps[j + 1]: jumps[j], jumps[j + 1] = jumps[j + 1], jumps[j] capacities[j], capacities[j + 1] = capacities[j + 1], capacities[j] for i in range(5): r_plus.append(r_plus[i]+capacities[i+1]) r_minus.append(r_plus[i]) jumps.append(500) r_plus.append(r_plus[5]) r_minus.append(r_plus[5]) self.session.vars['jumps'] = jumps self.session.vars['r_plus'] = r_plus self.session.vars['r_minus'] = r_minus self.session.vars['capacities'] = capacities for i in range(7): if 1000-2*jumps[i] > r_plus[i]: #на очередной ступеньке верхнее значение меньше спроса continue else:#на очередной ступеньке верхнее значение оказалось не меньше спроса, хотя на предыдущей было меньше if 1000-2*jumps[i] > r_minus[i]:#в точности больше: пересечение на вертикальной части self.price = jumps[i] self.total_units = 1000-2*jumps[i] added_supply = 1000-2*jumps[i] - r_minus[i] break else:#равно: пересечение на горизонтальной части self.total_units = r_minus[i] self.price = 500 - self.total_units/2 break #p.payoff = self.price * p.units - p.marginal_cost*p.units self.session.vars['added_supply'] = added_supply with_same_price = 0 for p in self.get_players(): if p.reserve_price > self.price: p.units = 0 p.payoff = 0 elif p.reserve_price < self.price: p.units = p.chosen_capacity p.payoff = (self.price-p.marginal_cost)*p.units else: p.payoff = 0 with_same_price = with_same_price+1 p.units = added_supply/with_same_price class Player(BasePlayer): units = models.PositiveIntegerField() reserve_price = models.PositiveIntegerField() marginal_cost = models.PositiveIntegerField() maximal_capacity = models.PositiveIntegerField() chosen_capacity = models.PositiveIntegerField() def other_players(self): return self.get_others_in_group()