Money and Points¶
In many experiments, participants play for currency:
either real money, or points. oTree supports both;
you can switch from points to real money by setting USE_POINTS = False
in settings.py
.
If you have a value that represents an amount of currency
(either points or dollars, etc),
you should mark it with c()
, e.g. c(10)
or c(0)
.
It will still work just like a number
(e.g. c(1) + c(0.2) == c(1.2)
).
The advantage is that when it’s displayed to users, it will automatically
formatted as $1.20
or 1,20 €
, etc., depending on your
REAL_WORLD_CURRENCY_CODE
and LANGUAGE_CODE
settings.
Money amounts are displayed with 2 decimal places by default;
you can change this with the setting REAL_WORLD_CURRENCY_DECIMAL_PLACES
.
If a model field is a currency amount,
you should define it as a CurrencyField
.
For example:
class Player(BasePlayer):
random_bonus = models.CurrencyField()
def some_method(self):
self.random_bonus = c(random.randint(1, 10))
Note: instead of using Python’s built-in range
function,
you should use oTree’s currency_range
with currency values,
e.g.:
class Player(BasePlayer):
contribution = models.CurrencyField(
choices=currency_range(c(0), c(0.10), c(0.02))
# this gives:
# [$0.00, $0.02, $0.04, $0.06, $0.08, $0.10]
)
currency_range
takes 3 arguments (start, stop, step), just like range.
However, unlike range()
, the returned list includes the stop
value
as shown above.
In templates, instead of using the c()
function, you should use the
|c
filter.
For example, {{ 20|c }}
displays as 20 points
.
payoffs¶
Each player has a payoff
field,
which is a CurrencyField
.
If your player makes money, you should store it in this field.
self.participant.payoff
is the sum of the payoffs a participant
made in each subsession.
At the end of the experiment, a participant’s
total profit can be accessed by self.participant.payoff_plus_participation_fee()
;
it is calculated by converting self.participant.payoff
to real-world currency
(if USE_POINTS
is True
), and then adding
self.session.config['participation_fee']
.
Note
The initial (default) value of payoff
was changed from None
to 0
in oTree 1.0.
Points (i.e. “experimental currency”)¶
Sometimes it is preferable for players to play games for points or
“experimental currency units”, which are converted to real money at the
end of the session. You can set USE_POINTS = True
in
settings.py
, and then in-game currency amounts will be expressed in
points rather than dollars or euros, etc.
For example, c(10)
is displayed as 10 points
.
To change the exchange rate to real money, go to settings.py
and set real_world_currency_per_point
in the session config.
For example, if you pay the user 2 cents per point, you would set
'real_world_currency_per_point': 0.02
.
Points are integers by default. You can change this by setting POINTS_DECIMAL_PLACES = 2
(or whatever number of decimal places you desire).
If you switch your language setting to one of oTree’s supported languages,
the name “points” is automatically translated,
e.g. “puntos” in Spanish.
To further customize the name “points” to something else like “tokens” or “credits”,
set POINTS_CUSTOM_NAME
, e.g. POINTS_CUSTOM_NAME = 'tokens'
.
Converting points to real world currency¶
You can convert a points amount to money using the method
.to_real_world_currency(self.session)
. In the above example, that would be:
>>> c(10).to_real_world_currency(self.session)
$0.20
It requires self.session
to be passed, because
different sessions can have different conversion rates).