Hello Everyone,
I am programming my first experiment and I am fairly new to all of this so please bear with me. I am creating a virtual stock market. Mine is somewhat different from the examples I have seen here but what I am doing is as follows:
Participants own shares of stock in a company and have enough money to buy more or sell the shares they have. If a participant clicks on the button to buy more shares, the price of the stock goes up, and if they click on the sell button the price goes down. So far, I have managed to program this function successfully using Live pages. Doing something similiar to the dollar auction example.
I am at the point now where I want to make it so when a participant clicks buy/sell the amount of money in there account goes down/up and the amount of shares they have increases/decreases. I also want to disable the buy/sell buttons depending on the situation for the individual player. I have everything up until this point using the group models but the actions I just described will of course need to take place using the player models. This is where I am a bit confused.
Should I create another live pages function using player instead of group? Or is there another way of doing this. I have pasted the code that works thus far. I would appreciate any help. Even if its something as simple as "Hey, look at this example to get some ideas." Thanks!
-Mark
Here is the html page :
{{ block content }}
<!--displays to the participant the current price-->
<p id="msg-current-price"></p>
<!--creates a button where the participant can buy or sell the asset. On click the function buyAsset-->
<!--or the function sellAsset is executed-->
<button type="button" id="btn-buy" onclick="buyAsset(this)"></button>
<button type="button" id="btn-sell" onclick="sellAsset(this)" ></button>
<br><br>
<!--Start Javascript code, define that the buttons are elements which can be changed, and define
the current price to be displayed as a message which can also change-->
<script>
let buyBtn= document.getElementById('btn-buy');
let sellBtn = document.getElementById('btn-sell');
let msgCurrentPrice= document.getElementById('msg-current-price');
//defines the buy button function
function buyAsset(btn) {
liveSend(parseInt(btn.value));
}
//defines the sell button function
function sellAsset(btn) {
liveSend(parseInt(btn.value));
}
//defines the live receive function, where the current price is changed to the new price upon
//clicking of either button
function liveRecv(data) {
msgCurrentPrice.innerText = `The current price is ${data.current_price}`;
let nextBuy = data.current_price + 10;
buyBtn.value = nextBuy;
buyBtn.innerText = `Buy at ${nextBuy} dollars`;
let nextSell = data.current_price - 10;
sellBtn.value = nextSell;
sellBtn.innerText = `Sell at ${nextSell} dollars`;
}
//loads the liveSend function when the page is full loaded
document.addEventListener("DOMContentLoaded", function (event) {
liveSend({});
});
</script>
{{ endblock }}
---------------------------------------
Here is the python file:
----------------------------------------
from otree.api import *
c = Currency
doc = """
Your app description
"""
#creating the roles of bad tip, middle tip, and good tip
class Constants(BaseConstants):
name_in_url = 'stonkz'
instructions_template = 'stonkz/instructions.html'
players_per_group = None
num_rounds = 1
bad_tip_role = 'Bad tip'
middle_tip_role = 'Middle tip'
good_tip_role = 'Good tip'
class Subsession(BaseSubsession):
pass
class Group(BaseGroup):
current_price = models.IntegerField(initial=100)
new_price = models.IntegerField(initial=100)
auction_timeout = models.FloatField()
def get_state(group: Group):
return dict(
current_price=group.current_price,
new_price=group.new_price,
)
class Player(BasePlayer):
pass
class Intro(Page):
pass
#Waits for all players to arrive and sets the time of the round to 120 seconds
class WaitToStart(WaitPage):
@staticmethod
def after_all_players_arrive(group: Group):
import time
group.auction_timeout = time.time() + 120
# PAGES
class Bid(Page):
@staticmethod
def get_timeout_seconds(player: Player):
import time
group = player.group
return group.auction_timeout - time.time()
@staticmethod
def js_vars(player: Player):
return dict(my_id=player.id_in_group)
#figure out what has to happen here to change the variables
@staticmethod
def live_method(player: Player, data):
group = player.group
my_id = player.id_in_group
if data:
if data > group.current_price:
group.new_price = group.current_price
group.current_price = data
return {0: get_state(group)}
elif data < group.current_price:
group.new_price = group.current_price
group.current_price = data
return {0: get_state(group)}
else:
return {0: get_state(group)}
class Results(Page):
pass
page_sequence = [Intro, WaitToStart, Bid, Results]