|
| 1 | +--- |
| 2 | +jupytext: |
| 3 | + text_representation: |
| 4 | + extension: .md |
| 5 | + format_name: myst |
| 6 | + format_version: 0.13 |
| 7 | + jupytext_version: 1.14.4 |
| 8 | +kernelspec: |
| 9 | + display_name: Python 3 (ipykernel) |
| 10 | + language: python |
| 11 | + name: python3 |
| 12 | +--- |
| 13 | + |
| 14 | +# Business Cycle |
| 15 | + |
| 16 | +## Overview |
| 17 | + |
| 18 | +This lecture is about illustrateing business cycles in different countries and period. |
| 19 | + |
| 20 | +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. |
| 21 | + |
| 22 | +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). |
| 23 | + |
| 24 | +In addition to what's in Anaconda, this lecture will need the following libraries to get World bank data |
| 25 | + |
| 26 | +```{code-cell} ipython3 |
| 27 | +:tags: [hide-output] |
| 28 | +
|
| 29 | +!pip install wbgapi |
| 30 | +!pip install imfpy |
| 31 | +``` |
| 32 | + |
| 33 | +We use the following imports |
| 34 | + |
| 35 | +```{code-cell} ipython3 |
| 36 | +import matplotlib.pyplot as plt |
| 37 | +import pandas as pd |
| 38 | +import numpy as np |
| 39 | +import scipy.stats as st |
| 40 | +import wbgapi as wb |
| 41 | +from imfpy.retrievals import dots |
| 42 | +``` |
| 43 | + |
| 44 | +## Data Acquaisition |
| 45 | + |
| 46 | +We will use `wbgapi` and `imfpy` to retrieve data from the World Bank and IMF API throughout this lecture. |
| 47 | + |
| 48 | +So let's explore how to query data together. |
| 49 | + |
| 50 | +We can use `wb.series.info` with parameter `q` to query available data from the World Bank (`imfpy. searches.database_codes()` in `imfpy`) |
| 51 | + |
| 52 | +For example, GDP growth is a key indicator to show the expension and contraction of level of economic activities. |
| 53 | + |
| 54 | +Let's retrive GDP growth data together |
| 55 | + |
| 56 | +```{code-cell} ipython3 |
| 57 | +wb.series.info(q='GDP growth') |
| 58 | +``` |
| 59 | + |
| 60 | +In a similar fashion, we can also retrieve data that covers different aspects of economic activities. |
| 61 | + |
| 62 | +We can cover indicators of |
| 63 | + |
| 64 | +- labour market |
| 65 | + |
| 66 | +```{code-cell} ipython3 |
| 67 | +:tags: [hide-output] |
| 68 | +
|
| 69 | +wb.series.info(q='unemployment') |
| 70 | +``` |
| 71 | + |
| 72 | +- credit level |
| 73 | + |
| 74 | +```{code-cell} ipython3 |
| 75 | +:tags: [hide-output] |
| 76 | +
|
| 77 | +wb.series.info(q='credit') |
| 78 | +``` |
| 79 | + |
| 80 | +- consumer price index |
| 81 | + |
| 82 | +```{code-cell} ipython3 |
| 83 | +:tags: [hide-output] |
| 84 | +
|
| 85 | +wb.series.info(q='consumer') |
| 86 | +``` |
| 87 | + |
| 88 | +- consumption level |
| 89 | + |
| 90 | +```{code-cell} ipython3 |
| 91 | +:tags: [hide-output] |
| 92 | +
|
| 93 | +wb.series.info(q='consumption') |
| 94 | +``` |
| 95 | + |
| 96 | +```{code-cell} ipython3 |
| 97 | +wb.series.info(q='capital account') # TODO: Check if it is to be plotted |
| 98 | +``` |
| 99 | + |
| 100 | +- international trade volumn |
| 101 | + |
| 102 | ++++ |
| 103 | + |
| 104 | +These indicators will give us an overview of variations in economic activities across time. |
| 105 | + |
| 106 | +## GDP Growth Rate and Unemployment |
| 107 | + |
| 108 | +First we look at the GDP growth rate and unemployment rate. |
| 109 | + |
| 110 | +Let's source our data from the World Bank and clean the data |
| 111 | + |
| 112 | +```{code-cell} ipython3 |
| 113 | +gdp_growth = wb.data.DataFrame('NY.GDP.MKTP.KD.ZG',['CHN', 'USA', 'DEU', 'BRA', 'ARG', 'GBR', 'MEX', 'CHL', 'COL', 'SLV', 'HTI'], labels=True) |
| 114 | +gdp_growth = gdp_growth.set_index('Country') |
| 115 | +gdp_growth.columns = gdp_growth.columns.str.replace('YR', '').astype(int) |
| 116 | +``` |
| 117 | + |
| 118 | +```{code-cell} ipython3 |
| 119 | +gdp_growth |
| 120 | +``` |
| 121 | + |
| 122 | +```{code-cell} ipython3 |
| 123 | +cycler = plt.cycler(linestyle=['-', '-.', '--'], color=['#377eb8', '#ff7f00', '#4daf4a']) |
| 124 | +plt.rc('axes', prop_cycle=cycler) |
| 125 | +``` |
| 126 | + |
| 127 | +```{code-cell} ipython3 |
| 128 | +fig, ax = plt.subplots() |
| 129 | +ax.set_xticks([i for i in range(1960, 2021, 10)], minor=False) |
| 130 | +plt.locator_params(axis='x', nbins=10) |
| 131 | +
|
| 132 | +def plot_comparison(data, countries, title, ylabel, title_pos, ax, g_params, b_params, t_params): |
| 133 | + for country in countries: |
| 134 | + ax.plot(data.loc[country], label=country, **g_params) |
| 135 | + ax.axvspan(1973, 1975, **b_params) |
| 136 | + ax.axvspan(1990, 1992, **b_params) |
| 137 | + ax.axvspan(2007, 2009, **b_params) |
| 138 | + ax.axvspan(2019, 2021, **b_params) |
| 139 | + ylim = ax.get_ylim()[1] |
| 140 | + ax.text(1974, ylim + ylim * title_pos, 'Oil Crisis\n(1974)', **t_params) |
| 141 | + ax.text(1991, ylim + ylim * title_pos, '1990s recession\n(1991)', **t_params) |
| 142 | + ax.text(2008, ylim + ylim * title_pos, 'GFC\n(2008)', **t_params) |
| 143 | + ax.text(2020, ylim + ylim * title_pos, 'Covid-19\n(2020)', **t_params) |
| 144 | + ax.set_title(title, pad=40) |
| 145 | + ax.set_ylabel(ylabel) |
| 146 | + ax.legend() |
| 147 | + return ax |
| 148 | +
|
| 149 | +g_params = {'alpha': 0.7} |
| 150 | +b_params = {'color':'grey', 'alpha': 0.2} |
| 151 | +t_params = {'color':'grey', 'fontsize': 9, 'va':'center', 'ha':'center'} |
| 152 | +countries = ['United Kingdom', 'United States', 'Germany'] |
| 153 | +title = 'United Kingdom, United States, and Germany (GDP Growth Rate %)' |
| 154 | +ylabel = 'GDP Growth Rate (%)' |
| 155 | +title_height = 0.1 |
| 156 | +ax = plot_comparison(gdp_growth, countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) |
| 157 | +``` |
| 158 | + |
| 159 | +```{code-cell} ipython3 |
| 160 | +fig, ax = plt.subplots() |
| 161 | +
|
| 162 | +countries = ['Brazil', 'China', 'Argentina'] |
| 163 | +title = 'Brazil, China, Argentina (GDP Growth Rate %)' |
| 164 | +ax = plot_comparison(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) |
| 165 | +``` |
| 166 | + |
| 167 | +```{code-cell} ipython3 |
| 168 | +fig, ax = plt.subplots() |
| 169 | +
|
| 170 | +countries = ['Argentina'] |
| 171 | +title = 'Argentina (GDP Growth Rate %)' |
| 172 | +ax = plot_comparison(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) |
| 173 | +``` |
| 174 | + |
| 175 | +```{code-cell} ipython3 |
| 176 | +fig, ax = plt.subplots() |
| 177 | +
|
| 178 | +countries = ['Mexico'] |
| 179 | +title = 'Mexico (GDP Growth Rate %)' |
| 180 | +ax = plot_comparison(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) |
| 181 | +``` |
| 182 | + |
| 183 | +```{code-cell} ipython3 |
| 184 | +fig, ax = plt.subplots() |
| 185 | +
|
| 186 | +countries = ['Chile'] |
| 187 | +title = 'Chile (GDP Growth Rate %)' |
| 188 | +ax = plot_comparison(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) |
| 189 | +``` |
| 190 | + |
| 191 | +```{code-cell} ipython3 |
| 192 | +fig, ax = plt.subplots() |
| 193 | +
|
| 194 | +countries = ['Colombia'] |
| 195 | +title = 'Colombia (GDP Growth Rate %)' |
| 196 | +ax = plot_comparison(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) |
| 197 | +``` |
| 198 | + |
| 199 | +```{code-cell} ipython3 |
| 200 | +fig, ax = plt.subplots() |
| 201 | +
|
| 202 | +countries = ['El Salvador'] |
| 203 | +title = 'El Salvador (GDP Growth Rate %)' |
| 204 | +ax = plot_comparison(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) |
| 205 | +``` |
| 206 | + |
| 207 | +```{code-cell} ipython3 |
| 208 | +fig, ax = plt.subplots() |
| 209 | +
|
| 210 | +countries = ['Haiti'] |
| 211 | +title = 'Haiti (GDP Growth Rate %)' |
| 212 | +ax = plot_comparison(gdp_growth.loc[countries, 1962:], countries, title, ylabel, 0.1, ax, g_params, b_params, t_params) |
| 213 | +``` |
| 214 | + |
| 215 | +```{code-cell} ipython3 |
| 216 | +unempl_rate = wb.data.DataFrame('SL.UEM.TOTL.NE.ZS',['CHN', 'USA', 'DEU', 'BRA', 'ARG', 'GBR', 'MEX', 'CHL', 'COL', 'SLV', 'HTI'], labels=True) |
| 217 | +unempl_rate = unempl_rate.set_index('Country') |
| 218 | +unempl_rate.columns = unempl_rate.columns.str.replace('YR', '').astype(int) |
| 219 | +``` |
| 220 | + |
| 221 | +```{code-cell} ipython3 |
| 222 | +fig, ax = plt.subplots() |
| 223 | +
|
| 224 | +countries = ['United Kingdom', 'United States', 'Germany'] |
| 225 | +title = 'United Kingdom, United States, and Germany (Unemployment Rate %)' |
| 226 | +ylabel = 'Unemployment Rate (National Estimate) (%)' |
| 227 | +ax = plot_comparison(unempl_rate, countries, title, ylabel, 0.03, ax, g_params, b_params, t_params) |
| 228 | +``` |
| 229 | + |
| 230 | +```{code-cell} ipython3 |
| 231 | +fig, ax = plt.subplots() |
| 232 | +
|
| 233 | +countries = ['Brazil', 'China', 'Argentina'] |
| 234 | +title = 'Brazil, China, Argentina (Unemployment Rate %)' |
| 235 | +ax = plot_comparison(unempl_rate, countries, title, ylabel, 0.04, ax, g_params, b_params, t_params) |
| 236 | +``` |
| 237 | + |
| 238 | +```{code-cell} ipython3 |
| 239 | +fig, ax = plt.subplots() |
| 240 | +
|
| 241 | +countries = ['Brazil'] |
| 242 | +title = 'Brazil (Unemployment Rate %)' |
| 243 | +ax = plot_comparison(unempl_rate, countries, title, ylabel, 0.04, ax, g_params, b_params, t_params) |
| 244 | +``` |
| 245 | + |
| 246 | +```{code-cell} ipython3 |
| 247 | +fig, ax = plt.subplots() |
| 248 | +
|
| 249 | +countries = ['Chile'] |
| 250 | +title = 'Chile (Unemployment Rate %)' |
| 251 | +ax = plot_comparison(unempl_rate, countries, title, ylabel, 0.04, ax, g_params, b_params, t_params) |
| 252 | +``` |
| 253 | + |
| 254 | +```{code-cell} ipython3 |
| 255 | +fig, ax = plt.subplots() |
| 256 | +
|
| 257 | +countries = ['Colombia'] |
| 258 | +title = 'Colombia (Unemployment Rate %)' |
| 259 | +ax = plot_comparison(unempl_rate, countries, title, ylabel, 0.04, ax, g_params, b_params, t_params) |
| 260 | +``` |
| 261 | + |
| 262 | +```{code-cell} ipython3 |
| 263 | +fig, ax = plt.subplots() |
| 264 | +
|
| 265 | +countries = ['El Salvador'] |
| 266 | +title = 'El Salvador (Unemployment Rate %)' |
| 267 | +ax = plot_comparison(unempl_rate, countries, title, ylabel, 0.04, ax, g_params, b_params, t_params) |
| 268 | +``` |
| 269 | + |
| 270 | +## Credit Level |
| 271 | + |
| 272 | +```{code-cell} ipython3 |
| 273 | +private_credit = wb.data.DataFrame('FD.AST.PRVT.GD.ZS',['CHN', 'USA', 'DEU', 'BRA', 'ARG', 'GBR'], labels=True) |
| 274 | +private_credit = private_credit.set_index('Country') |
| 275 | +private_credit.columns = private_credit.columns.str.replace('YR', '').astype(int) |
| 276 | +``` |
| 277 | + |
| 278 | +```{code-cell} ipython3 |
| 279 | +fig, ax = plt.subplots() |
| 280 | +
|
| 281 | +countries = ['United Kingdom', 'United States', 'Germany'] |
| 282 | +title = 'United Kingdom, United States, and Germany \n Domestic credit to private sector by banks (% of GDP)' |
| 283 | +ylabel = '% of GDP' |
| 284 | +ax = plot_comparison(private_credit, countries, title, ylabel, 0.05, ax, g_params, b_params, t_params) |
| 285 | +``` |
| 286 | + |
| 287 | +```{code-cell} ipython3 |
| 288 | +fig, ax = plt.subplots() |
| 289 | +
|
| 290 | +countries = ['Brazil', 'China', 'Argentina'] |
| 291 | +title = 'Brazil, China, Argentina \n Domestic credit to private sector by banks (% of GDP)' |
| 292 | +ax = plot_comparison(private_credit, countries, title, ylabel, 0.05, ax, g_params, b_params, t_params) |
| 293 | +``` |
| 294 | + |
| 295 | +```{code-cell} ipython3 |
| 296 | +fig, ax = plt.subplots() |
| 297 | +
|
| 298 | +countries = ['United Kingdom', 'China'] |
| 299 | +title = 'United Kingdom and China \n Domestic credit to private sector by banks (% of GDP)' |
| 300 | +ax = plot_comparison(private_credit, countries, title, ylabel, 0.05, ax, g_params, b_params, t_params) |
| 301 | +``` |
| 302 | + |
| 303 | +## Inflation |
| 304 | + |
| 305 | +```{code-cell} ipython3 |
| 306 | +cpi = wb.data.DataFrame('FP.CPI.TOTL.ZG',['CHN', 'USA', 'DEU', 'BRA', 'ARG', 'GBR'], labels=True) |
| 307 | +cpi = cpi.set_index('Country') |
| 308 | +cpi.columns = cpi.columns.str.replace('YR', '').astype(int) |
| 309 | +``` |
| 310 | + |
| 311 | +```{code-cell} ipython3 |
| 312 | +fig, ax = plt.subplots() |
| 313 | +
|
| 314 | +countries = ['United Kingdom', 'United States', 'Germany'] |
| 315 | +title = 'United Kingdom, United States, and Germany \n Inflation, consumer prices (annual %)' |
| 316 | +ylabel = 'annual %' |
| 317 | +ax = plot_comparison(cpi, countries, title, ylabel, 0.05, ax, g_params, b_params, t_params) |
| 318 | +``` |
| 319 | + |
| 320 | +## International Trade |
| 321 | + |
| 322 | +```{code-cell} ipython3 |
| 323 | +trade_us = dots('US','W00', 1960, 2020, freq='A') |
| 324 | +trade_us['Period'] = trade_us['Period'].astype('int') |
| 325 | +``` |
| 326 | + |
| 327 | +```{code-cell} ipython3 |
| 328 | +def plot_trade(data, title, ylabel, title_pos, ax, g_params, b_params, t_params): |
| 329 | + ax.plot(data['Period'], data['Twoway Trade'], **g_params) |
| 330 | + ax.axvspan(1973, 1975, **b_params) |
| 331 | + ax.axvspan(1990, 1992, **b_params) |
| 332 | + ax.axvspan(2007, 2009, **b_params) |
| 333 | + ax.axvspan(2019, 2021, **b_params) |
| 334 | + ylim = ax.get_ylim()[1] |
| 335 | + ax.text(1974, ylim + ylim * title_pos, 'Oil Crisis\n(1974)', **t_params) |
| 336 | + ax.text(1991, ylim + ylim * title_pos, '1990s recession\n(1991)', **t_params) |
| 337 | + ax.text(2008, ylim + ylim * title_pos, 'GFC\n(2008)', **t_params) |
| 338 | + ax.text(2020, ylim + ylim * title_pos, 'Covid-19\n(2020)', **t_params) |
| 339 | + ax.set_title(title, pad=40) |
| 340 | + ax.set_ylabel(ylabel) |
| 341 | + return ax |
| 342 | +
|
| 343 | +
|
| 344 | +fig, ax = plt.subplots() |
| 345 | +title = 'United States (International Trade Volumn)' |
| 346 | +ylabel = 'US Dollars, Millions' |
| 347 | +plot_UStrade = plot_trade(trade_us[['Period', 'Twoway Trade']], title, ylabel, 0.05, ax, g_params, b_params, t_params) |
| 348 | +``` |
| 349 | + |
| 350 | +```{code-cell} ipython3 |
| 351 | +fig, ax = plt.subplots() |
| 352 | +trade_cn = dots('CN','W00', 1960, 2020, freq='A') |
| 353 | +
|
| 354 | +trade_cn['Period'] = trade_cn['Period'].astype('int') |
| 355 | +title = 'China (International Trade Volumn)' |
| 356 | +ylabel = 'US Dollars, Millions' |
| 357 | +plot_trade_cn = plot_trade(trade_cn[['Period', 'Twoway Trade']], title, ylabel, 0.05, ax, g_params, b_params, t_params) |
| 358 | +``` |
| 359 | + |
| 360 | +```{code-cell} ipython3 |
| 361 | +fig, ax = plt.subplots() |
| 362 | +trade_mx = dots('MX','W00', 1960, 2020, freq='A') |
| 363 | +
|
| 364 | +trade_mx['Period'] = trade_mx['Period'].astype('int') |
| 365 | +title = 'Mexico (International Trade Volumn)' |
| 366 | +ylabel = 'US Dollars, Millions' |
| 367 | +plot_trade_mx = plot_trade(trade_mx[['Period', 'Twoway Trade']], title, ylabel, 0.05, ax, g_params, b_params, t_params) |
| 368 | +``` |
| 369 | + |
| 370 | +```{code-cell} ipython3 |
| 371 | +fig, ax = plt.subplots() |
| 372 | +trade_ar = dots('AR','W00', 1960, 2020, freq='A') |
| 373 | +
|
| 374 | +trade_ar['Period'] = trade_ar['Period'].astype('int') |
| 375 | +title = 'Argentina (International Trade Volumn)' |
| 376 | +ylabel = 'US Dollars, Millions' |
| 377 | +plot_trade_ar = plot_trade(trade_ar[['Period', 'Twoway Trade']], title, ylabel, 0.05, ax, g_params, b_params, t_params) |
| 378 | +``` |
0 commit comments