Passer au contenu
Tous les documents de la bibliothèque

Mesurer l’instabilité des estimations par statistiques glissantes

Notebook Cours Quantopian

Résumé

Ce cours présente les estimations de paramètres comme des quantités incertaines, susceptibles de changer avec de nouvelles observations ou selon la fenêtre d’échantillonnage. Il propose de mesurer cette instabilité en estimant une statistique sur plusieurs sous-ensembles de données et en examinant les variations des estimations obtenues. Des exemples utilisant des données normales et bimodales simulées montrent qu’une moyenne peut masquer la forme d’une distribution, et présentent le test de Jarque-Bera comme vérification de la normalité.

Les exemples financiers appliquent des fenêtres glissantes aux rendements et aux prix, notamment un ratio de Sharpe glissant, des moyennes mobiles, des écarts-types et des bandes de Bollinger. La variation des estimations du ratio de Sharpe illustre pourquoi une valeur unique peut être un faible indicateur des performances futures. Le cours précise également que les écarts-types seuls ne donnent pas de probabilités précises pour les observations futures sans hypothèse sur la distribution sous-jacente. La variabilité glissante aide à décrire l’incertitude, mais ne peut tenir compte de nouvelles conditions hors de l’échantillon observé ni garantir la précision des prévisions.

Idées clés

  • Un paramètre calculé à partir de données historiques est une estimation dont il convient d’évaluer l’incertitude.
  • Comparer les estimations entre plusieurs sous-ensembles de données fournit une mesure pratique de l’instabilité.
  • Une moyenne unique peut masquer des caractéristiques importantes, comme une distribution multimodale.
  • Les ratios de Sharpe glissants et les statistiques de prix révèlent l’évolution des estimations dans le temps.
  • L’écart-type décrit la dispersion, mais ne permet pas d’inférer des probabilités précises sans hypothèses sur la distribution.

Étiquettes

Texte intégral
# Instability of Parameter Estimates


<a href="https://www.quantrocket.com"><img alt="QuantRocket logo" src="https://www.quantrocket.com/assets/img/notebook-header-logo.png"></a>

© Copyright Quantopian Inc.<br>
© Modifications Copyright QuantRocket LLC<br>
Licensed under the [Creative Commons Attribution 4.0](https://creativecommons.org/licenses/by/4.0/legalcode).<br>
<a href="https://www.quantrocket.com/disclaimer/">Disclaimer</a>

***
[Quant Finance Lectures (adapted Quantopian Lectures)](Introduction.ipynb) › Lecture 10 - Instability of Estimates
***

# Instability of Parameter Estimates

By Evgenia "Jenny" Nitishinskaya and Delaney Granizo-Mackenzie. Algorithms by David Edwards.

<a href="https://youtu.be/2pbu3_6lF40?t=164" target="_blank">Quantopian video for this lecture ↗</a>

## Parameters

A parameter is anything that a model uses to constrain its predictions. Commonly, a parameter is a quantity that helps to describe a data set or a distribution. For example, the mean of a normal distribution is a parameter; in fact, we say that a normal distribution is <i>parameterized</i> by its mean and variance. If we take the mean of a set of samples drawn from the normal distribution, we get an estimate of the mean of the distribution. Similarly, the mean of a set of observations is an estimate of the parameter of the underlying distribution (which is often assumed to be normal). Other parameters include the median, the correlation coefficient to another series, the standard deviation, and every other measurement of a data set.

## You Never Know, You Only Estimate

When you take the mean of a data set, you do not know the mean. You have estimated the mean as best you can from the data you have. The estimate can be off. This is true of any parameter you estimate. To actually understand what is going on you need to determine how good your estimate is by looking at its stability/standard error/confidence intervals.

## Instability of estimates

Whenever we consider a set of observations, our calculation of a parameter can only be an estimate. It will change as we take more measurements or as time passes and we get new observations. We can quantify the uncertainty in our estimate by looking at how the parameter changes as we look at different subsets of the data. For instance, standard deviation describes how different the mean of a set is from the mean of each observation, that is, from each observation itself. In financial applications, data often comes in time series. In this case, we can estimate a parameter at different points in time; say, for the previous 30 days. By looking at how much this moving estimate fluctuates as we change our time window, we can compute the instability of the estimated parameter.

```python
# We'll be doing some examples, so let's import the libraries we'll need
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
```

## Example: mean and standard deviation

First, let's take a look at some samples from a normal distribution. We know that the mean of the distribution is 0 and the standard deviation is 1; but if we measure the parameters from our observations, we will get only approximately 0 and approximately 1. We can see how these estimates change as we take more and more samples:

```python
# Set a seed so we can play with the data without generating new random numbers every time
np.random.seed(123)

normal = np.random.randn(500)
print(np.mean(normal[:10]))
print(np.mean(normal[:100]))
print(np.mean(normal[:250]))
print(np.mean(normal))

# Plot a stacked histogram of the data
plt.hist([normal[:10], normal[10:100], normal[100:250], normal], density=1, histtype='bar', stacked=True);
plt.ylabel('Frequency')
plt.xlabel('Value');
```

```python
print(np.std(normal[:10]))
print(np.std(normal[:100]))
print(np.std(normal[:250]))
print(np.std(normal))
```

Notice that, although the probability of getting closer to 0 and 1 for the mean and standard deviation, respectively, increases with the number of samples, we do not always get better estimates by taking more data points. Whatever our expectation is, we can always get a different result, and our goal is often to compute the probability that the result is significantly different than expected.

With time series data, we usually care only about contiguous subsets of the data. The moving average (also called running or rolling) assigns the mean of the previous $n$ data points to each point in time. Below, we compute the 90-day moving average of a stock price and plot it to see how it changes. There is no result in the beginning because we first have to accumulate at least 90 days of data.

## Example: Non-Normal Underlying Distribution

What happens if the underlying data isn't normal? A mean will be very deceptive. Because of this it's important to test for normality of your data. We'll use a Jarque-Bera test as an example.

```python
#Generate some data from a bi-modal distribution
def bimodal(n):
    X = np.zeros((n))
    for i in range(n):
        if np.random.binomial(1, 0.5) == 0:
            X[i] = np.random.normal(-5, 1)
        else:
            X[i] =  np.random.normal(5, 1)
    return X
            
X = bimodal(1000)

#Let's see how it looks
plt.hist(X, bins=50)
plt.ylabel('Frequency')
plt.xlabel('Value')
print('mean:', np.mean(X))
print('standard deviation:', np.std(X))
```

Sure enough, the mean is incredibly non-informative about what is going on in the data. We have collapsed all of our data into a single estimate, and lost of a lot of information doing so. This is what the distribution should look like if our hypothesis that it is normally distributed is correct.

```python
mu = np.mean(X)
sigma = np.std(X)

N = np.random.normal(mu, sigma, 1000)

plt.hist(N, bins=50)
plt.ylabel('Frequency')
plt.xlabel('Value');
```

We'll test our data using the Jarque-Bera test to see if it's normal. A significant p-value indicates non-normality.

```python
from statsmodels.stats.stattools import jarque_bera

jarque_bera(X)
```

Sure enough the value is < 0.05 and we say that X is not normal. This saves us from accidentally making horrible predictions.

## Example: Sharpe ratio

One statistic often used to describe the performance of assets and portfolios is the Sharpe ratio, which measures the additional return per unit additional risk achieved by a portfolio, relative to a risk-free source of return such as Treasury bills or cash:
$$R = \frac{E[r_a - r_b]}{\sqrt{Var(r_a - r_b)}}$$

where $r_a$ is the returns on our asset and $r_b$ is the risk-free rate of return. As with mean and standard deviation, we can compute a rolling Sharpe ratio to see how our estimate changes through time.

```python
from quantrocket.master import get_securities
from quantrocket import get_prices

def sharpe_ratio(asset, riskfree=0):
    return np.mean(asset - riskfree)/np.std(asset - riskfree)

aapl = get_securities(symbols='AAPL', vendors='usstock').index[0]

start = '2012-01-01'
end = '2015-01-01'

closes = get_prices('usstock-free-1min', data_frequency='daily', sids=aapl, fields='Close', start_date=start, end_date=end).loc['Close']
aapl_closes = closes[aapl]
returns = aapl_closes.pct_change()[1:] # Get the returns on the asset

# Compute the running Sharpe ratio
running_sharpe = returns.rolling(90).apply(sharpe_ratio) 

# Plot running Sharpe ratio up to 100 days before the end of the data set
_, ax1 = plt.subplots()
ax1.plot(running_sharpe[90:-100]);
plt.xlabel('Date')
plt.ylabel('Sharpe Ratio');
```

The Sharpe ratio looks rather volatile, and it's clear that just reporting it as a single value will not be very helpful for predicting future values. Instead, we can compute the mean and standard deviation of the data above, and then see if it helps us predict the Sharpe ratio for the next 100 days.

```python
# Compute the mean and std of the running Sharpe ratios up to 100 days before the end
mean_rs = np.mean(running_sharpe[90:-100])
std_rs = np.std(running_sharpe[90:-100])

# Plot running Sharpe ratio
_, ax2 = plt.subplots()
ax2.plot(running_sharpe[90:])

# Plot its mean and the +/- 1 standard deviation lines
ax2.axhline(mean_rs)
ax2.axhline(mean_rs + std_rs, linestyle='--')
ax2.axhline(mean_rs - std_rs, linestyle='--')

# Indicate where we computed the mean and standard deviations
# Everything after this is 'out of sample' which we are comparing with the estimated mean and std
ax2.axvline(returns.index[-100], color='pink');
plt.xlabel('Date')
plt.ylabel('Sharpe Ratio')
plt.legend(['Sharpe Ratio', 'Mean', '+/- 1 Standard Deviation'])

print('Mean of running Sharpe ratio:', mean_rs)
print('std of running Sharpe ratio:', std_rs)
```

The standard deviation in this case is about a quarter of the range, so this data is extremely volatile. Taking this into account when looking ahead gave a better prediction than just using the mean, although we still observed data more than one standard deviation away. We could also compute the rolling mean of the Sharpe ratio to try and follow trends; but in that case, too, we should keep in mind the standard deviation.

## Example: Moving Average

Let's say you take the average with a lookback window; how would you determine the standard error on that estimate? Let's start with an example showing a 90-day moving average.

```python
# Compute the rolling mean for each day
mu = aapl_closes.rolling(window=90).mean()

# Plot pricing data
_, ax1 = plt.subplots()
ax1.plot(aapl_closes) 
plt.ylabel('Price')
plt.xlabel('Date')

# Plot rolling mean
ax1.plot(mu);
plt.legend(['Price','Rolling Average']);
```

This lets us see the instability/standard error of the mean, and helps anticipate future variability in the data. We can quantify this variability by computing the mean and standard deviation of the rolling mean.

```python
print('Mean of rolling mean:', np.mean(mu))
print('std of rolling mean:', np.std(mu))
```

In fact, the standard deviation, which we use to quantify variability, is itself variable. Below we plot the rolling standard deviation (for a 90-day window), and compute <i>its</i> mean and standard deviation.

```python
# Compute rolling standard deviation
std = aapl_closes.rolling(window=90).std()

# Plot rolling std
_, ax2 = plt.subplots()
ax2.plot(std)
plt.ylabel('Standard Deviation')
plt.xlabel('Date')

print('Mean of rolling std:', np.mean(std))
print('std of rolling std:', np.std(std))
```

To see what this changing standard deviation means for our data set, let's plot the data again along with the Bollinger bands: the rolling mean, one rolling standard deviation (of the data) above the mean, and one standard deviation below.

Note that although standard deviations give us more information about the spread of the data, we cannot assign precise probabilities to our expectations for future observations without assuming a particular distribution for the underlying process.

```python
# Plot original data
_, ax3 = plt.subplots()
ax3.plot(aapl_closes)

# Plot Bollinger bands
ax3.plot(mu)
ax3.plot(mu + std)
ax3.plot(mu - std);
plt.ylabel('Price')
plt.xlabel('Date')
plt.legend(['Price', 'Moving Average', 'Moving Average +1 Std', 'Moving Average -1 Std'])
```

## Conclusion

Whenever we compute a parameter for a data set, we should also compute its volatility. Otherwise, we do not know whether or not we should expect new data points to be aligned with this parameter. A good way of computing volatility is dividing the data into subsets and estimating the parameter from each one, then finding the variability among the results. There may still be outside factors which are introduced after our sample period and which we cannot predict. However, the instability analysis and testing for standard error is still very useful for telling us how much we should distrust our estimates.

---

**Next Lecture:** [Random Variables](Lecture11-Random-Variables.ipynb) 

[Back to Introduction](Introduction.ipynb) 

---

*This presentation is for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation for any security; nor does it constitute an offer to provide investment advisory or other services by QuantRocket LLC ("QuantRocket"). Nothing contained herein constitutes investment advice or offers any opinion with respect to the suitability of any security, and any views expressed herein should not be taken as advice to buy, sell, or hold any security or as an endorsement of any security or company.  In preparing the information contained herein, the authors have not taken into account the investment needs, objectives, and financial circumstances of any particular investor. Any views expressed and data illustrated herein were prepared based upon information believed to be reliable at the time of publication. QuantRocket makes no guarantees as to their accuracy or completeness. All information is subject to change and may quickly become unreliable for various reasons, including changes in market conditions or economic circumstances.*
![notebook output](figures/p1_1.png)
![notebook output](figures/p1_2.png)
![notebook output](figures/p1_3.png)
![notebook output](figures/p1_4.png)
![notebook output](figures/p1_5.png)
![notebook output](figures/p1_6.png)
![notebook output](figures/p1_7.png)
![notebook output](figures/p1_8.png)

Reproduit dans son intégralité avec attribution, conformément à la licence de la source. Licence: CC BY 4.0

Ce résumé a été rédigé par l’agent de recherche de Stratmill à partir de la source originale ; il n’en est pas une copie.