Skip to content

Commit cb2995a

Browse files
authored
Merge branch 'main' into update_markov_asset
2 parents 211ec24 + c027427 commit cb2995a

File tree

11 files changed

+821
-40
lines changed

11 files changed

+821
-40
lines changed

.github/workflows/cache.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ jobs:
3636
run: |
3737
jb build lectures --path-output ./ -W --keep-going
3838
- name: Upload Execution Reports
39-
uses: actions/upload-artifact@v4
39+
uses: actions/upload-artifact@v5
4040
if: failure()
4141
with:
4242
name: execution-reports
4343
path: _build/html/reports
4444
- name: Upload "_build" folder (cache)
45-
uses: actions/upload-artifact@v4
45+
uses: actions/upload-artifact@v5
4646
with:
4747
name: build-cache
4848
path: _build

.github/workflows/ci.yml

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ on:
1111
jobs:
1212
preview:
1313
runs-on: "runs-on=${{ github.run_id }}/family=g4dn.2xlarge/image=quantecon_ubuntu2404/disk=large"
14+
env:
15+
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
16+
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
1417
steps:
1518
- uses: actions/checkout@v5
1619
with:
@@ -57,7 +60,7 @@ jobs:
5760
mkdir -p _build/html/_notebooks
5861
cp -u _build/jupyter/*.ipynb _build/html/_notebooks
5962
- name: Upload Execution Reports (Download Notebooks)
60-
uses: actions/upload-artifact@v4
63+
uses: actions/upload-artifact@v5
6164
if: failure()
6265
with:
6366
name: execution-reports-notebooks
@@ -69,7 +72,7 @@ jobs:
6972
mkdir -p _build/html/_pdf
7073
cp -u _build/latex/*.pdf _build/html/_pdf
7174
- name: Upload Execution Reports (LaTeX)
72-
uses: actions/upload-artifact@v4
75+
uses: actions/upload-artifact@v5
7376
if: failure()
7477
with:
7578
name: execution-reports
@@ -80,7 +83,7 @@ jobs:
8083
run: |
8184
jb build lectures --path-output ./ -n -W --keep-going
8285
- name: Upload Execution Reports (HTML)
83-
uses: actions/upload-artifact@v4
86+
uses: actions/upload-artifact@v5
8487
if: failure()
8588
with:
8689
name: execution-reports
@@ -168,6 +171,11 @@ jobs:
168171
fi
169172
- name: Preview Deploy to Netlify
170173
id: netlify-deploy
174+
if: >
175+
github.actor != 'dependabot[bot]' &&
176+
(github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) &&
177+
env.NETLIFY_AUTH_TOKEN != '' &&
178+
env.NETLIFY_SITE_ID != ''
171179
shell: bash -l {0}
172180
run: |
173181
if [ "${{ github.event_name }}" = "pull_request" ]; then
@@ -238,11 +246,16 @@ jobs:
238246
echo "🎯 Preview page: ${deploy_url}/${{ github.event.inputs.preview_page }}"
239247
fi
240248
fi
241-
env:
242-
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
243-
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
249+
- name: Skip Netlify Deploy (no secrets or untrusted actor)
250+
if: >
251+
!(github.actor != 'dependabot[bot]' &&
252+
(github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) &&
253+
env.NETLIFY_AUTH_TOKEN != '' &&
254+
env.NETLIFY_SITE_ID != '')
255+
run: |
256+
echo "Skipping Netlify preview deploy: secrets unavailable or actor not trusted (actor=${{ github.actor }})"
244257
- name: Post PR Comment with Preview Links
245-
if: github.event_name == 'pull_request'
258+
if: github.event_name == 'pull_request' && steps.netlify-deploy.outputs.deploy_url != ''
246259
uses: actions/github-script@v7
247260
with:
248261
script: |

.github/workflows/collab.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ jobs:
4545
run: |
4646
jb build lectures --path-output ./ -n -W --keep-going
4747
- name: Upload Execution Reports
48-
uses: actions/upload-artifact@v4
48+
uses: actions/upload-artifact@v5
4949
if: failure()
5050
with:
5151
name: execution-reports
@@ -85,7 +85,7 @@ jobs:
8585
EOF
8686
- name: Create Issue on Execution Failure
8787
if: failure()
88-
uses: peter-evans/create-issue-from-file@v5
88+
uses: peter-evans/create-issue-from-file@v6
8989
with:
9090
title: "Weekly Colab Execution Check Failed - ${{ github.run_id }}"
9191
content-filepath: execution-failure-report.md

.github/workflows/linkcheck.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
args: --accept 200,403,503 *.html
2525
- name: Create Issue From File
2626
if: steps.lychee.outputs.exit_code != 0
27-
uses: peter-evans/create-issue-from-file@v5
27+
uses: peter-evans/create-issue-from-file@v6
2828
with:
2929
title: Link Checker Report
3030
content-filepath: ./lychee/out.md

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ jobs:
5959
run: |
6060
jb build lectures --path-output ./ --builder=custom --custom-builder=jupyter -n -W --keep-going
6161
zip -r download-notebooks.zip _build/jupyter
62-
- uses: actions/upload-artifact@v4
62+
- uses: actions/upload-artifact@v5
6363
with:
6464
name: download-notebooks
6565
path: download-notebooks.zip

lectures/_config.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ sphinx:
120120
schelling: https://intro.quantecon.org/schelling.html
121121
scalar_dynam: https://intro.quantecon.org/scalar_dynam.html
122122
complex_and_trig: https://intro.quantecon.org/complex_and_trig.html
123+
# sphinx-proof
124+
proof_minimal_theme: true
125+
# sphinx-tojupyter
123126
tojupyter_static_file_path: ["source/_static", "_static"]
124127
tojupyter_target_html: true
125128
tojupyter_urlpath: "https://python.quantecon.org/"

lectures/_static/quant-econ.bib

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,62 @@
33
Note: Extended Information (like abstracts, doi, url's etc.) can be found in quant-econ-extendedinfo.bib file in _static/
44
###
55
6+
7+
@article{harsanyi1968games,
8+
title={Games with Incomplete Information Played by ``{B}ayesian'' Players, {I}--{III} Part {II}. {B}ayesian Equilibrium Points},
9+
author={Harsanyi, John C.},
10+
journal={Management Science},
11+
volume={14},
12+
number={5},
13+
pages={320--334},
14+
year={1968},
15+
publisher={INFORMS}
16+
}
17+
18+
@article{harsanyi1968games3,
19+
title={Games with Incomplete Information Played by ``{B}ayesian'' Players, {I}--{III} Part {III}. {T}he Basic Probability Distribution of the Game},
20+
author={Harsanyi, John C.},
21+
journal={Management Science},
22+
volume={14},
23+
number={7},
24+
pages={486--502},
25+
year={1968},
26+
publisher={INFORMS}
27+
}
28+
29+
@article{harsanyi1967games,
30+
title={Games with Incomplete Information Played by ``{B}ayesian'' Players, {I}--{III} Part {I}. {T}he Basic Model},
31+
author={Harsanyi, John C.},
32+
journal={Management Science},
33+
volume={14},
34+
number={3},
35+
pages={159--182},
36+
year={1967},
37+
publisher={INFORMS}
38+
}
39+
40+
@article{miller1977risk,
41+
title={Risk, uncertainty, and divergence of opinion},
42+
author={Miller, Edward M},
43+
journal={The Journal of finance},
44+
volume={32},
45+
number={4},
46+
pages={1151--1168},
47+
year={1977},
48+
publisher={JSTOR}
49+
}
50+
51+
@article{jeffreys1946invariant,
52+
title={An invariant form for the prior probability in estimation problems},
53+
author={Jeffreys, Harold},
54+
journal={Proceedings of the Royal Society of London. Series A. Mathematical and Physical Sciences},
55+
volume={186},
56+
number={1007},
57+
pages={453--461},
58+
year={1946},
59+
publisher={The Royal Society London}
60+
}
61+
662
@article{blume2018case,
763
title={A case for incomplete markets},
864
author={Blume, Lawrence E and Cogley, Timothy and Easley, David A and Sargent, Thomas J and Tsyrennikov, Viktor},
@@ -1378,6 +1434,16 @@ @article{HarrKreps1978
13781434
pages = {323-336}
13791435
}
13801436

1437+
@article{Morris1996,
1438+
author = {Stephen Morris},
1439+
title = {Speculative Investor Behavior and Learning},
1440+
journal = {The Quarterly Journal of Economics},
1441+
year = {1996},
1442+
volume = {111},
1443+
number = {4},
1444+
pages = {1111-1133}
1445+
}
1446+
13811447
@article{pal2013,
13821448
title = {Fitted value function iteration with probability one contractions},
13831449
author = {P{\'a}l, Jen{\H{o}} and Stachurski, John},

lectures/_toc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ parts:
112112
- file: markov_asset
113113
- file: ge_arrow
114114
- file: harrison_kreps
115+
- file: morris_learn
115116
- caption: Data and Empirics
116117
numbered: true
117118
chapters:

lectures/harrison_kreps.md

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ jupytext:
33
text_representation:
44
extension: .md
55
format_name: myst
6+
format_version: 0.13
7+
jupytext_version: 1.17.1
68
kernelspec:
7-
display_name: Python 3
8-
language: python
99
name: python3
10+
display_name: Python 3 (ipykernel)
11+
language: python
1012
---
1113

1214
(harrison_kreps)=
@@ -29,10 +31,9 @@ kernelspec:
2931

3032
In addition to what's in Anaconda, this lecture uses following libraries:
3133

32-
```{code-cell} ipython
33-
---
34-
tags: [hide-output]
35-
---
34+
```{code-cell} ipython3
35+
:tags: [hide-output]
36+
3637
!pip install quantecon
3738
```
3839

@@ -51,7 +52,7 @@ The model features
5152

5253
Let's start with some standard imports:
5354

54-
```{code-cell} ipython
55+
```{code-cell} ipython3
5556
import numpy as np
5657
import quantecon as qe
5758
import scipy.linalg as la
@@ -131,15 +132,15 @@ But in state $1$, a type $a$ investor is more pessimistic about next period's
131132

132133
The stationary (i.e., invariant) distributions of these two matrices can be calculated as follows:
133134

134-
```{code-cell} python3
135+
```{code-cell} ipython3
135136
qa = np.array([[1/2, 1/2], [2/3, 1/3]])
136137
qb = np.array([[2/3, 1/3], [1/4, 3/4]])
137138
mca = qe.MarkovChain(qa)
138139
mcb = qe.MarkovChain(qb)
139140
mca.stationary_distributions
140141
```
141142

142-
```{code-cell} python3
143+
```{code-cell} ipython3
143144
mcb.stationary_distributions
144145
```
145146

@@ -270,7 +271,7 @@ The first two rows of the table report $p_a(s)$ and $p_b(s)$.
270271
271272
Here's a function that can be used to compute these values
272273
273-
```{code-cell} python3
274+
```{code-cell} ipython3
274275
def price_single_beliefs(transition, dividend_payoff, β=.75):
275276
"""
276277
Function to Solve Single Beliefs
@@ -399,7 +400,7 @@ Investors of type $a$ want to sell the asset in state $1$ while investors of typ
399400
400401
Here's code to solve for $\bar p$, $\hat p_a$ and $\hat p_b$ using the iterative method described above
401402
402-
```{code-cell} python3
403+
```{code-cell} ipython3
403404
def price_optimistic_beliefs(transitions, dividend_payoff, β=.75,
404405
max_iter=50000, tol=1e-16):
405406
"""
@@ -414,15 +415,15 @@ def price_optimistic_beliefs(transitions, dividend_payoff, β=.75,
414415
p_old = p_new
415416
p_new = β * np.max([q @ p_old
416417
+ q @ dividend_payoff for q in transitions],
417-
1)
418+
axis=0)
418419
419420
# If we succeed in converging, break out of for loop
420421
if np.max(np.sqrt((p_new - p_old)**2)) < tol:
421422
break
422423
423424
ptwiddle = β * np.min([q @ p_old
424425
+ q @ dividend_payoff for q in transitions],
425-
1)
426+
axis=0)
426427
427428
phat_a = np.array([p_new[0], ptwiddle[1]])
428429
phat_b = np.array([ptwiddle[0], p_new[1]])
@@ -444,8 +445,8 @@ Instead of equation {eq}`hakr2`, the equilibrium price satisfies
444445
\check p(s)
445446
= \beta \min
446447
\left\{
447-
P_a(s,1) \check p(0) + P_a(s,1) ( 1 + \check p(1)) ,\;
448-
P_b(s,1) \check p(0) + P_b(s,1) ( 1 + \check p(1))
448+
P_a(s,0) \check p(0) + P_a(s,1) ( 1 + \check p(1)) ,\;
449+
P_b(s,0) \check p(0) + P_b(s,1) ( 1 + \check p(1))
449450
\right\}
450451
```
451452
@@ -467,7 +468,7 @@ Constraints on short sales prevent that.
467468
468469
Here's code to solve for $\check p$ using iteration
469470
470-
```{code-cell} python3
471+
```{code-cell} ipython3
471472
def price_pessimistic_beliefs(transitions, dividend_payoff, β=.75,
472473
max_iter=50000, tol=1e-16):
473474
"""
@@ -482,7 +483,7 @@ def price_pessimistic_beliefs(transitions, dividend_payoff, β=.75,
482483
p_old = p_new
483484
p_new = β * np.min([q @ p_old
484485
+ q @ dividend_payoff for q in transitions],
485-
1)
486+
axis=0)
486487
487488
# If we succeed in converging, break out of for loop
488489
if np.max(np.sqrt((p_new - p_old)**2)) < tol:
@@ -512,8 +513,6 @@ Scheinkman extracts insights about the effects of financial regulations on bubbl
512513
513514
He emphasizes how limiting short sales and limiting leverage have opposite effects.
514515
515-
## Exercises
516-
517516
```{exercise-start}
518517
:label: hk_ex1
519518
```
@@ -570,7 +569,7 @@ We'll use these transition matrices when we present our solution of exercise 1 b
570569
First, we will obtain equilibrium price vectors with homogeneous beliefs, including when all
571570
investors are optimistic or pessimistic.
572571
573-
```{code-cell} python3
572+
```{code-cell} ipython3
574573
qa = np.array([[1/2, 1/2], [2/3, 1/3]]) # Type a transition matrix
575574
qb = np.array([[2/3, 1/3], [1/4, 3/4]]) # Type b transition matrix
576575
# Optimistic investor transition matrix
@@ -595,7 +594,7 @@ for transition, label in zip(transitions, labels):
595594
We will use the price_optimistic_beliefs function to find the price under
596595
heterogeneous beliefs.
597596
598-
```{code-cell} python3
597+
```{code-cell} ipython3
599598
opt_beliefs = price_optimistic_beliefs([qa, qb], dividendreturn)
600599
labels = ['p_optimistic', 'p_hat_a', 'p_hat_b']
601600
@@ -614,4 +613,4 @@ with **permanently optimistic** investors - this is due to the marginal investor
614613
```{solution-end}
615614
```
616615
617-
[^f1]: By assuming that both types of agents always have "deep enough pockets" to purchase all of the asset, the model takes wealth dynamics off the table. The Harrison-Kreps model generates high trading volume when the state changes either from 0 to 1 or from 1 to 0.
616+
[^f1]: By assuming that both types of agents always have "deep enough pockets" to purchase all of the asset, the model takes wealth dynamics off the table. The Harrison-Kreps model generates high trading volume when the state changes either from 0 to 1 or from 1 to 0.

0 commit comments

Comments
 (0)