Skew and kurtosis: A quick guide for great risk management

Skew and kurtosis: A quick guide for great risk management
A quote I say at least weekly: No risk metric paints the whole picture.
This means that you need many different metrics to really understand the dynamics of a trading strategy.
While volatility (standard deviation) is commonly used, it really doesn't show the complete risk picture.
That's why we'll explore skewness and kurtosis, risk metrics often overlooked in traditional analysis.
By reading today’s newsletter, you’ll get Python code to compute skew and kurtosis in the context of strategy performance.
We’ll use SPY for the example, but you can easily extend the analysis to your strategy’s returns.
Let's go!
Skew and kurtosis: A quick guide for great risk management
Skewness and kurtosis give us a unique lens into investment risk. Unlike standard deviation, they let us quantify the asymmetry and tail risk of financial returns. Understanding these metrics can let us get a better idea of how strategies might perform in the future.
These concepts come to life when assessing returns distributions.
Financial professionals look at skew and kurtosis to anticipate market volatility. They use these metrics to gauge potential market extremes and adapt risk strategies accordingly. Stress testing with skewness and kurtosis can help build more resilient portfolios.
Let's see how it works with Python.
Imports and set up
These libraries help us fetch financial data, manipulate it, and visualize the results.
import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
We'll get SPY data for the last 5 years and calculate its daily returns.
spy = yf.Ticker("SPY")
data = spy.history(period="5y")
returns = data['Close'].pct_change().dropna()
We use yfinance to download SPY stock data for the past 5 years. Then, we calculate the daily percentage change in closing prices. This gives us the daily returns. We remove any missing values to ensure our data is clean and ready for analysis.
Calculate distribution statistics
Now we'll compute the skewness and kurtosis of the returns. It’s simply with Pandas.
skewness = returns.skew()
kurtosis = returns.kurtosis()
print(f"Skewness: {skewness:.4f}")
print(f"Kurtosis: {kurtosis:.4f}")
We calculate two important measures of the returns distribution. Skewness tells us about the symmetry of the distribution. Kurtosis gives us information about the tails of the distribution. These values help us understand how the returns are distributed compared to a normal distribution.
As of writing the skew was slightly positive indicating more positive returns than negative ones. This makes sense since SPY has increased in value over the last five years.
Kurtosis is 7.7 which shows there are “fat tails.” This means there are turns that fall outside the 99.6% of returns typically seen within a normal distribution.
Putting skew and kurtosis paints the picture that we have positive fat tails. We can visually inspect this through a histogram.
plt.figure(figsize=(10, 6))
returns.hist(bins=50, density=True, alpha=0.7)
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 100)
p = stats.norm.pdf(x, returns.mean(), returns.std())
plt.plot(x, p, 'k', linewidth=2)
plt.title("SPY Daily Returns Distribution")
plt.xlabel("Returns")
plt.ylabel("Frequency")
plt.show()
We create a histogram of the returns to visually represent their distribution.

We set the number of bins to 50 for a detailed view. We also calculate and plot a normal distribution curve using the mean and standard deviation of our returns. This allows us to compare our actual returns distribution to what a normal distribution would look like.
Your next steps
This is a simple example using an ETF. Replace the return stream of SPY with your portfolio returns. If there is negative skew (which is common), it’s worth spending time investigating which asset led to the fat tails. Can you better protect against these extreme downside returns?
