#------------------------------------- # #------------------------------------- from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random import math import openpyxl # should not use xlrd to read xlsx files. use: openpyxl and read_excel("my.xlsx",engine='openpyxl') import pandas import numpy as np import statistics author = 'Michael' doc = """ This is a study on investor behavior. """ #------------------------------------- # Basic inputs (parameters, distribution) #------------------------------------- class Constants(BaseConstants): name_in_url = 'MRE1' players_per_group = None num_rounds = 10 # how many rounds does a one player play num_years = 20 # years of one simulation num_distributions = 12000 # number of rows in the returns excel sheet begin_row = 1 # read the samples from return distributions sheet = pandas.read_excel('MRE1/r_distributions_MRE1.xlsx', engine='openpyxl') #This turns the excel file into a pandas dataframe sheet= sheet.dropna(axis=0, how="all", inplace=False) #drops NAn values sheet= sheet.dropna(axis=1, how="all", inplace=False) #drops NAn values distributions = {} #creates the distribution dictionary for distr in range(num_distributions): #fills the dict with the data distributions[distr] = [] for year in range(num_years): distributions[distr].append([sheet.iloc[distr+begin_row, [year]].iloc[0], 0]) bonus = c(10) #Dicts with the questions and answers used in the experiment question_dict = [ 'BeliefsDependence_Mu1','BeliefsDependence_PLoss1'] short_q_dict = ['the average return of the asset '] #------------------------------------- # Allocate treatments #------------------------------------- class Subsession(BaseSubsession): def creating_session(self): # Allocate the distributions for each player ---------------------------------------------------------- # allocation of distributions is done at round 1. if self.round_number == 1: def apply_arrangement(lst, a): return [lst[i] for i in a] # allocate the distributions i_low, i_high = 0, Constants.num_rounds - 1 for p in self.get_players(): # Determine the payoff p.paid_subsection = random.randint(1,Constants.num_rounds) # for each participant create a list [d1,d2,...dnum_rounds], s.t. d1 = Constants.distributions[i] (the i:th joint distribution) p.participant.vars['distributions'] = [] p.participant.vars['distribution_ids'] = [] p.participant.vars['pair_order'] = [] treatment_key = (p.participant.id_in_session - 1) % 4 + 1 # integer from 1 to 4 p.participant.vars["goal_treatment"] = treatment_key # 1: Summary screen + investment incentivized, 2: Summary screen + prediction incentivized, 3: no Summary screen + investment incetivized, 4: no Summary screen + prediction incentivized p.goal_treatment = p.participant.vars["goal_treatment"] if p.goal_treatment == 2 or 4: p.random_question_index = 1 # random.randint(1, 2) p.short_q = Constants.short_q_dict[p.random_question_index - 1] else: p.random_question_index = 1000 p.short_q = '' for distr_id in range(i_low,i_high+1): po = [0,1] p.participant.vars['pair_order'].append(po) round_i_distr = [] #print(Constants.distributions[distr_id]) for pair in Constants.distributions[distr_id]: round_i_distr.append(apply_arrangement(pair,po)) p.participant.vars['distributions'].append(round_i_distr) # p.participant.vars['distributions'].append(Constants.distributions[distr_id]) # OLD, no pairwise randomization p.participant.vars['distribution_ids'].append(distr_id) i_low += Constants.num_rounds i_high += Constants.num_rounds # Save treatment value, sampling pairs, order of sample etc. to fields in database--------------------- for p in self.get_players(): p.distribution_id = p.participant.vars['distribution_ids'][self.round_number-1] this_round_distr = p.participant.vars['distributions'][self.round_number-1] p.distribution = ' '.join([str(pair).replace(',',' ') for pair in this_round_distr]) round_pair_order = p.participant.vars['pair_order'][self.round_number-1] p.pair_order = ' '.join([str(i) for i in round_pair_order]) #DIRECT COPY FROM PDE3 PROB INCLUDES A LOT OF UNNESSARY STUFF BUT ALSO SOMETHING THAT WE NEED dataArray = p.participant.vars['distributions'][self.round_number - 1] num_ret1_neg = 0 num_ret1_pos = 0 num_ret1_neg_ret2_pos = 0 num_ret1_pos_ret2_pos = 0 ret2_outperf_ret1 = 0 num_ret2_neg = 0 asset1Arr = [] asset2Arr = [] for i in range(len(dataArray)): asset1Arr.append(dataArray[i][0]) asset2Arr.append(dataArray[i][1]) if dataArray[i][0] < 0: num_ret1_neg = num_ret1_neg + 1 if dataArray[i][1] < 0: num_ret2_neg = num_ret2_neg + 1 if dataArray[i][0] > 0: num_ret1_pos = num_ret1_pos + 1 if dataArray[i][0] < 0 and dataArray[i][1] > 0: num_ret1_neg_ret2_pos = num_ret1_neg_ret2_pos + 1 if dataArray[i][0] > 0 and dataArray[i][1] > 0: num_ret1_pos_ret2_pos = num_ret1_pos_ret2_pos + 1 if dataArray[i][1] > dataArray[i][0]: ret2_outperf_ret1 = ret2_outperf_ret1 + 1 p.BeliefsDependence_Mu1_Res = statistics.mean(asset1Arr)*100 #p.BeliefsDependence_PLoss1_Res = (num_ret1_neg / 20)*100 class Group(BaseGroup): pass class Player(BasePlayer): # Treatment related --------------------------------- distribution_id = models.IntegerField() distribution = models.LongStringField() pair_order = models.LongStringField() goal_treatment = models.IntegerField() # Payment related ----------------------------------- paid_subsection = models.PositiveIntegerField() # 1,..,or num_rounds to be paid paid_rendite1 = models.FloatField() paid_rendite2 = models.FloatField() payoff_100 = models.CurrencyField() random_question_index = models.IntegerField() short_q = models.CharField() # Other information -------------------------- browser_first = models.CharField() browser_last = models.CharField() #------------------------------------- # Tasks - Investment decision(s) #------------------------------------- # Player fills ----------------------------------- InvestmentAsset1 = models.CurrencyField( # initial=None, label='How much out of the £10\xa0000 do you invest into the asset?', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset2 = models.CurrencyField( label='How much out of the £10\xa0000 do you invest into cash?', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentEitherOr = models.CharField(initial=None, choices=['Asset', 'Cash', 'Indifferent (both assets are equally attractive)'], verbose_name='Alternatively: If you had to invest the full £10\xa0000 into either asset or cash (without the option to split the investment between the two options), which option would you select?', widget=widgets.RadioSelectHorizontal()) #------------------------------------- # Tasks - Beliefs about dependence #------------------------------------- # NOT USED # 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") und 5 ("most of the time together").', # choices=range(1, 6), # initial=None, # widget=widgets.RadioSelectHorizontal() # ) # NOT USED # 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() # ) # NOT USED # 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() # ) # NOT USED # 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, # ) # NOT USED # 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 # ) # NOT USED # 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 the asset to be ... (in %, e.g., 10 for 10%)', min=-40, max=50, ) #CASH WILL ALWAYS HAVE 0 RETURN SO NOT USED #BeliefsDependence_Mu2 = models.FloatField( # label='Cash will always have a return of 0%' #) # 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 the asset to realize a loss (negative return) in ... out of 100 cases.', # min=0, max=100 #) #ANSWERS FOR BELEIFS BeliefsDependence_Mu1_Res = models.FloatField( min=-100, max=150, ) BeliefsDependence_PLoss1_Res = models.FloatField( min=0, max=100, ) #CASH SO NOT USED #BeliefsDependence_PLoss2 = models.IntegerField( # label='Cash will cannot realize a loss or a gain', # min=0, max=0 # ) # 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_Risk1 = models.PositiveIntegerField( label='How risky is the asset? Please select a category between 1 ("risk-free") and 7 ("very risky").', choices=range(1, 8), initial=None, widget=widgets.RadioSelectHorizontal() ) # NOT USED # 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 one year from now, given your investment decision (in £)?', # min=0, max=1000000 # ) # NOT USED # BeliefsPortfolio_Mu = models.FloatField( # label='I expect the return of my portfolio to be... (in %, e.g., 10 for 10%)' # ) # NOT USED # BeliefsPortfolio_PLoss = models.IntegerField( # label='I expect my portfolio to realize a loss (negative return) in ... out of 100 cases', # min=0, max=100 # ) # NOT USED # 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 # ) # NOT USED # 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 # ) # NOT USED # 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 #------------------------------------- # NOT USED # ''' # # 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 allocation.', ) # # 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 #------------------------------------- paid_input1 = models.CurrencyField() paid_input2 = models.CurrencyField() # Determin the payoff def set_payoffs(self): goal_treatment = self.participant.vars["goal_treatment"] if goal_treatment == 1 or goal_treatment == 3: payoff_distribution = self.participant.vars['distributions'][self.in_round(1).paid_subsection-1] payoff_return_pair = payoff_distribution[random.randint(0,len(payoff_distribution)-1)] self.paid_rendite1 = payoff_return_pair[0] self.paid_rendite2 = payoff_return_pair[1] self.paid_input1 = self.in_round(self.in_round(1).paid_subsection).InvestmentAsset1 # How much participant invested in payoff round to asset1 self.paid_input2 = 10000 -self.paid_input1 #print("payoff_wr") payoff = (self.paid_input1 * (1 + payoff_return_pair[0]) + self.paid_input2 * (1 + payoff_return_pair[1]))/10000 # print(payoff) # print("gt") # print(goal_treatment) self.payoff = payoff #this to $payment port_value = self.paid_input1 * (1 + payoff_return_pair[0]) + self.paid_input2 * (1 + payoff_return_pair[1]) self.payoff_100 = port_value else: index_temp = self.in_round(1).random_question_index questions = [self.in_round(self.in_round(1).paid_subsection).BeliefsDependence_Mu1] answers = [self.in_round(self.in_round(1).paid_subsection).BeliefsDependence_Mu1_Res] # print("questions") # print(questions[index_temp - 1]) self.payoff = max(0, 1.5 - abs(questions[index_temp - 1] - answers[index_temp - 1]) * 0.10) self.payoff_100 = max(0, 1.5 - abs(questions[index_temp - 1] - answers[index_temp - 1]) * 0.10) * 10000 def pay_round_num(self): return self.in_round(1).paid_subsection #----------------------------------------- # Directly after two rounds - Comparison of two rounds #----------------------------------------- # NOT USED # ''' # 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 return of the asset?', choices=[ [1, 'No'], [2, 'Yes'],], widget=widgets.RadioSelectHorizontal()) GenReasons_Mu_Direction = models.IntegerField( initial=None, verbose_name='You considered the average return of the asset: Would you decrease or increase your investment into an asset 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 riskiness of the asset?', choices=[ [1, 'No'], [2, 'Yes'],], widget=widgets.RadioSelectHorizontal()) GenReasons_SigmaPL_Direction = models.IntegerField( initial=None, verbose_name='You considered the riskiness of the asset: Would you decrease or increase your investment into an asset with a higher riskiness?', 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 asset and cash (e.g., whether cash tends to perform well when Asset 1 performs badly and, vice versa, whether Asset 1 tends to perform well when cash performs badly)?', 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 probability of a loss (likelihood that the return is negative) of the asset?', choices=[ [1, 'No'], [2, 'Yes'],], widget=widgets.RadioSelectHorizontal()) GenReasons_PD_Direction = models.IntegerField( initial=None, verbose_name='You considered the probability of a loss of the asset: Would you decrease or increase your investment into an asset with a higher probability of a loss?', 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.',)