from otree.api import * c = cu doc = '' class C(BaseConstants): PLAYERS_PER_GROUP = None NUM_ROUNDS = 101 NAME_IN_URL = 'fixed' ENDOWMENT = 1000000 PRICE = (750, 730, 750, 770, 750, 770, 750, 770, 750, 730, 710, 730, 750, 770, 750, 770, 790, 770, 750, 730, 750, 770, 750, 730, 750, 770, 750, 730, 750, 730, 710, 690, 670, 690, 670, 650, 630, 610, 590, 610, 590, 610, 630, 610, 630, 650, 630, 650, 670, 690, 670, 690, 710, 690, 710, 690, 670, 650, 630, 650, 670, 690, 710, 690, 710, 730, 750, 770, 750, 730, 710, 730, 710, 690, 670, 650, 630, 650, 670, 650, 630, 650, 670, 690, 710, 730, 710, 730, 750, 730, 750, 770, 750, 730, 750, 770, 750, 770, 790, 770, 750, 770, 750, 730, 710, 730, 750, 730, 750, 770, 750, 730, 750, 770, 790, 770, 790, 770, 750, 770) class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): day = models.IntegerField() current = models.IntegerField() money = models.FloatField(initial=C.ENDOWMENT) debt = models.FloatField(initial=0) countBorrow = models.IntegerField(initial=0) position = models.IntegerField(initial=0) open = models.IntegerField(initial=0) aveQuote = models.FloatField(initial=0) amount = models.FloatField(initial=0) value = models.IntegerField(initial=0) gain = models.FloatField(initial=0) rate = models.FloatField(initial=0) reverse = models.IntegerField(initial=0) realize = models.FloatField(initial=0) close = models.IntegerField(initial=0) settle = models.IntegerField(initial=0) refund = models.FloatField(initial=0) totalRealize = models.FloatField(initial=0) netGain = models.FloatField() action = models.IntegerField(choices=[[1, '買い'], [-1, '売り'], [0, '待機']], label='1. 行動を選択してください。', widget=widgets.RadioSelect) quantity = models.IntegerField(choices=[], label='2. 数量を指定してください。', max=100000) level = models.IntegerField(choices=[[2, '難しい'], [1, 'やや難しい'], [0, '変わらない'], [-1, 'やや簡単'], [-2, '簡単']], widget=widgets.RadioSelect) reason = models.LongStringField() pastPeriod = models.IntegerField(max=20, min=1) futurePeriod = models.IntegerField(max=20, min=1) beforeAfter = models.IntegerField(choices=[[1, 'はい'], [0, 'いいえ']], widget=widgets.RadioSelect) how = models.LongStringField() begin1 = models.FloatField(initial=0) spend1 = models.FloatField() begin2 = models.FloatField(initial=0) spend2 = models.FloatField() beginExperiment = models.FloatField(initial=0) spendExperiment = models.FloatField() beginTrade = models.FloatField(initial=0) spendTrade = models.FloatField() beginResult = models.FloatField(initial=0) spendResult = models.FloatField() beginSurvey = models.FloatField(initial=0) spendSurvey = models.FloatField() spendTotal = models.FloatField() def quantity_choices(player: Player): return range( 0, 100001, 100 ) Player.quantity_choices = quantity_choices def custom_export(players): import datetime yield ["session", "participant_code", "id_in_group", "participant._current_page_name", "participant._index_in_pages", "participant._max_page_index", "round_number", "player.day", "player.current", "player.action", "player.quantity", "player.money", "player.debt", "player.countBorrow", "player.position", "player.open", "player.aveQuote", "player.amount", "player.value", "player.gain", "player.rate", "player.reverse", "player.realize", "player.close", "player.settle", "player.refund", "player.totalRealize", "player.netGain", "player.level", "player.reason", "player.pastPeriod", "player.futurePeriod", "player.beforeAfter", "player.how", "player.begin1", "player.spend1", "player.begin2", "player.spend2", "player.beginExperiment", "player.spendExperiment", "player.beginTrade", "player.spendTrade", "player.beginResult", "player.spendResult", "player.beginSurvey", "player.spendSurvey", "player.spendTotal"] for p in players: participant = p.participant session = p.session yield [session.code, participant.code, p.id_in_group, participant._current_page_name, participant._index_in_pages, participant._max_page_index, p.round_number, p.day, p.current, p.action, p.quantity, p.money, p.debt, p.countBorrow, p.position, p.open, p.aveQuote, p.amount, p.value, p.gain, p.rate, p.reverse, p.realize, p.close, p.settle, p.refund, p.totalRealize, p.netGain, p.level, p.reason, p.pastPeriod, p.futurePeriod, p.beforeAfter, p.how, datetime.datetime.fromtimestamp(int(p.begin1)), p.spend1, datetime.datetime.fromtimestamp(int(p.begin2)), p.spend2, datetime.datetime.fromtimestamp(int(p.beginExperiment)), p.spendExperiment, datetime.datetime.fromtimestamp(int(p.beginTrade)), p.spendTrade, datetime.datetime.fromtimestamp(int(p.beginResult)), p.spendResult, datetime.datetime.fromtimestamp(int(p.beginSurvey)), p.spendSurvey, p.spendTotal] class Welcome(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == 1 @staticmethod def vars_for_template(player: Player): import time player.begin1 = time.time() return dict() @staticmethod def before_next_page(player: Player, timeout_happened): import time player.spend1 = time.time() - player.begin1 player.spendTotal = player.spend1 class Difference(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == 1 @staticmethod def vars_for_template(player: Player): import time player.begin2 = time.time() return dict() @staticmethod def before_next_page(player: Player, timeout_happened): import time player.spend2 = time.time() - player.begin2 player.spendTotal += player.spend2 class Experiment(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == 1 @staticmethod def vars_for_template(player: Player): import time player.beginExperiment = time.time() return dict() @staticmethod def before_next_page(player: Player, timeout_happened): import time player.spendExperiment = time.time() - player.beginExperiment player.spendTotal += player.spendExperiment class Trade(Page): form_model = 'player' form_fields = ['action', 'quantity'] @staticmethod def is_displayed(player: Player): if player.round_number != C.NUM_ROUNDS: return True @staticmethod def js_vars(player: Player): import time player.beginTrade = time.time() player.day = player.round_number player.current = C.PRICE[player.day+18] borrowing = False preAct = 0 prePos = 0 vol = 0 if player.round_number > 1: preAct = player.in_round(player.round_number - 1).action prePos = player.in_round(player.round_number - 1).position vol = player.in_round(player.round_number - 1).quantity player.debt = player.in_round(player.round_number - 1).debt player.countBorrow = player.in_round(player.round_number - 1).countBorrow if player.in_round(player.round_number - 1).action == 1: if player.in_round(player.round_number - 1).position == -1: player.open = player.in_round(player.round_number - 1).open - player.in_round(player.round_number - 1).quantity if player.open == 0: player.position = 0 player.aveQuote = 0 player.amount = 0 else: player.position = player.in_round(player.round_number - 1).position player.aveQuote = player.in_round(player.round_number - 1).aveQuote player.amount = player.aveQuote * player.open player.reverse = player.in_round(player.round_number - 1).action player.realize = player.in_round(player.round_number - 1).position * (player.current - player.in_round(player.round_number - 1).aveQuote) * player.in_round(player.round_number - 1).quantity player.close = player.in_round(player.round_number - 1).quantity player.settle = player.current * player.close player.refund = player.in_round(player.round_number - 1).aveQuote * player.in_round(player.round_number - 1).quantity + player.realize player.money = player.in_round(player.round_number - 1).money + player.refund else: if player.in_round(player.round_number - 1).position == 0: player.position = player.in_round(player.round_number - 1).action else: player.position = player.in_round(player.round_number - 1).position player.open = player.in_round(player.round_number - 1).open + player.in_round(player.round_number - 1).quantity player.amount = player.in_round(player.round_number - 1).aveQuote * player.in_round(player.round_number - 1).open + player.current * player.in_round(player.round_number - 1).quantity player.aveQuote = player.amount / player.open player.money = player.in_round(player.round_number - 1).money - player.current * player.in_round(player.round_number - 1).quantity elif player.in_round(player.round_number - 1).action == -1: if player.in_round(player.round_number - 1).position == 1: player.open = player.in_round(player.round_number - 1).open - player.in_round(player.round_number - 1).quantity if player.open == 0: player.position = 0 player.aveQuote = 0 player.amount = 0 else: player.position = player.in_round(player.round_number - 1).position player.aveQuote = player.in_round(player.round_number - 1).aveQuote player.amount = player.aveQuote * player.open player.reverse = player.in_round(player.round_number - 1).action player.realize = player.in_round(player.round_number - 1).position * (player.current - player.in_round(player.round_number - 1).aveQuote) * player.in_round(player.round_number - 1).quantity player.close = player.in_round(player.round_number - 1).quantity player.settle = player.current * player.close player.refund = player.in_round(player.round_number - 1).aveQuote * player.in_round(player.round_number - 1).quantity + player.realize player.money = player.in_round(player.round_number - 1).money + player.refund else: if player.in_round(player.round_number - 1).position == 0: player.position = player.in_round(player.round_number - 1).action else: player.position = player.in_round(player.round_number - 1).position player.open = player.in_round(player.round_number - 1).open + player.in_round(player.round_number - 1).quantity player.amount = player.in_round(player.round_number - 1).aveQuote * player.in_round(player.round_number - 1).open + player.current * player.in_round(player.round_number - 1).quantity player.aveQuote = player.amount / player.open player.money = player.in_round(player.round_number - 1).money - player.current * player.in_round(player.round_number - 1).quantity else: player.position = player.in_round(player.round_number - 1).position player.open = player.in_round(player.round_number - 1).open player.aveQuote = player.in_round(player.round_number - 1).aveQuote player.amount = player.in_round(player.round_number - 1).amount player.money = player.in_round(player.round_number - 1).money player.value = player.current * player.open player.gain = player.position * (player.current - player.aveQuote) * player.open if player.open == 0: player.rate = 0 else: player.rate = player.position * (player.current - player.aveQuote)/player.aveQuote if player.gain == -0.0: player.gain = 0 player.rate = 0 player.totalRealize = player.in_round(player.round_number - 1).totalRealize + player.realize if player.position == 0 and player.money / player.current < 200: player.money += C.ENDOWMENT player.debt += C.ENDOWMENT player.countBorrow += 1 borrowing = True return dict( round = player.day, remain = C.NUM_ROUNDS - 1 - player.day, prices = C.PRICE[player.day-1:player.day+19], current = player.current, endowment = C.ENDOWMENT, preAction = preAct, prePosition = prePos, volume = vol, money = player.money, debt = player.debt, borrowed = borrowing, position = player.position, open = player.open, aveQuote = player.aveQuote, amount = player.amount, value = player.value, gain = player.gain, rate = player.rate, reverse = player.reverse, realize = player.realize, close = player.close, settle = player.settle, refund = player.refund, totalRealize = player.totalRealize, ) @staticmethod def before_next_page(player: Player, timeout_happened): import time player.spendTrade = time.time() - player.beginTrade if player.round_number > 1: player.spendTotal = player.in_round(player.round_number - 1).spendTotal + player.spendTrade else: player.spendTotal += player.spendTrade class Result(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): if player.round_number == C.NUM_ROUNDS: return True @staticmethod def js_vars(player: Player): group = player.group participant = player.participant import time player.beginResult = time.time() player.day = player.round_number player.current = C.PRICE[player.day+18] borrowing = False preAct = player.in_round(player.round_number - 1).action prePos = player.in_round(player.round_number - 1).position vol = player.in_round(player.round_number - 1).quantity player.debt = player.in_round(player.round_number - 1).debt player.countBorrow = player.in_round(player.round_number - 1).countBorrow if player.in_round(player.round_number - 1).action == 1: if player.in_round(player.round_number - 1).position == -1: player.open = player.in_round(player.round_number - 1).open - player.in_round(player.round_number - 1).quantity if player.open == 0: player.position = 0 player.aveQuote = 0 player.amount = 0 else: player.position = player.in_round(player.round_number - 1).position player.aveQuote = player.in_round(player.round_number - 1).aveQuote player.amount = player.aveQuote * player.open player.reverse = player.in_round(player.round_number - 1).action player.realize = player.in_round(player.round_number - 1).position * (player.current - player.in_round(player.round_number - 1).aveQuote) * player.in_round(player.round_number - 1).quantity player.close = player.in_round(player.round_number - 1).quantity player.settle = player.current * player.close player.refund = player.in_round(player.round_number - 1).aveQuote * player.in_round(player.round_number - 1).quantity + player.realize player.money = player.in_round(player.round_number - 1).money + player.refund else: if player.in_round(player.round_number - 1).position == 0: player.position = player.in_round(player.round_number - 1).action else: player.position = player.in_round(player.round_number - 1).position player.open = player.in_round(player.round_number - 1).open + player.in_round(player.round_number - 1).quantity player.amount = player.in_round(player.round_number - 1).aveQuote * player.in_round(player.round_number - 1).open + player.current * player.in_round(player.round_number - 1).quantity player.aveQuote = player.amount / player.open player.money = player.in_round(player.round_number - 1).money - player.current * player.in_round(player.round_number - 1).quantity elif player.in_round(player.round_number - 1).action == -1: if player.in_round(player.round_number - 1).position == 1: player.open = player.in_round(player.round_number - 1).open - player.in_round(player.round_number - 1).quantity if player.open == 0: player.position = 0 player.aveQuote = 0 player.amount = 0 else: player.position = player.in_round(player.round_number - 1).position player.aveQuote = player.in_round(player.round_number - 1).aveQuote player.amount = player.aveQuote * player.open player.reverse = player.in_round(player.round_number - 1).action player.realize = player.in_round(player.round_number - 1).position * (player.current - player.in_round(player.round_number - 1).aveQuote) * player.in_round(player.round_number - 1).quantity player.close = player.in_round(player.round_number - 1).quantity player.settle = player.current * player.close player.refund = player.in_round(player.round_number - 1).aveQuote * player.in_round(player.round_number - 1).quantity + player.realize player.money = player.in_round(player.round_number - 1).money + player.refund else: if player.in_round(player.round_number - 1).position == 0: player.position = player.in_round(player.round_number - 1).action else: player.position = player.in_round(player.round_number - 1).position player.open = player.in_round(player.round_number - 1).open + player.in_round(player.round_number - 1).quantity player.amount = player.in_round(player.round_number - 1).aveQuote * player.in_round(player.round_number - 1).open + player.current * player.in_round(player.round_number - 1).quantity player.aveQuote = player.amount / player.open player.money = player.in_round(player.round_number - 1).money - player.current * player.in_round(player.round_number - 1).quantity else: player.position = player.in_round(player.round_number - 1).position player.open = player.in_round(player.round_number - 1).open player.aveQuote = player.in_round(player.round_number - 1).aveQuote player.amount = player.in_round(player.round_number - 1).amount player.money = player.in_round(player.round_number - 1).money player.value = player.current * player.open player.gain = player.position * (player.current - player.aveQuote) * player.open if player.open == 0: player.rate = 0 else: player.rate = player.position * (player.current - player.aveQuote)/player.aveQuote if player.gain == -0.0: player.gain = 0 player.rate = 0 player.totalRealize = player.in_round(player.round_number - 1).totalRealize + player.realize if player.position == 0 and player.money / player.current < 200: player.money += C.ENDOWMENT player.debt += C.ENDOWMENT player.countBorrow += 1 borrowing = True player.netGain = player.totalRealize + player.gain - player.debt * 0.05 finish = 1 ranking = 1 topGain = player.netGain for p in group.get_players(): if player.id_in_group != p.id_in_group: if p.participant._index_in_pages == p.participant._max_page_index: finish += 1 if player.netGain < p.netGain: ranking += 1 if topGain < p.netGain: topGain = p.netGain return dict( current = player.current, endowment = C.ENDOWMENT, preAction = preAct, prePosition = prePos, volume = vol, money = player.money, debt = player.debt, borrowed = borrowing, position = player.position, open = player.open, aveQuote = player.aveQuote, amount = player.amount, value = player.value, gain = player.gain, rate = player.rate, reverse = player.reverse, realize = player.realize, close = player.close, settle = player.settle, refund = player.refund, totalRealize = player.totalRealize, netGain = player.netGain, rank = ranking, completed = finish, gap = topGain - player.netGain, ) @staticmethod def before_next_page(player: Player, timeout_happened): import time player.spendResult = time.time() - player.beginResult player.spendTotal = player.in_round(player.round_number - 1).spendTotal + player.spendResult class Survey(Page): form_model = 'player' form_fields = ['pastPeriod', 'futurePeriod', 'how', 'beforeAfter', 'level', 'reason'] @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS @staticmethod def vars_for_template(player: Player): import time player.beginSurvey = time.time() return dict() @staticmethod def before_next_page(player: Player, timeout_happened): import time player.spendSurvey = time.time() - player.beginSurvey player.spendTotal += player.spendSurvey class End(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS page_sequence = [Welcome, Difference, Experiment, Trade, Result, Survey, End]