From 56875ec987135b7555da2f9e8c402823c2459388 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Sun, 5 Mar 2023 16:30:16 +1100 Subject: [PATCH 01/15] update business_cycle lecture --- lectures/business_cycle.md | 88 ++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 52 deletions(-) diff --git a/lectures/business_cycle.md b/lectures/business_cycle.md index 70fa5cc1d..f94c5a8b9 100644 --- a/lectures/business_cycle.md +++ b/lectures/business_cycle.md @@ -19,9 +19,9 @@ This lecture is about illustrateing business cycles in different countries and p The business cycle refers to the fluctuations in economic activity over time. These fluctuations can be observed in the form of expansions, contractions, recessions, and recoveries in the economy. -In this lecture, we will see expensions and contractions of economies from 1960s to the recent pandemic using [World Bank API](https://documents.worldbank.org/en/publication/documents-reports/api). +In this lecture, we will see expensions and contractions of economies from 1960s to the recent pandemic using [World Bank API](https://documents.worldbank.org/en/publication/documents-reports/api), [IMF API](http://www.bd-econ.com/imfapi1.html), and [FRED](https://fred.stlouisfed.org/) data. -In addition to what's in Anaconda, this lecture will need the following libraries to get World bank data +In addition to what's in Anaconda, this lecture will need the following libraries to get World Bank and IMF data ```{code-cell} ipython3 :tags: [hide-output] @@ -41,11 +41,19 @@ import wbgapi as wb from imfpy.retrievals import dots ``` +```{code-cell} ipython3 +# Set Graphical Parameters +cycler = plt.cycler(linestyle=['-', '-.', '--'], color=['#377eb8', '#ff7f00', '#4daf4a']) +plt.rc('axes', prop_cycle=cycler) +``` + ## Data Acquaisition -We will use `wbgapi` and `imfpy` to retrieve data from the World Bank and IMF API throughout this lecture. +We will use `wbgapi`, `imfpy`, and Pandas `datareader` to retrieve data throughout this lecture. + +This help us speed up the quary since we do not need to handle the raw JSON files. -So let's explore how to query data together. +So let's explore how to query data together. We can use `wb.series.info` with parameter `q` to query available data from the World Bank (`imfpy. searches.database_codes()` in `imfpy`) @@ -57,60 +65,23 @@ Let's retrive GDP growth data together wb.series.info(q='GDP growth') ``` -In a similar fashion, we can also retrieve data that covers different aspects of economic activities. - -We can cover indicators of - -- labour market +We can always learn more about the data by checking the metadata of the series ```{code-cell} ipython3 -:tags: [hide-output] - -wb.series.info(q='unemployment') +wb.series.metadata.get('NY.GDP.MKTP.KD.ZG') ``` -- credit level +We can now dive into the data we have. -```{code-cell} ipython3 -:tags: [hide-output] -wb.series.info(q='credit') -``` - -- consumer price index - -```{code-cell} ipython3 -:tags: [hide-output] - -wb.series.info(q='consumer') -``` - -- consumption level - -```{code-cell} ipython3 -:tags: [hide-output] - -wb.series.info(q='consumption') -``` - -```{code-cell} ipython3 -wb.series.info(q='capital account') # TODO: Check if it is to be plotted -``` - -- international trade volumn - -+++ - -These indicators will give us an overview of variations in economic activities across time. - -## GDP Growth Rate and Unemployment +## GDP Growth Rate First we look at the GDP growth rate and unemployment rate. Let's source our data from the World Bank and clean the data ```{code-cell} ipython3 -gdp_growth = wb.data.DataFrame('NY.GDP.MKTP.KD.ZG',['CHN', 'USA', 'DEU', 'BRA', 'ARG', 'GBR', 'MEX', 'CHL', 'COL', 'SLV', 'HTI'], labels=True) +gdp_growth = wb.data.DataFrame('NY.GDP.MKTP.KD.ZG',['USA', 'ARG', 'GBR', 'GRC', 'JPN'], labels=True) gdp_growth = gdp_growth.set_index('Country') gdp_growth.columns = gdp_growth.columns.str.replace('YR', '').astype(int) ``` @@ -119,19 +90,21 @@ gdp_growth.columns = gdp_growth.columns.str.replace('YR', '').astype(int) gdp_growth ``` -```{code-cell} ipython3 -cycler = plt.cycler(linestyle=['-', '-.', '--'], color=['#377eb8', '#ff7f00', '#4daf4a']) -plt.rc('axes', prop_cycle=cycler) -``` +Now we write a function to generate plots ```{code-cell} ipython3 fig, ax = plt.subplots() + +# Draw x-axis ax.set_xticks([i for i in range(1960, 2021, 10)], minor=False) plt.locator_params(axis='x', nbins=10) def plot_comparison(data, countries, title, ylabel, title_pos, ax, g_params, b_params, t_params): + # Allow the function to go through more than one series for country in countries: ax.plot(data.loc[country], label=country, **g_params) + + # Highlight Recessions ax.axvspan(1973, 1975, **b_params) ax.axvspan(1990, 1992, **b_params) ax.axvspan(2007, 2009, **b_params) @@ -146,16 +119,27 @@ def plot_comparison(data, countries, title, ylabel, title_pos, ax, g_params, b_p ax.legend() return ax +# Define graphical parameters g_params = {'alpha': 0.7} b_params = {'color':'grey', 'alpha': 0.2} t_params = {'color':'grey', 'fontsize': 9, 'va':'center', 'ha':'center'} -countries = ['United Kingdom', 'United States', 'Germany'] -title = 'United Kingdom, United States, and Germany (GDP Growth Rate %)' +``` + +Let's start with individual coutries + +```{code-cell} ipython3 +country = 'United States' +title = ' United States (Real GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' title_height = 0.1 ax = plot_comparison(gdp_growth, countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) ``` +## Unemployment + +## Synchronization + + ```{code-cell} ipython3 fig, ax = plt.subplots() From bbb5aa5f0e49a3997106f114cf7583b5465334e7 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Sun, 5 Mar 2023 18:26:56 +1100 Subject: [PATCH 02/15] update individual country function --- lectures/business_cycle.md | 123 +++++++++++++++++++++++++++++++++---- 1 file changed, 110 insertions(+), 13 deletions(-) diff --git a/lectures/business_cycle.md b/lectures/business_cycle.md index f94c5a8b9..834de45d2 100644 --- a/lectures/business_cycle.md +++ b/lectures/business_cycle.md @@ -68,6 +68,8 @@ wb.series.info(q='GDP growth') We can always learn more about the data by checking the metadata of the series ```{code-cell} ipython3 +:tags: [hide-output] + wb.series.metadata.get('NY.GDP.MKTP.KD.ZG') ``` @@ -93,22 +95,16 @@ gdp_growth Now we write a function to generate plots ```{code-cell} ipython3 -fig, ax = plt.subplots() - -# Draw x-axis -ax.set_xticks([i for i in range(1960, 2021, 10)], minor=False) -plt.locator_params(axis='x', nbins=10) - -def plot_comparison(data, countries, title, ylabel, title_pos, ax, g_params, b_params, t_params): - # Allow the function to go through more than one series - for country in countries: - ax.plot(data.loc[country], label=country, **g_params) +def plot_comparison(data, country, title, ylabel, title_pos, ax, g_params, b_params, t_params): + + ax.plot(data.loc[country], label=country, **g_params) # Highlight Recessions ax.axvspan(1973, 1975, **b_params) ax.axvspan(1990, 1992, **b_params) ax.axvspan(2007, 2009, **b_params) ax.axvspan(2019, 2021, **b_params) + ax.set_ylim([-15, 15]) ylim = ax.get_ylim()[1] ax.text(1974, ylim + ylim * title_pos, 'Oil Crisis\n(1974)', **t_params) ax.text(1991, ylim + ylim * title_pos, '1990s recession\n(1991)', **t_params) @@ -125,20 +121,121 @@ b_params = {'color':'grey', 'alpha': 0.2} t_params = {'color':'grey', 'fontsize': 9, 'va':'center', 'ha':'center'} ``` -Let's start with individual coutries +Let's start with individual coutries. + +We start with plotting the GDP growth rate for Unitied States ```{code-cell} ipython3 +fig, ax = plt.subplots() + +# Draw x-axis +plt.locator_params(axis='x', nbins=10) +ax.set_xticks([i for i in range(1960, 2021, 10)], minor=False) + country = 'United States' -title = ' United States (Real GDP Growth Rate %)' +title = 'United States (Real GDP Growth Rate %)' +ylabel = 'GDP Growth Rate (%)' +title_height = 0.1 +ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) +``` + +We find that there is a cyclical pattern across time, and volatile drops and rises during recessions + +Let's look at a few more countries across the world + ++++ + +Britain has a relative similar pattern compared to the US. + +However it has a more signicant drop in the GDP growth during the global economic recessions. + +```{code-cell} ipython3 +fig, ax = plt.subplots() + +# Draw x-axis +plt.locator_params(axis='x', nbins=10) +ax.set_xticks([i for i in range(1960, 2021, 10)], minor=False) + +country = 'United Kingdom' +title = ' United Kingdom (Real GDP Growth Rate %)' +ylabel = 'GDP Growth Rate (%)' +title_height = 0.1 +ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) +``` + +Japan and Greece both had a history of rapid growth in the 1960s, but a slowed economic expension in the past decade. + +We can see the + +```{code-cell} ipython3 +fig, ax = plt.subplots() + + +country = 'Japan' +title = 'Japan (Real GDP Growth Rate %)' +ylabel = 'GDP Growth Rate (%)' +title_height = 0.1 +ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) +``` + +```{code-cell} ipython3 +fig, ax = plt.subplots() + +country = 'Greece' +title = ' Greece (Real GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' title_height = 0.1 -ax = plot_comparison(gdp_growth, countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) +ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) ``` +```{code-cell} ipython3 +fig, ax = plt.subplots() + +country = 'Argentina' +title = 'Argentina (Real GDP Growth Rate %)' +ylabel = 'GDP Growth Rate (%)' +title_height = 0.1 +ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) +``` + +We find similar cyclical patterns across different countries. + +Countries such as Argentina has a more volatile cycle compared to other economies. + +Some economie + ++++ + ## Unemployment ## Synchronization +```{code-cell} ipython3 +def plot_comparison(data, countries, title, ylabel, title_pos, ax, g_params, b_params, t_params): + # Allow the function to go through more than one series + for country in countries: + ax.plot(data.loc[country], label=country, **g_params) + + # Highlight Recessions + ax.axvspan(1973, 1975, **b_params) + ax.axvspan(1990, 1992, **b_params) + ax.axvspan(2007, 2009, **b_params) + ax.axvspan(2019, 2021, **b_params) + ylim = ax.get_ylim()[1] + ax.text(1974, ylim + ylim * title_pos, 'Oil Crisis\n(1974)', **t_params) + ax.text(1991, ylim + ylim * title_pos, '1990s recession\n(1991)', **t_params) + ax.text(2008, ylim + ylim * title_pos, 'GFC\n(2008)', **t_params) + ax.text(2020, ylim + ylim * title_pos, 'Covid-19\n(2020)', **t_params) + ax.set_title(title, pad=40) + ax.set_ylabel(ylabel) + ax.legend() + return ax + +# Define graphical parameters +g_params = {'alpha': 0.7} +b_params = {'color':'grey', 'alpha': 0.2} +t_params = {'color':'grey', 'fontsize': 9, 'va':'center', 'ha':'center'} +``` ```{code-cell} ipython3 fig, ax = plt.subplots() From 7e751f91b35c23740477532f8153a2a8b15d29f7 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Mon, 6 Mar 2023 22:52:04 +1100 Subject: [PATCH 03/15] adding long-run unemployment rate --- lectures/business_cycle.md | 115 +++++++++++++++++++++++++++++++++---- 1 file changed, 105 insertions(+), 10 deletions(-) diff --git a/lectures/business_cycle.md b/lectures/business_cycle.md index 834de45d2..39499f9fa 100644 --- a/lectures/business_cycle.md +++ b/lectures/business_cycle.md @@ -4,7 +4,7 @@ jupytext: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.4 + jupytext_version: 1.14.5 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -28,6 +28,7 @@ In addition to what's in Anaconda, this lecture will need the following librarie !pip install wbgapi !pip install imfpy +!pip install pandas-datareader ``` We use the following imports @@ -37,8 +38,10 @@ import matplotlib.pyplot as plt import pandas as pd import numpy as np import scipy.stats as st +import datetime import wbgapi as wb from imfpy.retrievals import dots +import pandas_datareader.data as web ``` ```{code-cell} ipython3 @@ -65,6 +68,10 @@ Let's retrive GDP growth data together wb.series.info(q='GDP growth') ``` +```{code-cell} ipython3 +wb.series.info(q='income share') +``` + We can always learn more about the data by checking the metadata of the series ```{code-cell} ipython3 @@ -110,6 +117,7 @@ def plot_comparison(data, country, title, ylabel, title_pos, ax, g_params, b_par ax.text(1991, ylim + ylim * title_pos, '1990s recession\n(1991)', **t_params) ax.text(2008, ylim + ylim * title_pos, 'GFC\n(2008)', **t_params) ax.text(2020, ylim + ylim * title_pos, 'Covid-19\n(2020)', **t_params) + plt.axhline(y=0, color='black', linestyle='--') ax.set_title(title, pad=40) ax.set_ylabel(ylabel) ax.legend() @@ -133,7 +141,7 @@ plt.locator_params(axis='x', nbins=10) ax.set_xticks([i for i in range(1960, 2021, 10)], minor=False) country = 'United States' -title = 'United States (Real GDP Growth Rate %)' +title = 'United States (GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' title_height = 0.1 ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) @@ -157,7 +165,7 @@ plt.locator_params(axis='x', nbins=10) ax.set_xticks([i for i in range(1960, 2021, 10)], minor=False) country = 'United Kingdom' -title = ' United Kingdom (Real GDP Growth Rate %)' +title = ' United Kingdom (GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' title_height = 0.1 ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) @@ -165,14 +173,14 @@ ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_pa Japan and Greece both had a history of rapid growth in the 1960s, but a slowed economic expension in the past decade. -We can see the +We can see there is a general downward trend in additonal to fluctuations in the growth rate ```{code-cell} ipython3 fig, ax = plt.subplots() country = 'Japan' -title = 'Japan (Real GDP Growth Rate %)' +title = 'Japan (GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' title_height = 0.1 ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) @@ -182,17 +190,19 @@ ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_pa fig, ax = plt.subplots() country = 'Greece' -title = ' Greece (Real GDP Growth Rate %)' +title = ' Greece (GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' title_height = 0.1 ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) ``` +Some countries have more volitile cycles. + ```{code-cell} ipython3 fig, ax = plt.subplots() country = 'Argentina' -title = 'Argentina (Real GDP Growth Rate %)' +title = 'Argentina (GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' title_height = 0.1 ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) @@ -202,12 +212,97 @@ We find similar cyclical patterns across different countries. Countries such as Argentina has a more volatile cycle compared to other economies. -Some economie +One interesting insight is that the GDP growth of Argentina did not fall in the two recessions in 1970s and 1990s when most of developed economy is affected. + +We will come back to this point later. +++ ## Unemployment +Another important indicator of business cycles is the unemployment rate. + +When there is a recession, it is more likely to have more working population. + +We will show this using a long-run unemployment rate from FRED from [1929-1942](https://fred.stlouisfed.org/series/M0892AUSM156SNBR) and [1948-1011](https://fred.stlouisfed.org/series/UNRATE) with the unemployment rate between 1942-1948 estimated by [The Census Bureau](https://www.census.gov/library/publications/1975/compendia/hist_stats_colonial-1970.html). + +```{code-cell} ipython3 +start_date = datetime.datetime(1929, 1, 1) +end_date = datetime.datetime(1942, 6, 1) + +unrate_history = web.DataReader("M0892AUSM156SNBR", "fred", start_date,end_date) +unrate_history.rename(columns={'M0892AUSM156SNBR': 'UNRATE'}, inplace=True) +``` + +```{code-cell} ipython3 +import datetime + +start_date = datetime.datetime(1948, 1, 1) +end_date = datetime.datetime(2022, 12, 31) + +unrate = web.DataReader("UNRATE", "fred", start_date, end_date) +``` + +For years between 1942-1948, we use data from + +```{code-cell} ipython3 +years = [datetime.datetime(year, 6, 1) for year in range(1942,1948)] +unrate_interim = [4.7, 1.9, 1.2, 1.9, 3.9, 3.9] + +interim_data = {'DATE': years, 'UNRATE': unrate_interim} +interim_data = pd.DataFrame(interim_data) +interim_data.set_index('DATE', inplace=True) +``` + +```{code-cell} ipython3 +start_date = datetime.datetime(1929, 1, 1) +end_date = datetime.datetime(2022, 12, 31) + +nber = web.DataReader("USREC", "fred", start_date, end_date) +``` + +```{code-cell} ipython3 +fig, ax = plt.subplots() + +ax.plot(unrate_history, **g_params, color='#377eb8', linestyle='-') +ax.plot(interim_data, **g_params, color='black', linestyle="--", label='interim estimates') +ax.plot(unrate, **g_params, color='#377eb8', linestyle="-") + +# Draw gray boxes according to NBER recession indicators +ax.fill_between(nber.index, 0, 1, where=nber['USREC']==1, color='grey', edgecolor="none", + alpha=0.3, transform=ax.get_xaxis_transform(), + label='NBER Recession Indicators') +ax.set_ylim([0, ax.get_ylim()[1]]) +ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.05), + ncol=3, fancybox=True, shadow=True) +ax.set_ylabel('Unemployment Rate (%)') + +# Suppress Output +ax = ax.set_title('Long-run Unemployment Rate, 1929-2022\n with Recession Records (United States)', pad=20) +``` + +In the plot we see the expensions and contraction of the labour market has been highly correlated with recessions. + +However, there is a delay in the improvement of labor market after recession, which is clearly visible for the Great Recession before the war started, and recessions from 1980s. + +It also shows us how special the labor market condition during the pandemic is. + +The labour market recovers at an unprecedent rate. + +```{code-cell} ipython3 +income_share = wb.data.DataFrame('SI.DST.10TH.10', ['USA'], labels=True) +income_share = income_share.set_index('Country') +income_share.columns = income_share.columns.str.replace('YR', '').astype(int) +income_share.T.plot() +``` + +```{code-cell} ipython3 +income_share = wb.data.DataFrame('SI.DST.FRST.10', ['USA'], labels=True) +income_share = income_share.set_index('Country') +income_share.columns = income_share.columns.str.replace('YR', '').astype(int) +income_share.T.plot() +``` + ## Synchronization ```{code-cell} ipython3 @@ -248,9 +343,9 @@ ax = plot_comparison(gdp_growth.loc[countries, 1962:], countries, title, ylabel, ```{code-cell} ipython3 fig, ax = plt.subplots() -countries = ['Argentina'] +countries = ['United States'] title = 'Argentina (GDP Growth Rate %)' -ax = plot_comparison(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) +ax = plot_comparison(income_share.loc[countries], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) ``` ```{code-cell} ipython3 From ac243ce5dc5a740edc7dbaba1224758861622f16 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 8 Mar 2023 20:07:00 +1100 Subject: [PATCH 04/15] update bc --- lectures/business_cycle.md | 126 +++++++++---------------------------- 1 file changed, 28 insertions(+), 98 deletions(-) diff --git a/lectures/business_cycle.md b/lectures/business_cycle.md index 39499f9fa..11deb8be3 100644 --- a/lectures/business_cycle.md +++ b/lectures/business_cycle.md @@ -46,7 +46,7 @@ import pandas_datareader.data as web ```{code-cell} ipython3 # Set Graphical Parameters -cycler = plt.cycler(linestyle=['-', '-.', '--'], color=['#377eb8', '#ff7f00', '#4daf4a']) +cycler = plt.cycler(linestyle=['-', '-.', '--', ':'], color=['#377eb8', '#ff7f00', '#4daf4a', '#ff334f']) plt.rc('axes', prop_cycle=cycler) ``` @@ -289,24 +289,18 @@ It also shows us how special the labor market condition during the pandemic is. The labour market recovers at an unprecedent rate. -```{code-cell} ipython3 -income_share = wb.data.DataFrame('SI.DST.10TH.10', ['USA'], labels=True) -income_share = income_share.set_index('Country') -income_share.columns = income_share.columns.str.replace('YR', '').astype(int) -income_share.T.plot() -``` - -```{code-cell} ipython3 -income_share = wb.data.DataFrame('SI.DST.FRST.10', ['USA'], labels=True) -income_share = income_share.set_index('Country') -income_share.columns = income_share.columns.str.replace('YR', '').astype(int) -income_share.T.plot() -``` ++++ ## Synchronization +In our previous dicussion, we find that developed economies have a more synchronized period of recessions. + +Let's examine this trend further. + +With slight modification, we can draw a plot that includes many countries + ```{code-cell} ipython3 -def plot_comparison(data, countries, title, ylabel, title_pos, ax, g_params, b_params, t_params): +def plot_comparison_multi(data, countries, title, ylabel, title_pos, y_lim, ax, g_params, b_params, t_params): # Allow the function to go through more than one series for country in countries: ax.plot(data.loc[country], label=country, **g_params) @@ -316,6 +310,8 @@ def plot_comparison(data, countries, title, ylabel, title_pos, ax, g_params, b_p ax.axvspan(1990, 1992, **b_params) ax.axvspan(2007, 2009, **b_params) ax.axvspan(2019, 2021, **b_params) + if y_lim != None: + ax.set_ylim([-y_lim, y_lim]) ylim = ax.get_ylim()[1] ax.text(1974, ylim + ylim * title_pos, 'Oil Crisis\n(1974)', **t_params) ax.text(1991, ylim + ylim * title_pos, '1990s recession\n(1991)', **t_params) @@ -333,63 +329,32 @@ t_params = {'color':'grey', 'fontsize': 9, 'va':'center', 'ha':'center'} ``` ```{code-cell} ipython3 -fig, ax = plt.subplots() - -countries = ['Brazil', 'China', 'Argentina'] -title = 'Brazil, China, Argentina (GDP Growth Rate %)' -ax = plot_comparison(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) -``` - -```{code-cell} ipython3 -fig, ax = plt.subplots() - -countries = ['United States'] -title = 'Argentina (GDP Growth Rate %)' -ax = plot_comparison(income_share.loc[countries], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) -``` - -```{code-cell} ipython3 -fig, ax = plt.subplots() - -countries = ['Mexico'] -title = 'Mexico (GDP Growth Rate %)' -ax = plot_comparison(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) -``` - -```{code-cell} ipython3 -fig, ax = plt.subplots() - -countries = ['Chile'] -title = 'Chile (GDP Growth Rate %)' -ax = plot_comparison(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) +gdp_growth = wb.data.DataFrame('NY.GDP.MKTP.KD.ZG',['CHN', 'USA', 'DEU', 'BRA', 'ARG', 'GBR', 'JPN', 'MEX'], labels=True) +gdp_growth = gdp_growth.set_index('Country') +gdp_growth.columns = gdp_growth.columns.str.replace('YR', '').astype(int) ``` ```{code-cell} ipython3 fig, ax = plt.subplots() - -countries = ['Colombia'] -title = 'Colombia (GDP Growth Rate %)' -ax = plot_comparison(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) +countries = ['United Kingdom', 'United States', 'Germany', 'Japan'] +title = 'United Kingdom, United States, Germany, and Japan (GDP Growth Rate %)' +ylabel = 'GDP Growth Rate (%)' +title_height = 0.1 +ax = plot_comparison_multi(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, 20, ax, g_params, b_params, t_params) ``` ```{code-cell} ipython3 fig, ax = plt.subplots() - -countries = ['El Salvador'] -title = 'El Salvador (GDP Growth Rate %)' -ax = plot_comparison(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) +countries = ['Brazil', 'China', 'Argentina', 'Mexico'] +title = 'Brazil, China, Argentina, and Mexico (GDP Growth Rate %)' +ax = plot_comparison_multi(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, 20, ax, g_params, b_params, t_params) ``` -```{code-cell} ipython3 -fig, ax = plt.subplots() +By comparing the trend of GDP growth rates between developed and developing economies, we find the business cycles are more and more synchronized in from 21st-century recessions. -countries = ['Haiti'] -title = 'Haiti (GDP Growth Rate %)' -ax = plot_comparison(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) -``` ```{code-cell} ipython3 -unempl_rate = wb.data.DataFrame('SL.UEM.TOTL.NE.ZS',['CHN', 'USA', 'DEU', 'BRA', 'ARG', 'GBR', 'MEX', 'CHL', 'COL', 'SLV', 'HTI'], labels=True) +unempl_rate = wb.data.DataFrame('SL.UEM.TOTL.NE.ZS',['CHN', 'USA', 'DEU', 'BRA', 'ARG', 'GBR', 'JPN'], labels=True) unempl_rate = unempl_rate.set_index('Country') unempl_rate.columns = unempl_rate.columns.str.replace('YR', '').astype(int) ``` @@ -397,50 +362,14 @@ unempl_rate.columns = unempl_rate.columns.str.replace('YR', '').astype(int) ```{code-cell} ipython3 fig, ax = plt.subplots() -countries = ['United Kingdom', 'United States', 'Germany'] +countries = ['United Kingdom', 'United States', 'Germany', 'Japan'] title = 'United Kingdom, United States, and Germany (Unemployment Rate %)' ylabel = 'Unemployment Rate (National Estimate) (%)' -ax = plot_comparison(unempl_rate, countries, title, ylabel, 0.03, ax, g_params, b_params, t_params) -``` - -```{code-cell} ipython3 -fig, ax = plt.subplots() - -countries = ['Brazil', 'China', 'Argentina'] -title = 'Brazil, China, Argentina (Unemployment Rate %)' -ax = plot_comparison(unempl_rate, countries, title, ylabel, 0.04, ax, g_params, b_params, t_params) -``` - -```{code-cell} ipython3 -fig, ax = plt.subplots() - -countries = ['Brazil'] -title = 'Brazil (Unemployment Rate %)' -ax = plot_comparison(unempl_rate, countries, title, ylabel, 0.04, ax, g_params, b_params, t_params) +ax = plot_comparison_multi(unempl_rate, countries, title, ylabel, 0.05, None, ax, g_params, b_params, t_params) ``` ```{code-cell} ipython3 -fig, ax = plt.subplots() - -countries = ['Chile'] -title = 'Chile (Unemployment Rate %)' -ax = plot_comparison(unempl_rate, countries, title, ylabel, 0.04, ax, g_params, b_params, t_params) -``` - -```{code-cell} ipython3 -fig, ax = plt.subplots() - -countries = ['Colombia'] -title = 'Colombia (Unemployment Rate %)' -ax = plot_comparison(unempl_rate, countries, title, ylabel, 0.04, ax, g_params, b_params, t_params) -``` - -```{code-cell} ipython3 -fig, ax = plt.subplots() -countries = ['El Salvador'] -title = 'El Salvador (Unemployment Rate %)' -ax = plot_comparison(unempl_rate, countries, title, ylabel, 0.04, ax, g_params, b_params, t_params) ``` ## Credit Level @@ -496,8 +425,9 @@ ax = plot_comparison(cpi, countries, title, ylabel, 0.05, ax, g_params, b_params ## International Trade ```{code-cell} ipython3 -trade_us = dots('US','W00', 1960, 2020, freq='A') +trade_us = dots('200','W00', 1960, 2020, freq='A') trade_us['Period'] = trade_us['Period'].astype('int') +trade_us ``` ```{code-cell} ipython3 From 4525e27b902d39ed6e6895c560c2efbea89b9830 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 8 Mar 2023 23:27:32 +1100 Subject: [PATCH 05/15] add consumer index --- lectures/business_cycle.md | 99 ++++++++++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 25 deletions(-) diff --git a/lectures/business_cycle.md b/lectures/business_cycle.md index 11deb8be3..85b4548ea 100644 --- a/lectures/business_cycle.md +++ b/lectures/business_cycle.md @@ -4,7 +4,7 @@ jupytext: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.5 + jupytext_version: 1.14.4 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -41,6 +41,7 @@ import scipy.stats as st import datetime import wbgapi as wb from imfpy.retrievals import dots +from imfpy import searches import pandas_datareader.data as web ``` @@ -247,14 +248,16 @@ For years between 1942-1948, we use data from ```{code-cell} ipython3 years = [datetime.datetime(year, 6, 1) for year in range(1942,1948)] -unrate_interim = [4.7, 1.9, 1.2, 1.9, 3.9, 3.9] +unrate_census = [4.7, 1.9, 1.2, 1.9, 3.9, 3.9] -interim_data = {'DATE': years, 'UNRATE': unrate_interim} -interim_data = pd.DataFrame(interim_data) -interim_data.set_index('DATE', inplace=True) +unrate_census = {'DATE': years, 'UNRATE': unrate_census} +unrate_census = pd.DataFrame(unrate_census) +unrate_census.set_index('DATE', inplace=True) ``` ```{code-cell} ipython3 +:tags: [] + start_date = datetime.datetime(1929, 1, 1) end_date = datetime.datetime(2022, 12, 31) @@ -262,11 +265,13 @@ nber = web.DataReader("USREC", "fred", start_date, end_date) ``` ```{code-cell} ipython3 +:tags: [] + fig, ax = plt.subplots() -ax.plot(unrate_history, **g_params, color='#377eb8', linestyle='-') -ax.plot(interim_data, **g_params, color='black', linestyle="--", label='interim estimates') -ax.plot(unrate, **g_params, color='#377eb8', linestyle="-") +ax.plot(unrate_history, **g_params, color='#377eb8', linestyle='-', linewidth=2) +ax.plot(unrate_census, **g_params, color='black', linestyle="--", label='Census Estimates', linewidth=2) +ax.plot(unrate, **g_params, color='#377eb8', linestyle="-", linewidth=2) # Draw gray boxes according to NBER recession indicators ax.fill_between(nber.index, 0, 1, where=nber['USREC']==1, color='grey', edgecolor="none", @@ -350,11 +355,14 @@ title = 'Brazil, China, Argentina, and Mexico (GDP Growth Rate %)' ax = plot_comparison_multi(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, 20, ax, g_params, b_params, t_params) ``` -By comparing the trend of GDP growth rates between developed and developing economies, we find the business cycles are more and more synchronized in from 21st-century recessions. +By comparing the trend of GDP growth rates between developed and developing economies, we find the business cycles are more and more synchronized in 21st-century recessions. + +Although we have seen synchronization in GDP growth as a general trend, we also need to acknowledge the experience of individual countries during the recession is very different. +Here we use unemployment rate as an example ```{code-cell} ipython3 -unempl_rate = wb.data.DataFrame('SL.UEM.TOTL.NE.ZS',['CHN', 'USA', 'DEU', 'BRA', 'ARG', 'GBR', 'JPN'], labels=True) +unempl_rate = wb.data.DataFrame('SL.UEM.TOTL.NE.ZS',['CHN', 'USA', 'DEU', 'FRA', 'BRA', 'ARG', 'GBR', 'JPN'], labels=True) unempl_rate = unempl_rate.set_index('Country') unempl_rate.columns = unempl_rate.columns.str.replace('YR', '').astype(int) ``` @@ -362,20 +370,67 @@ unempl_rate.columns = unempl_rate.columns.str.replace('YR', '').astype(int) ```{code-cell} ipython3 fig, ax = plt.subplots() -countries = ['United Kingdom', 'United States', 'Germany', 'Japan'] +countries = ['United Kingdom', 'United States', 'Germany', 'France'] title = 'United Kingdom, United States, and Germany (Unemployment Rate %)' ylabel = 'Unemployment Rate (National Estimate) (%)' ax = plot_comparison_multi(unempl_rate, countries, title, ylabel, 0.05, None, ax, g_params, b_params, t_params) ``` +Labor market in German was resilient to the GFC from 2007 to 2008, which is mostly linked to [its labor market policy and various socio-economic factors](http://ilo.org/wcmsp5/groups/public/---dgreports/---inst/documents/publication/wcms_449926.pdf). + +The recovery from the crisis is another aspect. + +France, as a country with strong labor union, has prolonged labour market recovery compared to the US and UK. + ++++ + +## Leading Indicators and Correlated Factors for Business Cycles + +Understanding leading indicators and correlated factors help policy maker to better understand the causes and results of business cycles. + +We will discuss potential leading indicators and correlated factors from consumption, production, and credit level. + +### Consumption + ++++ + +One widely cited indicator for consumer confidence is [Consumer Sentiment Index](https://fred.stlouisfed.org/series/UMCSENT) published by University of Michigan. + +We find the consumer sentiment maintains at a high level during the expension period, but there are significant drops before the recession officially hits. + +We can also find that 2022 is + ```{code-cell} ipython3 +years = [datetime.datetime(year, 6, 1) for year in range(1942,1948)] +unrate_census = [4.7, 1.9, 1.2, 1.9, 3.9, 3.9] -``` +unrate_census = {'DATE': years, 'UNRATE': unrate_census} +unrate_census = pd.DataFrame(unrate_census) +unrate_census.set_index('DATE', inplace=True) + +start_date = datetime.datetime(1978, 1, 1) +end_date = datetime.datetime(2022, 12, 31) -## Credit Level +nber = web.DataReader("USREC", "fred", start_date, end_date) +consumer_confidence = web.DataReader("UMCSENT", "fred", start_date, end_date) + + +fig, ax = plt.subplots() +ax.plot(consumer_confidence, **g_params, color='#377eb8', linestyle='-', linewidth=2) +ax.fill_between(nber.index, 0, 1, where=nber['USREC']==1, color='grey', edgecolor="none", + alpha=0.3, transform=ax.get_xaxis_transform(), + label='NBER Recession Indicators') +ax.set_ylim([0, ax.get_ylim()[1]]) +ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.05), + ncol=3, fancybox=True, shadow=True) +ax.set_ylabel('Consumer Sentiment Index') + +# Suppress Output +ax = ax.set_title('University of Michigan: Consumer Sentiment Index 1978-2022\n (United States)', pad=20) +``` ```{code-cell} ipython3 -private_credit = wb.data.DataFrame('FD.AST.PRVT.GD.ZS',['CHN', 'USA', 'DEU', 'BRA', 'ARG', 'GBR'], labels=True) +private_credit = wb.data.DataFrame('UMCSENT',['USA'], labels=True) private_credit = private_credit.set_index('Country') private_credit.columns = private_credit.columns.str.replace('YR', '').astype(int) ``` @@ -425,7 +480,11 @@ ax = plot_comparison(cpi, countries, title, ylabel, 0.05, ax, g_params, b_params ## International Trade ```{code-cell} ipython3 -trade_us = dots('200','W00', 1960, 2020, freq='A') +searches.country_search("united") +``` + +```{code-cell} ipython3 +trade_us = dots('US','W00', 1960, 2020, freq='A') trade_us['Period'] = trade_us['Period'].astype('int') trade_us ``` @@ -463,16 +522,6 @@ ylabel = 'US Dollars, Millions' plot_trade_cn = plot_trade(trade_cn[['Period', 'Twoway Trade']], title, ylabel, 0.05, ax, g_params, b_params, t_params) ``` -```{code-cell} ipython3 -fig, ax = plt.subplots() -trade_mx = dots('MX','W00', 1960, 2020, freq='A') - -trade_mx['Period'] = trade_mx['Period'].astype('int') -title = 'Mexico (International Trade Volumn)' -ylabel = 'US Dollars, Millions' -plot_trade_mx = plot_trade(trade_mx[['Period', 'Twoway Trade']], title, ylabel, 0.05, ax, g_params, b_params, t_params) -``` - ```{code-cell} ipython3 fig, ax = plt.subplots() trade_ar = dots('AR','W00', 1960, 2020, freq='A') From 7fcf9f971abcfe9fd828e742f53d610fe0ac8e44 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Thu, 9 Mar 2023 11:24:25 +1100 Subject: [PATCH 06/15] complete leading factors --- lectures/business_cycle.md | 165 ++++++++++++++----------------------- 1 file changed, 64 insertions(+), 101 deletions(-) diff --git a/lectures/business_cycle.md b/lectures/business_cycle.md index 85b4548ea..833bcf90e 100644 --- a/lectures/business_cycle.md +++ b/lectures/business_cycle.md @@ -19,15 +19,14 @@ This lecture is about illustrateing business cycles in different countries and p The business cycle refers to the fluctuations in economic activity over time. These fluctuations can be observed in the form of expansions, contractions, recessions, and recoveries in the economy. -In this lecture, we will see expensions and contractions of economies from 1960s to the recent pandemic using [World Bank API](https://documents.worldbank.org/en/publication/documents-reports/api), [IMF API](http://www.bd-econ.com/imfapi1.html), and [FRED](https://fred.stlouisfed.org/) data. +In this lecture, we will see expensions and contractions of economies from 1960s to the recent pandemic using [World Bank API](https://documents.worldbank.org/en/publication/documents-reports/api), and [FRED](https://fred.stlouisfed.org/) data. -In addition to what's in Anaconda, this lecture will need the following libraries to get World Bank and IMF data +In addition to what's in Anaconda, this lecture will need the following libraries to get World Bank and FRED ```{code-cell} ipython3 :tags: [hide-output] !pip install wbgapi -!pip install imfpy !pip install pandas-datareader ``` @@ -40,8 +39,6 @@ import numpy as np import scipy.stats as st import datetime import wbgapi as wb -from imfpy.retrievals import dots -from imfpy import searches import pandas_datareader.data as web ``` @@ -53,13 +50,13 @@ plt.rc('axes', prop_cycle=cycler) ## Data Acquaisition -We will use `wbgapi`, `imfpy`, and Pandas `datareader` to retrieve data throughout this lecture. +We will use `wbgapi`, and Pandas `datareader` to retrieve data throughout this lecture. This help us speed up the quary since we do not need to handle the raw JSON files. So let's explore how to query data together. -We can use `wb.series.info` with parameter `q` to query available data from the World Bank (`imfpy. searches.database_codes()` in `imfpy`) +We can use `wb.series.info` with parameter `q` to query available data from the World Bank. For example, GDP growth is a key indicator to show the expension and contraction of level of economic activities. @@ -103,7 +100,7 @@ gdp_growth Now we write a function to generate plots ```{code-cell} ipython3 -def plot_comparison(data, country, title, ylabel, title_pos, ax, g_params, b_params, t_params): +def plot_comparison(data, country, title, ylabel, title_pos, ax, g_params, b_params, t_params, ylim=15, baseline=True): ax.plot(data.loc[country], label=country, **g_params) @@ -112,13 +109,15 @@ def plot_comparison(data, country, title, ylabel, title_pos, ax, g_params, b_par ax.axvspan(1990, 1992, **b_params) ax.axvspan(2007, 2009, **b_params) ax.axvspan(2019, 2021, **b_params) - ax.set_ylim([-15, 15]) + if ylim != None: + ax.set_ylim([-ylim, ylim]) ylim = ax.get_ylim()[1] ax.text(1974, ylim + ylim * title_pos, 'Oil Crisis\n(1974)', **t_params) ax.text(1991, ylim + ylim * title_pos, '1990s recession\n(1991)', **t_params) ax.text(2008, ylim + ylim * title_pos, 'GFC\n(2008)', **t_params) ax.text(2020, ylim + ylim * title_pos, 'Covid-19\n(2020)', **t_params) - plt.axhline(y=0, color='black', linestyle='--') + if baseline: + plt.axhline(y=0, color='black', linestyle='--') ax.set_title(title, pad=40) ax.set_ylabel(ylabel) ax.legend() @@ -396,138 +395,102 @@ We will discuss potential leading indicators and correlated factors from consump One widely cited indicator for consumer confidence is [Consumer Sentiment Index](https://fred.stlouisfed.org/series/UMCSENT) published by University of Michigan. -We find the consumer sentiment maintains at a high level during the expension period, but there are significant drops before the recession officially hits. +We find the consumer sentiment maintains at a high level during the expension period, but there are significant drops before the recession hits. -We can also find that 2022 is +There is also a clear negative correlation between consumer sentiment and [core consumer price index](https://fred.stlouisfed.org/series/CPILFESL). -```{code-cell} ipython3 -years = [datetime.datetime(year, 6, 1) for year in range(1942,1948)] -unrate_census = [4.7, 1.9, 1.2, 1.9, 3.9, 3.9] +This trend is more significant in period of [stagflation](https://en.wikipedia.org/wiki/Stagflation). -unrate_census = {'DATE': years, 'UNRATE': unrate_census} -unrate_census = pd.DataFrame(unrate_census) -unrate_census.set_index('DATE', inplace=True) +When the price of consumer commodities in the market is higher, the consumer confidence diminishes. +We will have a detailed look into inflation in the following lecture (TODO: Link to inflation lecture) + +```{code-cell} ipython3 start_date = datetime.datetime(1978, 1, 1) end_date = datetime.datetime(2022, 12, 31) +start_date_graph = datetime.datetime(1977, 1, 1) +end_date_graph = datetime.datetime(2023, 12, 31) + + nber = web.DataReader("USREC", "fred", start_date, end_date) consumer_confidence = web.DataReader("UMCSENT", "fred", start_date, end_date) - fig, ax = plt.subplots() -ax.plot(consumer_confidence, **g_params, color='#377eb8', linestyle='-', linewidth=2) +ax.plot(consumer_confidence, **g_params, color='#377eb8', linestyle='-', linewidth=2, label='Consumer Price Index') ax.fill_between(nber.index, 0, 1, where=nber['USREC']==1, color='grey', edgecolor="none", alpha=0.3, transform=ax.get_xaxis_transform(), label='NBER Recession Indicators') ax.set_ylim([0, ax.get_ylim()[1]]) -ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.05), - ncol=3, fancybox=True, shadow=True) ax.set_ylabel('Consumer Sentiment Index') -# Suppress Output -ax = ax.set_title('University of Michigan: Consumer Sentiment Index 1978-2022\n (United States)', pad=20) -``` +ax_t=ax.twinx() -```{code-cell} ipython3 -private_credit = wb.data.DataFrame('UMCSENT',['USA'], labels=True) -private_credit = private_credit.set_index('Country') -private_credit.columns = private_credit.columns.str.replace('YR', '').astype(int) -``` +inflation = web.DataReader("CPILFESL", "fred", start_date, end_date).pct_change(12) * 100 -```{code-cell} ipython3 -fig, ax = plt.subplots() +ax_t.plot(2020, 0, **g_params, linestyle='-', linewidth=2, label='Consumer Price Index') +ax_t.plot(inflation, **g_params, color='#ff7f00', linestyle='--', linewidth=2, label='CPI YoY Change (%)') +ax_t.fill_between(nber.index, 0, 1, where=nber['USREC']==1, color='grey', edgecolor="none", + alpha=0.3, transform=ax.get_xaxis_transform(), label='NBER Recession Indicators') +ax_t.set_ylim([0, ax_t.get_ylim()[1]]) +ax_t.set_xlim([start_date_graph, end_date_graph]) +ax_t.legend(loc='upper center', bbox_to_anchor=(0.5, 1.1), + ncol=3) +ax_t.set_ylabel('Consumer Price Index (% Change)',) -countries = ['United Kingdom', 'United States', 'Germany'] -title = 'United Kingdom, United States, and Germany \n Domestic credit to private sector by banks (% of GDP)' -ylabel = '% of GDP' -ax = plot_comparison(private_credit, countries, title, ylabel, 0.05, ax, g_params, b_params, t_params) +# Suppress Output +ax = ax.set_title('University of Michigan Consumer Sentiment Index,\n and Year-over-year Consumer Price Index Change, 1978-2022 (United States)', pad=40) ``` -```{code-cell} ipython3 -fig, ax = plt.subplots() +### Production -countries = ['Brazil', 'China', 'Argentina'] -title = 'Brazil, China, Argentina \n Domestic credit to private sector by banks (% of GDP)' -ax = plot_comparison(private_credit, countries, title, ylabel, 0.05, ax, g_params, b_params, t_params) -``` +Consumer confidence often affects the consumption pattern of consumers. -```{code-cell} ipython3 -fig, ax = plt.subplots() +This is often manifest on the production side. -countries = ['United Kingdom', 'China'] -title = 'United Kingdom and China \n Domestic credit to private sector by banks (% of GDP)' -ax = plot_comparison(private_credit, countries, title, ylabel, 0.05, ax, g_params, b_params, t_params) -``` +We find that the real output of the industry is also highly correlated with recessions in the economy. -## Inflation +However, instead of being a leading factor, the peak of the contraction in the production delays compared to consumer confidence and inflation ```{code-cell} ipython3 -cpi = wb.data.DataFrame('FP.CPI.TOTL.ZG',['CHN', 'USA', 'DEU', 'BRA', 'ARG', 'GBR'], labels=True) -cpi = cpi.set_index('Country') -cpi.columns = cpi.columns.str.replace('YR', '').astype(int) -``` +start_date = datetime.datetime(1919, 1, 1) +end_date = datetime.datetime(2022, 12, 31) -```{code-cell} ipython3 -fig, ax = plt.subplots() +nber = web.DataReader("USREC", "fred", start_date, end_date) +consumer_confidence = web.DataReader("INDPRO", "fred", start_date, end_date).pct_change(12) * 100 -countries = ['United Kingdom', 'United States', 'Germany'] -title = 'United Kingdom, United States, and Germany \n Inflation, consumer prices (annual %)' -ylabel = 'annual %' -ax = plot_comparison(cpi, countries, title, ylabel, 0.05, ax, g_params, b_params, t_params) +fig, ax = plt.subplots() +ax.plot(consumer_confidence, **g_params, color='#377eb8', linestyle='-', linewidth=2, label='Consumer Price Index') +ax.fill_between(nber.index, 0, 1, where=nber['USREC']==1, color='grey', edgecolor="none", + alpha=0.3, transform=ax.get_xaxis_transform(), + label='NBER Recession Indicators') +ax.set_ylim([ax.get_ylim()[0], ax.get_ylim()[1]]) +ax.set_ylabel('YoY Real Ouput Change (%)') +ax = ax.set_title('Year-over-year Industrial Production: Total Index, 1919-2022 (United States)', pad=20) ``` -## International Trade +### Credit Level -```{code-cell} ipython3 -searches.country_search("united") -``` +Credit contraction usually happends with recessions as lenders become more cautious and borrowers become more hesitant to take on additional debt. -```{code-cell} ipython3 -trade_us = dots('US','W00', 1960, 2020, freq='A') -trade_us['Period'] = trade_us['Period'].astype('int') -trade_us -``` +This can be due to several factors such as a decrease in overall economic activity, rising unemployment, and gloomy expections for the future. -```{code-cell} ipython3 -def plot_trade(data, title, ylabel, title_pos, ax, g_params, b_params, t_params): - ax.plot(data['Period'], data['Twoway Trade'], **g_params) - ax.axvspan(1973, 1975, **b_params) - ax.axvspan(1990, 1992, **b_params) - ax.axvspan(2007, 2009, **b_params) - ax.axvspan(2019, 2021, **b_params) - ylim = ax.get_ylim()[1] - ax.text(1974, ylim + ylim * title_pos, 'Oil Crisis\n(1974)', **t_params) - ax.text(1991, ylim + ylim * title_pos, '1990s recession\n(1991)', **t_params) - ax.text(2008, ylim + ylim * title_pos, 'GFC\n(2008)', **t_params) - ax.text(2020, ylim + ylim * title_pos, 'Covid-19\n(2020)', **t_params) - ax.set_title(title, pad=40) - ax.set_ylabel(ylabel) - return ax +One example is domestic credit to private sector by banks in the UK. - -fig, ax = plt.subplots() -title = 'United States (International Trade Volumn)' -ylabel = 'US Dollars, Millions' -plot_UStrade = plot_trade(trade_us[['Period', 'Twoway Trade']], title, ylabel, 0.05, ax, g_params, b_params, t_params) -``` +Note that the credit level expends rapidly in the period of economic expension, and stagnate or decreased after recessions ```{code-cell} ipython3 -fig, ax = plt.subplots() -trade_cn = dots('CN','W00', 1960, 2020, freq='A') - -trade_cn['Period'] = trade_cn['Period'].astype('int') -title = 'China (International Trade Volumn)' -ylabel = 'US Dollars, Millions' -plot_trade_cn = plot_trade(trade_cn[['Period', 'Twoway Trade']], title, ylabel, 0.05, ax, g_params, b_params, t_params) +private_credit = wb.data.DataFrame('FS.AST.PRVT.GD.ZS',['GBR'], labels=True) +private_credit = private_credit.set_index('Country') +private_credit.columns = private_credit.columns.str.replace('YR', '').astype(int) +private_credit ``` ```{code-cell} ipython3 fig, ax = plt.subplots() -trade_ar = dots('AR','W00', 1960, 2020, freq='A') -trade_ar['Period'] = trade_ar['Period'].astype('int') -title = 'Argentina (International Trade Volumn)' -ylabel = 'US Dollars, Millions' -plot_trade_ar = plot_trade(trade_ar[['Period', 'Twoway Trade']], title, ylabel, 0.05, ax, g_params, b_params, t_params) +countries = 'United Kingdom' +title = 'Domestic Credit to Private Sector by Banks, United Kingdom (% of GDP)' +ylabel = '% of GDP' +ax = plot_comparison(private_credit, countries, title, ylabel, 0.05, ax, g_params, b_params, t_params, ylim=None, baseline=False) ``` From e29a52c735a876e9e8e4552cf95acde73f03ab9c Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Thu, 9 Mar 2023 22:22:24 +1100 Subject: [PATCH 07/15] update text --- lectures/business_cycle.md | 150 ++++++++++++++++++++----------------- 1 file changed, 81 insertions(+), 69 deletions(-) diff --git a/lectures/business_cycle.md b/lectures/business_cycle.md index 833bcf90e..2761795c3 100644 --- a/lectures/business_cycle.md +++ b/lectures/business_cycle.md @@ -15,13 +15,13 @@ kernelspec: ## Overview -This lecture is about illustrateing business cycles in different countries and period. +This lecture is about illustrating business cycles in different countries and periods. The business cycle refers to the fluctuations in economic activity over time. These fluctuations can be observed in the form of expansions, contractions, recessions, and recoveries in the economy. -In this lecture, we will see expensions and contractions of economies from 1960s to the recent pandemic using [World Bank API](https://documents.worldbank.org/en/publication/documents-reports/api), and [FRED](https://fred.stlouisfed.org/) data. +In this lecture, we will see the expansions and contractions of economies from the 1960s to the recent pandemic using [World Bank API](https://documents.worldbank.org/en/publication/documents-reports/api), and [FRED](https://fred.stlouisfed.org/) data. -In addition to what's in Anaconda, this lecture will need the following libraries to get World Bank and FRED +In addition to what’s in Anaconda, this lecture will need the following libraries to get World Bank and FRED data ```{code-cell} ipython3 :tags: [hide-output] @@ -48,27 +48,25 @@ cycler = plt.cycler(linestyle=['-', '-.', '--', ':'], color=['#377eb8', '#ff7f00 plt.rc('axes', prop_cycle=cycler) ``` -## Data Acquaisition +## Data Acquisition We will use `wbgapi`, and Pandas `datareader` to retrieve data throughout this lecture. -This help us speed up the quary since we do not need to handle the raw JSON files. +They help us speed up the query since we do not need to handle the raw JSON files. So let's explore how to query data together. We can use `wb.series.info` with parameter `q` to query available data from the World Bank. -For example, GDP growth is a key indicator to show the expension and contraction of level of economic activities. +For example, GDP growth is a key indicator to show expansions and contractions of the level of economic activities. -Let's retrive GDP growth data together +Let's retrieve the ID for GDP growth data together ```{code-cell} ipython3 wb.series.info(q='GDP growth') ``` -```{code-cell} ipython3 -wb.series.info(q='income share') -``` +After retrieving the ID, it can be used to obtain the data in the following sections. We can always learn more about the data by checking the metadata of the series @@ -129,9 +127,7 @@ b_params = {'color':'grey', 'alpha': 0.2} t_params = {'color':'grey', 'fontsize': 9, 'va':'center', 'ha':'center'} ``` -Let's start with individual coutries. - -We start with plotting the GDP growth rate for Unitied States +Let's start with the United States ```{code-cell} ipython3 fig, ax = plt.subplots() @@ -144,18 +140,18 @@ country = 'United States' title = 'United States (GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' title_height = 0.1 -ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) +_ = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) ``` -We find that there is a cyclical pattern across time, and volatile drops and rises during recessions +We find that there is a cyclical pattern across time, and the economy shrinks during recessions. Let's look at a few more countries across the world +++ -Britain has a relative similar pattern compared to the US. +Britain has a relatively similar pattern compared to the US. -However it has a more signicant drop in the GDP growth during the global economic recessions. +However, it has a more significant drop in GDP growth during global economic recessions. ```{code-cell} ipython3 fig, ax = plt.subplots() @@ -168,12 +164,12 @@ country = 'United Kingdom' title = ' United Kingdom (GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' title_height = 0.1 -ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) +_ = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) ``` -Japan and Greece both had a history of rapid growth in the 1960s, but a slowed economic expension in the past decade. +Japan and Greece both had a history of rapid growth in the 1960s, but a slowed economic expansion in the past decade. -We can see there is a general downward trend in additonal to fluctuations in the growth rate +We can see there is a general downward trend in addition to fluctuations in the growth rate ```{code-cell} ipython3 fig, ax = plt.subplots() @@ -183,7 +179,7 @@ country = 'Japan' title = 'Japan (GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' title_height = 0.1 -ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) +_ = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) ``` ```{code-cell} ipython3 @@ -193,10 +189,14 @@ country = 'Greece' title = ' Greece (GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' title_height = 0.1 -ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) +_ = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) ``` -Some countries have more volitile cycles. +Note that Greece has another significant drop in GDP growth around 2010-2011 at the peak of the Greek debt crisis. + +We find similar cyclical patterns across different countries, and major recessions mostly overlap among them. + +Countries such as Argentina have more volatile cycles compared to the economies above. ```{code-cell} ipython3 fig, ax = plt.subplots() @@ -205,16 +205,12 @@ country = 'Argentina' title = 'Argentina (GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' title_height = 0.1 -ax = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) +_ = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) ``` -We find similar cyclical patterns across different countries. - -Countries such as Argentina has a more volatile cycle compared to other economies. - -One interesting insight is that the GDP growth of Argentina did not fall in the two recessions in 1970s and 1990s when most of developed economy is affected. +One interesting insight is that the GDP growth of Argentina did not fall in the two recessions in the 1970s and 1990s when most of the developed economy is affected. -We will come back to this point later. +We will come back to this [later](synchronization). +++ @@ -222,9 +218,9 @@ We will come back to this point later. Another important indicator of business cycles is the unemployment rate. -When there is a recession, it is more likely to have more working population. +When there is a recession, it is more likely to have a larger proportion of the working population being laid off. -We will show this using a long-run unemployment rate from FRED from [1929-1942](https://fred.stlouisfed.org/series/M0892AUSM156SNBR) and [1948-1011](https://fred.stlouisfed.org/series/UNRATE) with the unemployment rate between 1942-1948 estimated by [The Census Bureau](https://www.census.gov/library/publications/1975/compendia/hist_stats_colonial-1970.html). +We show this using a long-run unemployment rate from FRED from [1929-1942](https://fred.stlouisfed.org/series/M0892AUSM156SNBR) and [1948-1011](https://fred.stlouisfed.org/series/UNRATE) with the unemployment rate between 1942-1948 estimated by [The Census Bureau](https://www.census.gov/library/publications/1975/compendia/hist_stats_colonial-1970.html). ```{code-cell} ipython3 start_date = datetime.datetime(1929, 1, 1) @@ -243,9 +239,8 @@ end_date = datetime.datetime(2022, 12, 31) unrate = web.DataReader("UNRATE", "fred", start_date, end_date) ``` -For years between 1942-1948, we use data from - ```{code-cell} ipython3 +# We use the census bureau's estimate for the unemployment rate between 1942 and 1948 years = [datetime.datetime(year, 6, 1) for year in range(1942,1948)] unrate_census = [4.7, 1.9, 1.2, 1.9, 3.9, 3.9] @@ -257,6 +252,7 @@ unrate_census.set_index('DATE', inplace=True) ```{code-cell} ipython3 :tags: [] +# Obtain the NBER-defined recession periods start_date = datetime.datetime(1929, 1, 1) end_date = datetime.datetime(2022, 12, 31) @@ -273,7 +269,8 @@ ax.plot(unrate_census, **g_params, color='black', linestyle="--", label='Census ax.plot(unrate, **g_params, color='#377eb8', linestyle="-", linewidth=2) # Draw gray boxes according to NBER recession indicators -ax.fill_between(nber.index, 0, 1, where=nber['USREC']==1, color='grey', edgecolor="none", +ax.fill_between(nber.index, 0, 1, where=nber['USREC']==1, + color='grey', edgecolor="none", alpha=0.3, transform=ax.get_xaxis_transform(), label='NBER Recession Indicators') ax.set_ylim([0, ax.get_ylim()[1]]) @@ -282,26 +279,29 @@ ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.05), ax.set_ylabel('Unemployment Rate (%)') # Suppress Output -ax = ax.set_title('Long-run Unemployment Rate, 1929-2022\n with Recession Records (United States)', pad=20) +_ = ax.set_title('Long-run Unemployment Rate, 1929-2022\n with Recession Records (United States)', pad=20) ``` -In the plot we see the expensions and contraction of the labour market has been highly correlated with recessions. +In the plot, we see the expansions and contractions of the labor market have been highly correlated with recessions. -However, there is a delay in the improvement of labor market after recession, which is clearly visible for the Great Recession before the war started, and recessions from 1980s. +However, there is a delay in the recovery of the labor market after recessions, -It also shows us how special the labor market condition during the pandemic is. +This trend is clearly visible in the 1930s, and in recessions in the 1980s. -The labour market recovers at an unprecedent rate. +It also shows us how special the labor market condition during the post-pandemic recovery is. + +The labor market recovers at an unprecedented rate to the tightest point in the past decades after the shock in 2020-2021. +++ ## Synchronization -In our previous dicussion, we find that developed economies have a more synchronized period of recessions. +In our previous discussion, we find that developed economies have a more synchronized period of recessions, +but the synchronization does not appear in Argentina until the 2000s Let's examine this trend further. -With slight modification, we can draw a plot that includes many countries +With slight modification, we can use our previous function to draw a plot that includes many countries ```{code-cell} ipython3 def plot_comparison_multi(data, countries, title, ylabel, title_pos, y_lim, ax, g_params, b_params, t_params): @@ -333,6 +333,7 @@ t_params = {'color':'grey', 'fontsize': 9, 'va':'center', 'ha':'center'} ``` ```{code-cell} ipython3 +# Obtain GDP growth rate for a list of countries gdp_growth = wb.data.DataFrame('NY.GDP.MKTP.KD.ZG',['CHN', 'USA', 'DEU', 'BRA', 'ARG', 'GBR', 'JPN', 'MEX'], labels=True) gdp_growth = gdp_growth.set_index('Country') gdp_growth.columns = gdp_growth.columns.str.replace('YR', '').astype(int) @@ -344,21 +345,23 @@ countries = ['United Kingdom', 'United States', 'Germany', 'Japan'] title = 'United Kingdom, United States, Germany, and Japan (GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' title_height = 0.1 -ax = plot_comparison_multi(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, 20, ax, g_params, b_params, t_params) +_ = plot_comparison_multi(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, 20, ax, g_params, b_params, t_params) ``` ```{code-cell} ipython3 fig, ax = plt.subplots() countries = ['Brazil', 'China', 'Argentina', 'Mexico'] title = 'Brazil, China, Argentina, and Mexico (GDP Growth Rate %)' -ax = plot_comparison_multi(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, 20, ax, g_params, b_params, t_params) +_ = plot_comparison_multi(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, 20, ax, g_params, b_params, t_params) ``` -By comparing the trend of GDP growth rates between developed and developing economies, we find the business cycles are more and more synchronized in 21st-century recessions. +By comparing the trend of GDP growth rates between developed and developing economies, we find that business cycles are more and more synchronized in 21st-century recessions. Although we have seen synchronization in GDP growth as a general trend, we also need to acknowledge the experience of individual countries during the recession is very different. -Here we use unemployment rate as an example +Emerging and less developed economies often experience more volatile change throughout the economic cycles. + +Here we use the unemployment rate as another example ```{code-cell} ipython3 unempl_rate = wb.data.DataFrame('SL.UEM.TOTL.NE.ZS',['CHN', 'USA', 'DEU', 'FRA', 'BRA', 'ARG', 'GBR', 'JPN'], labels=True) @@ -372,43 +375,48 @@ fig, ax = plt.subplots() countries = ['United Kingdom', 'United States', 'Germany', 'France'] title = 'United Kingdom, United States, and Germany (Unemployment Rate %)' ylabel = 'Unemployment Rate (National Estimate) (%)' -ax = plot_comparison_multi(unempl_rate, countries, title, ylabel, 0.05, None, ax, g_params, b_params, t_params) +_ = plot_comparison_multi(unempl_rate, countries, title, ylabel, 0.05, None, ax, g_params, b_params, t_params) ``` -Labor market in German was resilient to the GFC from 2007 to 2008, which is mostly linked to [its labor market policy and various socio-economic factors](http://ilo.org/wcmsp5/groups/public/---dgreports/---inst/documents/publication/wcms_449926.pdf). +The labor market in German was resilient to the GFC from 2007 to 2008, which is mostly linked to [its labor market policy and various socioeconomic factors]( http://ilo.org/wcmsp5/groups/public/---dgreports/---inst/documents/publication/wcms_449926.pdf). The recovery from the crisis is another aspect. -France, as a country with strong labor union, has prolonged labour market recovery compared to the US and UK. +France, as a country with strong labor unions, has prolonged labor market recovery compared to the US and UK. +++ ## Leading Indicators and Correlated Factors for Business Cycles -Understanding leading indicators and correlated factors help policy maker to better understand the causes and results of business cycles. +Understanding leading indicators and correlated factors help policy maker to better understand and reflect on +the causes and results of business cycles. -We will discuss potential leading indicators and correlated factors from consumption, production, and credit level. +We will discuss potential leading indicators and correlated factors from three perspectives: +consumption, production, and credit level. ### Consumption +++ -One widely cited indicator for consumer confidence is [Consumer Sentiment Index](https://fred.stlouisfed.org/series/UMCSENT) published by University of Michigan. +Consumption level is dependent on how confident consumers are toward their income and the overall performance of the economy in the future. -We find the consumer sentiment maintains at a high level during the expension period, but there are significant drops before the recession hits. +One widely cited indicator for consumer confidence is the [Consumer Sentiment Index](https://fred.stlouisfed.org/series/UMCSENT) published by the University of Michigan. + +We find that consumer sentiment maintains a high level during the expansion period, but there are significant drops before the recession hits. There is also a clear negative correlation between consumer sentiment and [core consumer price index](https://fred.stlouisfed.org/series/CPILFESL). -This trend is more significant in period of [stagflation](https://en.wikipedia.org/wiki/Stagflation). +This trend is more significant in the period of [stagflation](https://en.wikipedia.org/wiki/Stagflation). -When the price of consumer commodities in the market is higher, the consumer confidence diminishes. +When the price of consumer commodities in the market is higher, consumer confidence diminishes. -We will have a detailed look into inflation in the following lecture (TODO: Link to inflation lecture) +We will have a detailed look into inflation in the following lecture (TODO: Link to inflation lecture) ```{code-cell} ipython3 start_date = datetime.datetime(1978, 1, 1) end_date = datetime.datetime(2022, 12, 31) +# Limit the plot to a specific range start_date_graph = datetime.datetime(1977, 1, 1) end_date_graph = datetime.datetime(2023, 12, 31) @@ -424,29 +432,33 @@ ax.fill_between(nber.index, 0, 1, where=nber['USREC']==1, color='grey', edgecolo ax.set_ylim([0, ax.get_ylim()[1]]) ax.set_ylabel('Consumer Sentiment Index') +# Plot CPI on another y-axis ax_t=ax.twinx() - inflation = web.DataReader("CPILFESL", "fred", start_date, end_date).pct_change(12) * 100 -ax_t.plot(2020, 0, **g_params, linestyle='-', linewidth=2, label='Consumer Price Index') -ax_t.plot(inflation, **g_params, color='#ff7f00', linestyle='--', linewidth=2, label='CPI YoY Change (%)') -ax_t.fill_between(nber.index, 0, 1, where=nber['USREC']==1, color='grey', edgecolor="none", - alpha=0.3, transform=ax.get_xaxis_transform(), label='NBER Recession Indicators') +# Add CPI on the legend without drawing the line again +ax_t.plot(2020, 0, **g_params, linestyle='-', + linewidth=2, label='Consumer Price Index') +ax_t.plot(inflation, **g_params, color='#ff7f00', linestyle='--', + linewidth=2, label='CPI YoY Change (%)') +ax_t.fill_between(nber.index, 0, 1, where=nber['USREC']==1, + color='grey', edgecolor="none", + alpha=0.3, transform=ax.get_xaxis_transform(), label='NBER Recession Indicators') ax_t.set_ylim([0, ax_t.get_ylim()[1]]) ax_t.set_xlim([start_date_graph, end_date_graph]) ax_t.legend(loc='upper center', bbox_to_anchor=(0.5, 1.1), - ncol=3) + ncol=3) ax_t.set_ylabel('Consumer Price Index (% Change)',) -# Suppress Output -ax = ax.set_title('University of Michigan Consumer Sentiment Index,\n and Year-over-year Consumer Price Index Change, 1978-2022 (United States)', pad=40) +# Suppress the text output +_ = ax.set_title('University of Michigan Consumer Sentiment Index,\n and Year-over-year Consumer Price Index Change, 1978-2022 (United States)', pad=40) ``` ### Production Consumer confidence often affects the consumption pattern of consumers. -This is often manifest on the production side. +This often manifests on the production side. We find that the real output of the industry is also highly correlated with recessions in the economy. @@ -471,13 +483,13 @@ ax = ax.set_title('Year-over-year Industrial Production: Total Index, 1919-2022 ### Credit Level -Credit contraction usually happends with recessions as lenders become more cautious and borrowers become more hesitant to take on additional debt. +Credit contraction usually happens with recessions as lenders become more cautious and borrowers become more hesitant to take on additional debt. -This can be due to several factors such as a decrease in overall economic activity, rising unemployment, and gloomy expections for the future. +This can be due to several factors such as a decrease in overall economic activity, rising unemployment, and gloomy expectations for the future. -One example is domestic credit to private sector by banks in the UK. +One example is domestic credit to the private sector by banks in the UK. -Note that the credit level expends rapidly in the period of economic expension, and stagnate or decreased after recessions +Note that the credit level expands rapidly in the period of economic expansion, and stagnates or decreased after recessions ```{code-cell} ipython3 private_credit = wb.data.DataFrame('FS.AST.PRVT.GD.ZS',['GBR'], labels=True) From 88ab2a520e14d9ceb663e5a294b72c43ec14c5a7 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Thu, 9 Mar 2023 22:27:45 +1100 Subject: [PATCH 08/15] fix reference --- lectures/business_cycle.md | 1 + 1 file changed, 1 insertion(+) diff --git a/lectures/business_cycle.md b/lectures/business_cycle.md index 2761795c3..1b3b840b7 100644 --- a/lectures/business_cycle.md +++ b/lectures/business_cycle.md @@ -294,6 +294,7 @@ The labor market recovers at an unprecedented rate to the tightest point in the +++ +(synchronization)= ## Synchronization In our previous discussion, we find that developed economies have a more synchronized period of recessions, From affceb4fdc39f3517ac1e95f1e3442c3466580b9 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Thu, 16 Mar 2023 10:40:36 +1100 Subject: [PATCH 09/15] update graph title --- lectures/business_cycle.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lectures/business_cycle.md b/lectures/business_cycle.md index 1b3b840b7..38f59bff9 100644 --- a/lectures/business_cycle.md +++ b/lectures/business_cycle.md @@ -196,7 +196,7 @@ Note that Greece has another significant drop in GDP growth around 2010-2011 at We find similar cyclical patterns across different countries, and major recessions mostly overlap among them. -Countries such as Argentina have more volatile cycles compared to the economies above. +Countries such as Argentina have more volatile cycles compared to the economies above. ```{code-cell} ipython3 fig, ax = plt.subplots() @@ -373,7 +373,7 @@ unempl_rate.columns = unempl_rate.columns.str.replace('YR', '').astype(int) ```{code-cell} ipython3 fig, ax = plt.subplots() -countries = ['United Kingdom', 'United States', 'Germany', 'France'] +countries = ['United Kingdom', 'United States', 'Japan', 'France'] title = 'United Kingdom, United States, and Germany (Unemployment Rate %)' ylabel = 'Unemployment Rate (National Estimate) (%)' _ = plot_comparison_multi(unempl_rate, countries, title, ylabel, 0.05, None, ax, g_params, b_params, t_params) @@ -439,7 +439,7 @@ inflation = web.DataReader("CPILFESL", "fred", start_date, end_date).pct_change( # Add CPI on the legend without drawing the line again ax_t.plot(2020, 0, **g_params, linestyle='-', - linewidth=2, label='Consumer Price Index') + linewidth=2, label='Consumer Sentiment Index') ax_t.plot(inflation, **g_params, color='#ff7f00', linestyle='--', linewidth=2, label='CPI YoY Change (%)') ax_t.fill_between(nber.index, 0, 1, where=nber['USREC']==1, From 067c75b3a70762d0950547add555eee210d56762 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Thu, 16 Mar 2023 19:11:49 +1100 Subject: [PATCH 10/15] fix labels and titles, simplify code --- lectures/business_cycle.md | 103 ++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 46 deletions(-) diff --git a/lectures/business_cycle.md b/lectures/business_cycle.md index 38f59bff9..6b817834d 100644 --- a/lectures/business_cycle.md +++ b/lectures/business_cycle.md @@ -86,7 +86,8 @@ First we look at the GDP growth rate and unemployment rate. Let's source our data from the World Bank and clean the data ```{code-cell} ipython3 -gdp_growth = wb.data.DataFrame('NY.GDP.MKTP.KD.ZG',['USA', 'ARG', 'GBR', 'GRC', 'JPN'], labels=True) +gdp_growth = wb.data.DataFrame('NY.GDP.MKTP.KD.ZG', + ['USA', 'ARG', 'GBR', 'GRC', 'JPN'], labels=True) gdp_growth = gdp_growth.set_index('Country') gdp_growth.columns = gdp_growth.columns.str.replace('YR', '').astype(int) ``` @@ -95,10 +96,12 @@ gdp_growth.columns = gdp_growth.columns.str.replace('YR', '').astype(int) gdp_growth ``` -Now we write a function to generate plots +Now we write a function to generate plots for individual countries ```{code-cell} ipython3 -def plot_comparison(data, country, title, ylabel, title_pos, ax, g_params, b_params, t_params, ylim=15, baseline=True): +def plot_comparison(data, country, title, + ylabel, title_pos, ax, g_params, + b_params, t_params, ylim=15): ax.plot(data.loc[country], label=country, **g_params) @@ -114,8 +117,7 @@ def plot_comparison(data, country, title, ylabel, title_pos, ax, g_params, b_par ax.text(1991, ylim + ylim * title_pos, '1990s recession\n(1991)', **t_params) ax.text(2008, ylim + ylim * title_pos, 'GFC\n(2008)', **t_params) ax.text(2020, ylim + ylim * title_pos, 'Covid-19\n(2020)', **t_params) - if baseline: - plt.axhline(y=0, color='black', linestyle='--') + ax.hlines(y=0, color='black', linestyle='--') ax.set_title(title, pad=40) ax.set_ylabel(ylabel) ax.legend() @@ -139,8 +141,9 @@ ax.set_xticks([i for i in range(1960, 2021, 10)], minor=False) country = 'United States' title = 'United States (GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' -title_height = 0.1 -_ = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) +_ = plot_comparison(gdp_growth, country, + title, ylabel, 0.1, ax, + g_params, b_params, t_params) ``` We find that there is a cyclical pattern across time, and the economy shrinks during recessions. @@ -164,7 +167,9 @@ country = 'United Kingdom' title = ' United Kingdom (GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' title_height = 0.1 -_ = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) +_ = plot_comparison(gdp_growth, country, title, + ylabel, 0.1, ax, g_params, + b_params, t_params) ``` Japan and Greece both had a history of rapid growth in the 1960s, but a slowed economic expansion in the past decade. @@ -177,9 +182,9 @@ fig, ax = plt.subplots() country = 'Japan' title = 'Japan (GDP Growth Rate %)' -ylabel = 'GDP Growth Rate (%)' -title_height = 0.1 -_ = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) +_ = plot_comparison(gdp_growth, country, title, + ylabel, 0.1, ax, g_params, + b_params, t_params) ``` ```{code-cell} ipython3 @@ -187,9 +192,9 @@ fig, ax = plt.subplots() country = 'Greece' title = ' Greece (GDP Growth Rate %)' -ylabel = 'GDP Growth Rate (%)' -title_height = 0.1 -_ = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) +_ = plot_comparison(gdp_growth, country, title, + ylabel, 0.1, ax, g_params, + b_params, t_params) ``` Note that Greece has another significant drop in GDP growth around 2010-2011 at the peak of the Greek debt crisis. @@ -203,9 +208,9 @@ fig, ax = plt.subplots() country = 'Argentina' title = 'Argentina (GDP Growth Rate %)' -ylabel = 'GDP Growth Rate (%)' -title_height = 0.1 -_ = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) +_ = plot_comparison(gdp_growth, country, title, + ylabel, 0.1, ax, + g_params, b_params, t_params) ``` One interesting insight is that the GDP growth of Argentina did not fall in the two recessions in the 1970s and 1990s when most of the developed economy is affected. @@ -226,17 +231,15 @@ We show this using a long-run unemployment rate from FRED from [1929-1942](https start_date = datetime.datetime(1929, 1, 1) end_date = datetime.datetime(1942, 6, 1) -unrate_history = web.DataReader("M0892AUSM156SNBR", "fred", start_date,end_date) +unrate_history = web.DataReader('M0892AUSM156SNBR', 'fred', start_date,end_date) unrate_history.rename(columns={'M0892AUSM156SNBR': 'UNRATE'}, inplace=True) ``` ```{code-cell} ipython3 -import datetime - start_date = datetime.datetime(1948, 1, 1) end_date = datetime.datetime(2022, 12, 31) -unrate = web.DataReader("UNRATE", "fred", start_date, end_date) +unrate = web.DataReader('UNRATE', 'fred', start_date, end_date) ``` ```{code-cell} ipython3 @@ -256,7 +259,7 @@ unrate_census.set_index('DATE', inplace=True) start_date = datetime.datetime(1929, 1, 1) end_date = datetime.datetime(2022, 12, 31) -nber = web.DataReader("USREC", "fred", start_date, end_date) +nber = web.DataReader('USREC', 'fred', start_date, end_date) ``` ```{code-cell} ipython3 @@ -265,21 +268,20 @@ nber = web.DataReader("USREC", "fred", start_date, end_date) fig, ax = plt.subplots() ax.plot(unrate_history, **g_params, color='#377eb8', linestyle='-', linewidth=2) -ax.plot(unrate_census, **g_params, color='black', linestyle="--", label='Census Estimates', linewidth=2) -ax.plot(unrate, **g_params, color='#377eb8', linestyle="-", linewidth=2) +ax.plot(unrate_census, **g_params, color='black', linestyle='--', label='Census Estimates', linewidth=2) +ax.plot(unrate, **g_params, color='#377eb8', linestyle='-', linewidth=2) # Draw gray boxes according to NBER recession indicators ax.fill_between(nber.index, 0, 1, where=nber['USREC']==1, - color='grey', edgecolor="none", + color='grey', edgecolor='none', alpha=0.3, transform=ax.get_xaxis_transform(), label='NBER Recession Indicators') ax.set_ylim([0, ax.get_ylim()[1]]) -ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.05), +ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.1), ncol=3, fancybox=True, shadow=True) ax.set_ylabel('Unemployment Rate (%)') -# Suppress Output -_ = ax.set_title('Long-run Unemployment Rate, 1929-2022\n with Recession Records (United States)', pad=20) +_ = ax.set_title('Long-run Unemployment Rate, 1929-2022\n with Recession Indicators (United States)', pad=40) ``` In the plot, we see the expansions and contractions of the labor market have been highly correlated with recessions. @@ -305,7 +307,10 @@ Let's examine this trend further. With slight modification, we can use our previous function to draw a plot that includes many countries ```{code-cell} ipython3 -def plot_comparison_multi(data, countries, title, ylabel, title_pos, y_lim, ax, g_params, b_params, t_params): +def plot_comparison_multi(data, countries, title, + ylabel, title_pos, y_lim, ax, + g_params, b_params, t_params): + # Allow the function to go through more than one series for country in countries: ax.plot(data.loc[country], label=country, **g_params) @@ -335,7 +340,8 @@ t_params = {'color':'grey', 'fontsize': 9, 'va':'center', 'ha':'center'} ```{code-cell} ipython3 # Obtain GDP growth rate for a list of countries -gdp_growth = wb.data.DataFrame('NY.GDP.MKTP.KD.ZG',['CHN', 'USA', 'DEU', 'BRA', 'ARG', 'GBR', 'JPN', 'MEX'], labels=True) +gdp_growth = wb.data.DataFrame('NY.GDP.MKTP.KD.ZG', + ['CHN', 'USA', 'DEU', 'BRA', 'ARG', 'GBR', 'JPN', 'MEX'], labels=True) gdp_growth = gdp_growth.set_index('Country') gdp_growth.columns = gdp_growth.columns.str.replace('YR', '').astype(int) ``` @@ -365,7 +371,8 @@ Emerging and less developed economies often experience more volatile change thro Here we use the unemployment rate as another example ```{code-cell} ipython3 -unempl_rate = wb.data.DataFrame('SL.UEM.TOTL.NE.ZS',['CHN', 'USA', 'DEU', 'FRA', 'BRA', 'ARG', 'GBR', 'JPN'], labels=True) +unempl_rate = wb.data.DataFrame('SL.UEM.TOTL.NE.ZS', + ['CHN', 'USA', 'DEU', 'FRA', 'BRA', 'ARG', 'GBR', 'JPN'], labels=True) unempl_rate = unempl_rate.set_index('Country') unempl_rate.columns = unempl_rate.columns.str.replace('YR', '').astype(int) ``` @@ -374,7 +381,7 @@ unempl_rate.columns = unempl_rate.columns.str.replace('YR', '').astype(int) fig, ax = plt.subplots() countries = ['United Kingdom', 'United States', 'Japan', 'France'] -title = 'United Kingdom, United States, and Germany (Unemployment Rate %)' +title = 'United Kingdom, United States, Japan, and France (Unemployment Rate %)' ylabel = 'Unemployment Rate (National Estimate) (%)' _ = plot_comparison_multi(unempl_rate, countries, title, ylabel, 0.05, None, ax, g_params, b_params, t_params) ``` @@ -421,21 +428,23 @@ end_date = datetime.datetime(2022, 12, 31) start_date_graph = datetime.datetime(1977, 1, 1) end_date_graph = datetime.datetime(2023, 12, 31) - -nber = web.DataReader("USREC", "fred", start_date, end_date) -consumer_confidence = web.DataReader("UMCSENT", "fred", start_date, end_date) +nber = web.DataReader('USREC', 'fred', start_date, end_date) +consumer_confidence = web.DataReader('UMCSENT', 'fred', start_date, end_date) fig, ax = plt.subplots() -ax.plot(consumer_confidence, **g_params, color='#377eb8', linestyle='-', linewidth=2, label='Consumer Price Index') -ax.fill_between(nber.index, 0, 1, where=nber['USREC']==1, color='grey', edgecolor="none", - alpha=0.3, transform=ax.get_xaxis_transform(), - label='NBER Recession Indicators') +ax.plot(consumer_confidence, **g_params, + color='#377eb8', linestyle='-', + linewidth=2, label='Consumer Price Index') +ax.fill_between(nber.index, 0, 1, + where=nber['USREC']==1, color='grey', edgecolor='none', + alpha=0.3, transform=ax.get_xaxis_transform(), + label='NBER Recession Indicators') ax.set_ylim([0, ax.get_ylim()[1]]) ax.set_ylabel('Consumer Sentiment Index') # Plot CPI on another y-axis ax_t=ax.twinx() -inflation = web.DataReader("CPILFESL", "fred", start_date, end_date).pct_change(12) * 100 +inflation = web.DataReader('CPILFESL', 'fred', start_date, end_date).pct_change(12) * 100 # Add CPI on the legend without drawing the line again ax_t.plot(2020, 0, **g_params, linestyle='-', @@ -443,8 +452,9 @@ ax_t.plot(2020, 0, **g_params, linestyle='-', ax_t.plot(inflation, **g_params, color='#ff7f00', linestyle='--', linewidth=2, label='CPI YoY Change (%)') ax_t.fill_between(nber.index, 0, 1, where=nber['USREC']==1, - color='grey', edgecolor="none", - alpha=0.3, transform=ax.get_xaxis_transform(), label='NBER Recession Indicators') + color='grey', edgecolor='none', + alpha=0.3, transform=ax.get_xaxis_transform(), + label='NBER Recession Indicators') ax_t.set_ylim([0, ax_t.get_ylim()[1]]) ax_t.set_xlim([start_date_graph, end_date_graph]) ax_t.legend(loc='upper center', bbox_to_anchor=(0.5, 1.1), @@ -452,7 +462,8 @@ ax_t.legend(loc='upper center', bbox_to_anchor=(0.5, 1.1), ax_t.set_ylabel('Consumer Price Index (% Change)',) # Suppress the text output -_ = ax.set_title('University of Michigan Consumer Sentiment Index,\n and Year-over-year Consumer Price Index Change, 1978-2022 (United States)', pad=40) +_ = ax.set_title('University of Michigan Consumer Sentiment Index,\n and \ +Year-over-year Consumer Price Index Change, 1978-2022 (United States)', pad=40) ``` ### Production @@ -469,12 +480,12 @@ However, instead of being a leading factor, the peak of the contraction in the p start_date = datetime.datetime(1919, 1, 1) end_date = datetime.datetime(2022, 12, 31) -nber = web.DataReader("USREC", "fred", start_date, end_date) -consumer_confidence = web.DataReader("INDPRO", "fred", start_date, end_date).pct_change(12) * 100 +nber = web.DataReader('USREC', 'fred', start_date, end_date) +consumer_confidence = web.DataReader('INDPRO', 'fred', start_date, end_date).pct_change(12) * 100 fig, ax = plt.subplots() ax.plot(consumer_confidence, **g_params, color='#377eb8', linestyle='-', linewidth=2, label='Consumer Price Index') -ax.fill_between(nber.index, 0, 1, where=nber['USREC']==1, color='grey', edgecolor="none", +ax.fill_between(nber.index, 0, 1, where=nber['USREC']==1, color='grey', edgecolor='none', alpha=0.3, transform=ax.get_xaxis_transform(), label='NBER Recession Indicators') ax.set_ylim([ax.get_ylim()[0], ax.get_ylim()[1]]) From 6f7967ccd46aa9206247ffbe5d0134e1dd33e022 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Thu, 16 Mar 2023 19:31:40 +1100 Subject: [PATCH 11/15] change wording --- lectures/business_cycle.md | 79 +++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/lectures/business_cycle.md b/lectures/business_cycle.md index 6b817834d..35038228b 100644 --- a/lectures/business_cycle.md +++ b/lectures/business_cycle.md @@ -19,9 +19,9 @@ This lecture is about illustrating business cycles in different countries and pe The business cycle refers to the fluctuations in economic activity over time. These fluctuations can be observed in the form of expansions, contractions, recessions, and recoveries in the economy. -In this lecture, we will see the expansions and contractions of economies from the 1960s to the recent pandemic using [World Bank API](https://documents.worldbank.org/en/publication/documents-reports/api), and [FRED](https://fred.stlouisfed.org/) data. +In this lecture, we will look into series of economic indicators to visualize the expansions and contractions of economies from the 1960s to the recent pandemic using [World Bank](https://documents.worldbank.org/en/publication/documents-reports/api), and [FRED](https://fred.stlouisfed.org/) data. -In addition to what’s in Anaconda, this lecture will need the following libraries to get World Bank and FRED data +In addition to what is in Anaconda, this lecture will require the following libraries to obtain World Bank and FRED data. ```{code-cell} ipython3 :tags: [hide-output] @@ -50,11 +50,12 @@ plt.rc('axes', prop_cycle=cycler) ## Data Acquisition -We will use `wbgapi`, and Pandas `datareader` to retrieve data throughout this lecture. +We will use `wbgapi`, and `pandas_datareader` to retrieve data throughout this lecture. -They help us speed up the query since we do not need to handle the raw JSON files. +They help us speed up the query since we do not need to handle the tedious +raw results from the API. -So let's explore how to query data together. +So let's explore how to query data first. We can use `wb.series.info` with parameter `q` to query available data from the World Bank. @@ -66,7 +67,7 @@ Let's retrieve the ID for GDP growth data together wb.series.info(q='GDP growth') ``` -After retrieving the ID, it can be used to obtain the data in the following sections. +After retrieving the series ID, it can be used to obtain the data. We can always learn more about the data by checking the metadata of the series @@ -76,7 +77,7 @@ We can always learn more about the data by checking the metadata of the series wb.series.metadata.get('NY.GDP.MKTP.KD.ZG') ``` -We can now dive into the data we have. +Let's dive into the data with the tools we have. ## GDP Growth Rate @@ -86,6 +87,7 @@ First we look at the GDP growth rate and unemployment rate. Let's source our data from the World Bank and clean the data ```{code-cell} ipython3 +# Use the series ID retrived before gdp_growth = wb.data.DataFrame('NY.GDP.MKTP.KD.ZG', ['USA', 'ARG', 'GBR', 'GRC', 'JPN'], labels=True) gdp_growth = gdp_growth.set_index('Country') @@ -113,10 +115,14 @@ def plot_comparison(data, country, title, if ylim != None: ax.set_ylim([-ylim, ylim]) ylim = ax.get_ylim()[1] - ax.text(1974, ylim + ylim * title_pos, 'Oil Crisis\n(1974)', **t_params) - ax.text(1991, ylim + ylim * title_pos, '1990s recession\n(1991)', **t_params) - ax.text(2008, ylim + ylim * title_pos, 'GFC\n(2008)', **t_params) - ax.text(2020, ylim + ylim * title_pos, 'Covid-19\n(2020)', **t_params) + ax.text(1974, ylim + ylim * title_pos, + 'Oil Crisis\n(1974)', **t_params) + ax.text(1991, ylim + ylim * title_pos, + '1990s recession\n(1991)', **t_params) + ax.text(2008, ylim + ylim * title_pos, ' + 'GFC\n(2008)', **t_params) + ax.text(2020, ylim + ylim * title_pos, + 'Covid-19\n(2020)', **t_params) ax.hlines(y=0, color='black', linestyle='--') ax.set_title(title, pad=40) ax.set_ylabel(ylabel) @@ -126,7 +132,8 @@ def plot_comparison(data, country, title, # Define graphical parameters g_params = {'alpha': 0.7} b_params = {'color':'grey', 'alpha': 0.2} -t_params = {'color':'grey', 'fontsize': 9, 'va':'center', 'ha':'center'} +t_params = {'color':'grey', 'fontsize': 9, + 'va':'center', 'ha':'center'} ``` Let's start with the United States @@ -134,7 +141,7 @@ Let's start with the United States ```{code-cell} ipython3 fig, ax = plt.subplots() -# Draw x-axis +# Draw customized x-axis plt.locator_params(axis='x', nbins=10) ax.set_xticks([i for i in range(1960, 2021, 10)], minor=False) @@ -152,7 +159,7 @@ Let's look at a few more countries across the world +++ -Britain has a relatively similar pattern compared to the US. +Britain has a similar pattern compared to the US. However, it has a more significant drop in GDP growth during global economic recessions. @@ -174,7 +181,7 @@ _ = plot_comparison(gdp_growth, country, title, Japan and Greece both had a history of rapid growth in the 1960s, but a slowed economic expansion in the past decade. -We can see there is a general downward trend in addition to fluctuations in the growth rate +We can see there is a downward trend in addition to fluctuations in the growth rate ```{code-cell} ipython3 fig, ax = plt.subplots() @@ -197,11 +204,11 @@ _ = plot_comparison(gdp_growth, country, title, b_params, t_params) ``` -Note that Greece has another significant drop in GDP growth around 2010-2011 at the peak of the Greek debt crisis. +Note that Greece had another significant drop in GDP growth around 2010-2011 at the peak of the Greek debt crisis. -We find similar cyclical patterns across different countries, and major recessions mostly overlap among them. +From series above, we find similar cyclical patterns across different countries, and major recessions mostly overlap among them. -Countries such as Argentina have more volatile cycles compared to the economies above. +However, countries such as Argentina have more volatile cycles compared to the economies above. ```{code-cell} ipython3 fig, ax = plt.subplots() @@ -213,7 +220,7 @@ _ = plot_comparison(gdp_growth, country, title, g_params, b_params, t_params) ``` -One interesting insight is that the GDP growth of Argentina did not fall in the two recessions in the 1970s and 1990s when most of the developed economy is affected. +One interesting insight is that the GDP growth of Argentina did not fall during the two recessions in the 1970s and 1990s when most of the developed economies were affected. We will come back to this [later](synchronization). @@ -243,7 +250,8 @@ unrate = web.DataReader('UNRATE', 'fred', start_date, end_date) ``` ```{code-cell} ipython3 -# We use the census bureau's estimate for the unemployment rate between 1942 and 1948 +# We use the census bureau's estimate for the unemployment rate +# between 1942 and 1948 years = [datetime.datetime(year, 6, 1) for year in range(1942,1948)] unrate_census = [4.7, 1.9, 1.2, 1.9, 3.9, 3.9] @@ -323,10 +331,14 @@ def plot_comparison_multi(data, countries, title, if y_lim != None: ax.set_ylim([-y_lim, y_lim]) ylim = ax.get_ylim()[1] - ax.text(1974, ylim + ylim * title_pos, 'Oil Crisis\n(1974)', **t_params) - ax.text(1991, ylim + ylim * title_pos, '1990s recession\n(1991)', **t_params) - ax.text(2008, ylim + ylim * title_pos, 'GFC\n(2008)', **t_params) - ax.text(2020, ylim + ylim * title_pos, 'Covid-19\n(2020)', **t_params) + ax.text(1974, ylim + ylim * title_pos, + 'Oil Crisis\n(1974)', **t_params) + ax.text(1991, ylim + ylim * title_pos, + '1990s recession\n(1991)', **t_params) + ax.text(2008, ylim + ylim * title_pos, + 'GFC\n(2008)', **t_params) + ax.text(2020, ylim + ylim * title_pos, + 'Covid-19\n(2020)', **t_params) ax.set_title(title, pad=40) ax.set_ylabel(ylabel) ax.legend() @@ -335,7 +347,8 @@ def plot_comparison_multi(data, countries, title, # Define graphical parameters g_params = {'alpha': 0.7} b_params = {'color':'grey', 'alpha': 0.2} -t_params = {'color':'grey', 'fontsize': 9, 'va':'center', 'ha':'center'} +t_params = {'color':'grey', 'fontsize': 9, + 'va':'center', 'ha':'center'} ``` ```{code-cell} ipython3 @@ -364,9 +377,9 @@ _ = plot_comparison_multi(gdp_growth.loc[countries, 1962:], countries, title, yl By comparing the trend of GDP growth rates between developed and developing economies, we find that business cycles are more and more synchronized in 21st-century recessions. -Although we have seen synchronization in GDP growth as a general trend, we also need to acknowledge the experience of individual countries during the recession is very different. +However, emerging and less developed economies often experience more volatile changes throughout the economic cycles. -Emerging and less developed economies often experience more volatile change throughout the economic cycles. +Although we have seen synchronization in GDP growth as a general trend, we also need to acknowledge the experience of individual countries during the recession is often very different. Here we use the unemployment rate as another example @@ -390,7 +403,7 @@ The labor market in German was resilient to the GFC from 2007 to 2008, which is The recovery from the crisis is another aspect. -France, as a country with strong labor unions, has prolonged labor market recovery compared to the US and UK. +France, with its strong labor unions, has prolonged labor market recovery compared to the US and UK. +++ @@ -444,7 +457,8 @@ ax.set_ylabel('Consumer Sentiment Index') # Plot CPI on another y-axis ax_t=ax.twinx() -inflation = web.DataReader('CPILFESL', 'fred', start_date, end_date).pct_change(12) * 100 +inflation = web.DataReader('CPILFESL', 'fred', + start_date, end_date).pct_change(12) * 100 # Add CPI on the legend without drawing the line again ax_t.plot(2020, 0, **g_params, linestyle='-', @@ -490,7 +504,8 @@ ax.fill_between(nber.index, 0, 1, where=nber['USREC']==1, color='grey', edgecolo label='NBER Recession Indicators') ax.set_ylim([ax.get_ylim()[0], ax.get_ylim()[1]]) ax.set_ylabel('YoY Real Ouput Change (%)') -ax = ax.set_title('Year-over-year Industrial Production: Total Index, 1919-2022 (United States)', pad=20) +ax = ax.set_title('Year-over-year Industrial Production:\ + Total Index, 1919-2022 (United States)', pad=20) ``` ### Credit Level @@ -501,7 +516,7 @@ This can be due to several factors such as a decrease in overall economic activi One example is domestic credit to the private sector by banks in the UK. -Note that the credit level expands rapidly in the period of economic expansion, and stagnates or decreased after recessions +Note that the credit level expands rapidly in the period of economic expansion, and stagnates or even contracts after recessions ```{code-cell} ipython3 private_credit = wb.data.DataFrame('FS.AST.PRVT.GD.ZS',['GBR'], labels=True) @@ -516,5 +531,5 @@ fig, ax = plt.subplots() countries = 'United Kingdom' title = 'Domestic Credit to Private Sector by Banks, United Kingdom (% of GDP)' ylabel = '% of GDP' -ax = plot_comparison(private_credit, countries, title, ylabel, 0.05, ax, g_params, b_params, t_params, ylim=None, baseline=False) +ax = plot_comparison(private_credit, countries, title, ylabel, 0.05, ax, g_params, b_params, t_params, ylim=None) ``` From 9a5ce2f3eddc41bfd16836c0d7ecbc2b1f24e4ea Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Thu, 16 Mar 2023 21:04:53 +1100 Subject: [PATCH 12/15] further simplify the code and text --- lectures/business_cycle.md | 76 +++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/lectures/business_cycle.md b/lectures/business_cycle.md index 35038228b..c3be301a7 100644 --- a/lectures/business_cycle.md +++ b/lectures/business_cycle.md @@ -69,7 +69,16 @@ wb.series.info(q='GDP growth') After retrieving the series ID, it can be used to obtain the data. -We can always learn more about the data by checking the metadata of the series +```{code-cell} ipython3 +:tags: [hide-output] + +# Use the series ID retrived before +gdp_growth = wb.data.DataFrame('NY.GDP.MKTP.KD.ZG', + ['USA', 'ARG', 'GBR', 'GRC', 'JPN'], labels=True) +gdp_growth +``` + +We can also learn more about the data by checking the metadata of the series ```{code-cell} ipython3 :tags: [hide-output] @@ -103,7 +112,7 @@ Now we write a function to generate plots for individual countries ```{code-cell} ipython3 def plot_comparison(data, country, title, ylabel, title_pos, ax, g_params, - b_params, t_params, ylim=15): + b_params, t_params, ylim=15, baseline=0): ax.plot(data.loc[country], label=country, **g_params) @@ -114,16 +123,18 @@ def plot_comparison(data, country, title, ax.axvspan(2019, 2021, **b_params) if ylim != None: ax.set_ylim([-ylim, ylim]) - ylim = ax.get_ylim()[1] - ax.text(1974, ylim + ylim * title_pos, + else: + ylim = ax.get_ylim()[1] + ax.text(1974, ylim + ylim * title_pos, 'Oil Crisis\n(1974)', **t_params) - ax.text(1991, ylim + ylim * title_pos, + ax.text(1991, ylim + ylim * title_pos, '1990s recession\n(1991)', **t_params) - ax.text(2008, ylim + ylim * title_pos, ' + ax.text(2008, ylim + ylim * title_pos, 'GFC\n(2008)', **t_params) - ax.text(2020, ylim + ylim * title_pos, - 'Covid-19\n(2020)', **t_params) - ax.hlines(y=0, color='black', linestyle='--') + ax.text(2020, ylim + ylim * title_pos, + 'Covid-19\n(2020)', **t_params) + if baseline != None: + ax.axhline(y=baseline, color='black', linestyle='--') ax.set_title(title, pad=40) ax.set_ylabel(ylabel) ax.legend() @@ -141,10 +152,6 @@ Let's start with the United States ```{code-cell} ipython3 fig, ax = plt.subplots() -# Draw customized x-axis -plt.locator_params(axis='x', nbins=10) -ax.set_xticks([i for i in range(1960, 2021, 10)], minor=False) - country = 'United States' title = 'United States (GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' @@ -166,10 +173,6 @@ However, it has a more significant drop in GDP growth during global economic rec ```{code-cell} ipython3 fig, ax = plt.subplots() -# Draw x-axis -plt.locator_params(axis='x', nbins=10) -ax.set_xticks([i for i in range(1960, 2021, 10)], minor=False) - country = 'United Kingdom' title = ' United Kingdom (GDP Growth Rate %)' ylabel = 'GDP Growth Rate (%)' @@ -186,7 +189,6 @@ We can see there is a downward trend in addition to fluctuations in the growth r ```{code-cell} ipython3 fig, ax = plt.subplots() - country = 'Japan' title = 'Japan (GDP Growth Rate %)' _ = plot_comparison(gdp_growth, country, title, @@ -289,7 +291,7 @@ ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.1), ncol=3, fancybox=True, shadow=True) ax.set_ylabel('Unemployment Rate (%)') -_ = ax.set_title('Long-run Unemployment Rate, 1929-2022\n with Recession Indicators (United States)', pad=40) +_ = ax.set_title('Long-run Unemployment Rate, 1929-2022\n with Recession Indicators (United States)', pad=30) ``` In the plot, we see the expansions and contractions of the labor market have been highly correlated with recessions. @@ -317,7 +319,7 @@ With slight modification, we can use our previous function to draw a plot that i ```{code-cell} ipython3 def plot_comparison_multi(data, countries, title, ylabel, title_pos, y_lim, ax, - g_params, b_params, t_params): + g_params, b_params, t_params, baseline=0): # Allow the function to go through more than one series for country in countries: @@ -339,6 +341,10 @@ def plot_comparison_multi(data, countries, title, 'GFC\n(2008)', **t_params) ax.text(2020, ylim + ylim * title_pos, 'Covid-19\n(2020)', **t_params) + if baseline != None: + ax.hlines(y=baseline, xmin=ax.get_xlim()[0], + xmax=ax.get_xlim()[1], color='black', + linestyle='--') ax.set_title(title, pad=40) ax.set_ylabel(ylabel) ax.legend() @@ -381,11 +387,11 @@ However, emerging and less developed economies often experience more volatile ch Although we have seen synchronization in GDP growth as a general trend, we also need to acknowledge the experience of individual countries during the recession is often very different. -Here we use the unemployment rate as another example +Here we use the unemployment rate and the recovery of labor market condition as another example ```{code-cell} ipython3 unempl_rate = wb.data.DataFrame('SL.UEM.TOTL.NE.ZS', - ['CHN', 'USA', 'DEU', 'FRA', 'BRA', 'ARG', 'GBR', 'JPN'], labels=True) + ['USA', 'FRA', 'GBR', 'JPN'], labels=True) unempl_rate = unempl_rate.set_index('Country') unempl_rate.columns = unempl_rate.columns.str.replace('YR', '').astype(int) ``` @@ -396,15 +402,15 @@ fig, ax = plt.subplots() countries = ['United Kingdom', 'United States', 'Japan', 'France'] title = 'United Kingdom, United States, Japan, and France (Unemployment Rate %)' ylabel = 'Unemployment Rate (National Estimate) (%)' -_ = plot_comparison_multi(unempl_rate, countries, title, ylabel, 0.05, None, ax, g_params, b_params, t_params) +_ = plot_comparison_multi(unempl_rate, countries, title, + ylabel, 0.05, None, ax, g_params, + b_params, t_params, baseline=None) ``` -The labor market in German was resilient to the GFC from 2007 to 2008, which is mostly linked to [its labor market policy and various socioeconomic factors]( http://ilo.org/wcmsp5/groups/public/---dgreports/---inst/documents/publication/wcms_449926.pdf). - -The recovery from the crisis is another aspect. - France, with its strong labor unions, has prolonged labor market recovery compared to the US and UK. +However, Japan has a history of very low and stable unemployment rate due to a constellation of social, demographic and cultural factors + +++ ## Leading Indicators and Correlated Factors for Business Cycles @@ -456,7 +462,7 @@ ax.set_ylim([0, ax.get_ylim()[1]]) ax.set_ylabel('Consumer Sentiment Index') # Plot CPI on another y-axis -ax_t=ax.twinx() +ax_t = ax.twinx() inflation = web.DataReader('CPILFESL', 'fred', start_date, end_date).pct_change(12) * 100 @@ -472,12 +478,12 @@ ax_t.fill_between(nber.index, 0, 1, where=nber['USREC']==1, ax_t.set_ylim([0, ax_t.get_ylim()[1]]) ax_t.set_xlim([start_date_graph, end_date_graph]) ax_t.legend(loc='upper center', bbox_to_anchor=(0.5, 1.1), - ncol=3) + ncol=3, fontsize=9) ax_t.set_ylabel('Consumer Price Index (% Change)',) # Suppress the text output _ = ax.set_title('University of Michigan Consumer Sentiment Index,\n and \ -Year-over-year Consumer Price Index Change, 1978-2022 (United States)', pad=40) +Year-over-year Consumer Price Index Change, 1978-2022 (United States)', pad=30) ``` ### Production @@ -504,8 +510,8 @@ ax.fill_between(nber.index, 0, 1, where=nber['USREC']==1, color='grey', edgecolo label='NBER Recession Indicators') ax.set_ylim([ax.get_ylim()[0], ax.get_ylim()[1]]) ax.set_ylabel('YoY Real Ouput Change (%)') -ax = ax.set_title('Year-over-year Industrial Production:\ - Total Index, 1919-2022 (United States)', pad=20) +ax = ax.set_title('Year-over-year Industrial Production: \ +Total Index, 1919-2022 (United States)', pad=20) ``` ### Credit Level @@ -530,6 +536,8 @@ fig, ax = plt.subplots() countries = 'United Kingdom' title = 'Domestic Credit to Private Sector by Banks, United Kingdom (% of GDP)' -ylabel = '% of GDP' -ax = plot_comparison(private_credit, countries, title, ylabel, 0.05, ax, g_params, b_params, t_params, ylim=None) +ylabel = 'Credit Level (% of GDP)' +ax = plot_comparison(private_credit, countries, title, + ylabel, 0.05, ax, g_params, b_params, + t_params, ylim=None, baseline=None) ``` From 0995ca55127d9133c0f1fb595d07b5031e9ad7ab Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Thu, 16 Mar 2023 21:41:58 +1100 Subject: [PATCH 13/15] update wording --- lectures/business_cycle.md | 81 ++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/lectures/business_cycle.md b/lectures/business_cycle.md index c3be301a7..f0c4ab676 100644 --- a/lectures/business_cycle.md +++ b/lectures/business_cycle.md @@ -19,9 +19,9 @@ This lecture is about illustrating business cycles in different countries and pe The business cycle refers to the fluctuations in economic activity over time. These fluctuations can be observed in the form of expansions, contractions, recessions, and recoveries in the economy. -In this lecture, we will look into series of economic indicators to visualize the expansions and contractions of economies from the 1960s to the recent pandemic using [World Bank](https://documents.worldbank.org/en/publication/documents-reports/api), and [FRED](https://fred.stlouisfed.org/) data. +In this lecture, we will look into a series of economic indicators to visualize the expansions and contractions of economies from the 1960s to the recent pandemic using[World Bank](https://documents.worldbank.org/en/publication/documents-reports/api), and [FRED](https://fred.stlouisfed.org/) data. -In addition to what is in Anaconda, this lecture will require the following libraries to obtain World Bank and FRED data. +In addition to what is in Anaconda, this lecture will require the following libraries to obtain World Bank and FRED data ```{code-cell} ipython3 :tags: [hide-output] @@ -52,16 +52,15 @@ plt.rc('axes', prop_cycle=cycler) We will use `wbgapi`, and `pandas_datareader` to retrieve data throughout this lecture. -They help us speed up the query since we do not need to handle the tedious -raw results from the API. +They help us speed up the query since we do not need to handle the tedious raw results from the API. So let's explore how to query data first. -We can use `wb.series.info` with parameter `q` to query available data from the World Bank. +We can use `wb.series.info` with the argument `q` to query available data from the World Bank. For example, GDP growth is a key indicator to show expansions and contractions of the level of economic activities. -Let's retrieve the ID for GDP growth data together +Let's retrieve the ID to query GDP growth data first ```{code-cell} ipython3 wb.series.info(q='GDP growth') @@ -162,27 +161,26 @@ _ = plot_comparison(gdp_growth, country, We find that there is a cyclical pattern across time, and the economy shrinks during recessions. -Let's look at a few more countries across the world +Let's look at a few more countries around the world +++ Britain has a similar pattern compared to the US. -However, it has a more significant drop in GDP growth during global economic recessions. +However, it experiences a more significant drop in GDP growth during global economic recessions. ```{code-cell} ipython3 fig, ax = plt.subplots() country = 'United Kingdom' title = ' United Kingdom (GDP Growth Rate %)' -ylabel = 'GDP Growth Rate (%)' title_height = 0.1 _ = plot_comparison(gdp_growth, country, title, ylabel, 0.1, ax, g_params, b_params, t_params) ``` -Japan and Greece both had a history of rapid growth in the 1960s, but a slowed economic expansion in the past decade. +Japan and Greece both had a history of rapid growth in the 1960s, but have experienced slowed economic expansion in the past decade. We can see there is a downward trend in addition to fluctuations in the growth rate @@ -206,11 +204,11 @@ _ = plot_comparison(gdp_growth, country, title, b_params, t_params) ``` -Note that Greece had another significant drop in GDP growth around 2010-2011 at the peak of the Greek debt crisis. +Note that Greece had another significant drop in GDP growth around 2010-2011 during the peak of the Greek debt crisis. -From series above, we find similar cyclical patterns across different countries, and major recessions mostly overlap among them. +From the series above, we can see similar cyclical patterns across different countries, and major recessions mostly overlap among them. -However, countries such as Argentina have more volatile cycles compared to the economies above. +However, countries such as Argentina have more volatile cycles compared to the economies mentioned above ```{code-cell} ipython3 fig, ax = plt.subplots() @@ -224,7 +222,7 @@ _ = plot_comparison(gdp_growth, country, title, One interesting insight is that the GDP growth of Argentina did not fall during the two recessions in the 1970s and 1990s when most of the developed economies were affected. -We will come back to this [later](synchronization). +We will revisit this topic [later](synchronization). +++ @@ -232,9 +230,9 @@ We will come back to this [later](synchronization). Another important indicator of business cycles is the unemployment rate. -When there is a recession, it is more likely to have a larger proportion of the working population being laid off. +During a recession, it is more likely that a larger proportion of the working population will be laid off. -We show this using a long-run unemployment rate from FRED from [1929-1942](https://fred.stlouisfed.org/series/M0892AUSM156SNBR) and [1948-1011](https://fred.stlouisfed.org/series/UNRATE) with the unemployment rate between 1942-1948 estimated by [The Census Bureau](https://www.census.gov/library/publications/1975/compendia/hist_stats_colonial-1970.html). +We demonstrate this using a long-run unemployment rate from FRED spanning from [1929-1942](https://fred.stlouisfed.org/series/M0892AUSM156SNBR) to [1948-2022](https://fred.stlouisfed.org/series/UNRATE) with the unemployment rate between 1942 and 1948 estimated by [The Census Bureau](https://www.census.gov/library/publications/1975/compendia/hist_stats_colonial-1970.html). ```{code-cell} ipython3 start_date = datetime.datetime(1929, 1, 1) @@ -294,27 +292,27 @@ ax.set_ylabel('Unemployment Rate (%)') _ = ax.set_title('Long-run Unemployment Rate, 1929-2022\n with Recession Indicators (United States)', pad=30) ``` -In the plot, we see the expansions and contractions of the labor market have been highly correlated with recessions. +In the plot, we can see that the expansions and contractions of the labor market have been highly correlated with recessions. -However, there is a delay in the recovery of the labor market after recessions, +However, there is often a delay in the recovery of the labor market after recessions. -This trend is clearly visible in the 1930s, and in recessions in the 1980s. +This trend is clearly visible in the 1930s, as well as in recessions in the 1980s. -It also shows us how special the labor market condition during the post-pandemic recovery is. +It also shows us how unique the labor market condition is during the post-pandemic recovery. -The labor market recovers at an unprecedented rate to the tightest point in the past decades after the shock in 2020-2021. +The labor market is recovering at an unprecedented rate, leading to the tightest point in the past decades after the shock in 2020-2021. +++ (synchronization)= ## Synchronization -In our previous discussion, we find that developed economies have a more synchronized period of recessions, -but the synchronization does not appear in Argentina until the 2000s +In our previous discussion, we found that developed economies have a more synchronized period of recessions, +but the synchronization does not appear in Argentina until the 2000s. -Let's examine this trend further. +Let's examine this trend further. -With slight modification, we can use our previous function to draw a plot that includes many countries +With slight modifications, we can use our previous function to draw a plot that includes many countries ```{code-cell} ipython3 def plot_comparison_multi(data, countries, title, @@ -381,11 +379,12 @@ title = 'Brazil, China, Argentina, and Mexico (GDP Growth Rate %)' _ = plot_comparison_multi(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, 20, ax, g_params, b_params, t_params) ``` -By comparing the trend of GDP growth rates between developed and developing economies, we find that business cycles are more and more synchronized in 21st-century recessions. +By comparing the trend of GDP growth rates between developed and developing economies, we find that business cycles are becoming more and more synchronized in 21st-century recessions. + -However, emerging and less developed economies often experience more volatile changes throughout the economic cycles. +However, emerging and less developed economies often experience more volatile changes throughout the economic cycles. -Although we have seen synchronization in GDP growth as a general trend, we also need to acknowledge the experience of individual countries during the recession is often very different. +Although we have seen synchronization in GDP growth as a general trend, we also need to acknowledge that the experience of individual countries during the recession is often very different. Here we use the unemployment rate and the recovery of labor market condition as another example @@ -407,25 +406,23 @@ _ = plot_comparison_multi(unempl_rate, countries, title, b_params, t_params, baseline=None) ``` -France, with its strong labor unions, has prolonged labor market recovery compared to the US and UK. +France, with its strong labor unions, has a prolonged labor market recovery compared to the US and UK. -However, Japan has a history of very low and stable unemployment rate due to a constellation of social, demographic and cultural factors +However, Japan has a history of very low and stable unemployment rates due to a constellation of social, demographic, and cultural factors. +++ ## Leading Indicators and Correlated Factors for Business Cycles -Understanding leading indicators and correlated factors help policy maker to better understand and reflect on -the causes and results of business cycles. +Understanding leading indicators and correlated factors helps policymakers to better understand and reflect on the causes and results of business cycles. -We will discuss potential leading indicators and correlated factors from three perspectives: -consumption, production, and credit level. +We will discuss potential leading indicators and correlated factors from three perspectives: consumption, production, and credit level. ### Consumption +++ -Consumption level is dependent on how confident consumers are toward their income and the overall performance of the economy in the future. +Consumption level is dependent on how confident consumers are toward their income and the overall performance of the economy in the future. One widely cited indicator for consumer confidence is the [Consumer Sentiment Index](https://fred.stlouisfed.org/series/UMCSENT) published by the University of Michigan. @@ -437,8 +434,6 @@ This trend is more significant in the period of [stagflation](https://en.wikiped When the price of consumer commodities in the market is higher, consumer confidence diminishes. -We will have a detailed look into inflation in the following lecture (TODO: Link to inflation lecture) - ```{code-cell} ipython3 start_date = datetime.datetime(1978, 1, 1) end_date = datetime.datetime(2022, 12, 31) @@ -453,7 +448,7 @@ consumer_confidence = web.DataReader('UMCSENT', 'fred', start_date, end_date) fig, ax = plt.subplots() ax.plot(consumer_confidence, **g_params, color='#377eb8', linestyle='-', - linewidth=2, label='Consumer Price Index') + linewidth=2) ax.fill_between(nber.index, 0, 1, where=nber['USREC']==1, color='grey', edgecolor='none', alpha=0.3, transform=ax.get_xaxis_transform(), @@ -486,9 +481,11 @@ _ = ax.set_title('University of Michigan Consumer Sentiment Index,\n and \ Year-over-year Consumer Price Index Change, 1978-2022 (United States)', pad=30) ``` +We will have a detailed look into inflation in the following lecture (TODO: Link to inflation lecture) + ### Production -Consumer confidence often affects the consumption pattern of consumers. +Consumer confidence often influences the consumption pattern of consumers. This often manifests on the production side. @@ -516,14 +513,12 @@ Total Index, 1919-2022 (United States)', pad=20) ### Credit Level -Credit contraction usually happens with recessions as lenders become more cautious and borrowers become more hesitant to take on additional debt. +Credit contraction usually happens with recessions as lenders become more cautious, and borrowers become more hesitant to take on additional debt. This can be due to several factors such as a decrease in overall economic activity, rising unemployment, and gloomy expectations for the future. One example is domestic credit to the private sector by banks in the UK. -Note that the credit level expands rapidly in the period of economic expansion, and stagnates or even contracts after recessions - ```{code-cell} ipython3 private_credit = wb.data.DataFrame('FS.AST.PRVT.GD.ZS',['GBR'], labels=True) private_credit = private_credit.set_index('Country') @@ -541,3 +536,5 @@ ax = plot_comparison(private_credit, countries, title, ylabel, 0.05, ax, g_params, b_params, t_params, ylim=None, baseline=None) ``` + +Note that the credit level expands rapidly in the period of economic expansion and stagnates or even contracts after recessions. \ No newline at end of file From 924c49ac94708dd7c81f8702f01e80e90234adb0 Mon Sep 17 00:00:00 2001 From: John Stachurski Date: Thu, 23 Mar 2023 15:34:06 +1100 Subject: [PATCH 14/15] misc --- lectures/business_cycle.md | 162 ++++++++++++++++++++++++------------- 1 file changed, 104 insertions(+), 58 deletions(-) diff --git a/lectures/business_cycle.md b/lectures/business_cycle.md index f0c4ab676..02f4b7d75 100644 --- a/lectures/business_cycle.md +++ b/lectures/business_cycle.md @@ -11,17 +11,19 @@ kernelspec: name: python3 --- -# Business Cycle +# Business Cycles ## Overview -This lecture is about illustrating business cycles in different countries and periods. +In this lecture we study business cycles, which +are fluctuations in economic activity over time. -The business cycle refers to the fluctuations in economic activity over time. These fluctuations can be observed in the form of expansions, contractions, recessions, and recoveries in the economy. +These fluctuations can be observed in the form of expansions (booms), contractions (recessions), and recoveries. -In this lecture, we will look into a series of economic indicators to visualize the expansions and contractions of economies from the 1960s to the recent pandemic using[World Bank](https://documents.worldbank.org/en/publication/documents-reports/api), and [FRED](https://fred.stlouisfed.org/) data. +In this lecture, we will look into a series of economic indicators to visualize the expansions and contractions of economies from the 1960s to the recent pandemic using [World Bank](https://documents.worldbank.org/en/publication/documents-reports/api) and [FRED](https://fred.stlouisfed.org/) data. -In addition to what is in Anaconda, this lecture will require the following libraries to obtain World Bank and FRED data +In addition to those installed by Anaconda, this lecture requires +libraries to obtain World Bank and FRED data: ```{code-cell} ipython3 :tags: [hide-output] @@ -43,6 +45,7 @@ import pandas_datareader.data as web ``` ```{code-cell} ipython3 +:tags: [hide-input] # Set Graphical Parameters cycler = plt.cycler(linestyle=['-', '-.', '--', ':'], color=['#377eb8', '#ff7f00', '#4daf4a', '#ff334f']) plt.rc('axes', prop_cycle=cycler) @@ -50,34 +53,31 @@ plt.rc('axes', prop_cycle=cycler) ## Data Acquisition -We will use `wbgapi`, and `pandas_datareader` to retrieve data throughout this lecture. - -They help us speed up the query since we do not need to handle the tedious raw results from the API. +We will use `wbgapi`, and `pandas_datareader` to retrieve data throughout this +lecture. So let's explore how to query data first. -We can use `wb.series.info` with the argument `q` to query available data from the World Bank. - -For example, GDP growth is a key indicator to show expansions and contractions of the level of economic activities. +We can use `wb.series.info` with the argument `q` to query available data from +the [World Bank](https://www.worldbank.org/en/home). -Let's retrieve the ID to query GDP growth data first +For example, let's retrieve the ID to query GDP growth data. ```{code-cell} ipython3 wb.series.info(q='GDP growth') ``` -After retrieving the series ID, it can be used to obtain the data. +After retrieving the series ID, we use it to obtain the data. ```{code-cell} ipython3 :tags: [hide-output] -# Use the series ID retrived before gdp_growth = wb.data.DataFrame('NY.GDP.MKTP.KD.ZG', ['USA', 'ARG', 'GBR', 'GRC', 'JPN'], labels=True) gdp_growth ``` -We can also learn more about the data by checking the metadata of the series +We can learn more about the data by checking the metadata of the series ```{code-cell} ipython3 :tags: [hide-output] @@ -88,9 +88,11 @@ wb.series.metadata.get('NY.GDP.MKTP.KD.ZG') Let's dive into the data with the tools we have. + + ## GDP Growth Rate -First we look at the GDP growth rate and unemployment rate. +First we look at the GDP growth rate Let's source our data from the World Bank and clean the data @@ -102,13 +104,17 @@ gdp_growth = gdp_growth.set_index('Country') gdp_growth.columns = gdp_growth.columns.str.replace('YR', '').astype(int) ``` +Here's a first look at the data, which measures the GDP growth rate in +percentages. + ```{code-cell} ipython3 gdp_growth ``` -Now we write a function to generate plots for individual countries +The cell below contains a function to generate plots for individual countries. ```{code-cell} ipython3 +:tags: [hide-input] def plot_comparison(data, country, title, ylabel, title_pos, ax, g_params, b_params, t_params, ylim=15, baseline=0): @@ -146,7 +152,9 @@ t_params = {'color':'grey', 'fontsize': 9, 'va':'center', 'ha':'center'} ``` -Let's start with the United States +Now we can show some time series. + +Let's start with the United States. ```{code-cell} ipython3 fig, ax = plt.subplots() @@ -159,15 +167,19 @@ _ = plot_comparison(gdp_growth, country, g_params, b_params, t_params) ``` -We find that there is a cyclical pattern across time, and the economy shrinks during recessions. +GDP growth is positive on average and trending slightly downward over time. -Let's look at a few more countries around the world +We also see fluctuations over GDP growth over time, some of which are quite large. + +Let's look at a few more countries to get a basis for comparison. +++ -Britain has a similar pattern compared to the US. +Britain has a similar pattern to the US, with a slow decline in the growth +rate and significant fluctuations. + +Notice the very large dip during the Covid-19 pandemic. -However, it experiences a more significant drop in GDP growth during global economic recessions. ```{code-cell} ipython3 fig, ax = plt.subplots() @@ -180,9 +192,11 @@ _ = plot_comparison(gdp_growth, country, title, b_params, t_params) ``` -Japan and Greece both had a history of rapid growth in the 1960s, but have experienced slowed economic expansion in the past decade. +Now let's consider Japan, which experienced rapid growth in the 1960s and +1970s, followed by slowed expansion in the past two decades. -We can see there is a downward trend in addition to fluctuations in the growth rate +Major dips in the growth rate coincided with the Oil Crisis of the 1970s, the +GFC and the Covid-19 pandemic. ```{code-cell} ipython3 fig, ax = plt.subplots() @@ -194,6 +208,8 @@ _ = plot_comparison(gdp_growth, country, title, b_params, t_params) ``` +Now let's study Greece. + ```{code-cell} ipython3 fig, ax = plt.subplots() @@ -204,11 +220,11 @@ _ = plot_comparison(gdp_growth, country, title, b_params, t_params) ``` -Note that Greece had another significant drop in GDP growth around 2010-2011 during the peak of the Greek debt crisis. -From the series above, we can see similar cyclical patterns across different countries, and major recessions mostly overlap among them. +Greece had a significant drop in GDP growth around 2010-2011, during the peak +of the Greek debt crisis. -However, countries such as Argentina have more volatile cycles compared to the economies mentioned above +Next let's consider Argentina. ```{code-cell} ipython3 fig, ax = plt.subplots() @@ -220,17 +236,22 @@ _ = plot_comparison(gdp_growth, country, title, g_params, b_params, t_params) ``` -One interesting insight is that the GDP growth of Argentina did not fall during the two recessions in the 1970s and 1990s when most of the developed economies were affected. -We will revisit this topic [later](synchronization). +The figure shows that Argentina has experienced more volatile cycles than +the economies mentioned above. + +At the same time, growth of Argentina did not fall during the two developed +economy recessions in the 1970s and 1990s. + +++ ## Unemployment -Another important indicator of business cycles is the unemployment rate. +Another important measure of business cycles is the unemployment rate. -During a recession, it is more likely that a larger proportion of the working population will be laid off. +During a recession, it is more likely that a larger proportion of the working +population will be laid off. We demonstrate this using a long-run unemployment rate from FRED spanning from [1929-1942](https://fred.stlouisfed.org/series/M0892AUSM156SNBR) to [1948-2022](https://fred.stlouisfed.org/series/UNRATE) with the unemployment rate between 1942 and 1948 estimated by [The Census Bureau](https://www.census.gov/library/publications/1975/compendia/hist_stats_colonial-1970.html). @@ -292,27 +313,35 @@ ax.set_ylabel('Unemployment Rate (%)') _ = ax.set_title('Long-run Unemployment Rate, 1929-2022\n with Recession Indicators (United States)', pad=30) ``` -In the plot, we can see that the expansions and contractions of the labor market have been highly correlated with recessions. +In the plot, we can see that the expansions and contractions of the labor +market have been highly correlated with recessions. -However, there is often a delay in the recovery of the labor market after recessions. +However, there is often a delay in the recovery of the labor market after +recessions. -This trend is clearly visible in the 1930s, as well as in recessions in the 1980s. +This trend is clearly visible in the 1930s, as well as in recessions in the +1980s. -It also shows us how unique the labor market condition is during the post-pandemic recovery. +It also shows us how unique labor market conditions have been during the +post-pandemic recovery. -The labor market is recovering at an unprecedented rate, leading to the tightest point in the past decades after the shock in 2020-2021. +The labor market has recovered at an unprecedented rate, leading to the +tightest point in the past decades after the shock in 2020-2021. +++ (synchronization)= ## Synchronization -In our previous discussion, we found that developed economies have a more synchronized period of recessions, -but the synchronization does not appear in Argentina until the 2000s. +In our previous discussion, we found that developed economies have had +relatively synchronized period of recessions. + +At the same time, this synchronization does not appear in Argentina until the 2000s. Let's examine this trend further. -With slight modifications, we can use our previous function to draw a plot that includes many countries +With slight modifications, we can use our previous function to draw a plot +that includes many countries ```{code-cell} ipython3 def plot_comparison_multi(data, countries, title, @@ -379,14 +408,19 @@ title = 'Brazil, China, Argentina, and Mexico (GDP Growth Rate %)' _ = plot_comparison_multi(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, 20, ax, g_params, b_params, t_params) ``` -By comparing the trend of GDP growth rates between developed and developing economies, we find that business cycles are becoming more and more synchronized in 21st-century recessions. - +By comparing the trend of GDP growth rates between developed and developing +economies, we find that business cycles are becoming more and more +synchronized in 21st-century recessions. -However, emerging and less developed economies often experience more volatile changes throughout the economic cycles. +However, emerging and less developed economies often experience more volatile +changes throughout the economic cycles. -Although we have seen synchronization in GDP growth as a general trend, we also need to acknowledge that the experience of individual countries during the recession is often very different. +Although we have seen synchronization in GDP growth as a general trend, we +also need to acknowledge that the experience of individual countries during +the recession is often very different. -Here we use the unemployment rate and the recovery of labor market condition as another example +Here we use the unemployment rate and the recovery of labor market condition +as another example. ```{code-cell} ipython3 unempl_rate = wb.data.DataFrame('SL.UEM.TOTL.NE.ZS', @@ -406,33 +440,41 @@ _ = plot_comparison_multi(unempl_rate, countries, title, b_params, t_params, baseline=None) ``` -France, with its strong labor unions, has a prolonged labor market recovery compared to the US and UK. +France, with its strong labor unions, has a prolonged labor market recovery +compared to the US and UK. -However, Japan has a history of very low and stable unemployment rates due to a constellation of social, demographic, and cultural factors. +However, Japan has a history of very low and stable unemployment rates due to +a constellation of social, demographic, and cultural factors. +++ ## Leading Indicators and Correlated Factors for Business Cycles -Understanding leading indicators and correlated factors helps policymakers to better understand and reflect on the causes and results of business cycles. +Understanding leading indicators and correlated factors helps policymakers to +better understand and reflect on the causes and results of business cycles. -We will discuss potential leading indicators and correlated factors from three perspectives: consumption, production, and credit level. +We will discuss potential leading indicators and correlated factors from three +perspectives: consumption, production, and credit level. ### Consumption +++ -Consumption level is dependent on how confident consumers are toward their income and the overall performance of the economy in the future. +Consumption is dependent on how confident consumers are toward their +income and the overall performance of the economy in the future. -One widely cited indicator for consumer confidence is the [Consumer Sentiment Index](https://fred.stlouisfed.org/series/UMCSENT) published by the University of Michigan. +One widely cited indicator for consumer confidence is the [Consumer Sentiment Index](https://fred.stlouisfed.org/series/UMCSENT) published by the University +of Michigan. -We find that consumer sentiment maintains a high level during the expansion period, but there are significant drops before the recession hits. +We find that consumer sentiment maintains a high level during the expansion +period, but there are significant drops before the recession hits. There is also a clear negative correlation between consumer sentiment and [core consumer price index](https://fred.stlouisfed.org/series/CPILFESL). This trend is more significant in the period of [stagflation](https://en.wikipedia.org/wiki/Stagflation). -When the price of consumer commodities in the market is higher, consumer confidence diminishes. +When the price of consumer commodities in the market is higher, consumer +confidence diminishes. ```{code-cell} ipython3 start_date = datetime.datetime(1978, 1, 1) @@ -481,7 +523,6 @@ _ = ax.set_title('University of Michigan Consumer Sentiment Index,\n and \ Year-over-year Consumer Price Index Change, 1978-2022 (United States)', pad=30) ``` -We will have a detailed look into inflation in the following lecture (TODO: Link to inflation lecture) ### Production @@ -489,9 +530,11 @@ Consumer confidence often influences the consumption pattern of consumers. This often manifests on the production side. -We find that the real output of the industry is also highly correlated with recessions in the economy. +We find that the real output of the industry is also highly correlated with +recessions in the economy. -However, instead of being a leading factor, the peak of the contraction in the production delays compared to consumer confidence and inflation +However, instead of being a leading factor, the peak of the contraction in the +production delays compared to consumer confidence and inflation ```{code-cell} ipython3 start_date = datetime.datetime(1919, 1, 1) @@ -513,9 +556,11 @@ Total Index, 1919-2022 (United States)', pad=20) ### Credit Level -Credit contraction usually happens with recessions as lenders become more cautious, and borrowers become more hesitant to take on additional debt. +Credit contractions often occur during recessions, as lenders become more +cautious and borrowers become more hesitant to take on additional debt. -This can be due to several factors such as a decrease in overall economic activity, rising unemployment, and gloomy expectations for the future. +This can be due to several factors such as a decrease in overall economic +activity, rising unemployment, and gloomy expectations for the future. One example is domestic credit to the private sector by banks in the UK. @@ -537,4 +582,5 @@ ax = plot_comparison(private_credit, countries, title, t_params, ylim=None, baseline=None) ``` -Note that the credit level expands rapidly in the period of economic expansion and stagnates or even contracts after recessions. \ No newline at end of file +Note that the credit level expands rapidly in the period of economic expansion +and stagnates or even contracts after recessions. From 84fb9651e412c3e7b35a041f5bd6161ec6a9b5d5 Mon Sep 17 00:00:00 2001 From: John Stachurski Date: Thu, 23 Mar 2023 15:38:46 +1100 Subject: [PATCH 15/15] misc --- lectures/business_cycle.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lectures/business_cycle.md b/lectures/business_cycle.md index 02f4b7d75..ae1fc0cb8 100644 --- a/lectures/business_cycle.md +++ b/lectures/business_cycle.md @@ -175,8 +175,8 @@ Let's look at a few more countries to get a basis for comparison. +++ -Britain has a similar pattern to the US, with a slow decline in the growth -rate and significant fluctuations. +The United Kingdom (UK) has a similar pattern to the US, with a slow decline +in the growth rate and significant fluctuations. Notice the very large dip during the Covid-19 pandemic. @@ -473,8 +473,7 @@ There is also a clear negative correlation between consumer sentiment and [core This trend is more significant in the period of [stagflation](https://en.wikipedia.org/wiki/Stagflation). -When the price of consumer commodities in the market is higher, consumer -confidence diminishes. +When the price of consumer commodities rises, consumer confidence diminishes. ```{code-cell} ipython3 start_date = datetime.datetime(1978, 1, 1)