GDP per capita #
This category group contains point-in-time indicators of GDP per capita, both in USD terms and adjusted for purchasing power parity to account for differences in cost of living and inflation rates.
GDP per capita in U.S. dollars #
Ticker : GDPPC_SA / _P1Q1QL4 / _P1Qv5YMA
Label : GDP (1-year moving average) per capita in USD : level / % oya / % 1q vs 5yma
Definition : Nominal GDP in USD, one year moving average, per capita: level / % over year ago / % change, latest quarter versus 5-year moving average.
Notes :
-
USD GDP values are obtained by converting local-currency nominal GDP values according to the national accounts and by the average USD exchange rate for the quarter.
-
The 1-year moving average of the nominal GDP is formed over the coverted USD values of nomrinal GDP and then divided by the population.
-
Population data are taken from national statistics sources. If population data have longer publication lags then the national accounts, the latest available value of population is used to calculate GDP per capita ratios.
GDP per capita in purchasing power parity terms #
Ticker : GDPPPPFXPC_SA / _P1Q1QL4 / _P1Qv5YMA
Label : GDP (1-year moving average) per capita in PPP-terms: level / % oya / % 1q vs 5yma
Definition : Nominal GDP in PPP terms, one year moving average, per capita: level / % over year ago / % change, latest quarter versus 5-year moving average.
Notes :
-
USD GDP values are obtained by converting local-currency nominal GDP values according to the national accounts and by the average USD exchange rate for the quarter.
-
The 1-year moving average of the nominal GDP is formed over the coverted USD values of nomrinal GDP and then divided by the population.
-
Population data are taken from national statistics sources. If population data have longer publication lags then the national accounts, the latest available value of population is used to calculate GDP per capita ratios.
-
Purchasing power parity adjustment is done by dividing the GDP per capita in USD by the PPP conversion rate. Its unit is still USD but represents the U.S.-equivalent value the of goods and services that can be purchased in the local economy with the nominal USD GDP amount. For low-income countries, this value is typically higher than the nominal GDP, because goods and, particularly, services are cheaper in USD terms. Daily PPP-coversion values are based on various surveys and estimations based on local CPI values. More info on the PPP can be found here .
-
As PPP is defined in USD we do not calculate PPP adjusted GDP per capita for USD. And as PPP is not available for TWD the related GDP per capita statistic cannot be calculated.
Imports #
Only the standard Python data science packages and the specialized
macrosynergy
package are needed.
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import math
import json
import yaml
import macrosynergy.management as msm
import macrosynergy.panel as msp
import macrosynergy.signal as mss
import macrosynergy.pnl as msn
from macrosynergy.download import JPMaQSDownload
from timeit import default_timer as timer
from datetime import timedelta, date, datetime
import warnings
warnings.simplefilter("ignore")
The
JPMaQS
indicators we consider are downloaded using the J.P. Morgan Dataquery API interface within the
macrosynergy
package. This is done by specifying
ticker strings
, formed by appending an indicator category code
<category>
to a currency area code
<cross_section>
. These constitute the main part of a full quantamental indicator ticker, taking the form
DB(JPMAQS,<cross_section>_<category>,<info>)
, where
<info>
denotes the time series of information for the given cross-section and category. The following types of information are available:
-
value
giving the latest available values for the indicator -
eop_lag
referring to days elapsed since the end of the observation period -
mop_lag
referring to the number of days elapsed since the mean observation period -
grade
denoting a grade of the observation, giving a metric of real time information quality.
After instantiating the
JPMaQSDownload
class within the
macrosynergy.download
module, one can use the
download(tickers,start_date,metrics)
method to easily download the necessary data, where
tickers
is an array of ticker strings,
start_date
is the first collection date to be considered and
metrics
is an array comprising the times series information to be downloaded.
cids_dm = ["AUD", "CAD", "CHF", "EUR", "GBP", "JPY", "NOK", "NZD", "SEK", "USD"]
cids_latm = ["BRL", "COP", "CLP", "MXN", "PEN"]
cids_emea = ["CZK", "HUF", "ILS", "PLN", "RON", "RUB", "TRY", "ZAR"]
cids_emas = ["CNY", "IDR", "INR", "KRW", "MYR", "PHP", "SGD", "THB", "TWD"]
cids_eu = ["NLG","FRF","ESP","DEM","ITL"]
cids_em = cids_latm + cids_emea + cids_emas
cids = sorted(cids_dm + cids_em)
# Define quantamental indicators (category tickers)
main = [
"GDPPC_SA",
"GDPPPPFXPC_SA",
"GDPPC_SA_P1Q1QL4",
"GDPPPPFXPC_SA_P1Q1QL4",
"GDPPC_SA_P1Qv5YMA",
"GDPPPPFXPC_SA_P1Qv5YMA",
]
econ = [
"FXTARGETED_NSA",
"FXUNTRADABLE_NSA"
] # economic context
mark = [
"FXXRHvGDRB_NSA",
"FXXR_NSA",
"FXXR_VT10",
"RIR_NSA"
] # market links
xcats = main + econ + mark
# Download series from J.P. Morgan DataQuery by tickers
start_date = "1990-01-01"
tickers = [cid + "_" + xcat for cid in cids for xcat in xcats]
print(f"Maximum number of tickers is {len(tickers)}")
# Retrieve credentials
client_id: str = os.getenv("DQ_CLIENT_ID")
client_secret: str = os.getenv("DQ_CLIENT_SECRET")
# Download from DataQuery
with JPMaQSDownload(client_id=client_id, client_secret=client_secret) as downloader:
start = timer()
df = downloader.download(
tickers=tickers,
start_date=start_date,
show_progress=True,
report_time_taken=True,
metrics=["value", "eop_lag", "mop_lag", "grading"],
suppress_warning=True,
)
end = timer()
dfd = df
print("Download time from DQ: " + str(timedelta(seconds=end - start)))
Maximum number of tickers is 384
Downloading data from JPMaQS.
Timestamp UTC: 2024-11-20 16:19:05
Connection successful!
Requesting data: 100%|██████████| 77/77 [00:15<00:00, 4.95it/s]
Downloading data: 100%|██████████| 77/77 [00:40<00:00, 1.89it/s]
Time taken to download data: 62.28 seconds.
Some expressions are missing from the downloaded data. Check logger output for complete list.
44 out of 1536 expressions are missing. To download the catalogue of all available expressions and filter the unavailable expressions, set `get_catalogue=True` in the call to `JPMaQSDownload.download()`.
Some dates are missing from the downloaded data.
281 out of 9105 dates are missing.
Download time from DQ: 0:01:03.280385
Availability #
cids_exp = cids # cids expected in category panels
msm.missing_in_df(dfd, xcats=main, cids=cids_exp)
No missing XCATs across DataFrame.
Missing cids for GDPPC_SA: []
Missing cids for GDPPC_SA_P1Q1QL4: []
Missing cids for GDPPC_SA_P1Qv5YMA: []
Missing cids for GDPPPPFXPC_SA: ['TWD', 'USD']
Missing cids for GDPPPPFXPC_SA_P1Q1QL4: ['TWD', 'USD']
Missing cids for GDPPPPFXPC_SA_P1Qv5YMA: ['TWD', 'USD']
For most countries the simple per capita data is available since the 1990’s, however when using the 5-year lookback most EM countries will only begin the 2000’s.
xcatx = main
cidx = cids_exp
dfx = msm.reduce_df(dfd, xcats=xcatx, cids=cidx)
dfs = msm.check_startyears(
dfx,
)
msm.visual_paneldates(dfs, size=(18, 8))
print("Last updated:", date.today())
Last updated: 2024-11-20
xcatx = main
cidx = cids_exp
plot = msm.check_availability(
dfd, xcats=xcatx, cids=cidx, start_size=(18, 8), start_years=False
)
Most developed markets have grade 1 vintages, compared to emerging markets which are more mixed.
plot = msp.heatmap_grades(
dfd,
xcats=main,
cids=cids_exp,
size=(19, 2),
title=f"Average vintage grades from {start_date} onwards",
)
msp.view_ranges(
dfd,
xcats = ["GDPPC_SA"],
cids=cids_exp,
val="eop_lag",
title="End of observation period lags (ranges of time elapsed since end of observation period in days)",
start=start_date,
kind="box",
size=(16, 4),
)
msp.view_ranges(
dfd,
xcats=["GDPPC_SA"],
cids=cids_exp,
val="mop_lag",
title="Median of observation period lags (ranges of time elapsed since end of observation period in days)",
start=start_date,
kind="box",
size=(16, 4),
)
History #
GDP per capita #
Differences in GDP per capita in U.S. dollar across economies with liquid derivatives markets have been in double-digit multiples over the past decades. The differences in GDP per capita in PPP terms have been less but still reached high single-digit multiples.
xcatx = ["GDPPC_SA", "GDPPPPFXPC_SA"]
cidx = cids_exp
msp.view_ranges(
dfd,
xcats=xcatx,
cids=cidx,
start="1995-01-01",
sort_cids_by="mean",
kind="bar",
size=(16, 8),
title="Means and standard deviations of GDP per capita, since 1995",
xcat_labels=["USD terms", "PPP terms"],
)
The expansions of GDP per capita in PPP terms have generally been smoother than in USD terms, mainly because their effect of spot USD exchange rates is mitigated through the PPP adjustment. However, PPP values show occasional sudden jumps as consequences of revisions in PPP estimates by the World Bank or the OECD.
xcatx = ["GDPPC_SA", "GDPPPPFXPC_SA"]
cidx = cids_exp
msp.view_timelines(
dfd,
xcats=xcatx,
cids=cidx,
start="1995-01-01",
title="GDP per capita, 1-year moving averages and cross-country average (red)",
title_adj=1.02,
title_xadj=0.5,
title_fontsize=27,
ncol=4,
same_y=False,
aspect=1.7,
all_xticks=True,
size=(16, 8),
xcat_labels=["USD terms", "PPP terms"],
)
GDP per capita ratios in USD terms have not generally been converging in past decades.
xcatx = ["GDPPC_SA"]
cidx = cids_exp
msp.view_timelines(
dfd,
xcats=xcatx,
cids=cidx,
start="1995-01-01",
title="GDP per capita, 1-year moving averages and cross-country average (red)",
cs_mean=True,
title_adj=1.02,
title_xadj=0.5,
title_fontsize=27,
ncol=4,
same_y=False,
aspect=1.7,
all_xticks=True,
size=(16, 8),
)
USD GDP per capita growth #
Averages and patterns of annual GDP per capita growth can be quite different between the USD and PPP metric, reflecting the influence of exchange rate trends. However, these two many metrics also have many cycles in common.
xcatx = ["GDPPC_SA_P1Q1QL4","GDPPPPFXPC_SA_P1Q1QL4"]
cidx = cids_exp
msp.view_ranges(
dfd,
xcats=xcatx,
cids=cidx,
start="1995-01-01",
sort_cids_by="mean",
kind="bar",
size=(16, 8),
title="Means and standard deviations of GDP per capita growth since 2000",
xcat_labels=["versus a year ago", "versus a 5 year lookback"],
)
xcatx = ["GDPPC_SA_P1Q1QL4","GDPPPPFXPC_SA_P1Q1QL4"]
cidx = cids_exp
msp.view_timelines(
dfd,
xcats=xcatx,
cids=cidx,
start="1995-01-01",
title="GDP per capita, seasonally-adjusted",
title_adj=1.02,
title_xadj=0.5,
title_fontsize=27,
ncol=4,
xcat_labels=["USD terms", "PPP terms"],
same_y=False,
aspect=1.7,
all_xticks=True,
size=(16, 8),
)
Growth rates of GDP per capita have predominantly been positively correlated across economies with liquid derivatives markets.
msp.correl_matrix(
dfd,
freq="Q",
xcats="GDPPC_SA_P1Q1QL4",
start="1995-01-01",
cids=cids_exp,
size=(20, 14),
title="Cross-correlations of USD GDP per capita growth, %oya, quarterly averages",
)
msp.correl_matrix(
dfd,
xcats="GDPPPPFXPC_SA_P1Q1QL4",
start="1995-01-01",
cids=cids_exp,
size=(20, 14),
title="Cross-correlations of PPP GDP per capita growth, %oya, quarterly averages",
)
Importance #
Research links #
“Second, slower growth of the labor force due to the aging of the population and moderate productivity growth imply a lower potential real GDP growth rate as compared to the 1990s and 2000s. Because the level of real equilibrium interest rates appears to be positively related to potential real GDP growth, this slower trend implies lower real equilibrium interest rates even after all the current headwinds fully dissipate.” Macrosynergy
Empirical clues #
GDP growth per capita (in PPP terms) have negatively predicted subsequent FX forward returns across EM and DM countries since 1995. The relationship has been statistically significant, not just over the full sample period but also over sub-periods. There are two plausible mechanisms behind this regularity. First, many countries have undergone persistent policy episodes of protracted easy (tighter) monetary policy that stimulated (curbed) growth, but led to a softer (stronger) currency. Second, periods of high (low or negative) GDP per capita growth often come with exuberant (depressed) expectations of a country’s economic future and subsequent setbacks (payback). These setbacks may occur for sets of countries, such as emerging markets or commodity exporters.
dfb = dfd[dfd["xcat"].isin(["FXTARGETED_NSA", "FXUNTRADABLE_NSA"])].loc[
:, ["cid", "xcat", "real_date", "value"]
]
dfba = (
dfb.groupby(["cid", "real_date"])
.aggregate(value=pd.NamedAgg(column="value", aggfunc="max"))
.reset_index()
)
dfba["xcat"] = "FXBLACK"
fxblack = msp.make_blacklist(dfba, "FXBLACK")
xcatx = ["GDPPPPFXPC_SA_P1Q1QL4", "FXXR_NSA"]
cidx = list(set(cids_exp) - set(["USD"]))
cr = msp.CategoryRelations(
dfd,
xcats=xcatx,
cids=cids,
freq="Q",
lag=1,
xcat_aggs=["last", "sum"],
start="1995-01-01",
blacklist=fxblack,
)
cr.reg_scatter(
title="GDP per capita growth and subsequent FX returns, 31 currencies, since 1995",
labels=False,
separator=2010,
coef_box="lower right",
ylab="1-month FX forward return, next quarter",
xlab="GDP per capita growth PPP adjusted, % over a year ago, quarter-end information state",
)
GDPPPPFXPC_SA_P1Q1QL4 misses: ['TWD', 'USD'].
FXXR_NSA misses: ['USD'].