summaryrefslogtreecommitdiff
path: root/scenes/stockticker/stonks.gd
blob: 127938267d5026c6211e9141b28f67c74e599236 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
extends Node2D

signal buy(amount)
signal sell(amount)

const MAX_PRICES = 15

const Y_START = 60
const Y_END = 356
const X_START = 50
const X_END = 1000

var price_label
var shares_label
var top_label
var mid_label
var bottom_label
var darksouls_background: Sprite2D
var darksouls_text: Label

var price_history = []
var base_pos_mult = 0.5 # no size limit
var base_neg_mult = 0.5 # probably keep this below 1

var hype_mult = 1.0
var hype_decr = 0.1
var hype_inc = 0.05
var panic_mult = 1.0
var panic_decr = 0.1
var panic_inc = 0.01

var bailout_counter = 0
var bailout_time = 1

var bailout_price = Big.new(5)
var start_val = Big.new(5)
var prev_price = start_val

var shares = 0

func handle_bailout(new_price: Big) -> Big:
	if bailout_counter < bailout_time:
		new_price = Big.new(0)
		bailout_counter += 1
	else:
		darksouls_background.visible = true
		darksouls_text.visible = true
		darksouls_text.text = "Bailed Out"
		new_price = bailout_price
		bailout_counter = 0
		bailout_time *= 2
		panic_mult = 1.0
		hype_mult = 1.0
		
	return new_price
	
func draw_stonks(minval: Big, maxval: Big) -> void:
	var stonks: Line2D = $Stonks
	stonks.clear_points()
	
	var index = 0
	var x_delta = (X_END - X_START)/float(len(price_history)-1)
	var y_range = Big.new(Y_END - Y_START)
	var price_range = maxval.minus(minval)
	for price: Big in price_history:
		var x_pos = x_delta * index + X_START
		var y_pos = Y_END
		if price_range.isGreaterThan(0.001):
			var price_ratio = (price.minus(minval)).dividedBy(price_range)
			y_pos = float(Big.new(Y_END).minus(y_range.times(price_ratio)).toString())
		var pos = Vector2(x_pos, y_pos)
		stonks.add_point(pos, index)
		index += 1
	
func get_min_price() -> Big:
	var minval = Big.new(-1)
	for price in price_history:
		if price.isLessThan(minval) or minval.isLessThan(0):
			minval = price
	return minval
	
func get_max_price() -> Big:
	var maxval = Big.new(-1)
	for price in price_history:
		if price.isGreaterThan(maxval):
			maxval = price
	return maxval

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	price_label = $"Price Label"
	shares_label = $"Shares Held Label"
	top_label = $Top
	mid_label = $Middle
	bottom_label = $Bottom
	darksouls_background = $DarkSoulsTextBox
	darksouls_text = $DarkSoulsLabel
	
	price_label.text = "Price:\n$%s" % start_val.toString()
	price_history.push_front(start_val)
	
	shares_label.text = "Shares\nHeld:%d" % shares

 
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta: float) -> void:
	pass


func _on_timer_timeout() -> void:
	darksouls_background.visible = false
	darksouls_text.visible = false
	var new_price = prev_price
	
	hype_mult -= hype_decr
	if hype_mult < 1: hype_mult = 1.0
	
	panic_mult -= panic_decr
	if panic_mult < 1: panic_mult = 1.0
		
	if prev_price.isLessThanOrEqualTo(0):
		new_price = handle_bailout(new_price)
	elif randf() < 0.5:
		var mult = Big.new(1).plus(Big.new(base_pos_mult * hype_mult * randf()))
		new_price = new_price.times(mult)
	else:
		var mult = Big.new(1).minus(Big.new(base_neg_mult * panic_mult * randf()))
		new_price = new_price.times(mult)
		
	if new_price.isLessThan(1) or new_price.toString()[0] == '-':
		if bailout_counter == 0:
			darksouls_background.visible = true
			darksouls_text.visible = true
			darksouls_text.text = "Stock Bankrupt"
			new_price = Big.new(0)
			shares = 0
			shares_label.text = "Shares\nHeld:%d" % shares
		
	if len(price_history) >= MAX_PRICES:
		price_history.pop_front()
	price_history.push_back(new_price)
	prev_price = new_price
	
	price_label.text = "Price:\n$%s" % new_price.toString()
	
	var min_price = get_min_price()
	var max_price = get_max_price()
	var mean_price = min_price.plus(max_price).dividedBy(2)
	
	top_label.text = "%s" % max_price.toScientific()
	mid_label.text = "%s" % mean_price.toScientific()
	bottom_label.text = "%s" % min_price.toScientific()
	
	draw_stonks(min_price, max_price)


func _on_buy_button_button_up() -> void:
	if shares < 100 and prev_price.isGreaterThan(0):
		shares += 1
		shares_label.text = "Shares\nHeld:%d" % shares
		hype_mult += hype_inc
		buy.emit(prev_price)


func _on_sell_button_button_up() -> void:
	if shares > 0:
		shares -= 1
		shares_label.text = "Shares\nHeld:%d" % shares
		panic_mult += panic_inc
		sell.emit(prev_price)