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

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 .

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 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>_ , ), where 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 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())
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/f46fd0820aed67b379ec04eef9cfe9d00db031ae34a36443513edf0174f8d3ac.png
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())
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/15bdce0555d13832d53c4f2d66770913e1e16a10f180b3169913fe9b3c53fc71.png
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())
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/e03a1084360830724f061c956a87fee7a92b6f839f6f664a5267cb5632218c51.png
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
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/c8def0ea5b3512601164f3bf3d5d4bbe7224776367236d52a0eb84787ab0847e.png

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",
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/0a4e9fff38a7b6addaae76056c6580497530405312d1a169112260eb1af9d8c1.png

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,
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/a939885b6df04154ad87279f1cb23f7d7dd27905ff6a6d71616389b19e6bea12.png
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",
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/d601f76f9127c48e2aaee3287fe1a1f359cf945f50de2ea0838a09eb1d12d54c.png

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,
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/1225b63757597fb2685ab94dcb5ba5f017a4bc883aa60f32b9bbf1762b9d779a.png

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,
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/cf342357e5757c3a67fa8a894aafcd40c0b27e0ac68822ee6594dbced172ae88.png

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",
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/9e8cc57b00429c7412a2bd833449e945212cb0dcbf6a576c80a5b9b39e89116e.png

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,
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/857e999b8216976901a818aa611c72124cb505e795764da8ccfeaa4e97822492.png

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))
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/3b66e95267e6c8957ce893305aa9e49a07ed8116c86417f26b5465975773ade8.png

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,
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/7c2d877b197b4c41b215640e6cfc3ac51e74a5d48e3c8a82372dea4219f7ea5a.png
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,
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/b550e5271f833c9888df11f9bffa985ffb26b341c885ccef3feaf11e510c6aa8.png

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",
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/35499d94f1e4cb77bf479ed95cd847ed9e041a14cd78452f0afb671b1b9fa725.png

Importance #

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'].
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/ee9549d7cc55d069892dd840dd1b2939985a666c19d9f3bbb295c7dec75b7376.png

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'].
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/4744ffd0818c28a94689e1d0400fa4af53a9dc4cbf51aef7b7b1fa880f7abf24.png

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'].
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/3a0e023aaa25006dbf7f78d9e6e0e02d2f285b03a3e35c4d689992137b131735.png

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

\[ Z_{i, t} = \frac{X_{i, t} - \bar{X_i|t}}{\sigma_i|t} \]

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