Spx had a rather long streak of low volatility. There is no predictive value or signal here, i just wanted to eyeball how long the low vol streak lasted and how it compared to other low vol streaks.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import datetime as dt
%matplotlib inline
plt.style.use("seaborn-whitegrid")
plt.rcParams.update({"figure.figsize":(16, 9), "grid.alpha":0.21})
# Spx since 1950’s
# https://finance.yahoo.com/quote/^GSPC/history?period1=-630986400&period2=1516572000&interval=1d&filter=history&frequency=1d
spx = pd.read_csv("../Data/^GSPC.csv", index_col="Date")
spx.index = pd.to_datetime(spx.index, format="%Y-%m-%d")
spx.index = spx.index.map(lambda x: x.strftime("%Y-%m-%d"))
spx["pct"] = spx["Close"].pct_change()
spx.dropna(inplace=True)
Setting up the streak instances count and index
spx_reset = spx.copy().reset_index()
instances = pd.DataFrame(index=spx_reset.index)
vol_threshold = 0.01
start_index = None
for index, row in spx_reset.iterrows():
abs_ret = abs(row["pct"])
abs_ret_yest = abs(spx_reset["pct"].iloc[index-1])
if abs_ret <= vol_threshold and abs_ret_yest > vol_threshold:
start_index = index-1
if abs_ret > vol_threshold and abs_ret_yest <= vol_threshold:
rets = spx_reset["pct"].loc[start_index:index]
rets.iloc[:1] = 0
col_name = str("{} to {}").format(spx.index[start_index], spx.index[index])
instances[col_name] = rets.reset_index(drop=True)
start_index = None
instances.dropna(inplace=True, how="all")
Setting up the latest low vol streak and plotting everything
curr_instance = instances.iloc[:, -4].dropna()
latest_instance_range = instances.columns[-4]
for col, vals in instances.iteritems():
rets = vals.dropna()
if len(rets) > 42:
plt.plot(rets.cumsum(), color="#555555", alpha=0.42, linewidth=1, label="_nolegend_")
if len(rets) > 69:
plt.text(rets.index[-1]+1, rets.cumsum().iloc[-1], col)
plt.plot(curr_instance.cumsum(), color="crimson", label="_nolegend_")
plt.text(curr_instance.index[-1]+1, curr_instance.cumsum().iloc[-1], latest_instance_range)
plt.title("Spx low volatility streaks (daily close to close change below +/- {}%) of longer than 42 days, since 1950".format(vol_threshold*100), fontsize=10)
plt.xlabel("# Of trading days in low vol streak")
plt.ylabel("Streak return")
plt.legend(loc="center right")
plt.xlim(0, 200)
(0, 200)
Thanks your time