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):
= 'trust_game_corso'
NAME_IN_URL = 2
PLAYERS_PER_GROUP = 1
NUM_ROUNDS =[10,0] #payoffs exit
P_1=[0,40] # payoffs entry, exploitation
P_2_3= [22, 18] # payoffs entry, reciprocity P_2_4
- 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:
= True
first else:
= False
first = first p.first_mover
- 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):
= models.CharField(choices=[['Option 1','Option 1'], ['Option 2', 'Option 2']], widget=widgets.RadioSelectHorizontal, label="")
choice_1 = models.CharField(choices=[['Option 3','Option 3'], ['Option 4', 'Option 4']], widget=widgets.RadioSelectHorizontal, label="")
choice_2
# Compute payoffs
def set_payoffs(group: Group):
= group.get_player_by_id(1)
p1 = group.get_player_by_id(2)
p2 if group.choice_1 == 'Option 1':
= C.P_1[0]
p1.payoff = C.P_1[1]
p2.payoff else:
if group.field_maybe_none('choice_2') == 'Option 3':
= C.P_2_3[0]
p1.payoff = C.P_2_3[1]
p2.payoff else:
= C.P_2_4[0]
p1.payoff = C.P_2_4[1] p2.payoff
- 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):
= models.BooleanField()
first_mover = models.CharField() treatment
- 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(
='TG',
name=['TG_2'],
app_sequence=2,
num_demo_participants= "play"# play= sequential; method= strategy method
treatment )
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):
= 'group'
form_model = ['choice_1']
form_fields
@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):
= 'group'
form_model = ['choice_2']
form_fields
@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_template
to 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):
= 'set_payoffs' after_all_players_arrive
- 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
payoff
captures 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>
<br>
One of the participants in each couple is randomly assigned to be Subject A and the other to be Subject B.
{{ 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
play
is a variable passed to the templateplay
is 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
formfield
is a template taggroup.choice_1
is 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
display
is a variable passed to the template
- A form field is included
formfield
is a template taggroup.choice_2
is 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 }}<br>You chose {{choice_1 }}. <br>
You were a Subject A.
The other chose {{ choice_2 }}.
{{ else }}<br>
You were a Subject B. <br>
You chose {{ choice_2 }}.
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_mover
is 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