예제 #1
0
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
예제 #3
0
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