from quantopian.pipeline.data import Fundamentals
from quantopian.pipeline.data import morningstar
from quantopian.pipeline.factors import AverageDollarVolume
from quantopian.pipeline.factors.morningstar import MarketCap
from quantopian.pipeline.classifiers.morningstar import Sector
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline import Pipeline
from quantopian.research import run_pipeline
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from pandas import DataFrame as df
import time
from quantopian.pipeline.experimental import QTradableStocksUS
# Function used to create a pipeline with the QTradableStocksUS as a screen. The pipeline contains common metrics as columns:
def make_pipeline():
average_day_dv_200 = AverageDollarVolume(window_length=200)
market_cap = Fundamentals.market_cap.latest
price = USEquityPricing.close.latest
volume = USEquityPricing.volume.latest
sector = Sector()
return Pipeline(
columns={
'AverageDollarVolume200': average_day_dv_200,
'MarketCap': market_cap,
'Price': price,
'Volume': volume,
'Sector': sector,
},
screen=QTradableStocksUS()
)
# Pipeline is run over this time range and outputs a dataframe indexed by asset name:
START_DATE = '2003'
END_DATE = '2017-11-01'
start = time.time()
QTU_pipeline = run_pipeline(make_pipeline(), START_DATE, END_DATE, chunksize=252)
print 'Took %s seconds' % (time.time() - start)
#Specific limits applied to the QTradableStocksUS:
#* Market cap over $500M
#* daily dollar volume of $2.5m or more over the trailing 200 days
#* $5 floor
#* 200 days of price and volume
#* Primary/Common share status of all assets
#* Exclusion of ADRs and LPs
# Display constituent stocks of QTradableStocksUS:
QTU_pipeline
## The QTradableStocksUS universe generally contains a greater number of assets than previous iterations of the tradable universe.
## The resulting summary table displays the mean, std, min-max of daily median in addition to number of assets in this universe:
daily_constituent_count = QTU_pipeline.groupby(level=0).sum()
QTU_pipeline.groupby(level=0).median().describe()
#Displays the number of assets in universe every day, which mirrors major economic events throughout the time period.
dates = QTU_pipeline.index.levels[0]
grouped = QTU_pipeline.groupby(level=0).count()
num_securities = grouped['AverageDollarVolume200'].values
plt.plot(dates, num_securities)
plt.title('Number of securities in tradeable universe')
#Number of assets in universe broken down by sector type:
colors = ['b', 'g', 'r', 'c', 'm', 'y', 'orange', 'gray', 'maroon', 'olive', 'navy']
for (sector, name), color in zip(Sector.SECTOR_NAMES.iteritems(), colors):
sector_result = QTU_pipeline.loc[QTU_pipeline['Sector'] == sector]
grouped = sector_result.groupby(level=0).count()
num_securities = grouped['AverageDollarVolume200'].values
plt.plot(dates, num_securities, label=name, color=color)
plt.legend(bbox_to_anchor=(1.3, 1))
plt.title('Number of securities per sector in tradeable universe')
#Number of assets added to universe is usually slightly greater than number of assets removed from universe.
assets_each_day = [set(df.loc[date].index) for date, df in QTU_pipeline.groupby(level=0)]
a = []
for i in range(1, len(assets_each_day)):
a.append(assets_each_day[i] - assets_each_day[i-1])
#Record the number of new assets to universe each day:
new_assets_each_day = pd.Series(a, dates[1:])
num_new_assets_each_day = new_assets_each_day.apply(lambda x: len(x))
b = []
for i in range(1, len(assets_each_day)):
b.append(assets_each_day[i-1] - assets_each_day[i])
#Record the number of assets removed from universe each day:
removed_assets_each_day = pd.Series(b, dates[1:])
num_removed_assets_each_day = removed_assets_each_day.apply(lambda x: len(x))
plt.plot(num_new_assets_each_day)
plt.title('Number of new securities per day in tradeable universe')
plt.plot(num_removed_assets_each_day)
plt.title('Number of removed securities per day in tradeable universe')