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())
https://macrosynergy.com/notebooks.build/themes/macroeconomic-balance-sheets/_images/98abe1ef9947b7bd11b8d32c85a6958a64e6b5cb7b99445f1c50d9e2010258d7.png
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
)
https://macrosynergy.com/notebooks.build/themes/macroeconomic-balance-sheets/_images/2f93c72a21099cecd93378a5df0e6e09cbace908dd6262c80c6f7bb6e6159d48.png

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",
)
https://macrosynergy.com/notebooks.build/themes/macroeconomic-balance-sheets/_images/a666a1c30baaa4bd017eee4494540d0633b5f4a9d3b45e2ea3b9ef25ddf5f467.png
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),
)
https://macrosynergy.com/notebooks.build/themes/macroeconomic-balance-sheets/_images/f234f47e1f831c38338edafa102eee687070e0062d8f3081ccecaeaa9dfa4b86.png https://macrosynergy.com/notebooks.build/themes/macroeconomic-balance-sheets/_images/87c4a381a4fbd247908f5ee9e457fe087dbda1bc875a31cdbeda0ff96e18b042.png

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"],
)
https://macrosynergy.com/notebooks.build/themes/macroeconomic-balance-sheets/_images/f88d814b3a38fedf3017b33a374868b4ab7564d184b5c9027bb0730f721ee76c.png

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"],
)
https://macrosynergy.com/notebooks.build/themes/macroeconomic-balance-sheets/_images/f231e307456458cf16d742db3abf4583e33365a4c1f4dea9557cc9ab3d670e10.png

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),
)
https://macrosynergy.com/notebooks.build/themes/macroeconomic-balance-sheets/_images/1a2fd9ea3916373c24959f83fa3418cfe80b7078311207fd8c41decfd478af54.png

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"],
)
https://macrosynergy.com/notebooks.build/themes/macroeconomic-balance-sheets/_images/8e00884f70f871a022e83bcebab401b4ec1b315d863d3747409ad2b51c60421b.png
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),
)
https://macrosynergy.com/notebooks.build/themes/macroeconomic-balance-sheets/_images/661dce027ff2853b175483704d543d27306a7c1d86232709c0cd22e8b0197175.png

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",
)
https://macrosynergy.com/notebooks.build/themes/macroeconomic-balance-sheets/_images/b3f148805c66f5becb2afcb9308b48a0f25b16472304c23e7483b161a8e29563.png
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",
)
https://macrosynergy.com/notebooks.build/themes/macroeconomic-balance-sheets/_images/9a4178ae452da1b0cf0e673362d4772114f905cd400b06a879f4f9aeb7c099ed.png

Importance #

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'].
https://macrosynergy.com/notebooks.build/themes/macroeconomic-balance-sheets/_images/2e986c9457cebf3a9d49da79560166877806b72a1b2b936e1f51989acc2b483e.png