Skip to content

Commit 4f4562c

Browse files
authored
MAINT: Simplify pages and migrate to gh-pages based deployments (#6)
* MAINT: integrate book-dp1-public-companion into repo * copy contents of html rather than folder * revise copy of contents * check why cp -r is not working as expected * try /* * change name of workflow * update config and pdf * enable sphinx-design clickable card * fix reference to sphinx_design * try relative link back to landing page * remove code-book and reorganise public code into directories * simplify publish github workflows * move slides to easy place to update * update gitignore to remove built assets * add a way back to landing page * add a code page * update code page * update title for code page
1 parent 6f9bf11 commit 4f4562c

File tree

168 files changed

+11362
-17
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

168 files changed

+11362
-17
lines changed

.github/workflows/ci.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Build Project [using jupyter-book]
2+
on: [push]
3+
jobs:
4+
preview:
5+
runs-on: ubuntu-latest
6+
steps:
7+
- name: Checkout
8+
uses: actions/checkout@v4
9+
# Push website files to netlify
10+
- name: Preview Deploy to Netlify
11+
uses: nwtgck/actions-netlify@v2
12+
with:
13+
publish-dir: website
14+
production-branch: main
15+
github-token: ${{ secrets.GITHUB_TOKEN }}
16+
deploy-message: "Preview Deploy from GitHub Actions"
17+
env:
18+
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
19+
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

.github/workflows/publish.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Assemble & Publish to GH-PAGES
2+
on:
3+
push:
4+
tags:
5+
- 'publish*'
6+
jobs:
7+
publish:
8+
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Checkout
12+
uses: actions/checkout@v4
13+
- name: Deploy website to gh-pages
14+
uses: peaceiris/actions-gh-pages@v3
15+
with:
16+
github_token: ${{ secrets.GITHUB_TOKEN }}
17+
publish_dir: website
18+
cname: dp.quantecon.org

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
.DS_Store
2-
*./DS_Store
2+
*./DS_Store
3+
.ipynb_checkpoints
4+
__pycache__

LICENSE

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2022, QuantEcon
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
1. Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
3. Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ Public repo for the textbook **Dynamic Programming Volume 1** by [Thomas J.
44
Sargent](http://www.tomsargent.com/) and [John
55
Stachurski](https://johnstachurski.net/).
66

7-
## Website
7+
| Folder | Description |
8+
|--------|-------------|
9+
| website | HTML files that build the website |
10+
| pdf | PDF of the book |
11+
| code | Public source of `py` and `jl` code |
812

9-
The website is currently being built with `jekyll`
13+
## PDF
14+
15+
The PDF is available in `pdf/dp.pdf`
16+
17+
Comments and feedback are very welcome.
18+
The easiest way to provide feedback is to open an issue above.

code/jl/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
The source code here is read into the private repo via a symbolic link.
2+
3+
If you edit a jl file here and rerun to produce a PDF, it needs to be shifted to
4+
code_book/figures, which is also connected to the private repo via a sym link.

code/jl/american_option.jl

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
"""
2+
Valuation for finite-horizon American call options in discrete time.
3+
4+
"""
5+
6+
include("s_approx.jl")
7+
using QuantEcon, LinearAlgebra, IterTools
8+
9+
"Creates an instance of the option model with log S_t = Z_t + W_t."
10+
function create_american_option_model(;
11+
n=100, μ=10.0, # Markov state grid size and mean value
12+
ρ=0.98, ν=0.2, # persistence and volatility for Markov state
13+
s=0.3, # volatility parameter for W_t
14+
r=0.01, # interest rate
15+
K=10.0, T=200) # strike price and expiration date
16+
t_vals = collect(1:T+1)
17+
mc = tauchen(n, ρ, ν)
18+
z_vals, Q = mc.state_values .+ μ, mc.p
19+
w_vals, φ, β = [-s, s], [0.5, 0.5], 1 / (1 + r)
20+
e(t, i_w, i_z) = (t T) * (z_vals[i_z] + w_vals[i_w] - K)
21+
return (; t_vals, z_vals, w_vals, Q, φ, T, β, K, e)
22+
end
23+
24+
"The continuation value operator."
25+
function C(h, model)
26+
(; t_vals, z_vals, w_vals, Q, φ, T, β, K, e) = model
27+
Ch = similar(h)
28+
z_idx, w_idx = eachindex(z_vals), eachindex(w_vals)
29+
for (t, i_z) in product(t_vals, z_idx)
30+
out = 0.0
31+
for (i_w′, i_z′) in product(w_idx, z_idx)
32+
t′ = min(t + 1, T + 1)
33+
out += max(e(t′, i_w′, i_z′), h[t′, i_z′]) *
34+
Q[i_z, i_z′] * φ[i_w′]
35+
end
36+
Ch[t, i_z] = β * out
37+
end
38+
return Ch
39+
end
40+
41+
"Compute the continuation value function by successive approx."
42+
function compute_cvf(model)
43+
h_init = zeros(length(model.t_vals), length(model.z_vals))
44+
h_star = successive_approx(h -> C(h, model), h_init)
45+
return h_star
46+
end
47+
48+
49+
# Plots
50+
51+
using PyPlot
52+
using LaTeXStrings
53+
PyPlot.matplotlib[:rc]("text", usetex=true) # allow tex rendering
54+
fontsize=16
55+
56+
57+
function plot_contours(; savefig=false,
58+
figname="./figures/american_option_1.pdf")
59+
60+
model = create_american_option_model()
61+
(; t_vals, z_vals, w_vals, Q, φ, T, β, K, e) = model
62+
h_star = compute_cvf(model)
63+
64+
fig, axes = plt.subplots(3, 1, figsize=(7, 11))
65+
z_idx, w_idx = eachindex(z_vals), eachindex(w_vals)
66+
H = zeros(length(w_vals), length(z_vals))
67+
68+
for (ax_index, t) in zip(1:3, (1, 195, 199))
69+
70+
ax = axes[ax_index, 1]
71+
72+
for (i_w, i_z) in product(w_idx, z_idx)
73+
H[i_w, i_z] = e(t, i_w, i_z) - h_star[t, i_z]
74+
end
75+
76+
cs1 = ax.contourf(w_vals, z_vals, transpose(H), alpha=0.5)
77+
ctr1 = ax.contour(w_vals, z_vals, transpose(H), levels=[0.0])
78+
plt.clabel(ctr1, inline=1, fontsize=13)
79+
plt.colorbar(cs1, ax=ax) #, format="%.6f")
80+
81+
ax.set_title(L"t=" * "$t", fontsize=fontsize)
82+
ax.set_xlabel(L"w", fontsize=fontsize)
83+
ax.set_ylabel(L"z", fontsize=fontsize)
84+
85+
end
86+
87+
fig.tight_layout()
88+
if savefig
89+
fig.savefig(figname)
90+
end
91+
plt.show()
92+
end
93+
94+
95+
function plot_strike(; savefig=false,
96+
fontsize=12,
97+
figname="./figures/american_option_2.pdf")
98+
99+
model = create_american_option_model()
100+
(; t_vals, z_vals, w_vals, Q, φ, T, β, K, e) = model
101+
h_star = compute_cvf(model)
102+
103+
# Built Markov chains for simulation
104+
z_mc = MarkovChain(Q, z_vals)
105+
P_φ = zeros(length(w_vals), length(w_vals))
106+
for i in eachindex(w_vals) # Build IID chain
107+
P_φ[i, :] = φ
108+
end
109+
w_mc = MarkovChain(P_φ, w_vals)
110+
111+
112+
y_min = minimum(z_vals) + minimum(w_vals)
113+
y_max = maximum(z_vals) + maximum(w_vals)
114+
fig, axes = plt.subplots(3, 1, figsize=(7, 12))
115+
116+
for ax in axes
117+
118+
# Generate price series
119+
z_draws = simulate_indices(z_mc, T, init=Int(length(z_vals) / 2 - 10))
120+
w_draws = simulate_indices(w_mc, T)
121+
s_vals = z_vals[z_draws] + w_vals[w_draws]
122+
123+
# Find the exercise date, if any.
124+
exercise_date = T + 1
125+
for t in 1:T
126+
if e(t, w_draws[t], z_draws[t]) h_star[w_draws[t], z_draws[t]]
127+
exercise_date = t
128+
end
129+
end
130+
131+
@assert exercise_date T "Option not exercised."
132+
133+
# Plot
134+
ax.set_ylim(y_min, y_max)
135+
ax.set_xlim(1, T)
136+
ax.fill_between(1:T, ones(T) * K, ones(T) * y_max, alpha=0.2)
137+
ax.plot(1:T, s_vals, label=L"S_t")
138+
ax.plot((exercise_date,), (s_vals[exercise_date]), "ko")
139+
ax.vlines((exercise_date,), 0, (s_vals[exercise_date]), ls="--", colors="black")
140+
ax.legend(loc="upper left", fontsize=fontsize)
141+
ax.text(-10, 11, "in the money", fontsize=fontsize, rotation=90)
142+
ax.text(-10, 7.2, "out of the money", fontsize=fontsize, rotation=90)
143+
ax.text(exercise_date-20, 6, #s_vals[exercise_date]+0.8,
144+
"exercise date", fontsize=fontsize)
145+
ax.set_xticks((1, T))
146+
ax.set_yticks((y_min, y_max))
147+
end
148+
149+
if savefig
150+
fig.savefig(figname)
151+
end
152+
plt.show()
153+
end

code/jl/ar1_spec_rad.jl

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
"""
2+
3+
Compute r(L) for model
4+
5+
Zₜ = μ (1 - ρ) + ρ Zₜ₋₁ + σ εₜ
6+
β_t = b(Z_t)
7+
8+
The process is discretized using the Tauchen method with n states.
9+
"""
10+
11+
using LinearAlgebra, QuantEcon
12+
13+
function compute_mc_spec_rad(n, ρ, σ, μ, m, b)
14+
mc = tauchen(n, ρ, σ, μ * (1 - ρ), m)
15+
state_values, P = mc.state_values, mc.p
16+
17+
L = zeros(n, n)
18+
for i in 1:n
19+
for j in 1:n
20+
L[i, j] = b(state_values[i]) * P[i, j]
21+
end
22+
end
23+
r = maximum(abs.(eigvals(L)))
24+
return r
25+
end
26+
27+
# Hubmer et al parameter values, p. 24 of May 17 2020 version.
28+
29+
n = 15
30+
ρ = 0.992
31+
σ = 0.0006
32+
μ = 0.944
33+
m = 4
34+
b(z) = z
35+
36+
println("Spectral radius of L in Hubmer et al.:")
37+
println(compute_mc_spec_rad(n, ρ, σ, μ, m, b))
38+
39+
# ## Hills et al 2019 EER
40+
41+
# For the empirical model,
42+
#
43+
# $$
44+
# Z_{t+1} = 1 - \rho + \rho Z_t + \sigma \epsilon_{t+1},
45+
# \quad \beta_t = \beta Z_t
46+
# $$
47+
#
48+
# with
49+
#
50+
# $$
51+
# \beta = 0.99875, \; \rho = 0.85, \; \sigma = 0.0062
52+
# $$
53+
#
54+
# They use 15 grid points on $[1-4.5\sigma_\delta, 1+4.5\sigma_\delta]$.
55+
56+
n = 15
57+
ρ = 0.85
58+
σ = 0.0062
59+
μ = 1
60+
m = 4.5
61+
beta = 0.99875
62+
b(z) = beta * z
63+
64+
println("Spectral radius of L in Hills et al.:")
65+
println(compute_mc_spec_rad(n, ρ, σ, μ, m, b))
66+
67+
# Let's run a simulation of the discount process.
68+
# Plots
69+
70+
using PyPlot
71+
using LaTeXStrings
72+
PyPlot.matplotlib[:rc]("text", usetex=true) # allow tex rendering
73+
fs=14
74+
75+
function plot_beta_sim(; T=80,
76+
savefig=false,
77+
figname="./figures/ar1_spec_rad.pdf")
78+
β_vals = zeros(T)
79+
Z = 1
80+
for t in 1:T
81+
β_vals[t] = beta * Z
82+
Z = 1 - ρ + ρ * Z + σ * randn()
83+
end
84+
85+
fig, ax = plt.subplots(figsize=(6, 3.8))
86+
87+
ax.plot(β_vals, label=L"\beta_t")
88+
ax.plot(1:T, ones(T), "k--", alpha=0.5, label=L"\beta=1")
89+
ax.set_yticks((0.97, 1.0, 1.03))
90+
ax.set_xlabel("time")
91+
ax.legend(frameon=false, fontsize=fs)
92+
93+
if savefig
94+
fig.savefig(figname)
95+
end
96+
plt.show()
97+
end

0 commit comments

Comments
 (0)