from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import config_collat debug = True author = "Research team under Professor Kevin McCabe" doc = """ Investment Game with Collateral and Smart Contracts """ class Constants(BaseConstants): name_in_url = 'Collateral_Game' '''determines which treatment to run. Treatment is a key which is passed into the dictionary of treatments, this corresponds with a treatment specific dictionary. Within the treatment specific dictionary each individual variable has a key that corresponds with its name. ex contract enforcement can be obtained by passing the string 'contract_enforcement' into the treatment dictionary''' treatment = 'treatment4' dic_of_treatments = config_collat.parameters[treatment] '''references the dictionary of treatments to assign variables to this round''' contract_enforcement = dic_of_treatments['contract_enforcement'] #boolean has not been integrated yet '''as of right now this will always be set to two. If for some reason this is changed it will *Break* the game''' players_per_group = dic_of_treatments["players_per_group"] '''as of right now this will always be set to one''' num_rounds = dic_of_treatments["num_rounds"] '''returns an integer which is converted into an otree specific type currency''' initial_points = c(dic_of_treatments["initial_points "]) recovery_fee = c(dic_of_treatments["recovery_fee"]) productivity = dic_of_treatments["productivity"] loan_agreement_instructions_template = 'Collateral_Instructions/LoanAgreement.html' '''Instruction that cover the general flow of the game. With limited detail''' loan_fulfillment_instructions_template = 'Collateral_Instructions/LoanFulfillment.html' '''Instruction that covers the same material as loan agreement but with examples, excluding collateral''' loan_remediation_instruction_template = 'Collateral_Instructions/LoanRemediation.html' '''Instruction that describes the collateral and the loan remediation process with examples''' task_repayment_instruction_template = 'Collateral_Instructions/TaskRepayment.html' '''explains the process in which a player earns money''' class Subsession(BaseSubsession): pass class Group(BaseGroup): '''defines group variables *these will be changed throughout the experiment* every variable that takes the form of models. will write to a csv''' '''value of collateral after salvage cost is subtracted''' collateral_after_salvage = models.CurrencyField() #change to collateral after salvage '''repayment rate lender expects''' rate_of_return = models.FloatField(min=0, max=Constants.productivity) '''collateral offered by borrower''' collateral = models.CurrencyField(min=0, max=Constants.initial_points ) '''amount lent to borrower''' loan = models.CurrencyField(min=0, max=Constants.initial_points ) '''the amount that the borrower has returned to the lender''' repaymentodels.CurrencyField(min=0, initial=0) '''the actual return ration from the loan''' actual_return = models.FloatField() #lenders actual return '''two buttons that are either Yes or No regarding accepting the loan package''' accept_loan = models.CharField( verbose_name='Do you accept the Loan Package?', choices=['Yes', 'No'], widget=widgets.RadioSelect) '''two buttons that are either Yes or No about if the lender is satified with the actual from the loan''' satisfied = models.CharField( verbose_name='Are you satisfied with the Outcome?', choices=['Yes', 'No'], widget=widgets.RadioSelect) def repayment(self): '''this turn the maximum amount that the borrower can return to the lender as a function of the game productivity and the amount that the lender invested''' max_return = int(self.loan) * Constants.productivity return max_return recovered_collateral = models.CurrencyField(min=0) def recovered_collateral_max(self): return self.collateral class Player(BasePlayer): '''this is diffrent from endowment(initial_points ) because it changes throughout the experiment''' money = models.CurrencyField(initial=Constants.initial_points ) def role(self): if self.id_in_group == 1: return 'lender' if self.id_in_group == 2: return 'borrower'