Exemple #1
0
def make_pipeline():
    base_universe = QTradableStocksUS()
    beta = SimpleBeta(
                target=sid(8554),
                regression_length=260,
                )
    universe = (Sector().notnull() & base_universe & beta.notnull())
    AMTvol = AverageMonthlyTradingVolume()
    #market_cap = Fundamentals.market_cap.latest
    #book_to_price = 1/Fundamentals.pb_ratio.latest
    momentum = Momentum(window_length=252)
    growth = Fundamentals.growth_score.latest
    
    # Alpha Generation
    # ----------------
    # Compute Z-scores  
    AMTvol_z = AMTvol.zscore(mask=universe)
    growth_z = growth.zscore(mask=universe)
    large = AMTvol_z.percentile_between(80,100)
    fast = growth_z.percentile_between(80,100)
    momentum_z = momentum.zscore(mask=(universe & (fast | large)))
    # Alpha Combination
    # -----------------
    # Assign every asset a combined rank and center the values at 0.
    # For UNIVERSE_SIZE=500, the range of values should be roughly -250 to 250.
    alpha1 = (momentum_z).rank().demean()    
    
    # S2
    monthly_top_volume = (
        AverageDollarVolume(window_length=LIQUIDITY_LOOKBACK_LENGTH)
        .top(UNIVERSE_SIZE, mask=universe)
        .downsample(BASE_UNIVERSE_RECALCULATE_FREQUENCY))
    universe2 = (monthly_top_volume & universe)
    vr = mstar.valuation_ratios
    #fcf_zscore = vr.fcf_yield.latest.zscore(mask=universe2)
    yield_zscore = vr.earning_yield.latest.zscore(mask=universe2)
    roe_zscore = Fundamentals.roic.latest.zscore(mask=universe2)
    ltd_to_eq = Fundamentals.long_term_debt_equity_ratio.latest.zscore(mask=universe2)
    value = (Fundamentals.cash_return.latest.zscore(mask=universe2) + Fundamentals.fcf_yield.latest.zscore(mask=universe2)).zscore()
    quality = (roe_zscore + ltd_to_eq +value + 0)
    
    #alpha2 = (fcf_zscore + yield_zscore+quality).rank().demean()
    alpha2 = (yield_zscore+quality).rank().demean()
    
    combined_alpha = alpha1 + alpha2
    
    return Pipeline(
        columns={
            'Momentum': momentum,
            'Volume': AMTvol,
            'Growth_score':growth,
            'sector':Sector(),
            'alpha':combined_alpha,
            'beta': beta,
        },
        screen= combined_alpha.notnull() 
    )
def initialize(context):
    """
    Called once at the start of the program. Any one-time
    startup logic goes here.
    """
    # Define context variables that can be accessed in other methods of
    # the algorithm.
    context.long_leverage = 0.5
    context.short_leverage = -0.5
    context.returns_lookback = 2
    context.sector = Sector()

    # Rebalance on the first trading day of each week at 11AM.
    schedule_function(rebalance,
                      date_rules.every_day(),
                      time_rules.market_close(minutes=1))
    '''
    # Record tracking variables at the end of each day.
    schedule_function(record_vars,
                      date_rules.every_day(),
                      time_rules.market_close(minutes=1))
    '''
    set_commission(commission.PerShare(cost=0, min_trade_cost=10))

    # Create and attach our pipeline (dynamic stock selector), defined below.
    attach_pipeline(make_pipeline(context), 'mean_reversion_example')
def make_pipeline(context):
    mask = Q500US()
    #lb_13 = -Returns(window_length=13, mask=mask)

    weekly_return = Returns(window_length=6, mask=mask)
    pipe = Pipeline(
        columns={
            'weekly_return': weekly_return,
            'sector': Sector(),
        },
        # combined_alpha will be NaN for all stocks not in our universe,
        # but we also want to make sure that we have a sector code for everything
        # we trade.
        screen=weekly_return.notnull() & Sector().notnull(),
    )
    return pipe
Exemple #4
0
def make_pipeline():
    """
    A function to create our dynamic stock selector (pipeline). Documentation on
    pipeline can be found here: https://www.quantopian.com/help#pipeline-title
    """
    base_universe = Q1500US()
    sector = Sector()
    # screen is based off of returns
    returns = Returns(window_length=2)
    # check if stock price has good strength, but not necessarily overbought
    rsi = RSI()
    price = USEquityPricing.close.latest
    # creating filter by specifying the type of returns desired
    top_return_stocks = returns.top(1, mask=base_universe, groupby=sector)
    pipe = Pipeline(
        columns={
            'rsi': rsi,
            'price': price
        },
        # filter top return stocks, and stocks that are not being overbought
        # but are not too oversold either
        screen=base_universe & top_return_stocks & (20 < rsi < 80)
        # the above is equivalent to: choose stocks from the base universe that have had the top returns in their sectors and have a good RSI value
    )
    return pipe
Exemple #5
0
def make_pipeline():
    
    #Nuestro universo de acciones serán todas aquellas que se puedan comprar en US#
    base_universe = QTradableStocksUS()
	
    #Nuestro primer factor será el fcf: Cash Flow Operations minus Capital Expenditures.#
    fcf_growth = Fundamentals.free_cash_flow.latest
 
    #Segundo factor será el ROIC: Net Income / (Total Equity + Long-term Debt and Capital Lease Obligation + Short-term Debt and Capital Lease Obligation)#
    roic = morningstar.operation_ratios.roic.latest
    
    #Filtramos por aquellas con Roic más alto (he estado jugando con los percentiles por lo que quizas el rto no sea el mismo)#
    high_roic = roic.percentile_between(60,100, mask=base_universe)
    
    #Filtramos por aquellas con FCF que más ha crecido#
    high_fcfgrowth = fcf_growth.percentile_between(60, 100, mask = base_universe)
    
    #Mezclamos los dos anteriores y hacemos un único ranking#
    securities_of_high_growth = (high_roic & high_fcfgrowth)
    
    #De ese ranking queremos que nos saque los siguientes datos#
    return Pipeline(
        columns = {
            'Return on Invested Capital': roic,
            'Top Growth Company': securities_of_high_growth, 
            'FCF Growth': fcf_growth,
            'Sector': Sector(),
        },
        screen = securities_of_high_growth
    )
	
	#Debe devolver a la función anterior el Pipeline#
    return Pipeline()
Exemple #6
0
def make_pipeline(context):
    base_universe = Q500US()
    # 昨日の終値
    yesterday_close = USEquityPricing.close.latest
    yesterday_volume = USEquityPricing.volume.latest
    dollar_volume = AverageDollarVolume(window_length=30)
    high_dollar_volume = dollar_volume.percentile_between(
        context.high_dollar_volume_thresh_min,
        context.high_dollar_volume_thresh_max)
    sector = Sector()
    rsi = RSI(inputs=[USEquityPricing.close])

    pipe = Pipeline(screen=base_universe & high_dollar_volume,
                    columns={
                        'high_dollar_volume': high_dollar_volume,
                        'sector': sector,
                        'rsi': rsi,
                        'roa': ROA(),
                        'roe': ROE(),
                        'normalized_basic_eps': NormalizedBasicEps(),
                        'net_income_growth': NetIncomeGrowth(),
                        'pe': PE(),
                        'book_value_yield': BookValueYield(),
                        'dividend_yield': DividendYield(),
                        'period_ending_date': PeriodEndingDate(),
                        'prev_close': yesterday_close,
                    })
    return pipe
Exemple #7
0
def make_pipeline():
    """
    Create and return our pipeline.
    We break this piece of logic out into its own function to make it easier to
    test and modify in isolation.
    
    """

    # Create our mean reversion factor by taking the negative of a momentum factor
    
    reversion = Reversion()

    # Classify all securities by sector so that we can enforce sector neutrality later
    sector = Sector()

    # Screen out non-desirable securities by defining our universe.
    universe = Q1500US()

    # By applying a mask to the rank computations, we remove any stocks that failed
    # to meet our initial criteria **before** computing ranks.  This means that the
    # stock with rank 10.0 is the 10th-lowest stock that was included in the Q1500US.
    # 標準偏差
    # filter のかけかたを mask で行ってしまう
    factor_rank = reversion.rank(mask=universe).zscore()

    # Build Filters representing the top and bottom 150 stocks by our ranking system.
    # We'll use these as our tradeable universe each day.
    longs = factor_rank.top(NUM_LONG_POSITIONS)
    shorts = factor_rank.bottom(NUM_SHORT_POSITIONS)

    # The final output of our pipeline should only include
    # the top/bottom 300 stocks by our criteria
    long_short_screen = (longs | shorts)

    # Define any risk factors that we will want to neutralize
    # We are chiefly interested in market beta as a risk factor so we define it using
    # Bloomberg's beta calculation
    # Ref: https://www.lib.uwo.ca/business/betasbydatabasebloombergdefinitionofbeta.html
    beta = 0.66 * RollingLinearRegressionOfReturns(
        target=sid(8554),
        returns_length=5,
        regression_length=260,
        mask=long_short_screen
    ).beta + 0.33*1.0

    # Create pipeline
    pipe = Pipeline(
        columns={
            'longs': longs,
            'shorts': shorts,
            'factor_rank': factor_rank,
            'reversion': reversion,
            'sector': sector,
            'market_beta': beta
        },
        screen=long_short_screen
    )
    return pipe
Exemple #8
0
def make_pipeline(context):
    ## symbol universe
    base_universe = Q500US() if False else Q1500US()
    ## filters
    # Filter for primary share equities. IsPrimaryShare is a built-in filter.
    primary_share = IsPrimaryShare()
    # Equities listed as common stock (as opposed to, say, preferred stock).
    # 'ST00000001' indicates common stock.
    common_stock = morningstar.share_class_reference.security_type.latest.eq(
        'ST00000001')
    # Non-depositary receipts. Recall that the ~ operator inverts filters,
    # turning Trues into Falses and vice versa
    not_depositary = ~morningstar.share_class_reference.is_depositary_receipt.latest
    # Equities not trading over-the-counter.
    not_otc = ~morningstar.share_class_reference.exchange_id.latest.startswith(
        'OTC')
    # Not when-issued equities.
    not_wi = ~morningstar.share_class_reference.symbol.latest.endswith('.WI')
    # Equities without LP in their name, .matches does a match using a regular expression
    not_lp_name = ~morningstar.company_reference.standard_name.latest.matches(
        '.* L[. ]?P.?$')
    # Equities with a null value in the limited_partnership Morningstar fundamental field.
    not_lp_balance_sheet = morningstar.balance_sheet.limited_partnership.latest.isnull(
    )
    # Equities whose most recent Morningstar market cap is not null have fundamental data and therefore are not ETFs.
    have_market_cap = morningstar.valuation.market_cap.latest.notnull()
    is_cyclical = SuperSector().eq(SuperSector.CYCLICAL)
    is_defensive = SuperSector().eq(SuperSector.DEFENSIVE)
    is_sensitive = SuperSector().eq(SuperSector.SENSITIVE)

    sector = Sector()
    close = USEquityPricing.close

    # For filter
    tradeable_stocks = (primary_share
                        & common_stock
                        & not_depositary
                        & not_otc
                        & not_wi
                        & not_lp_name
                        & not_lp_balance_sheet
                        & have_market_cap
                        & (is_cyclical | is_defensive | is_sensitive))
    dollar_volume = AverageDollarVolume(window_length=30)
    high_dollar_volume = dollar_volume.percentile_between(98, 100)

    myscreen = (base_universe & tradeable_stocks & high_dollar_volume)

    # Pipeline
    pipe = Pipeline(columns={
        'yesterday_close': close.latest,
        'day_before_yesterday_close': PrevClose(),
        'day_before_yesterday_volume': PrevVolume(),
        'morningstar_sector_code': sector,
    },
                    screen=myscreen)
    return pipe
Exemple #9
0
def MYQ500US():
    return make_us_equity_universe(
        target_size=500,
        rankby=AverageDollarVolume(window_length=200),
        mask=default_us_equity_universe_mask(),
        groupby=Sector(),
        max_group_weight=1.0,
        smoothing_func=lambda f: f.downsample('month_start'),
    )
Exemple #10
0
def make_pipeline():
    minprice = USEquityPricing.close.latest > 5
    not_announced_acq_target = ~IsAnnouncedAcqTarget()
    pipe = Pipeline(screen=Q1500US() & minprice & not_announced_acq_target)
    
    sectors = Sector()
    pipe.add(sectors, 'sector')
    pipe.add(BusinessDaysSincePreviousEarnings(), 'PE')
    return pipe
def initialize(context):
    ## plugging in our factors into existing code
    testing_factor1 = operation_ratios.operation_margin.latest
    testing_factor2 = operation_ratios.revenue_growth.latest
    testing_factor3 = sentiment.sentiment_signal.latest
    
    universe = (Q1500US() & 
                testing_factor1.notnull() & 
                testing_factor2.notnull() & 
                testing_factor3.notnull())
    
    testing_factor1 = testing_factor1.rank(mask=universe, method='average')
    testing_factor2 = testing_factor2.rank(mask=universe, method='average')
    testing_factor3 = testing_factor3.rank(mask=universe, method='average')
    
    combined_alpha = testing_factor1 + testing_factor2 + testing_factor3
    
    testing_quantiles = combined_alpha.quantiles(2)

    # Schedule Tasks
    # --------------
    # Create and register a pipeline computing our combined alpha and a sector
    # code for every stock in our universe. We'll use these values in our 
    # optimization below.
    pipe = Pipeline(
        columns={
            'alpha': combined_alpha,
            'sector': Sector(),
        },
        # combined_alpha will be NaN for all stocks not in our universe,
        # but we also want to make sure that we have a sector code for everything
        # we trade.
        screen=combined_alpha.notnull() & Sector().notnull(),
    )
    algo.attach_pipeline(pipe, 'pipe')

    # Schedule a function, 'do_portfolio_construction', to run once a week
    # ten minutes after market open.
    algo.schedule_function(
        do_portfolio_construction,
        date_rule=algo.date_rules.week_start(),
        time_rule=algo.time_rules.market_open(minutes=MINUTES_AFTER_OPEN_TO_TRADE),
        half_days=False,
    )
Exemple #12
0
def make_pipeline(context):

    profitable = mstar.valuation_ratios.ev_to_ebitda.latest > 0
    market_cap = mstar.valuation.market_cap.latest

    my_screen = market_cap.top(context.n_stocks, mask=(Q1500US() & profitable))

    return Pipeline(columns={
        'sector': Sector(),
    }, screen=my_screen)
def make_pipeline():

    pipe = Pipeline()

    # Set the universe to the QTradableStocksUS & stocks with Sector and Top 2000 by MarketCap
    universe = MarketCap().top(2000, mask = QTradableStocksUS()) & Sector().notnull()

    #filter more with momentum and volarility filter(lowest 600 volatility stocks)

    momentum = Momentum()

    volatility = Volatility()

    volatility_rank = volatility.rank(mask=universe, ascending=True)

    pipe.set_screen(universe  & (volatility_rank.top(600)) & (momentum>1))

    # Creating Price_to_book,Price_to_earnings, and return_on_assets, return_on_Equity, Return on Invested Capital Objects, and Dividend_yield Object and Rank them

    #Create Price to book and Price to Earning and rank them, the lower the ratio, the better
    pb = Price_to_Book()
    pb_rank = pb.rank(mask=universe, ascending=True)

    pe = Price_to_Earnings()
    pe_rank = pe.rank(mask=universe, ascending=True)

    #Create Return on Assets, Return on Equity, Return on Invested Capital and Dividend Yield Class and rank them,the higher the ratio, the better
    roa = Return_on_Assets()
    roa_rank = roa.rank(mask=universe, ascending=False)

    roe = Return_on_Equity()
    roe_rank = roe.rank(mask=universe, ascending=False)

    roic = Return_on_Invested_Capital()
    roic_rank = roic.rank(mask=universe, ascending=False)

    earnings_yield = Earnings_Yield()
    EY_rank   = earnings_yield.rank(ascending=False, mask=universe)


    dy = Dividend_Yield()
    dy_rank = dy.rank(mask=universe, ascending=False)


    #Give 1 weight forall metrics such as P/e,P/B,Dividend Yield,Return on Assets,Equity and Invested Capital
    the_ranking_score = (pb_rank+pe_rank+dy_rank+roa_rank+roe_rank+roic_rank*2 + EY_rank)/8

    # Rank the combo_raw and add that to the pipeline
    pipe.add(the_ranking_score.rank(mask=universe), 'ranking_score')

    return pipe
def make_pipeline(investment_set):
    """
    This will return the selected stocks by market cap, dynamically updated.
    """
    # Base universe
    base_universe = investment_set
    yesterday_close = USEquityPricing.close.latest

    pipe = Pipeline(screen=base_universe,
                    columns={
                        'close': yesterday_close,
                        'sector': Sector()
                    })
    return pipe
Exemple #15
0
def make_pipeline(context):
    """
    Builds a Pipeline with Bollinger bands for top NUM_SYMBOLS stocks by market cap in the tech sector.
    Starts out from the Q500US base universe.
    """

    # Base universe of top 500 US stocks.
    base_universe_filter = Q500US()

    # Stocks of only tech sector.
    tech_sector = Sector(mask=base_universe_filter)
    tech_universe_filter = base_universe_filter & tech_sector.eq(311)

    # Top 10 tech stocks with largest market cap.
    mkt_cap_filter = morningstar.valuation.market_cap.latest
    top_mkt_cap_tech_filter = mkt_cap_filter.top(context.NUM_SYMBOLS,
                                                 mask=tech_universe_filter)

    # Bollinger band factor with Stdev factor 2.
    lower_band_factor, middle_factor, upper_band_factor = BollingerBands(
        window_length=22, k=2, mask=top_mkt_cap_tech_filter)

    # Percent difference between (price, lower_band) and (price, upper_band).
    price = USEquityPricing.close.latest
    buy_percent_factor = ((lower_band_factor - price) * 100) / price
    sell_percent_factor = ((price - upper_band_factor) * 100) / price

    # Mean reversion buy and sell filters.
    # Sell when price exceeds upper-band and buy when price is below lower-band.
    buy_filter = buy_percent_factor > 0
    sell_filter = sell_percent_factor > 0

    # Build and return the Pipeline.
    pipe_bbands = Pipeline(columns={
        'buy_percent': buy_percent_factor,
        'lower_band': lower_band_factor,
        'buy': buy_filter,
        'price': price,
        'sell': sell_filter,
        'upper_band': upper_band_factor,
        'sell_percent': sell_percent_factor
    },
                           screen=top_mkt_cap_tech_filter)

    return pipe_bbands
def make_pipeline():

    # Sector
    sector = Sector()

    # Equity Filters
    mkt_cap_filter = morningstar.valuation.market_cap.latest >= 500000000
    price_filter = USEquityPricing.close.latest >= 5
    nan_filter = sentiment_free.sentiment_signal.latest.notnull()

    # Universe
    universe = Q1500US() & price_filter & mkt_cap_filter & nan_filter

    # Rank
    sentiment_signal = sentiment_free.sentiment_signal.latest
    sma_30 = SimpleMovingAverage(inputs=[sentiment_free.sentiment_signal],
                                 window_length=30,
                                 mask=universe)

    combined_rank = (sentiment_signal + sma_30.rank(mask=universe).zscore())

    # Long and Short Positions
    longs = combined_rank.top(NUM_LONG_POSITIONS)
    shorts = combined_rank.bottom(NUM_SHORT_POSITIONS)

    long_short_screen = (longs | shorts)

    # Bloomberg Beta Implementation
    beta = 0.66 * RollingLinearRegressionOfReturns(
        target=sid(8554),
        returns_length=5,
        regression_length=260,
        mask=long_short_screen).beta + 0.33 * 1.0

    pipe = Pipeline()
    pipe.add(longs, 'longs')
    pipe.add(shorts, 'shorts')
    pipe.add(combined_rank, 'combined_rank')
    pipe.add(sentiment_free.sentiment_signal.latest, 'sentiment_signal')
    pipe.add(sma_30, 'sma_30')
    pipe.add(sector, 'sector')
    pipe.add(beta, 'market_beta')
    pipe.set_screen(universe)

    return pipe
def make_pipeline():

    base_universe = QTradableStocksUS()

    gross_margin = morningstar.operation_ratios.gross_margin.latest

    roa = morningstar.operation_ratios.roa.latest

    factor_to_analyze = gross_margin.zscore() + roa.zscore()

    sector = Sector()

    return Pipeline(columns={
        'factor to analyze': factor_to_analyze,
        'sector': sector
    },
                    screen=base_universe & sector.notnull()
                    & factor_to_analyze.notnull())
Exemple #18
0
def make_ml_pipeline(factors, universe, window_length=21, n_fwd_days=5):
    factors_pipe = OrderedDict()
    # Create returns over last n days.
    factors_pipe['Returns'] = Returns(inputs=[USEquityPricing.open],
                                      mask=universe,
                                      window_length=n_fwd_days + 1)

    # Instantiate ranked factors
    for name, f in factors.iteritems():
        factors_pipe[name] = f().rank(mask=universe)

    # Create our ML pipeline factor. The window_length will control how much
    # lookback the passed in data will have.
    factors_pipe['ML'] = ML(inputs=factors_pipe.values(),
                            window_length=window_length + 1,
                            mask=universe)

    factors_pipe['Sector'] = Sector()

    pipe = Pipeline(screen=universe, columns=factors_pipe)

    return pipe
Exemple #19
0
def make_pipeline():
    """
        A function to create our dynamic stock selector (pipeline). Documentation
        on pipeline can be found here:
        https://www.quantopian.com/help#pipeline-title
        """
    
    # Base universe set to the QTradableStocksUS
    base_universe = QTradableStocksUS()#Q500US()
    base_universe = (base_universe & Q500US())
    #base_universe = (base_universe & Fundamentals.market_cap.latest.top(150))
    # Factor of yesterday's close price.
    #yesterday_close = USEquityPricing.close.latest
    
    pipe = Pipeline(
                    columns={
                    #'close': yesterday_close,
                    'sector': Sector(),
                    },
                    screen=base_universe
                    )
    return pipe
Exemple #20
0
def make_history_pipeline(factors, universe, n_fwd_days=5):
    # Call .rank() on all factors and mask out the universe
    factor_zscore = {
        name: f().zscore(mask=universe)
        for name, f in factors.iteritems()
    }
    # Get cumulative returns over last n_fwd_days days. We will later shift these.
    factor_zscore['Returns'] = Returns(inputs=[USEquityPricing.open],
                                       mask=universe,
                                       window_length=n_fwd_days)
    factor_zscore['Momentum'] = Momentum(mask=universe)
    factor_zscore['Sectors'] = Sector(mask=universe)

    # Add many returns as factors
    for i in [2, 3, 4, 5, 10, 20]:
        factor_zscore['Return' + str(i)] = Returns(
            inputs=[USEquityPricing.open], mask=universe, window_length=i)

    #factor_zscore['SPY']=Returns(inputs=[USEquityPricing.open('SPY')] )

    pipe = Pipeline(screen=universe, columns=factor_zscore)

    return pipe
Exemple #21
0
                            'Percent Difference':percent_difference,
                            '30 Day Mean Close':mean_close_30,
                            'Latest Close':latest_close,
                            'Positive Percent Diff': perc_diff_check},
                    screen=final_filter)
                    
results = run_pipeline(make_pipeline(),'2017-01-01','2017-01-01')
results.head()  
len(results)


### Classifiers: for categorical output
from quantopian.pipeline.data import morningstar
from quantopian.pipeline.classifiers.morningstar import Sector

morningstar_sector = Sector()
exchange = morningstar.share_class_reference.exchange_id.latest
exchange

nyse_filter = exchange.eq('NYS')

def make_pipeline():
    
    # Create Filters for Masks First
    latest_close = USEquityPricing.close.latest
    small_price = latest_close < 5
    
    # Classifier
    nyse_filter = exchange.eq('NYS')
    
    # Pass in the mask
def make_pipeline():
    """
     Defining out trading universe and alpha factor for long and short equities 
    """

    operation_margin = operation_ratios.operation_margin.latest
    revenue_growth = operation_ratios.revenue_growth.latest
    value = (Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest)
    roe = Fundamentals.roe.latest
    momentum = Momentum()
    liquidity = Liquidity()
    free_cash_flows = morningstar.valuation_ratios.fcf_yield.latest
    earnings_yield = morningstar.valuation_ratios.earning_yield.latest

    # Filter for stocks that are announced acquisition target.
    not_announced_acq_target = ~IsAnnouncedAcqTarget()

    mkt_cap_filter = morningstar.valuation.market_cap.latest >= 500000000
    # dividend_filter = Fundamentals.valuation_ratios.dividend_yield >= 0.02

    # Our universe is made up of stocks that have a non-null factors & with market cap over 500 Million $, are not announced
    # acquisition targets, and are in the Q1500US.
    universe = (
        QTradableStocksUS()
        # & not_near_earnings_announcement
        & not_announced_acq_target
        & earnings_yield.notnull()
        & free_cash_flows.notnull()
        & value.notnull()
        & roe.notnull()
        & mkt_cap_filter
        & momentum.notnull())

    # combined_factor = roe*0
    # for factor in factors:
    #     combined_factor += factor.rank(mask=universe)

    # prediction_rank_quantiles = prediction_quality.quantiles(5)

    # longs = prediction_rank_quantiles.eq(4)
    # shorts = prediction_rank_quantiles.eq(0)

    combined_factor = (
        earnings_yield.winsorize(min_percentile=0.05,
                                 max_percentile=0.95).zscore(mask=universe) +
        free_cash_flows.winsorize(min_percentile=0.05,
                                  max_percentile=0.95).zscore(mask=universe) +
        value.winsorize(min_percentile=0.05,
                        max_percentile=0.95).zscore(mask=universe) +
        roe.winsorize(min_percentile=0.05,
                      max_percentile=0.95).zscore(mask=universe) +
        momentum.winsorize(min_percentile=0.05,
                           max_percentile=0.95).zscore(mask=universe))
    combined_factor_quantiles = combined_factor.quantiles(10)

    longs = combined_factor_quantiles.eq(9)
    shorts = combined_factor_quantiles.eq(0)
    # longs = combined_factor.top(2*TOTAL_POSITIONS//3, mask=universe)
    # shorts = combined_factor.bottom(TOTAL_POSITIONS//3, mask=universe)

    # We will take market beta into consideration when placing orders in our algorithm.
    beta = RollingLinearRegressionOfReturns(target=sid(8554),
                                            returns_length=5,
                                            regression_length=260,
                                            mask=(longs | shorts)).beta

    # I calculated the market beta using rolling window regression using Bloomberg's computation.
    # Ref: https://guides.lib.byu.edu/c.php?g=216390&p=1428678
    bb_beta = (0.66 * beta) + (0.33 * 1.0)

    ## create pipeline
    columns = {
        'longs': longs,
        'shorts': shorts,
        'market_beta': bb_beta,
        'sector': Sector(),
        'combined_factor': combined_factor,
    }
    pipe = Pipeline(columns=columns, screen=(longs | shorts))

    return pipe
Exemple #23
0
def make_pipeline():
    """
    Create and return 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.
    """
    
    # Create our momentum, value, and quality factors
    momentum = Momentum()
    # By appending .latest to the imported morningstar data, we get builtin Factors
    # so there's no need to define a CustomFactor
    value = morningstar.income_statement.ebit.latest / morningstar.valuation.enterprise_value.latest
    quality = morningstar.operation_ratios.roe.latest
    
    # Classify all securities by sector so that we can enforce sector neutrality later
    sector = Sector()
    
    # Screen out non-desirable securities by defining our universe. 
    # Removes ADRs, OTCs, non-primary shares, LP, etc.
    # Also sets a minimum $500MM market cap filter and $5 price filter
    mkt_cap_filter = morningstar.valuation.market_cap.latest >= 500000000 
    price_filter = USEquityPricing.close.latest >= 5
    
    universe = Q1500US() & price_filter & mkt_cap_filter

    # Construct a Factor representing the rank of each asset by our momentum,
    # value, and quality metrics. We aggregate them together here using simple
    # addition.
    #
    # By applying a mask to the rank computations, we remove any stocks that failed
    # to meet our initial criteria **before** computing ranks.  This means that the
    # stock with rank 10.0 is the 10th-lowest stock that was included in the Q1500US.
    combined_rank = (
        momentum.rank(mask=universe).zscore() +
        value.rank(mask=universe).zscore() +
        quality.rank(mask=universe).zscore()
    )

    # Build Filters representing the top and bottom 150 stocks by our combined ranking system.
    # We'll use these as our tradeable universe each day.
    longs = combined_rank.top(NUM_LONG_POSITIONS)
    shorts = combined_rank.bottom(NUM_SHORT_POSITIONS)

    # The final output of our pipeline should only include
    # the top/bottom 300 stocks by our criteria
    long_short_screen = (longs | shorts)
    
    # Define any risk factors that we will want to neutralize
    # We are chiefly interested in market beta as a risk factor so we define it using
    # Bloomberg's beta calculation
    # Ref: https://www.lib.uwo.ca/business/betasbydatabasebloombergdefinitionofbeta.html
    beta = 0.66*RollingLinearRegressionOfReturns(
                    target=sid(8554),
                    returns_length=5,
                    regression_length=260,
                    mask=long_short_screen
                    ).beta + 0.33*1.0
    

    # Create pipeline
    pipe = Pipeline(columns = {
        'longs':longs,
        'shorts':shorts,
        'combined_rank':combined_rank,
        'quality':quality,
        'value':value,
        'momentum':momentum,
        'sector':sector,
        'market_beta':beta
    },
    screen = long_short_screen)
    return pipe
def make_pipeline():
    """
    Dynamically apply the custom factors defined below to 
    select candidate stocks from the PreCog universe 
    
    """

    pred_quality_thresh = 0.5

    # Filter for stocks that are not within 2 days of an earnings announcement.
    not_near_earnings_announcement = ~(
        (BusinessDaysUntilNextEarnings() <= 2)
        | (BusinessDaysSincePreviousEarnings() <= 2))

    # Filter for stocks that are announced acquisition target.
    not_announced_acq_target = ~IsAnnouncedAcqTarget()

    # Our universe is made up of stocks that have a non-null sentiment & precog signal that was
    # updated in the last day, are not within 2 days of an earnings announcement, are not announced
    # acquisition targets, and are in the Q1500US.
    universe = (Q1500US()
                & precog.predicted_five_day_log_return.latest.notnull()
                & not_near_earnings_announcement
                & not_announced_acq_target)

    # Prediction quality factor.
    prediction_quality = PredictionQuality(mask=universe)

    # Filter for stocks above the threshold quality.
    quality = prediction_quality > pred_quality_thresh

    latest_prediction = precog.predicted_five_day_log_return.latest

    non_outliers = latest_prediction.percentile_between(1, 99, mask=quality)
    normalized_return = latest_prediction.zscore(mask=non_outliers)

    normalized_prediction_rank = normalized_return.rank()

    prediction_rank_quantiles = normalized_prediction_rank.quantiles(5)

    longs = prediction_rank_quantiles.eq(4)
    shorts = prediction_rank_quantiles.eq(0)

    # We will take market beta into consideration when placing orders in our algorithm.
    beta = RollingLinearRegressionOfReturns(target=sid(8554),
                                            returns_length=5,
                                            regression_length=260,
                                            mask=(longs | shorts)).beta

    # We will actually be using the beta computed using Bloomberg's computation.
    # Ref: https://www.lib.uwo.ca/business/betasbydatabasebloombergdefinitionofbeta.html
    bb_beta = (0.66 * beta) + (0.33 * 1.0)

    ## create pipeline
    columns = {
        'longs': longs,
        'shorts': shorts,
        'market_beta': bb_beta,
        'sector': Sector(),
    }
    pipe = Pipeline(columns=columns, screen=(longs | shorts))

    return pipe
def initialize(context):
    # To set a custom benchmark the following function can be called:
    # set_benchmark(symbol('IWV'))
    # Otherwise the default benchmark will be used (SPY).

    # Commission is set to be $0.005 per share and $1 per trade.
    set_commission(
        us_equities=commission.PerShare(cost=0.005, min_trade_cost=1))

    # Exchange code of a firm.
    exchange = mstar.share_class_reference.exchange_id.latest

    # A filter rule is created that returns True only for
    # the stocks from the exchanges listed.
    my_exchanges = exchange.element_of(['NYSE', 'NYS', 'NAS', 'ASE'])

    # Market capitalisation, sector code and momentum of a firm.
    market_cap = MarketCap()
    sector = Sector()
    umd = Momentum()

    # Defining total_equity, operating_income and interest_expense as
    # corresponding values in the latest income statement and balance sheet.
    total_equity = mstar.balance_sheet.total_equity.latest
    operating_income = mstar.income_statement.operating_income.latest
    interest_expense = mstar.income_statement.interest_expense.latest

    # The trading universe is defined as QTradableStocksUS that falls into
    # my_exchanges and has data for umd, total_equity, operating_income,
    # interest_expense, market_cap and sector.
    universe_exchange = QTradableStocksUS() & umd.notnull(
    ) & my_exchanges & total_equity.notnull() & market_cap.notnull(
    ) & sector.notnull() & operating_income.notnull(
    ) & interest_expense.notnull()

    # Small and large market cap groups specified as percentile.
    small = (MarketCap(mask=universe_exchange).percentile_between(0, 50))
    large = (MarketCap(mask=universe_exchange).percentile_between(50, 100))

    # Create a filter that returns True for the assets in the universe
    # that belong to the given sector(s).
    sec = mstar.asset_classification.morningstar_sector_code.latest
    my_sec = sec.element_of([101])

    # Here the universe redefined as universe_exchange that belongs
    # to the sector(s) in 'my_sec' and falls into either
    # small or large market cap group as defined above.
    # my_sec should be uncommented in case if a speficic sector is wanted.
    '''
    Here are the sector codes that might be used:
    
     -1: 'Misc',  
    101: 'Basic Materials',  
    102: 'Consumer Cyclical',  
    103: 'Financial Services',  
    104: 'Real Estate',  
    205: 'Consumer Defensive',  
    206: 'Healthcare',  
    207: 'Utilities',  
    308: 'Communication Services',  
    309: 'Energy',  
    310: 'Industrials',  
    311: 'Technology' , 
    '''
    universe = universe_exchange & small  #& my_sec

    # Book to market is defined as total_equity divided by the market_cap.
    # The value is normalised and ranked in an ascending order.
    bm = total_equity / market_cap
    bm_weights = bm.rank(ascending=True, mask=universe)

    # Operating profitability ratio is defined as operating_income subtracted
    # interest_expense divided by the total_equity.
    # The value is normalised and ranked in an ascending order.
    op = (operating_income - interest_expense) / total_equity
    op_weights = op.rank(ascending=True, mask=universe)

    # Price momentum values are ranked and normalised in an ascending order.
    umd_weights = umd.rank(ascending=True, mask=universe)

    # A class JoinFactors is defined that is used to combine the normalised
    # scores of the factors defined above.
    class JoinFactors(CustomFactor):
        #inputs = [factor1, factor2, ...] There can be multiple inputs.
        window_length = 1

        def compute(self, today, assets, out, *inputs):
            array = np.concatenate(inputs, axis=0)
            out[:] = np.nansum(array, axis=0)
            out[np.all(np.isnan(array), axis=0)] = np.nan

    # window_safe declares that scores of the factors are robust to
    # pricing adjustments from splits or dividends. In other words,
    # the value that will be the same no matter what day you are
    # looking back from. This is a required step in order to
    # use them as the input to JoinFactors.
    bm_weights.window_safe = True
    op_weights.window_safe = True
    umd_weights.window_safe = True

    # The weights of the combined factor. 1, 2, 3 or more factors can be used.
    final_weights = JoinFactors(inputs=[bm_weights, op_weights, umd_weights],
                                mask=universe)
    universe = final_weights.notnan()

    # The Pipeline object filled with the data defined above is returned.
    pipe = Pipeline(
        columns={
            'bm_weights': bm_weights,
            'op_weights': op_weights,
            'umd_weights': umd_weights,
            'alpha': final_weights,
            'exchange': exchange,
            'market_cap': market_cap,
            'sector': sector,
        },
        # Screen out all the data points outside the trading universe.
        screen=universe)

    # The function attach_pipeline is called
    # to load the data in defined in the pipeline.
    algo.attach_pipeline(pipe, 'pipe')

    # Schedule a function, 'do_portfolio_construction', to run once a month
    # ten minutes after market is open.
    algo.schedule_function(
        do_portfolio_construction,
        date_rule=algo.date_rules.month_start(),
        time_rule=algo.time_rules.market_open(minutes=MINUTES_AFTER_MARKET),
        half_days=False,
    )
Exemple #26
0
def make_pipeline(context):
    ## symbol universe
    base_universe = Q500US() if False else Q1500US()

    ## filters
    # Filter for primary share equities. IsPrimaryShare is a built-in filter.
    primary_share = IsPrimaryShare()
    # Equities listed as common stock (as opposed to, say, preferred stock).
    # 'ST00000001' indicates common stock.
    common_stock = morningstar.share_class_reference.security_type.latest.eq('ST00000001')
    # Non-depositary receipts. Recall that the ~ operator inverts filters,
    # turning Trues into Falses and vice versa
    not_depositary = ~morningstar.share_class_reference.is_depositary_receipt.latest
    # Equities not trading over-the-counter.
    not_otc = ~morningstar.share_class_reference.exchange_id.latest.startswith('OTC')
    # Not when-issued equities.
    not_wi = ~morningstar.share_class_reference.symbol.latest.endswith('.WI')
    # Equities without LP in their name, .matches does a match using a regular expression
    not_lp_name = ~morningstar.company_reference.standard_name.latest.matches('.* L[. ]?P.?$')
    # Equities with a null value in the limited_partnership Morningstar fundamental field.
    not_lp_balance_sheet = morningstar.balance_sheet.limited_partnership.latest.isnull()
    # Equities whose most recent Morningstar market cap is not null have fundamental data and therefore are not ETFs.
    have_market_cap = morningstar.valuation.market_cap.latest.notnull()
    is_cyclical = SuperSector().eq(SuperSector.CYCLICAL)
    is_defensive = SuperSector().eq(SuperSector.DEFENSIVE)
    is_sensitive = SuperSector().eq(SuperSector.SENSITIVE)

    # Filter for stocks that pass all of our previous filters.
    tradeable_stocks = (
        primary_share
        &common_stock
        &not_depositary
        &not_otc
        &not_wi
        &not_lp_name
        &not_lp_balance_sheet
        &have_market_cap
        #&(is_cyclical)
        #&(is_defensive)
        #&(is_sensitive)
        &(is_cyclical | is_defensive | is_sensitive)
    )

    # ToDo この範囲を色々変えてみる.
    dollar_volume = AverageDollarVolume(window_length=30)
    high_dollar_volume = dollar_volume.percentile_between(98, 100)
    daily_volatility = AnnualizedVolatility(window_length=20)/math.sqrt(252)
    sme20 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=20)
    rsi = RSI(inputs=[USEquityPricing.close])
    #sector = ms.asset_classification.morningstar_sector_code
    sector = Sector()
    static_sectors = (sector.eq(311) | 
                      sector.eq(309) | 
                      sector.eq(103) | 
                      sector.eq(101) | 
                      sector.eq(308) | 
                      sector.eq(206) )

    if context.static_asset:
        myscreen = StaticSids(context.special_sids) #context.special_assets
    else: 
        myscreen = (base_universe & tradeable_stocks & high_dollar_volume ) # & static_sectors
        

    pipe = Pipeline(
        columns={
            'prev_close': PrevClose(),
            'prev_volume': PrevVolume(),
            'prev_turnover': PrevClose()*PrevVolume(),
            'dollar_volume': dollar_volume,
            'high_dollar_volume': high_dollar_volume,
            'daily_volatility': daily_volatility,
            'sma20': sme20,
            'rsi': rsi,
            'morningstar_sector_code': sector,
        },
        screen=myscreen,
    )
    return pipe
Exemple #27
0
# ----- Pipeline construction ----------
pipe = Pipeline(screen=universe)
pipe.add(factor, select_factor)

# ------- Ranking factor top to bottom -------
factor_rank = factor.rank()

# ------- Ranking factor top to bottom -------
factor_rank = factor.rank()

# ------- Adding Factor Rank to Pipeline as separate column -------
pipe.add(factor_rank, 'factor_rank')

# ------- Adding Sector categorization to Pipeline construction  -------
pipe.add(Sector(), 'Sector')

# ------- Measurement inteval for the analysis -------
#start = pd.Timestamp("2015-01-01")
start = pd.Timestamp("2015-01-01")

#end = pd.Timestamp("2017-06-30")
#start = pd.Timestamp("2017-06-30")
#start = pd.Timestamp("2017-08-01")

end = pd.Timestamp("2017-08-29")

# ------- Run the pipeline and measure runtime -------
start_timer = time()
#results = run_pipeline(pipe, start_date=start, end_date=end).dropna()
results = run_pipeline(pipe, start_date=start,
def initialize(context):
    pipe = Pipeline()
    attach_pipeline(pipe, 'ranked_2000')
    my_sectors = [206]  #"Healthcare"
    sector_filter = Sector().element_of(my_sectors)
    # Create list of all criteria for securities worth investing in
    """
    9 filters:
        1. common stock
        2 & 3. not limited partnership - name and database check
        4. database has fundamental data
        5. not over the counter
        6. not when issued
        7. not depository receipts
        8. primary share
        9. high dollar volume
    """
    mkt_cap = MarketCap()
    top_2000 = mkt_cap.top(2000)
    common_stock = morningstar.share_class_reference.security_type.latest.eq(
        'ST00000001')
    not_lp_name = ~morningstar.company_reference.standard_name.latest.matches(
        '.* L[\\. ]?P\.?$')
    not_lp_balance_sheet = morningstar.balance_sheet.limited_partnership.latest.isnull(
    )
    have_data = morningstar.valuation.market_cap.latest.notnull()
    not_otc = ~morningstar.share_class_reference.exchange_id.latest.startswith(
        'OTC')
    not_wi = ~morningstar.share_class_reference.symbol.latest.endswith('.WI')
    not_depository = ~morningstar.share_class_reference.is_depositary_receipt.latest
    primary_share = IsPrimaryShare()

    # Combine the above filters.
    tradable_filter = (common_stock & not_lp_name & not_lp_balance_sheet
                       & have_data & not_otc & not_wi & not_depository
                       & primary_share & sector_filter & top_2000)
    pipe_screen = (sector_filter)

    # Create, register and name a pipeline

    # Add the factor defined to the pipeline
    price_to_sales = Price_to_sales(mask=tradable_filter)
    pipe.add(price_to_sales, 'price to sales')

    # Create and apply a filter representing the top 2000 equities by MarketCap every day
    # This is an approximation of the Russell 2000

    # Rank price to sales and add the rank to our pipeline
    price_to_sales_rank = price_to_sales.rank(mask=tradable_filter)
    pipe.add(price_to_sales_rank, 'ps_rank')
    # Set a screen to ensure that only the top 2000 companies by market cap
    # which are healthcare companies with positive PS ratios are screened
    pipe.set_screen(top_2000 & (price_to_sales > 0))
    # Scedule my rebalance function
    schedule_function(func=rebalance,
                      date_rule=date_rules.month_start(days_offset=0),
                      time_rule=time_rules.market_open(hours=0, minutes=30),
                      half_days=True)
    # Schedule my plotting function
    schedule_function(func=record_vars,
                      date_rule=date_rules.every_day(),
                      time_rule=time_rules.market_close(),
                      half_days=True)
    # set my leverage
    context.long_leverage = 1.00
    context.short_leverage = -0.00
    context.spy = sid(8554)
    context.short_list = []
    context.short_list.append(context.spy)
Exemple #29
0
def universe_filters():
    """
    Create a Pipeline producing Filters implementing common acceptance criteria.
    
    Returns
    -------
    zipline.Filter
        Filter to control tradeablility
    """

    # Equities with an average daily volume greater than 750000.
    high_volume = (AverageDollarVolume(window_length=252) > 750000)

    # Not Misc. sector:
    sector_check = Sector().notnull()

    # Equities that morningstar lists as primary shares.
    # NOTE: This will return False for stocks not in the morningstar database.
    primary_share = IsPrimaryShare()

    # Equities for which morningstar's most recent Market Cap value is above $300m.
    have_market_cap = mstar.valuation.market_cap.latest > 300000000

    # Equities not listed as depositary receipts by morningstar.
    # Note the inversion operator, `~`, at the start of the expression.
    not_depositary = ~mstar.share_class_reference.is_depositary_receipt.latest

    # Equities that listed as common stock (as opposed to, say, preferred stock).
    # This is our first string column. The .eq method used here produces a Filter returning
    # True for all asset/date pairs where security_type produced a value of 'ST00000001'.
    common_stock = mstar.share_class_reference.security_type.latest.eq(
        COMMON_STOCK)

    # Equities whose exchange id does not start with OTC (Over The Counter).
    # startswith() is a new method available only on string-dtype Classifiers.
    # It returns a Filter.
    not_otc = ~mstar.share_class_reference.exchange_id.latest.startswith('OTC')

    # Equities whose symbol (according to morningstar) ends with .WI
    # This generally indicates a "When Issued" offering.
    # endswith() works similarly to startswith().
    not_wi = ~mstar.share_class_reference.symbol.latest.endswith('.WI')

    # Equities whose company name ends with 'LP' or a similar string.
    # The .matches() method uses the standard library `re` module to match
    # against a regular expression.
    not_lp_name = ~mstar.company_reference.standard_name.latest.matches(
        '.* L[\\. ]?P\.?$')

    # Equities with a null entry for the balance_sheet.limited_partnership field.
    # This is an alternative way of checking for LPs.
    not_lp_balance_sheet = mstar.balance_sheet.limited_partnership.latest.isnull(
    )

    # Highly liquid assets only. Also eliminates IPOs in the past 12 months
    # Use new average dollar volume so that unrecorded days are given value 0
    # and not skipped over
    # S&P Criterion
    liquid = ADV_adj() > 250000

    # Add logic when global markets supported
    # S&P Criterion
    domicile = True

    # Keep it to liquid securities
    ranked_liquid = ADV_adj().rank(ascending=False) < 1500

    universe_filter = (high_volume & primary_share & have_market_cap
                       & not_depositary & common_stock & not_otc & not_wi
                       & not_lp_name & not_lp_balance_sheet & liquid & domicile
                       & sector_check & liquid & ranked_liquid)

    return universe_filter
Exemple #30
0
        '30 Day Mean Close': mean_close_30,
        'Percent Diff': percent_diff,
        'Latest Close': latest_close,
        'Percent Diff Filter': percent_diff_filter
    },  # OR USE COMBINATION FILTER combo_filter
        screen=percent_diff_filter)  # OR '~percent_diff_filter' FOR OPPOSITE OF THE FILTER

pipe = make_pipeline()  # start_date == end_date, THEREFORE THE SAME DAY
result = run_pipeline(pipe, start_date='2017-01-03', end_date='2017-01-03')
result.head()

# NOW, USING MASKS
latest_close = USEquityPricing.close.latest
small_price = latest_close < 5
mean_close_30 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=30, mask=small_price)
mean_close_10 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=10, mask=small_price)
# mask=val APPLIES A FILTER 1ST BEFORE CALC'ING THIS SMA FACTOR (SAVES COMPUTATIONAL COMPLEXITY)
# NOW USE FACTORS (mean_close_30, mean_close_10) HOWEVER


# NOW, USING CLASSIFIERS
from quantopian.pipeline.data import morningstar
from quantopian.pipeline.classifiers.morningstar import Sector

ms_sector = Sector()  # A LOT OF PROPERTIES OF ms_sector ARE CLASSIFIERS
exchange_classifier = ms_sector.share_class_reference.exchange_id.latest
nyse_filter = exchange_classifier.eq('NYS')  # OR .isnull() / startswith()
# NOW, USE nyse_filter WITHIN pipe = Pipeline(..., screen=nyse_filter)