A fun saturday morning simulation
After walking the dogs this morning, I peaked at twitter, and found this
For those who prefer text to the image, the question is posed, what is the probability of stock B being of higher value than A, given both start with the initial value of $100/share. Stock A rises in value by 10% per year, while B either rises 30% or falls 10% in value with a even probability of either outcome.
One can solve this analytically, and arrive at a simple closed form solution. That solution works out to be about 37.8% probability of B being higher than A.
But I wanted to write a quick simulation. Because I've got this shiny tool (Julia Language) and it is designed to make building code easy, and avoid getting in your way. Its also fast, as it is a compiled language.
So I threw this code together in about 10 minutes.
#!/usr/bin/env julia
# solve this: https://twitter.com/10kdiver/status/1459494548443332611
using Printf
N = 100000 # number of samples
y = 10 # number of years
function A_value(y::Int64)
v = 100 # starting value
dv = 0.10 # fixed return rate
return v*(1+dv)^y
end
function B_value(y::Int64)
v = 100 # starting value
# dv set to either 0.30 or -0.10 with 0.5 probability for each value
for y in 1:y
dv = -0.1
if round(rand()) == 1 # assumes rand() is uniform ...
dv = 0.3
end
v *= (1+dv)
end
return v
end
A,B = 0,0
for s in 1:N
if A_value(y) > B_value(y)
global A += 1
else
global B += 1
end
end
@printf( "after N=%i simulations, value of B > A is %g percent \n",N,100.0*B/(A+B))
Here, I create 2 simple functions that return A and B values given an argument of y years. Since B value is effectively stochastic, B will likely be different every time the outer for s in 1:N
loop executes. Counters for which value is higher are incremented when the values are determined.
At the end, we simply print out the number of simulations, and the percent of the time that B was greater than A in our simulation.
joe@lrrr:~/play/stock$ ./stock.jl
after N=100000 simulations, value of B > A is 37.86 percent
Note a few specific elements here. First, the use of global
in the loops. This is because we defined global variables A,B = 0,0
and the loops have a local variable context. If we enclosed all of the computation in a function scope, this wouldn't be an issue. The global
keyword enables the loop context to use/update the global variable. This was a change in the 1.6.x series of Julia.
Second, note the use of the @printf
macro. I'd honestly prefer a builtin function for this, but using Printf
is not a hard pill to swallow. Some of us (old grumpy folks) like our printf
/ sprintf
functions.
Most important for me, note the structure is not a function of the layout. That is, I can't introduce a logic bug in this code with an errant space bar press. All structures are terminated by end
.
My goal accomplished, I have simulated. All runs done on my linux laptops. Code edited using atom editor.