0
votes

I have minute by minute a panda dataframe df. I'm looking to apply weighting to Return and compute a rolling weighted standard deviation, with window = 10. I can calculate non-weighted std, annualized with:

df_spy['10mVol'] = df_spy['Return'].rolling(center=False,window=10).std()*(1440*252)**(0.5)*100

There is another question asking for weighted std in Numpy, but i'm curious on the rolling weighted stdev. (Weighted standard deviation in NumPy?)

The formula for calculating weighted standard deviation is: https://math.stackexchange.com/questions/320441/standard-deviation-of-the-weighted-mean

weighting   Midpoint   Return      10mVol   Weighted
0.2         215.6700    NaN         NaN      NaN
0.8         215.8400    -0.000788   NaN     -0.000630
0.8         216.0600    -0.001019   NaN     -0.000815

Thanks for helping

1

1 Answers

1
votes

As far as I understand, the chained function after the rolling method is a function that takes an array and gives a number. That function is calculated for each window. So, if we have a function that calculates the weighted-std, we can use it with a lambda function to get the rolling-weighted-std. Here is my take. (I hope I didn't make a mistake with weighted-std calculation you provided)

import pandas as pd
import numpy as np


def weighted_std(values, weights):
    # For simplicity, assume len(values) == len(weights)
    # assume all weights > 0
    sum_of_weights = np.sum(weights)
    weighted_average = np.sum(values * weights) / sum_of_weights
    n = len(weights)
    numerator = np.sum(n * weights * (values - weighted_average) ** 2.0)
    denominator = (n - 1) * sum_of_weights
    weighted_std = np.sqrt(numerator / denominator)
    return weighted_std


def rolling_std(s, weights):
    window_size = len(weights)
    return s.rolling(center=False, window=window_size).apply(lambda win: weighted_std(win, weights))

s = pd.Series(np.random.random([10]))  # generate random data
w = np.array([1., 3., 5.])  # choose weights
print(s.values)
print(rolling_std(s, w).values)

Example output:

[ 0.08101966  0.57133241  0.29491028  0.25139964  0.26151065  0.45768199
  0.94459935  0.21534497  0.35999294  0.60242746]
[        nan         nan  0.19701963  0.11936639  0.01539041  0.12097725
  0.33346742  0.40784167  0.25884732  0.17709334]

Here lambda win: weighted_std(win, weights) is a function that takes an array as an input and returns a number.