JuliaForDataAnalysis/ch14.jl

159 lines
3.7 KiB
Julia

# Bogumił Kamiński, 2022
# Codes for chapter 14
# Codes for section 14.1
using Plots
using Statistics
X = [1.0, 1.1, 1.3, 1.2, 1.2]
T = 1.0
m = 4
Y = mean(X)
K = 1.05
plot(range(0.0, T; length=m+1), X;
xlabel="T", legend=false, color="black")
hline!([Y], color="gray", lw=3, ls=:dash)
hline!([K], color="gray", lw=3, ls=:dot)
annotate!([(T, Y + 0.01, "Y"),
(T, K + 0.01, "K"),
(T, X[end] + 0.01, "X")])
using DataFrames
using Random
Random.seed!(1234);
X0, T, s, r, m = 1.0, 2.0, 0.2, 0.1, 4
gbm = DataFrame(X=X0, t=0.0)
for i in 1:m
Z = randn()
log_return = (r - s^2/2) * T/m + s * sqrt(T/m) * Z
next_X = gbm.X[end] * exp(log_return)
next_t = gbm.t[end] + T/m
push!(gbm, (next_X, next_t))
end
gbm
# Codes for section 14.2
# start Julia with and additional -t4 command line switch
Threads.nthreads()
# Code for listing 14.1
function payoff_asian_sample(T, X0, K, r, s, m)::Float64
X = X0
sumX = X
d = T / m
for i in 1:m
X *= exp((r - s^2 / 2) * d + s * sqrt(d) * randn())
sumX += X
end
Y = sumX / (m + 1)
return exp(-r * T) * max(Y - K, 0)
end
# Code for checking the results of the payoff simulation
payoff_asian_sample(1.0, 50.0, 55.0, 0.05, 0.3, 200)
payoff_asian_sample(1.0, 50.0, 55.0, 0.05, 0.3, 200)
payoff_asian_sample(1.0, 50.0, 55.0, 0.05, 0.3, 200)
# Benchmarking map
using BenchmarkTools
@btime map(i -> payoff_asian_sample(1.0, 50.0, 55.0, 0.05, 0.3, 200), 1:10_000);
using ThreadsX
@btime ThreadsX.map(i -> payoff_asian_sample(1.0, 50.0, 55.0, 0.05, 0.3, 200), 1:10_000);
# Codes for section 14.3
# Code for listing 14.2
using Statistics
function asian_value(T, X0, K, r, s, m, max_time)
result = Float64[]
start_time = time()
while time() - start_time < max_time
append!(result, ThreadsX.map(i -> payoff_asian_sample(T, X0, K, r, s, m), 1:10_000))
end
n = length(result)
mv = mean(result)
sdv = std(result)
lo95 = mv - 1.96 * sdv / sqrt(n)
hi95 = mv + 1.96 * sdv / sqrt(n)
zero = mean(==(0), result)
return (; n, mv, lo95, hi95, zero)
end
# Code for example of the mean function
mean(x -> x ^ 2, [1, 2, 3])
eq0 = ==(0)
eq0(1)
eq0(0)
# Code for shorthand NamedTuple notation
val1 = 10
val2 = "x"
(; val1, val2)
# Testing asian_value function
@time asian_value(1.0, 50.0, 55.0, 0.05, 0.3, 200, 0.25)
@time asian_value(1.0, 50.0, 55.0, 0.05, 0.3, 200, 0.25)
@time asian_value(1.0, 50.0, 55.0, 0.05, 0.3, 200, 0.25)
# Converting NamedTuple to JSON response
using Genie
Genie.Renderer.Json.json((firstname="Bogumił", lastname="Kamiński"))
# Codes for section 14.4
# Start a new Julia session
using HTTP
using JSON3
req = HTTP.post("http://127.0.0.1:8000",
["Content-Type" => "application/json"],
JSON3.write((K=55.0, max_time=0.25)))
JSON3.read(req.body)
JSON3.write((K=55.0, max_time=0.25))
HTTP.post("http://127.0.0.1:8000",
["Content-Type" => "application/json"],
JSON3.write((K="", max_time=0.25)))
using DataFrames
df = DataFrame(K=30:2:80, max_time=0.25)
df.data = map(df.K, df.max_time) do K, max_time
@show K
@time req = HTTP.post("http://127.0.0.1:8000",
["Content-Type" => "application/json"],
JSON3.write((;K, max_time)))
return JSON3.read(req.body)
end;
df
all(x -> x.status == "OK", df.data)
small_df = DataFrame(x=[(a=1, b=2), (a=3, b=4), (a=5, b=6)])
transform(small_df, :x => identity => AsTable)
transform(small_df, :x => AsTable)
df2 = select(df, :K, :data => ByRow(x -> x.value) => AsTable)
using Plots
plot(plot(df2.K, df2.mv; legend=false,
xlabel="K", ylabel="expected value"),
plot(df2.K, df2.zero; legend=false,
xlabel="K", ylabel="probability of zero"))