Private consumption #
This category group contains trends and conditions related to private consumption. At present this includes real-time standardized and seasonally adjusted measures of private consumption, consumer confidence and retail sales growth. Survey vintages are standardized by using historical means and standard deviations on the survey level. The purpose of standardization based on expanding samples is to replicate the market’s information state on what was considered normal in terms of level and deviation and to make metrics more intuitive and comparable across countries.
Private consumption growth #
Ticker : RPCONS_SA_P1Q1QL4 / _P1M1ML12 / _P1M1ML12_3MMA
Label : Real Private consumption, sa: % oya (q) / % oya / % oya, 3mma
Definition : Real Private consumption, seasonally adjusted: percentage over a year ago (quarterly) / percentage over a year ago / percentage over a year ago, 3-month moving average
Notes :
-
The underlying data is sourced from national accounts. Most countries release quarterly data except for USA (USD) which produces a separate monthly-frequency data.
-
China (CNY) does not produce quarterly private consumption data
Private consumption trends #
Ticker : RPCONS_SA_P1Q1QL1AR / _P2Q2QL2AR / _P3M3ML3AR / _P6M6ML6AR
Label : Real Private consumption, sa: % 1q/1q ar / % 2q/2q ar / % 3m/3m ar / % 6m/6m ar
Definition : Real Private consumption, seasonally adjusted: % of latest quarter over previous quarter at annualized rate / % of latest 2 quarters over previous 2 quarters at an annualized rate / % of latest 3 months over previous 3 months at annualized rate / % of latest 6 months over previous 6 months at an annualized rate
Notes :
-
See notes for private consumption growth
Consumer confidence scores #
Ticker : CCSCORE_SA / _3MMA
Label : Consumer confidence, sa: z-score / z-score, 3mma
Definition : Consumer confidence, seasonally adjusted: z-score / z-score, 3-month moving average
Notes :
-
The underlying data is sourced from national statistical offices and business groups. Most countries release monthly-frequency data. The exceptions are the following currency areas which produce quarterly data: Switzerland(CHF), New Zealand (NZD), the Phillipines (PHP), Russia (RUB) and South Africa (ZAR).
-
Confidence levels are seasonally adjusted, either at the source or by JPMaQS, on a rolling and out-of-sample basis.
-
Peru (PEN), Romania (RON) and Singapore (SGD) do not release publicly available consumer surveys, hence they are excluded from this set.
-
For in-depth explanation of how the z-scores are computed, please read Appendix 2 .
Consumer confidence scores trends #
Ticker : CCSCORE_SA_D1M1ML1 / _D3M3ML3 / _D1Q1QL1 / _D6M6ML6 / _D2Q2QL2 / _3MMA_D1M1ML12 / _D1Q1QL4
Label : Consumer confidence, sa, z-score: diff m/m / diff 3m/3m / diff q/q / diff 6m/6m / diff 2q/2q / diff oya, 3mma / diff oya (q)
Definition : Consumer confidence, seasonally adjusted, z-score: difference over 1 month / difference of last 3 months over previous 3 months / difference of last quarter over previous quarter / difference of last 6 months over previous 6 months / difference of last 2 quarters over previous 2 quarters / difference over a year ago, 3-month moving average / difference over a year ago, quarterly values
Notes :
-
See notes for consumer confidence scores
Retail sales growth #
Ticker : NRSALES_SA_P1M1ML12 / _P1M1ML12_3MMA / _P1Q1QL4
Label : Nominal retail sales, sa: % oya / % oya, 3mma / % oya (q)
Definition : Nominal retail sales, seasonally adjusted: percentage over a year ago / percentage over a year ago, 3-month moving average / percentage over a year ago (quarterly)
Notes :
-
Chile (CLP), Indonesia (IDR), Isreal (ILS), Mexico (MXN), Malaysia (MYR), Romania (RON), Singpore (SGD) and Taiwan (TWD) only produce real retail sales information and they are not part of this category set.
-
Australia (AUD), New Zealand (NZD) and Philippines (PHP) only produce quarterly data.
Ticker : RRSALES_SA_P1M1ML12 / _P1M1ML12_3MMA / _P1Q1QL4
Label : Real retail sales, sa: % oya / % oya, 3mma / % oya (q)
Definition : Real retail sales, seasonally adjusted: percentage over a year ago / percentage over a year ago, 3-month moving average / percentage over a year ago (quarterly)
Notes :
-
India (IDR) does not produce official retail trade statisitcs for real or nominal data.
-
Australia (AUD), New Zealand (NZD) and Philippines (PHP) only produce quarterly data.
-
China (CNY), Thailand (THB) and USA (USD) do not produce real retail sales, to calculate this we take the ratio of nominal retail sales and a form of CPI. For Thailand we use headline CPI, for the USA we use goods CPI and for China we use both as the series for Goods CPI only started being produced in 2011.
-
Peru (PEN) we also estimate the real retail sales but as the offical nominal series only produces yearly changes, to estimate this we take the yearly change in nominal retail sales and subtract it from the change in headline CPI.
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
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 obtain the data. Here tickers is an array of ticker strings, start_date is the first release date to be considered and metrics denotes the types of information requested.
# Cross-sections of interest
cids_dmca = [
"AUD",
"CAD",
"CHF",
"EUR",
"GBP",
"JPY",
"NOK",
"NZD",
"SEK",
"USD",
] # DM currency areas
cids_dmec = ["DEM", "ESP", "FRF", "ITL", "NLG"] # DM euro area countries
cids_latm = ["BRL", "COP", "CLP", "MXN", "PEN"] # Latam countries
cids_emea = ["CZK", "HUF", "ILS", "PLN", "RON", "RUB", "TRY", "ZAR"] # EMEA countries
cids_emas = [
"CNY",
"HKD",
"IDR",
"INR",
"KRW",
"MYR",
"PHP",
"SGD",
# "THB",
"TWD",
] # EM Asia countries
cids_dm = cids_dmca + cids_dmec
cids_em = cids_latm + cids_emea + cids_emas
cids = sorted(cids_dm + cids_em)
# FX cross-sections lists (for research purposes)
cids_nofx = ["EUR", "USD", "SGD"] + cids_dmec
cids_fx = list(set(cids) - set(cids_nofx))
cids_dmfx = set(cids_dm).intersection(cids_fx)
cids_emfx = set(cids_em).intersection(cids_fx)
cids_eur = ["CHF", "CZK", "HUF", "NOK", "PLN", "RON", "SEK"] # trading against EUR
cids_eud = ["GBP", "RUB", "TRY"] # trading against EUR and USD
cids_usd = list(set(cids_fx) - set(cids_eur + cids_eud))
# Quantamental categories of interest
confs = [
"CCSCORE_SA",
"CCSCORE_SA_3MMA",
"CCSCORE_SA_D1M1ML1",
"CCSCORE_SA_D3M3ML3",
"CCSCORE_SA_D1Q1QL1",
"CCSCORE_SA_D6M6ML6",
"CCSCORE_SA_D2Q2QL2",
"CCSCORE_SA_3MMA_D1M1ML12",
"CCSCORE_SA_D1Q1QL4",
]
sales = [
"NRSALES_SA_P1M1ML12",
"NRSALES_SA_P1M1ML12_3MMA",
"NRSALES_SA_P1Q1QL4",
"RRSALES_SA_P1M1ML12",
"RRSALES_SA_P1M1ML12_3MMA",
"RRSALES_SA_P1Q1QL4",
]
rpcons = [
"RPCONS_SA_P1M1ML12",
"RPCONS_SA_P1M1ML12_3MMA",
"RPCONS_SA_P1Q1QL4",
"RPCONS_SA_P1Q1QL1AR",
"RPCONS_SA_P2Q2QL2AR",
"RPCONS_SA_P3M3ML3AR",
"RPCONS_SA_P6M6M6AR",
]
main = confs + sales + rpcons
econ = ["IVAWGT_SA_1YMA", "IVAWGT_SA_3YMA"] # economic context
mark = [
"DU02YXR_NSA",
"DU05YXR_NSA",
"DU02YXR_VT10",
"DU05YXR_VT10",
"EQXR_VT10",
"FXXR_NSA",
"FXXR_VT10",
"FXTARGETED_NSA",
"FXUNTRADABLE_NSA",
] # market links
xcats = main + 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,
metrics=["value", "eop_lag", "mop_lag", "grading"],
suppress_warning=True,
show_progress=True,
)
end = timer()
dfd = df
print("Download time from DQ: " + str(timedelta(seconds=end - start)))
Maximum number of tickers is 1147
Downloading data from JPMaQS.
Timestamp UTC: 2023-10-18 15:57:15
Connection successful!
Number of expressions requested: 4588
Requesting data: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 230/230 [01:19<00:00, 2.88it/s]
Downloading data: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 230/230 [00:14<00:00, 15.85it/s]
Download time from DQ: 0:03:00.655745
Availability #
basics = [
"CCSCORE_SA",
"NRSALES_SA_P1M1ML12",
"RRSALES_SA_P1M1ML12",
"RPCONS_SA_P1Q1QL4"
]
msm.missing_in_df(dfd, xcats=basics, cids=cids)
Missing xcats across df: []
Missing cids for CCSCORE_SA: ['SGD', 'PEN', 'HKD', 'RON']
Missing cids for NRSALES_SA_P1M1ML12: ['HKD', 'RON', 'INR', 'SGD', 'TWD', 'AUD', 'CLP', 'NZD', 'ILS', 'MYR', 'PHP', 'MXN', 'IDR']
Missing cids for RPCONS_SA_P1Q1QL4: ['HKD', 'CNY', 'USD']
Missing cids for RRSALES_SA_P1M1ML12: ['HKD', 'INR', 'AUD', 'PHP', 'NZD']
In most countries quantamental indicators of real private consumption are available from the mid-1990s or early 2000s. Late starters with data beginning after 2008 include Colombia, Indonesia, Malaysia and Peru.
xcatx = rpcons
cidx = cids
dfx = msm.reduce_df(dfd, xcats=xcatx, cids=cidx)
dfs = msm.check_startyears(dfx)
msm.visual_paneldates(dfs, size=(18, 3))
print("Last updated:", date.today())
Last updated: 2023-10-18
Consumer condidence indicators in most countries are available back to the early-1990s. Canada, Israel and India are late starters.
For the explanation of currency symbols, which are related to currency areas or countries for which categories are available, please view Appendix 1 .
xcatx = confs
cidx = cids
dfx = msm.reduce_df(dfd, xcats=xcatx, cids=cidx)
dfs = msm.check_startyears(dfx)
msm.visual_paneldates(dfs, size=(18, 4))
print("Last updated:", date.today())
Last updated: 2023-10-18
In most countries quantamental indicators of retail sales growth are available from the mid-1990s or early 2000s. Late starters with data beginning after 2010 include Malaysia, Peru, Poland, and Turkey.
xcatx = sales
cidx = cids
dfx = msm.reduce_df(dfd, xcats=xcatx, cids=cidx)
dfs = msm.check_startyears(dfx)
msm.visual_paneldates(dfs, size=(18, 6))
print("Last updated:", date.today())
Last updated: 2023-10-18
xcatx = main
cidx = cids
plot = msm.check_availability(
dfd, xcats=xcatx, cids=cidx, start_size=(18, 4), start_years=False, start=start_date
)
Average grades are currently quite mixed across countries and times. This reflects the availability of survey’s vintages and the use of multiple surveys used in some countries (USD for example).
xcatx = main
cidx = cids
plot = msp.heatmap_grades(
dfd,
xcats=xcatx,
cids=cidx,
start=start_date,
size=(18, 10),
title=f"Average vintage grades, from {start_date} onwards",
)
For graphical representation, it is helpful to rename some quarterly dynamics into an equivalent monthly dynamics.
dfx = dfd.copy()
dict_repl = {
"CCSCORE_SA_D1Q1QL1": "CCSCORE_SA_D3M3ML3",
"CCSCORE_SA_D2Q2QL2": "CCSCORE_SA_D6M6ML6",
"CCSCORE_SA_D1Q1QL4": "CCSCORE_SA_3MMA_D1M1ML12",
"NRSALES_SA_P1Q1QL4": "RRSALES_SA_3MMA_P1M1ML12",
"RRSALES_SA_P1Q1QL4": "RRSALES_SA_3MMA_P1M1ML12",
"RPCONS_SA_P1M1ML12_3MMA":"RPCONS_SA_P1Q1QL4",
"RPCONS_SA_P3M3ML3AR":"RPCONS_SA_P1Q1QL1AR",
"RPCONS_SA_P6M6ML6AR":"RPCONS_SA_P2Q2QL2AR",
}
for key, value in dict_repl.items():
dfd["xcat"] = dfd["xcat"].str.replace(key, value)
History #
Private consumption growth #
In developed countries real private consumption growth has historically been more stable than GDP growth. By contrast, in developed countries household spending post large fluctuations in crises and recoveries. Also the COVID pandemic has triggered outsized fluctuations of private consumption in almost all countries.
cidx = list(set(cids)- set(["CNY"])) # exclude countries with monthly release
xcatx = [
"RPCONS_SA_P1Q1QL4",
"RPCONS_SA_P1M1ML12_3MMA"
]
msp.view_timelines(
dfd,
xcats=xcatx,
cids=cidx,
start=start_date,
title="Real private consumption growth (information states)",
ncol=5,
same_y=False,
title_adj=1.02,
title_xadj=0.415,
legend_fontsize=17,
title_fontsize=27,
size=(12, 7),
aspect=1.7,
all_xticks=True,
legend_ncol=2,
label_adj=0.05,
)
msp.correl_matrix(
dfd,
xcats="RPCONS_SA_P1Q1QL4",
cids=cidx,
size=(20, 14),
start=start_date,
title="Cross-sectional correlation of z-scored consumer confidence, since 1990",
)
In most countries, quarterly consumption growth rates look rather erratic.
cidx = list(set(cids) - set(["USD","CNY"])) # exclude countries with quarterly surveys
xcatx = [
"RPCONS_SA_P1Q1QL1AR",
"RPCONS_SA_P2Q2QL2AR",
]
msp.view_timelines(
dfd,
xcats=xcatx,
cids=cidx,
start=start_date,
title="Real private consumption growth (information states)",
xcat_labels=[
"Private consumption quarter trends",
"Private consumption 2 quarter trends",
],
ncol=4,
same_y=False,
title_adj=1.02,
title_xadj=0.415,
legend_fontsize=17,
title_fontsize=27,
size=(12, 7),
aspect=1.7,
all_xticks=True,
legend_ncol=2,
label_adj=0.05,
)
Consumer confidence scores #
Consumer confidence level typically swing from positive to negative in multi-year cycles. Looking at 3-month moving average significantly adds to the stability of the indicators.
cidx = list(
set(cids) - set(["CHF", "NZD", "PHP", "RUB", "ZAR","HKD","RON","SGD","PEN"])
) # exclude countries with quarterly surveys
xcatx = ["CCSCORE_SA", "CCSCORE_SA_3MMA"]
msp.view_timelines(
dfx,
xcats=xcatx,
cids=cidx,
start=start_date,
title="Consumer confidence scores and 3-month averages (information states)",
xcat_labels=[
"monthly",
"3-month moving average",
],
ncol=4,
same_y=True,
title_adj=1.02,
title_xadj=0.415,
legend_fontsize=17,
title_fontsize=27,
size=(12, 7),
aspect=1.7,
all_xticks=True,
legend_ncol=2,
label_adj=0.05,
)
Correlation across (information states of) consumer confidence has not been uniformly positive around the world, with many emerging countries posting idiosyncratic dynamics, even vis-a-vis the dominant economies of the U.S. and the Euro area.
msp.correl_matrix(
dfd,
xcats="CCSCORE_SA",
cids=cidx,
size=(20, 14),
start=start_date,
title="Cross-sectional correlation of z-scored consumer confidence, since 1990",
)
Consumer confidence score dynamics #
Annual changes and changes of 6-month periods over the previous 6 months still seem to be consistent with business cycle fluctuations. Changes of the last three months over the previous three months can be quite volatile.
xcatx = ["CCSCORE_SA_3MMA_D1M1ML12", "CCSCORE_SA_D6M6ML6", "CCSCORE_SA_D3M3ML3"]
cidx = cids
msp.view_timelines(
dfx,
xcats=xcatx,
cids=cidx,
start=start_date,
title="Consumer confidence z-score trend 6-month or 3-month",
title_adj=1.02,
title_xadj=0.5,
legend_fontsize=17,
title_fontsize=27,
ncol=4,
same_y=True,
size=(12, 7),
aspect=1.7,
all_xticks=True,
)
Interestingly, changes in consumer confidence are more correlated across countries than the levels themselves.
msp.correl_matrix(dfd, xcats="CCSCORE_SA_D6M6ML6", cids=cidx, size=(20, 14))
Retail sales growth #
Averaging of monthly growth rates of nominal or real retail sales gorwth is very useful for detecting information states of more stable trends. In countries with escalating inflation, such as Turkey in the early 2020s, CPI growth dominates volume dynamics.
cidx = list(set(cids) - set(["NZD", "AUD"])) # exclude countries with quarterly surveys
xcatx = [
"NRSALES_SA_P1M1ML12",
"NRSALES_SA_P1M1ML12_3MMA",
]
msp.view_timelines(
dfd,
xcats=xcatx,
cids=cidx,
start=start_date,
title="Nominal retail sales and 3-month averages (information states)",
xcat_labels=[
"Nominal monthly",
"Nominal 3-month moving average",
],
ncol=4,
same_y=False,
title_adj=1.02,
title_xadj=0.415,
legend_fontsize=17,
title_fontsize=27,
size=(12, 7),
aspect=1.7,
all_xticks=True,
legend_ncol=2,
label_adj=0.05,
)
cidx = list(set(cids) - set(["NZD", "AUD"])) # exclude countries with quarterly surveys
xcatx = ["RRSALES_SA_P1M1ML12", "RRSALES_SA_P1M1ML12_3MMA"]
msp.view_timelines(
dfx,
xcats=xcatx,
cids=cidx,
start=start_date,
title="Real retail sales and 3-month averages (information states)",
xcat_labels=[
"Real monthly",
"Real 3-month moving average",
],
ncol=4,
same_y=False,
title_adj=1.02,
title_xadj=0.415,
legend_fontsize=17,
title_fontsize=27,
size=(12, 7),
aspect=1.7,
all_xticks=True,
legend_ncol=2,
label_adj=0.05,
)
Retail sales growth is mostly positively correlated across most countries.
msp.correl_matrix(
dfx,
xcats="RRSALES_SA_P1M1ML12_3MMA",
cids=cidx,
size=(20, 14),
start=start_date,
title="Cross-sectional correlation of real retail sales growth (%oya, 3mma), since 1990",
)
Importance #
Research links #
“The interaction between the macroeconomy and asset markets is central to a variety of modern theories of the business cycle. Much recent work emphasizes the joint nature of the consumption decision and the portfolio allocation decision.” Mankiw and Shapiro
“Empirical studies have documented the time-varying correlation between returns on the market portfolio of stocks and those on long-term (5-10 years) nominal Treasury bonds. This correlation was positive before 2000 but turned negative afterwards (see chart below). At the same time, the correlation between consumption growth and inflation also changed sign around 2000 from negative to positive.” Li, Tao, Ji and Hao, 2021
Empirical clues #
In the developed world changes in consumer confidence over a shorter horizon have positively predicted local equity index returns.
cidx = cids_dmca
cr = msp.CategoryRelations(
dfx,
xcats=["CCSCORE_SA_D3M3ML3", "EQXR_VT10"],
cids=cidx,
freq="M",
lag=1,
xcat_aggs=["last", "sum"],
fwin=1,
start="2000-01-01",
years=None,
)
cr.reg_scatter(
coef_box="lower right",
title="Short-term changes in consumer confidence and subsequent equity returns",
xlab="Consumer confidence, sa, z-score, diff 3m/3m ",
ylab="Local equity index future return, next month, %",
prob_est="map",
)
CCSCORE_SA_D3M3ML3 misses: ['CHF', 'NZD'].
EQXR_VT10 misses: ['NOK', 'NZD'].
Also, consumer confidence score differences of individual countries relative to the U.S. or the euro area are significant predictors of subsequent FX forward returns.
dfb = df[df["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")
fxblack
{'BRL': (Timestamp('2012-12-03 00:00:00'), Timestamp('2013-09-30 00:00:00')),
'CHF': (Timestamp('2011-10-03 00:00:00'), Timestamp('2015-01-30 00:00:00')),
'CNY': (Timestamp('1999-01-01 00:00:00'), Timestamp('2023-10-17 00:00:00')),
'CZK': (Timestamp('2014-01-01 00:00:00'), Timestamp('2017-07-31 00:00:00')),
'HKD': (Timestamp('1999-01-01 00:00:00'), Timestamp('2023-10-17 00:00:00')),
'ILS': (Timestamp('1999-01-01 00:00:00'), Timestamp('2005-12-30 00:00:00')),
'INR': (Timestamp('1999-01-01 00:00:00'), Timestamp('2004-12-31 00:00:00')),
'MYR_1': (Timestamp('1999-01-01 00:00:00'), Timestamp('2007-11-30 00:00:00')),
'MYR_2': (Timestamp('2018-07-02 00:00:00'), Timestamp('2023-10-17 00:00:00')),
'PEN': (Timestamp('2021-07-01 00:00:00'), Timestamp('2021-07-30 00:00:00')),
'RON': (Timestamp('1999-01-01 00:00:00'), Timestamp('2005-11-30 00:00:00')),
'RUB_1': (Timestamp('1999-01-01 00:00:00'), Timestamp('2005-11-30 00:00:00')),
'RUB_2': (Timestamp('2022-02-01 00:00:00'), Timestamp('2023-10-17 00:00:00')),
'SGD': (Timestamp('1999-01-01 00:00:00'), Timestamp('2023-10-17 00:00:00')),
'TRY_1': (Timestamp('1999-01-01 00:00:00'), Timestamp('2003-09-30 00:00:00')),
'TRY_2': (Timestamp('2020-01-01 00:00:00'), Timestamp('2023-10-17 00:00:00'))}
xcatx = ["CCSCORE_SA_D3M3ML3", "CCSCORE_SA_D6M6ML6", "CCSCORE_SA", "CCSCORE_SA_D1M1ML1"]
dfa = pd.DataFrame(columns=list(dfx.columns))
for xc in xcatx:
calc_eur = [f"{xc}vBM = {xc} - iEUR_{xc}"]
calc_usd = [f"{xc}vBM = {xc} - iUSD_{xc}"]
calc_eud = [f"{xc}vBM = {xc} - 0.5 * ( iEUR_{xc} + iUSD_{xc} )"]
dfa_eur = msp.panel_calculator(dfx, calcs=calc_eur, cids=cids_eur)
dfa_usd = msp.panel_calculator(dfx, calcs=calc_usd, cids=cids_usd)
dfa_eud = msp.panel_calculator(dfx, calcs=calc_eud, cids=cids_eud)
dfa = msm.update_df(dfa, pd.concat([dfa_eur, dfa_usd, dfa_eud]))
dfy = msm.update_df(dfx, dfa)
cidx = cids_dmca
crx = msp.CategoryRelations(
dfy,
xcats=["CCSCORE_SAvBM", "FXXR_NSA"],
cids=cidx,
freq="M",
lag=1,
xcat_aggs=["last", "sum"],
start="2000-01-01",
blacklist=fxblack,
)
crx.reg_scatter(
labels=False,
coef_box="lower left",
title="Consumer confidence differentials and subsequent FX forward return across DM countries",
xlab="Consumer confidence score relative to base currency (USD or EUR)",
ylab="Next month FX forward return, %",
size=(10, 6),
prob_est="map",
)
CCSCORE_SAvBM misses: ['EUR', 'USD'].
FXXR_NSA misses: ['USD'].
There has been a clear and significant negative relation between quarterly private consumption growth and subsequent duration returns in the past.
cidx = cids
crx = msp.CategoryRelations(
dfd,
xcats=["RPCONS_SA_P1Q1QL1AR", "DU05YXR_VT10"],
cids=cidx,
freq="Q",
lag=1,
xcat_aggs=["last", "sum"],
xcat_trims=[100, 100],
start="2000-01-01",
)
crx.reg_scatter(
labels=False,
coef_box="upper right",
title="Real private consumption growth and subsequent IRS receiver returns (all markets ex U.S.)",
xlab="Real private consumption, %q/q, saar",
ylab="Next quarter 5-year IRS receiver return, vol-targeted, %",
size=(10, 6),
prob_est="map",
)
RPCONS_SA_P1Q1QL1AR misses: ['CNY', 'HKD'].
DU05YXR_VT10 misses: ['BRL', 'DEM', 'ESP', 'FRF', 'ITL', 'NLG', 'PEN', 'PHP', 'RON'].
Appendices #
Appendix 1: Currency symbols #
The word ‘cross-section’ refers to currencies, currency areas or economic areas. In alphabetical order, these are AUD (Australian dollar), BRL (Brazilian real), CAD (Canadian dollar), CHF (Swiss franc), CLP (Chilean peso), CNY (Chinese yuan renminbi), COP (Colombian peso), CZK (Czech Republic koruna), DEM (German mark), ESP (Spanish peseta), EUR (Euro), FRF (French franc), GBP (British pound), HKD (Hong Kong dollar), HUF (Hungarian forint), IDR (Indonesian rupiah), ITL (Italian lira), JPY (Japanese yen), KRW (Korean won), MXN (Mexican peso), MYR (Malaysian ringgit), NLG (Dutch guilder), NOK (Norwegian krone), NZD (New Zealand dollar), PEN (Peruvian sol), PHP (Phillipine peso), PLN (Polish zloty), RON (Romanian leu), RUB (Russian ruble), SEK (Swedish krona), SGD (Singaporean dollar), THB (Thai baht), TRY (Turkish lira), TWD (Taiwanese dollar), USD (U.S. dollar), ZAR (South African rand).
Appendix 2: Methodology of scoring #
Survey confidence values are transformed into z-scores based on past expanding data samples in order to replicate the market’s information state on survey readings relative to what is considered as “normal”.
The underlying economic data used to develop the above indicators comes in the form of diffusion index or derivatives thereof. They are either seasonally adjusted at the source or by JPMaQS. This statistic is typically used to summarise surveys results with focus on the direction of conditions (extensive margin) rather than the quantity (intensive margin).
In order to standardise different survey indicators, we apply a custom z-scoring methodology to each survey’s vintage based on the principle of a sliding scale for the weights of empirical versus theoretical neutral level:
-
We first determine a theoretical nominal neutral level, defined by the original formula used by the publishing institution. This is typically one of 0, 50, or 100.
-
We compute the measure of central tendency: for the first 5 years this is a weighted average of neutral level and realised median. As time progresses, the weight of the historical median increases and the weight of the notional neutral level decreases until it reaches zero at the end of the 5-year period.,
-
We compute the mean absolute deviation to normalize deviations of confidence levels from their presumed neutral level. We require at least 12 observations to estimate it.
We finally calculate the z-score for the vintage values as
where \(X_{i, t}\) is the value of the indicator for country \(i\) at time \(t\) , \(\bar{X_i|t}\) is the measure of central tendency for country \(i\) at time \(t\) based on information up to that date, and \(\sigma_i|t\) is the mean absolute deviation for country \(i\) at time \(t\) based on information up to that date. Whenever a country / currency area has more than one representative survey, we average the z-scores by observation period (month or quarter).
We want to maximise the use of information set at each point in time, so we devised a back-casting algorithm to estimate a z-scored diffusion index in case another survey has already released some data for the latest observation period. Put simply, as soon as one survey for a month has been published we estimated the value for the other(s) in order to derive a new monthly observation.
Appendix 3: Survey details #
surveys = pd.DataFrame(
[
{
"country": "Australia",
"source": "Melbourne Institute of Applied Economic & Social Research",
"details": "Australian Consumer Sentiment Index Total SA Index",
},
{
"country": "Brazil",
"source": "FecomercioSP",
"details": "Consumer Confidence Index Total SA Index",
},
{
"country": "Canada",
"source": "Refinitiv/Ipsos",
"details": "Consumer Confidence Canada",
},
{
"country": "Switzerland",
"source": "Swiss State Secretariat for Economic Affairs",
"details": "Consumer Confidence, Total, SA",
},
{
"country": "Chile",
"source": "Central Bank of Chile",
"details": "Business Confidence Index Manufacturing Industries Assessment Manufacturing Index",
},
{
"country": "Chile",
"source": "Development University of Chile",
"details": "Economic Perception Index Total",
},
{
"country": "China",
"source": "China Economic Monitoring & Analysis Centre (CEMAC)",
"details": "Consumer Confidence Index Total",
},
{
"country": "Colombia",
"source": "Foundation for Higher Education & Development (Fedesarrollo)",
"details": "Consumer Confidence Index",
},
{
"country": "Czech Republic",
"source": "Czech Statistical Office",
"details": "Consumer Confidence, Total, SA",
},
{
"country": "Germany",
"source": "European Commission (DG ECFIN)",
"details": "Consumer Confidence Balance SA",
},
{
"country": "Spain",
"source": "Spanish Minsitry of Economy & Buisness",
"details": "Consumer Confidence Indicator SA",
},
{
"country": "Euro Area",
"source": "European Commission (DG ECFIN)",
"details": "Consumer Confidence Balance SA",
},
{
"country": "France",
"source": "INSEE",
"details": "Consumer Confidence Index SA Index",
},
{
"country": "United Kingdom",
"source": "GFK Group",
"details": "GFK Consumer Confidence Index",
},
{
"country": "Hungary",
"source": "GKI Economic Research",
"details": "Consumer Confidence Indicator SA Index",
},
{
"country": "Indonesia",
"source": "Bank Indonesia",
"details": "Consumer Confidence Index",
},
{
"country": "Israel",
"source": "Isreal Central Bureau of Statistics",
"details": "Consumer Confidence Indicator, Total, Weighted",
},
{
"country": "India",
"source": "Reserve Bank of India",
"details": "Consumer Confidence Index",
},
{
"country": "Italy",
"source": "ISTAT",
"details": "Consumer Confidence Indicator SA Index",
},
{
"country": "Japan",
"source": "Japanese Cabinet Office",
"details": "Consumer Confidence Index, Total, All",
},
{
"country": "South Korea",
"source": " Bank of Korea",
"details": " Consumer Opinion Surveys, SA",
},
{
"country": "Mexico",
"source": "INEGI National Institute of Geography & Statistics",
"details": "Consumer Confidence Total SA",
},
{
"country": "Malaysia",
"source": "Malaysian Institute of Economic Research",
"details": "Consumer Sentiment Index",
},
{
"country": "Netherlands",
"source": "Statistics Netherlands",
"details": "Consumer Confidence Index Balance SA",
},
{
"country": "Norway",
"source": "KANTAR TNS",
"details": "Consumer Confidence Indicator",
},
{
"country": "New Zealand",
"source": "Westpac - McDermott Miller",
"details": "Consumer Confidence Index",
},
{
"country": "Philippines",
"source": "Central Bank of the Philippines",
"details": "Consumer Confidence Index",
},
{
"country": "Poland",
"source": "European Commission (DG ECFIN)",
"details": "Consumer Confidence Balance SA",
},
{
"country": "Russia",
"source": "Rosstat",
"details": "Consumer Confidence Indicator",
},
{
"country": "Sweden",
"source": "Swedish National Institute of Economic Research",
"details": "The Consumer Confidence Indicator (CCI)",
},
{
"country": "Thailand",
"source": "University of the Thai Chamber of Commerce",
"details": "Consumer Confidence Index",
},
{
"country": "Turkey",
"source": "TurkStat",
"details": "Consumer Confidence Index",
},
{
"country": "Taiwan",
"source": "National Central University of Taiwan",
"details": "Consumer Confidence Index, Expecatation Total Index",
},
{
"country": "United States",
"source": "University of Michigan",
"details": "Consumer Sentiment Index",
},
{
"country": "United States",
"source": "Conference Board",
"details": "Consumer Confidence Index",
},
{
"country": "South Africa",
"source": "BER",
"details": "Consumer Confidence Index",
},
]
)
from IPython.display import HTML
HTML(surveys.to_html(index=False))
country | source | details |
---|---|---|
Australia | Melbourne Institute of Applied Economic & Social Research | Australian Consumer Sentiment Index Total SA Index |
Brazil | FecomercioSP | Consumer Confidence Index Total SA Index |
Canada | Refinitiv/Ipsos | Consumer Confidence Canada |
Switzerland | Swiss State Secretariat for Economic Affairs | Consumer Confidence, Total, SA |
Chile | Central Bank of Chile | Business Confidence Index Manufacturing Industries Assessment Manufacturing Index |
Chile | Development University of Chile | Economic Perception Index Total |
China | China Economic Monitoring & Analysis Centre (CEMAC) | Consumer Confidence Index Total |
Colombia | Foundation for Higher Education & Development (Fedesarrollo) | Consumer Confidence Index |
Czech Republic | Czech Statistical Office | Consumer Confidence, Total, SA |
Germany | European Commission (DG ECFIN) | Consumer Confidence Balance SA |
Spain | Spanish Minsitry of Economy & Buisness | Consumer Confidence Indicator SA |
Euro Area | European Commission (DG ECFIN) | Consumer Confidence Balance SA |
France | INSEE | Consumer Confidence Index SA Index |
United Kingdom | GFK Group | GFK Consumer Confidence Index |
Hungary | GKI Economic Research | Consumer Confidence Indicator SA Index |
Indonesia | Bank Indonesia | Consumer Confidence Index |
Israel | Isreal Central Bureau of Statistics | Consumer Confidence Indicator, Total, Weighted |
India | Reserve Bank of India | Consumer Confidence Index |
Italy | ISTAT | Consumer Confidence Indicator SA Index |
Japan | Japanese Cabinet Office | Consumer Confidence Index, Total, All |
South Korea | Bank of Korea | Consumer Opinion Surveys, SA |
Mexico | INEGI National Institute of Geography & Statistics | Consumer Confidence Total SA |
Malaysia | Malaysian Institute of Economic Research | Consumer Sentiment Index |
Netherlands | Statistics Netherlands | Consumer Confidence Index Balance SA |
Norway | KANTAR TNS | Consumer Confidence Indicator |
New Zealand | Westpac - McDermott Miller | Consumer Confidence Index |
Philippines | Central Bank of the Philippines | Consumer Confidence Index |
Poland | European Commission (DG ECFIN) | Consumer Confidence Balance SA |
Russia | Rosstat | Consumer Confidence Indicator |
Sweden | Swedish National Institute of Economic Research | The Consumer Confidence Indicator (CCI) |
Thailand | University of the Thai Chamber of Commerce | Consumer Confidence Index |
Turkey | TurkStat | Consumer Confidence Index |
Taiwan | National Central University of Taiwan | Consumer Confidence Index, Expecatation Total Index |
United States | University of Michigan | Consumer Sentiment Index |
United States | Conference Board | Consumer Confidence Index |
South Africa | BER | Consumer Confidence Index |