Johnson SU distribution, and VaR
This version: 2024-06-13
First version: 2024-06-13
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
\(\seteqnumber{0}{1.}{0}\)\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
\(\seteqnumber{0}{1.}{0}\)\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
\(\seteqnumber{0}{1.}{0}\)\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
\(\seteqnumber{0}{2.}{0}\)\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.