Experimental Economics: Data Workflow
Lecture 5a: Sequential Experiments
0.1 Sequential an simultaneous games
- Sequential games
- Choices of one player are conditional upon choices of another player
- Example: (mini) Trust game
- Choices of one player are conditional upon choices of another player
- We will implement both
- a play method version of the game
- Only the nodes of the game actually reached are played
- a strategy method version of the game
- All nodes of the game are played, but the payoff is only assigned to the node reached
- a play method version of the game
1 A (mini) Trust Game (TG)
1.1 Setting
- Players are matched in couples
- A player is the first mover (Subject A)
- A player is the second mover (Subject B)
- Subject A can choose between enter the game (Option 2) or exit the game (Option 1)
- If enter → Subject B can choose between reward (Option 4) or exploit (Option 3)
- If exit → Subject B has no choice to marker
- Payoffs are defined by the combination of choices by Subject A and B
- (Option 1,.): 10, 0
- (Option 2, Option 3): 0, 40
- (Option 2, Option 4): 22, 18
2 oTree code: init.py
2.1 Constants (models)
class C(BaseConstants):
NAME_IN_URL = 'trust_game_corso'
PLAYERS_PER_GROUP = 2
NUM_ROUNDS = 1
P_1=[10,0] #payoffs exit
P_2_3=[0,40] # payoffs entry, exploitation
P_2_4 = [22, 18] # payoffs entry, reciprocity- Match participants in groups of 2
- Define here the payoffs as lists
2.2 Subsession (models)
class Subsession(BaseSubsession):
pass
# Assign roles to players
def creating_session(player: Player):
for g in player.get_groups():
for p in g.get_players():
if p.id_in_group == 1:
first = True
else:
first = False
p.first_mover = first- Assign roles randomly using the ID in group
- ID=1 is first mover
- ID=2 is second mover
2.3 Group (models)
class Group(BaseGroup):
choice_1 = models.CharField(choices=[['Option 1','Option 1'], ['Option 2', 'Option 2']], widget=widgets.RadioSelectHorizontal, label="")
choice_2 = models.CharField(choices=[['Option 3','Option 3'], ['Option 4', 'Option 4']], widget=widgets.RadioSelectHorizontal, label="")
# Compute payoffs
def set_payoffs(group: Group):
p1 = group.get_player_by_id(1)
p2 = group.get_player_by_id(2)
if group.choice_1 == 'Option 1':
p1.payoff = C.P_1[0]
p2.payoff = C.P_1[1]
else:
if group.field_maybe_none('choice_2') == 'Option 3':
p1.payoff = C.P_2_3[0]
p2.payoff = C.P_2_3[1]
else:
p1.payoff = C.P_2_4[0]
p2.payoff = C.P_2_4[1] - Choices are defined for class Group
- Payoffs are defined at the group level
- Outcome is conditional upon choice of Subject A and Subject B
2.4 Player (models)
class Player(BasePlayer):
first_mover = models.BooleanField()
treatment= models.CharField()- Role of the player
page_sequence = [Instructions, Choice_1, SendWaitPage, Choice_2, ResultsWaitPage, Results]
2.5 Instructions (pages)
class Instructions(Page):
@staticmethod
def vars_for_template(player: Player):
if player.session.config['treatment'] == "play":
return {
'play': True
}
else:
return {
'play': False
}- To condition the instructions on the treatment
- In settings.py
dict(
name='TG',
app_sequence=['TG_2'],
num_demo_participants=2,
treatment = "play"# play= sequential; method= strategy method
)If play → instructions are different
- Subject B will choose after knowing the choice of Player A.
If method → instructions are different
- Subject B will choose before knowing the choice of Player A.
2.6 Choice_1
class Choice_1(Page):
form_model = 'group'
form_fields = ['choice_1']
@staticmethod
def is_displayed(player: Player):
return player.first_mover == 1- Collect the choice of Subject A
- Notice that the field “belongs” to Group
- The page is displayed only if the Subject is a first mover
- As defined in Subsession
2.7 SendWaitPage
class SendWaitPage(WaitPage):
def is_displayed(player: Player):
return player.session.config['treatment'] == "play"- A waiting page so that Subject B waits that Subject A makes her choice -Displayed only for the play treatment
2.8 Choice_2
class Choice_2(Page):
form_model = 'group'
form_fields = ['choice_2']
@staticmethod
def vars_for_template(player: Player):
if player.session.config['treatment'] == "play":
return {
'display': True,
'choice_other': player.group.choice_1
}
else:
return {
'display': False
}
@staticmethod
def is_displayed(player: Player):
if player.session.config['treatment'] == "play":
return player.first_mover == False and player.group.choice_1 == 'Option 2'
else:
return player.first_mover == False
- Collect the choice of Subject B
vars_for_templateto display the choice of A- play treatment
- The page is displayed only if two conditions are simultaneously met
- Player is not a first mover
- First mover chose Option 2
- Otherwise, Subject B has no choice to make
- The page is displayed only if two conditions are simultaneously met
- method treatment
- The page is displayed only if the player is not a first mover
2.9 ResultsWaitPage
class ResultsWaitPage(WaitPage):
after_all_players_arrive = 'set_payoffs'- A waiting page so that Subject A waits that Subject B makes her choice
- After all make their choices we can compute payoffs
- set_payoffs() at the Group level
2.10 Results
class Results(Page):
@staticmethod
def vars_for_template(player: Player):
return {
'first_mover': player.first_mover,
'choice_1': player.group.choice_1,
'choice_2': player.group.field_maybe_none('choice_2'),
'payoff': player.payoff
}field_maybe_none()is needed because ‘choice_2’ may possibly be None- When second mover in play has no choice to make
- Variables needed to give feedback
payoffcaptures the earnings in the game
3 Templates
3.1 Instructions
{{ extends "global/Page.html" }}
{{ load otree static }}
{{ block title }}
Instructions
{{ endblock }}
{{ block content }}
<p>Consider the following situation:</p>
<p>Two participants to this study are randomly and anonymously paired. One participant is labelled <i>Subject A</i> and the other <i>Subject B.</i>
</p>
<p>Subject A must decide among two alternatives, called <i>Option 1</i> and <i>Option 2.</i></p>
<br>
<center><img src="{{ static "TG/en.png" }}" width=300 /></center>
<br>
<ul>
<li>
<b>Option 1:</b> Subject A keeps the 10 Points and nothing is passed to Subject B. The game ends without Subject B taking any decision and earnings will be 10 Points for Subject A and 0 Points for Subject B, respectively.
</li>
<li>
<b>Option 2:</b> Subject A passes 10 Points to Subject B. The 10 Points will be multiplied by a factor of 4, thus Subject B will receive 40 Points. In this case Subject B must decide among <i>Option 3</i> and <i>Option 4</i>:
</li>
<li>
<b>Option 3:</b> Subject B keeps the 40 Points and nothing is passed back to Subject A. Earnings will be 0 Points for Subject A and 40 Points for Subject B, respectively.
</li>
<li>
<b>Option 4:</b> Subject B keeps the 18 Points and passes back 22 Points to Subject A. Earnings will be 22 Points for Subject A and 18 Points for Subject B, respectively.
</li>
</ul>
One of the participants in each couple is randomly assigned to be Subject A and the other to be Subject B.<br>
{{ if play == True}}
Subject B will choose after knowing the choice of Player A.
{{ else}}
Subject B will choose before knowing the choice of Player A.
{{ endif }}
<div class="container" style="font-size:12pt">
<div class="row">
</div>
<div class="row" style="padding-left:135px;">
<div class="col-md-10">
</div>
<div class="col-md-2">
<button name="btn_submit" value="True" class="btn btn-primary btn-large">
<span style="font-size:18pt">Start</span>
</button>
</div>
</div>
</div>
{{ endblock }}- A figure is included in the template
- Imported from static folder
- The last sentence is conditional upon the treatment
playis a variable passed to the templateplayis defined in the view
3.2 Choice_1
{{ extends "global/Page.html" }}
{{ load otree static }}
{{ block title }}
You are Subject A
{{ endblock }}
{{ block content }}
<center><img src="{{ static "TG/en.png" }}" /></center>
{{ formfield group.choice_1 label="Please choose between Option 1 and Option 2:" }}
<div class="container" style="font-size:12pt">
<div class="row">
</div>
<div class="row" style="padding-left:135px;">
<div class="col-md-10">
</div>
<div class="col-md-2">
<button name="btn_submit" value="True" class="btn btn-primary btn-large">
<span style="font-size:18pt">Confirm</span>
</button>
</div>
</div>
</div>
{{ endblock }}- The template is very simple
- A figure is included
- A form field is included
formfieldis a template taggroup.choice_1is the field to be displayed
- A button to confirm the choice
3.3 Choice_2
{{ extends "global/Page.html" }}
{{ load otree static }}
{{ block title }}
You are Subject B
{{ endblock }}
{{ block content }}
{{ if display == True}}
Subject A chose {{choice_other}}.
{{else}}
{{endif}}
<br>
<center><img src="{{ static "TG/en.png" }}" /></center>
{{ formfield group.choice_2 label="Please choose between Option 3 and Option 4:" }}
<div class="container" style="font-size:12pt">
<div class="row">
</div>
<div class="row" style="padding-left:135px;">
<div class="col-md-10">
</div>
<div class="col-md-2">
<button name="btn_submit" value="True" class="btn btn-primary btn-large">
<span style="font-size:18pt">Confirm</span>
</button>
</div>
</div>
</div>
{{ endblock }}- The template is very similar to the previous one
- A conditional sentence is included
displayis a variable passed to the template
- A form field is included
formfieldis a template taggroup.choice_2is the field to be displayed
- A button to confirm the choice
- A conditional sentence is included
3.4 Results
{{ extends "global/Page.html" }}
{{ load otree static }}
{{ block title }}
Results
{{ endblock }}
{{ block content }}
<center><img src="{{ static "TG/en.png" }}" /></center>
{{ if first_mover == True }}
You were a Subject A. <br>You chose {{choice_1 }}. <br>
The other chose {{ choice_2 }}.
{{ else }}
You were a Subject B. <br>
You chose {{ choice_2 }}.<br>
The other chose {{ choice_1 }}.
{{ endif }}
<br>
Thus, you earn {{ payoff }}.
<br>
<div class="container" style="font-size:12pt">
<div class="row">
</div>
<div class="row" style="padding-left:135px;">
<div class="col-md-10">
</div>
<div class="col-md-2">
<button name="btn_submit" value="True" class="btn btn-primary btn-large">
<span style="font-size:18pt">Finish</span>
</button>
</div>
</div>
</div>
{{ endblock }}- A conditional sentence is included
first_moveris a variable passed to the template- To differentiate the display of the results
- A button to confirm the choice
4 Appendix
4.1 OTree code
- Trust Game