\(\newcommand{\footnotename}{footnote}\) \(\def \LWRfootnote {1}\) \(\newcommand {\footnote }[2][\LWRfootnote ]{{}^{\mathrm {#1}}}\) \(\newcommand {\footnotemark }[1][\LWRfootnote ]{{}^{\mathrm {#1}}}\) \(\let \LWRorighspace \hspace \) \(\renewcommand {\hspace }{\ifstar \LWRorighspace \LWRorighspace }\) \(\newcommand {\mathnormal }[1]{{#1}}\) \(\newcommand \ensuremath [1]{#1}\) \(\newcommand {\LWRframebox }[2][]{\fbox {#2}} \newcommand {\framebox }[1][]{\LWRframebox } \) \(\newcommand {\setlength }[2]{}\) \(\newcommand {\addtolength }[2]{}\) \(\newcommand {\setcounter }[2]{}\) \(\newcommand {\addtocounter }[2]{}\) \(\newcommand {\arabic }[1]{}\) \(\newcommand {\number }[1]{}\) \(\newcommand {\noalign }[1]{\text {#1}\notag \\}\) \(\newcommand {\cline }[1]{}\) \(\newcommand {\directlua }[1]{\text {(directlua)}}\) \(\newcommand {\luatexdirectlua }[1]{\text {(directlua)}}\) \(\newcommand {\protect }{}\) \(\def \LWRabsorbnumber #1 {}\) \(\def \LWRabsorbquotenumber "#1 {}\) \(\newcommand {\LWRabsorboption }[1][]{}\) \(\newcommand {\LWRabsorbtwooptions }[1][]{\LWRabsorboption }\) \(\def \mathchar {\ifnextchar "\LWRabsorbquotenumber \LWRabsorbnumber }\) \(\def \mathcode #1={\mathchar }\) \(\let \delcode \mathcode \) \(\let \delimiter \mathchar \) \(\def \oe {\unicode {x0153}}\) \(\def \OE {\unicode {x0152}}\) \(\def \ae {\unicode {x00E6}}\) \(\def \AE {\unicode {x00C6}}\) \(\def \aa {\unicode {x00E5}}\) \(\def \AA {\unicode {x00C5}}\) \(\def \o {\unicode {x00F8}}\) \(\def \O {\unicode {x00D8}}\) \(\def \l {\unicode {x0142}}\) \(\def \L {\unicode {x0141}}\) \(\def \ss {\unicode {x00DF}}\) \(\def \SS {\unicode {x1E9E}}\) \(\def \dag {\unicode {x2020}}\) \(\def \ddag {\unicode {x2021}}\) \(\def \P {\unicode {x00B6}}\) \(\def \copyright {\unicode {x00A9}}\) \(\def \pounds {\unicode {x00A3}}\) \(\let \LWRref \ref \) \(\renewcommand {\ref }{\ifstar \LWRref \LWRref }\) \( \newcommand {\multicolumn }[3]{#3}\) \(\require {textcomp}\) \(\newcommand {\intertext }[1]{\text {#1}\notag \\}\) \(\let \Hat \hat \) \(\let \Check \check \) \(\let \Tilde \tilde \) \(\let \Acute \acute \) \(\let \Grave \grave \) \(\let \Dot \dot \) \(\let \Ddot \ddot \) \(\let \Breve \breve \) \(\let \Bar \bar \) \(\let \Vec \vec \) \(\require {mathtools}\) \(\newenvironment {crampedsubarray}[1]{}{}\) \(\newcommand {\smashoperator }[2][]{#2\limits }\) \(\newcommand {\SwapAboveDisplaySkip }{}\) \(\newcommand {\LaTeXunderbrace }[1]{\underbrace {#1}}\) \(\newcommand {\LaTeXoverbrace }[1]{\overbrace {#1}}\) \(\newcommand {\LWRmultlined }[1][]{\begin {multline*}}\) \(\newenvironment {multlined}[1][]{\LWRmultlined }{\end {multline*}}\) \(\let \LWRorigshoveleft \shoveleft \) \(\renewcommand {\shoveleft }[1][]{\LWRorigshoveleft }\) \(\let \LWRorigshoveright \shoveright \) \(\renewcommand {\shoveright }[1][]{\LWRorigshoveright }\) \(\newcommand {\shortintertext }[1]{\text {#1}\notag \\}\) \(\newcommand {\vcentcolon }{\mathrel {\unicode {x2236}}}\) \(\newcommand {\toprule }[1][]{\hline }\) \(\let \midrule \toprule \) \(\let \bottomrule \toprule \) \(\def \LWRbooktabscmidruleparen (#1)#2{}\) \(\newcommand {\LWRbooktabscmidrulenoparen }[1]{}\) \(\newcommand {\cmidrule }[1][]{\ifnextchar (\LWRbooktabscmidruleparen \LWRbooktabscmidrulenoparen }\) \(\newcommand {\morecmidrules }{}\) \(\newcommand {\specialrule }[3]{\hline }\) \(\newcommand {\addlinespace }[1][]{}\)

Johnson SU distribution, and VaR

This version: 2024-06-13

First version: 2024-06-13

Summary

Johnson SU distribution is a very flexible and surprisingly suitable distribution for the financial markets. In this article we show some of its properties and test it on market data. This article is based on (Alexander, 2009, Section IV.3.4.4).

1 The Johnson SU distribution

A random variable \(X\) has Johnson’s SU (JSU) distribution if

\begin{equation*} \left ( {\frac {{X - \xi }}{\lambda }} \right ) = \sinh \left ( {\frac {{Z - \gamma }}{\delta }} \right ), Z \sim N(0,1). \end{equation*}

The JSU distribution thus arises from a transformation of a standard normal random variable \(Z\).

The parameters \(\xi , \lambda \) are parameters of location and scale, respectively. \(\gamma \) and \(\delta \) control the shape of the distribution.

The PDF and CDF of JSU \(X\) read

\begin{eqnarray*} f(x)&=&\frac {\delta }{{\lambda \sqrt {2\pi } }}\frac {1}{{\sqrt {1 + {{\left ( {\frac {{x - \xi }}{\lambda }} \right )}^2}} }}{e^{ - \frac {1}{2}{{\left ( {\gamma + \delta {{\sinh }^{ - 1}}\left ( {\frac {{x - \xi }}{\lambda }} \right )} \right )}^2}}},\\ F(x) &=& N\left ( {\gamma + \delta {{\sinh }^{ - 1}}\left ( {\frac {{x - \xi }}{\lambda }} \right )} \right ). \end{eqnarray*}

\(\alpha \)–quantile of \(X\), \(x_\alpha \) is then easily obtainable from standard normal \(\alpha \)–quantile \({z_\alpha } = {N^{ - 1}}(\alpha )\) as

\begin{equation*} {x_\alpha } = \lambda \sinh \left ( {\frac {{{z_\alpha } - \gamma }}{\delta }} \right ) + \xi . \end{equation*}

Despite the overall nice analytical form of the JSU distribution, the distribution doesn’t have characteristic function in a closed form.

2 The JSU moments

JSU-distributed variable \(X\) has the following mean, variance, and kurtosis

\begin{eqnarray*} \mathbb {E}\left [ X \right ] &=& \xi - \lambda \exp \frac {{{\delta ^{ - 2}}}}{2}\sinh \left ( {\frac {\gamma }{\delta }} \right )\\ {\mathbb {V}}[X] &=& \frac {{{\lambda ^2}}}{2}(\exp ({\delta ^{ - 2}}) - 1)\left ( {\exp ({\delta ^{ - 2}})\cosh \left ( {\frac {{2\gamma }}{\delta }} \right ) + 1} \right )\\ {\mathbb {K}}[X] &=& \frac {{3 + 6{e^{\frac {1}{{{\delta ^2}}}}} + 4{e^{\frac {2}{{{\delta ^2}}}}}\left ( {{e^{\frac {1}{{{\delta ^2}}}}} + 2} \right )\cosh \left ( {\frac {{2\gamma }}{\delta }} \right ) + {e^{\frac {2}{{{\delta ^2}}}}}\left ( { - 3 + 3{e^{\frac {2}{{{\delta ^2}}}}} + 2{e^{\frac {3}{{{\delta ^2}}}}} + {e^{\frac {4}{{{\delta ^2}}}}}} \right )\cosh \left ( {\frac {{4\gamma }}{\delta }} \right )}}{{2{{\left ( {1 + {e^{\frac {1}{{{\delta ^2}}}}}\cosh \left ( {\frac {{2\gamma }}{\delta }} \right )} \right )}^2}}} \end{eqnarray*}

(the kurtosis \({\mathbb {K}}[X]\) is ’Pearson’s’ kurtosis, not excess kurtosis).

3 JSU in python scipy package

Python’s scipy library contains an implementation of the JSU distribution in the johnsonsu package. This package uses the following parameters: loc, scale, a, b. In Section 1 we however used 4 parameters with different symbols \(\xi , \lambda \), \(\gamma \) and \(\delta \). The link between the parameters used in this article and scipy’s johnsonsu parameters is as follows:

  • \(\xi \) = loc

  • \(\lambda \) = scale

  • \(\gamma \) = a

  • \(\delta \) = b

Note that in johnsonsu the four JSU parameters are in the order a, b, loc, scale, so for example when fitting a returns dataset, we obtain

# scipy's native params
a, b, loc, scale = johnsonsu.fit(returns)

# the same fitting exercise but using params in this article
gamma, delta, xi, lbda = johnsonsu.fit(returns)

4 Example: fit JSU to S&P 500 data and JSU VaR

In this simple example, we fit the JSU to daily S&P return data, compute the kurtosis of the fitted distribution (to see the fat-tailedness), and compute the VaR as an extreme quantile of the fitted distribution.

# imports
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

import yfinance as yf # Yahoo finance data downloader (pip install yfinance)
from scipy.stats import johnsonsu, probplot # problot = QQ plot

# load S&P500 and compute daily returns
data = yf.download('^GSPC', start='2001-01-01', end='2024-02-28')
returns = data['Close'].pct_change().dropna()

4.1 Fit JSU and show kurtosis

We fit JSU parameters (for consistency with the Section 1 we use the parameter set (\(\xi , \delta , \gamma , \lambda \))). Then we compute the kurtosis - to see the fat tailedness.

# fit JSU parameters
gamma, delta, xi, lbda = johnsonsu.fit(returns)

# compute kurtosis
def kurtosisJSU(delta, gamma):
     """
       Function computes kurtosis of the Johnson SU distribution.
       The result is Pearson's kurtosis (i.e. not excess kurtosis but raw kurtosis)
     """

    k1 = 6 * np.exp(1 / delta**2)
    k2 = 4 * np.exp(2 / delta**2) * (np.exp(1 / delta**2) + 2) * np.cosh(2 * gamma / delta)
    k3a = np.exp(2 / delta**2)*np.cosh(4 * gamma / delta)
    k3b = (-3 + 3 * np.exp(2 / delta**2) + 2 * np.exp(3 / delta**2) + np.exp(4 / delta**2))
    denom = (2 * (1 + np.exp(1 / delta**2) * np.cosh(2 * gamma / delta))**2)
    return (3 + k1 + k2 + k3a * k3b ) / denom

print('Kurtosis =', kurtosisJSU(delta, gamma))
# returns Kurtosis = 29.84891519423454

The high kurtosis indeed shows the fitted distribution is quite fat-tailed.

4.2 Density and QQ plot

To get a better visual feel for the quality of the fit of JSU to the empirical return data, we compare the empirical densities to the JSU densities.

# plot densitities
x = np.linspace(-0.05, 0.05, 1000)
fig, ax = plt.subplots(figsize = (8, 5), nrows = 2)
ax[0].plot(x, johnsonsu.pdf(x, loc = xi, scale = lbda, a = gamma, b=delta), color = 'red')
returns.plot(kind='hist', ax=ax[0], density=True, bins = 100,
              color='lightgreen', edgecolor='black', alpha = 0.5, histtype = 'bar')

ax[0].set_xlim(left = min(x), right = max(x))
ax[0].grid(linestyle = ':')
ax[0].legend(['JSU density', 'empirical density'])
ax[0].set_title('Densities: JSU vs. Empirical Distribution')

# QQ plot
probplot(returns, dist='johnsonsu', sparams=[gamma, delta, xi, lbda], plot=ax[1])
ax[1].set_title("QQ Plot: JSU vs. Empirical Distribution")
ax[1].set_xlabel("Theoretical Quantiles (Johnson SU)")
ax[1].set_ylabel("Sample Quantiles")
ax[1].grid(linestyle = ':')

plt.tight_layout()

Figure 4.1 shows the quality of the fit of JSU to the empirical data. The fit is excellent, including the fat tails. The QQ plot is nearly a flat line across the entire range of return values, confirming even the extreme quantiles are well captured by the JSU.

(image)

Figure 4.1: Comparison of JSU-fitted distribution and empirical distribution of 1-day S&P500 returns. Densities and QQ plot.
4.3 Computation of extreme quantiles (VaR)

In this short block, 99.9% VaR is computed by picking an extreme quantile. It is easy to see that even an extreme quantile in the JSU is not far from the empirical quantile, proving its appropriateness for market risk computations.

# show some extreme quantiles (e.g. for 99.9% VaR)
jsu_quantile = johnsonsu.ppf(1-0.999, loc = xi, scale = lbda, a = gamma, b=delta)
empirical_quantile = returns.quantile(1-0.999)

print('empirical quantile = ',empirical_quantile)
print('JSU quantile = ',jsu_quantile)

# prints
# empirical quantile = -0.07600483438031827
# JSU quantile = -0.08066790043579355

References

  • Alexander, Carol (Jan. 2009). Market risk analysis IV. en. The Wiley Finance Series. Chichester, England: John Wiley & Sons.