Market-implied inflation expectations#

This category contains market-based inflation expectations inferred from (i) inflation-linked bonds and (ii) inflation swaps. This label postulates that breakeven inflation rates of these contracts are a valid proxy of the market’s inflation expectations. In reality, breakeven inflation rates are also subject to other influences, such as risk premia, liquidity premia, taxes, and collateral rules. Various adjustments of breakeven rates can be considered to arrive at better estimates of market expectations.

The scope of market-implied inflation expectations is limited by available liquid trading contracts. This is the second version of data released for this category on JPMaQS; a number of contracts that were unsuitable or not sufficiently liquid for deriving expectations were removed.

Breakeven rates of inflation-linked bonds#

Ticker: IMPINFB2Y_NSA / IMPINFB5Y_NSA

Label: Breakeven rate of inflation-linked bond: 2 years ahead / 5 years ahead

Definition: Implied breakeven inflation rate of inflation-linked bonds for: the next 2 years / the next 5 years

Notes:

  • The breakeven inflation rates are calculated as the differences between nominal bond yields and real yields for inflation linked bonds of roughly the same maturities. For example, for the 2-year forward horizon, the nominal bond and the inflation linked bond are selected where the time to maturity for both bonds is approximately 2 years.

  • The nominal yield is the current mid yield of the sovereign-issued nominal bond.

  • The real yield is the mid yield derived from the inflation-adjusted coupon and secondary market price of the sovereign issued inflation linked bond.

  • In most countries, inflation-linked bonds are indexed to the regular headline consumer price index (CPIH). Two exceptions are Brazil (using the extended national consumer price index, IPCA) and the UK (using a retail price index, RPI).

Breakeven rates of inflation swaps#

Ticker: IMPINFM1Y_NSA / IMPINFM2Y_NSA / IMPINFM5Y_NSA

Label: Breakeven rates of inflation swap (market convention): 1 year ahead / 2 years ahead / 5 years ahead

Definition: Implied breakeven inflation rate (market convention) of inflation swaps for: the next year / the next 2 years / the next 5 years

Notes:

  • An inflation swap is a derivative contract where one party pays a fixed rate cashflow and the other party pays a floating rate based on an inflation index, such as a consumer price index. The breakeven rate (or swap rate) for an inflation swap is the rate at which the fixed rate is equivalent to the floating rate making the swap price zero.

  • As the floating leg is linked to an inflation index, the breakeven rate provides a useful first proxy for market-based inflation expectations.

  • The inflation swap rate used for this indicator denotes the swap rate with a default lookback period for the underlying inflation index. The reference period with a lookback period is the market convention for inflation swap rates. The lookback reference periods for the underlying inflation index are as follows:

    • Australia - 3m lag

    • Eurozone - 3m lag

    • Great Britain - 2m lag

    • US Dollar - 3m lag

  • In most countries, inflation swaps are written on the main headline consumer price index (CPIH). In the euro area, the swaps are based on the harmonized index of consumer price inflation (HICP).

  • Disclaimer: JPMaQS is currently reviewing the Australia inflation swap data for July-August 2022. Please reach out to the JPMaQS team at jpmaqs_support@jpmorgan.com for further information.

Ticker: IMPINFS1Y_NSA / IMPINFS2Y_NSA / IMPINFS5Y_NSA

Label: Breakeven rates of inflation swap: 1 year ahead / 2 years ahead / 5 years ahead

Definition: Implied breakeven inflation rate of inflation swaps for: the next year / the next 2 years / the next 5 years

Notes:

  • An inflation swap is a derivative contract where one party pays a fixed rate cashflow and the other party pays a floating rate based on an inflation index, such as a consumer price index. The breakeven rate (or swap rate) for an inflation swap is the rate at which the fixed rate is equivalent to the floating rate making the swap price zero.

  • As the floating leg is linked to an inflation index, the breakeven rate provides a useful first proxy for market-based inflation expectations.

  • The inflation swap rate used for this indicator denotes the swap rate without the default lookback period for the underlying inflation index. The reference period for the underlying inflation index is roughly similar to the swap start and swap end date.

  • In most countries, inflation swaps are written on the main headline consumer price index (CPIH). In the Euro area, the swaps are based on the harmonized index of consumer price inflation (HICP).

  • Disclaimer: JPMaQS is currently reviewing the Australia inflation swap data for July-August 2022. Please reach out to the JPMaQS team at jpmaqs_support@jpmorgan.com for further information.

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.

infb_cids_dm = ["AUD", "GBP", "JPY", "USD"]  # DM currency areas
infb_cids_latm = ["BRL"]  # Latam countries
infb_cids_emea = ["ILS", "TRY"]  # EMEA countries

infb_cids_em = infb_cids_latm + infb_cids_emea
infb_cids = sorted(infb_cids_dm + infb_cids_em)

infs_cids = ["AUD", "EUR", "GBP", "USD"]

cids = sorted(list(set(infs_cids).union(set(infb_cids))))
main_b = ["IMPINFB2Y_NSA", "IMPINFB5Y_NSA"]
main_s = ["IMPINFS1Y_NSA", "IMPINFS2Y_NSA", "IMPINFS5Y_NSA"]
main_s_mkt_conv = ["IMPINFM1Y_NSA", "IMPINFM2Y_NSA", "IMPINFM5Y_NSA"]
main = list(set(main_b).union(set(main_s)).union(set(main_s_mkt_conv)))
main.sort()
econ = [
    "INFTARGET_NSA",
    "CPIH_SA_P1M1ML12",
    "CPIH_SJA_P6M6ML6AR",
    "INFE5Y_JA",
    "FXTARGETED_NSA",
    "FXUNTRADABLE_NSA",
]  # economic context
mark = [
    "EQXR_NSA",
    "EQXR_VT10",
    "DU02YXR_NSA",
    "DU02YXR_VT10",
    "DU05YXR_NSA",
    "DU05YXR_VT10",
    "FXXR_NSA",
    "FXXR_VT10",
]  # market links

xcats = main_b + main_s + main_s_mkt_conv + econ + mark
# Download series from J.P. Morgan DataQuery by tickers

start_date = "2000-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 176
Downloading data from JPMaQS.
Timestamp UTC:  2023-07-14 15:05:21
Connection successful!
Number of expressions requested: 704
Requesting data: 100%|█████████████████████████████████████████████████████████████████| 36/36 [00:11<00:00,  3.21it/s]
Downloading data: 100%|████████████████████████████████████████████████████████████████| 36/36 [00:23<00:00,  1.50it/s]
Download time from DQ: 0:00:43.203206

Availability#

cids_exp = cids  # cids expected in category panels
msm.missing_in_df(dfd, xcats=main, cids=cids_exp)
Missing xcats across df:  set()
Missing cids for IMPINFB2Y_NSA:  {'GBP', 'USD', 'BRL', 'EUR', 'AUD', 'ILS', 'JPY'}
Missing cids for IMPINFB5Y_NSA:  {'EUR'}
Missing cids for IMPINFM1Y_NSA:  {'BRL', 'JPY', 'TRY', 'ILS'}
Missing cids for IMPINFM2Y_NSA:  {'BRL', 'JPY', 'TRY', 'ILS'}
Missing cids for IMPINFM5Y_NSA:  {'BRL', 'JPY', 'TRY', 'ILS'}
Missing cids for IMPINFS1Y_NSA:  {'BRL', 'JPY', 'TRY', 'ILS'}
Missing cids for IMPINFS2Y_NSA:  {'BRL', 'JPY', 'TRY', 'ILS'}
Missing cids for IMPINFS5Y_NSA:  {'BRL', 'JPY', 'TRY', 'ILS'}

Outside the U.S. and Euro areas, history of breakeven inflation rates is limited, with data typically starting in the 2010s. Swap data is available only for selected developed markets, whilst emerging market breakeven rates are available only for certain tenors.

For the explanation of currency symbols, which are related to currency areas or countries for which categories are available, please view Appendix 1.

xcatx = main
cidx = cids_exp

dfx = msm.reduce_df(dfd, xcats=xcatx, cids=cidx)
dfs = msm.check_startyears(
    dfx,
)
msm.visual_paneldates(dfs, size=(20, 5))

print("Last updated:", date.today())
../_images/Market-implied inflation expectations_17_0.png
Last updated: 2023-07-14
plot = msm.check_availability(
    dfd, xcats=main, cids=cids_exp, start_size=(40, 8), start_years=False
)
../_images/Market-implied inflation expectations_18_0.png

All available data is of the highest grading.

plot = msp.heatmap_grades(
    dfd,
    xcats=main,
    cids=cids_exp,
    size=(20, 4),
    title=f"Average vintage grades from {start_date} onwards",
)
../_images/Market-implied inflation expectations_20_0.png
for x in main:
    xcatx = [x]
    msp.view_ranges(
        dfd,
        xcats=xcatx,
        cids=cids_exp,
        val="eop_lag",
        title="End of observation period lags (ranges of time elapsed since end of observation period in days)",
        start=start_date,
        kind="box",
        size=(16, 4),
    )
    msp.view_ranges(
        dfd,
        xcats=xcatx,
        cids=cids_exp,
        val="mop_lag",
        title="Median of observation period lags (ranges of time elapsed since middle of observation period in days)",
        start=start_date,
        kind="box",
        size=(16, 4),
    )
../_images/Market-implied inflation expectations_21_0.png ../_images/Market-implied inflation expectations_21_1.png ../_images/Market-implied inflation expectations_21_2.png ../_images/Market-implied inflation expectations_21_3.png ../_images/Market-implied inflation expectations_21_4.png ../_images/Market-implied inflation expectations_21_5.png ../_images/Market-implied inflation expectations_21_6.png ../_images/Market-implied inflation expectations_21_7.png ../_images/Market-implied inflation expectations_21_8.png ../_images/Market-implied inflation expectations_21_9.png ../_images/Market-implied inflation expectations_21_10.png ../_images/Market-implied inflation expectations_21_11.png ../_images/Market-implied inflation expectations_21_12.png ../_images/Market-implied inflation expectations_21_13.png ../_images/Market-implied inflation expectations_21_14.png ../_images/Market-implied inflation expectations_21_15.png

History#

Breakeven rates of inflation-linked bonds#

The history of the available bonds-based breakeven rates has been quite diverse, albeit all showed a pronounced increase during the 2020-22 pandemic.

xcatx = ["IMPINFB2Y_NSA", "IMPINFB5Y_NSA"]
cidx = infb_cids
msp.view_timelines(
    dfd,
    xcats=xcatx,
    cids=cidx,
    start=start_date,
    title="Breakeven rates of inflation-linked bonds",
    title_adj=1.05,
    title_xadj=0.48,
    title_fontsize=27,
    legend_fontsize=17,
    xcat_labels=["2-year", "5-year"],
    ncol=3,
    same_y=False,
    size=(12, 7),
    aspect=1.7,
    all_xticks=True,
)
../_images/Market-implied inflation expectations_25_0.png

Cross correlations of breakeven rates have been mostly positive, but not universally so.

msp.correl_matrix(
    dfd,
    xcats="IMPINFB5Y_NSA",
    cids=infb_cids,
    title="Cross-sectional correlations of inflation-linked bond breakeven rates",
    size=(8, 5),
)
../_images/Market-implied inflation expectations_27_0.png

Breakeven rates of inflation swaps#

Longer-term breakeven inflation rates have been more stable than short-term rates, testifying to the credibility of inflation targeting regimes in the 2000s and 2010s in the major developed countries.

xcatx = ["IMPINFM1Y_NSA", "IMPINFM2Y_NSA", "IMPINFM5Y_NSA"]
cidx = infs_cids

msp.view_timelines(
    dfd,
    xcats=xcatx,
    cids=cidx,
    start="2000-01-01",
    title="Breakeven rates of inflation swaps (market convention)",
    title_adj=1.1,
    title_xadj=0.49,
    title_fontsize=27,
    legend_fontsize=15,
    label_adj=0.075,
    xcat_labels=["1-year", "2-year", "5-year"],
    ncol=3,
    same_y=False,
    size=(12, 7),
    aspect=1.7,
    all_xticks=True,
)
../_images/Market-implied inflation expectations_30_0.png
xcatx = ["IMPINFS1Y_NSA", "IMPINFS2Y_NSA", "IMPINFS5Y_NSA"]
cidx = infs_cids

msp.view_timelines(
    dfd,
    xcats=xcatx,
    cids=cidx,
    start="2000-01-01",
    title="Breakeven rates of inflation swaps (without lookback)",
    xcat_labels=["1-year", "2-year", "5-year"],
    title_adj=1.1,
    title_xadj=0.49,
    title_fontsize=27,
    legend_fontsize=15,
    label_adj=0.075,
    ncol=3,
    same_y=False,
    size=(12, 7),
    aspect=1.7,
    all_xticks=True,
)
../_images/Market-implied inflation expectations_31_0.png

5-year swap-based breakeven rates have mostly fluctuated around the inflation target.

xcatx = ["IMPINFM5Y_NSA", "INFTARGET_NSA"]
cidx = infs_cids

msp.view_timelines(
    dfd,
    xcats=xcatx,
    cids=cidx,
    start="2000-01-01",
    title="5-year breakeven rates, market-convention, and inflation targets",
    xcat_labels=["5-year breakeven rate", "Inflation target"],
    ncol=3,
    same_y=False,
    size=(12, 7),
    aspect=1.7,
    all_xticks=True,
    title_adj=1.1,
    title_xadj=0.45,
    title_fontsize=27,
    legend_fontsize=15,
    label_adj=0.075,
)
../_images/Market-implied inflation expectations_33_0.png

Importance#

Empirical clues#

Based on inflation swaps, there has been a strong correlation between recorded CPI trends and 1-year ahead breakeven inflation rates.

xcatx = ["CPIH_SJA_P6M6ML6AR", "IMPINFM1Y_NSA"]
cidx = infs_cids

cr = msp.CategoryRelations(
    dfd,
    xcats=xcatx,
    cids=cidx,
    freq="M",
    lag=0,
    xcat_aggs=["mean", "mean"],
    start="2000-01-01",
    years=None,
)
cr.reg_scatter(
    title="AUD, EUR, GBP, USD: Inflation trends and 1-year ahead breakeven inflation rates, based on inflation swaps, monthly averages",
    labels=False,
    coef_box="lower right",
    xlab="CPI, % 6m/6m, saar, adjusted for jumps and spikes",
    ylab="1-year ahead inflation swap breakeven rate, % ar",
)
../_images/Market-implied inflation expectations_43_0.png

As suggested by theory, larger inflation expectations coincide with smaller subsequent fixed receiver IRS returns. This is seen across all cross-sections for which data is available.

xcatx = ["IMPINFM5Y_NSA", "DU02YXR_VT10"]
cidx = infs_cids

cr = msp.CategoryRelations(
    dfd,
    xcats=xcatx,
    cids=cidx,
    freq="M",
    lag=1,
    xcat_aggs=["mean", "sum"],
    start="2000-01-01",
    xcat_trims=[4, 20],
    years=None,
)
cr.reg_scatter(
    title="AUD, EUR, GBP, USD: Implied breakeven inflation swap rates, market convention, and total next-month 2-year IRS returns, 10% vol-target",
    xlab="5-year ahead inflation swap breakeven rate, % ar",
    ylab="Subsequent cumulative monthly 2-year IRS returns, 10% vol-target",
    coef_box="upper right",
)
../_images/Market-implied inflation expectations_45_0.png
xcatx = ["IMPINFM5Y_NSA", "DU02YXR_VT10"]
cidx = infs_cids

cr = msp.CategoryRelations(
    dfd,
    xcats=xcatx,
    cids=cidx,
    freq="M",
    lag=1,
    xcat_aggs=["mean", "sum"],
    start="2000-01-01",
    years=None,
)
cr.reg_scatter(
    title="Implied breakeven inflation swap rates, market convention, and total next-month 2-year IRS returns, 10% vol-target",
    xlab="5-year ahead breakeven rate",
    ylab="Next month total return",
    coef_box="upper right",
    separator="cids",
    title_adj=1.05,
)
../_images/Market-implied inflation expectations_46_0.png

Changes in swap breakeven rates above the central bank’s inflation target have been strongly and negatively correlated with subsequent fixed income returns in developed markets. This supports the theory that central banks respond to rising inflation fears with a shift in policy bias towards less easing or more tightening.

calcs = ["XIMINFM5Y = IMPINFM5Y_NSA - INFTARGET_NSA"]
dfa = msp.panel_calculator(dfd, calcs=calcs, cids=infs_cids)
dfx = msm.update_df(dfd, dfa)

cr = msp.CategoryRelations(
    dfx,
    xcats=["XIMINFM5Y", "DU02YXR_VT10"],
    cids=infs_cids,
    xcat1_chg="diff",
    freq="M",
    lag=1,
    xcat_aggs=["mean", "sum"],
    xcat_trims=[1, 20],
    start="2000-01-01",
    years=None,
)
cr.reg_scatter(
    title="AUD, EUR, GBP, USD: Changes in excess breakeven inflation and subsequent IRS returns",
    labels=False,
    coef_box="lower right",
    xlab="Average monthly difference in 5-year ahead breakeven inflation versus inflation target",
    ylab="2-year IRS receiver return, next month",
)
../_images/Market-implied inflation expectations_48_0.png

There is also some evidence of predictive power in 5-year inflation swap breakeven rates for subsequent equity returns.

cr = msp.CategoryRelations(
    dfd,
    xcats=["IMPINFM5Y_NSA", "EQXR_NSA"],
    cids=infs_cids,
    freq="M",
    lag=1,
    xcat_aggs=["mean", "sum"],
    # xcat_trims=[2.5, 5],
    start="2000-01-01",
    years=None,
)
cr.reg_scatter(
    coef_box="upper right",
    title="Inflation swap breakeven rates, 5-years ahead, and next-month equity returns, all available history",
    ylab="Next-month cumulative equity returns",
    xlab="Inflation swap breakeven rates, 5-years ahead, monthly average",
)
../_images/Market-implied inflation expectations_50_0.png

Appendices#

Appendix 1: Currency symbols#

The word ‘cross-section’ refers to currencies, currency areas or economic areas. The cross-sections used in this notebook are:

  • AUD (Australian dollar)

  • BRL (Brazilian real)

  • EUR (Euro)

  • GBP (British pound)

  • ILS (Israeli shekel)

  • JPY (Japanese yen)

  • TRY (Turkish lira)

  • USD (U.S. dollar).