Construction activity indicators #

This category group contains construction activity indicators. At present this includes real-time information states of construction output growth and business confidence. Survey vintages are standardized by using historical means and standard deviations on the survey level. The purpose of standardizing survey indices 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.

Construction activity growth #

Ticker : CSTR_SA_P1M1ML12 / _P1M1ML12_3MMA / _P1Q1QL4

Label : Construction output, sa: %oya / %oya, 3mma / %oya (q)

Definition : Construction output, seasonally adjusted: % over a year ago / % over a year ago, 3-month moving average / % over a year ago (quarterly)

Notes :

  • Across countries, financial markets, and the public focus on different aspects of construction activity as their main indicator. For this JPMaQS category, the general preference is to use a metric of completed units, such as floor space or buildings, but where that is not available units in progress, inflation-adjusted construction value, or units started is used.

  • In term periodicity of releases China (CNY), Chile (CLP), Czech Republic (CZK), Euro area (EUR), France (FRF), Germany (DEM), Great Britain (GBP), Hungary (HUF), Mexico (MXN), Netherlands (NLG), Peru (PEN), Poland (PLN), Romania (RON), Spain (ESP), South Africa (ZAR), South Korea (KRW), Sweden (SEK), Thailand (THB) have a monthly release schedule. Australia (AUD), Canada (CAD), Switzerland (CHF), Indonesia (IDR), Israel (ILS), Malaysia (MYR), Philippines (PHP), Russia (RUB), Singapore (SGD), New Zealand (NZD), Thailand (THB), USA (USD) have a quarterly release schedule.

  • Australia (AUD), Great Britian (GBP), New Zealand (NZD) and South Africa (ZAR) is the real value of construction completed.

  • For the Czech Republic (CZK), Euro area (EUR), France (FRF), Germany (DEM), Hungary (HUF), Netherlands (NLG), Norway (NOK), Poland (PLN), Romania (RON), Spain (ESP) and Switzerland (CHF) activity is based on a production volume index.

  • For China (CNY), Israel (ILS), Philippines (PHP) and Russia (RUB) construction refers to square meters completed.

  • For Indonesia (IDR) and Thailand (THB) activity refers to the construction estimate of the national accounts.

  • Mexico (MXN), Peru (PEN) and South Korea (KRW) activity refers to a construction sub-index of the industrial production report.

  • Chile (CLP) uses a special construction activity index.

  • For the U.S. activity refers to the number of homes completed and does not include commercial real-estate.

  • For Canada, activity refers to the number of homes starting construction

  • In Singapore (SGD) activity measures industrial square meters under construction.

Construction survey scores #

Ticker : CBCSCORE_SA / _3MMA

Label : Construction confidence, sa: z-score / z-score, 3mma

Definition : Construction confidence, seasonally adjusted: z-score / z-score, 3-month moving average

Notes :

  • The underlying data is sourced from national statistical offices and business groups. For a country-by-country referece view Appendix 3 .

  • Most countries release monthly-frequency data. The exceptions are the following currency areas which produce quarterly data Colombia (COP), Malaysia (MYR), Philippines (PHP), Russia (RUB), South Africa (ZAR)

  • Confidence levels are seasonally adjusted, either at the source or by JPMaQS, on rolling and out-of-sample basis.

  • For in-depth explanation of how the z-scores are computed, please read Appendix 2 .

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_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))
cstr_conf = [
    # CONFIDENCE
    "CBCSCORE_SA",
    "CBCSCORE_SA_3MMA",
    "CBCSCORE_SA_D1M1ML1",
    "CBCSCORE_SA_D3M3ML3",
    "CBCSCORE_SA_D1Q1QL1",
    "CBCSCORE_SA_D6M6ML6",
    "CBCSCORE_SA_D2Q2QL2",
    "CBCSCORE_SA_3MMA_D1M1ML12",
    "CBCSCORE_SA_D1Q1QL4",
]
# output
cstr_out = [
    "CSTR_SA_P1M1ML12",
    "CSTR_SA_P3M3ML3AR",
    "CSTR_SA_P6M6ML6AR",
    "CSTR_SA_P1Q1QL4",
    "CSTR_SA_P1Q1QL1AR",
    "CSTR_SA_P2Q2QL2AR",
    "CSTR_SA_P1M1ML12_3MMA",
]
main = cstr_out + cstr_conf
econ = ["USDGDPWGT_SA_1YMA"]  # economic context

mark = [
    "DU02YXR_NSA",
    "DU05YXR_NSA",
    "DU02YXR_VT10",
    "DU05YXR_VT10",
    "CDS02YXR_VT10",
    "CDS05YXR_VT10",
    "FXXR_NSA",
    "FXTARGETED_NSA",
    "FXUNTRADABLE_NSA",
]  # market links


xcats = main + econ + mark
cids_co = [
    "ALM",
    "CPR",
    "TIN",
]
xcats_co = ["COXR_NSA", "COXR_VT10"]

cotix = [cid + "_" + xcat for cid in cids_co for xcat in xcats_co]
# 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] +cotix
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()
    assert downloader.check_connection()
    df = downloader.download(
        tickers=tickers,
        start_date=start_date,
        show_progress=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 994
Downloading data from JPMaQS.
Timestamp UTC:  2024-03-27 11:34:11
Connection successful!
Requesting data:  23%|██▎       | 45/199 [00:09<00:36,  4.17it/s]
Requesting data: 100%|██████████| 199/199 [00:44<00:00,  4.49it/s]
Downloading data: 100%|██████████| 199/199 [00:27<00:00,  7.35it/s]
Some expressions are missing from the downloaded data. Check logger output for complete list.
1696 out of 3976 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. 
2 out of 8935 dates are missing.
Download time from DQ: 0:01:21.444305

Availability #

cids_exp = cids_dm + cids_em  # cids expected in category panels
msm.missing_in_df(df, xcats=main, cids=cids_exp)
Missing xcats across df:  []
Missing cids for CBCSCORE_SA:                ['AUD', 'GBP', 'HKD', 'IDR', 'INR', 'MXN', 'NOK', 'NZD', 'PEN', 'PLN', 'SGD']
Missing cids for CBCSCORE_SA_3MMA:           ['AUD', 'COP', 'GBP', 'HKD', 'IDR', 'INR', 'MXN', 'MYR', 'NOK', 'NZD', 'PEN', 'PHP', 'PLN', 'RUB', 'SGD', 'THB', 'ZAR']
Missing cids for CBCSCORE_SA_3MMA_D1M1ML12:  ['AUD', 'COP', 'GBP', 'HKD', 'IDR', 'INR', 'MXN', 'MYR', 'NOK', 'NZD', 'PEN', 'PHP', 'PLN', 'RUB', 'SGD', 'THB', 'ZAR']
Missing cids for CBCSCORE_SA_D1M1ML1:        ['AUD', 'COP', 'GBP', 'HKD', 'IDR', 'INR', 'MXN', 'MYR', 'NOK', 'NZD', 'PEN', 'PHP', 'PLN', 'RUB', 'SGD', 'THB', 'ZAR']
Missing cids for CBCSCORE_SA_D1Q1QL1:        ['AUD', 'BRL', 'CAD', 'CHF', 'CLP', 'CNY', 'CZK', 'DEM', 'ESP', 'EUR', 'FRF', 'GBP', 'HKD', 'HUF', 'IDR', 'ILS', 'INR', 'ITL', 'JPY', 'KRW', 'MXN', 'NLG', 'NOK', 'NZD', 'PEN', 'PLN', 'RON', 'SEK', 'SGD', 'TRY', 'TWD', 'USD']
Missing cids for CBCSCORE_SA_D1Q1QL4:        ['AUD', 'BRL', 'CAD', 'CHF', 'CLP', 'CNY', 'CZK', 'DEM', 'ESP', 'EUR', 'FRF', 'GBP', 'HKD', 'HUF', 'IDR', 'ILS', 'INR', 'ITL', 'JPY', 'KRW', 'MXN', 'NLG', 'NOK', 'NZD', 'PEN', 'PLN', 'RON', 'SEK', 'SGD', 'TRY', 'TWD', 'USD']
Missing cids for CBCSCORE_SA_D2Q2QL2:        ['AUD', 'BRL', 'CAD', 'CHF', 'CLP', 'CNY', 'CZK', 'DEM', 'ESP', 'EUR', 'FRF', 'GBP', 'HKD', 'HUF', 'IDR', 'ILS', 'INR', 'ITL', 'JPY', 'KRW', 'MXN', 'NLG', 'NOK', 'NZD', 'PEN', 'PLN', 'RON', 'SEK', 'SGD', 'TRY', 'TWD', 'USD']
Missing cids for CBCSCORE_SA_D3M3ML3:        ['AUD', 'COP', 'GBP', 'HKD', 'IDR', 'INR', 'MXN', 'MYR', 'NOK', 'NZD', 'PEN', 'PHP', 'PLN', 'RUB', 'SGD', 'THB', 'ZAR']
Missing cids for CBCSCORE_SA_D6M6ML6:        ['AUD', 'COP', 'GBP', 'HKD', 'IDR', 'INR', 'MXN', 'MYR', 'NOK', 'NZD', 'PEN', 'PHP', 'PLN', 'RUB', 'SGD', 'THB', 'ZAR']
Missing cids for CSTR_SA_P1M1ML12:           ['AUD', 'BRL', 'CAD', 'CHF', 'COP', 'HKD', 'IDR', 'ILS', 'INR', 'ITL', 'JPY', 'MYR', 'NZD', 'PHP', 'RUB', 'SGD', 'THB', 'TRY', 'TWD', 'USD']
Missing cids for CSTR_SA_P1M1ML12_3MMA:      ['AUD', 'BRL', 'CAD', 'CHF', 'COP', 'HKD', 'IDR', 'ILS', 'INR', 'ITL', 'JPY', 'MYR', 'NZD', 'PHP', 'RUB', 'SGD', 'THB', 'TRY', 'TWD', 'USD']
Missing cids for CSTR_SA_P1Q1QL1AR:          ['BRL', 'CLP', 'CNY', 'COP', 'CZK', 'DEM', 'ESP', 'EUR', 'FRF', 'GBP', 'HKD', 'HUF', 'INR', 'ITL', 'JPY', 'KRW', 'MXN', 'NLG', 'NOK', 'PEN', 'PLN', 'RON', 'SEK', 'TRY', 'TWD', 'ZAR']
Missing cids for CSTR_SA_P1Q1QL4:            ['BRL', 'CLP', 'CNY', 'COP', 'CZK', 'DEM', 'ESP', 'EUR', 'FRF', 'GBP', 'HKD', 'HUF', 'INR', 'ITL', 'JPY', 'KRW', 'MXN', 'NLG', 'NOK', 'PEN', 'PLN', 'RON', 'SEK', 'TRY', 'TWD', 'ZAR']
Missing cids for CSTR_SA_P2Q2QL2AR:          ['BRL', 'CLP', 'CNY', 'COP', 'CZK', 'DEM', 'ESP', 'EUR', 'FRF', 'GBP', 'HKD', 'HUF', 'INR', 'ITL', 'JPY', 'KRW', 'MXN', 'NLG', 'NOK', 'PEN', 'PLN', 'RON', 'SEK', 'TRY', 'TWD', 'ZAR']
Missing cids for CSTR_SA_P3M3ML3AR:          ['AUD', 'BRL', 'CAD', 'CHF', 'COP', 'HKD', 'IDR', 'ILS', 'INR', 'ITL', 'JPY', 'MYR', 'NZD', 'PHP', 'RUB', 'SGD', 'THB', 'TRY', 'TWD', 'USD']
Missing cids for CSTR_SA_P6M6ML6AR:          ['AUD', 'BRL', 'CAD', 'CHF', 'COP', 'HKD', 'IDR', 'ILS', 'INR', 'ITL', 'JPY', 'MYR', 'NZD', 'PHP', 'RUB', 'SGD', 'THB', 'TRY', 'TWD', 'USD']

For most countries quantamental information states of construction output are available from the late 1990’s to early 2000’s with the late starters being Great Britain (2011), Indonesia (2011) and Malaysia (2016).

xcatx = main
cidx = cids_exp

dfx = msm.reduce_df(df, xcats=cstr_out, 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/4ebbd79a6aab67a0311ecccab329a4e352bde28903013bddc8e298bff93378dd.png
Last updated: 2024-03-27

Quantamental information states of construction confidence are available for fewer currency areas than construction output (27 versus 30) and have a wide range of start dates from 1990 to 2021.

xcatx = main
cidx = cids_exp

dfx = msm.reduce_df(df, xcats=cstr_conf, 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/df9935ed8a3c4fdfabe1110378b8a9599d10298ae9003108217bb346cd5c7571.png
Last updated: 2024-03-27
plot = msm.check_availability(
    df, xcats=main, cids=cids_exp, start_size=(20, 2), start_years=False
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/883a3f08ef33f04d60d698a08fc5eaa69015b92ab05730bcfd7e6b65b0194922.png

Vintage quality is mixed and at the limit for many emerging countries, as vintage information in electronic format is scarce.

plot = msp.heatmap_grades(
    df,
    xcats=main,
    cids=cids_exp,
    size=(18, 6),
    title=f"Average vintage grades from {start_date} onwards",
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/71e00213c41878d9ca548992846bf5fefa0b5fb1bacb2f878e4b496b38d80fcb.png

For graphical representation below, it is helpful to rename some quarterly dynamics into an equivalent monthly dynamics.

dict_repl = {
    "CBCSCORE_SA_D1Q1QL1": "CBCSCORE_SA_D3M3ML3",
    "CBCSCORE_SA_D2Q2QL2": "CBCSCORE_SA_D6M6ML6",
    "CBCSCORE_SA_D1Q1QL4": "CBCSCORE_SA_3MMA_D1M1ML12",
    "CSTR_SA_P1Q1QL1AR": "CSTR_SA_P3M3ML3AR",
    "CSTR_SA_P2Q2QL2AR": "CSTR_SA_P6M6ML6AR",
    "CSTR_SA_P1Q1QL4": "CSTR_SA_P1M1ML12_3MMA",
}
for key, value in dict_repl.items():
    dfd["xcat"] = dfd["xcat"].str.replace(key, value)

History #

Construction activity growth #

Construction activity growth, measured as over-a-year-ago rate at quarterly or 3-month average periods, has posted pronounced cycles and modest short-term volatility. The COVID crisis triggered some extreme fluctions.

The South African spike in construction output growth is not a data error, but reflects a rebound of construction activity from a near-zero level.

cidx = cids 
xcatx = ["CSTR_SA_P1M1ML12_3MMA"]

msp.view_timelines(
    dfd,
    xcats=xcatx,
    cids=cidx,
    start=start_date,
    title="Construction output growth, % over a year ago, 3-month average or quarterly",
    xcat_labels=None,
    ncol=4,
    same_y=False,
    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/38172ae98a94711cbd86f3b5aa0bb322a7b48ea66b60b3e217c62cb0b89dfad2.png

Unlike other economic sectors, activity growth in construction has not been uniformly or strongly correlated across economies. This highlights its quality as a differentiating economic factor.

msp.correl_matrix(
    dfd,
    xcats="CSTR_SA_P1M1ML12_3MMA",
    cids=cidx,
    size=(20, 14),
    start=start_date,
    title="Cross-sectional correlation of construction output growth",
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/6bb35edbce42dd5691c350cee967e8bade6d4957f4a9925ca5dc01b636332751.png

Construction confidence scores #

The statistical properties of construction confidence scores are quite different across countries, and not only due to different peridoicity of releases. Yet most display broad cycles and modest short-term volatility.

cidx = cids
xcatx = ["CBCSCORE_SA"]

msp.view_timelines(
    dfd,
    xcats=xcatx,
    cids=cidx,
    start=start_date,
    title="Construction confidence scores (monthly or quarterly)",
    ncol=4,
    same_y=True,
    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/5dbae4bc979ddb0cf503371b15a2557373d279976f315de22e4d1413095ca8dd.png

Confidence score changes #

Confidence score changes are often early indicators of changes in the local construction cycles. Unlike for activity growth, the 3-month over 3-month change offers information advantage without excess volatility, at least for most countries.

xcatx = ["CBCSCORE_SA_D3M3ML3", "CBCSCORE_SA_D6M6ML6"]
cidx = cids 

msp.view_timelines(
    dfd,
    xcats=xcatx,
    cids=cidx,
    start=start_date,
    title="Construction business confidence score changes",
    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/422a2bae70bb832899a787259ec35cf2c218ae26f210a1e9a4ef34f44371a0b0.png

Importance #

Empirical clues #

Construction information states as predictor for metals markets #

# Create global GDP-weighted construction activity and survey scores

xcatx = [
    "CBCSCORE_SA_D3M3ML3",
    "CBCSCORE_SA_3MMA",
    "CSTR_SA_P1M1ML12_3MMA",
    "CSTR_SA_P3M3ML3AR",
    "CSTR_SA_P6M6ML6AR"
]

for xc in xcatx:
    dfa = msp.linear_composite(
    df=dfd,
    xcats=xc,
    cids=cids,
    weights="USDGDPWGT_SA_1YMA",
    new_cid="GLB",
    complete_cids=False,
    )
    dfd = msm.update_df(dfd, dfa)
msp.view_timelines(
    dfd,
    cids="GLB",
    xcats=["CBCSCORE_SA_D3M3ML3"],
    xcat_labels=["Business confidence"],
    start=start_date,
    title="Global construction 3-month over 3-month confidence changes, GDP-weighted average of information states",
    title_adj=1.02,
    title_xadj=0.49,
    title_fontsize=16,
    size=(12, 5),
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/47845b4f7de6354f92e35a68e8108c01f92f60c98e0b91c735e1b00ff4888517.png
# Calculate returns of construction-related metals basket

contracts = [c + "_CO" for c in cids_co]
bask_co = msp.Basket(df=dfd, contracts=contracts, ret="XR_NSA")
bask_co.make_basket(weight_meth="equal", basket_name="GLB_MTL")
dfa = bask_co.return_basket()
dfd = msm.update_df(dfd, dfa)

In accordance with economic relations and the theory of rational inattention, short-term changes in construction confidence have been highly significant predictors of construction-related metal futures prices over past decades. Significance of predictive power has been highest at the monthly frequency but was also still near 95% at a weekly frequency.

cr = msp.CategoryRelations(
    dfd,
    xcats=["CBCSCORE_SA_D3M3ML3", "MTL_XR_NSA"],
    cids=["GLB"],
    freq="M",
    lag=1,
    xcat_aggs=["last", "sum"],
    fwin=1,
    start="2000-01-01",
    years=None,
)

cr.reg_scatter(
    title="Global short-term construction confidence change and subsequent metal futures returns since 2000",
    labels=False,
    coef_box="lower right",
    xlab="Change in construction survey score, 3 months over previous 3 months, seasonally adjusted",
    ylab="Next month's return on basket of aluminium, copper and tin futures, %",
    prob_est="map",
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/f312173c56c27959186c065421aa472ad24b865f38b056cdfcad9975f7a23817.png

There has also been a meaningful positive relation between medium-term construction confidence changes and subsequent quarterly returns of a basket of construction-related metals. Its significance has been lower, since less data points are available for the analysis, but the correlation has been stronger than for short-term variation and is in line with plausible theory.

cr = msp.CategoryRelations(
    dfd,
    xcats=["CSTR_SA_P6M6ML6AR", "MTL_XR_NSA"],
    cids=["GLB"],
    freq="Q",
    lag=1,
    xcat_aggs=["last", "sum"],
    fwin=1,
    start="2000-01-01",
    years=None,
)

cr.reg_scatter(
    title="Global medium-term construction confidence change and subsequent metal futures returns",
    labels=False,
    coef_box="lower right",
    xlab="Change in construction survey score, 6 months over previous 6 months, seasonally adjusted",
    ylab="Next quarters's return on basket of aluminium, copper and tin futures, %",
    prob_est="map",
)
https://macrosynergy.com/notebooks.build/themes/economic-trends/_images/946789122e0da55307f329470f75770bc19f4b3c39ee03563276185a918e4834.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": "Brazil",
            "source": "Getulio Varags Foundation",
            "details": "Construction Confidence Index Total SA Index",
        },
        {
            "country": "Canada",
            "source": "Canadian Federation of Independent Business",
            "details": "CFIB Business Barometer Index Overall Index Business Construction Long-term Index",
        },
        {
            "country": "Switzerland",
            "source": "KOF Swiss Economic Institute",
            "details": "Business Situation Construction SA",
        },
        {
            "country": "China",
            "source": "China Federation of Logistics & Purchasing",
            "details": "Purchasing Managers Index Construction PMI SA Index",
        },
        {
            "country": "Chile",
            "source": "Chilean Institute of Rational Administration",
            "details": "Business confidence index construction",
        },
        {
            "country": "Czech Republic",
            "source": "Business Tendency Surveys (Construction)",
            "details": "Confidence Indicators Composite Indicators OECD Indicator SA Index",
        },
        {
            "country": "Germany",
            "source": "Ifo Institue",
            "details": "Assessment of the Buisness situation, Construction SA Index",
        },
        {
            "country": "Spain",
            "source": "Business Tendency Surveys (Construction)",
            "details": "Confidence Indicators Composite Indicators OECD Indicator SA Index",
        },
        {
            "country": "Euro Area",
            "source": "DG ECFIN",
            "details": "Construction Confidence Indicator Total Services Sector"
        },
        {
            "country": "France",
            "source": "INSEE",
            "details": "Buisness industry Climate Indicator Index",
        },
        {
            "country": "Hungary",
            "source": "Eurostat",
            "details": "Busines surveys Construction Confidence indicator"
        },
        {
            "country": "Israel",
            "source": "Business Tendency Surveys (Construction)",
            "details": "Confidence Indicators Composite Indicators OECD Indicator SA Index",
        },
        {
            "country": "Italy",
            "source": "ISTAT",
            "details": "Buisness surveys confidence construction index"
        },
        {
            "country": "Japan",
            "source": "Japan Teikoku Databank",
            "details": "Diffusion index for current conditions construction index",
        },
        {
            "country": "South Korea",
            "source": "Bank of Korea",
            "details": "Buisness Condition Construction Index",
        },
        {
            "country": "South Korea",
            "source": "Federation of Korean Industries",
            "details": "Business Survey Index Buisness Condition Construction Index",
        },
        {
            "country": "Malaysia",
            "source": "Department of Statistics Malaysia",
            "details": "Business Tendency Survey Current Situation Construction Total",
        },
        {
            "country": "Malaysia",
            "source": "Department of Statistics Malaysia",
            "details": "Business Tendency Survey Confidence Construction Total",
        },
        {
            "country": "Netherlands",
            "source": "DG ECFIN",
            "details": "Construction Confidence Indicator Total Services Sector",
        },
        {
            "country": "New Zealand",
            "source": "Business New Zealand",
            "details": "Performance of Services Index",
        },
        {
            "country": "Philippines",
            "source": " Central Bank of the Philippines",
            "details": " Business Outlook Index on the Macroeconomy Current Quarter Construction Sector Index",
        },
        {
            "country": "Russia",
            "source": "Rosstat",
            "details": "Entrepreneur Confidence index construction"
        },
        {
            "country": "Russia",
            "source": "Business Tendency Surveys (Construction)",
            "details": "Confidence Indicators Composite Indicators OECD Indicator SA Index",
        },
        {
            "country": "Romania",
            "source": "DG ECFIN",
            "details": "Construction Confidence Indicator Total Services Sector"
        },
        {
            "country": "Sweden",
            "source": "Swedbank",
            "details": "Purchasing Managers Index Total Services SA Index",
        },
        {
            "country": "Turkey",
            "source": "DG ECFIN",
            "details": "Services Confidence Indicator Total Services Sector"
        },
        {
            "country": "Thailand",
            "source": "Thai Real Estate Information Center",
            "details": "Housing Development Buisness Sentiment Index",
        },
        {
            "country": "Taiwan",
            "source": "Taiwan National Development Council",
            "details": "Business Surveys Index Construction",
        },
        {
            "country": "United States",
            "source": "ISM",
            "details": "Report on Business Services Purchasing Managers SA Index",
        },
        {
            "country": "South Africa",
            "source": "Bureau for Cconomic Research of South Africa",
            "details": "Building confidence Index",
        },
    ]
)