This example comes from a request in the forums. The original post can be found here: https://www.quantopian.com/posts/ranking-system-based-on-trading-volume-slash-shares-outstanding
It has also been used as the core pipeline API example. The notebooks below shows how you would compute this pipeline here in a research notebooks.
The original request was:
I am stuck trying to build a stock ranking system with two signals:
from quantopian.pipeline import Pipeline
from quantopian.pipeline import CustomFactor
from quantopian.research import run_pipeline
from quantopian.pipeline.data import morningstar
from quantopian.pipeline.data.builtin import USEquityPricing
Documentation can be found here: https://www.quantopian.com/help#quantopian_pipeline_Pipeline
class Liquidity(CustomFactor):
# Pre-declare inputs and window_length
inputs = [USEquityPricing.volume, morningstar.valuation.shares_outstanding]
window_length = 1
# Compute factor1 value
def compute(self, today, assets, out, volume, shares):
out[:] = volume[-1]/shares[-1]
class Momentum(CustomFactor):
# Pre-declare inputs and window_length
inputs = [USEquityPricing.close]
window_length = 60
# Compute factor2 value
def compute(self, today, assets, out, close):
out[:] = close[-1]/close[0]
class MarketCap(CustomFactor):
# Pre-declare inputs and window_length
inputs = [USEquityPricing.close, morningstar.valuation.shares_outstanding]
window_length = 1
# Compute market cap value
def compute(self, today, assets, out, close, shares):
out[:] = close[-1] * shares[-1]
liquidity = Liquidity()
momentum = Momentum()
mkt_cap = MarketCap()
mkt_cap_rank = mkt_cap.rank(ascending=False)
russell_2000 = (1000 > mkt_cap_rank) & (mkt_cap_rank <= 3000)
liquidity_rank = liquidity.rank(mask=russell_2000, ascending=False)
momentum_rank = momentum.rank(mask=russell_2000, ascending=False)
combo_raw = (liquidity_rank+momentum_rank)/2
combo_rank = combo_raw.rank(mask=russell_2000, ascending=True)
pipe = Pipeline()
pipe.add(liquidity, 'liquidity')
pipe.add(momentum, 'momentum')
pipe.add(liquidity_rank, 'liq_rank')
pipe.add(momentum_rank, 'mom_rank')
pipe.add(combo_raw, 'combo_raw')
pipe.add(combo_rank, 'combo_rank')
pipe.set_screen(russell_2000 & (momentum.eq(momentum)))
pipe = Pipeline(
columns={'mkt_cap':mkt_cap,
'momentum':momentum,
'liquidity':liquidity,
'liquidity_rank':liquidity_rank,
'momentum_rank':momentum_rank,
'combo_raw':combo_raw,
'combo_rank':combo_rank
},
screen=(russell_2000 & (momentum.eq(momentum))),
)
pipe.show_graph(format='png')
In research, you must specify a start and end date. The results are a heirarchical dataframe, where the pipeline output for each day is included. The output shows the results that the pipeline would generate in before_trading_start on that day, using the data of the day before. This is different from the backtest, where only the results of the given day are included on any day.
run_pipeline(pipe, start_date='2015-11-01', end_date='2015-11-25')