예제 #1
0
def initialize(context):

    universe = QTradableStocksUS()
    sector = Sector()
    momentum = Momentum()
    pipe = Pipeline()
    pipe.add(sector, 'sector')
    
    # ALPHA
    asset_turnover = Fundamentals.assets_turnover.latest.winsorize(.05, .95).zscore()
    ciwc = Fundamentals.change_in_working_capital.latest.winsorize(.05, .95).zscore()

    alpha = (asset_turnover + ciwc).rank().demean()
    pipe.add(alpha, 'alpha')
    
    # BETA
    beta = RollingLinearRegressionOfReturns(target=sid(8554),
                                            returns_length=5,
                                            regression_length=252,
                                            mask=alpha.notnull() & Sector().notnull()
                                            ).beta                    
    pipe.add(beta, 'beta')
    
    # REGISTER PIPELINES
    # ------------------
    attach_pipeline(pipe, 'pipe')
    attach_pipeline(risk_loading_pipeline(), 'risk_loading_pipeline')
    pipe.set_screen(alpha.notnull() & Sector().notnull() & beta.notnull() & universe & (momentum>0))
    
    # SCHEDULE FUNCTIONS
    # ------------------   
    schedule_function(rebalance, 
                      date_rule=date_rules.every_day(), 
                      time_rule=time_rules.market_open(minutes=10))
예제 #2
0
def initialize(context):

    # DEFINE UNIVERSE
    # ------------------
    universe = QTradableStocksUS()

    # ALPHA GENERATION
    # ----------------
    # COMPUTE Z SCORES: ASSET TURNOVER AND CHANGE IN WORKING CAPITAL
    # BOTH ARE FUNDAMENTAL VALUE MEASURES

    asset_turnover = Fundamentals.assets_turnover.latest.winsorize(
        .05, .95).zscore()
    ciwc = Fundamentals.change_in_working_capital.latest.winsorize(
        .05, .95).zscore()

    # ALPHA COMBINATION
    # -----------------
    # ASSIGN EVERY ASSET AN ALPHA RANK AND CENTER VALUES AT 0 (DEMEAN).
    alpha = (asset_turnover + 2 * ciwc).rank().demean()

    # BETA DEFINITION
    beta = 0.66 * RollingLinearRegressionOfReturns(
        target=sid(8554),
        returns_length=5,
        regression_length=252,
        mask=alpha.notnull() & Sector().notnull()).beta + 0.33 * 1.0

    # CREATE AND REGISTER PIPELINE
    #-------------------------------
    # COMPUTES COMBINES ALPHA AND SECTOR CODE FOR UNIVERSE OF STOCKS TO BE USED IN OPTIMIZATION
    pipe = Pipeline(
        columns={
            'alpha': alpha,
            'sector': Sector(),
            'beta': beta,
        },
        # RETURN ONLY "NOT NULL" VALUES IN OUR PIPELINE
        screen=alpha.notnull() & Sector().notnull() & beta.notnull()
        & universe,
    )

    # LOAD ALL PIPELINES
    algo.attach_pipeline(pipe, 'pipe')
    algo.attach_pipeline(risk_loading_pipeline(), 'risk_loading_pipeline')

    # SCHEDULE FUNCTIONS
    #--------------------
    algo.schedule_function(
        do_portfolio_construction,
        date_rule=algo.date_rules.week_start(),
        time_rule=algo.time_rules.market_open(minutes=10),
        half_days=False,
    )
예제 #3
0
def make_pipeline():
    # Set the universe to the QTradableStocksUS & stocks with Sector defined
    universe  = QTradableStocksUS() & Sector().notnull()

    # A Filterfor market cap greater than 1  billion
    medium_cap = Fundamentals.market_cap.latest > 1000000000

    # We don't choose from Financial and Ultility Sector
    not_Finan_and_Ulti = ((Sector != 103) & (Sector != 207))

    # the final universe
    universe = universe & medium_cap & not_Finan_and_Ulti

    #Create an object of Earnings_Yield and rank them in descending order
    earnings_yield = Earnings_Yield()
    EY_rank   = earnings_yield.rank(ascending=False, mask=universe)

    #Create an object of Return on invested Capital and rank them in descending order
    roic= Return_on_Invested_Capital()
    roic_rank = roic.rank(ascending=False, mask=universe)

    # the rank of magic formula is equal to the sum of rank of Earning Yields and Return on invested capital
    Magic_Formula_rank   = EY_rank + roic_rank

    pipe = Pipeline(columns = {
        'earnings_yield': earnings_yield,
        'Earnings_yield_rank':EY_rank,
        'roic'          : roic,
        'Roic_rank': roic_rank,
        'MagicFormula_rank': Magic_Formula_rank,
    }, screen = universe )
    return pipe
예제 #4
0
def make_pipeline2():
    pipe = Pipeline()
    '''standards'''
    book_to_price = 1 / Latest([Fundamentals.pb_ratio])
    PE = Latest([Fundamentals.pe_ratio])
    #research_and_development = Latest([Fundamentals.research_and_development])
    gross_dividend_payment = Latest([Fundamentals.gross_dividend_payment])
    value_score = Latest([Fundamentals.value_score])
    returns = Returns(inputs=[USEquityPricing.close], window_length=2)
    growth_score = Latest([Fundamentals.growth_score])
    profit_grade = Fundamentals.profitability_grade.latest
    financial_health_grade = Fundamentals.financial_health_grade.latest
    '''filter'''
    #profit_requirement = (profit_grade=='A') | (profit_grade=='B')
    mask = QTradableStocksUS()
    mask &= Sector().eq(sector)
    #mask &= value_score > 30
    mask &= PE < 35
    mask &= USEquityPricing.volume.latest > 10000
    '''pipeline'''
    pipe = Pipeline(columns={
        'Returns': returns,
        'B/P': book_to_price,
        'P/E': PE,
        'Dividends': gross_dividend_payment,
        'Value Score': value_score,
        'Growth_Score': growth_score,
        'Profit_Grade': profit_grade,
        'Financial_Health': financial_health_grade
    },
                    screen=mask)
    return pipe
예제 #5
0
def make_pipeline(context):
    # Use a universe of just the top 500 US stocks
    universe = Q500US()
    sector = Sector()

    # Determine if the market is trending up or down. If the market is trending down then just buy bonds. If it is trending up then buy stocks
    # This is not an optimal solution and will obviously not work in all future market crashes
    spy_ma_fast_slice = SMA(
        inputs=[USEquityPricing.close],
        window_length=context.TF_FAST_LOOKBACK)[context.SPY]
    spy_ma_slow_slice = SMA(
        inputs=[USEquityPricing.close],
        window_length=context.TF_SLOW_LOOKBACK)[context.SPY]
    spy_ma_fast = SMA(inputs=[spy_ma_fast_slice], window_length=1)
    spy_ma_slow = SMA(inputs=[spy_ma_slow_slice], window_length=1)
    # If the 100 moving average crosses the 10 then alter the trend up variable
    trend_up = spy_ma_fast > spy_ma_slow

    # Get simple factors to determine "quality" companies
    cash_return = ms.cash_return.latest.rank(mask=universe)
    fcf_yield = ms.fcf_yield.latest.rank(mask=universe)
    roic = ms.roic.latest.rank(mask=universe)
    rev_growth = ms.revenue_growth.latest.rank(mask=universe)

    value = (cash_return + fcf_yield).rank(mask=universe)

    # Find sentiment rank using https://www.quantopian.com/posts/sentiment-as-a-factor
    sentiment_score = SMA(
        inputs=[sentiment.sentiment_signal],
        window_length=30,
    )
    sentiment_score_zscore = sentiment_score.zscore()
    sentiment_overall_rank = sentiment_score_zscore.rank(
        mask=universe, groupby=sector).demean()

    # Combine factors to create one single ranking system
    quality = roic + rev_growth + value + sentiment_overall_rank

    # Create a 'momentum' factor by looking back over the last 140 days (20 weeks).
    momentum = Returns(window_length=context.MOMENTUM_LOOKBACK_DAYS)

    # Filters for top quality and momentum to use in the selection criteria
    top_quality = quality.top(context.TOP_ROE_QTY, mask=universe)
    top_quality_momentum = momentum.top(context.TARGET_SECURITIES,
                                        mask=top_quality)
    # Only return values to be used in the selection criteria by using the screen parameter
    pipe = Pipeline(columns={
        'trend_up': trend_up,
        'top_quality_momentum': top_quality_momentum,
    },
                    screen=top_quality_momentum)
    return pipe
예제 #6
0
def make_pipeline():
    base_universe = QTradableStocksUS()
    sector = Sector()
    sector2 = morningstar.asset_classification.morningstar_sector_code.latest

    healthcare_sector = sector.eq(206)

    airline_sector = sector2.eq(31053108)

    sent = sentiment.sentiment_signal.latest

    longs = healthcare_sector and (sent > 3)

    shorts = airline_sector and (sent < 1)

    tradable_securities = (longs | shorts) and base_universe

    return Pipeline(columns={
        'longs': longs,
        'shorts': shorts
    },
                    screen=tradable_securities)
예제 #7
0
def make_pipeline(context):
    """
    A function to build out filtered stock list by sectors.
    """
    # Hold sector object, which will be used as a column in the pipeline, identifying
    # each stock's sector.
    stocks_sector = Sector()
    
    # Possible short version of a pipeline without filters
    return Pipeline(
        columns={
            'sector_code': stocks_sector
        }
    )
예제 #8
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.
    """

    # By appending .latest to the imported morningstar data, we get builtin Factors
    # so there's no need to define a CustomFactor
    value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.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 = Fundamentals.market_cap.latest >= 500000000
    price_filter = USEquityPricing.close.latest >= 5
    universe = QTradableStocksUS() & price_filter & mkt_cap_filter

    # Construct a Factor representing the rank of each asset by our value
    # quality metrics. We aggregate them together here using simple addition
    # after zscore-ing them
    combined_rank = (value.zscore() + quality.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, mask=universe)
    shorts = combined_rank.bottom(NUM_SHORT_POSITIONS, 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_rank': combined_rank,
        'quality': quality,
        'value': value,
        'sector': sector
    },
                    screen=long_short_screen)
    return pipe
예제 #9
0
def make_pipeline():

    exchange = Fundamentals.exchange_id.latest
    nyse_filter = exchange.eq('NYS')

    morningstar_sector = Sector()

    dollar_volume_decile = AverageDollarVolume(window_length=10).deciles()
    top_decile = (dollar_volume_decile.eq(9))

    return Pipeline(columns={
        'exchange': exchange,
        'sector_code': morningstar_sector,
        'dollar_volume_decile': dollar_volume_decile
    },
                    screen=(nyse_filter & top_decile))
예제 #10
0
def make_pipeline():

    # Define universe
    # ===============================================
    base_universe = QTradableStocksUS()
    value = morningstar.valuation_ratios.ev_to_ebitda.latest
    market_cap = morningstar.valuation.market_cap.latest > 2e9
    #Screen Value
    universe1 = value.bottom(2 * (NUM_LONG_POSITIONS + NUM_SHORT_POSITIONS),
                             mask=(QTradableStocksUS() & market_cap))
    universe2 = value.top(2 * (NUM_LONG_POSITIONS + NUM_SHORT_POSITIONS),
                          mask=(QTradableStocksUS() & market_cap))
    #Screen Quality
    #universe3 =
    #universe4 =
    universe = base_universe & (universe1 | universe2)
    sector = Sector(mask=universe)  # sector needed to construct portfolio
    # ===============================================

    factors = make_factors()

    combined_alpha = None
    for name, f in factors.iteritems():
        if combined_alpha == None:
            combined_alpha = f(mask=universe)
        else:
            combined_alpha = combined_alpha + f(mask=universe)

    longs = combined_alpha.top(NUM_LONG_POSITIONS)
    shorts = combined_alpha.bottom(NUM_SHORT_POSITIONS)

    long_short_screen = (longs | shorts)

    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={
        'combined_alpha': combined_alpha,
        'sector': sector,
        'market_beta': beta
    },
                    screen=long_short_screen)
    return pipe
예제 #11
0
def make_pipeline():
    
   # Define universe
   # ===============================================    
    base_universe = QTradableStocksUS() 
    value = morningstar.valuation_ratios.ev_to_ebitda.latest
    market_cap = morningstar.valuation.market_cap.latest > 2e9   
    Long_universe = value.bottom(5*(NUM_LONG_POSITIONS), mask = (QTradableStocksUS() & market_cap))
    Short_universe = value.top(5*(NUM_LONG_POSITIONS), mask = (QTradableStocksUS() & market_cap))
    sector_code = morningstar.asset_classification.morningstar_sector_code.latest
    sector_screen = (~sector_code.eq(103) and ~sector_code.eq(104) )
    universe = QTradableStocksUS() & market_cap & sector_screen & (Long_universe | Short_universe)
    sector = Sector(mask=universe)  # sector needed to construct portfolio
    # ===============================================
    factors = make_factors()
    
    combined_alpha = None
    for name, f in factors.iteritems():
        if combined_alpha == None:
            combined_alpha = f(mask=universe)
        else:
            combined_alpha = combined_alpha + f(mask=universe)
    
    longs = combined_alpha.top(NUM_LONG_POSITIONS)
    #longs = (Long_universe & Quality)
    shorts = combined_alpha.bottom(NUM_SHORT_POSITIONS)
    #shorts = (Short_universe & bad_quality)
    long_short_screen = (longs | shorts)
    
    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 = {
        'combined_alpha':combined_alpha,
        'sector':sector,
        'market_beta':beta
    },
    screen = long_short_screen)
    return pipe
예제 #12
0
def make_pipeline():
    """
    Create our pipeline.
    """

    # Base universe set to the Q1500US.
    base_universe = Q1500US()

    # 30-day close price average.
    mean_30 = ExponentialWeightedMovingAverage(inputs=[USEquityPricing.close],
                                               window_length=30,
                                               mask=base_universe,
                                               decay_rate=0.9)

    # 120-day close price average.
    mean_120 = ExponentialWeightedMovingAverage(inputs=[USEquityPricing.close],
                                                window_length=120,
                                                mask=base_universe,
                                                decay_rate=0.9)

    percent_difference = (mean_30 - mean_120) / mean_120

    # Filter to select securities to long.
    longs = percent_difference.top(50)
    long_value = percent_difference

    # sector attribution
    sector = Sector()

    #pipeline construction
    return Pipeline(
        columns={
            'long value': long_value,
            'sector': sector
        },
        screen=longs,
    )
예제 #13
0
def make_pipeline():
    pipe = Pipeline()
    '''standards'''
    book_to_price = 1 / Latest([Fundamentals.pb_ratio])
    earning_to_price = 1 / Latest([Fundamentals.pe_ratio])
    #research_and_development = Latest([Fundamentals.research_and_development])
    gross_dividend_payment = Latest([Fundamentals.gross_dividend_payment])
    value_score = Latest([Fundamentals.value_score])
    returns = Returns(inputs=[USEquityPricing.close], window_length=2)
    '''filter'''
    mask = QTradableStocksUS()
    mask &= Sector().eq(sector)
    #mask &= value_score > 70
    mask &= USEquityPricing.volume.latest > 10000
    '''pipeline'''
    pipe = Pipeline(columns={
        'Returns': returns,
        'B/P': book_to_price,
        'E/P': earning_to_price,
        'Dividends': gross_dividend_payment,
        'Value_score': value_score
    },
                    screen=mask)
    return pipe
예제 #14
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
    mask = QTradableStocksUS() & Sector().notnull()
    mask &= (Fundamentals.market_cap.latest > 1000000000)
    mask &= (
        (Fundamentals.morningstar_sector_code.latest != 103) &
        (Fundamentals.morningstar_sector_code.latest != 207) &
        (Fundamentals.morningstar_sector_code.latest != 206) &
        (Fundamentals.morningstar_sector_code.latest != 309) &
        (Fundamentals.morningstar_industry_code.latest != 20533080) &
        (Fundamentals.morningstar_industry_code.latest != 10217033) &
        (Fundamentals.morningstar_industry_group_code != 10106) &
        (Fundamentals.morningstar_industry_group_code != 10104)
    )
    
    #mask &= (Fundamentals.total_debt_equity_ratio.latest < 1.0)
    
    earnings_yield = Fundamentals.ebit.latest/Fundamentals.enterprise_value.latest
    EY_rank   = earnings_yield.rank(ascending=False, mask=mask)
    
    roic      = Fundamentals.roic.latest
    roic_rank = roic          .rank(ascending=False, mask=mask)
    
    debt_equity = Fundamentals.total_debt_equity_ratio.latest
    debt_equity_rank = debt_equity.rank(ascending=True, mask=mask)  # lower is better
    
    div_yield = Fundamentals.trailing_dividend_yield.latest
    div_rank = div_yield.rank(ascending=False, mask=mask)  # higher is better
    
    gross_margin = Fundamentals.gross_margin.latest
    gross_margin_rank = gross_margin.rank(ascending=False, mask=mask)
    
    rnd_ocf = Fundamentals.research_and_development.latest / Fundamentals.operating_cash_flow.latest
    rnd_ocf_rank = rnd_ocf.rank(ascending=False, mask=mask)
    
    total_yield = Fundamentals.total_yield.latest
    total_yield_rank = total_yield.rank(ascending=False, mask=mask)
    
    ma50 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=50, mask=mask)
    ma200 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=200, mask=mask)
    mv_yield = ma50 / ma200
    mv_yield_rank = mv_yield.rank(ascending=False, mask=mask)
    
    revenue_growth = Fundamentals.revenue_growth.latest
    revenue_growth_rank = revenue_growth.rank(ascending=False, mask=mask)
    
    
    mf_rank   = np.sum([
                        EY_rank,
                        roic_rank,  # returns = 24.12%, alpha = -.09, beta = 1.3, sharpe = .47, drawdown = -27.95%
                        debt_equity_rank, # returns = 35.45%, alpha = -.04, beta = 1.18, sharpe = .65, drawdown = -30.26%
                        #div_rank,  # returns = 30.44%, alpha = -.05, beta = 1.07, sharpe = .65, drawdown = -22.73%
                        gross_margin_rank,
                        rnd_ocf_rank,
                        total_yield_rank,
                        revenue_growth_rank,
                        #
                       ])

    
    # Factor of yesterday's close price.
    yesterday_close = USEquityPricing.close.latest

    pipe = Pipeline(
        columns={
            'mf_rank'       : mf_rank,
        },
        screen=mask
    )
    return pipe
def make_pipeline():
    # Windows used for moving averages
    windows = [10, 20, 50]

    price = USEquityPricing.close.latest

    # Let's calculate moving averages based on our windows
    price_ma_10 = SimpleMovingAverage(inputs=[USEquityPricing.close],
                                      window_length=windows[0])
    price_ma_20 = SimpleMovingAverage(inputs=[USEquityPricing.close],
                                      window_length=windows[1])
    price_ma_50 = SimpleMovingAverage(inputs=[USEquityPricing.close],
                                      window_length=windows[2])

    # Score the divergence
    momentum_score = .67 * (
        (price_ma_10 - price_ma_20) / price_ma_20) + .33 * (
            (price_ma_20 - price_ma_50) / price_ma_50)
    momentum_abs = momentum_score.abs()

    # Top decile of momentum_scores are our longs and bottom ten are shorts
    score_deciles = momentum_score.deciles()
    bottom_ten = score_deciles.eq(0)
    top_ten = score_deciles.eq(9)

    ################################################
    # Now let's filter out all stocks we don't want:
    ################################################

    # Screening for short positions
    shorts = bottom_ten

    # Screening for long positions
    longs = top_ten

    # Let's get dollar volume moving averages for each stock
    dv_ma_20 = AverageDollarVolume(window_length=20)
    dv_ma_5 = AverageDollarVolume(window_length=5)

    # We only want stocks with notable trade volume >$5,000,000
    dv_min = dv_ma_20 > 5e6

    # We want technology sector stocks
    sector = Sector().eq(Sector.TECHNOLOGY)

    # We don't want super cheap stocks
    not_cheap_stock = (price_ma_10 > 5)

    # Check for increasing trade volume
    inc_volume = dv_ma_5 > dv_ma_20

    # Universe of stocks we want to trade that fit all our criteria
    universe = sector & not_cheap_stock & dv_min & inc_volume & (shorts
                                                                 | longs)

    return Pipeline(
        columns={
            'price': price,
            'price_ma_10': price_ma_10,
            'price_ma_20': price_ma_20,
            'price_ma_50': price_ma_50,
            'dollar_volume': dv_ma_5,
            'momentum_score': momentum_score,
            'momentum_abs': momentum_abs,
            'long_bets': longs,
            'short_bets': shorts,
        },
        screen=universe,
        domain=US_EQUITIES,
    )
def initialize(context):
    # Universe Selection
    # ------------------
    base_universe = QTradableStocksUS()

    # From what remains, each month, take the top UNIVERSE_SIZE stocks by average dollar
    # volume traded.
    monthly_top_volume = (AverageDollarVolume(
        window_length=LIQUIDITY_LOOKBACK_LENGTH).top(
            UNIVERSE_SIZE, mask=base_universe).downsample('week_start'))
    # The final universe is the monthly top volume &-ed with the original base universe.
    # &-ing these is necessary because the top volume universe is calculated at the start
    # of each month, and an asset might fall out of the base universe during that month.
    universe = monthly_top_volume & base_universe

    # Alpha Generation
    # ----------------
    # Compute Z-scores of free cash flow yield and earnings yield.
    # Both of these are fundamental value measures.
    fcf_zscore = Fundamentals.fcf_yield.latest.zscore(mask=universe)
    yield_zscore = Fundamentals.earning_yield.latest.zscore(mask=universe)
    sentiment_zscore = psychsignal.stocktwits.bull_minus_bear.latest.zscore(
        mask=universe)

    # 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.
    combined_alpha = (fcf_zscore + yield_zscore +
                      sentiment_zscore).rank().demean()

    beta = 0.66 * RollingLinearRegressionOfReturns(
        target=sid(8554),
        returns_length=5,
        regression_length=260,
        mask=combined_alpha.notnull() & Sector().notnull()).beta + 0.33 * 1.0

    # 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(),
            'sentiment': sentiment_zscore,
            'beta': beta,
        },
        # 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() & beta.notnull(),
    )

    # Multiple pipelines can be used in a single algorithm.
    algo.attach_pipeline(pipe, 'pipe')
    algo.attach_pipeline(risk_loading_pipeline(), 'risk_loading_pipeline')

    # Schedule a function, 'do_portfolio_construction', to run twice 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,
    )
예제 #17
0
print 'Number of securities that passed the filter: %d' % len(result)
''' 
	8. Classifiers
'''
''' Classifiers '''
# A classifier is a function from an asset and a moment in time to a categorical output
# such as a string or integer label.

from quantopian.pipeline.data import Fundamentals
# Since the underlying data of Fundamentals.exchange_id
# is of type string, .latest returns a Classifier
exchange = Fundamentals.exchange_id.latest

# Using Sector is equivalent to Fundamentals.morningstar_sector_code.latest
from quantopian.pipeline.classifiers.fundamentals import Sector
morningstar_sector = Sector()
''' Building Filters From Classifiers '''
# Classifier Methods:
# 		https://www.quantopian.com/help#quantopian_pipeline_classifiers_Classifier

# If we wanted a filter to select securities trading on the New York Stock Exchange,
# we can use the eq method of our exchange classifier.
nyse_filter = exchange.eq('NYS')
''' Quantiles '''
# Classifiers can also be produced from various Factor methods.
# The most general of these is the quantiles method,
# which accepts a bin count as an argument.
# The quantiles classifier assigns a label from 0 to (bins - 1) to
# every non-NaN data point in the factor output. NaNs are labeled with -1.
# Aliases are available for quartiles (quantiles(4)), quintiles (quantiles(5)),
# and deciles (quantiles(10)). As an example, this is what a filter for the
예제 #18
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 = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
    quality = Fundamentals.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 = Fundamentals.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
예제 #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 set to the QTradableStocksUS
    mask = QTradableStocksUS() & Sector().notnull()
    mask &= (F.market_cap.latest > 1000000000)
    mask &= ((F.morningstar_sector_code.latest != 103) &
             (F.morningstar_sector_code.latest != 207) &
             (F.morningstar_sector_code.latest != 206) &
             (F.morningstar_sector_code.latest != 309) &
             (F.morningstar_industry_code.latest != 20533080) &
             (F.morningstar_industry_code.latest != 10217033) &
             (F.morningstar_industry_group_code != 10106) &
             (F.morningstar_industry_group_code != 10104))
    mask &= (F.morningstar_sector_code.latest == 311)
    revenue_growth = F.revenue_growth.latest
    revenue_growth_rank = revenue_growth.rank(ascending=False,
                                              mask=mask)  # higher is better

    rule_40 = F.revenue_growth.latest + F.net_margin.latest
    rule_40_rank = rule_40.rank(ascending=False, mask=mask)  # higher is better

    ps_ratio = F.ps_ratio.latest
    ps_ratio_rank = ps_ratio.rank(ascending=True, mask=mask)  # lower is better

    # relative historical self price to sales
    mean_ps = MeanPS()
    rel_ps = F.ps_ratio.latest / mean_ps
    rel_ps_rank = rel_ps.rank(ascending=True, mask=mask)  # lower is better

    # run rate := cash on hand / operating expense
    run_rate = F.cash_and_cash_equivalents.latest / F.operating_expense
    run_rate_rank = run_rate.rank(ascending=False,
                                  mask=mask)  # higher is better

    gross_margin = F.gross_margin.latest
    gross_margin_rank = gross_margin.rank(ascending=False, mask=mask)

    # Factor of yesterday's close price.
    yesterday_close = USEquityPricing.close.latest

    rank = np.sum([
        #rule_40_rank,
        #rel_ps_rank,
        #run_rate_rank,
        #revenue_growth_rank,
        ps_ratio_rank,
        gross_margin_rank,
    ])

    pipe = Pipeline(columns={
        'close': yesterday_close,
        'rank': rank,
    },
                    screen=mask)
    return pipe
예제 #20
0
def make_pipeline():

    base_universe = QTradableStocksUS()

    latest_close = USEquityPricing.close.latest
    latest_volume = USEquityPricing.volume.latest
    latest_close = USEquityPricing.close.latest
    mkt_cap = morningstar.valuation.market_cap.latest
    symbol_float1 = morningstar.Fundamentals.shares_outstanding.latest
    symbol_float2 = morningstar.Fundamentals.ordinary_shares_number.latest
    morningstar_sector = Sector()

    volume_3_months = AverageDollarVolume(
        window_length=66,
        mask=base_universe & (mkt_cap < 5000000000)  #masking 
    )

    volume_1_day = AverageDollarVolume(
        window_length=1,
        mask=base_universe & (mkt_cap < 5000000000)  #masking 
    )

    mean_close_30 = SimpleMovingAverage(
        inputs=[USEquityPricing.close],
        window_length=30,
        mask=base_universe & (mkt_cap < 5000000000)  #masking
    )

    rv = volume_1_day / volume_3_months

    high_52_w = High252()
    high_3_m = High66()
    low_52_w = Low252()

    # price at 30%, 50%, 60% and 90% respectively of the yearly price range
    third_range = (high_52_w - low_52_w) * (1 / 3) + low_52_w
    half_range = (high_52_w - low_52_w) * 0.5 + low_52_w
    sixty_range = (high_52_w - low_52_w) * 0.6 + low_52_w
    ninty_range = (high_52_w - low_52_w) * 0.9 + low_52_w
    fifteen_range = (high_52_w - low_52_w) * 0.15 + low_52_w

    #create the price range for potential longs
    long_range = (latest_close <= sixty_range) & (latest_close >= third_range)

    #take profit range
    tp_range = latest_close >= ninty_range

    #stop loss range
    sl_range = latest_close <= fifteen_range

    valid_open_position_range = (latest_close <=
                                 ninty_range) & (latest_close >= fifteen_range)

    #filters (the data type is a zipline pipeline filter not a df)
    # returns True or False per row (per symbol):
    close_price_filter = (latest_close < 15)
    price_under_30mva = latest_close < mean_close_30  #price under 30 mva

    #create a list of stocks for potential longs
    universe = close_price_filter & base_universe & (mkt_cap < 5000000000)

    # create the "go long" critera
    longs = price_under_30mva & long_range

    return Pipeline(columns={
        'latest_close': latest_close,
        'rv': rv,
        'stop_loss': sl_range,
        'take_profit': tp_range,
        'valid_open_position': valid_open_position_range,
        'longs': longs
    },
                    screen=universe)