#1 by Trontatuma (edited )
Has anybody implemented this for Otree 5? https://github.com/felixholzmeister/icl https://www.sciencedirect.com/science/article/pii/S2214635017300540
#2
by
FEDx
I did it, and it worked pretty well with minor adjustments to adapt it to the new version of Otree
#3 by Trontatuma
Could you share the code?
#4
by
FEDx
Sure: https://github.com/federicoatz/Staircase_oTreeLite.git Let me know if you need any help.
#5 by Trontatuma
Thanks!
#6
by
BonnEconLab
A drawback of using oTree rounds for the steps in a staircase procedure is that you cannot easily revert to a previous step. Given that this leads to “error propagation” in the sense that mistakes early in the sequence have a large impact on the elicited value, I find it desirable to include a “back”/“revise” button when implementing a staircase procedure.
Programming a button that allows participants to revise the choices that they have made so far is relatively easy in JavaScript.
Here is some self-contained HTML and JavaScript code that implements the “risk staircase method” from Falk et al. (2023), including a “Revise” button:
<html>
<head>
<title>Risk staircase method</title>
</head>
<body>
<h2>Hypothetical choice between safe and risky payoff</h2>
<p>Please imagine the following situation:</p>
<p><ul>
<li>You can choose between receiving a particular monetary amount for sure and a random draw.</li>
<li>The random draw results in either a payment of 300 euros or no payment at all; both outcomes have the same probability.</li>
</ul></p>
<p id="staircase-label">What do you prefer: a random draw that gives you a 50% chance of receiving 300 euros and the same 50% chance of receiving nothing at all—or receiving the amount of <span id="staircase-value">y</span> euros for sure?</p>
<p>
<span id="staircase-buttons">
<button type="button" class="btn btn-primary" onclick="staircase('L')" id="staircase_left">
300 euros with 50% chance
</button>
<button type="button" class="btn btn-primary" onclick="staircase('S')" id="staircase_right">
<span id="staircase-value-btn">y</span> euros for sure
</button>
</span>
<span id="back-button" style="visibility: hidden;">
<button type="button" class="btn btn-warning" onclick="staircase('B')" id="staircase_back" style="opacity: 0.5;">
Revise previous choice
</button>
</span>
</p>
<p>
The certainty equivalent lies in the interval
<input type="text" id='GPS-risk-staircase' readonly></input>.
</p>
<p id="next-button" style="visibility: hidden; opacity: 0;">
<button>Continue</button>
</p>
<p><i>Based on <a href="https://doi.org/10.1287/mnsc.2022.4455" target="_blank">Falk et al. (2023)</a>, <a href="https://pubsonline.informs.org/doi/suppl/10.1287/mnsc.2022.4455/suppl_file/mnsc.2022.4455.sm1.pdf" target="_blank">Online Appendix</a>, p. 44.</i></p>
<script>
var i = 0; // counter for staircase step
var j = 0; // counter for staircase interval in step i
var k = 0; // counter for lower/upper bound of interval j
let staircaseEntries = [
[[160]],
[[80, 240]],
[[40, 120], [200, 280]],
[[20, 60], [100, 140], [180, 220], [260, 300]],
[[10, 30], [50, 70], [90, 110], [130, 150], [170, 190], [210, 230], [250, 270], [290, 310]],
[[5, 15], [25, 35], [45, 55], [65, 75], [85, 95], [105, 115], [125, 135], [145, 155], [165, 175], [185, 195], [205, 215], [225, 235], [245, 255], [265, 275], [285, 295], [305, 315]]
];
let numSteps = staircaseEntries.length;
var safeOption = staircaseEntries[0][0][0]; // Initial safe payment
var lowerBound = "0"; // Initial lower bound
var upperBound = "> " + staircaseEntries[numSteps - 1][2**(numSteps - 2) - 1][1]; // Initial upper bound
// Arrays to enable “Back” button
var jkHist = Array(numSteps).fill([9999, 9999]); // Initialize with nonsensical values
var safeHist = Array(numSteps).fill("9999"); // Initialize with nonsensical values
var lbHist = Array(numSteps).fill("9999"); // Initialize with nonsensical values
var ubHist = Array(numSteps).fill("9999"); // Initialize with nonsensical values
safeHist[0] = safeOption;
jkHist[0] = [0, 0];
lbHist[0] = lowerBound;
ubHist[0] = upperBound;
document.getElementById('staircase-value').innerHTML = safeOption;
document.getElementById('staircase-value-btn').innerHTML = safeOption;
document.getElementById('GPS-risk-staircase').value = "[" + lowerBound + ", " + upperBound + "]";
function staircase(choice) {
document.getElementById('staircase-label').style.opacity = "0";
document.getElementById('staircase-buttons').style.opacity = "0";
document.getElementById('back-button').style.opacity = "0";
if (choice == "L") { // Lottery chosen
k = 1;
lowerBound = safeOption;
}
if (choice == "S") { // Safe option chosen
k = 0;
upperBound = safeOption;
};
safeHist[i] = safeOption;
if (choice == "B") { // “Back“ button pressed
if (i > 0) {
i -= 1;
j = jkHist[i][0];
k = jkHist[i][1];
safeOption = safeHist[i];
upperBound = ubHist[i];
lowerBound = lbHist[i];
}
} else {
if (i < numSteps - 1) {
jkHist[i] = [j, k];
i += 1;
safeOption = staircaseEntries[i][j][k];
j = 2 * j + k;
} else {
i = numSteps;
}
lbHist[i] = lowerBound;
ubHist[i] = upperBound;
};
if (i < numSteps) {
if (i > 0) {
document.getElementById('back-button').style.visibility = "visible";
} else {
document.getElementById('back-button').style.visibility = "hidden";
}
document.getElementById('staircase-buttons').style.visibility = "visible";
document.getElementById('next-button').style.visibility = "hidden";
setTimeout(function() {
document.getElementById('staircase-value').innerHTML = safeOption;
document.getElementById('staircase-value-btn').innerHTML = safeOption;
}, 1000);
setTimeout(function() {
document.getElementById('staircase-label').style.opacity = "1";
document.getElementById('staircase-buttons').style.opacity = "1";
}, 1000);
} else {
document.getElementById('staircase-buttons').style.visibility = "hidden";
document.getElementById('next-button').style.visibility = "visible";
document.getElementById('next-button').style.opacity = "1";
};
setTimeout(function() {
document.getElementById('back-button').style.opacity = "1";
}, 1000);
document.getElementById('GPS-risk-staircase').value = "[" + lowerBound + ", " + upperBound + "]";
};
</script>
</body>
</html>
#7
by
FEDx
Thanks @BonnEconLab, you rise a very interesting point.