Skip to content
All library documents

Daily Volatility Estimates and the Importance of Return Alignment

Article Quant Q&A · Author: md0101

Summary

The document compares two ways of estimating daily volatility from closing prices: an exponentially weighted standard deviation of ordinary percentage changes, and a method from a financial machine-learning text that searches for a prior observation near one calendar day earlier. The question arises because the resulting volatility series differ, especially when trading dates do not occur every calendar day.

The accepted answer traces the discrepancy to the date alignment in the snippet. Its search procedure can pair a Wednesday close with Monday’s close, producing a multi-day return instead of the adjacent trading-day return. A small weekday price example shows the resulting return is larger than the day-on-day calculation. The answer recommends percentage changes between successive observations as a simpler alternative, while noting that time-series filtering and lagging choices still affect the data. It does not investigate the book author’s intended rationale or establish which sampling convention is appropriate for every market or volatility application.

Key ideas

  • The volatility estimate depends on how returns are aligned to dates.
  • A calendar-day lookup can span multiple trading days when markets are closed.
  • Multi-day returns can differ materially from adjacent-observation returns.
  • Successive-observation percentage changes offer a simpler daily-return calculation.
  • Sampling and filtering choices should match the intended volatility measure.

Tags

Full text
# Advances in financial machine learning (Marcos López de Prado): explanation of snippet 3.1


# Advances in financial machine learning (Marcos López de Prado): explanation of snippet 3.1












I have been reading AFML ( Marcos López de Prado ) and I am having trouble understanding snippet 3.1 which provides the following code:

```
def getDailyVol(close,span0=100):
    # daily vol, reindexed to close
    df0=close.index.searchsorted(close.index-pd.Timedelta(days=1))
    df0=df0[df0>0]
    df0=pd.Series(close.index[df0-1], index=close.index[close.shape[0]-df0.shape[0]:])
    df0=close.loc[df0.index]/close.loc[df0.values].values-1 # daily returns
    df0=df0.ewm(span=span0).std()
    return df0
```

Could anyone explain what is wrong with computing daily volatility as:

```
span0 = 100
close.pct_change().ewm(span = span0).std()
```

The results in the two methods of computation differ as the previous date used in `getDailyVol` is different from the day before.

For E-Mini S&P 500 Jun 23, I obtain (blue curve obtained using snippet 3.1 vs. orange curve obtained using `pct_change`):

Could anyone please explain?

Thank you!

## Answer by oronimbus (score 6, accepted)

https://quant.stackexchange.com/a/75770

I can't comment on why MLDP is calculating returns this way (perhaps there is a reason explained in the book, which I don't have). However, from a pure code point-of-view he seems to be calculating returns (incorrectly) over a 3 day period. For example, for end date 2000-01-05 (Wednesday) he takes the start date 2000-01-03 (Monday).

Take some dummy data:

```
close = pd.DataFrame([100, 101, 104, 103, 101], index=pd.date_range("2000-01-03", "2000-01-07"))
```

Now if you print out `df0` before he calculates the daily returns, you get the following:

```
2000-01-05   2000-01-03
2000-01-06   2000-01-04
2000-01-07   2000-01-05
```

This doesn't look right, the return on 2000-01-05 should just be the value from that day vs the previous day. He calculates 104/100-1 which is 4% vs the actual day-on-day return of 104/101-1 of 2.9%.

I'd stick to using the pandas `pct_change()`, it's not only a lot less convoluted but also allows easy chaining of commands (e.g. if you want to filter out weekends, lag the series by a day or remove zero-values in your time series).

As a final side note, although I appreciate a lot of his work, his Python snippets should perhaps best be rewritten to match current best practices and code standards.

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.