from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random random.seed(107) author = 'Claudia Marangon, Alexia Gaudeul' doc = """ Stock Experiment """ class Constants(BaseConstants): name_in_url = 'soft_treatment_automatic_reverted_robo_adviser' players_per_group = None num_rounds= 3*21+3 end = c(350) blocked_r= [3, 5, 7, 9, 11, 13, 15, 17, 19, 21] blocked_last_r =[i+44 for i in blocked_r] start_second_phase = 23 start_third_phase = 45 seq_dict = {} eight_hours = 8*60*60 #8*60*60 instructions_template = 'soft_treatment_automatic/Instructions.html' for i in range(1, 9): seq = {} for n in range(1, num_rounds+1): realiz = {} if n==1 or n==23 or n==45: st_a = random.randint(1, 2) if st_a==1: realiz['state_a']='Good' else: realiz['state_a'] = 'Bad' realiz['update_a']="" realiz['delta_p_a']=0 st_b = random.randint(1, 2) if st_b==1: realiz['state_b']='Good' else: realiz['state_b'] = 'Bad' realiz['update_b']="" realiz['delta_p_b']=0 st_c = random.randint(1, 2) if st_c==1: realiz['state_c']='Good' else: realiz['state_c'] = 'Bad' realiz['update_c']="" realiz['delta_p_c']=0 else: prob1_a = random.randint(1, 10) prob2_a = random.randint(1, 10) if seq[n-1]['state_a'] == 'Good': if prob1_a < 9: realiz['state_a'] = 'Good' else: realiz['state_a'] = 'Bad' else: if prob1_a >= 9: realiz['state_a'] = 'Good' else: realiz['state_a'] = 'Bad' if realiz['state_a'] == 'Good': if prob2_a > 7: realiz['delta_p_a'] = -random.choice([5, 10, 15]) else: realiz['delta_p_a'] = random.choice([5, 10, 15]) else: if prob2_a > 7: realiz['delta_p_a'] = random.choice([5, 10, 15]) else: realiz['delta_p_a'] = -random.choice([5, 10, 15]) prob1_b = random.randint(1, 10) prob2_b = random.randint(1, 10) if seq[n-1]['state_b'] == 'Good': if prob1_b < 9: realiz['state_b'] = 'Good' else: realiz['state_b'] = 'Bad' else: if prob1_b >= 9: realiz['state_b'] = 'Good' else: realiz['state_b'] = 'Bad' if realiz['state_b'] == 'Good': if prob2_b > 7: realiz['delta_p_b'] = -random.choice([5, 10, 15]) else: realiz['delta_p_b'] = random.choice([5, 10, 15]) else: if prob2_b > 7: realiz['delta_p_b'] = random.choice([5, 10, 15]) else: realiz['delta_p_b'] = -random.choice([5, 10, 15]) prob1_c = random.randint(1, 10) prob2_c = random.randint(1, 10) if seq[n-1]['state_c'] == 'Good': if prob1_c < 9: realiz['state_c'] = 'Good' else: realiz['state_c'] = 'Bad' else: if prob1_c >= 9: realiz['state_c'] = 'Good' else: realiz['state_c'] = 'Bad' if realiz['state_c'] == 'Good': if prob2_c > 7: realiz['delta_p_c'] = -random.choice([5, 10, 15]) else: realiz['delta_p_c'] = random.choice([5, 10, 15]) else: if prob2_c > 7: realiz['delta_p_c'] = random.choice([5, 10, 15]) else: realiz['delta_p_c'] = -random.choice([5, 10, 15]) # price_update = random.randint(1, 3) # if price_update == 1: # realiz['update'] = 'a' # elif price_update == 2: # realiz['update'] = 'b' # else: # realiz['update'] = 'c' seq[n] = realiz seq_dict[i]= seq class Subsession(BaseSubsession): def creating_session(self): if self.round_number==1: for p in self.get_players(): #n=random.randint(1,6) n=p.id_in_group%8+1 p.participant.vars['realization_sequence'] = Constants.seq_dict[n] p.price_a = 100 p.price_b = 100 p.price_c = 100 p.prob_a =0.5 p.prob_b =0.5 p.prob_c =0.5 p.z_a = 0 p.z_b = 0 p.z_c = 0 p.state_a=p.participant.vars['realization_sequence'][self.round_number]['state_a'] p.state_b=p.participant.vars['realization_sequence'][self.round_number]['state_b'] p.state_c=p.participant.vars['realization_sequence'][self.round_number]['state_c'] p.in_round(Constants.num_rounds).payoff_part=random.randint(1,3) #variable that determines from which part of the experiment the payoff is computed p.cash=Constants.end p.price_bought_a = p.price_a p.price_bought_b = p.price_b p.price_bought_c = p.price_c else: for p in self.get_players(): p.state_a=p.participant.vars['realization_sequence'][self.round_number]['state_a'] p.state_b=p.participant.vars['realization_sequence'][self.round_number]['state_b'] p.state_c=p.participant.vars['realization_sequence'][self.round_number]['state_c'] #p.stock_update=p.participant.vars['realization_sequence'][self.round_number]['update'] delta_p_a=p.participant.vars['realization_sequence'][self.round_number]['delta_p_a'] delta_p_b=p.participant.vars['realization_sequence'][self.round_number]['delta_p_b'] delta_p_c=p.participant.vars['realization_sequence'][self.round_number]['delta_p_c'] p.stock_a = 1 p.stock_b = 1 p.stock_c = 1 p.cash = 0 if self.round_number in [Constants.start_second_phase, Constants.start_third_phase]: p.cash = Constants.end p.price_bought_a = p.price_a p.price_bought_b = p.price_b p.price_bought_c = p.price_c p.price_a = 100#+delta_p p.price_b = 100 p.price_c = 100 p.prob_a =0.5 p.prob_b =0.5 p.prob_c =0.5 p.z_a = 0 p.z_b = 0 p.z_c = 0 else: #p.stock_update='a' p.price_a = p.in_round(self.round_number-1).price_a+delta_p_a p.price_b = p.in_round(self.round_number-1).price_b+delta_p_b p.price_c = p.in_round(self.round_number-1).price_c+delta_p_c if delta_p_a>0 : p.z_a =1 else: p.z_a =-1 if delta_p_b>0 : p.z_b =1 else: p.z_b =-1 if delta_p_c>0 : p.z_c =1 else: p.z_c =-1 p.pz_a = (0.5+0.2*p.z_a)*(0.8*p.in_round(self.round_number-1).prob_a+0.2*(1-p.in_round(self.round_number-1).prob_a))+(0.5-0.2*p.z_a)*(0.2*p.in_round(self.round_number-1).prob_a+0.8*(1-p.in_round(self.round_number-1).prob_a)) p.pz_b = (0.5+0.2*p.z_b)*(0.8*p.in_round(self.round_number-1).prob_b+0.2*(1-p.in_round(self.round_number-1).prob_b))+(0.5-0.2*p.z_b)*(0.2*p.in_round(self.round_number-1).prob_b+0.8*(1-p.in_round(self.round_number-1).prob_b)) p.pz_c = (0.5+0.2*p.z_c)*(0.8*p.in_round(self.round_number-1).prob_c+0.2*(1-p.in_round(self.round_number-1).prob_c))+(0.5-0.2*p.z_c)*(0.2*p.in_round(self.round_number-1).prob_c+0.8*(1-p.in_round(self.round_number-1).prob_c)) p.prob_a = (0.5+0.2*p.z_a)*(0.8*p.in_round(self.round_number-1).prob_a+0.2*(1-p.in_round(self.round_number-1).prob_a))/p.pz_a p.prob_b = (0.5+0.2*p.z_b)*(0.8*p.in_round(self.round_number-1).prob_b+0.2*(1-p.in_round(self.round_number-1).prob_b))/p.pz_b p.prob_c = (0.5+0.2*p.z_c)*(0.8*p.in_round(self.round_number-1).prob_c+0.2*(1-p.in_round(self.round_number-1).prob_c))/p.pz_c pass class Group(BaseGroup): pass class Player(BasePlayer): payoff_part=models.IntegerField() payoff_period=models.CurrencyField() codice_lab = models.IntegerField( label="Inserisci l'ID di 2 cifre che ti รจ stato assegnato in laboratorio:" ) price_a = models.CurrencyField() price_b = models.CurrencyField() price_c = models.CurrencyField() z_a = models.FloatField() z_b = models.FloatField() z_c = models.FloatField() pz_a = models.FloatField() pz_b = models.FloatField() pz_c = models.FloatField() prob_a = models.FloatField() prob_b = models.FloatField() prob_c = models.FloatField() state_a = models.StringField( choices=['Good', 'Bad'] ) state_b = models.StringField( choices=['Good', 'Bad'] ) state_c = models.StringField( choices=['Good', 'Bad'] ) stock_a_rec = models.StringField( choices=['Compra', 'Non Comprare', 'Vendi', 'Non Vendere'] ) stock_b_rec = models.StringField( choices=['Compra', 'Non Comprare', 'Vendi', 'Non Vendere'] ) stock_c_rec = models.StringField( choices=['Compra', 'Non Comprare', 'Vendi', 'Non Vendere'] ) # stock_update = models.StringField( # choices=['a', 'b', 'c'], # initial='a' # ) stock_a_buy = models.StringField( choices=["Compra", "Non Comprare"], label="Puoi acquistare it titolo A:", #blank=True, widget= widgets.RadioSelect, ) stock_b_buy = models.StringField( choices=["Compra", "Non Comprare"], widget=widgets.RadioSelect, #blank=True, label="Puoi acquistare it titolo B:", ) stock_c_buy = models.StringField( choices=["Compra", "Non Comprare"], widget=widgets.RadioSelect, #blank=True, label="Puoi acquistare it titolo C:", ) stock_a_sell = models.StringField( choices=["Vendi", "Non Vendere"], widget=widgets.RadioSelect, #blank=True, label="Puoi vendere it titolo A:" ) stock_b_sell = models.StringField( choices=["Vendi", "Non Vendere"], widget=widgets.RadioSelect, #blank=True, label="Puoi vendere it titolo B:" ) stock_c_sell = models.StringField( choices=["Vendi", "Non Vendere"], widget=widgets.RadioSelect, #blank=True, label="Puoi vendere it titolo C:" ) stock_a = models.IntegerField( choices=[0, 1], ) stock_b = models.IntegerField( choices=[0, 1], ) stock_c = models.IntegerField( choices=[0, 1], ) price_bought_a = models.CurrencyField() price_bought_b = models.CurrencyField() price_bought_c = models.CurrencyField() cash = models.CurrencyField() restrict_last_part=models.StringField( choices=['Con algoritmo', 'Senza algoritmo'], label="In che modo desideri giocare?" ) transaction = models.StringField( choices=['Effettua la Transazione'], blank=True, label='Sei sicuro di volere effettuare una transazione?' ) def prev_round(self): if self.round_number==1: return self.round_number else: m = self.round_number-1 return m def stock_val(self): if self.round_number==1: self.participant.vars['payoff_1'] = 0 self.participant.vars['payoff_2'] = 0 self.participant.vars['payoff_3'] = 0 if self.stock_a_buy=='Compra': self.stock_a=1 cash_a = - self.price_a self.price_bought_a = self.price_a elif self.stock_a_sell=='Vendi': self.stock_a = 0 cash_a = self.price_a self.price_bought_a = 0 else: self.stock_a=self.in_round(self.prev_round()).stock_a cash_a = 0 self.price_bought_a = self.in_round(self.prev_round()).price_bought_a if self.stock_b_buy=='Compra': self.stock_b=1 cash_b = - self.price_b self.price_bought_b = self.price_b elif self.stock_b_sell=='Vendi': self.stock_b = 0 cash_b = self.price_b self.price_bought_b = 0 else: self.stock_b=self.in_round(self.prev_round()).stock_b cash_b = 0 self.price_bought_b = self.in_round(self.prev_round()).price_bought_b if self.stock_c_buy=='Compra': self.stock_c=1 cash_c = - self.price_c self.price_bought_c = self.price_c elif self.stock_c_sell=='Vendi': self.stock_c = 0 cash_c = self.price_c self.price_bought_c = 0 else: self.stock_c=self.in_round(self.prev_round()).stock_c cash_c = 0 self.price_bought_c = self.in_round(self.prev_round()).price_bought_c if self.round_number not in [Constants.start_second_phase, Constants.start_third_phase]: self.cash = self.in_round(self.prev_round()).cash + cash_a + cash_b + cash_c else: self.cash = Constants.end + cash_a + cash_b + cash_c def buy_in_r1(self): #if self.round_number>1: self.stock_a_buy = "Compra" self.stock_b_buy = "Compra" self.stock_c_buy = "Compra" def robo_decision(self): if (self.in_round(self.round_number-1).stock_a==0 and int(100*self.prob_a)>50): self.stock_a_buy = "Compra" if (self.in_round(self.round_number-1).stock_b==0 and int(100*self.prob_b)>50): self.stock_b_buy = "Compra" if (self.in_round(self.round_number-1).stock_c==0 and int(100*self.prob_c)>50): self.stock_c_buy = "Compra" if (self.in_round(self.round_number-1).stock_a==1 and int(100*self.prob_a)<50): self.stock_a_sell = "Vendi" if (self.in_round(self.round_number-1).stock_b==1 and int(100*self.prob_b)<50): self.stock_b_sell = "Vendi" if (self.in_round(self.round_number-1).stock_c==1 and int(100*self.prob_c)<50): self.stock_c_sell = "Vendi" def stock_a_rec(self): if (self.in_round(self.round_number-1).stock_a==0 and int(100*self.prob_a)>50): return "Compra" elif (self.in_round(self.round_number-1).stock_a==0 and int(100*self.prob_a)<=50): return "Non Comprare" elif (self.in_round(self.round_number-1).stock_a==1 and int(100*self.prob_a)<50): return "Vendi" else: return "Non Vendere" def stock_b_rec(self): if (self.in_round(self.round_number-1).stock_b==0 and int(100*self.prob_b)>50): return "Compra" elif (self.in_round(self.round_number-1).stock_b==0 and int(100*self.prob_b)<=50): return "Non Comprare" elif (self.in_round(self.round_number-1).stock_b==1 and int(100*self.prob_b)<50): return "Vendi" else: return "Non Vendere" def stock_c_rec(self): if (self.in_round(self.round_number-1).stock_c==0 and int(100*self.prob_c)>50): return "Compra" elif (self.in_round(self.round_number-1).stock_c==0 and int(100*self.prob_c)<=50): return "Non Comprare" elif (self.in_round(self.round_number-1).stock_c==1 and int(100*self.prob_c)<50): return "Vendi" else: return "Non Vendere" def set_payoff(self): self.payoff_period = self.cash + self.stock_a * self.price_a + self.stock_b * self.price_b + self.stock_c * self.price_c #if self.round_number>22 and self.round_number<=43: if self.round_number>=Constants.start_second_phase and self.round_number