from otree.api import Currency as c, currency_range from ._builtin import Page, WaitPage from .models import Constants, Item, Subsession import random class IntroWp(WaitPage): group_by_arrival_time = True def get_players_for_group(self, waiting_players): if len(waiting_players) >= self.subsession.num_sellers + self.subsession.num_buyers: return waiting_players def after_all_players_arrive(self): self.group.set_role() self.group.set_total_round() self.group.set_sequence() self.group.fake_draw() g = self.group sub = self.subsession for p in self.group.get_players(): p.inherit_sequence_payoff() p.clear_sequence_payoff() if self.round_number != 1 : for p in self.group.get_players(): p.allocation_dollar = p.in_round(self.round_number -1).allocation_dollar p.allocation_btc = p.in_round(self.round_number -1).allocation_btc if self.round_number in g.first_round_in_sequence(): for p in g.get_players(): p.allocation_dollar= 0.0 p.allocation_dollar_save = 0.0 p.allocation_btc = 0.0 p.allocation_btc_save = 0.0 else: if self.subsession.inflation_on == 1: for p in g.get_players(): p.allocation_dollar = round(p.allocation_dollar*(1+self.subsession.inflation_rate),2) class WorkPage(Page): _allow_custom_attributes = True form_model = 'player' form_fields = ['allocation_unit_dollar','allocation_unit_btc','allocation_dollar','allocation_btc','allocation_dollar_save','allocation_btc_save'] timer_text = 'Time left to complete the task:' def get_timeout_seconds(self): return self.subsession.time_per_round_currency def is_displayed(self): display = 0 if self.player.role() == 'seller': display = 1 if self.round_number in self.group.first_round_in_sequence(): if self.player.role() =='buyer': self.player.allocation_dollar = Constants.buyer_dollar_endowment self.player.allocation_dollar_save = 0 self.player.allocation_btc = Constants.buyer_btc_endowment self.player.allocation_btc_save = 0 return display def get_form_fields(self): if self.player.role() =='seller': return ['allocation_unit_dollar','allocation_unit_btc'] elif self.player.role() =='buyer': return ['allocation_dollar','allocation_btc','allocation_dollar_save','allocation_btc_save'] def vars_for_template(self): return { 'allocation_unit_dollar_label': 'How many units will you allocate to Currency A auction house (from {} to {})?'.format(0,Constants.seller_endowment), 'allocation_dollar_label': 'How many dollars will you allocate to Currency A auction house (from {} to {})?'.format(0,Constants.buyer_dollar_endowment), 'allocation_unit_btc_label': 'Number of units to be sold in Currency B auction house (from {} to {})'.format(0,Constants.seller_endowment), 'allocation_btc_label': 'How many bitcoins will you allocate to Currency B auction house (from {} to {})?'.format( 0,Constants.buyer_btc_endowment), 'allocation_dollar_save_label': 'Amount of dollar remaining for saving', 'allocation_btc_save_label': 'Amount of bitcoins remaining for saving' } def before_next_page(self): if self.timeout_happened: if self.player.role() =='buyer': self.player.allocation_dollar = Constants.buyer_dollar_endowment self.player.allocation_dollar_save = 0 self.player.allocation_btc = Constants.buyer_btc_endowment self.player.allocation_btc_save = 0 elif self.player.role() =='seller': self.player.allocation_unit_dollar = Constants.seller_endowment self.player.allocation_unit_btc = 0 class GeneratingInitialsWP(WaitPage): def after_all_players_arrive(self): g = self.group sub = self.subsession for s in g.get_sellers(): # we create slots for both sellers and buyers, but for sellers we fill them with items # and also pregenerate costs. For buyers they are initially empty for i in range(s.allocation_unit_btc): #slot = s.slots.create(cost=random.randint(sub.seller_cost_lb, sub.seller_cost_ub)) slot = s.slots.create(cost=0,BTC=True) item = Item(slot=slot, quantity=Constants.initial_quantity) item.save() for i in range(s.allocation_unit_dollar): #slot = s.slots.create(cost=random.randint(sub.seller_cost_lb, sub.seller_cost_ub)) slot = s.slots.create(cost=0,BTC=False) item = Item(slot=slot, quantity=Constants.initial_quantity) item.save() s.set_units(True) s.set_units(False) for b in g.get_buyers(): for i in range(sub.units_per_buyer): if i <=9: b.slots.create(value=75,BTC=True) b.slots.create(value=100-i*10,BTC=False) elif i <=18: b.slots.create(value=75,BTC=True) b.slots.create(value=10-(i-9)*1,BTC=False) else: b.slots.create(value=75,BTC=True) b.slots.create(value=1,BTC=False) b.allocation_unit_btc = 0 b.allocation_unit_dollar = 0 b.set_units(True) b.set_units(False) class Market(Page): def get_timeout_seconds(self): return self.subsession.time_per_round def is_displayed(self): if self.group.After_CE == False: return 1 if self.group.After_CE == True and self.subsession.currency_exchange_on == 0: return 0 elif self.group.After_CE == True and self.subsession.currency_exchange_on == 1: player_active = self.player.active_btc or self.player.active_dollar return player_active and self.group.active def vars_for_template(self): c = self.player.get_form_context(True) c['asks'] = self.group.get_asks(False) c['bids'] = self.group.get_bids(False) c['asks_btc'] = self.group.get_asks(True) c['bids_btc'] = self.group.get_bids(True) c['repository'] = self.player.get_repo_context(False) c['repository_btc'] = self.player.get_repo_context(True) c['contracts'] = self.player.get_contracts_queryset(False) c['contracts_btc'] = self.player.get_contracts_queryset(True) c['page_index'] = self.participant._index_in_pages # prepare an json object for highchart. here is an example # history_output = [player1,player2,player3,....] playeri = {'data':[output in round1, 2, 3,4...],'name':`Firm1'} Euro = [] # print('players: ',self.get_others_in_group()) Euro.append({}) Euro[0]['data'] = [] Euro[0]['name'] = 'Earnings in ' + self.player.Currency_name() for i in range(1,1001): Euro[0]['data'].append(round((i)**0.5/10,2)) c['Euro'] = Euro return c def before_next_page(self): self.player.thisround_btc = 0 self.player.thisround_dollar = 0 self.player.thisstage_profit = 0 self.group.After_CE = True class ResultsWaitPage(WaitPage): def after_all_players_arrive(self): self.group.clear_ask_bid() pass class CurrencyPage(Page): _allow_custom_attributes = True form_model = 'player' form_fields = ['exchange_dollar','exchange_btc','currency_option'] timer_text = 'Time left to complete the task:' def get_timeout_seconds(self): return self.subsession.time_per_round_currency def is_displayed(self): if self.subsession.currency_exchange_on == 1: displayed = 1 else: for p in self.group.get_players(): p.exchange_btc = 0 p.exchange_dollar = 0 displayed = 0 return displayed def vars_for_template(self): return { 'exchange_dollar_label': 'How many Currency A do you want to exchange (from {} to {})?'.format(0.01,self.player.allocation_dollar), 'exchange_btc_label': 'How many Currency B do you want to exchange (from {} to {})?'.format(0.01,self.player.allocation_btc) } def before_next_page(self): if self.timeout_happened: self.player.exchange_btc = 0 self.player.exchange_dollar = 0 if self.player.currency_option == 0: self.player.exchange_btc = 0.0 elif self.player.currency_option == 1: self.player.exchange_dollar = 0.0 elif self.player.currency_option == 2: self.player.exchange_btc = 0 self.player.exchange_dollar = 0 class ResultsWaitPage2(WaitPage): body_text = "Waiting for the other participant to decide." def after_all_players_arrive(self): self.group.exchange_currency() self.group.reactive() class CurrencyResultPage(Page): timer_text = 'Time left to complete the task:' def get_timeout_seconds(self): return self.subsession.time_per_round_currency def is_displayed(self): if self.subsession.currency_exchange_on == 1: displayed = 1 else: displayed = 0 return displayed class ResultsWaitPage3(WaitPage): body_text = "Waiting for the other participant to decide." class ResultsWaitPage4(WaitPage): body_text = "Waiting for the other participant to decide." def after_all_players_arrive(self): for p in self.group.get_players(): p.set_sequence_payoff() p.set_payoff() class SequencePage(Page): timer_text = 'Time left to complete the task:' ''' def is_displayed(self): if self.round_number in self.group.final_round_in_sequence(): displayed = 1 else: displayed = 0 return displayed ''' def get_timeout_seconds(self): return self.subsession.time_per_round_currency def before_next_page(self): if self.timeout_happened: self.player.no_action1 = True class Dropout(Page): timer_text = 'Time Remaining before dropping out of the experiment' form_model = 'player' form_fields = [] timeout_seconds = 60 def is_displayed(self): if self.player.no_action1 == True and self.subsession.drop_player_on == 1: return True else: return False def before_next_page(self): if self.timeout_happened: self.player.drop_one() class ResultsWaitPage5(WaitPage): body_text = "Waiting for the other participant to decide." class Termination(Page): timer_text = 'Time left to complete the task:' def is_displayed(self): if self.player.disconnection_flag !=0: self.player.set_payment_message() displayed = 1 else: displayed = 0 return displayed def app_after_this_page(self, upcoming_apps): if self.player.disconnection_flag != 0: return upcoming_apps[0] class PaymentPage(Page): timer_text = 'Time left to complete the task:' def is_displayed(self): if self.round_number == self.group.total_round: self.player.set_payment_message() displayed = 1 else: displayed = 0 return displayed def app_after_this_page(self, upcoming_apps): if self.round_number == self.group.total_round: return upcoming_apps[0] page_sequence = [ IntroWp, WorkPage, GeneratingInitialsWP, Market, ResultsWaitPage, CurrencyPage, ResultsWaitPage2, CurrencyResultPage, ResultsWaitPage3, Market, ResultsWaitPage4, SequencePage, Dropout, ResultsWaitPage5, Termination, PaymentPage, ]