Beispiel #1
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.
    """

    # Basic momentum metrics.
    cross_momentum = CrossSectionalMomentum()

    abs_momentum = Returns(inputs=[USEquityPricing.close], window_length=252)

    # We only want to trade relatively liquid stocks.
    # Build a filter that only passes stocks that have $10,000,000 average
    # daily dollar volume over the last 20 days.
    dollar_volume = AverageDollarVolume(window_length=20)
    is_liquid = (dollar_volume > 1e7)

    # We also don't want to trade penny stocks, which we define as any stock with an
    # average price of less than $5.00 over the last 200 days.
    sma_200 = SimpleMovingAverage(inputs=[USEquityPricing.close],
                                  window_length=200)
    not_a_penny_stock = (sma_200 > 5)

    # Before we do any other ranking, we want to throw away the bad assets.
    initial_screen = (is_liquid & not_a_penny_stock)

    # 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 passed `initial_screen`.
    combined_rank = (cross_momentum.rank(mask=initial_screen) +
                     abs_momentum.rank(mask=initial_screen))

    # Build Filters representing the top and bottom 5% of stocks by our combined ranking system.
    # We'll use these as our tradeable universe each day.
    longs = combined_rank.percentile_between(95, 100)
    shorts = combined_rank.percentile_between(0, 5)

    # The final output of our pipeline should only include
    # the top/bottom 5% of stocks by our criteria.
    pipe_screen = (longs | shorts)

    pipe_columns = {
        'longs': longs,
        'shorts': shorts,
        'combined_rank': combined_rank,
        'abs_momentum': abs_momentum,
        'cross_momentum': cross_momentum
    }

    # Create pipe
    pipe = Pipeline(columns=pipe_columns, screen=pipe_screen)
    return pipe
Beispiel #2
0
def initialize(context):

    # UNIVERSE DECLARATION
    universe = QTradableStocksUS()

    # ATTACH PIPELINE NAME
    pipe = Pipeline(screen=universe)
    attach_pipeline(pipe, 'my pipe')

    # ADD SECTOR TO THE PIPELINE
    sector = Fundamentals.morningstar_sector_code.latest
    pipe.add(sector, 'sector')

    # ADD MONTHLY RETURN FACTOR AND RANKED RETURN FACTOR
    monthly_return = Returns(window_length=21)
    monthly_rank = monthly_return.rank(mask=universe)
    pipe.add(monthly_return, 'Mreturn')
    pipe.add(monthly_rank, 'Mrank')

    # ADD CUMULATIVE MONTHLY RETURNS TO THE PIPELINE
    prod_return = np.prod(monthly_return)
    pipe.add(prod_return, 'prodReturn')

    # DEFINE OUR PRE-FILTERED LONG AND SHORT LISTS
    longs = (prod_return > 0)
    pipe.add(longs, 'longs')

    # SETTINGS
    #----------

    # SCHEDULE SETTINGS FOR THE 'REBALANCE' FUNCTION
    schedule_function(func=rebalance,
                      date_rule=date_rules.month_start(),
                      time_rule=time_rules.market_open(),
                      half_days=True)

    # SCHEDULE SETTINGS FOR THE 'RECORD VARS' FUNCTION
    schedule_function(func=record_vars,
                      date_rule=date_rules.month_start(),
                      time_rule=time_rules.market_open(),
                      half_days=True)

    # LEVERAGE SETTINGS (CAN BE ADJUSTED)
    context.long_leverage = 0.5
    context.short_leverage = -0.5

    # SLIPPAGE SETTINGS (CAN BE ADJUSTED - DEFAULT)
    set_slippage(us_equities=slippage.FixedBasisPointsSlippage(
        basis_points=5, volume_limit=0.1))

    # COMMISSION SETTINGS (CAN BE ADJUSTED - SET TO INTERACTIVE BROKERS COMMISSION PRICING)
    set_commission(
        us_equities=commission.PerShare(cost=0.005, min_trade_cost=1))
def make_pipeline(context):
    """
    A function to create our pipeline (dynamic security selector). The pipeline is used
    to rank securities based on different factors, including builtin facotrs, or custom 
    factors that you can define. Documentation on pipeline can be found here:
        https://www.quantopian.com/help#pipeline-title
    """

    # Create a pipeline object.
    pipe = Pipeline()

    # Create a dollar_volume factor using default inputs and window_length.
    # This is a builtin factor.
    dollar_volume = AverageDollarVolume(window_length=1)
    pipe.add(dollar_volume, 'dollar_volume')

    # Create a recent_returns factor with a 5-day returns lookback. This is
    # a custom factor defined below (see RecentReturns class).
    recent_returns = Returns(window_length=context.returns_lookback)
    pipe.add(recent_returns, 'recent_returns')

    # Define high dollar-volume filter to be the top 5% of securities by dollar volume.
    high_dollar_volume = dollar_volume.percentile_between(95, 100)

    # Define high and low returns filters to be the bottom 10% and top 10% of
    # securities in the high dollar-volume group.
    low_returns = recent_returns.percentile_between(0,
                                                    10,
                                                    mask=high_dollar_volume)
    high_returns = recent_returns.percentile_between(90,
                                                     100,
                                                     mask=high_dollar_volume)

    # Factors return a scalar value for each security in the entire universe
    # of securities. Here, we add the recent_returns rank factor to our pipeline
    # and we provide it with a mask such that securities that do not pass the mask
    # (i.e. do not have high dollar-volume), are not considered in the ranking.
    pipe.add(recent_returns.rank(mask=high_dollar_volume),
             'recent_returns_rank')

    # Add a filter to the pipeline such that only high-return and low-return
    # securities are kept.
    pipe.set_screen(low_returns | high_returns)

    # Add the low_returns and high_returns filters as columns to the pipeline so
    # that when we refer to securities remaining in our pipeline later, we know
    # which ones belong to which category.
    pipe.add(low_returns, 'low_returns')
    pipe.add(high_returns, 'high_returns')

    return pipe
Beispiel #4
0
def make_pipeline():
    # get factors
    mktcap = Fundamentals.market_cap.latest
    price_close = USEquityPricing.close.latest

    # get factors, higher is better
    roe = Fundamentals.roe.latest
    fcf_yield = Fundamentals.fcf_yield.latest
    ret_20 = Returns(window_length=20)

    # compare built-in valuation ratio with manually calculated
    price_close = USEquityPricing.close.latest
    fcf_per_share = Fundamentals.fcf_per_share.latest
    fcf_yield_manual = fcf_per_share / price_close

    # get ranks, masked by the universe, higher is better
    quality = roe.rank(method='average', mask=min_liq_univ())
    value = fcf_yield.rank(method='average', mask=min_liq_univ())
    momentum = ret_20.rank(method='average', mask=min_liq_univ())

    # combine ranks
    qvm = (quality + value + momentum).rank(method='average',
                                            mask=min_liq_univ())

    # Sort into 10 deciles
    num_quantiles = 10
    qvm_quantiles = qvm.quantiles(num_quantiles, mask=min_liq_univ())
    long_decile = qvm_quantiles.eq(num_quantiles - 1)
    short_decile = qvm_quantiles.eq(0)

    # Get top 10 and bottom 10 stocks by rank
    long_10 = qvm.top(10, mask=min_liq_univ())
    short_10 = qvm.bottom(10, mask=min_liq_univ())

    return Pipeline(columns={
        'mktcap': mktcap,
        'fcf_yield': fcf_yield,
        'fcf_yield_manual': fcf_yield_manual,
        'roe': roe,
        'ret_20': ret_20,
        'quality': quality,
        'value': value,
        'momentum': momentum,
        'qvm': qvm,
        'long_10': long_10
    },
                    screen=min_liq_univ())
def make_pipeline(context):
    """
    A function to create our pipeline (dynamic security selector). The pipeline is used
    to rank securities based on different factors, including builtin facotrs, or custom 
    factors that you can define. Documentation on pipeline can be found here:
        https://www.quantopian.com/help#pipeline-title
    """
    
    # Create a pipeline object. 
    pipe = Pipeline()
    
    # Create a dollar_volume factor using default inputs and window_length.
    # This is a builtin factor.
    dollar_volume = AverageDollarVolume(window_length=1)
    pipe.add(dollar_volume, 'dollar_volume')
    
    # Create a recent_returns factor with a 5-day returns lookback. This is
    # a custom factor defined below (see RecentReturns class).
    recent_returns = Returns(window_length=context.returns_lookback)
    pipe.add(recent_returns, 'recent_returns')
    
    # Define high dollar-volume filter to be the top 5% of securities by dollar volume.
    high_dollar_volume = dollar_volume.percentile_between(95, 100)
    
    # Define high and low returns filters to be the bottom 10% and top 10% of
    # securities in the high dollar-volume group.
    low_returns = recent_returns.percentile_between(0,10,mask=high_dollar_volume)
    high_returns = recent_returns.percentile_between(90,100,mask=high_dollar_volume)
    
    # Factors return a scalar value for each security in the entire universe
    # of securities. Here, we add the recent_returns rank factor to our pipeline
    # and we provide it with a mask such that securities that do not pass the mask
    # (i.e. do not have high dollar-volume), are not considered in the ranking.
    pipe.add(recent_returns.rank(mask=high_dollar_volume), 'recent_returns_rank')
    
    # Add a filter to the pipeline such that only high-return and low-return
    # securities are kept.
    pipe.set_screen(low_returns | high_returns)
    
    # Add the low_returns and high_returns filters as columns to the pipeline so
    # that when we refer to securities remaining in our pipeline later, we know
    # which ones belong to which category.
    pipe.add(low_returns, 'low_returns')
    pipe.add(high_returns, 'high_returns')
    
    return pipe
Beispiel #6
0
def make_pipeline():
    """
    pipeline を作る
    make_pipeline を作ったほうが,research にもコピペして使えるし,テストや修正も簡単に出来るので,幸せになれます
    """
    # クロスモメンタム
    cross_momentum = CrossSectionalMomentum()
    # Returns で過去252分全てのクローズベースのリターンを取得
    abs_momentum = Returns(input=[USEquityPricing.close], window_length = 252)
    # 流動性がある株式だけ取引する.過去20日間,平均1千万ドル平均の取引高(price*volume)があるものだけを取引
    dollar_volume = AverageDollarVolume(window_length=20)
    is_liquid = (dollar_volume > le7) 
    # 過去200日平均で株価5ドル以下のペニーストックはトレードしない.
    sma_200 = SimpleMovingAverage(inputs = [USEquityPricing.close], window_length=200)
    not_a_penny_stock = (sma_200 > 5) 
    # 不必要な銘柄は取り除く
    initial_screen = (is_liquid & not_a_penny_stock)
    # cross momentum を適用したあとに,ランク付けをする
    combined_rank = (cross_momentum.rank(mask=initial_screen) + abs_momentum.rank(mask=initial_screen))
    # top 5 % をロング    
    longs = combined_rank.percentile_between(95, 100)
    shorts = combined_rank.percentile_between(0, 5)
    # パイプラインにロングショートする銘柄を取得
    pipe_screen = (longs | shorts) 
    
    pipe_columns = {
        'longs': longs,
        'shorts': shorts,
        'combined_rank': combined_rank, 
        'abs_momentum': abs_momentum, 
        'cross_momentum': cross_momentum, 
    }
    
    # パイプ作成
    pipe = Pipeline(columns=pipe_columns, screen=pipe_screen)
    return pipe
def make_pipeline(context):
    #create pipeline
    pipe = Pipeline()

    #use built in factor AverageDollarVolume to screen for liquid stocks
    avg_dollar_volume = AverageDollarVolume(window_length=1)
    pipe.add(avg_dollar_volume, 'avg_dollar_volume')

    #use built in factor Returns to get returns over the recent_lookback window
    recent_returns = Returns(window_length=context.returns_lookback)
    pipe.add(recent_returns, 'recent_returns')

    #filter out stocks in the top % of dollar volume
    high_dollar_volume = avg_dollar_volume.percentile_between(95, 100)

    #rank the recent returns in the high dollar volume group and add to pipe
    pipe.add(recent_returns.rank(mask=high_dollar_volume),
             'recent_returns_rank')

    #get stocks with the highest and lowest returns in the high dollar volume         group
    low_returns = recent_returns.percentile_between(0,
                                                    10,
                                                    mask=high_dollar_volume)

    high_returns = recent_returns.percentile_between(90,
                                                     100,
                                                     mask=high_dollar_volume)

    #add high and low returns as columns to pipeline for easier data mgmt
    pipe.add(high_returns, 'high_returns')
    pipe.add(low_returns, 'low_returns')

    ######Earnings Announcement Risk Framework#############
    # https://www.quantopian.com/data/eventvestor/earnings_calendar
    # EarningsCalendar.X is the actual date of the announcement
    # E.g. 9/12/2015
    pipe.add(EarningsCalendar.next_announcement.latest, 'next')
    pipe.add(EarningsCalendar.previous_announcement.latest, 'prev')

    # BusinessDaysX is the integer days until or after the closest
    # announcement. So if AAPL had an earnings announcement yesterday,
    # prev_earnings would be 1. If it's the day of, it will be 0.
    # For BusinessDaysUntilNextEarnings(), it is common that the value
    # is NaaN because we typically don't know the precise date of an
    # earnings announcement until about 15 days before
    ne = BusinessDaysUntilNextEarnings()
    pe = BusinessDaysSincePreviousEarnings()
    pipe.add(ne, 'next_earnings')
    pipe.add(pe, 'prev_earnings')

    # The number of days before/after an announcement that you want to
    # avoid an earnings for.
    # pipe.set_screen ( (ne.isnan() | (ne > 3)) & (pe > 3) )

    #####Set Pipe based on the desired framework######
    #screen the pipeline by the high and low returns(and high dollar volume, implicitly
    pipe.set_screen(high_returns | low_returns
                    | ((ne.isnan() | (ne > 3)) & (pe > 3)))
    # pipe.set_screen(high_returns | low_returns)

    return pipe