Commodity future volatility #

This category group includes measures of realized return volatility for commodity futures. It also includes related generic leverage ratios for volatility targets.

Commodity future volatility #

Ticker : COXRxEASD_NSA

Label : Estimated annualized standard deviation of commodity future return.

Definition : Annualized standard deviation of commodity front future return, % of notional, based on exponential moving average of daily returns.

Notes :

  • The standard deviation has been calculated based on an exponential moving average of daily returns with a half-life of 11 active trading days.

  • The return is simply the % change in the front futures price. The return calculation assumes rolling futures (from front to second) on the first day of the month when the contract is due to expire. Not all commodities have monthly contracts.

  • For information on the components comprising each commodity group, see Appendix 1 .

Leverage ratio of vol-targeted commodity future position #

Ticker : COXRxLEV10_NSA

Label : Leverage ratio of commodity future position for 10% annualized vol target.

Definition : Commodity future leverage for a 10% annualized vol target, as ratio of contract notional relative to risk capital on which the return is calculated.

Notes :

  • This serves as the leverage ratio for a 10% annualized vol target and is inversely proportional to the estimated annualized standard deviation of the return on a USD1 notional position. The leverage can be viewed as indicative for positioning and endogenous market risk.

  • See also related important notes on “Commodity future volatility” ( COXRxEASD_NSA ).

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_nfm = ["GLD", "SIV", "PAL", "PLT"]
cids_fme = ["ALM", "CPR", "LED", "NIC", "TIN", "ZNC"]
cids_ene = ["BRT", "WTI", "NGS", "GSO", "HOL"]
cids_sta = ["COR", "WHT", "SOY", "CTN"]
cids_liv = ["CAT", "HOG"]
cids_mis = ["CFE", "SGR", "NJO", "CLB"]

cids = cids_nfm + cids_fme + cids_ene + cids_sta + cids_liv + cids_mis
main = ["COXRxEASD_NSA", "COXRxLEV10_NSA"]
econ = []  # economic context
mark = ["COCRY_NSA", "COCRY_VT10", "COXR_NSA"]  # market links

xcats = main + 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 125
Downloading data from JPMaQS.
Timestamp UTC:  2023-08-21 14:00:18
Connection successful!
Number of expressions requested: 500
Requesting data: 100%|█████████████████████████████████████████████████████████████████| 25/25 [00:07<00:00,  3.22it/s]
Downloading data: 100%|████████████████████████████████████████████████████████████████| 25/25 [00:25<00:00,  1.04s/it]
Download time from DQ: 0:00:41.333670

Availability #

cids_exp = cids
msm.missing_in_df(dfd, xcats=main, cids=cids_exp)
Missing xcats across df:  []
Missing cids for COXRxEASD_NSA:  []
Missing cids for COXRxLEV10_NSA:  []

Most of commodities indicators are available from the early 1990s. Only a few energy products start in the 2000s: Brent, gasoline and natural gas.

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, 3))

print("Last updated:", date.today())
https://macrosynergy.com/notebooks.build/themes/shock-and-risk-measures/_images/b87b60ebdddf3ed87ea5ae9683342ff4a5647fe17b577fa4c1a8a8c3f8dca3a2.png
Last updated: 2023-08-21
plot = msm.check_availability(
    dfd, xcats=main, cids=cids_exp, start_size=(20, 2), start_years=False
)
https://macrosynergy.com/notebooks.build/themes/shock-and-risk-measures/_images/ba516e37f100607e2916750e78720712f19b4a4bb9f9b31678d9e2abff738690.png
msp.heatmap_grades(dfd, xcats=main, cids=cids_exp, start="2000-01-10", size=(16, 1))
https://macrosynergy.com/notebooks.build/themes/shock-and-risk-measures/_images/3f5153b638b9ff13420a479de8da25431553e1861779b9a9861bf6a12302db7c.png
xcatx = main
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="2000-01-01",
    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="2000-01-01",
    kind="box",
    size=(16, 4),
)
https://macrosynergy.com/notebooks.build/themes/shock-and-risk-measures/_images/9a5aa986bac7f61cfe61dafe1a1c9bee71d7e6b25b667857c1066e06ff739953.png https://macrosynergy.com/notebooks.build/themes/shock-and-risk-measures/_images/e17cbf430567137eba289fc3c7405135b9956a9d911f182dbc9f9b6489a980b6.png

History #

Commodity future volatility #

Average annualized volatility across commodities since 2000 ranges from over 40% (natural gas) to near 15% (live cattle). Spikes, i.e. large short-lived outliers, are discernible in many commodities.

xcatx = ["COXRxEASD_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 commodity future volatility, since 2000",
    kind="bar",
    size=(16, 8),
)
https://macrosynergy.com/notebooks.build/themes/shock-and-risk-measures/_images/877a3e7a5f364106f6fc36a2c0174aff7484610d0a42e4ea59ee9c373cbaf63b.png
xcatx = ["COXRxEASD_NSA"]
cidx = cids_exp

msp.view_timelines(
    dfd,
    xcats=xcatx,
    cids=cidx,
    start="2000-01-01",
    title="Commodity future volatility, exponential lookback, 11-day half-life, % ar",
    title_adj=1.03,
    title_fontsize=27,
    title_xadj=0.52,
    cumsum=False,
    ncol=4,
    same_y=True,
    size=(12, 7),
    aspect=1.7,
    all_xticks=True,
)
https://macrosynergy.com/notebooks.build/themes/shock-and-risk-measures/_images/d9bbe4e723d96dd9f4218b075ed74ce4bb75c04ea2fee63fc4d026a8b78192a4.png

Realized volatility has mostly been positively correlated across commodities. But unlike in the equity space positive correlation has been quite weak and has not been universal. Coffee and livestock display little correlation with other commodities.

msp.correl_matrix(dfd, xcats="COXRxEASD_NSA", cids=cids_exp, size=(20, 14))
https://macrosynergy.com/notebooks.build/themes/shock-and-risk-measures/_images/7341d49d0c8248f403b08da39afb645a3e2319b0a457a342f21561c8ac8fa575.png

Leverage ratio of vol-targeted commodity future position #

Since volatility of commodity returns is higher than for other asset clasess, leverage differences for equal volatility targets across markets have been low, between 0.2 and 0.75.

xcatx = ["COXRxLEV10_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 vol-targeted commodity future position leverage ratios",
    kind="bar",
    size=(16, 8),
)
https://macrosynergy.com/notebooks.build/themes/shock-and-risk-measures/_images/b3555e45ef839ebe6663e32e3c99bfe246bb37da9c5d8869616e5729b0be55dd.png
xcatx = ["COXRxLEV10_NSA"]
cidx = cids_exp

msp.view_timelines(
    dfd,
    xcats=xcatx,
    cids=cidx,
    start="2000-01-01",
    title="Leverage ratios of vol-targeted commodity future positions",
    title_adj=1.02,
    title_fontsize=27,
    title_xadj=0.5,
    cumsum=False,
    ncol=4,
    same_y=True,
    size=(12, 7),
    aspect=1.7,
    all_xticks=True,
)
https://macrosynergy.com/notebooks.build/themes/shock-and-risk-measures/_images/c96a3040cf7c58360ddf370d6f31b9b7b4bab05d3b86069af1a6c47a5c49736c.png

Importance #

Relevant research #

“Analysing volatility for the aggregate commodity market and for various commodity groups we find that factors associated with macroeconomic and financial market uncertainty explain subsequent volatility of commodity returns. Variables motivated by commodity pricing theories, such as the futures basis and hedging pressure, are also significant. Economic uncertainty measures based on differences in beliefs of economic agents extracted from survey data provide additional information to that contained in volatility series of current economic fundamentals. Finally, we find evidence of a strong bi-directional causal link between inflation uncertainty and commodity return volatility.” Prokopczuk and Symeonidis

“Volatility risk premia – differences between options-implied and actual volatility – are valid predictors for risky asset returns. High premia typically indicate high surcharges for the risk of changes in volatility, which are paid by investors with strong preference for more stable returns. For commodities volatility risk premia should have become a greater factor as consequence of their ‘financialization’. New evidence suggests that indeed volatility risk premia on commodity currencies have predictive power for subsequent commodity returns, while crude and gold premia have predictive power for other asset classes in accordance with the nature of these commodities. Since estimation of these premia takes some skill and judgment this points to opportunities for macro trading with econometric support” Macrosynergy

Empirical clues #

On balance, there has been a tendency for period and commodities with higher volatility leading higher returns.

cr = msp.CategoryRelations(
    dfd,
    xcats=["COXRxEASD_NSA", "COXR_NSA"],
    cids=cids_exp,
    freq="Q",
    lag=1,
    xcat_aggs=["last", "sum"],
    start="2000-01-01",
)
cr.reg_scatter(
    title="Commodity futures volatility and subsequent quarterly returns (global panel, since 2000)",
    labels=False,
    coef_box="upper right",
    xlab="Historic commodity futures return volatility (11-day half-time, end of quarter)",
    ylab="Commodity future retun (next quarter)",
)
https://macrosynergy.com/notebooks.build/themes/shock-and-risk-measures/_images/4601224799b42fddd0594b14b73fa6d6c64abfa5fe80584381a26fefaa9f6a04.png

Appendices #

Appendix 1: Commodity group definitions and symbols #

The commodity groups considered are: energy, base metals, precious metals, agricultural commodities and livestock.

  • The energy commodity group contains:

    • BRT : ICE Brent crude

    • WTI : NYMEX WTI light crude

    • NGS : NYMEX natural gas, Henry Hub

    • GSO : NYMEX RBOB Gasoline

    • HOL : NYMEX Heating oil, New York Harbor ULSD

  • The base metals group contains:

    • ALM : London Metal Exchange aluminium

    • CPR : Comex copper

    • LED : London Metal Exchange Lead

    • NIC : London Metal Exchange Nickel

    • TIN : London Metal Exchange Tin

    • ZNC : London Metal Exchange Zinc

  • The precious metals group contains:

    • GLD : COMEX gold 100 Ounce

    • SIV : COMEX silver 5000 Ounce

    • PAL : NYMEX palladium

    • PLT : NYMEX platinum

  • The agricultural commodity group contains:

    • COR : Chicago Board of Trade corn composite

    • WHT : Chicago Board of Trade wheat composite

    • SOY : Chicago Board of Trade soybeans composite

    • CTN : NYBOT / ICE cotton #2

    • CFE : NYBOT / ICE coffee ‘C’ Arabica

    • SGR : NYBOT / ICE raw cane sugar #11

    • NJO : NYBOT / NYCE FCOJ frozen orange juice concentrate

    • CLB : Chicago Mercantile Exchange random length lumber

  • The (U.S.) livestock commodity group contains:

    • CAT : Chicago Mercantile Exchange live cattle composite

    • HOG : Chicago Mercantile Exchange lean hogs composite