-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvolatility_adjustment.py
67 lines (50 loc) · 2.83 KB
/
volatility_adjustment.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import time
import urllib.request
import io
import numpy as np
import pandas as pd
from scipy.stats import norm, shapiro, ks_1samp
import matplotlib.pyplot as plt
days_back = 365 * 9
secs_in_one_day = 86400
_now = int(time.time())
print("The period from ", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(_now- secs_in_one_day * days_back)), " to ", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(_now)))
target_url_spx = 'https://query2.finance.yahoo.com/v7/finance/download/^GSPC?period1=' + str(_now - secs_in_one_day * days_back) + '&period2=' + str(_now) + '&interval=1d&events=history&crumb=2MbBGaxDo3l'
target_url_vix = 'https://query2.finance.yahoo.com/v7/finance/download/^VIX?period1=' + str(_now - secs_in_one_day * days_back) + '&period2=' + str(_now) + '&interval=1d&events=history&crumb=2MbBGaxDo3l'
with urllib.request.urlopen(target_url_spx) as response:
csv1 = response.read()
with urllib.request.urlopen(target_url_vix) as response:
csv2 = response.read()
spx = pd.read_csv(io.BytesIO(csv1), encoding='utf8', index_col='Date')
vix = pd.read_csv(io.BytesIO(csv2), encoding='utf8', index_col='Date')
spx_close = spx.loc[:,'Close']
spx_close = np.log(spx_close).diff().dropna()
vix_close = vix.loc[:,'Close'][1:]
# Normalization without VIX-adjustment
spx_close_unadjusted = (spx_close - spx_close.mean()) / spx_close.std()
spx_close_unadjusted = spx_close_unadjusted.sort_values()
# Normalization with VIX-adjustment
df = spx_close / vix_close
df = (df - df.mean()) / df.std()
df_sorted = df.sort_values()
for x in (1.0, 1.3, 1.7, 2.0, 2.3, 2.7, 3.0, 3.3, 3.7, 4.0):
print("The actual estimated probability of deviation beyond %3.1f standard deviations is %10.8f vs. the theoretical probability of %10.8f" % (x, (sum(df > x) / df.shape[0] + sum(df < -x) / df.shape[0])/2.0, 1.0 - norm.cdf(x)))
print("Shapiro test: ", shapiro(df_sorted))
print("Kolmogorov-Smirnov test: ", ks_1samp(df_sorted, norm.cdf))
normal_quantiles = norm.cdf(df_sorted)
real_quantiles = np.linspace(0.0, 1.0, df_sorted.shape[0])
plt.plot(spx_close_unadjusted, real_quantiles, color='#e3526e')
plt.plot(df_sorted, normal_quantiles, color='#3e084c')
plt.plot(df_sorted, real_quantiles, color='#025d93')
plt.legend(["Unadjusted returns", "Normal", "VIX-adjusted returns"], loc ="lower right")
plt.title('CDFs')
plt.xlabel('Normalized daily S&P 500 log returns')
plt.ylabel('Quantiles')
plt.show()
plt.scatter(norm.ppf(real_quantiles), spx_close_unadjusted, s=16, facecolors='none', edgecolors='#e3526e')
plt.scatter(norm.ppf(real_quantiles), df_sorted, s=16, facecolors='none', edgecolors='#025d93')
plt.plot(norm.ppf(real_quantiles), norm.ppf(real_quantiles), color='#3e084c', linestyle='dashed', linewidth=2)
plt.title('Q-Q plot')
plt.legend(["Normal", "Unadjusted returns", "VIX-adjusted returns"], loc ="lower right")
plt.xlabel('Normal theoretical quantiles')
plt.show()