# this is copy of PRE2 # ------------------------------------- # # ------------------------------------- from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random import math import openpyxl import pandas as pd import numpy as np def apply_arrangement(lst, a): return [lst[i] for i in a] author = 'Michael' doc = """ This is a study on investor behavior. """ # ------------------------------------- # Basic inputs (parameters, distribution) # ------------------------------------- class Constants(BaseConstants): name_in_url = 'PRE2' players_per_group = None num_rounds = 2 num_page = 1 # own constants begin_row = 1 num_rows = 50 total_amount = 10000 n_participants = 8 return_max_weight_tr1 = np.array([0, 1]) return_max_weight_tr2 = np.array([0, 1]) risk_min_weight_tr1 = np.array([0.7, 0.3]) risk_min_weight_tr2 = np.array([1, 0]) # read the samples from return distributions sheet = pd.read_excel("PRE2/r_distributions_PRE2.xlsx", engine='openpyxl', usecols="A:D") low_cor_rets = sheet.iloc[:, [0, 1]].to_numpy() high_cor_rets = sheet.iloc[:, [2, 3]].to_numpy() # sheet= sheet.dropna(axis=0, how="all", inplace=False) # sheet= sheet.dropna(axis=1, how="all", inplace=False) # for row_index in range(begin_row, begin_row + num_rows): # nied_korr[row_index - begin_row] = [sheet.iloc[row_index, [0]].iloc[0], sheet.iloc[row_index, [1]].iloc[0]] # 1 indicates column B in the excel sheet # hoeh_korr[row_index - begin_row] = [sheet.iloc[row_index, [2]].iloc[0], sheet.iloc[row_index, [3]].iloc[0]] # read as: "FirstCorrelation_PortfolioReturn_Insentivization" treatment_names = {1: "Low_Pr_ReG", 2: "Low_Pr_RiG", 3: "Low_Pr_Self", 4: "Low_Pr_Own", 5: "Hi_Pr_ReG", 6: "Hi_Pr_RiG", 7: "Hi_Pr_Self", 8: "Hi_Pr_Own", 9: "Low_nPr_ReG", 10: "Low_nPr_RiG", 11: "Low_nPr_Self", 12: "Low_nPr_Own", 13: "Hi_nPr_ReG", 14: "Hi_nPr_RiG", 15: "Hi_nPr_Self", 16: "Hi_nPr_Own"} endowment = c(100) bonus = c(10) # ------------------------------------- # Allocate treatments # ------------------------------------- class Subsession(BaseSubsession): def creating_session(self): if self.round_number == 1: # grouping takes place only in the first round for p in self.get_players(): # assign payoff round p.participant.vars["paid_subsection"] = random.randint(1, 2) p.paid_subsection = p.participant.vars["paid_subsection"] # assign treatment. Treatment are assigned as: # 1: treatment_key = (p.participant.id_in_session - 1) % 16 + 1 # integer from 1 to 16 p.participant.vars["low_first"] = (treatment_key < 5) + 0 or ( 13 > treatment_key > 8) + 0 # 1: low correaltion first, 0: high correlation first p.low_first = p.participant.vars["low_first"] p.participant.vars["format"] = ( treatment_key < 9) + 0 # 1: with Portfoliorenditen; 0: without Portfoliorenditen p.format = p.participant.vars["format"] p.participant.vars["goal_treatment"] = ( treatment_key - 1) % 4 + 1 # 1: max return goal, 2 = min risk goal, 3 = self-selection, 4 = own preferences p.goal_treatment = p.participant.vars["goal_treatment"] p.treatment_key = treatment_key # assign return distributions order_low_cor = random.sample(range(0, 2), 2) p.participant.vars["order_low_cor"] = order_low_cor p.participant.vars["low_cor_returns"] = random.sample(Constants.low_cor_rets[:, order_low_cor].tolist(), Constants.num_rows) p.participant.vars["low_cor_returns"].extend( random.sample(Constants.low_cor_rets[:, order_low_cor].tolist(), Constants.num_rows)) # add retunrs to rounds 50 to 100 order_high_cor = random.sample(range(0, 2), 2) p.participant.vars["order_high_cor"] = order_high_cor p.participant.vars["high_cor_returns"] = random.sample( Constants.high_cor_rets[:, order_high_cor].tolist(), Constants.num_rows) p.participant.vars["high_cor_returns"].extend( random.sample(Constants.high_cor_rets[:, order_high_cor].tolist(), Constants.num_rows)) # add retunrs to rounds 50 to 100 # save return information to database fields p.low_order = str(order_low_cor) p.low_correlation_distribution = ";".join( [str(ret_t) for ret_t in p.participant.vars["low_cor_returns"]]) p.high_order = str(order_high_cor) p.high_correlation_distribution = ";".join( [str(ret_t) for ret_t in p.participant.vars["low_cor_returns"]]) class Group(BaseGroup): pass class Player(BasePlayer): # -------------------------------------- # treatment related # --------------------------------------- treatment_key = models.IntegerField() low_first = models.IntegerField() # 1: low first format = models.IntegerField() goal_treatment = models.IntegerField() paid_subsection = models.PositiveIntegerField() # 1 or 2 (to be paid) paid_rendite1 = models.FloatField() paid_rendite2 = models.FloatField() payoff_100 = models.CurrencyField() browser_first = models.CharField() browser_last = models.CharField() low_order = models.CharField() low_correlation_distribution = models.LongStringField() high_order = models.CharField() high_correlation_distribution = models.LongStringField() SelectedTreatment = models.IntegerField( label="Please, select a portfolio goal", choices=[[1, "My goal is to select a portfolio such that the portfolio has the highest possible expected return (i.e., median return)."], [2, "My goal is to select a portfolio such that the portfolio has the lowest possible risk (i.e., probability of loss)."]], widget=widgets.RadioSelect ) # ------------------------------------- # Tasks - Investment decision(s) # ------------------------------------- # For Group 1 InvestmentAsset2 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) # For Group 2 and 3 -- Round 1 InvestmentAsset20 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset21 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset22 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset23 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset24 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset25 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset26 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset27 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset28 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset29 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) # For Group 2 and 3 -- Round 2 InvestmentAsset210 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset211 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset212 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset213 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset214 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset215 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset216 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset217 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset218 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset219 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset220 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset221 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset222 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset223 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset224 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset225 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset226 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset227 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset228 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset229 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset230 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset231 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset232 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset233 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset234 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset235 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset236 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset237 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset238 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset239 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset240 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset241 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset242 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset243 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset244 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset245 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset246 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset247 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset248 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset249 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset250 = models.CurrencyField( # initial=None, label='Investment into Asset 2', min=0, max=10000, doc=""" Amount invested by this player. """ ) # ------------------------------------- # Tasks - Beliefs about dependence # ------------------------------------- BeliefsDependence_Overall = models.PositiveIntegerField( label='The returns of Asset 1 and Asset 2 move... Please select one of the categories between 1 ("most of the time in opposite directions") and 5 ("most of the time together").', choices=range(1, 6), initial=None, widget=widgets.RadioSelectHorizontal() ) BeliefsDependence_Direction1 = models.CharField(initial=None, choices=['negative', 'zero', 'positive'], verbose_name='If the return of Asset 1 is negative, I expect the return of Asset 2 to be...', widget=widgets.RadioSelectHorizontal() ) # BeliefsDependence_Direction2 = models.CharField(initial=None, # choices=['negative', 'zero','positive'], # verbose_name='If the return of Asset 1 is positive, I expect the return of Asset 2 to be...', # widget=widgets.RadioSelectHorizontal() # ) # BeliefsDependence_FreqComove1 = models.IntegerField( # label='If the return of Asset 1 is negative, I expect Asset 2 to have a positive return in ... out of 100 cases.', # min=0, max=100, # ) BeliefsDependence_FreqComove2 = models.IntegerField( label='If the return of Asset 1 is positive, I expect Asset 2 to have a positive return in ... out of 100 cases.', min=0, max=100 ) # BeliefsDependence_FreqOutperf = models.IntegerField( # label='I expect the return of Asset 2 to be higher than the return of Asset 1 in ... out of 100 cases.', # min=0, max=100 # ) # ------------------------------------- # Tasks - Beliefs about individual assets # ------------------------------------- # NOT USED # BeliefsAssets_Mu = models.CharField(initial=None, # choices=['Asset 1', 'Asset 2','It is around the same for both assets.'], # verbose_name='Which Asset has the higher average return?', # widget=widgets.RadioSelectHorizontal() # ) BeliefsDependence_Mu1 = models.FloatField( label='I expect the return of Asset 1 to be ... (in %, e.g., 10 for 10%)' ) BeliefsDependence_Mu2 = models.FloatField( label='I expect the return of Asset 2 to be ... (in %, e.g., 10 for 10%)' ) # NOT USED # BeliefsAssets_PLoss = models.CharField(initial=None, # choices=['Asset 1', 'Asset 2','It is around the same for both assets.'], # verbose_name='Which Asset has the higher probability of realizing a loss (negative return)?', # widget=widgets.RadioSelectHorizontal() # ) BeliefsDependence_PLoss1 = models.IntegerField( label='I expect Asset 1 to realize a loss (negative return) in ... out of 100 cases.', min=0, max=100 ) BeliefsDependence_PLoss2 = models.IntegerField( label='I expect Asset 2 to realize a loss (negative return) in ... out of 100 cases.', min=0, max=100 ) # NOT USED # BeliefsAssets_Sigma = models.CharField(initial=None, # choices=['Asset 1', 'Asset 2','It is around the same for both assets.'], # verbose_name='Which Asset has the higher return volatility (higher fluctuation in returns)?', # widget=widgets.RadioSelectHorizontal() # ) BeliefsAssets_SubjRisk1 = models.PositiveIntegerField( label='How risky is Asset 1? Please select a category between 1 ("risk-free") and 7 ("very risky").', choices=range(1, 8), initial=None, widget=widgets.RadioSelectHorizontal() ) BeliefsAssets_SubjRisk2 = models.PositiveIntegerField( label='How risky is Asset 2? Please select a category between 1 ("risk-free") and 7 ("very risky").', choices=range(1, 8), initial=None, widget=widgets.RadioSelectHorizontal() ) # ------------------------------------- # Tasks - Beliefs about portfolio return # ------------------------------------- # NOT USED # BeliefsPortfolio_Wealth = models.CurrencyField( # # initial=None, # label='What level of wealth do you expect, given your investment decision (in £)?', # min=0, max=1000000 # ) BeliefsPortfolio_Mu = models.FloatField( label='I expect the return of my portfolio to be... (in %, e.g., 10 for 10%)' ) BeliefsPortfolio_PLoss = models.IntegerField( label='I expect my portfolio to realize a loss (negative return) in ... out of 100 cases', min=0, max=100 ) BeliefsPortfolio_PLGain = models.IntegerField( label='I expect my portfolio to realize a large gain (return above 20%) in ... out of 100 cases', min=0, max=100 ) BeliefsPortfolio_PLLoss = models.IntegerField( label='I expect my portfolio to realize a large loss (return below -10%) in ... out of 100 cases', min=0, max=100 ) BeliefsPortfolio_SubjRisk = models.PositiveIntegerField( label='How risky is your portfolio? Please select a category between 1 ("risk-free") and 7 ("very risky").', choices=range(1, 8), initial=None, widget=widgets.RadioSelectHorizontal() ) # NOT USED # BeliefsPortfolio_Confidence = models.PositiveIntegerField( # label='How confident are you about your investment decision? Please select a category between 1 ("not at all") and 7 ("completely confident").', # choices=range(1, 8), # initial=None, # widget=widgets.RadioSelectHorizontal()) # ------------------------------------- # Tasks - Reasons for investment decision in a specific round # ------------------------------------- # # http://otree.readthedocs.io/en/latest/forms.html#radio-buttons-in-tables-and-other-custom-layouts # RoundSpecificReasons_Free = models.LongStringField( # blank=True, # label='Please describe in short why you made this investment decision.', ) # ''' # RoundSpecificReasons_Intuition = models.PositiveIntegerField( # label='I made an intuitive choice, based on gut feeling.', # choices=range(1, 8), # initial=None, # widget=widgets.RadioSelectHorizontal()) # # RoundSpecificReasons_AssetCompRisk = models.IntegerField( # initial=None, # verbose_name='Which of the following statements describes your view of the two assets?', # choices=[ # [1, 'Individually, Asset 1 was riskier than Asset 2'], # [2, 'Individually, Asset 2 was riskier than Asset 1'], # [3, 'Individually, Assets 1 and 2 were equally risky'], # [4, 'I do not know'], # ] # ) # # RoundSpecificReasons_WeightAndDownsideRisk = models.IntegerField( # initial=None , # verbose_name='How would a change in investment weight affect the downside risks of your portfolio?' , # choices=[ # [1 , 'A lower investment into Asset 2 would increase my probability of loss'] , # [2 , 'A higher investment into Asset 2 would increase my probability of loss'] , # [3 , 'I do not know'] , # ] # ) # # RoundSpecificReasons_WeightAndUpsideChances = models.IntegerField( # initial=None , # verbose_name='How would a change in investment weight affect the upside chances of your portfolio?' , # choices=[ # [1 , 'A lower investment into Asset 2 would increase my probability of gain'] , # [2 , 'A higher investment into Asset 2 would increase my probability of gain'] , # [3 , 'I do not know'] , # ] # ) # # RoundSpecificReasons_2Hedges1 = models.PositiveIntegerField( # label='I like the investment into Asset 2, because Asset 2 often delivers high returns, when Asset 1 delivers low returns, so that losses are offset.' , # choices=range(1 , 8) , # initial=None , # widget=widgets.RadioSelectHorizontal()) # # RoundSpecificReasons_2Amplifies1 = models.PositiveIntegerField( # label='I like the investment into Asset 2, because Asset 2 often delivers high returns, when Asset 1 delivers high returns, so that gains are amplified.' , # choices=range(1 , 8) , # initial=None , # widget=widgets.RadioSelectHorizontal()) # # RoundSpecificReasons_RiskReturnRight = models.PositiveIntegerField( # label='Overally, I think the risk-return-relation of my portfolio is just right.' , # choices=range(1 , 8) , # initial=None , # widget=widgets.RadioSelectHorizontal()) # ''' # ------------------------------------- # Directly after two rounds - Stuff related to payoff # ------------------------------------- # define the payoff round number in the corresponding section (first or second) to be shown to the subjects def pay_round_num(self): return self.in_round(1).paid_subsection paid_input1 = models.CurrencyField() paid_input2 = models.CurrencyField() payoffre1 = models.CurrencyField() payoffre2 = models.CurrencyField() # set the payoff def set_payoffs(self): def payoff_for123(player_investment, optimal_portfolio): investment2 = float(player_investment) investment1 = 10000 - investment2 player_port = np.array([investment1, investment2]) optimal_port = np.array(optimal_portfolio) * 10000 return c(max(0, 2 - abs(player_port[1] - optimal_port[1]) / 5000)) def payoff_for4(joint_returns, player_investment): w2 = float(player_investment/10000) w1 = 1 - w2 sampled_return_pair = random.sample(joint_returns, 1) li = [(sampled_return_pair[0][0]), (sampled_return_pair[0][1]), ((sampled_return_pair[0][0] * w1) + (sampled_return_pair[0][1] * w2))] return li low_first = self.participant.vars['low_first'] payoff_round = self.participant.vars["paid_subsection"] goal_treatment = self.participant.vars["goal_treatment"] player_investment = self.in_round(payoff_round).InvestmentAsset250 self.participant.vars["final_investment_in_asset2"] = player_investment player_weight = float(player_investment / 10000) # Calculate correct payoffs # payoff for risk and return goals if goal_treatment < 4: if goal_treatment == 3: goal_ind = self.in_round(1).SelectedTreatment else: goal_ind = goal_treatment # 1: max return goal, 2 = min risk goal, 3 = self-selection, 4 = own preferences # select optimal portfolios: if payoff_round == 1 and low_first == 1 and goal_ind == 1: optimal_portfolio = Constants.return_max_weight_tr1[self.participant.vars["order_low_cor"]] elif payoff_round == 1 and low_first == 1 and goal_ind == 2: optimal_portfolio = Constants.risk_min_weight_tr1[self.participant.vars["order_low_cor"]] elif payoff_round == 1 and low_first == 1 and goal_ind == 1: optimal_portfolio = Constants.return_max_weight_tr2[self.participant.vars["order_high_cor"]] elif payoff_round == 1 and low_first == 0 and goal_ind == 2: optimal_portfolio = Constants.risk_min_weight_tr2[self.participant.vars["order_high_cor"]] elif payoff_round == 2 and low_first == 1 and goal_ind == 1: optimal_portfolio = Constants.return_max_weight_tr2[self.participant.vars["order_high_cor"]] elif payoff_round == 2 and low_first == 1 and goal_ind == 2: optimal_portfolio = Constants.risk_min_weight_tr2[self.participant.vars["order_high_cor"]] elif payoff_round == 2 and low_first == 0 and goal_ind == 1: optimal_portfolio = Constants.return_max_weight_tr1[self.participant.vars["order_low_cor"]] else: optimal_portfolio = Constants.risk_min_weight_tr1[self.participant.vars["order_low_cor"]] self.participant.vars['optimal_portfolio'] = optimal_portfolio.tolist() self.payoff = payoff_for123(player_investment, optimal_portfolio) # payoff for own preferences else: if payoff_round == 1: if low_first == 1: payoff_returns = self.participant.vars["low_cor_returns"] else: payoff_returns = self.participant.vars["high_cor_returns"] else: if low_first == 1: payoff_returns = self.participant.vars["high_cor_returns"] else: payoff_returns = self.participant.vars["low_cor_returns"] payoff_temp = payoff_for4(payoff_returns, player_investment) self.payoff = (1 + payoff_temp[2]) self.paid_rendite1 = payoff_temp[0] self.paid_rendite2 = payoff_temp[1] # ----------------------------------------- # Directly after two rounds - Comparison of two rounds # ----------------------------------------- ComparisonRounds_Risk = models.IntegerField(initial=None, choices=[ [1, 'My first portfolio is riskier.'], [2, 'My two portfolios are equally risky.'], [3, 'My second portfolio is riskier.'], ], verbose_name='Which of the two portfolios you selected in your first and second round do you assess as riskier?', widget=widgets.RadioSelect()) ComparisonRounds_Return = models.IntegerField(initial=None, choices=[ [1, 'My first portfolio has a higher expected return.'], [2, 'My two portfolios have equally high expected returns.'], [3, 'My second portfolio has a higher expected return.'], ], verbose_name='Which of the two portfolios you selected in your first and second round exhibits higher expected returns?', widget=widgets.RadioSelect()) # ----------------------------------------- # Directly after two rounds - Reasons for investment decision independent of the particular round # ----------------------------------------- GenReasons_Mu_Consider = models.IntegerField( initial=None, verbose_name='Did you consider the average returns of Assets 1 and 2?', choices=[ [1, 'No'], [2, 'Yes'], ], widget=widgets.RadioSelectHorizontal()) GenReasons_Mu_Direction = models.IntegerField( initial=None, verbose_name='You considered average returns of assets: Would you decrease or increase your investment into assets with a higher average return?', choices=[ [1, 'Decrease'], [2, 'Increase'], [3, 'I do not know'], ], widget=widgets.RadioSelectHorizontal()) GenReasons_SigmaPL_Consider = models.IntegerField( initial=None, verbose_name='Did you consider the return volatily (fluctuation in returns or loss probability) of Assets 1 and 2?', choices=[ [1, 'No'], [2, 'Yes'], ], widget=widgets.RadioSelectHorizontal()) GenReasons_SigmaPL_Direction = models.IntegerField( initial=None, verbose_name='You considered return volatilites (fluctuations in returns or loss probabilities) of assets: Would you decrease or increase you investment into assets with a higher return volatility (a higher fluctuation in returns or loss probability)?', choices=[ [1, 'Decrease'], [2, 'Increase'], [3, 'I do not know'], ], widget=widgets.RadioSelectHorizontal()) GenReasons_Rho_Consider = models.IntegerField( initial=None, verbose_name='Did you consider the correlation between the returns of Assets 1 and 2 (e.g., whether Asset 2 tends to perform well when Asset 1 performs badly and, vice versa, whether Asset 2 tends to perform badly when Asset 1 performs well)?', choices=[ [1, 'No'], [2, 'Yes'], ], widget=widgets.RadioSelectHorizontal()) GenReasons_Rho_Direction = models.IntegerField( initial=None, verbose_name='You considered the correlation: Would you decrease or increase you investment into assets with a lower correlation with your overall portfolio (i.e., Assets that go up when your portfolio goes down and down when your portfolio goes up)?', choices=[ [1, 'Decrease'], [2, 'Increase'], [3, 'I do not know'], ], widget=widgets.RadioSelectHorizontal()) # GenReasons_PD_Consider = models.IntegerField( # initial=None, # verbose_name='Did you consider the frequency of outperformance (e.g., the likelihood that the return of Asset 2 is higher than the return of Asset 1)?', # choices=[ # [1, 'No'], # [2, 'Yes'],], # widget=widgets.RadioSelectHorizontal()) # GenReasons_PD_Direction = models.IntegerField( # initial=None, # verbose_name='You considered the frequency of outperformance: Would you decrease or increase your investment into assets with a higher frequency of outperformance?', # choices=[ # [1, 'Decrease'], # [2, 'Increase'], # [3, 'I do not know'],], # widget=widgets.RadioSelectHorizontal()) # ----------------------------------------- # Demographics / Questionnaire - Can partially already be asked before the start of treatments (helps analyze attrition later on) # ----------------------------------------- Demographics_Age = models.PositiveIntegerField( label='What is your age?', min=1, max=130 ) Demographics_Sex = models.IntegerField(initial=None, choices=[ [1, 'Male'], [2, 'Female'], ], verbose_name='Are you male or female?', widget=widgets.RadioSelectHorizontal()) Demographics_FinInterest = models.PositiveIntegerField( label='Are you interested in financial markets? Please select a category between 1 ("not at all") and 7 ("very much").', choices=range(1, 8), initial=None, widget=widgets.RadioSelectHorizontal() ) Demographics_Investor = models.IntegerField( initial=None, verbose_name='Do you own stocks or mutual funds?', choices=[ [1, 'No'], [2, 'Yes'], ] ) Demographics_FinanceProf = models.IntegerField( initial=None, verbose_name='Have you ever had a job in the financial industry?', choices=[ [1, 'No'], [2, 'Yes'], ] ) Demographics_RiskAffinity = models.PositiveIntegerField( verbose_name='Please assess your willingness to take financial risks. Select a category between 1 ("Not willing to take financial risks") and 5 ("Willing to take large risks to achieve a significant gain").', choices=range(1, 6), initial=None, widget=widgets.RadioSelectHorizontal()) Demographics_Statistics = models.PositiveIntegerField( verbose_name='How would you describe your skills in statistics? Please select a category between 1 ("Poor") and 5 ("Excellent").', choices=range(1, 6), initial=None, widget=widgets.RadioSelectHorizontal()) # NOT USED # Demographics_Impatience = models.PositiveIntegerField( # verbose_name='Are you generally rather impatient or patient? Please select a category between 0 ("Very impatient") and 10 ("Very patient").', # choices=range(0, 11), # initial=None, # widget=widgets.RadioSelectHorizontal()) # NOT USED # Demographics_NumberAffinity = models.PositiveIntegerField( # verbose_name='How do you assess the following statement (1="do not agree at all" and 6="fully agree"): I do not enjoy thinking about numerical problems.', # choices=range(1 , 7) , # initial=None , # widget=widgets.RadioSelectHorizontal()) # NOT USED # Demographics_ImportanceNumbers = models.PositiveIntegerField( # verbose_name='How do you assess the following statement (1="do not agree at all" and 6="fully agree"): I think it is important to learn about the correct interpretation of numerical information and to use numerical information to make good choices.', # choices=range(1 , 7) , # initial=None , # widget=widgets.RadioSelectHorizontal()) # ----------------------------------------- # Understanding of diversification benefits # ----------------------------------------- DJ30PF_Return = models.PositiveIntegerField(initial=None, choices=[ [1, 'Higher return for Portfolio A'], [2, 'Higher return for Portfolio B'], [3, 'Same expectations'], ], verbose_name='For which portfolio do you expect a higher return?', widget=widgets.RadioSelectHorizontal()) DJ30PF_Risk = models.PositiveIntegerField(initial=None, choices=[ [1, 'Higher risk for Portfolio A'], [2, 'Higher risk for Portfolio B'], [3, 'Same risk'], ], verbose_name='For which portfolio do you expect higher risk?', widget=widgets.RadioSelectHorizontal()) # ----------------------------------------- # General financial literacy # ----------------------------------------- # NOT USED # ''' # FinLit_1 = models.IntegerField( # initial=None, # verbose_name='The interest rate of your savings account is 1% per year and the inflation rate is 2% per year. What do you think: One year from now, will your savings be worth as much as today, more, or less than today?', # choices=[ # [1, 'More'], # [2, 'As much as today'], # [3, 'Less'], # [4, 'Do not know'], # [5, 'Prefer not to answer'], # ] # ) # # FinLit_2 = models.IntegerField( # initial=None, # verbose_name='True or false? "Bonds are usually riskier than stocks."', # choices=[ # [1, 'True'], # [2, 'False'], # [3, 'Do not know'], # [4, 'Prefer not to answer'], # ] # ) # # FinLit_3 = models.IntegerField( # initial=None, # verbose_name='Which asset typically returns the most over a long investment horizon (for instance 10 or 20 years)?', # choices=[ # [1, 'Savings account'], # [2, 'Stocks'], # [3, 'Bonds'], # [4, 'Do not know'], # [5, 'Prefer not to answer'], # ] # ) # # FinLit_4 = models.IntegerField( # initial=None, # verbose_name='Which asset typically varies the most in value?', # choices=[ # [1, 'Savings account'], # [2, 'Stocks'], # [3, 'Bonds'], # [4, 'Do not know'], # [5, 'Prefer not to answer'], # ] # ) # # FinLit_5 = models.IntegerField( # initial=None, # verbose_name='If an investor splits savings across multiple different assets, how does the risk of large losses change?', # choices=[ # [1, 'It increases'], # [2, 'It decreases'], # [3, 'It stays the same'], # [4, 'Do not know'], # [5, 'Prefer not to answer'], # ] # ) # # FinLit_6 = models.IntegerField( # initial=None, # verbose_name='True or false? "A mutual fund combines investments of many people, to buy a large number of different stocks."', # choices=[ # [1, 'True'], # [2, 'False'], # [3, 'Do not know'], # [4, 'Prefer not to answer'], # ] # ) # # FinLit_7 = models.IntegerField( # initial=None, # verbose_name='True or false? "Returns of individual stocks vary less than returns of mutual funds."', # choices=[ # [1, 'True'], # [2, 'False'], # [3, 'Do not know'], # [4, 'Prefer not to answer'], # ] # ) # # FinLit_8 = models.IntegerField( # initial=None, # verbose_name='Assume you have £100 on a savings account. The account returns 20% per year and ' # 'you do not make any withdrawals (including interest payments). What is the balance ' # 'of your account after five years?', # choices=[ # [1, 'More than £200'], # [2, 'Exactly £200'], # [3, 'Less than £200'], # [4, 'Do not know'], # [5, 'Prefer not to answer'], # ] # ) # # FinLit_9 = models.IntegerField( # initial=None, # verbose_name='Which of the following statements is correct?', # choices=[ # [1, 'After investing into a mutual fund, money cannot be withdrawn within the first year.'], # [2, 'Mutual funds typically invest into multiples stocks.'], # [3, 'Mutual funds guarantee a minimum payment, based on past performance.'], # [4, 'None of the above statements is correct.'], # [5, 'Do not know'], # [6, 'Prefer not to answer'], # ] # ) # # FinLit_10 = models.IntegerField( # initial=None, # verbose_name='Which of the following statements is correct if someone buys a bond of firm B?', # choices=[ # [1, 'The investor owns part of firm B.'], # [2, 'The investor has lent money to firm B.'], # [3, 'The investor is liable for debts of firm B.'], # [4, 'None of the above statements is correct.'], # [5, 'Do not know'], # [6, 'Prefer not to answer'], # ] # ) # ''' # ----------------------------------------- # Numeracy (Berlin numeracy test) # ----------------------------------------- # NOT USED # ----------------------------------------- # Overconfidence questions (overconfidence in performing better than others, or better than objectively true, ...) # ----------------------------------------- # NOT USED # ----------------------------------------- # Susceptibility to framing # ----------------------------------------- # NOT USED # ''' # SusceptibilityFraming_1 = models.PositiveIntegerField( # verbose_name='Psychologists have found that different wordings of the same message, despite unchanged content, ' # 'affect the behavior of people differently. Opinions and choices of people can be manipulated ' # 'with small variations in phrasing. For instance, people are more likely to buy products, which ' # 'are "98% fat free" than products with "2% fat". ' # 'How susceptible are you to such effects? Please describe a category between 1 ("Completely unsusceptible") and 7 ("Highly susceptible")?', # choices=range(1, 8), # initial=None, # widget=widgets.RadioSelectHorizontal()) # # SusceptibilityFraming_2 = models.PositiveIntegerField( # verbose_name='How susceptible are average participants of this experiment for such effects? Please select a category between 1 ("Completely unsusceptible") and 7 ("Highly susceptible")?', # choices=range(1, 8), # initial=None, # widget=widgets.RadioSelectHorizontal()) # ''' # ----------------------------------------- # Final question (satisfaction, feedback...) # ----------------------------------------- Satisfaction = models.PositiveIntegerField( verbose_name='How satisfied are you with your result? Plese select a category between 1 ("Very unsatisfied") and 5 ("Very satisfied")?', choices=range(1, 6), initial=None, widget=widgets.RadioSelectHorizontal()) OpenFeedback = models.LongStringField( blank=True, label='Please describe in short any feedback you might have on this experiment.', ) # ----------------------------------------- # Stuff related to Prolific, mTurk, or other platform used to run the experiment # ----------------------------------------- prolific_id = models.StringField( blank=True, label='Your Prolific ID') # pname = models.StringField( # blank=True, # label='Your Name',) # email = models.StringField( # blank=True, # label='Your e-mail adress',) # # clickerworker = models.LongStringField( # blank=True, # label='Please use this text field to give us feedback for your experiment. Particularly, let us know if you did not understand specific questions.',)