from otree.api import * import random import time c = Currency doc = """ This is a bond game with 4 players. """ class Constants(BaseConstants): name_in_url = 'bond_games' players_per_group = 4 num_rounds = 10 page1_template = __name__ + '/1Page.html' page2_template = __name__ + '/2Page.html' page3_template = __name__ + '/3Page.html' result_template = __name__ + '/resultPage.html' end_template = __name__ + '/endPage.html' rate_benefit = 5 invest_total = 1000 fixed_income = 5 benefit_fixed_income = 10 level_rate = ['AA', 'AA+', 'AAA'] AAA_possibility = 0.3 AAplus_possibility = 0.4 AA_possibility = 0.3 AAA_rate = 0.045 AAplus_rate = 0.052 AA_rate = 0.06 dis_AAA_rate = 4.5 dis_AAplus_rate = 5.2 dis_AA_rate = 6 AAA_default = 0.01 AAplus_default = 0.05 AA_default = 0.10 dis_AAA_default = 1 dis_AAplus_default = 5 dis_AA_default = 10 AAA_default_rate = 0 AAplus_default_rate = -0.1 AA_default_rate = -0.25 dis_AAA_default_rate = 0 dis_AAplus_default_rate = -10 dis_AA_default_rate = -25 ipo_role = '发行商' rate_role = '评级机构' invest_role = '投资者' financing_income = 0.01 rate_map = {'AA': AA_rate, 'AAA': AAA_rate, 'AA+': AAplus_rate} payoff_trans1 = 6 payoff_trans2 = 6 payoff_trans3 = 12 payoff_trans4 = 12 payoffH = 35 payoffL = 5 formal = 15 c = 0 # ---------------------------------------------------------------------------------------------------------------- # # --- Task-specific Settings --- # # ---------------------------------------------------------------------------------------------------------------- # # number (N) of lotteries with num_lotteries = 5 # sure_payoff; "low" and "high" payoff of the initial lottery (in currency units set in settings.py) # determines the 'starting point' for all lotteries in the single choice list (safe option in i = 1) # outcomes of subsequent lotteries are defined relative to the 'initial value' by the options below sure_payoff = 6 # increments of lottery outcomes (refer to the documentation for more detailed information) # defines the (negative) increment of the low outcome over the number of choices () # similarly, defines the (positive) increment of the high outcome for the choices delta_lo = 1 delta_hi = 2 # probability of lottery outcome "high" (in percent) # refers to the likelihood of outcome denoted in percent (as Integer or Float) # i.e. implies an x%-chance to win the "high" and a (1-x)%-chance to win the "low" payoff # note that the probability in this task is constant for each of the and only outcomes change probability = 50 # additional lottery to separate risk-loving from risk-neutral preferences # if , a lottery with the same expected value but a higher st. dev. as lottery is added # note that implies that the overall number of lotteries rendered will be + 1 risk_loving = True # ---------------------------------------------------------------------------------------------------------------- # # --- Overall Settings and Appearance --- # # ---------------------------------------------------------------------------------------------------------------- # # order choices between lottery pairs randomly # if , the ordering of binary decisions is randomized for display # if , binary choices are listed in ascending order of the probability of the "high" outcome random_order = False # show instructions page # if , a separate template "Instructions.html" is rendered prior to the task # if , the task starts immediately (e.g. in case of printed instructions) instructions = True # show results page summarizing the task's outcome including payoff information # if , a separate page containing all relevant information is displayed after finishing the task # if , the template "Decision.html" will not be rendered results = True class Subsession(BaseSubsession): pass class Group(BaseGroup): ipoPerson = models.StringField( choices=['A', 'B', '都不选'], label="请选择您要合作的公司:", widget=widgets.RadioSelect, ) ratePersonA = models.StringField( choices=['AAA', 'AA+', 'AA'], label="请选择您的预估评级:", widget=widgets.RadioSelect, ) ratePersonB = models.StringField( choices=['AAA', 'AA+', 'AA'], label="请选择您的预估评级:", widget=widgets.RadioSelect, ) investPerson = models.IntegerField(min=0, max=Constants.invest_total, label="请输入您的投资金额:") bondLevel = models.StringField() defaultRate = models.FloatField() rate = models.FloatField() fail_chance = models.FloatField() fail_rate = models.FloatField() a_caught = models.IntegerField() a_caught_h = models.IntegerField() a_caught_l = models.IntegerField() b_caught = models.IntegerField() b_caught_h = models.IntegerField() b_caught_l = models.IntegerField() past_rounds = models.IntegerField() # 获得评级公司的实际评级 def getFinalRate(self): if self.ipoPerson == 'A': return self.ratePersonA elif self.ipoPerson == 'B': return self.ratePersonB else: return '无' # 发行商的利润 def get_ipo_benefit(self): return round(Constants.fixed_income - Constants.rate_benefit + float(self.investPerson) * ( -Constants.rate_map[ self.getFinalRate()] + Constants.rate_map[self.bondLevel] + Constants.financing_income), 2) # 投资人的利润 def get_invest_benefit(self): if self.defaultRate <= 0: return round(float(self.investPerson) * self.defaultRate + Constants.fixed_income, 2) if self.defaultRate > 0: return round(float(self.investPerson) * Constants.rate_map[self.getFinalRate()] + Constants.fixed_income, 2) class Player(BasePlayer): income = models.FloatField(initial= 0) caught = models.IntegerField() caught_h = models.IntegerField() caught_l = models.IntegerField() a_caught = models.IntegerField() a_caught_h = models.IntegerField() a_caught_l = models.IntegerField() b_caught = models.IntegerField() b_caught_h = models.IntegerField() b_caught_l = models.IntegerField() lottery_choice = models.IntegerField() otherrisk = models.IntegerField() outcome_to_pay = models.StringField() outcome_lo = models.CurrencyField() outcome_hi = models.CurrencyField() prob_hi = models.FloatField() prob_lo = models.FloatField() Selectedlottery = models.CurrencyField() payoffscl = models.CurrencyField() dis_payoff = models.FloatField() s1 = models.StringField( label='Q1. 一个球拍和一个球总共卖 1.10 元,球拍比球多卖 1.00 元,请问球的价格是多少(单位:分)?' ) s2 = models.StringField( label='Q2. 如果 5 个机器耗时 5 分钟制作了 5 个装饰品,请问 100 个机器制作 100 个装饰品要耗时多久(单位:分钟)?' ) s3 = models.StringField( label='Q3. 湖面上有一片睡莲,它们每天以两倍的数量增加着。如果睡莲铺满整个湖面需要 48 天,那么它覆盖湖面的一半区域需要几天?' ) s4 = models.StringField( label='Q4. 假设您投掷一枚公平的硬币 1000 次,您认为有多少次这枚硬币会反面朝上?' ) s5 = models.StringField( label='Q5. 小镇上的1000人中有500人是合唱团成员。500名合唱团成员中有100名是男性,500名不是合唱团的居民中有300名是男性。请问随机抽取一名男性是合唱团成员的概率有多大?(请用百分率的形式表示)' ) s6 = models.StringField( choices=[['是', '是'], ['否', '否']], label='Q6. 您是否曾经看到过或者回答过上述问题?', widget=widgets.RadioSelect, ) s7 = models.StringField( choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], label='Q7. 请评价自己:您是愿意承担风险的人还是试图规避风险的人?(1代表着完全不愿意承担风险,10代表着非常愿意承担风险))', widget=widgets.RadioSelectHorizontal, ) s8 = models.StringField( choices=[['1050或以下', '1050或以下'], ['1100', '1100'], ['1150', '1150'], ['1200', '1200'], ['1250', '1250'], ['1300', '1300'], ['1350', '1350'],['1400', '1400'],['1450', '1450'], ['1500或以上', '1500或以上']], label='Q8. 对您来说现在的1000元相当于一年后的多少钱?', widget=widgets.RadioSelectHorizontal, ) s9 = models.FloatField( min=0, max=1000, label='Q9. 如果您有1000元,您愿意对一个利率为4.5%,违约率为1%,违约后收益率为0%的债券投资多少?' ) s10 = models.FloatField( min=0, max=1000, label='Q10. 如果您有1000元,您愿意对一个利率为5.2%,违约率为5%,违约后收益率为-10%的债券投资多少?' ) s11 = models.FloatField( min=0, max=1000, label='Q11. 如果您有1000元,您愿意对一个利率为6%,违约率为10%,违约后收益率为-25%的债券投资多少?' ) s12 = models.StringField( label='Q12. 请问您的年龄是?' ) s13 = models.StringField( choices=[['男性', '男性'], ['女性', '女性'], ['其他', '其他']], label='Q13. 请问您的性别是?', widget=widgets.RadioSelect, ) s13_1 = models.StringField( label='如果选择“其他”,请具体说明:', blank=True ) s14 = models.StringField( choices=[['是', '是'], ['否', '否']], label='Q13. 请问您是否已婚?', widget=widgets.RadioSelect, ) s15 = models.IntegerField( min = 0, max = 10, label='Q12. 请问您有几个孩子?' ) s16 = models.StringField( choices=[ ['会计', '会计'], ['经济', '经济'], ['金融', '金融'], [ '工商管理(除会计、经济、金融的其他商科专业)', '工商管理(除会计、经济、金融的其他商科专业)'], ['教育', '教育'], ['工程学', '工程学'], ['医疗卫生', '医疗卫生'], ['社会科学或历史学', '社会科学或历史学'], [ '数学,计算机或物理学', '数学,计算机或物理学'], ['生物学', '生物学'], ['人文科学', '人文科学'], ['公共事务管理或社会服务类', '公共事务管理或社会服务类'], ['心理学', '心理学'], [ '其他(如果您不是学生,请选择“其他”并说明您的职业)', '其他(如果您不是学生,请选择“其他”并说明您的职业)'] ], label='Q14. 请问您的专业是?', widget=widgets.RadioSelect, ) s16_1 = models.StringField( label='如果选择“其他”,请具体说明:', blank=True ) s17 = models.StringField( choices=[['本科', '本科'], ['硕士', '硕士'], ['博士', '博士'], ['不适用', '不适用']], label='Q15. 请问您的学历层次是?', widget=widgets.RadioSelect, ) s18 = models.StringField( choices=[['少于10,000元', '少于10,000元'], ['10,000-15,000元', '10,000-15,000元'], ['15,000-20,000元', '15,000-20,000元'], ['20,000-30,000元', '20,000-30,000元'], ['30,000-40,000元', '30,000-40,000元'],['40,000-50,000元', '40,000-50,000元'],['50,000元及以上', '50,000元及以上']], label='Q16. 请问您的总家庭月收入是?', widget=widgets.RadioSelect, ) s19 = models.FloatField( min=0, max=50, label='Q17. 您在金融行业工作多少年了?' ) s20 = models.StringField( label='Q18. 您当前从事的职业是?' ) s21 = models.StringField( label='Q19. 您考取过哪些金融领域相关的证书?' ) s22 = models.StringField( choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], label='Q20. 您认为我国债券市场存在压低评级的现象么?(1代表着完全不存在,10代表着存在且很普遍))', widget=widgets.RadioSelectHorizontal, ) s23 = models.StringField( choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], label='Q21. 您认为我国债券市场存在评级虚高现象么?(1代表着完全不存在,10代表着存在且很普遍))', widget=widgets.RadioSelectHorizontal, ) s24 = models.StringField( choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], label='Q20. 您认为本次实验中存在压低评级的现象么?(1代表着完全不存在,10代表着存在且很普遍))', widget=widgets.RadioSelectHorizontal, ) s25 = models.StringField( choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], label='Q21. 您认为本次实验中存在评级虚高现象么?(1代表着完全不存在,10代表着存在且很普遍))', widget=widgets.RadioSelectHorizontal, ) # 获取角色名 def role(self): if self.id_in_group == 1: return Constants.ipo_role elif self.id_in_group == 2: return Constants.rate_role + 'A' elif self.id_in_group == 3: return Constants.rate_role + 'B' else: return Constants.invest_role # 通过违约概率计算实际利率 def creating_session(subsession): subsession.group_randomly(fixed_id_in_group=True) for group in subsession.get_groups(): group.bondLevel = rand_pick(Constants.level_rate, [Constants.AA_possibility, Constants.AAplus_possibility, Constants.AAA_possibility]) for p in subsession.get_players(): n = Constants.num_lotteries # create list of lottery indices # -------------------------------------------------------------------------------------------------------- indices = [j for j in range(1, n + 1)] # create list of low and high outcomes (matched by index) # -------------------------------------------------------------------------------------------------------- outcomes_lo = [c(Constants.sure_payoff - Constants.delta_lo * j) for j in range(0, n)] outcomes_hi = [c(Constants.sure_payoff + Constants.delta_hi * j) for j in range(0, n)] choice_num = [j + 1 for j in range(0, n)] prob_lo = [c(Constants.probability) for j in range(0, n)] prob_hi = [c(Constants.sure_payoff) for j in range(0, n)] # append indices and outcomes by "risk loving" lottery if # -------------------------------------------------------------------------------------------------------- if Constants.risk_loving: indices.append(n + 1) outcomes_lo.append(c(outcomes_lo[-1] - Constants.delta_hi)) outcomes_hi.append(c(outcomes_hi[-1] + Constants.delta_hi)) # create list of lotteries # -------------------------------------------------------------------------------------------------------- p.participant.vars['scl_lotteries'] = list( zip(indices, outcomes_lo, outcomes_hi) ) # randomize order of lotteries if # -------------------------------------------------------------------------------------------------------- if Constants.random_order: random.shuffle( p.participant.vars['scl_lotteries'] ) def intro(group: Group): n = Constants.num_lotteries # create list of lottery indices # -------------------------------------------------------------------------------------------------------- indices = [j for j in range(1, n + 1)] # create list of low and high outcomes (matched by index) # -------------------------------------------------------------------------------------------------------- outcomes_lo = [c(Constants.sure_payoff - Constants.delta_lo * j) for j in range(0, n)] outcomes_hi = [c(Constants.sure_payoff + Constants.delta_hi * j) for j in range(0, n)] prob_lo = [c(Constants.probability) for j in range(0, n)] prob_hi = [c(Constants.sure_payoff) for j in range(0, n)] if Constants.risk_loving: indices.append(n + 1) outcomes_lo.append(c(outcomes_lo[-1] - Constants.delta_hi)) outcomes_hi.append(c(outcomes_hi[-1] + Constants.delta_hi)) for player in group.get_players(): if player.round_number == 1: player.participant.vars['scl_lotteries'] = list( zip(indices, outcomes_lo, outcomes_hi) ) p = Constants.probability rnd = random.randint(1, 100) player.outcome_to_pay = "high" if rnd <= p else "low" # select lottery choice out of list of lotteries # ------------------------------------------------------------------------------------------------------------ lottery_selected = [i for i in player.participant.vars['scl_lotteries'] if i[0] == player.in_round(1).lottery_choice] lottery_selected = lottery_selected[0] # store payoffs of chosen lottery in the model # ------------------------------------------------------------------------------------------------------------ player.outcome_lo = lottery_selected[1] player.outcome_hi = lottery_selected[2] # set player's payoff # ------------------------------------------------------------------------------------------------------------ if player.outcome_to_pay == "high": player.payoffscl = player.outcome_hi else: player.payoffscl = player.outcome_lo def intro(group: Group): n = Constants.num_lotteries # create list of lottery indices # -------------------------------------------------------------------------------------------------------- indices = [j for j in range(1, n + 1)] # create list of low and high outcomes (matched by index) # -------------------------------------------------------------------------------------------------------- outcomes_lo = [c(Constants.sure_payoff - Constants.delta_lo * j) for j in range(0, n)] outcomes_hi = [c(Constants.sure_payoff + Constants.delta_hi * j) for j in range(0, n)] prob_lo = [c(Constants.probability) for j in range(0, n)] prob_hi = [c(Constants.sure_payoff) for j in range(0, n)] if Constants.risk_loving: indices.append(n + 1) outcomes_lo.append(c(outcomes_lo[-1] - Constants.delta_hi)) outcomes_hi.append(c(outcomes_hi[-1] + Constants.delta_hi)) for player in group.get_players(): if player.round_number == Constants.num_rounds: player.participant.vars['scl_lotteries'] = list( zip(indices, outcomes_lo, outcomes_hi) ) p = Constants.probability rnd = random.randint(1, 100) player.outcome_to_pay = "high" if rnd <= p else "low" # select lottery choice out of list of lotteries # ------------------------------------------------------------------------------------------------------------ lottery_selected = [i for i in player.participant.vars['scl_lotteries'] if i[0] == player.in_round(Constants.num_rounds).lottery_choice] lottery_selected = lottery_selected[0] # store payoffs of chosen lottery in the model # ------------------------------------------------------------------------------------------------------------ player.outcome_lo = lottery_selected[1] player.outcome_hi = lottery_selected[2] # set player's payoff # ------------------------------------------------------------------------------------------------------------ if player.outcome_to_pay == "high": player.payoffscl = player.outcome_hi else: player.payoffscl = player.outcome_lo player.dis_payoff = float(player.payoff) + float(player.payoffscl) def get_rate(group: Group): if group.bondLevel == 'AAA': value_list = [Constants.AAA_rate, Constants.AAA_default_rate] probabilities = [1 - Constants.AAA_default, Constants.AAA_default] return rand_pick(value_list, probabilities) elif group.bondLevel == 'AA+': value_list = [Constants.AAplus_rate, Constants.AAplus_default_rate] probabilities = [1 - Constants.AAplus_default, Constants.AAplus_default] return rand_pick(value_list, probabilities) else: value_list = [Constants.AA_rate, Constants.AA_default_rate] probabilities = [1 - Constants.AA_default, Constants.AA_default] return rand_pick(value_list, probabilities) # 概率 def rand_pick(seq, probabilities): x = random.uniform(0, 1) cumprob = 0.0 for item, item_pro in zip(seq, probabilities): cumprob += item_pro if x < cumprob: break return item # 判断是否虚高评级 def fakeRate(group: Group): if group.ipoPerson =='都不选': group.defaultRate = 0.01 if (group.defaultRate <= 0 and group.getFinalRate() > group.bondLevel): return '发现评级公司虚高债券评级。' if (group.defaultRate <= 0 and group.getFinalRate() < group.bondLevel): return '发现评级公司压低债券评级。' else: return '未发现评级公司虚高或压低债券评级。' class Introduction(Page): def is_displayed(player): return player.round_number == 1 class waitPage0(WaitPage): pass class firstPage_ipo(Page): template_name = Constants.page1_template def is_displayed(player: Player): return player.id_in_group == 1 class firstPageA(Page): form_model = 'group' form_fields = ['ratePersonA'] template_name = Constants.page1_template def is_displayed(player: Player): return player.id_in_group == 2 def vars_for_template(player: Player): if player.round_number > 1: return dict( previous_rounds=player.round_number - 1, a_caught_h=player.in_round(player.round_number - 1).a_caught_h, b_caught_h=player.in_round(player.round_number - 1).b_caught_h, a_caught_l=player.in_round(player.round_number - 1).a_caught_l, b_caught_l=player.in_round(player.round_number - 1).b_caught_l, ) class firstPageB(Page): form_model = 'group' form_fields = ['ratePersonB'] template_name = Constants.page1_template def is_displayed(player: Player): return player.id_in_group == 3 def vars_for_template(player: Player): if player.round_number > 1: return dict( previous_rounds=player.round_number - 1, a_caught_h=player.in_round(player.round_number - 1).a_caught_h, b_caught_h=player.in_round(player.round_number - 1).b_caught_h, a_caught_l=player.in_round(player.round_number - 1).a_caught_l, b_caught_l=player.in_round(player.round_number - 1).b_caught_l, ) class firstPage_invest(Page): template_name = Constants.page1_template def is_displayed(player: Player): return player.id_in_group == 4 class waitPage1(WaitPage): pass class SecondPage_ipo(Page): form_model = 'group' form_fields = ['ipoPerson'] template_name = Constants.page2_template @staticmethod def is_displayed(player: Player): return player.id_in_group == 1 def vars_for_template(player: Player): if player.round_number > 1: return dict( previous_rounds=player.round_number - 1, a_caught_h=player.in_round(player.round_number - 1).a_caught_h, b_caught_h=player.in_round(player.round_number - 1).b_caught_h, a_caught_l=player.in_round(player.round_number - 1).a_caught_l, b_caught_l=player.in_round(player.round_number - 1).b_caught_l, ) class SecondPageA(Page): template_name = Constants.page2_template def is_displayed(player: Player): return player.id_in_group == 2 def vars_for_template(player: Player): if player.round_number > 1: return dict( previous_rounds=player.round_number - 1, a_caught_h=player.in_round(player.round_number - 1).a_caught_h, b_caught_h=player.in_round(player.round_number - 1).b_caught_h, a_caught_l=player.in_round(player.round_number - 1).a_caught_l, b_caught_l=player.in_round(player.round_number - 1).b_caught_l, ) class SecondPageB(Page): template_name = Constants.page2_template def is_displayed(player: Player): return player.id_in_group == 3 def vars_for_template(player: Player): if player.round_number > 1: return dict( previous_rounds=player.round_number - 1, a_caught_h=player.in_round(player.round_number - 1).a_caught_h, b_caught_h=player.in_round(player.round_number - 1).b_caught_h, a_caught_l=player.in_round(player.round_number - 1).a_caught_l, b_caught_l=player.in_round(player.round_number - 1).b_caught_l, ) class SecondPage_invest(Page): template_name = Constants.page2_template def is_displayed(player: Player): return player.id_in_group == 4 def vars_for_template(player: Player): if player.round_number > 1: return dict( previous_rounds=player.round_number - 1, a_caught_h=player.in_round(player.round_number - 1).a_caught_h, b_caught_h=player.in_round(player.round_number - 1).b_caught_h, a_caught_l=player.in_round(player.round_number - 1).a_caught_l, b_caught_l=player.in_round(player.round_number - 1).b_caught_l, ) class waitPage2(WaitPage): pass class thirdPage_ipo(Page): template_name = Constants.page3_template def is_displayed(player: Player): return player.id_in_group == 1 class thirdPageA(Page): template_name = Constants.page3_template def is_displayed(player: Player): return player.id_in_group == 2 class thirdPageB(Page): template_name = Constants.page3_template def is_displayed(player: Player): return player.id_in_group == 3 class thirdPage_invest(Page): form_model = 'group' form_fields = ['investPerson'] template_name = Constants.page3_template @staticmethod def is_displayed(player: Player): group = player.group return player.id_in_group == 4 and group.getFinalRate() != '无' def vars_for_template(player: Player): if player.round_number > 1: return dict( previous_rounds=player.round_number - 1, a_caught_h=player.in_round(player.round_number - 1).a_caught_h, b_caught_h=player.in_round(player.round_number - 1).b_caught_h, a_caught_l=player.in_round(player.round_number - 1).a_caught_l, b_caught_l=player.in_round(player.round_number - 1).b_caught_l, ) def before_next_page(player: Player, timeout_happened): group = player.group group.defaultRate = get_rate(group) class waitPage3(WaitPage): @staticmethod def after_all_players_arrive(group: Group): p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) p3 = group.get_player_by_id(3) p4 = group.get_player_by_id(4) if group.ipoPerson == '都不选': p1.income = Constants.fixed_income p2.income = Constants.fixed_income p3.income = Constants.fixed_income p4.income = Constants.fixed_income if group.round_number == 1: p2.caught_h = 0 p3.caught_h = 0 p2.caught_l = 0 p3.caught_l = 0 if group.round_number > 1: p2.caught_h = 0 + p2.in_round(group.round_number - 1).caught_h p3.caught_h = 0 + p3.in_round(group.round_number - 1).caught_h p2.caught_l = 0 + p2.in_round(group.round_number - 1).caught_l p3.caught_l = 0 + p3.in_round(group.round_number - 1).caught_l else: p1.income = round( float(group.investPerson) * ( Constants.rate_map[group.bondLevel] - Constants.rate_map[ group.getFinalRate()] + Constants.financing_income), 2) + Constants.fixed_income - Constants.rate_benefit if group.defaultRate <= 0: p4.income = round(float(group.investPerson) * group.defaultRate, 2) + Constants.fixed_income if group.defaultRate > 0: p4.income = round(float(group.investPerson) * Constants.rate_map[group.getFinalRate()], 2) + Constants.fixed_income if group.ipoPerson == 'A': p2.income = Constants.rate_benefit + Constants.fixed_income p3.income = 0 + Constants.fixed_income if group.ipoPerson == 'B': p2.income = 0 + Constants.fixed_income p3.income = Constants.rate_benefit + Constants.fixed_income if group.round_number == 1: p2.caught_h = 0 p3.caught_h = 0 p2.caught_l = 0 p3.caught_l = 0 if group.defaultRate <= 0 and group.getFinalRate() > group.bondLevel: p2.caught = 1 if group.ipoPerson == 'A': p3.caught = 20 p2.caught_h = 1 p3.caught_h = 0 p2.caught_l = 0 p3.caught_l = 0 if group.ipoPerson == 'B': p2.caught_h = 0 p3.caught_h = 1 p2.caught_l = 0 p3.caught_l = 0 if group.defaultRate <= 0 and group.getFinalRate() < group.bondLevel: p2.caught = 2 if group.ipoPerson == 'A': p3.caught = 30 p2.caught_l = 1 p3.caught_l = 0 p2.caught_h = 0 p3.caught_h = 0 if group.ipoPerson == 'B': p2.caught_l = 0 p3.caught_l = 1 p2.caught_h = 0 p3.caught_h = 0 else: if group.defaultRate <= 0 and group.getFinalRate() > group.bondLevel: p2.caught = 3 if group.ipoPerson == 'A': p2.caught = 101 p2.caught_h = 1 + p2.in_round(group.round_number - 1).caught_h p3.caught_h = 0 + p3.in_round(group.round_number - 1).caught_h p2.caught_l = 0 + p2.in_round(group.round_number - 1).caught_l p3.caught_l = 0 + p3.in_round(group.round_number - 1).caught_l if group.ipoPerson == 'B': p2.caught = 110 p2.caught_h = 0 + p2.in_round(group.round_number - 1).caught_h p3.caught_h = 1 + p3.in_round(group.round_number - 1).caught_h p2.caught_l = 0 + p2.in_round(group.round_number - 1).caught_l p3.caught_l = 0 + p3.in_round(group.round_number - 1).caught_l if group.defaultRate <= 0 and group.getFinalRate() < group.bondLevel: p2.caught = 4 if group.ipoPerson == 'A': p2.caught_h = 0 + p2.in_round(group.round_number - 1).caught_h p3.caught_h = 0 + p3.in_round(group.round_number - 1).caught_h p2.caught_l = 1 + p2.in_round(group.round_number - 1).caught_l p3.caught_l = 0 + p3.in_round(group.round_number - 1).caught_l if group.ipoPerson == 'B': p2.caught_h = 0 + p2.in_round(group.round_number - 1).caught_h p3.caught_h = 0 + p3.in_round(group.round_number - 1).caught_h p2.caught_l = 0 + p2.in_round(group.round_number - 1).caught_l p3.caught_l = 1 + p3.in_round(group.round_number - 1).caught_l if group.defaultRate > 0 : p2.caught_l = 0 + p2.in_round(group.round_number - 1).caught_l p3.caught_l = 0 + p3.in_round(group.round_number - 1).caught_l p2.caught_h = 0 + p2.in_round(group.round_number - 1).caught_h p3.caught_h = 0 + p3.in_round(group.round_number - 1).caught_h if group.getFinalRate() == group.bondLevel: p2.caught_l = 0 + p2.in_round(group.round_number - 1).caught_l p3.caught_l = 0 + p3.in_round(group.round_number - 1).caught_l p2.caught_h = 0 + p2.in_round(group.round_number - 1).caught_h p3.caught_h = 0 + p3.in_round(group.round_number - 1).caught_h group.a_caught_h = p2.caught_h group.b_caught_h = p3.caught_h group.a_caught_l = p2.caught_l group.b_caught_l = p3.caught_l for p in group.get_players(): p.a_caught_h = group.a_caught_h p.b_caught_h = group.b_caught_h p.a_caught_l = group.a_caught_l p.b_caught_l = group.b_caught_l if group.round_number == 1: p.payoff = p.income if group.round_number > 1: p.payoff = p.income + p.in_round(group.round_number-1).payoff class resultPage(Page): template_name = Constants.result_template @staticmethod def vars_for_template(player: Player): group = player.group return dict(fakeRate=fakeRate(group)) class Decision1(Page): # form model # ---------------------------------------------------------------------------------------------------------------- form_model = 'player' # form fields # ---------------------------------------------------------------------------------------------------------------- form_fields = ['lottery_choice'] # variables for template # ---------------------------------------------------------------------------------------------------------------- def is_displayed(player): return player.round_number == Constants.num_rounds def vars_for_template(self): return { 'n': Constants.num_lotteries, 'lotteries': self.participant.vars['scl_lotteries'], 'prob_hi': "{0:.1f}".format(Constants.probability) + "%", 'prob_lo': "{0:.1f}".format(100 - Constants.probability) + "%" } class Survey1(Page): def is_displayed(player): return player.round_number == Constants.num_rounds class Survey2(Page): form_model = 'player' form_fields = ['s1', 's2', 's3', 's4', 's5', 's6'] def is_displayed(player): return player.round_number == Constants.num_rounds class Survey3(Page): form_model = 'player' form_fields = ['s7', 's8', 's9', 's10', 's11'] def is_displayed(player): return player.round_number == Constants.num_rounds class Survey4(Page): form_model = 'player' form_fields = ['s12', 's13', 's13_1', 's14','s15', 's16', 's16_1','s17', 's18', 's19', 's20', 's21','s22','s23','s24','s25'] def is_displayed(player): return player.round_number == Constants.num_rounds class Waitforintro(WaitPage): after_all_players_arrive = intro body_text = "请耐心等待实验继续" def is_displayed(player): return player.round_number == Constants.num_rounds class final_results(Page): def is_displayed(player): return player.round_number == Constants.num_rounds page_sequence = [Introduction, waitPage0, firstPageA, firstPageB, waitPage1, SecondPage_ipo, waitPage2, thirdPage_invest, waitPage3, resultPage, Survey1, Decision1, Survey2, Survey3, Survey4, Waitforintro, final_results]