def make_pipeline(): universe = QTradableStocksUS() # Variables Seleccionadas Del Dataframe de Fundamentals value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest working_capital = Fundamentals.working_capital.latest restricted_cash = Fundamentals.restricted_cash.latest cash_and_cash_equivalents = Fundamentals.cash_and_cash_equivalents.latest goodwill = Fundamentals.goodwill.latest capital_stock = Fundamentals.capital_stock.latest total_assets = Fundamentals.total_assets.latest common_stock = Fundamentals.common_stock.latest free_cash_flow = Fundamentals.free_cash_flow.latest recent_returns = Returns(window_length=RETURNS_LOOKBACK_DAYS, mask=universe) # Winsorized - Variables (SIN ATIPICOS) value_winsorized = value.winsorize(min_percentile=0.05, max_percentile=0.95) working_capital = working_capital.winsorize(min_percentile=0.05, max_percentile=0.95) restricted_cash = restricted_cash.winsorize(min_percentile=0.05, max_percentile=0.95) cash_and_cash_equivalents = cash_and_cash_equivalents.winsorize( min_percentile=0.05, max_percentile=0.95) goodwill = goodwill.winsorize(min_percentile=0.05, max_percentile=0.95) capital_stock = capital_stock.winsorize(min_percentile=0.05, max_percentile=0.95) total_assets = total_assets.winsorize(min_percentile=0.05, max_percentile=0.95) common_stock = common_stock.winsorize(min_percentile=0.05, max_percentile=0.95) free_cash_flow = free_cash_flow.winsorize(min_percentile=0.05, max_percentile=0.95) recent_returns = recent_returns.winsorize(min_percentile=0.05, max_percentile=0.95) # FACTOR COMBINADO combined_factor = ( value_winsorized.zscore() * 0.05 + working_capital.zscore() * 0.55 + restricted_cash.zscore() * 0.2 + cash_and_cash_equivalents.zscore() * 0.01 + goodwill.zscore() * 0.01 + capital_stock.zscore() * 0.1 + total_assets.zscore() * 0.01 + common_stock.zscore() * 0.01 + free_cash_flow.zscore() * 0.01 + recent_returns.zscore() * 0.05) longs = combined_factor.top(TOTAL_POSITIONS // 2, mask=universe) shorts = combined_factor.bottom(TOTAL_POSITIONS // 2, mask=universe) long_short_screen = (longs | shorts) pipe = Pipeline(columns={ 'longs': longs, 'shorts': shorts, 'combined_factor': combined_factor }, screen=long_short_screen) return pipe
def make_pipeline(): """ A function that creates and returns our pipeline. We break this piece of logic out into its own function to make it easier to test and modify in isolation. In particular, this function can be copy/pasted into research and run by itself. Returns ------- pipe : Pipeline Represents computation we would like to perform on the assets that make it through the pipeline screen. """ sentiment_score = SimpleMovingAverage( inputs=[stocktwits.bull_minus_bear], window_length=7, ) Asset_Growth_7d = Returns(window_length=8); eveb = morningstar.valuation_ratios.ev_to_ebitda.latest cash_return = morningstar.valuation_ratios.cash_return.latest total_yield = morningstar.valuation_ratios.total_yield.latest #universe = Q1500US() universe = QTradableStocksUS() # We winsorize our factor values in order to lessen the impact of outliers # For more information on winsorization, please see # https://en.wikipedia.org/wiki/Winsorizing sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05, max_percentile=0.95) Asset_Growth_7d_winsorized = Asset_Growth_7d.winsorize(min_percentile=0.05, max_percentile=0.95) eveb_winsorized = eveb.winsorize(min_percentile=0.05, max_percentile=0.95) cash_return_winsorized = cash_return.winsorize(min_percentile=0.05, max_percentile=0.95) total_yield_winsorized = total_yield.winsorize(min_percentile=0.05, max_percentile=0.95) # Here we combine our winsorized factors, z-scoring them to equalize their influence """ combined_factor = -0.3*Asset_Growth_7d_winsorized.zscore() -0.25*sentiment_score_winsorized.zscore() +0.05*eveb_winsorized.zscore() +0.05*cash_return_winsorized.zscore() +0.35*total_yield_winsorized.zscore(); """ combined_factor = -0.3*Asset_Growth_7d_winsorized.zscore() -0.2*sentiment_score_winsorized.zscore() +0.1*eveb_winsorized.zscore() +0.1*cash_return_winsorized.zscore() +0.3*total_yield_winsorized.zscore(); # Build Filters representing the top and bottom baskets of stocks by our # combined ranking system. We'll use these as our tradeable universe each # day. longs = combined_factor.top(TOTAL_POSITIONS//2, mask=universe) shorts = combined_factor.bottom(TOTAL_POSITIONS//2, mask=universe) # The final output of our pipeline should only include # the top/bottom 300 stocks by our criteria long_short_screen = (longs | shorts) # Create pipeline pipe = Pipeline( columns={ 'longs': longs, 'shorts': shorts, 'combined_factor': combined_factor }, screen=long_short_screen & sentiment_score.notnull() & Asset_Growth_7d.notnull(), ) return pipe
def make_pipeline(): universe = QTradableStocksUS() # Variables seleccionadas del dataframe de Fundamentals value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest sentiment_score = SimpleMovingAverage( inputs=[stocktwits.bull_minus_bear], window_length=3, ) quality = Fundamentals.roe.latest working_capital = Fundamentals.working_capital.latest restricted_cash = Fundamentals.restricted_cash.latest accumulated_depreciation = Fundamentals.accumulated_depreciation.latest dps_growth = Fundamentals.dps_growth.latest capital_stock = Fundamentals.capital_stock.latest mcap = Fundamentals.market_cap.latest daily_returns = Returns(window_length=2) # Variables (SIN ATIPICOS) value_winsorized = value.winsorize(min_percentile=0.05, max_percentile=0.95) sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05, max_percentile=0.95) quality_winsorized = quality.winsorize(min_percentile=0.05, max_percentile=0.95) working_capital = working_capital.winsorize(min_percentile=0.05, max_percentile=0.95) restricted_cash = restricted_cash.winsorize(min_percentile=0.05, max_percentile=0.95) accumulated_depreciation = accumulated_depreciation.winsorize( min_percentile=0.05, max_percentile=0.95) dps_growth = dps_growth.winsorize(min_percentile=0.05, max_percentile=0.95) capital_stock = capital_stock.winsorize(min_percentile=0.05, max_percentile=0.95) mcap = mcap.winsorize(min_percentile=0.05, max_percentile=0.95) daily_returns = daily_returns.winsorize(min_percentile=0.05, max_percentile=0.95) # FACTOR COMBINADO combined_factor = ( quality_winsorized.zscore() * 0.01 + accumulated_depreciation.zscore() * 0.03 + working_capital.zscore() * 0.05 + dps_growth.zscore() * 0.85 + value_winsorized.zscore() * 0.01 + mcap.zscore() * 0.01 + capital_stock.zscore() * 0.01 + sentiment_score_winsorized.zscore() * 0.01 + restricted_cash.zscore() * 0.01 + daily_returns.zscore( groupby=mstar.company_reference.country_id.latest) * 0.01) longs = combined_factor.top(TOTAL_POSITIONS // 2, mask=universe) shorts = combined_factor.bottom(TOTAL_POSITIONS // 2, mask=universe) long_short_screen = (longs | shorts) pipe = Pipeline(columns={ 'longs': longs, 'shorts': shorts, 'combined_factor': combined_factor }, screen=long_short_screen) return pipe