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.