Ejemplo n.º 1
0
def make_pipeline():

    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(inputs=[stocktwits.bull_minus_bear],window_length=3,)

    twitter_score = SimpleMovingAverage(inputs=[twitter_withretweets.bull_bear_msg_ratio],window_length=3,)    

    news_score = SimpleMovingAverage(inputs=[sentiment.sentiment_signal], window_length=5)

    total_revenue = Fundamentals.total_revenue.latest

    growth = Fundamentals.sustainable_growth_rate.latest
    
    operation_margin = Fundamentals.operation_margin.latest
    
    net_margin = Fundamentals.net_margin.latest

    rec_corredor = SimpleMovingAverage( inputs = [ConsensusRecommendations.total], window_length=3, )

    universe = QTradableStocksUS()
    
    value_winsorized = value.winsorize(min_percentile=0.17, max_percentile=0.83)
    quality_winsorized = quality.winsorize(min_percentile=0.17, max_percentile=0.83)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.17,                                                                             max_percentile=0.83)
    twitter_score_winsorized = twitter_score.winsorize(min_percentile=0.17, max_percentile=0.83)
    news_score_winsorized = news_score.winsorize(min_percentile=0.17, max_percentile=0.83)
    total_revenue_winsorized = total_revenue.winsorize(min_percentile=0.17, max_percentile=0.83)
    growth_winsorized = growth.winsorize(min_percentile=0.17, max_percentile=0.83)
    operation_margin_winsorized = operation_margin.winsorize(min_percentile=0.17, max_percentile=0.83)
    net_margin_winsorized = net_margin.winsorize(min_percentile=0.17, max_percentile=0.83)
    rec_corredor_winsorized = rec_corredor.winsorize(min_percentile=0.17, max_percentile=0.83)

    combined_factor = (
        1*value_winsorized.zscore()  
        + 6*quality_winsorized.zscore()
        + 1*sentiment_score_winsorized.zscore()
        + 5*twitter_score_winsorized.zscore()
        + 1*news_score_winsorized.zscore()
        + 6*growth_winsorized.zscore()
        + 1*operation_margin_winsorized.zscore()
        + 1*net_margin_winsorized.zscore()
        + 6*total_revenue_winsorized.zscore()
        + 9*rec_corredor_winsorized.zscore()
    )

    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():
    #Predefined Factors
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )
    value_winsorized = value.winsorize(min_percentile=0.05,
                                       max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)

    # New Factors
    total_revenue = Fundamentals.total_revenue.latest

    mean_sentiment_5day = SimpleMovingAverage(
        inputs=[sentiment.sentiment_signal], window_length=5)

    mean_sentiment_5day_winsorized = mean_sentiment_5day.winsorize(
        min_percentile=0.05, max_percentile=0.95)

    operation_ratios_latest = operation_ratios.roic.latest

    valuation_ratios_dividend_yield_latest = valuation_ratios.dividend_yield.latest

    valuation_ratios_cash_return_latest = valuation_ratios.cash_return.latest

    universe = (QTradableStocksUS() & operation_ratios_latest.notnull()
                & valuation_ratios_dividend_yield_latest.notnull()
                & valuation_ratios_cash_return_latest.notnull())
    operation_ratios_latest = operation_ratios_latest.rank(mask=universe,
                                                           method='average')
    valuation_ratios_dividend_yield_latest = valuation_ratios_dividend_yield_latest.rank(
        mask=universe, method='average')
    valuation_ratios_cash_return_latest = valuation_ratios_cash_return_latest.rank(
        mask=universe, method='average')

    combined_factor = (
        #Original
        3 * value_winsorized.zscore() + quality_winsorized.zscore() +
        sentiment_score_winsorized.zscore() +
        #New
        operation_ratios_latest + valuation_ratios_dividend_yield_latest +
        3 * valuation_ratios_cash_return_latest +
        0.5 * mean_sentiment_5day_winsorized + 3 * total_revenue)

    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():
    # The factors we create here are based on fundamentals data and a moving
    # average of sentiment data
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(inputs=[stocktwits.bull_minus_bear],
        window_length=3)
    sma50 = SimpleMovingAverage(inputs=[USEquityPricing.close],                                           window_length=50)
    sma200 = SimpleMovingAverage(inputs=[USEquityPricing.close],
                                window_length=200)
    smaScore = sma50/sma200

    sizeScore = SimpleMovingAverage(inputs=[Fundamentals.size_score],window_length=3)
    
    growthScore = SimpleMovingAverage(inputs=[Fundamentals.growth_score],window_length=3)

    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
    value_winsorized = value.winsorize(min_percentile=0.05, max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05, max_percentile=0.95)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,                                                                             max_percentile=0.95)
    smaScore_winsorized =smaScore.winsorize(min_percentile=0.05, max_percentile=0.95)
    sizeScore_winsorized = sizeScore.winsorize(min_percentile=0.05, max_percentile=0.95)
    growthScore_winsorized = growthScore.winsorize(min_percentile=0.05, max_percentile=0.95)
    # Here we combine our winsorized factors, z-scoring them to equalize their influence
    combined_factor = (
        value_winsorized.zscore() + 
        quality_winsorized.zscore() + 
        sentiment_score_winsorized.zscore() +
        smaScore_winsorized.zscore() +
        sizeScore_winsorized.zscore() + 
        growthScore_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
    )
    return pipe
Ejemplo n.º 4
0
def make_pipeline():
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )

    rec_corredor = SimpleMovingAverage(
        inputs=[ConsensusRecommendations.total],
        window_length=3,
    )

    add_insider_transaction = SimpleMovingAverage(
        inputs=[
            Form3AggregatedTrades.slice(False, 90).num_unique_filers.latest
        ],
        window_length=1,
    )

    universe = QTradableStocksUS()

    value_winsorized = value.winsorize(min_percentile=0.05,
                                       max_percentile=0.95)

    quality_winsorized = quality.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)

    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)

    rec_corredor_winsorized = rec_corredor.winsorize(min_percentile=0.05,
                                                     max_percentile=0.95)

    add_insider_transaction_winsorized = add_insider_transaction.winsorize(
        min_percentile=0.05, max_percentile=0.95)

    combined_factor = (1 * value_winsorized.zscore() +
                       1 * quality_winsorized.zscore() +
                       1 * sentiment_score_winsorized.zscore() +
                       9 * rec_corredor_winsorized.zscore() +
                       1 * add_insider_transaction_winsorized.zscore())

    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():
    
    # The factors we create here are based on fundamentals data and a moving
    # average of sentiment data    
    value = Fundamentals.ebitda.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    
    #Puntaje para Stocktwits
    sentiment_score = SimpleMovingAverage(inputs=[stocktwits.bull_minus_bear],window_length=3,)    
    #Puntaje para twitter
    twitter_score = SimpleMovingAverage(inputs=[twitter_withretweets.bull_bear_msg_ratio],window_length=3,)    
    #Puntaje noticias
    news_score = SimpleMovingAverage(inputs=[sentiment.sentiment_signal], window_length=5)

    universe = QTradableStocksUS()
    
    # We winsorize our factor values in order to lessen the impact of outliers
    value_winsorized = value.winsorize(min_percentile=0.05, max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05, max_percentile=0.95)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05, max_percentile=0.95)
    twitter_score_winsorized = twitter_score.winsorize(min_percentile=0.05, max_percentile=0.95)
    news_score_winsorized = news_score.winsorize(min_percentile=0.05, max_percentile=0.95)

    # Here we combine our winsorized factors, z-scoring them to equalize their influence
    combined_factor = (
        3*value_winsorized.zscore()
        + 3*quality_winsorized.zscore()
        + 2*sentiment_score_winsorized.zscore()
        + twitter_score_winsorized.zscore()
        + 2*news_score_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
    )
    return pipe
Ejemplo n.º 6
0
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.
    """
    # The factors we create here are based on fundamentals data and a moving
    # average of sentiment data
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )

    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
    value_winsorized = value.winsorize(min_percentile=0.05, max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05, max_percentile=0.95)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,                                                                             max_percentile=0.95)

    # Here we combine our winsorized factors, z-scoring them to equalize their influence
    combined_factor = (
        value_winsorized.zscore() +
        quality_winsorized.zscore() +
        sentiment_score_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
    )
    return pipe
Ejemplo n.º 7
0
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.
    """
    # The factors we create here are based on fundamentals data and a moving
    # average of sentiment data
    value = Fundamentals.ebit.latest 
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )
    total_revenue = Fundamentals.total_revenue.latest
    
    positive_sentiment_pct = (
        twitter_sentiment.bull_scored_messages.latest
        / twitter_sentiment.total_scanned_messages.latest
    )
    
    positive_sentiment_pctt = (
        twitter_sentiment2.bull_scored_messages.latest
        / twitter_sentiment2.total_scanned_messages.latest
    )
    
    
    
    
    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
    value_winsorized = value.winsorize(min_percentile=0.05, max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05, max_percentile=0.95)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,                                                                             max_percentile=0.95)
    total_revenue_winsorized = total_revenue.winsorize(min_percentile=0.05, max_percentile=0.95)
    positive_sentiment_pct_winsorized = positive_sentiment_pct.winsorize(min_percentile=0.05,                                                                                     max_percentile=0.95)
    positive_sentiment_pctt_winsorized = positive_sentiment_pctt.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.2*value_winsorized.zscore() + 
        0.2*quality_winsorized.zscore() + 
        0.2*sentiment_score_winsorized.zscore()+
        0.2*total_revenue_winsorized.zscore()+
        0.1*positive_sentiment_pct_winsorized+
        0.1*positive_sentiment_pctt_winsorized
    )
Ejemplo n.º 8
0
def make_pipeline():
    #Example Variables
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )

    #Aditional Variables
    fcf_ratio = Fundamentals.fcf_ratio.latest
    roa = Fundamentals.roa.latest
    accounts_receivable = Fundamentals.accounts_receivable.latest
    gain_loss_on_sale_of_ppe = Fundamentals.gain_loss_on_sale_of_ppe.latest

    universe = QTradableStocksUS()

    #Eliminamos los valores atipicos de las distribuciones
    value_winsorized = value.winsorize(min_percentile=0.05,
                                       max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)
    fcf_ratio_winsorized = fcf_ratio.winsorize(min_percentile=0.05,
                                               max_percentile=0.95)
    roa_winsorized = roa.winsorize(min_percentile=0.05, max_percentile=0.95)
    accounts_receivable_winsorized = accounts_receivable.winsorize(
        min_percentile=0.05, max_percentile=0.95)
    gain_loss_on_sale_of_ppe_winsorized = gain_loss_on_sale_of_ppe.winsorize(
        min_percentile=0.05, max_percentile=0.95)

    # Aqui hacemos la combinacion y asignamos pesos
    combined_factor = (value_winsorized.zscore() * 0.1 +
                       quality_winsorized.zscore() * 0.1 +
                       sentiment_score_winsorized.zscore() * 0.2 +
                       fcf_ratio_winsorized.zscore() * 0.1 +
                       roa_winsorized.zscore() * 0.1 +
                       accounts_receivable_winsorized.zscore() * 0.2 +
                       gain_loss_on_sale_of_ppe_winsorized.zscore() * 0.2)

    #Vamos escoger en cuales vamos en largo y cuales vamos en corto
    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)
    return pipe
Ejemplo n.º 9
0
def make_pipeline():

    global value
    global quality
    global sentiment_score
    global test_sentiment
    global total_revenue
    global yesterday_close
    global yesterday_volume

    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest

    quality = Fundamentals.roe.latest

    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )

    test_sentiment = (twitter_sentiment.bull_scored_messages.latest /
                      twitter_sentiment.total_scanned_messages.latest)

    total_revenue = Fundamentals.total_revenue.latest

    yesterday_close = EquityPricing.close.latest

    yesterday_volume = EquityPricing.volume.latest

    universe = QTradableStocksUS()

    value_winsorized = value.winsorize(min_percentile=0.05,
                                       max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)

    combined_factor = (value_winsorized.zscore() +
                       quality_winsorized.zscore() +
                       sentiment_score_winsorized.zscore())

    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
Ejemplo n.º 10
0
def make_pipeline():
    returns = (-1) * Returns(window_length = 21)
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=21,
    )
    
    ty = Fundamentals.total_yield.latest
    wps = Fundamentals.working_capital_per_share.latest 
    epst = Fundamentals.tangible_book_value_per_share.latest
    eps = (epst-wps) * (-1)

    universe = QTradableStocksUS()
    
 
    value_winsorized = value.winsorize(min_percentile=0.05, max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05, max_percentile=0.95)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05, max_percentile=0.95)
    returns_winsorized = returns.winsorize(min_percentile=0.05, max_percentile=0.95)
    eps_wisorized = eps.winsorize(min_percentile=0.05, max_percentile=0.95)
    ty_winsorized = ty.winsorize(min_percentile=0.05, max_percentile=0.95)
  
    combined_factor = (
        value_winsorized.zscore() 
        + quality_winsorized.zscore()
        + sentiment_score_winsorized.zscore()
        + returns_winsorized.zscore() 
        + eps_wisorized.zscore()
        + ty_winsorized.zscore()
       
        
    )

   
    longs = combined_factor.top(TOTAL_POSITIONS//2, mask=universe)
    shorts = combined_factor.bottom(TOTAL_POSITIONS//2, mask=universe)

    
    long_short_screen = (longs | shorts)

    # Create pipeline
    pipe = Pipeline(
        columns={
            'longs': longs,
            'shorts': shorts,
            'combined_factor': combined_factor
        },
        screen=long_short_screen
    )
    
    return pipe
Ejemplo n.º 11
0
def make_pipeline():

    returns = (-1) * Returns(window_length = 21)
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.total_scanned_messages],
        window_length=21,
    )

    ty = Fundamentals.total_yield.latest #-7.77
    wps = Fundamentals.working_capital_per_share.latest #-7.53
    epst = Fundamentals.tangible_book_value_per_share.latest
    gro = Fundamentals.growth_score.latest
    dollar_volume = AverageDollarVolume(window_length=63)

    universe = QTradableStocksUS() & (dollar_volume > 10**7)

    value_winsorized = value.winsorize(min_percentile=0.15, max_percentile=0.85)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.15, max_percentile=0.85)
    eps_wisorized = wps.winsorize(min_percentile=0.15, max_percentile=0.85)
    ty_winsorized = ty.winsorize(min_percentile=0.15, max_percentile=0.85)
    gro_winsorize = gro.winsorize(min_percentile=0.15, max_percentile=0.85)
    returns_winsorize = returns.winsorize(min_percentile=0.05, max_percentile=0.85)
   
    # Here we combine our winsorized factors, z-scoring them to equalize their influence
    combined_factor = (
        value_winsorized.zscore() *0.15
        + gro_winsorize.zscore() *0.25 
        + sentiment_score_winsorized.zscore()* 0.2
        + eps_wisorized.zscore() *0.15 
        + ty_winsorized.zscore() *0.15
        + returns_winsorize.zscore() *0.1
    )

    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
Ejemplo n.º 12
0
def make_pipeline():
   
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.total_scanned_messages],
        window_length=21,
    )
    
    ty = Fundamentals.total_yield.latest 
    wps = Fundamentals.working_capital_per_share.latest 
    gro = Fundamentals.growth_score.latest
    dollar_volume = AverageDollarVolume(window_length=63)
    
    universe = QTradableStocksUS()
    
    dollar_winsorize = dollar_volume.winsorize(min_percentile=0.2, max_percentile=0.8)
    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)
    eps_wisorized = wps.winsorize(min_percentile=0.05, max_percentile=0.95)
    ty_winsorized = ty.winsorize(min_percentile=0.05, max_percentile=0.95)
    gro_winsorize = gro.winsorize(min_percentile=0.05, max_percentile=0.95)

   
    combined_factor = (
        value_winsorized.zscore() *0.15
        + gro_winsorize.zscore() *0.25 
        + sentiment_score_winsorized.zscore()* 0.15
        + eps_wisorized.zscore() *0.15 
        + ty_winsorized.zscore() *0.15
        + dollar_winsorize.zscore() *0.15
    )

    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
Ejemplo n.º 13
0
def make_pipeline():

    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )
    workingCapital = Fundamentals.working_capital_per_share.latest
    sGrowRate = Fundamentals.sustainable_growth_rate.latest
    dividendYield = Fundamentals.forward_dividend_yield.latest

    universe = QTradableStocksUS()

    value_winsorized = value.winsorize(min_percentile=0.05,
                                       max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)
    workingCapital_winsorized = workingCapital.winsorize(min_percentile=0.05,
                                                         max_percentile=0.95)
    sGrowRate_winsorized = sGrowRate.winsorize(min_percentile=0.05,
                                               max_percentile=0.95)
    dividendYield_winsorized = dividendYield.winsorize(min_percentile=0.05,
                                                       max_percentile=0.95)

    combined_factor = (value_winsorized.zscore() +
                       quality_winsorized.zscore() +
                       sentiment_score_winsorized.zscore() +
                       workingCapital_winsorized + sGrowRate_winsorized +
                       dividendYield_winsorized)

    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
Ejemplo n.º 14
0
def make_pipeline():

    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    positived_sentiment = (twitter_sentiment.bull_scored_messages.latest /
                           twitter_sentiment.total_scanned_messages.latest)
    sentiment_3day = SimpleMovingAverage(inputs=[sentiment.sentiment_signal],
                                         window_length=3)
    total_revenue = Fundamentals.total_revenue.latest
    yesterday_close = EquityPricing.close.latest
    yesterday_volume = EquityPricing.volume.latest

    universe = QTradableStocksUS()

    value_winsorized = value.winsorize(min_percentile=0.05,
                                       max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)
    sentiment_winsorized = sentiment_3day.winsorize(min_percentile=0.05,
                                                    max_percentile=0.95)
    revenue_winsorized = total_revenue.winsorize(min_percentile=0.05,
                                                 max_percentile=0.95)
    close_winsorized = yesterday_close.winsorize(min_percentile=0.05,
                                                 max_percentile=0.95)
    volume_winsorized = yesterday_volume.winsorize(min_percentile=0.05,
                                                   max_percentile=0.95)

    combined_factor = (
        value_winsorized.zscore() + quality_winsorized.zscore() +
        ((positived_sentiment.zscore() + sentiment_winsorized.zscore()) / 2) +
        revenue_winsorized.zscore() + close_winsorized.zscore() +
        volume_winsorized.zscore())

    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
Ejemplo n.º 15
0
def make_pipeline():
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    total_revenue = Fundamentals.total_revenue.latest
    yesterday_close = EquityPricing.close.latest
    yesterday_volume = EquityPricing.volume.latest
    working_capital_per_share = Fundamentals.working_capital_per_share.latest
    forward_dividend_yield = Fundamentals.forward_dividend_yield.latest
    peg_ratio = Fundamentals.peg_ratio.latest
    trailing_dividend_yield = Fundamentals.trailing_dividend_yield.latest
    sentiment_score = SimpleMovingAverage(inputs=[stocktwits.bull_minus_bear],
                                          window_length=2)

    test_sentiment = (twitter_sentiment.bull_scored_messages.latest /
                      twitter_sentiment.total_scanned_messages.latest)

    universe = QTradableStocksUS()
    #-----------------------------------------------------------------
    recent_returns = Returns(window_length=RETURNS_LOOKBACK_DAYS,
                             mask=universe)
    recent_returns_zscore = recent_returns.zscore()
    #----------------------------------------------------------------

    value_winsorized = value.winsorize(min_percentile=0.10,
                                       max_percentile=0.90)
    quality_winsorized = quality.winsorize(min_percentile=0.10,
                                           max_percentile=0.90)
    total_revenue_winsorized = total_revenue.winsorize(min_percentile=0.10,
                                                       max_percentile=0.90)
    yesterday_close_winsorized = yesterday_close.winsorize(min_percentile=0.10,
                                                           max_percentile=0.90)
    yesterday_volume_winsorized = yesterday_volume.winsorize(
        min_percentile=0.10, max_percentile=0.90)
    working_capital_per_share_winsorized = working_capital_per_share.winsorize(
        min_percentile=0.10, max_percentile=0.90)
    forward_dividend_yield_winsorized = forward_dividend_yield.winsorize(
        min_percentile=0.10, max_percentile=0.90)
    peg_ratio_winsorized = peg_ratio.winsorize(min_percentile=0.10,
                                               max_percentile=0.90)
    trailing_dividend_yield_winsorized = trailing_dividend_yield.winsorize(
        min_percentile=0.10, max_percentile=0.90)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.10,
                                                           max_percentile=0.90)
    #---------------------------------------------------------------
    combined_factor = (
        value_winsorized.zscore() + quality_winsorized.zscore() +
        total_revenue_winsorized.zscore() +
        yesterday_volume_winsorized.zscore() +
        working_capital_per_share_winsorized.zscore() * 2 +
        forward_dividend_yield_winsorized.zscore() * 2 +
        peg_ratio_winsorized.zscore() * 2 +
        trailing_dividend_yield_winsorized.zscore() +
        ((sentiment_score_winsorized.zscore() + test_sentiment.zscore()) / 2))
    #---------------------------------------------------------------

    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,
        'recent_returns_zscore': recent_returns_zscore,
        'combined_factor': combined_factor,
        'total_revenue': total_revenue,
        'close': yesterday_close,
        'volume': yesterday_volume,
    },
                    screen=long_short_screen)
    return pipe
Ejemplo n.º 16
0
def make_pipeline():
    # The factors we create here are based on fundamentals data and a moving
    # average of sentiment data
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest

    quality = Fundamentals.roe.latest

    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=50,
    )

    growth_score = Fundamentals.growth_score.latest

    opt_income = Fundamentals.operation_income_growth.latest

    market_cap = Fundamentals.market_cap.latest

    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
    value_winsorized = value.winsorize(min_percentile=0.05,
                                       max_percentile=0.95)

    quality_winsorized = quality.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)

    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)

    growth_score_winsorized = growth_score.winsorize(min_percentile=0.05,
                                                     max_percentile=0.95)

    opt_income_winsorized = opt_income.winsorize(min_percentile=0.05,
                                                 max_percentile=0.95)

    market_cap_winsorized = market_cap.winsorize(min_percentile=0.05,
                                                 max_percentile=0.95)

    combined_factor = ((1 * value_winsorized + 1 * quality_winsorized +
                        2 * sentiment_score_winsorized +
                        4 * growth_score_winsorized +
                        0.5 * opt_income_winsorized +
                        0.5 * market_cap_winsorized))

    # 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)
    return pipe
Ejemplo n.º 17
0
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.
    """
    # The factors we create here are based on fundamentals data and a moving
    # average of sentiment data
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest

    growth = Fundamentals.growth_score.latest
    accountsreceivable = Fundamentals.accounts_receivable.latest

    additionalcapital = Fundamentals.additional_paid_in_capital.latest

    capitalstock = Fundamentals.capital_stock.latest

    currentassets = Fundamentals.total_assets.latest

    currentdebt = Fundamentals.total_debt.latest

    dilutedgrowth = Fundamentals.equity_per_share_growth.latest

    dilutedepsgrowth = Fundamentals.diluted_eps_growth.latest

    dilutedcontepsgrowth = Fundamentals.diluted_cont_eps_growth.latest

    cashfinancingactivities = Fundamentals.cash_flow_from_continuing_financing_activities.latest

    cashinvestingactivities = Fundamentals.cash_flow_from_continuing_investing_activities.latest

    cashoperatingactivities = Fundamentals.cash_flow_from_continuing_operating_activities.latest

    changeinventory = Fundamentals.change_in_inventory.latest

    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )

    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
    value_winsorized = value.winsorize(min_percentile=0.05,
                                       max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)

    growth_winsorized = growth.winsorize(min_percentile=0.05,
                                         max_percentile=0.95)

    accounts_receivable_winsorized = accountsreceivable.winsorize(
        min_percentile=0.05, max_percentile=0.95)
    additional_capital_winsorized = additionalcapital.winsorize(
        min_percentile=0.05, max_percentile=0.95)

    capital_stock_winsorized = capitalstock.winsorize(min_percentile=0.05,
                                                      max_percentile=0.95)

    current_assets_winsorized = currentassets.winsorize(min_percentile=0.05,
                                                        max_percentile=0.95)

    current_debt_winsorized = currentdebt.winsorize(min_percentile=0.05,
                                                    max_percentile=0.95)

    diluted_growth_winsorized = dilutedgrowth.winsorize(min_percentile=0.05,
                                                        max_percentile=0.95)

    diluted_eps_growth_winsorized = dilutedepsgrowth.winsorize(
        min_percentile=0.05, max_percentile=0.95)

    diluted_cont_eps_growth_winsorized = dilutedcontepsgrowth.winsorize(
        min_percentile=0.05, max_percentile=0.95)

    cash_financing_activities_winsorized = cashfinancingactivities.winsorize(
        min_percentile=0.05, max_percentile=0.95)

    cash_investing_activities_winsorized = cashinvestingactivities.winsorize(
        min_percentile=0.05, max_percentile=0.95)

    cash_operating_activities_winsorized = cashoperatingactivities.winsorize(
        min_percentile=0.05, max_percentile=0.95)

    change_in_inventory_winsorized = changeinventory.winsorize(
        min_percentile=0.05, max_percentile=0.95)

    # Here we combine our winsorized factors, z-scoring them to equalize their influence
    combined_factor = (
        value_winsorized.zscore() + quality_winsorized.zscore() +
        sentiment_score_winsorized.zscore() + growth_winsorized.zscore() +
        accounts_receivable_winsorized.zscore() +
        additional_capital_winsorized.zscore() +
        capital_stock_winsorized.zscore() +
        current_assets_winsorized.zscore() - current_debt_winsorized.zscore() +
        diluted_growth_winsorized.zscore() -
        diluted_eps_growth_winsorized.zscore() -
        diluted_cont_eps_growth_winsorized.zscore() +
        cash_financing_activities_winsorized.zscore() +
        cash_investing_activities_winsorized.zscore() +
        cash_operating_activities_winsorized.zscore() +
        change_in_inventory_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)
    return pipe
Ejemplo n.º 18
0
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():

    # The factors we create here are based on fundamentals data and a moving
    # average of sentiment data
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )

    growthh = Fundamentals.growth_score.latest
    value_score = Fundamentals.value_score.latest
    profitability_grade = Fundamentals.profitability_grade.latest
    basic_average_shares = Fundamentals.basic_average_shares_earnings_reports.latest

    a = Fundamentals.current_ratio.latest
    b = Fundamentals.accumulated_depreciation.latest
    c = Fundamentals.ps_ratio.latest
    d = Fundamentals.style_score.latest
    e = Fundamentals.total_yield.latest
    #f = Fundamentals.
    #g = Fundamentals.

    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
    value_winsorized = value.winsorize(min_percentile=0.0, max_percentile=1)

    quality_winsorized = quality.winsorize(min_percentile=0.00,
                                           max_percentile=1)

    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)

    growthh_winsorized = growthh.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)

    value_score_winsorized = value_score.winsorize(min_percentile=0.05,
                                                   max_percentile=0.95)

    basic_average_shares_winzorized = basic_average_shares.winsorize(
        min_percentile=0.05, max_percentile=0.95)

    a_winso = a.winsorize(min_percentile=0.05, max_percentile=0.95)

    b_winso = b.winsorize(min_percentile=0.05, max_percentile=0.95)

    c_winso = c.winsorize(min_percentile=0.05, max_percentile=0.95)

    d_winso = d.winsorize(min_percentile=0.05, max_percentile=0.95)

    e_winso = e.winsorize(min_percentile=0.05, max_percentile=0.95)

    #f_winso = f.winsorize(min_percentile=0.05,                   max_percentile=0.95)

    #g_winso = g.winsorize(min_percentile=0.05,                   max_percentile=0.95)

    #profitability_grade_winsorized = profitability_grade.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.1*value_winsorized.zscore() )+
        #(-1.1*quality_winsorized.zscore() )+
        #(1*sentiment_score_winsorized.zscore())
        (1.4 * growthh_winsorized.zscore()) +
        (-1.6 * value_score_winsorized.zscore()) + (0.6 * a_winso.zscore()) +
        (0.8 * b_winso.zscore()) + (2.3 * c_winso.zscore()) +
        (0.75 * d_winso.zscore()) + (-1 * e_winso.zscore())
        #(f_winso.zscore())
        #(-0.1*basic_average_shares_winzorized.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)
    return pipe
def make_pipeline():
    universe = QTradableStocksUS()

    # Variables seleccionadas del dataframe de Fundamentals
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )
    buildings_and_improvements = Fundamentals.buildings_and_improvements.latest
    account_payable = Fundamentals.accounts_payable.latest
    current_assets = Fundamentals.current_assets.latest
    total_equity = Fundamentals.total_equity.latest
    accumulated_depreciation = Fundamentals.accumulated_depreciation.latest
    diluted_eps_growth = Fundamentals.diluted_eps_growth.latest
    dps_growth = Fundamentals.dps_growth.latest

    # Variables (SIN ATIPICOS)
    value_winsorized = value.winsorize(min_percentile=0.05,
                                       max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)
    buildings_and_improvements = buildings_and_improvements.winsorize(
        min_percentile=0.05, max_percentile=0.95)
    account_payable = account_payable.winsorize(min_percentile=0.05,
                                                max_percentile=0.95)
    current_assets = current_assets.winsorize(min_percentile=0.05,
                                              max_percentile=0.95)
    total_equity = total_equity.winsorize(min_percentile=0.05,
                                          max_percentile=0.95)
    accumulated_depreciation = accumulated_depreciation.winsorize(
        min_percentile=0.05, max_percentile=0.95)
    diluted_eps_growth = diluted_eps_growth.winsorize(min_percentile=0.05,
                                                      max_percentile=0.95)
    dps_growth = dps_growth.winsorize(min_percentile=0.05, max_percentile=0.95)

    # FACTOR COMBINADO
    combined_factor = (
        quality_winsorized.zscore() * 0.2 + value_winsorized.zscore() * 0.4 +
        dps_growth.zscore() * 0.15 +
        sentiment_score_winsorized.zscore() * 0.3 +
        buildings_and_improvements.zscore() * 0.2 +
        accumulated_depreciation.zscore() * 0.25 +
        account_payable.zscore() * 0.01 + current_assets.zscore() * 0.01 +
        total_equity.zscore() * 0.01 + diluted_eps_growth.zscore() * 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
Ejemplo n.º 21
0
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.
    """
    # The factors we create here are based on fundamentals data and a moving
    # average of sentiment data
    universe = QTradableStocksUS()

    fe_rec = fe.ConsensusRecommendations  # 5

    pe_ratio = Fundamentals.forward_pe_ratio.latest  # 4

    sentiment_score = SimpleMovingAverage(  # 3
        inputs=[stocktwits.bullish_intensity],
        window_length=5,
    )
    mean_close_10 = SimpleMovingAverage(inputs=[USEquityPricing.close],
                                        window_length=10)
    mean_close_30 = SimpleMovingAverage(inputs=[USEquityPricing.close],
                                        window_length=30)
    percent_difference = (mean_close_10 - mean_close_30) / mean_close_30

    # 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
    pe_ratio_winsorized = pe_ratio.winsorize(min_percentile=0.05,
                                             max_percentile=0.95)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)

    percent_difference_winsorized = percent_difference.winsorize(  # 2
        min_percentile=0.1, max_percentile=0.9)

    recent_returns = Returns(window_length=5)  # 6

    fq1_eps_cons = PeriodicConsensus.slice('EPS', 'qf', 1)  # 1
    fq2_eps_cons = PeriodicConsensus.slice('EPS', 'qf', 2)

    fq1_eps_mean = fq1_eps_cons.mean.latest
    fq2_eps_mean = fq2_eps_cons.mean.latest

    estimated_growth_factor = (fq2_eps_mean - fq1_eps_mean) / fq1_eps_mean

    estimated_growth_factor_windsorized = estimated_growth_factor.winsorize(
        min_percentile=0.01, max_percentile=0.99)

    # Here we combine our winsorized factors, z-scoring them to equalize their influence
    combined_factor = (0.01 * fe_rec.total.latest +
                       pe_ratio_winsorized.zscore() +
                       sentiment_score_winsorized.zscore() +
                       0.005 * percent_difference_winsorized.zscore() +
                       0.01 * recent_returns.zscore() +
                       estimated_growth_factor_windsorized.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)
    return pipe
Ejemplo n.º 22
0
def make_pipeline():
    qtu = QTradableStocksUS()

    # Aggregated Insider Transactions
    insider_txns_form3_90d = Form3AggregatedTrades.slice(False, 90)
    insider_txns_form4and5_90d = Form4and5AggregatedTrades.slice(False, 90)

    unique_filers_form3_90d = insider_txns_form3_90d.num_unique_filers.latest
    unique_buyers_form4and5_90d = insider_txns_form4and5_90d.num_unique_buyers.latest
    unique_sellers_form4and5_90d = insider_txns_form4and5_90d.num_unique_sellers.latest

    unique_buyers_90d = unique_filers_form3_90d + unique_buyers_form4and5_90d
    unique_sellers_90d = unique_sellers_form4and5_90d

    frac_insiders_buying_90d = unique_buyers_90d / (unique_buyers_90d +
                                                    unique_sellers_90d)
    frac_insiders_selling_90d = unique_sellers_90d / (unique_buyers_90d +
                                                      unique_sellers_90d)

    alpha_factor = frac_insiders_buying_90d - frac_insiders_selling_90d

    screen = qtu & ~alpha_factor.isnull() & alpha_factor.isfinite()

    alpha_winsorized = alpha_factor.winsorize(min_percentile=0.05,
                                              max_percentile=0.95,
                                              mask=screen)

    alpha_rank = alpha_winsorized.zscore()

    # FactSet Estimates – Consensus
    fq1_eps_cons = PeriodicConsensus.slice('EPS', 'qf', 1)
    fq2_eps_cons = PeriodicConsensus.slice('EPS', 'qf', 2)

    fq1_eps_mean = fq1_eps_cons.mean.latest
    fq2_eps_mean = fq2_eps_cons.mean.latest

    estimated_growth_factor = (fq2_eps_mean - fq1_eps_mean) / fq1_eps_mean

    estimated_growth_factor_rank = estimated_growth_factor.winsorize(
        min_percentile=0.05, max_percentile=0.95).zscore()

    # Sentdex News Sentiment
    mean_sentiment_5day = SimpleMovingAverage(
        inputs=[sentiment.sentiment_signal], window_length=5)

    # The factors we create here are based on fundamentals data and a moving
    # average of sentiment data
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )

    # 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
    value_winsorized = value.winsorize(min_percentile=0.05,
                                       max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)

    # Here we combine our winsorized factors, z-scoring them to equalize their influence
    combined_factor = (value_winsorized.zscore() +
                       quality_winsorized.zscore() +
                       sentiment_score_winsorized.zscore() + alpha_rank +
                       estimated_growth_factor_rank + mean_sentiment_5day)

    # 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=screen)
    shorts = combined_factor.bottom(TOTAL_POSITIONS // 2, mask=screen)

    # 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)
    return pipe
Ejemplo n.º 23
0
def make_pipeline():
    # The factors we create here are based on fundamentals data and a moving
    # average of sentiment data
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest

    quality = Fundamentals.roe.latest

    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=50,
    )

    growth_score = Fundamentals.growth_score.latest

    amortization = Fundamentals.amortization_of_securities.latest

    dividends = Fundamentals.cash_dividends_paid.latest

    asst_turnover = Fundamentals.assets_turnover.latest

    dps_growth = Fundamentals.dps_growth.latest

    sustainable = Fundamentals.sustainable_growth_rate.latest

    enterprise_value = Fundamentals.enterprise_value.latest

    gross_margin = Fundamentals.gross_margin.latest

    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
    value_winsorized = value.winsorize(min_percentile=0.05,
                                       max_percentile=0.95)

    quality_winsorized = quality.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)

    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)

    growth_score_winsorized = growth_score.winsorize(min_percentile=0.05,
                                                     max_percentile=0.95)

    amortization_winsorized = amortization.winsorize(min_percentile=0.05,
                                                     max_percentile=0.95)

    dividends_winsorized = dividends.winsorize(min_percentile=0.05,
                                               max_percentile=0.95)

    asst_turnover_winsorized = asst_turnover.winsorize(min_percentile=0.05,
                                                       max_percentile=0.95)

    dps_growth_winsorized = dps_growth.winsorize(min_percentile=0.05,
                                                 max_percentile=0.95)

    sustainable_winsorized = sustainable.winsorize(min_percentile=0.05,
                                                   max_percentile=0.95)

    enterprise_value_winsorized = enterprise_value.winsorize(
        min_percentile=0.05, max_percentile=0.95)

    gross_margin_winsorized = gross_margin.winsorize(min_percentile=0.05,
                                                     max_percentile=0.95)

    combined_factor = ((0.1 * value_winsorized + 0.1 * quality_winsorized +
                        0.2 * sentiment_score_winsorized +
                        0.2 * growth_score_winsorized +
                        0.3 * gross_margin_winsorized +
                        0.1 * amortization_winsorized))

    # 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)
    return pipe
Ejemplo n.º 24
0
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.
    """
    positive_sentiment_pct = (twitter_sentiment.bull_scored_messages.latest /
                              twitter_sentiment.total_scanned_messages.latest)

    # The factors we create here are based on fundamentals data and a moving
    # average of sentiment data
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )
    universe = QTradableStocksUS()
    yesterday_close = EquityPricing.close.latest
    yesterday_volume = EquityPricing.volume.latest
    v1 = Fundamentals.accounts_receivable.latest
    v2 = Fundamentals.size_score.latest
    v3 = Fundamentals.style_score.latest

    # 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
    positive_sentiment_pct_winsorized = positive_sentiment_pct.winsorize(
        min_percentile=0.05, max_percentile=0.95)
    value_winsorized = value.winsorize(min_percentile=0.05,
                                       max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)
    v1_winsorized = v1.winsorize(min_percentile=0.05, max_percentile=0.95)
    v2_winsorized = v2.winsorize(min_percentile=0.05, max_percentile=0.95)
    v3_winsorized = v3.winsorize(min_percentile=0.05, max_percentile=0.95)
    yesterday_close_winsorized = yesterday_close.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)
    yesterday_volume_winsorized = yesterday_volume.winsorize(
        min_percentile=0.05, max_percentile=0.95)

    # Here we combine our winsorized factors, z-scoring them to equalize their influence
    combined_factor = (positive_sentiment_pct_winsorized.zscore() * 0.8 +
                       value_winsorized.zscore() * 0.5 +
                       quality_winsorized.zscore() * 0.5 +
                       sentiment_score_winsorized.zscore() * 0.5 +
                       v1_winsorized.zscore() * 0.5 +
                       v2_winsorized.zscore() * 0.5 +
                       v3_winsorized.zscore() * 0.5 +
                       yesterday_close_winsorized.zscore() * 0.5 +
                       yesterday_volume_winsorized.zscore() * 0.7)

    # 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={
        'positive_sentiment_pct': positive_sentiment_pct,
        'longs': longs,
        'shorts': shorts,
        'combined_factor': combined_factor,
        'close': yesterday_close,
        'volume': yesterday_volume
    },
                    screen=long_short_screen,
                    domain=US_EQUITIES)
    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.
    """
    # The factors we create here are based on fundamentals data and a moving
    # average of sentiment data

    enterprise = SimpleMovingAverage(
        inputs=[Fundamentals.enterprise_value],
        window_length=10,
    )
    marketcap = SimpleMovingAverage(
        inputs=[Fundamentals.market_cap],
        window_length=10,
    )
    earnings = SimpleMovingAverage(inputs=[Fundamentals.ebit],
                                   window_length=10)

    equitymedia = (EquityPricing.high.latest + EquityPricing.low.latest) / 2

    high = SimpleMovingAverage(inputs=[EquityPricing.high], window_length=10)

    low = SimpleMovingAverage(inputs=[EquityPricing.low], window_length=10)

    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

    enterprise_winsorized = enterprise.winsorize(min_percentile=0.05,
                                                 max_percentile=0.95)
    marketcap_winsorized = marketcap.winsorize(min_percentile=0.05,
                                               max_percentile=0.95)
    earnings_winsorized = earnings.winsorize(min_percentile=0.05,
                                             max_percentile=0.95)
    equitymedia_winsorized = equitymedia.winsorize(min_percentile=0.05,
                                                   max_percentile=0.95)
    high_winsorized = high.winsorize(min_percentile=0.05, max_percentile=0.95)
    low_winsorized = low.winsorize(min_percentile=0.05, max_percentile=0.95)

    # Here we combine our winsorized factors, z-scoring them to equalize their influence
    combined_factor = (enterprise_winsorized.zscore() +
                       marketcap_winsorized.zscore() +
                       earnings_winsorized.zscore() +
                       high_winsorized.zscore() + low_winsorized.zscore() +
                       equitymedia_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)
    return pipe
Ejemplo n.º 26
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
Ejemplo n.º 27
0
def make_pipeline():

    # Ganancias por acción con frecuencia semestral reportada mas recientemente
    profits = fe.Actuals.slice('EPS', 'qf', 0).actual_value.latest

    # Estimación de ganancias por acción con frecuencia trimentral
    profits_estimation = fe.PeriodicConsensus.slice('EPS', 'qf', 0).mean.latest

    # Diferencia entre el valor real y el estimado
    difference_profits = (profits - profits_estimation) / profits_estimation

    # Flujo de caja por acción con frecuencia semestral reportada mas recientemente
    flow = fe.Actuals.slice('CFPS', 'qf', 0).actual_value.latest

    # Flujo de caja por acción con frecuencia trimentral
    flow_estimation = fe.PeriodicConsensus.slice('CFPS', 'qf', 0).mean.latest

    # Diferencia entre el valor real y el estimado
    difference_flow = (flow - flow_estimation) / flow_estimation

    # Precio de cierre
    close = EquityPricing.close.latest

    # Precio de apertura
    open = EquityPricing.open.latest

    # Diferencia entre el precio de apretura y de cierre
    difference_open_close_price = (close - open) / open

    # Precio mas alto
    high = EquityPricing.high.latest

    # Precio mas bajo
    low = EquityPricing.low.latest

    # diferencia entre el precio mas alto y el mas bajo
    difference_high_low_price = (high - low) / low

    # N° acciones negociadas
    volume = EquityPricing.volume.latest

    # factores basado en datos de fundamentals y SimpleMovingAverage
    value = Fundamentals.ebit.latest / Fundamentals.market_cap.latest
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )

    # Obtener universo de acciones negociables
    universe = QTradableStocksUS()

    # Cambiar los valores por fuera de los percentiles minimo y maximo por el valor del percentil del extremo correspondiente
    difference_profits_winsorized = -difference_profits.winsorize(
        min_percentile=0.05, max_percentile=0.95)
    difference_flow_winsorized = -difference_flow.winsorize(
        min_percentile=0.05, max_percentile=0.95)
    difference_open_close_price_winsorized = -difference_open_close_price.winsorize(
        min_percentile=0.05, max_percentile=0.95)
    difference_high_low_price_winsorized = -difference_high_low_price.winsorize(
        min_percentile=0.05, max_percentile=0.95)
    volume_winsorized = -volume.winsorize(min_percentile=0.05,
                                          max_percentile=0.95)
    value_winsorized = -value.winsorize(min_percentile=0.05,
                                        max_percentile=0.95)
    quality_winsorized = -quality.winsorize(min_percentile=0.05,
                                            max_percentile=0.95)
    sentiment_score_winsorized = -sentiment_score.winsorize(
        min_percentile=0.05, max_percentile=0.95)

    # Normalizar los datos y sumarlos para amplificar
    combined_factor = (difference_profits_winsorized.zscore() +
                       difference_flow_winsorized.zscore() +
                       difference_open_close_price_winsorized.zscore() +
                       difference_high_low_price_winsorized.zscore() +
                       volume_winsorized.zscore() + value_winsorized.zscore() +
                       quality_winsorized.zscore() +
                       sentiment_score_winsorized.zscore())

    # Filtrar los primeros y los ultimos valores
    longs = combined_factor.top(TOTAL_POSITIONS // 2, mask=universe)
    shorts = combined_factor.bottom(TOTAL_POSITIONS // 2, mask=universe)

    # Unir los primeros y los ultimos valores
    long_short_screen = (longs | shorts)

    # Crear tuberia
    pipe = Pipeline(columns={
        'longs': longs,
        'shorts': shorts,
        'combined_factor': combined_factor
    },
                    screen=long_short_screen)
    return pipe
Ejemplo n.º 28
0
def make_pipeline():
    """
    パイプラインを作成して返す関数
    
    パイプラインの構築は、NotebookとAlgorithmの両方で動作させることができるので、Notebook
    で検証したアルファをコピペしてアルゴリズムで使うことが可能。
    【Execise】make_pipeline をNotebookにコピーして動作することを確認しよう。

    Returns
    -------
    pipe : Pipeline
        Represents computation we would like to perform on the assets that make
        it through the pipeline screen.
    """

    # ファクターその1:バリューファクター(この時点では生データ)
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    # ファクターその2:クオリティファクター(ROE)(この時点では生データ)
    quality = Fundamentals.roe.latest
    # ファクターその3:センチメントファクター(この時点では生データ)
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )

    # ユニバースはQTradableStockUS()を使う
    universe = QTradableStocksUS()

    # 生データからwinsorizeによってスコア化
    # バリューファクタースコア
    value_winsorized = value.winsorize(min_percentile=0.05,
                                       max_percentile=0.95)
    # クオリティファクタースコア
    quality_winsorized = quality.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)
    # センチメントファクタースコア
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)

    # 3つのファクターを合成して、1つのアルファを構成
    # 【Execise】ファクターの合成方法を変えてバックテストしてみよう!
    combined_factor = (value_winsorized.zscore() +
                       quality_winsorized.zscore() +
                       sentiment_score_winsorized.zscore())

    # QTradableStocks構成銘柄の中から、さらに、combined_fatctorが上位のものだけを取得
    longs = combined_factor.top(TOTAL_POSITIONS // 2, mask=universe)
    # QTradableStocks構成銘柄の中から、さらに、combined_fatctorが下位のものだけを取得
    shorts = combined_factor.bottom(TOTAL_POSITIONS // 2, mask=universe)

    # longとshortsの構成銘柄を組み合わせることで、最終的なフィルタを構築
    long_short_screen = (longs | shorts)

    # パイプラインを作成
    pipe = Pipeline(
        columns={
            'longs': longs,
            'shorts': shorts,
            'combined_factor': combined_factor
        },
        # フィルタリング(longs または shorts に含まれる銘柄でフィルタリング)
        screen=long_short_screen)
    # 作成したパイプラインを返して終了
    return pipe
Ejemplo n.º 29
0
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.
    """
    #1
    positive_sentiment_pct = (twitter_sentiment.bull_scored_messages.latest /
                              twitter_sentiment.total_scanned_messages.latest)

    #2
    quarterly_sales = Fundamentals2.sales_qf.latest

    #3 bueno
    research_development = Fundamentals2.rd_exp_qf.latest

    #4
    pPEI = Fundamentals2.ppe_impair_qf.latest  #un poco mala

    #5 re malo :´v
    other_income = Fundamentals2.oper_inc_oth_qf.latest

    #6 un tris malo
    investment_income = Fundamentals2.invest_inc_qf.latest

    # The factors we create here are based on fundamentals data and a moving
    # average of sentiment data
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.roe.latest
    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )

    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
    investment_income_winsorized = investment_income.winsorize(
        min_percentile=0.05, max_percentile=0.95)
    other_income_winsorized = other_income.winsorize(min_percentile=0.05,
                                                     max_percentile=0.95)
    pPEI_winsorized = pPEI.winsorize(min_percentile=0.05, max_percentile=0.95)
    research_development_winsorized = research_development.winsorize(
        min_percentile=0.05, max_percentile=0.95)
    quarterly_sales_winsorized = quarterly_sales.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)
    positive_sentiment_pct_winsorized = positive_sentiment_pct.winsorize(
        min_percentile=0.05, max_percentile=0.95)
    value_winsorized = value.winsorize(min_percentile=0.05,
                                       max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)
    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)

    # Here we combine our winsorized factors, z-scoring them to equalize their influence
    combined_factor = (investment_income_winsorized.zscore() +
                       other_income_winsorized.zscore() +
                       pPEI_winsorized.zscore() +
                       research_development_winsorized.zscore() +
                       quarterly_sales_winsorized.zscore() +
                       positive_sentiment_pct_winsorized.zscore() +
                       value_winsorized.zscore() +
                       quality_winsorized.zscore() +
                       sentiment_score_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={
        'positive_sentiment_pct': positive_sentiment_pct,
        '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.
    """
    # Ganancias menos gastos sobre el valor total de la empresa incluida la deuda
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    # Utilidad
    quality = Fundamentals.roe.latest
    # Ingresos netos sobre activos totales promedio de los ultimos 5 años
    interest = Fundamentals.roa5_yr_avg.latest
    # Los gastos operativos son costos recurrentes primarios asociados con las operaciones centrales (que no sean el costo de los bienes vendidos) en los que se incurre para generar ventas.
    oExpense = Fundamentals.operating_expense.latest
    # Costo total del personal que se paga a los empleados que no forma parte de los gastos de venta, generales y administrativos.
    cost = Fundamentals.staff_costs.latest

    sentiment_score = SimpleMovingAverage(
        inputs=[stocktwits.bull_minus_bear],
        window_length=3,
    )

    universe = QTradableStocksUS()

    # Transformacion de las estadisticas al limitar los valores extremos
    value_winsorized = value.winsorize(min_percentile=0.05,
                                       max_percentile=0.95)
    quality_winsorized = quality.winsorize(min_percentile=0.05,
                                           max_percentile=0.95)
    interest_winsorized = interest.winsorize(min_percentile=0.05,
                                             max_percentile=0.95)
    oExpense_winsorized = oExpense.winsorize(min_percentile=0.1,
                                             max_percentile=0.9)
    cost_winsorized = cost.winsorize(min_percentile=0.05, max_percentile=0.95)

    sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05,
                                                           max_percentile=0.95)

    # Here we combine our winsorized factors, z-scoring them to equalize their influence
    combined_factor = (
        value_winsorized.zscore() + quality_winsorized.zscore() +
        oExpense_winsorized.zscore() +
        #interest_winsorized.zscore() +
        #cost_winsorized.zscore() +
        sentiment_score_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)
    return pipe