How to compute volatility (standard deviation) in rolling window in Pandas
Typically, [finance-type] people quote volatility in annualized terms of percent changes in price.
Assuming you have daily prices in a dataframe df
and there are 252 trading days in a year, something like the following is probably what you want:
df.pct_change().rolling(window_size).std()*(252**0.5)
"Volatility" is ambiguous even in a financial sense. The most commonly referenced type of volatility is realized volatility which is the square root of realized variance. The key differences from the standard deviation of returns are:
- Log returns (not simple returns) are used
- The figure is annualized (usually assuming between 252 and 260 trading days per year)
- In the case Variance Swaps, log returns are not demeaned
There are a variety of methods for computing realized volatility; however, I have implemented the two most common below:
import numpy as np
window = 21 # trading days in rolling window
dpy = 252 # trading days per year
ann_factor = days_per_year / window
df['log_rtn'] = np.log(df['price']).diff()
# Var Swap (returns are not demeaned)
df['real_var'] = np.square(df['log_rtn']).rolling(window).sum() * ann_factor
df['real_vol'] = np.sqrt(df['real_var'])
# Classical (returns are demeaned, dof=1)
df['real_var'] = df['log_rtn'].rolling(window).var() * ann_factor
df['real_vol'] = np.sqrt(df['real_var'])
It looks like you are looking for Series.rolling
. You can apply the std
calculations to the resulting object:
roller = Ser.rolling(w)
volList = roller.std(ddof=0)
If you don't plan on using the rolling window object again, you can write a one-liner:
volList = Ser.rolling(w).std(ddof=0)
Keep in mind that ddof=0
is necessary in this case because the normalization of the standard deviation is by len(Ser)-ddof
, and that ddof
defaults to 1
in pandas.