def make_pipeline(): """ A function to create our dynamic stock selector (pipeline). Documentation on pipeline can be found here: https://www.quantopian.com/help#pipeline-title """ base_universe = Q1500US() sector = Sector() # screen is based off of returns returns = Returns(window_length=2) # check if stock price has good strength, but not necessarily overbought rsi = RSI() price = USEquityPricing.close.latest # creating filter by specifying the type of returns desired top_return_stocks = returns.top(1, mask=base_universe, groupby=sector) pipe = Pipeline( columns={ 'rsi': rsi, 'price': price }, # filter top return stocks, and stocks that are not being overbought # but are not too oversold either screen=base_universe & top_return_stocks & (20 < rsi < 80) # the above is equivalent to: choose stocks from the base universe that have had the top returns in their sectors and have a good RSI value ) return pipe
def make_pipeline(context): # Use a universe of just the top 500 US stocks universe = Q500US() sector = Sector() # Determine if the market is trending up or down. If the market is trending down then just buy bonds. If it is trending up then buy stocks # This is not an optimal solution and will obviously not work in all future market crashes spy_ma_fast_slice = SMA( inputs=[USEquityPricing.close], window_length=context.TF_FAST_LOOKBACK)[context.SPY] spy_ma_slow_slice = SMA( inputs=[USEquityPricing.close], window_length=context.TF_SLOW_LOOKBACK)[context.SPY] spy_ma_fast = SMA(inputs=[spy_ma_fast_slice], window_length=1) spy_ma_slow = SMA(inputs=[spy_ma_slow_slice], window_length=1) # If the 100 moving average crosses the 10 then alter the trend up variable trend_up = spy_ma_fast > spy_ma_slow # Get simple factors to determine "quality" companies cash_return = ms.cash_return.latest.rank(mask=universe) fcf_yield = ms.fcf_yield.latest.rank(mask=universe) roic = ms.roic.latest.rank(mask=universe) rev_growth = ms.revenue_growth.latest.rank(mask=universe) value = (cash_return + fcf_yield).rank(mask=universe) # Find sentiment rank using https://www.quantopian.com/posts/sentiment-as-a-factor sentiment_score = SMA( inputs=[sentiment.sentiment_signal], window_length=30, ) sentiment_score_zscore = sentiment_score.zscore() sentiment_overall_rank = sentiment_score_zscore.rank( mask=universe, groupby=sector).demean() # Combine factors to create one single ranking system quality = roic + rev_growth + value + sentiment_overall_rank # Create a 'momentum' factor by looking back over the last 140 days (20 weeks). momentum = Returns(window_length=context.MOMENTUM_LOOKBACK_DAYS) # Filters for top quality and momentum to use in the selection criteria top_quality = quality.top(context.TOP_ROE_QTY, mask=universe) top_quality_momentum = momentum.top(context.TARGET_SECURITIES, mask=top_quality) # Only return values to be used in the selection criteria by using the screen parameter pipe = Pipeline(columns={ 'trend_up': trend_up, 'top_quality_momentum': top_quality_momentum, }, screen=top_quality_momentum) return pipe
def make_pipeline(): #0. Select top-1500 liquid stocks base_universe = Q1500US() #1. Market Capitalization Filter, select top 1200 out of 1500 market_cap = MarketCap(mask=base_universe) top_market_cap = market_cap.top(1200) #2. B/M Filter, select top 5000 out of all stocks (~8200) btom = morningstar.valuation_ratios.book_value_yield.latest top_btom = btom.top(5000) #3. Interception of 1st and 2nd filters results, on average returns ~1000 stocks top_cap_btom = top_market_cap & top_btom #4. Top Performers filter, select top 100 latest_return_7_1 = Returns( inputs=[USEquityPricing.close], window_length=147, mask=top_cap_btom) / Returns(inputs=[USEquityPricing.close], window_length=21, mask=top_cap_btom) top_performers = latest_return_7_1.top(100) #5. Smoothest Returns filter, select 50 smoothest r_7 = Returns(window_length=21, mask=top_performers) r_6 = (Returns(window_length=42, mask=top_performers) + 1) / (r_7 + 1) - 1 r_5 = (Returns(window_length=63, mask=top_performers) + 1) / ( (r_7 + 1) * (r_6 + 1)) - 1 r_4 = (Returns(window_length=84, mask=top_performers) + 1) / ( (r_7 + 1) * (r_6 + 1) * (r_5 + 1)) - 1 r_3 = (Returns(window_length=105, mask=top_performers) + 1) / ( (r_7 + 1) * (r_6 + 1) * (r_5 + 1) * (r_4 + 1)) - 1 r_2 = (Returns(window_length=126, mask=top_performers) + 1) / ( (r_7 + 1) * (r_6 + 1) * (r_5 + 1) * (r_4 + 1) * (r_3 + 1)) - 1 r_1 = (Returns(window_length=147, mask=top_performers) + 1) / ( (r_7 + 1) * (r_6 + 1) * (r_5 + 1) * (r_4 + 1) * (r_3 + 1) * (r_2 + 1)) - 1 r_mean = (r_1 + r_2 + r_3 + r_4 + r_5 + r_6) / 6.0 varr = ((r_1 - r_mean)**2 + (r_2 - r_mean)**2 + (r_3 - r_mean)**2 + (r_4 - r_mean)**2 + (r_5 - r_mean)**2 + (r_6 - r_mean)** 2) / 6.0 #Sample variance of monthly returns of each stock top_smooth = varr.bottom(50) #6. Screening filter, if (tradeable) then buy this stock tradeable = top_smooth return Pipeline(screen=tradeable, columns={'Tradeable': tradeable})
def make_pipeline(context): # Use a universe of just the top 500 US stocks universe = Q500US() # Get simple factors to determine "quality" companies cash_return_latest = ms.cash_return.latest fcf_yield_latest = ms.fcf_yield.latest roic_latest = ms.roic.latest rev_growth_latest = ms.revenue_growth.latest cash_return = cash_return_latest.rank(mask=universe) fcf_yield = fcf_yield_latest.rank(mask=universe) roic = roic_latest.rank(mask=universe) rev_growth = rev_growth_latest.rank(mask=universe) value = (cash_return + fcf_yield).rank(mask=universe) # Combine factors to create one single ranking system quality = value + roic + rev_growth # Create a 'momentum' factor by looking back over the last 140 days (20 weeks) momentum = Returns(window_length=context.MOMENTUM_LOOKBACK_DAYS) # Filters for top quality and momentum to use in the selection criteria top_quality = quality.top( context.TOP_ROE_QTY, mask=universe) & cash_return_latest.notnull( ) & fcf_yield_latest.notnull() & roic_latest.notnull( ) & rev_growth_latest.notnull() top_quality_momentum = momentum.top(context.TARGET_SECURITIES, mask=top_quality) # Only return values to be used in the selection criteria by using the screen parameter pipe = Pipeline(columns={ 'top_quality_momentum': top_quality_momentum, }, screen=top_quality_momentum) return pipe