from pytz import timezone
import matplotlib.pyplot as plt
import pandas as pd
# get minute bar price & volume data for SPY & SHY & compute dollar volume
# assumption is that empty bars can be filled with zeros, corresponding to no trading volume
price = get_pricing(['SPY','SHY'],start_date='2019-01-01',end_date='2020-04-10',fields='price',frequency='minute')
volume = get_pricing(['SPY','SHY'],start_date='2019-01-01',end_date='2020-04-10',fields='volume',frequency='minute').fillna(0)
data = price*volume
data.tail(3)
# add time & date columns to the data, for pivot table
data['time'] = data.index.tz_convert(timezone('US/Eastern')).time
data['date'] = data.index.date
data.tail(3)
# on a rolling basis, compute the difference in dollar volume z-scores using a minutely trailing window
# credit to Quantopian user Michael Van Kleeck for this efficient code
# ref.: https://www.quantopian.com/posts/modified-heatmap-based-on-grant-kiehnes-example
WINDOW = 260*390
dollar_volumes = data.iloc[:, 0:2]
means = dollar_volumes.apply(lambda x: pd.rolling_mean(x, window=WINDOW))
sds = dollar_volumes.apply(lambda x: pd.rolling_std(x, window=WINDOW))
zs = ((dollar_volumes - means) / sds)
data['z_diff'] = zs.iloc[:, 1] - zs.iloc[:, 0] # DV_SHY - DV_SPY (where DV is the z-score normalized dollar volume)
data.tail(3)
# apply a pivot table, with trading day along the vertical & trading time along the horizontal
# fill empty minutes with zeros
ht_map = pd.pivot_table(data.dropna(),'z_diff',index=data['date'], columns=data['time'],fill_value=0)
ht_map.head(3)
# plot heat map of z-score difference
# lighter color means z_diff > 0 (DV_SHY > DV_SPY) & darker color mean z_diff < 0 (DV_SHY < DV_SPY)
# see http://matplotlib.org/examples/color/colormaps_reference.html to switch colormap
plt.imshow(ht_map,cmap='jet',aspect=5)
plt.grid(False)
plt.colorbar()
plt.clim(ht_map.min().min(),ht_map.max().max())
plt.title('SPY & SHY z-score-normalized minutely dollar volume difference, ~2020-present')
plt.xlabel('trading minute')
plt.ylabel('trading day')