Directional risk basket carry #
The category group includes estimated carry measures of directional risk asset baskets for three asset classes: credit, equity, FX. A global composite is also provided.
The main purpose of generic risk basket carry is to serve as a benchmark for calculating relative carry of other contracts.
Nominal directional risk basket carry #
Ticker : DRBCRY_NSA
Label : Risk basket carry, % annualized.
Definition : Nominal expected carry on global asset class or composite (directional) basket of contracts, % annualized.
Notes :
-
Carry is defined as the return for unchanged market prices. For the credit (CDS index) basket, this is simply the spread implied by the default swap. For FX forwards, it is the 1-month forward implied interest rate differential. For equity, the carry needs to be estimated: market price is interpreted as the price of existing capital stock and carry is the difference between (i) the average of forward earnings and dividend yield and (ii) a short-term funding rate.
-
Note that real carry (
DRBXR_CRR
) is typically economically more meaningful than nominal carry. -
The global directional risk basket and its constituent asset class baskets are sets of liquid contracts whose performance metrics are good proxies for key market segments, formed by macro-criteria. Rebalancing is monthly-based on either fixed or inverse volatility weights. Inverse volatility weights are based on exponential lookback windows of daily returns with a half-life of 11 days.
-
If a contract or composite is missing within a basket, the weights are transferred to the available contracts to produce a long and smooth history. Thus, the assumption is that if a contract is missing, the basket is formed by the remaining available contracts.
-
The global equity index future basket (GEQ) is a fixed-weighted composite of Standard and Poor’s 500 Composite (40%), EURO STOXX 50 (25%), Nikkei 225 Stock Average (10%) FTSE 100 (10%), and Hang Seng China Enterprises (15%).
-
The global credit index (GCR) is an inverse-volatility weighted basket of CDX and iTraxx investment-grade and high-yield indices for the U.S. and the euro area.
-
The global currency basket (GFX) focuses on small, emerging market and commodity currencies (excluding pegs) and is an inverse volatility-weighted composite of 1-month forward shorts in USD or EUR against AUD, INR, KRW, NOK, NZD, PLN, RUB, SEK, TRY, ZAR. See Appendix 1 for the explanation of currency symbols.
-
The global directional risk basket (GLB) is a volatility-weighted composite of the above 3 global asset class baskets. For older history where credit or currency baskets are not available, the remaining constituents have been used for convenience.
Real directional risk basket carry #
Ticker : DRBCRR_NSA
Label : Real risk basket carry, % annualized.
Definition : Real expected carry on global asset class or composite (directional) basket of contracts, % annualized.
Notes :
-
Real carry is nominal carry adjusted for inflation effects. Inflation trends conceptually erode the value of nominal assets, even if these are only implied in a derivatives position. For FX forwards, the implied nominal interest rate differential is adjusted by an expected inflation differential. For equity, the discount rate is converted into a real rate. Indeed without this adjustment, equity carry is understated in all countries that have positive inflation rates and massively understated in high inflation countries. For credit (default swaps), the real carry is equal to the nominal carry.
-
The importance of inflation suggests that real carry measures are economically more meaningful, even if there can be estimation errors in real-time inflation expectations.
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.
# Define cross sections (currency tickers)
cids = ["GCR", "GEQ", "GFX", "GLB"]
# Define quantamental indicators (category tickers)
main = ["DRBCRR_NSA", "DRBCRY_NSA"]
econ = [] # economic context
mark = ["DRBXR_NSA"] # market links
xcats = main + econ + mark
# Download series from J.P. Morgan DataQuery by tickers
start_date = "1990-01-01"
tickers = [cid + "_" + xcat for cid in cids for xcat in xcats]
print(f"Maximum number of tickers is {len(tickers)}")
# Retrieve credentials
client_id: str = os.getenv("DQ_CLIENT_ID")
client_secret: str = os.getenv("DQ_CLIENT_SECRET")
# Download from DataQuery
with JPMaQSDownload(client_id=client_id, client_secret=client_secret) as downloader:
start = timer()
assert downloader.check_connection()
df = downloader.download(
tickers=tickers,
start_date=start_date,
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 12
Downloading data from JPMaQS.
Timestamp UTC: 2023-06-02 16:02:37
Connection successful!
Number of expressions requested: 48
Download time from DQ: 0:00:15.372742
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 DRBCRR_NSA: set()
Missing cids for DRBCRY_NSA: set()
The broad global directional risk basket carry series’ are available by the early 2000s.
The cross section identifiers refer to the global
-
CDS index basket (GCR),
-
equity index future basket (GEQ),
-
small, EM and commodity currency basket (GFX), and
-
cross-asset directional risk basket (GLB).
xcatx = main
cidx = cids_exp
dfx = msm.reduce_df(dfd, xcats=xcatx, cids=cidx)
dfs = msm.check_startyears(
dfx,
)
msm.visual_paneldates(dfs, size=(18, 1))
print("Last updated:", date.today())
Last updated: 2023-06-02
xcatx = main
cidx = cids_exp
plot = msm.check_availability(
dfd, xcats=xcatx, cids=cidx, start_size=(18, 1), start_years=False
)
xcatx = main
cidx = cids_exp
plot = msp.heatmap_grades(
dfd,
xcats=xcatx,
cids=cidx,
size=(18, 1),
title=f"Average vintage grades from {start_date} onwards",
)
xcatx = main
cidx = cids_exp
msp.view_ranges(
dfd,
xcats=xcatx,
cids=cidx,
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=cidx,
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),
)
History #
Inflation adjustment reveals that real equity carry has historically (since 2000) been higher than real FX carry, opposite to what one would see in nominal carry metrics.
xcatx = ["DRBCRY_NSA", "DRBCRR_NSA"]
cidx = cids_exp
msp.view_ranges(
dfd,
xcats=xcatx,
cids=cidx,
sort_cids_by="mean",
start="2000-01-01",
title="Means and standard deviations of risk basket carries, since 2001",
kind="bar",
xcat_labels=["Nominal", "Real"],
size=(16, 8),
)
xcatx = ["DRBCRY_NSA", "DRBCRR_NSA"]
cidx = cids_exp
msp.view_timelines(
dfd,
xcats=xcatx,
cids=cidx,
start="2000-01-01",
title="Real and nominal risk basket carries",
xcat_labels=["Nominal", "Real"],
title_adj=1.02,
title_xadj=0.45,
# cumsum=False,
ncol=2,
same_y=False,
size=(12, 7),
aspect=1.5,
label_adj=0.15,
)
Real carry has not generally been positively correlated across asset classes. In particular, FX carry has been largely uncorrelated from credit and equity.
xcatx = "DRBCRR_NSA"
cidx = cids_exp
msp.correl_matrix(
dfd,
xcats=xcatx,
cids=cidx,
start="2000-01-01",
title="Cross-sectional correlations for risk basket carry, since 2001",
size=(10, 7),
)
Importance #
Research links #
“Carry can be defined as return for unchanged market prices and is easy to calculate in real time across assets. Carry strategies often reap risk premia and implicit subsidies. Historically, they have produced positive returns in FX, commodities, bonds and equity. Carry strategies can also be combined across asset classes to render diversification benefits. Historically, since 1990, the performance of such diversified carry portfolios has been strong, with Sharpe ratios close to 1, limited correlation to benchmark indices and less of a downside skew that FX carry trades.” Macrosynergy
Empirical clues #
There is evidence of a positive correlation between real directional risk basket carry and subsequent cumulative monthly basket returns. This is consistent prior and post the 2008 financial crisis.
xcatx = ["DRBCRR_NSA", "DRBXR_NSA"]
cidx = cids_exp
cr = msp.CategoryRelations(
dfd,
xcats=xcatx,
cids=cidx,
freq="M",
lag=1,
xcat_aggs=["last", "sum"],
xcat_trims=[11, 5],
start="2001-01-01",
)
cr.reg_scatter(
title="Risk basket (real) carry and subsequent cumulative monthly returns",
coef_box="lower right",
# labels=True,
xlab="Risk basket carry",
ylab="Risk basket return",
separator=2008,
)
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).