def make_pipeline(): # Screen out penny stocks and low liquidity securities. dollar_volume = AverageDollarVolume(window_length=20) is_liquid = dollar_volume.rank(ascending=False) < 1000 # Create the mask that we will use for our percentile methods. base_universe = (is_liquid) # Filter down to stocks in the top/bottom 10% by sentiment rank factor = WeightedSentimentByVolatility() longs = factor.percentile_between(90, 100, mask=base_universe) shorts = factor.percentile_between(0, 10, mask=base_universe) # Add Accern to the Pipeline pipe_columns = { 'longs':longs, 'shorts':shorts } # Set our pipeline screens pipe_screen = (longs | shorts) & (factor != 0) # Create our pipeline pipe = Pipeline(columns = pipe_columns, screen = pipe_screen) return pipe
def make_pipeline(): base_universe = Q1500US() yesterday_close = PrevClose() yesterday_volume = PrevVolume() dollar_volume = AverageDollarVolume(window_length=30) # rsi = RSI()#default window_length = 15 # rsi_under_60 = rsi < 60 ## gap = today_open / yesterday_close - 1 では出来ない. ## TypeError: unsupported operand type(s) for /: 'BoundColumn' and 'BoundColumn' # gap = Gap() #ToDo この範囲を色々変えてみる. high_dollar_volume = dollar_volume.percentile_between(98, 100) pipe = Pipeline( columns = { 'yesterday_close': yesterday_close, 'yesterday_volume': yesterday_volume, 'yesterday_turnover': yesterday_close * yesterday_volume, 'dollar_volume': dollar_volume, 'high_dollar_volume': high_dollar_volume, # 'gap': gap, # 'rsi': rsi, }, screen = base_universe & high_dollar_volume #& rsi_under_60 ) return pipe
def initialize(context): # Create pipeline pipe = Pipeline() pipe = attach_pipeline(pipe, name='factors') pipe.add(PsychSignal(), "psychsignal_sentiment") #Screen out penny stocks and low liquidity securities dollar_volume = AverageDollarVolume(window_length=20) # Only look at top 1000 most liquid securities liquidity_rank = dollar_volume.rank(ascending=False) < 200 pipe.set_screen((dollar_volume > 10**7) & (liquidity_rank)) # Set our shorts and longs and define our benchmark context.spy = sid(8554) context.shorts = None context.longs = None schedule_function(rebalance, date_rules.every_day()) schedule_function(cancel_open_orders, date_rules.every_day(), time_rules.market_close()) set_commission(commission.PerShare(cost=0, min_trade_cost=0)) # no cost to trading set_slippage(slippage.FixedSlippage(spread=0))
def make_pipeline(): mean_close_10 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=10) mean_close_30 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=30) rsi_7 = RSI(inputs=[USEquityPricing.close], window_length=10) percent_difference = (mean_close_10 - mean_close_30) / mean_close_30 rsi_under_35 = (rsi_7 < 35) latest_close = USEquityPricing.close.latest dollar_volume = AverageDollarVolume(window_length=30) high_dollar_volume = dollar_volume.percentile_between(85, 100) filters = high_dollar_volume & rsi_under_35 return Pipeline(columns={ '10_day_mean_close': mean_close_10, 'latest_close_price': latest_close, 'percent_difference': percent_difference, 'dollar_value': dollar_volume }, screen=filters)
def my_pipeline(context): """ A function to create our dynamic stock selector (pipeline). Documentation on pipeline can be found here: https://www.quantopian.com/help#pipeline-title """ pipe = Pipeline() # span stands for past 120 days, need doulbe window length to get 120 data point. ewma120 = EWMA.from_span([USEquityPricing.close], window_length=2 * context.look_back_long, span=context.look_back_long) pipe.add(ewma120, "ewma120") ewma60 = EWMA.from_span([USEquityPricing.close], window_length=2 * context.look_back_middle, span=context.look_back_middle) pipe.add(ewma60, "ewma60") ewma15 = EWMA.from_span([USEquityPricing.close], window_length=2 * context.look_back_short, span=context.look_back_short) pipe.add(ewma15, "ewma15") pipe.add(Latest(inputs=[USEquityPricing.close]), "yes_price") momentum = (ewma120 - ewma60).abs() + (ewma60 - ewma15).abs() middle_momentum = momentum.percentile_between(0, 5) # Create a dollar volume factor. dollar_volume = AverageDollarVolume(window_length=1, mask=middle_momentum) pipe.add(dollar_volume, 'dollar_volume') # Pick the top 10% of stocks ranked by dollar volume. high_dollar_volume = dollar_volume.percentile_between(90, 100) pipe.set_screen(high_dollar_volume) return pipe
def make_pipeline(): base_universe = Q1500US() sector = morningstar.asset_classification.morningstar_sector_code.latest energy_sector = sector.eq(309) base_energy = base_universe & energy_sector dollar_volume = AverageDollarVolume(window_length=30) high_dollar_volume = dollar_volume.percentile_between(95, 100) top_half_base_energy = base_energy & high_dollar_volume mean_10 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=10, mask=top_half_base_energy) mean_30 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=30, mask=top_half_base_energy) percent_difference = (mean_10 - mean_30) / mean_30 shorts = percent_difference < 0 longs = percent_difference > 0 securities_to_trade = (shorts | longs) return Pipeline(columns={ 'longs': longs, 'shorts': shorts, 'percent_diff': percent_difference }, screen=securities_to_trade)
def make_pipeline(): pipe = Pipeline() # Base universe set to the QTradableStocksUS base_universe = QTradableStocksUS() #AverageDollarVolume dollar_volume = AverageDollarVolume(window_length=30) high_dollar_volume = dollar_volume.percentile_between(99, 100) # Factor of yesterday's close price. yesterday_close = USEquityPricing.close.latest #price latest_close = EquityPricing.close.latest above_10 = latest_close > 10 #LongPattern LongPattern = (CloseYesterday(inputs = [USEquityPricing.close]) - CloseBeforeYesterday(inputs =[USEquityPricing.close])) / (CloseYesterday(inputs = [USEquityPricing.close])) #pipe.add(LongPattern, 'LongPattern') #LongPatternZscore LongPattern_Zscore = LongPattern.zscore() high_returns = LongPattern_Zscore.percentile_between(99,100) low_returns = LongPattern_Zscore.percentile_between(0,99) #securities_to_trade securities_to_trade = (high_returns | low_returns ) #volume volume_day_before_yeseterday = ValueDaybeforeYesterday(inputs =[USEquityPricing.volume]) volume_change_mean = ChangeAverage(inputs = [USEquityPricing.volume], window_length = 5) my_screen = base_universe & high_dollar_volume & securities_to_trade & above_10 pipe.set_screen(my_screen) return pipe
def initialize(context): # set_commission(commission.PerShare(cost=0, min_trade_cost=None)) # set_slippage(slippage.FixedSlippage(spread=0)) pipe = Pipeline() attach_pipeline(pipe, 'ranked') dollar_volume = AverageDollarVolume(window_length=1) high_dollar_volume = dollar_volume.percentile_between(95, 100) alpha41 = Alpha41(mask=high_dollar_volume) vwap = VWAP(window_length=1) alpha41 = alpha41**.5 - vwap alpha41_rank = alpha41.rank(mask=high_dollar_volume) roe = ROE(mask=high_dollar_volume) combo_raw = (alpha41_rank) pipe.add(combo_raw, 'combo_raw') pipe.set_screen(roe > .005) schedule_function(func=rebalance, date_rule=date_rules.every_day(), time_rule=time_rules.market_open(hours=0, minutes=1)) context.long_leverage = .5 context.short_leverage = -.5 context.short_num = 20 context.long_num = 20
def make_pipeline(): # Base universe filter. base_universe = Q1500US() # Sector Classifier as Filter energy_sector = sector.eq(309) # Masking Base Energy Stocks base_energy = base_universe & energy_sector # Dollar volume factor dollar_volume = AverageDollarVolume(window_length=30) # Top half of dollar volume filter high_dollar_volume = dollar_volume.percentile_between(95,100) # Final Filter Mask top_half_base_energy = base_energy & high_dollar_volume # 10-day close price average. mean_10 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=10, mask=top_half_base_energy) # 30-day close price average. mean_30 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=30, mask=top_half_base_energy) # Percent difference factor. percent_difference = (mean_10 - mean_30) / mean_30 # Create a filter to select securities to short. shorts = percent_difference < 0 # Create a filter to select securities to long. longs = percent_difference > 0 # Filter for the securities that we want to trade. securities_to_trade = (shorts | longs) return Pipeline( columns={ 'longs': longs, 'shorts': shorts, 'percent_diff':percent_difference }, screen=securities_to_trade )
def make_pipeline(): # Universe Q1500US base_universe = Q1500US() # Energy Sector sector = morningstar.asset_classification.morningstar_sector_code.latest energy_sector = sector.eq(309) # Make Mask of 1500US and Energy base_energy = base_universe & energy_sector # Dollar Volume (30 Days) Grab the Info dollar_volume = AverageDollarVolume(window_length=30) # Grab the top 5% in avg dollar volume high_dollar_volume = dollar_volume.percentile_between(95,100) # Combine the filters top_five_base_energy = base_energy & high_dollar_volume # 10 day mean close mean_10 = SimpleMovingAverage(inputs=[USEquityPricing.close],window_length=10,mask=top_five_base_energy) # 30 day mean close mean_30 = SimpleMovingAverage(inputs=[USEquityPricing.close],window_length=30,mask=top_five_base_energy) # Percent Difference percent_difference = (mean_10-mean_30)/mean_30 # List of Shorts shorts = percent_difference < 0 # List of Longs longs = percent_difference > 0 # Final Mask/Filter for anything in shorts or longs securities_to_trade = (shorts | longs) # Return Pipeline return Pipeline(columns={ 'longs':longs, 'shorts':shorts, 'perc_diff':percent_difference },screen=securities_to_trade)
def make_pipeline(): # UNIVERSE Q1500US base_universe = Q1500US() # ENERGY SECTOR (OR: sector = Sector()) sector = morningstar.asset_classification.morningstar_sector_code.latest energy_sector = sector.eq(309) # MAKE MASK OF 1500US & ENERGY base_energy = base_universe & energy_sector # DOLLAR VOLUME (30 Days) GRAB THE INFO dollar_volume = AverageDollarVolume(window_length=30) # GRAB THE TOP 5% IN AVERAGE DOLLAR VOLUME high_dollar_volume = dollar_volume.percentile_between(95, 100) # COMBINE THE FILTERS top_five_base_energy = base_energy & high_dollar_volume # GRAB THE 10-day & 30-day MEAN CLOSE mean_10 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=10, mast=top_five_base_energy) mean_30 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=30, mast=top_five_base_energy) # PERCENT DIFFERNENCE percent_difference = (mean_10 - mean_30) / mean_30 # LIST OF SHORTS & LONGS shorts, longs = (percent_difference < 0), (percent_difference > 0) # FINAL MASK/FILTER FOR ANYTHING IN SHORTS / LONGS securities_to_trade = shorts & longs # RETURN THE PIPELINE return Pipeline(columns={ 'longs': longs, 'shorts': shorts, 'percent_diff': percent_difference }, screen=securities_to_trade)
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
def make_pipeline(): dollar_volume = AverageDollarVolume(window_length=30) is_liquid = dollar_volume.top(500) avg_sentiment = AvgSentiment(inputs=[sentdex.sentiment_signal], window_length=10) return Pipeline(columns={'sentiment': avg_sentiment}, screen=is_liquid)
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
def make_pipeline(): dollar_volume = AverageDollarVolume(window_length=1) high_dollar_volume = dollar_volume.percentile_between(99, 100) pipe = Pipeline( screen = high_dollar_volume, columns = {'dollar_volume': dollar_volume} ) return pipe
def initialize(context): #sell criteria the morning of -_- schedule_function(sellaII, date_rules.every_day(), time_rules.market_open(minutes=1)) #cancel all open orders before buy criteria schedule_function(sellaIII, date_rules.every_day(), time_rules.market_close(minutes=8)) #sell all (4 mins before sell all positions) schedule_function(selaV, date_rules.every_day(), time_rules.market_close(minutes=7)) for i in range(30, 380): schedule_function(sell_criteria, date_rules.every_day(), time_rules.market_open(minutes=i)) #pipeine initialization (2 mins before buy criteria) schedule_function(be4tradestart, date_rules.every_day(), time_rules.market_close(minutes=6)) #buy criteria (3 mins before sell criteria day of) schedule_function(examplee, date_rules.every_day(), time_rules.market_close(minutes=5)) schedule_function(mmarket, date_rules.every_day(), time_rules.market_close(minutes=1)) set_commission(commission.PerTrade(cost=0)) set_commission(commission.PerShare(cost=0, min_trade_cost=0)) set_slippage(slippage.VolumeShareSlippage(volume_limit=1, price_impact=0)) avg_volume = AverageDollarVolume(window_length=10) sma_2 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=2) sma_200 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=200) avg_volumee = AverageDollarVolume(window_length=2) volatilityy = AnnualizedVolatility(annualization_factor=252) pipe_screen = ((avg_volume >= 15000000) & (sma_2 >= sma_200) & (avg_volumee >= 3000000) & (sma_2 >= 5.0) & (volatilityy <= 0.93)) pipe_columns = { 'avg voI': avg_volume, 'sma2': sma_2, 'sma200': sma_200, 'avg voII': avg_volumee, 'volatility': volatilityy } pipe = Pipeline(columns=pipe_columns, screen=pipe_screen) attach_pipeline(pipe, 'example') set_long_only()
def make_pipeline(): dollar_volume_pipe = AverageDollarVolume(window_length=20) is_liquid_pipe = dollar_volume_pipe.top(1000) impact = alphaone_free.impact_score.latest sentiment = alphaone_free.article_sentiment.latest return Pipeline(columns={ 'impact': impact, 'sentiment': sentiment }, screen=is_liquid_pipe)
def make_pipeline(): # Screen out penny stocks and low liquidity securities. dollar_volume = AverageDollarVolume(window_length=20) is_liquid = dollar_volume.rank(ascending=False) < 1000 # Add pipeline factors impact = alphaone_free.impact_score.latest sentiment = alphaone_free.article_sentiment.latest return Pipeline(columns={ 'impact': impact, 'sentiment': sentiment, }, screen=is_liquid)
def high_dollar_volume_pipeline(): # Create a pipeline object. pipe = Pipeline() # Create a factor for average dollar volume over the last 63 day (1 quarter equivalent). dollar_volume = AverageDollarVolume(window_length=63) pipe.add(dollar_volume, 'dollar_volume') # Define high dollar-volume filter to be the top 5% of stocks by dollar volume. high_dollar_volume = dollar_volume.percentile_between(95, 100) pipe.set_screen(high_dollar_volume) return pipe
def make_pipeline(): dollar_volume = AverageDollarVolume(window_length=20) is_liquid = dollar_volume.top(1000) # impact = alphaone_free.impact_score.latest # sentiment = alphaone_free.article.sentiment.latest # return Pipeline(column={'impact': impact, 'sentiment':sentiment}, screen=is_liquid) avg_sentiment = AvgSentiment(inputs=[sentdex.sentiment_signal], window_length=10) return Pipeline(columns={'sentiment': avg_sentiment}, screen=is_liquid)
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
def make_pipeline(): dollar_vol = AverageDollarVolume(window_length=20) is_liq = dollar_vol.top(1000) # impact = sentiment.sentiment_signal.latest sentiment_score = sentiment.sentiment_signal.latest return Pipeline( columns={ # 'impact': impact, 'sentiment': sentiment_score }, screen=is_liq )
def make_pipeline(context): pipe = Pipeline() base_universe = QTradableStocksUS() dollar_volume = AverageDollarVolume(window_length=30) high_dollar_volume = dollar_volume.percentile_between(98, 100) close_day_before_yeseterday = ValueDaybeforeYesterday( inputs=[USEquityPricing.close]) volume_day_before_yeseterday = ValueDaybeforeYesterday( inputs=[USEquityPricing.volume]) pipe.add(close_day_before_yeseterday, "close_day_before_yeseterday") my_screen = base_universe & high_dollar_volume pipe.set_screen(my_screen) return pipe
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 """ # Create a dollar volume factor. dollar_volume = AverageDollarVolume(window_length=1) # Pick the top 1% of stocks ranked by dollar volume. high_dollar_volume = dollar_volume.percentile_between(99, 100) pipe = Pipeline( # screen = (high_dollar_volume & Q500US()), screen=Q1500US(), columns={'dollar_volume': dollar_volume}) return pipe
def make_pipeline2(context): primary_share = QTradableStocksUS() price = USEquityPricing.close.latest AtLeastPrice = (price >= context.MyLeastPrice) AtMostPrice = (price <= context.MyMostPrice) # Filter for stocks that pass all of our previous filters. tradeable_stocks = (primary_share & AtLeastPrice & AtMostPrice) log.info(''' Algorithm initialized variables: context.MaxCandidates %s LowVar %s HighVar %s''' % (context.MaxCandidates, context.LowerFilter, context.UpperFilter)) # High dollar volume filter. base_universe = AverageDollarVolume( window_length=20, mask=tradeable_stocks).percentile_between(context.LowerFilter, context.UpperFilter) # Short close price average. ShortSMA = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=context.ShortSmaTerm, mask=base_universe) # Long close price average. LongSMA = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=context.LongSmaTerm, mask=base_universe) percent_difference = (ShortSMA - LongSMA) / LongSMA ADV = AverageDollarVolume(window_length=context.LongSmaTerm, mask=base_universe) # Filter to select securities to long. stocks_worst = percent_difference.bottom(context.MaxCandidates) return Pipeline( columns={ 'average_dollor_vol': ADV, 'stocks_worst': stocks_worst, }, screen=stocks_worst, )
def make_pipeline(): value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest sentiment_score = SimpleMovingAverage( inputs=[stocktwits.total_scanned_messages], window_length=21, ) ty = Fundamentals.total_yield.latest wps = Fundamentals.working_capital_per_share.latest gro = Fundamentals.growth_score.latest dollar_volume = AverageDollarVolume(window_length=63) universe = QTradableStocksUS() dollar_winsorize = dollar_volume.winsorize(min_percentile=0.2, max_percentile=0.8) value_winsorized = value.winsorize(min_percentile=0.05, max_percentile=0.95) sentiment_score_winsorized = sentiment_score.winsorize(min_percentile=0.05, max_percentile=0.95) eps_wisorized = wps.winsorize(min_percentile=0.05, max_percentile=0.95) ty_winsorized = ty.winsorize(min_percentile=0.05, max_percentile=0.95) gro_winsorize = gro.winsorize(min_percentile=0.05, max_percentile=0.95) combined_factor = ( value_winsorized.zscore() *0.15 + gro_winsorize.zscore() *0.25 + sentiment_score_winsorized.zscore()* 0.15 + eps_wisorized.zscore() *0.15 + ty_winsorized.zscore() *0.15 + dollar_winsorize.zscore() *0.15 ) longs = combined_factor.top(TOTAL_POSITIONS//2, mask=universe) shorts = combined_factor.bottom(TOTAL_POSITIONS//2, mask=universe) long_short_screen = (longs | shorts) pipe = Pipeline( columns={ 'longs': longs, 'shorts': shorts, 'combined_factor': combined_factor }, screen=long_short_screen ) return pipe
def make_pipeline(): have_market_cap = morningstar.valuation.market_cap.latest.notnull() avg_volume = SimpleMovingAverage(inputs=[USEquityPricing.volume], window_length=50) filter_volume = avg_volume > 500000 last_price = Latest(inputs=[USEquityPricing.close], window_length=1) filter_price = last_price > 1 dollar_volume = AverageDollarVolume(window_length=50) filter_dollar_volume = dollar_volume > 2500000 sma_150 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=150) filter_sma_150 = USEquityPricing.close.latest > sma_150 atr_10_percent = atr_10days_percent() filter_atr_10 = atr_10_percent > 4 rsi = RSI(inputs=[USEquityPricing.close], window_length=3) filter_overbought = rsi < 30 atr_10 = atr_10days() stocks_to_trade = have_market_cap & filter_volume & filter_price & filter_dollar_volume & filter_sma_150 & filter_atr_10 & filter_overbought return Pipeline(columns={ 'stocks': stocks_to_trade, 'rsi': rsi, 'atr': atr_10 }, screen=(stocks_to_trade))
def filter_universe(): """ 8 filters: - Is a primary share - Is listed as a common stock - Is not a depositary receipt (ADR/GDR) - Is not trading over-the-counter (OTC) - Is not when-issued (WI) - Doesn't have a name indicating it's a limited partnership (LP) - Doesn't have a company reference entry indicating it's a LP - Is not an ETF (has Morningstar fundamental data) """ primary_share = IsPrimaryShare() common_stock = Fundamentals.security_type.latest.eq('ST00000001') not_depositary = ~Fundamentals.is_depositary_receipt.latest not_otc = ~Fundamentals.exchange_id.latest.startswith('OTC') not_wi = ~Fundamentals.symbol.latest.endswith('.WI') not_lp_name = ~Fundamentals.standard_name.latest.matches('.* L[. ]?P.?$') not_lp_balance_sheet = Fundamentals.limited_partnership.latest.isnull() have_market_cap = Fundamentals.market_cap.latest.notnull() # Combine the filters tradeable_stocks = (primary_share & common_stock & not_depositary & not_otc & not_wi & not_lp_name & not_lp_balance_sheet & have_market_cap) # Create final filter for top 30% of tradeable stocks by 20-day average dollar value tradeable_universe = AverageDollarVolume( window_length=20, mask=tradeable_stocks).percentile_between(70, 100) # THESE FILTER SETTINGS CAN BE REPLACED BY THE FILTER Q1500US() for tradeable_universe mask = tradeable_universe return mask
def make_pipeline(): # Base universe set to the QTradableStocksUS base_universe = QTradableStocksUS() #mean average difference 用乖離當作判斷依據 mean_10 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=10, mask=base_universe) mean_30 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=30, mask=base_universe) percent_diff = (mean_10 - mean_30) / mean_30 #dollar vol filter 月交易來看流動性 dollar_vol = AverageDollarVolume(window_length=30) high_dollar_vol = dollar_vol > 10000000 #Filter to select securities to short shorts = percent_diff.top(100, mask=high_dollar_vol) #Filter to select securities to long longs = percent_diff.bottom(100, mask=high_dollar_vol) #Filter for all securities that we want to trade. securities_to_trade = (shorts | longs) & high_dollar_vol return Pipeline(columns={ 'shorts': shorts, 'longs': longs }, screen=securities_to_trade)
def make_pipeline(context): # ベースユニバース base_universe = QTradableStocksUS() # make_pipelineを実行するのは before_trading_start(08:45ET) # 最新のプライスは前日の終値。 yesterday_close = USEquityPricing.close.latest min_price = yesterday_close >= context.MyLeastPrice max_price = yesterday_close <= context.MyMostPrice tradeable_stocks = base_universe & min_price & max_price base_universe = AverageDollarVolume( window_length=20, mask=tradeable_stocks).percentile_between(6, 40) short_sma = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=3, mask=base_universe) long_sma = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=45, mask=base_universe) percent_difference = (short_sma - long_sma) / long_sma #stocks_worst = percent_difference.bottom(context.MaxCandidates) stocks_worst = percent_difference.bottom(context.MaxBuyOrdersAtOnce) pipe = Pipeline(columns={ 'percent_difference': percent_difference, 'close': yesterday_close, }, screen=stocks_worst) return pipe
def make_pipeline(context): # Create our pipeline pipe = Pipeline() # Instantiating our factors factor = PercentSurprise() # Screen out penny stocks and low liquidity securities. dollar_volume = AverageDollarVolume(window_length=20) is_liquid = dollar_volume > 10**7 # Filter down to stocks in the top/bottom longs = (factor >= context.min_surprise) & (factor <= context.max_surprise) # Set our pipeline screens # Filter down stocks using sentiment article_sentiment = alphaone.article_sentiment.latest top_universe = is_liquid & longs & article_sentiment.notnan() & ( article_sentiment > .45) # Add longs to the pipeline pipe.add(top_universe, "longs") pipe.add(BusinessDaysSincePreviousEarnings(), 'pe') return pipe
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
def initialize(context): # Create, register and name a pipeline in initialize. pipe = Pipeline() attach_pipeline(pipe, 'dollar_volume_10m_pipeline') # Construct a 100-day average dollar volume factor and add it to the pipeline. dollar_volume = AverageDollarVolume(window_length=100) pipe.add(dollar_volume, 'dollar_volume') #Create high dollar-volume filter to be the top 2% of stocks by dollar volume. high_dollar_volume = dollar_volume.percentile_between(99, 100) # Set the screen on the pipelines to filter out securities. pipe.set_screen(high_dollar_volume) context.dev_multiplier = 2 context.max_notional = 1000000 context.min_notional = -1000000 context.days_traded = 0 schedule_function(func=process_data_and_order, date_rule=date_rules.every_day())
def initialize(context): context.lookback = 252 # Period to calculate slope and draw down context.maxlever = 1.0 # Leverage context.profittake = 1.96 # 95% bollinger band for profit take context.minimumreturn = 0.1 # Entry if annualized slope is over this level context.maxdrawdown = 0.12 # Avoid security with too much drawdown context.market_impact = 0.2 # Max order is 10% of market trading volume context.weights = {} # Slope at the time of entry. 0 if not to trade context.drawdown = {} # Draw down at the time of entry context.shares = {} # Daily target share schedule_function(regression, date_rules.every_day(), time_rules.market_open(minutes=45)) schedule_function(trade, date_rules.every_day(), time_rules.market_open(minutes=90) schedule_function(trail_stop, date_rules.every_day(), time_rules.market_open(minutes=30)) # Run trailing stop and execution every 30 minutes. for m in range(1, 391): if m % 30 == 0: schedule_function(execute, date_rules.every_day(), time_rules.market_open(minutes = m)) # Create and attach our pipeline (top dollar-volume selector), defined below. attach_pipeline(high_dollar_volume_pipeline(), 'top_dollar_volume') def high_dollar_volume_pipeline(): # Create a pipeline object. pipe = Pipeline() # Create a factor for average dollar volume over the last 62 day (1 quarter equivalent). dollar_volume = AverageDollarVolume(window_length=62) pipe.add(dollar_volume, 'dollar_volume') # Define high dollar-volume filter to be the top 5% of stocks by dollar volume. high_dollar_volume = dollar_volume.percentile_between(95, 100) pipe.set_screen(high_dollar_volume) return pipe def before_trading_start(context, data): context.pipe_output = pipeline_output('top_dollar_volume') context.security_list = context.pipe_output.index # Calculate the slopes for different assetes def regression(context, data): prices = data.history(context.security_list, 'open', context.lookback, '1d') X=range(len(prices)) # Add column of ones so we get intercept A=sm.add_constant(X) for s in context.security_list: # Price movement sd = prices[s].std() # Price points to run regression Y = prices[s].values # If all empty, skip if isnan(Y).any(): continue # Run regression y = ax + b results = sm.OLS(Y,A).fit() (b, a) =results.params # a is daily return. Multiply by 252 to get annualized trend line slope slope = a / Y[-1] * 252 # Daily return regression * 1 year if slope > 0: dd = drawdown(Y) if slope < 0: dd = drawdown(-Y) # Currently how far away from regression line? delta = Y - (dot(a,X) + b) # Don't trade if the slope is near flat slope_min = max(dd, context.minimumreturn) # Max drawdown and minimum return # Current gain if trading gain = get_gain(context, s) # Exits if s in context.weights and context.weights[s] != 0: # Long but slope turns down, then exit if context.weights[s] > 0 and slope < 0: context.weights[s] = 0 log.info('v %+2d%% Slope turn bull %3s - %s' %(gain*100, s.symbol, s.security_name)) # Short but slope turns upward, then exit if context.weights[s] < 0 and 0 < slope: context.weights[s] = 0 log.info('^ %+2d%% Slope turn bear %3s - %s' %(gain*100, s.symbol, s.security_name)) # Profit take, reaches the top of 95% bollinger band if delta[-1] > context.profittake * sd and s in context.weights and context.weights[s] > 0: context.weights[s] = 0 log.info('//%+2d%% Long exit %3s - %s'%(gain*100, s.symbol, s.security_name)) # Profit take, reaches the top of 95% bollinger band if delta[-1] < - context.profittake * sd and context.weights[s] < 0: context.weights[s] = 0 log.info('\\%+2d%% Short exit %3s - %s' %(gain*100, s.symbol, s.security_name)) # Entry else: # Trend is up and price crosses the regression line if slope > slope_min and delta[-1] > 0 and delta[-2] < 0 and dd < context.maxdrawdown: context.weights[s] = slope context.drawdown[s] = slope_min log.info('/ Long a = %+.2f%% %3s - %s' %(slope*100, s.symbol, s.security_name),gain) # Trend is down and price crosses the regression line if slope < -slope_min and delta[-1] < 0 and delta[-2] > 0 and dd < context.maxdrawdown: context.weights[s] = slope context.drawdown[s] = slope_min log.info('\ Short a = %+.2f%% %3s - %s' %(slope*100, s.symbol, s.security_name)) def get_gain(context, s): if s in context.portfolio.positions: cost = context.portfolio.positions[s].cost_basis amount = context.portfolio.positions[s].amount price = context.portfolio.positions[s].last_sale_price if cost == 0: return 0 if amount > 0: gain = price/cost - 1 elif amount < 0: gain = 1 - price/cost else: gain = 0 return gain def trade(context, data): w = context.weights record(leverage_pct = context.account.leverage*100.) record(longs = sum(context.portfolio.positions[s].amount > 0 for s in context.portfolio.positions)) record(shorts = sum(context.portfolio.positions[s].amount < 0 for s in context.portfolio.positions)) positions = sum(w[s] != 0 for s in w) held_positions = [p for p in context.portfolio.positions if context.portfolio.positions[p].amount != 0] context.securities = context.security_list.tolist() + held_positions for s in context.securities: if s not in w: context.shares.pop(s,0) context.drawdown.pop(s,0) elif w[s] == 0: context.shares.pop(s,0) context.drawdown.pop(s,0) context.weights.pop(s,0) elif w[s] > 0: context.shares[s] = context.maxlever/positions elif w[s] < 0: context.shares[s] = -context.maxlever/positions def execute(context,data): open_orders = get_open_orders() for s in context.shares: if not data.can_trade(s) or s in open_orders: continue order_target_percent(s, context.shares[s]) # We are entering into position when slope exceeds the drawdown # If we experience the drawdown again, stop loss def trail_stop(context, data): print get_datetime() print 'Positions: %s' % str(context.portfolio.positions.keys()) prices = data.history(context.portfolio.positions.keys(), 'price', context.lookback, '1d') for s in context.portfolio.positions: if s not in context.weights or context.weights[s] == 0: context.shares[s] = 0 continue if s not in prices or s in get_open_orders(): continue gain = get_gain(context, s) if context.portfolio.positions[s].amount > 0: if drawdown(prices[s].values) > context.drawdown[s]: log.info('x %+2d%% Long stop loss %3s - %s' %(gain * 100, s.symbol, s.security_name)) context.weights[s] = 0 context.shares[s] = 0 elif context.portfolio.positions[s].amount < 0: if drawdown(-prices[s].values) > context.drawdown[s]: log.info('x %+2d%% Short stop loss %3s - %s' %(gain * 100, s.symbol, s.security_name)) context.weights[s] = 0 context.shares[s] = 0 # Reference http://stackoverflow.com/questions/22607324/start-end-and-duration-of-maximum-drawdown-in-python def drawdown(xs): if len(xs) == 0: return 0. i = np.argmax(np.maximum.accumulate(xs) - xs) # end of the period if len(xs[:i]) == 0: return 0. j = np.argmax(xs[:i]) # start of period return abs((xs[i] - xs[j]) / xs[j])