Skip to content

Commit 9a46004

Browse files
Tom's edits of new lecture June 15
1 parent 6f7d93b commit 9a46004

File tree

5 files changed

+372
-0
lines changed

5 files changed

+372
-0
lines changed

lectures/_static/quant-econ.bib

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,24 @@
33
Note: Extended Information (like abstracts, doi, url's etc.) can be found in quant-econ-extendedinfo.bib file in _static/
44
###
55
6+
@book{sargent2002big,
7+
title={The Big Problem of Small Change},
8+
author={Sargent, Thomas J and Velde, Fran{\c{c}}ois R},
9+
year={2002},
10+
publisher={Princeton University Press},
11+
address = {Princeton, New Jersey}
12+
}
13+
14+
@book{sargent2013rational,
15+
title={Rational Expectations and Inflation},
16+
author={Sargent, Thomas J},
17+
year={2013},
18+
publisher={Princeton University Press},
19+
address = {Princeton, New Jersey}
20+
}
21+
22+
23+
624
@incollection{sargent1982ends,
725
title={The ends of four big inflations},
826
author={Sargent, Thomas J},

lectures/_toc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ parts:
2323
- file: pv
2424
- file: cons_smooth
2525
- file: equalizing_difference
26+
- file: inflation_history
2627
- file: cagan_ree
2728
- file: cagan_adaptive
2829
- file: geom_series

lectures/datasets/chapter_3.xlsx

71.6 KB
Binary file not shown.

lectures/datasets/longprices.xls

380 KB
Binary file not shown.

lectures/inflation_history.md

Lines changed: 353 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,353 @@
1+
---
2+
jupytext:
3+
text_representation:
4+
extension: .md
5+
format_name: myst
6+
format_version: 0.13
7+
jupytext_version: 1.14.5
8+
kernelspec:
9+
display_name: Python 3 (ipykernel)
10+
language: python
11+
name: python3
12+
---
13+
14+
+++ {"user_expressions": []}
15+
16+
# Price Level Histories
17+
18+
## Ends of Four Big Inflations
19+
20+
21+
22+
We want to construct four graphs from "The Ends of Four Big Inflations" from chapter 3 of {cite}`
23+
24+
This is chapter 3 of the book **Rational Expectations and Inflation** that I shared with you a couple of days ago.
25+
26+
27+
```python
28+
import numpy as np
29+
import pandas as pd
30+
import matplotlib.pyplot as plt
31+
import matplotlib.dates as mdates
32+
import datetime
33+
```
34+
35+
```python
36+
!pip install xlrd
37+
```
38+
39+
The graphs depict logarithms of price levels during the early post World War I years for four countries:
40+
41+
* Figure 3.1, Retail prices Austria 1921-1924 (page 42)
42+
* Figure 3.2, Wholesale prices Hungary, 1921-1924 (page 43)
43+
* Figure 3.3, Wholesale prices, Poland, 1921-1924 (page 44)
44+
* Figure pd.dataframe(3.4, Wholesale prices, Germany, 1919-1924 (page 45)
45+
46+
Data underlying these graphs appear in the tables in the appendix; all of the data have been organized into a spreadsheet *chapter_3.xls* that I include in our dropbox folder.
47+
48+
The spreadsheet refers to the tables that I now describe for each of our four countries.
49+
50+
51+
## Tweak request for Jiacheng
52+
53+
* for each of the four countries, please delete the graphs of the "money supplies" and "real balances" in the right panels. So now we'll just have your excellent graphs of the price level and exchange rate
54+
55+
* for each graph please add a caption below the graph just saying the country name. Maybe Zejin can quickly tell you how to do this.
56+
57+
* for Poland I think that there are some additional price level data in the table, but their units have changed. Please take a look at figure 3.3. in the chapter. I am pretty sure that to draw that graph I just made a guess about the units change -- sort of using "continuity" -- and adjusted the units of the second series and spliced the series to get the one in figure 3.3. We can talk about this if you wish
58+
59+
* for Germany, I'd like to do another "splicing operation" to avoid the big jump down in the price series and the exchange rate series. What those jumps reflect is the "units change" associated with the "currency reform". It was a pure units change.
60+
61+
* Here is one idea -- make two versions of the graph in two separate graphs. The first version is what you have
62+
63+
* The second version does the "splicing" by converting the new units to the old so that there is no drop. Then the graphs will be "continuous.
64+
65+
* By comparing the graphs we can teach about the "currency reform"
66+
67+
68+
69+
* Comment: I really like the way you put the exchange rate and the price level on the same graph for each country. Overall the graphs are great -- really exciting to me! And I love the "long series" graph at the end.
70+
71+
* Thanks so much.
72+
73+
74+
75+
```python
76+
def process_entry(entry):
77+
"Clean each entry of a dataframe."
78+
79+
if type(entry) == str:
80+
# remove leading and trailing whitespace
81+
entry = entry.strip()
82+
# remove comma
83+
entry = entry.replace(',', '')
84+
85+
# remove HTML markers
86+
item_to_remove = ['<s>a</s>', '<s>c</s>', '<s>d</s>', '<s>e</s>']
87+
88+
# <s>b</s> represents a billion
89+
if '<s>b</s>' in entry:
90+
entry = entry.replace('<s>b</s>', '')
91+
entry = float(entry) * 1e9
92+
else:
93+
for item in item_to_remove:
94+
if item in entry:
95+
entry = entry.replace(item, '')
96+
return entry
97+
98+
def process_df(df):
99+
"Clean and reorganize the entire dataframe."
100+
101+
# remove HTML markers from column names
102+
for item in ['<s>a</s>', '<s>c</s>', '<s>d</s>', '<s>e</s>']:
103+
df.columns = df.columns.str.replace(item, '')
104+
105+
df['Year'] = df['Year'].apply(lambda x: int(x))
106+
107+
# set index to date time
108+
df = df.set_index(
109+
pd.to_datetime((df['Year'].astype(str) + df['Month'].astype(str)), format='%Y%B'))
110+
df = df.drop(['Year', 'Month'], axis=1)
111+
112+
# handle duplicates by keeping the first
113+
df = df[~df.index.duplicated(keep='first')]
114+
115+
# convert to numeric
116+
df = df.applymap(lambda x: float(x) if x != '' else np.nan)
117+
118+
# finally, we only focus on data between 1919 and 1925
119+
mask = (df.index >= '1919-01-01') & (df.index < '1925-01-01')
120+
df = df.loc[mask]
121+
122+
return df
123+
124+
def create_plot(p_seq, e_seq, index, labs, ax):
125+
126+
p_lab, e_lab = labs
127+
128+
# price and exchange rates
129+
ax.plot(index, p_seq, label=p_lab, color='tab:blue')
130+
ax1 = ax.twinx()
131+
ax1.plot([None], [None], label=p_lab, color='tab:blue')
132+
ax1.plot(index, e_seq, label=e_lab, color='tab:orange')
133+
ax.set_yscale('log')
134+
ax1.set_yscale('log')
135+
136+
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=5))
137+
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))
138+
for label in ax.get_xticklabels():
139+
label.set_rotation(45)
140+
141+
ax.text(-0.08, 1.03, 'Price Level', transform=ax.transAxes)
142+
ax.text(0.92, 1.03, 'Exchange Rate', transform=ax.transAxes)
143+
144+
ax1.legend(loc='upper left')
145+
146+
return ax1
147+
```
148+
149+
```python
150+
# import data
151+
xls = pd.ExcelFile('datasets/chapter_3.xlsx')
152+
153+
# unpack and combine all series
154+
sheet_index = [(2, 3, 4), (9, 10), (14, 15, 16), (21, 18, 19)]
155+
remove_row = [(-2, -2, -2), (-7, -10), (-6, -4, -3), (-19, -3, -6)]
156+
157+
df_list = []
158+
159+
for i in range(4):
160+
161+
indices, rows = sheet_index[i], remove_row[i]
162+
sheet_list = [pd.read_excel(xls, 'Table3.' + str(ind), header=1).iloc[:row].applymap(process_entry)
163+
for ind, row in zip(indices, rows)]
164+
165+
sheet_list = [process_df(df) for df in sheet_list]
166+
df_list.append(pd.concat(sheet_list, axis=1))
167+
168+
df_Aus, df_Hung, df_Pol, df_Germ = df_list
169+
```
170+
171+
### Austria
172+
173+
* Table 3.2, money supply, $\exp M$
174+
* Table 3.3, rdf_Aus.indexetail prices, $\exp p$
175+
* Table 3.4, exchange rate with US
176+
177+
```python
178+
df_Aus.head(5)
179+
```
180+
181+
```python
182+
p_seq = df_Aus['Retail price index, 52 commodities']
183+
e_seq = df_Aus['Exchange Rate']
184+
185+
lab = ['Retail Price Index', 'Exchange Rate']
186+
187+
# create plot
188+
fig, ax = plt.subplots(figsize=[10,7], dpi=200)
189+
_ = create_plot(p_seq, e_seq, df_Aus.index, lab, ax)
190+
191+
# connect disjunct parts
192+
plt.figtext(0.5, 0.0, 'Austria', horizontalalignment='center', fontsize=12)
193+
plt.show()
194+
```
195+
196+
### Hungary
197+
198+
* Table 3.9, money supply, $\exp M$
199+
* Table 3.10, price level $\exp p$ and exchange rate
200+
201+
202+
```python
203+
df_Hung.head(5)
204+
```
205+
206+
```python
207+
m_seq = df_Hung['Notes in circulation']
208+
p_seq = df_Hung['Hungarian index of prices']
209+
e_seq = 1/df_Hung['Cents per crown in New York']
210+
rb_seq = np.log(m_seq) - np.log(p_seq)
211+
212+
lab = ['Hungarian Index of Prices', '1/Cents per Crown in New York']
213+
214+
# create plot
215+
fig, ax = plt.subplots(figsize=[10,7], dpi=200)
216+
_ = create_plot(p_seq, e_seq, df_Hung.index, lab, ax)
217+
218+
plt.figtext(0.5, 0.0, 'Hungary', horizontalalignment='center', fontsize=12)
219+
plt.show()
220+
```
221+
222+
### Poland
223+
224+
* Table 3.14, money supply, $\exp M$
225+
* Table 3.15, price level $\exp p$
226+
* Table 3.15, exchange rate
227+
228+
229+
Jiacheng:
230+
231+
I spliced the three series - Wholesale price index, Wholesale Price Index: On paper currency basis, and Wholesale Price Index: On zloty basis. I made the adjustment by adjusting the sequence based on the price level ratio at the last period of the available previous series and glue them to a single series.
232+
233+
I dropped the exchange rate after June 1924, when zloty was adopted, because we don't have the price measured in zloty and old currency in June to compute the exchange rate adjustment.
234+
235+
```python
236+
df_Pol.head(5)
237+
```
238+
239+
```python
240+
# splice three price series in different units
241+
p_seq1 = df_Pol['Wholesale price index'].copy()
242+
p_seq2 = df_Pol['Wholesale Price Index: On paper currency basis'].copy()
243+
p_seq3 = df_Pol['Wholesale Price Index: On zloty basis'].copy()
244+
245+
# non-nan part
246+
ch_index_1 = p_seq1[~p_seq1.isna()].index[-1]
247+
ch_index_2 = p_seq2[~p_seq2.isna()].index[-2]
248+
249+
adj_ratio12 = p_seq1[ch_index_1]/p_seq2[ch_index_1]
250+
adj_ratio23 = p_seq2[ch_index_2]/p_seq3[ch_index_2]
251+
252+
# glue three series
253+
p_seq = pd.concat([p_seq1[:ch_index_1],
254+
adj_ratio12 * p_seq2[ch_index_1:ch_index_2],
255+
adj_ratio23 * p_seq3[ch_index_2:]])
256+
p_seq = p_seq[~p_seq.index.duplicated(keep='first')]
257+
258+
# exchange rate
259+
e_seq = 1/df_Pol['Cents per Polish mark (zloty after May 1924)']
260+
e_seq[e_seq.index > '05-01-1924'] = np.nan
261+
```
262+
263+
```python
264+
lab = ['Wholesale Price Index', '1/Cents per Polish Mark']
265+
266+
# create plot
267+
fig, ax = plt.subplots(figsize=[10,7], dpi=200)
268+
ax1 = create_plot(p_seq, e_seq, df_Pol.index, lab, ax)
269+
270+
plt.figtext(0.5, 0.0, 'Poland', horizontalalignment='center', fontsize=12)
271+
plt.show()
272+
```
273+
274+
### Germany
275+
276+
* Table 3.21, money supply, $\exp M$ (last column)
277+
* Table 3.18, wholesale price level $\exp p$
278+
* Table 3.19, exchange rate
279+
280+
```python
281+
df_Germ.head(5)
282+
```
283+
284+
285+
```python
286+
p_seq = df_Germ['Price index (on basis of marks before July 1924, reichsmarks after)'].copy()
287+
e_seq = 1/df_Germ['Cents per mark']
288+
289+
lab = ['Price Index', '1/Cents per Mark']
290+
291+
# create plot
292+
fig, ax = plt.subplots(figsize=[9,5], dpi=200)
293+
ax1 = create_plot(p_seq, e_seq, df_Germ.index, lab, ax)
294+
295+
plt.figtext(0.5, 0.0, 'Germany', horizontalalignment='center', fontsize=12)
296+
plt.show()
297+
```
298+
299+
Jiacheng: I add the new graph here.
300+
301+
```python
302+
p_seq = df_Germ['Price index (on basis of marks before July 1924, reichsmarks after)'].copy()
303+
e_seq = 1/df_Germ['Cents per mark'].copy()
304+
305+
# adjust the price level/exchange rate after the currency reform
306+
p_seq[p_seq.index > '06-01-1924'] = p_seq[p_seq.index > '06-01-1924'] * 1e12
307+
e_seq[e_seq.index > '12-01-1923'] = e_seq[e_seq.index > '12-01-1923'] * 1e12
308+
309+
lab = ['Price Index (Marks or converted to Marks)', '1/Cents per Mark (or Reichsmark converted to Mark)']
310+
311+
# create plot
312+
fig, ax = plt.subplots(figsize=[10,7], dpi=200)
313+
ax1 = create_plot(p_seq, e_seq, df_Germ.index, lab, ax)
314+
315+
plt.figtext(0.5, 0.0, 'Germany', horizontalalignment='center', fontsize=12)
316+
plt.show()
317+
```
318+
319+
**Note to Jiacheng:**
320+
321+
There might be some ambiguity about exactly which column in the "balance sheets" of the central bank that we want to interpret as "money". Typically it will be something like "notes" or "total notes" on the liability sides of the balance sheets in the spreadsheet table. We can resolve uncertainties in your mind quickly with a meeting.
322+
323+
**First Steps:** What I'd like you to do as first is to use matplotlib in a Jupyter notebook to take logs of the price level and reproduce pretty versions of our four tables.
324+
325+
**Seecond Steps:** There are some fun additonal things we can plot to set the stage for our cagan_ree and cagan_adaptive notebooks. For example, we have the data to plot logs of real balances around the times of the stabilizations. We can hunt for instances of "velocity dividends".
326+
327+
328+
```python
329+
# import data
330+
df_fig5 = pd.read_excel('datasets/longprices.xls', sheet_name='all', header=2, index_col=0).iloc[1:]
331+
df_fig5.index = df_fig5.index.astype(int)
332+
333+
df_fig5.head(5)
334+
```
335+
336+
```python
337+
# create plot
338+
cols = ['UK', 'US', 'France', 'Castile']
339+
340+
fig, ax = plt.subplots(1, 1, figsize=[8, 5], dpi=200)
341+
342+
for col in cols:
343+
ax.plot(df_fig5.index, df_fig5[col])
344+
ax.text(x=df_fig5.index[-1]+2, y=df_fig5[col].iloc[-1], s=col)
345+
346+
ax.spines[['right', 'top']].set_visible(False)
347+
ax.set_yscale('log')
348+
ax.set_ylabel('Index 1913 = 100')
349+
ax.set_xlim(xmin=1600)
350+
ax.set_ylim([10, 1e6])
351+
plt.tight_layout()
352+
plt.show()
353+
```

0 commit comments

Comments
 (0)