def make_pipeline(): """ Create a pipeline to select stocks each day. """ universe = TradableStocksUS('Real Estate') | TradableStocksUS('Utilities') | \ TradableStocksUS('Consumer Staples') | TradableStocksUS('Technology') | \ TradableStocksUS('Financials') | TradableStocksUS('Energy') | \ TradableStocksUS('Materials') | TradableStocksUS('Health Care') | \ TradableStocksUS('Industrials') | TradableStocksUS('Consumer Discretionary') | \ TradableStocksUS('Communications') roic = shfd.slice(dimension='MRT', period_offset=0).ROIC.latest ebit = shfd.slice(dimension='MRQ', period_offset=0).EBIT.latest ev = shfd.slice(dimension='MRQ', period_offset=0).EV.latest volatility = AnnualizedVolatility(window_length=100) value = ebit / ev roic_rank = roic.rank(mask=universe) value_rank = value.rank(mask=universe) volatility_rank = volatility.rank(mask=universe, ascending=False) spy_ma100_price = SMA(inputs=[USEquityPricing.close], window_length=100)[algo.sid("FIBBG000BDTBL9")] spy_price = USEquityPricing.close.latest[algo.sid("FIBBG000BDTBL9")] momentum_score = MomentumScore() overall_rank = roic_rank + value_rank + volatility_rank # seven_month_returns = Returns(window_length=148, mask=universe,) # one_month_returns = Returns(window_length=30, mask=universe,) pipeline = Pipeline( columns={ 'stock': master.SecuritiesMaster.Symbol.latest, 'sid': master.SecuritiesMaster.Sid.latest, 'sector': master.SecuritiesMaster.usstock_Sector.latest, 'average_dollar_volume': AverageDollarVolume(window_length=200), 'price': EquityPricing.close.latest, 'volume': EquityPricing.volume.latest, 'roic': roic, 'value': value, 'volatility': volatility, 'roic_rank': roic_rank, 'value_rank': value_rank, 'momentum': momentum_score, 'momentum_decile': momentum_score.deciles(), 'volatility_decile': volatility.deciles(), 'overall_rank': overall_rank, 'overall_rank_decile': overall_rank.deciles(), 'trend_filter': spy_price > spy_ma100_price, # 'returns' : one_month_returns - seven_month_returns }, screen=universe) return pipeline
def test_simple_volatility(self): """ Simple test for uniform returns should generate 0 volatility """ nassets = 3 ann_vol = AnnualizedVolatility() today = pd.Timestamp("2016", tz="utc") assets = np.arange(nassets, dtype=np.float64) returns = np.full((ann_vol.window_length, nassets), 0.004, dtype=np.float64) out = np.empty(shape=(nassets, ), dtype=np.float64) ann_vol.compute(today, assets, out, returns, 252) expected_vol = np.zeros(nassets) np.testing.assert_almost_equal(out, expected_vol, decimal=8)
def test_volatility(self): """ Check volatility results against values calculated manually """ nassets = 3 ann_vol = AnnualizedVolatility() today = pd.Timestamp("2016", tz="utc") assets = np.arange(nassets, dtype=np.float64) returns = np.random.normal(loc=0.001, scale=0.01, size=(ann_vol.window_length, nassets)) out = np.empty(shape=(nassets, ), dtype=np.float64) ann_vol.compute(today, assets, out, returns, 252) mean = np.mean(returns, axis=0) annualized_variance = (((returns - mean)**2).sum(axis=0) / returns.shape[0] * 252) expected_vol = np.sqrt(annualized_variance) np.testing.assert_almost_equal(out, expected_vol, decimal=8)
def test_simple_volatility(self): """ Simple test for uniform returns should generate 0 volatility """ nassets = 3 ann_vol = AnnualizedVolatility() today = pd.Timestamp('2016', tz='utc') assets = np.arange(nassets, dtype=np.float64) returns = np.full((ann_vol.window_length, nassets), 0.004, dtype=np.float64) out = np.empty(shape=(nassets,), dtype=np.float64) ann_vol.compute(today, assets, out, returns, 252) expected_vol = np.zeros(nassets) np.testing.assert_almost_equal( out, expected_vol, decimal=8 )
def test_volatility(self): """ Check volatility results against values calculated manually """ nassets = 3 ann_vol = AnnualizedVolatility() today = pd.Timestamp('2016', tz='utc') assets = np.arange(nassets, dtype=np.float64) returns = np.random.normal(loc=0.001, scale=0.01, size=(ann_vol.window_length, nassets)) out = np.empty(shape=(nassets,), dtype=np.float64) ann_vol.compute(today, assets, out, returns, 252) mean = np.mean(returns, axis=0) annualized_variance = ((returns - mean) ** 2).sum(axis=0) / \ returns.shape[0] * 252 expected_vol = np.sqrt(annualized_variance) np.testing.assert_almost_equal( out, expected_vol, decimal=8 )
def make_pipeline(assets): WEIGHT1 = 1.0 WEIGHT2 = 1.0 WEIGHT3 = 1.0 WEIGHT4 = 1.0 etf_universe = StaticAssets(assets) day20_ret = Returns(inputs=[USEquityPricing.close], window_length=21, mask=etf_universe) day3mo_ret = Returns(inputs=[USEquityPricing.close], window_length=63, mask=etf_universe) day6mo_ret = Returns(inputs=[USEquityPricing.close], window_length=126, mask=etf_universe) day1yr_ret = Returns(inputs=[USEquityPricing.close], window_length=252, mask=etf_universe) volatility = AnnualizedVolatility(mask=etf_universe) score = ((WEIGHT1 * day20_ret) + (WEIGHT1 * day3mo_ret) + (WEIGHT3 * day6mo_ret) + (WEIGHT3 * day1yr_ret)) / (volatility) high = USEquityPricing.high.latest low = USEquityPricing.low.latest open_price = USEquityPricing.open.latest close = USEquityPricing.close.latest volume = USEquityPricing.volume.latest pipe = Pipeline(columns={ 'Score': score, 'Day20': day20_ret, 'high': high, 'low': low, 'close': close, 'open_price': open_price, 'volume': volume, }, screen=etf_universe) return pipe
def make_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 ''' universe = context.universe # Factor of yesterday's close price. day1mo_ret = Returns(inputs=[USEquityPricing.close], window_length=21, mask=universe) day3mo_ret = Returns(inputs=[USEquityPricing.close], window_length=63, mask=universe) day6mo_ret = Returns(inputs=[USEquityPricing.close], window_length=126, mask=universe) day9mo_ret = Returns(inputs=[USEquityPricing.close], window_length=189, mask=universe) day1yr_ret = Returns(inputs=[USEquityPricing.close], window_length=252, mask=universe) volatility = AnnualizedVolatility(mask=universe) score = ((WEIGHT1 * day1mo_ret) + (WEIGHT2 * day3mo_ret) + (WEIGHT3 * day6mo_ret) + (WEIGHT3 * day9mo_ret) + (WEIGHT5 * day1yr_ret)) / (volatility) high = USEquityPricing.high.latest low = USEquityPricing.low.latest open_price = USEquityPricing.open.latest close = USEquityPricing.close.latest volume = USEquityPricing.volume.latest pipe_columns = { 'Score': score, 'Day1mo': day1mo_ret, 'high': high, 'low': low, 'close': close, 'open_price': open_price, 'volume': volume, } pipe = Pipeline(columns=pipe_columns,screen=universe) return pipe
'Mean_Reversion_Sector_Neutral_Smoothed') pipeline.add(overnight_sentiment_smoothed(2, 10, universe), 'Overnight_Sentiment_Smoothed') # ## Features and Labels # Let's create some features that we think will help the model make predictions. # ### "Universal" Quant Features # To capture the universe, we'll use the following as features: # - Stock Volatility 20d, 120d # - Stock Dollar Volume 20d, 120d # - Sector # In[61]: pipeline.add( AnnualizedVolatility(window_length=20, mask=universe).rank().zscore(), 'volatility_20d') pipeline.add( AnnualizedVolatility(window_length=120, mask=universe).rank().zscore(), 'volatility_120d') pipeline.add( AverageDollarVolume(window_length=20, mask=universe).rank().zscore(), 'adv_20d') pipeline.add( AverageDollarVolume(window_length=120, mask=universe).rank().zscore(), 'adv_120d') pipeline.add(sector, 'sector_code') # ### Regime Features # We are going to try to capture market-wide regimes. To do that, we'll use the following features: # - High and low volatility 20d, 120d
def run_data_pipeline(engine, universe, start_date, end_date): pipeline = Pipeline(screen=universe) sector = Sector() # Alpha Factors : pipeline.add(DownsideRisk(), 'Downside Risk (Sortino Ratio)') pipeline.add(Vol3M(), '3 Month Volatility') pipeline.add(momentum_1yr(252, universe, sector), 'Momentum_1YR') pipeline.add( mean_reversion_5day_sector_neutral_smoothed(20, universe, sector), 'Mean_Reversion_Sector_Neutral_Smoothed') pipeline.add(overnight_sentiment_smoothed(2, 10, universe), 'Overnight_Sentiment_Smoothed') pipeline.add(rsi_sector_neutral(15, universe, sector), 'RSI_Sector_Neutral_15d') pipeline.add(rsi_sector_neutral(30, universe, sector), 'RSI_Sector_Neutral_30d') beta_factor = (RegressionAgainstTime(mask=universe).beta.rank().zscore()) gamma_factor = (RegressionAgainstTime(mask=universe).gamma.rank().zscore()) conditional_factor = (beta_factor * gamma_factor).rank().zscore() pipeline.add(beta_factor, 'time_beta') pipeline.add(gamma_factor, 'time_gamma') pipeline.add(conditional_factor, 'conditional_factor') # Universal Quant Features : pipeline.add( AnnualizedVolatility(window_length=20, mask=universe).rank().zscore(), 'volatility_20d') pipeline.add( AnnualizedVolatility(window_length=120, mask=universe).rank().zscore(), 'volatility_120d') pipeline.add( AverageDollarVolume(window_length=20, mask=universe).rank().zscore(), 'adv_20d') pipeline.add( AverageDollarVolume(window_length=120, mask=universe).rank().zscore(), 'adv_120d') pipeline.add(sector, 'sector_code') # Regime Features : pipeline.add( SimpleMovingAverage(inputs=[MarketDispersion(mask=universe)], window_length=20), 'dispersion_20d') pipeline.add( SimpleMovingAverage(inputs=[MarketDispersion(mask=universe)], window_length=120), 'dispersion_120d') pipeline.add(MarketVolatility(window_length=20), 'market_vol_20d') pipeline.add(MarketVolatility(window_length=120), 'market_vol_120d') # Target # Let's try to predict the go forward 1-week return. When doing this, it's important to quantize the target. The factor we create is the trailing 5-day return pipeline.add( Returns(window_length=5, mask=universe).quantiles(2), 'return_5d') pipeline.add( Returns(window_length=5, mask=universe).quantiles(25), 'return_5d_p') # Running the Pipeline all_factors = engine.run_pipeline(pipeline, start_date, end_date) # Computing Date Features all_factors = compute_date_features(all_factors, start_date, end_date) # One Hot Encoding Sectors all_factors = one_hot_encode_sectors(all_factors) # Shifted Target For Training The Model all_factors['target'] = all_factors.groupby(level=1)['return_5d'].shift(-5) return all_factors
def make_pipeline(underly_sid, shortable_sid):#,DAY_HACK_ENABLED=True,BB_WIN_LEN=126,WIN_LEN=20): sid = SidFactor() pipeline_underly_sid = sid.eq(underly_sid[0]) print("jzzz:", type(pipeline_underly_sid)) print("MNAME:", MNAME) for i in underly_sid: pipeline_underly_sid = pipeline_underly_sid | sid.eq(i) print('jzzz:', pipeline_underly_sid) pipeline_shortable_sid = sid.eq(shortable_sid[0]) for i in shortable_sid: pipeline_shortable_sid = pipeline_shortable_sid | sid.eq(i) #Filter for our choice of assets. bbands = BollingerBands(window_length=BB_WIN_LEN, k=sqrt(BB_WIN_LEN/5),mask = pipeline_underly_sid) lower, middle, upper = bbands #cud = Cud()#mask(pipeline underly_sid) returns_1D = Returns(window_length = 2, mask = pipeline_underly_sid) returns_6M = Returns(window_length = WIN_LEN, mask = pipeline_underly_sid) returns_6M = returns_6M if DAY_HACK_ENABLED else returns_6M - returns_1D returns_3M = Returns(window_length = 60, mask = pipeline_underly_sid) returns_3M = returns_3M if DAY_HACK_ENABLED else returns_3M - returns_1D returns_5M = Returns(window_length = WIN_LEN, mask = pipeline_underly_sid)#for es only returns_5M = returns_5M if DAY_HACK_ENABLED else returns_5M - returns_1D returns_1M = Returns(window_length = 20, mask = pipeline_underly_sid)#for es only returns_1M = returns_1M if DAY_HACK_ENABLED else returns_1M - returns_1D returns_5D = Returns(window_length =W_WIN_LEN,mask = pipeline_underly_sid) returns_5D = returns_5D if DAY_HACK_ENABLED else returns_5D - returns_1D returns_6D = Returns(window_length =7,mask = pipeline_underly_sid) - returns_1D annualizedVolatility_6M = AnnualizedVolatility(window_length = WIN_LEN,mask = pipeline_underly_sid) annualizedVolatility_3M = AnnualizedVolatility(window_length = int(WIN_LEN/2), mask = pipeline_underly_sid) annualizedVolatility_1M = AnnualizedVolatility(window_length = int(WIN_LEN/6), mask = pipeline_underly_sid) #annualizedVolatility_6M = ComputeVol6M(mask = pipeline_underly_sid) #annualizedVolatility_3M = ComputeVol3M(mask = pipeline_underly_sid) #annualizedVolatility_1M = ComputeVol1M(mask = pipeline_underly_sid) annualizedVolatility = max(annualizedVolatility_6M, annualizedVolatility_3M,annualizedVolatility_1M) sharpes_6M = returns_6M/annualizedVolatility_6M raw_signals = None if SHARPE: raw_signals = sharpes_6M else: raw_signals = returns_6M signals = raw_signals if LONG_ONLY else (raw_signals*raw_signals) #positive_return = (returns_6M > 0) #trigger = (returns 5D > -trigger_level) if LONG_ONLY else ((returns_5D < trigger_level) sigtop = signals.top(NUM_TOP_POSITIONS) raw_sig_top = raw_signals.top(NUM_TOP_POSITIONS) raw_sig_bot = raw_signals.bottom(NUM_TOP_POSITIONS) alongs = sigtop & raw_sig_top & (raw_signals > 0) & (returns_5D > -TRIGGER_LEVEL) # & (cud >= 13) ashorts = sigtop & raw_sig_bot &(raw_signals <= 0 ) & (returns_5D < TRIGGER_LEVEL) & pipeline_shortable_sid #alongs = (annualizedVolatility_6M> 0) #shorts# signals.top(NUN TOP POSITIONS) if not PIPE_ENABLED: alongs = (annualizedVolatility_6M > 0) ashorts = (annualizedVolatility_6M < 0)# if LONG ONLY else longs long_short_screen = alongs if LONG_ONLY else (alongs | ashorts) my_screen = (annualizedVolatility_6M > 0) if MNAME in ['es','bd','dm','ed','md'] else long_short_screen #my_screen = long_short_screen if False else (annualizedVolatility_6M > 0)#hlw print('finger1',MNAME) rsi = RSI(window_length=10,mask = pipeline_underly_sid) print('rsipipe',annualizedVolatility_6M) print('fxxxDAY_HACK_ENABLED',DAY_HACK_ENABLED) #Only compute volatilities for assets that satisfy the requirements of our rolling strategy. return Pipeline( columns= { #'cud' : cud, 'volatility' : annualizedVolatility, 'sharpes_6W' : sharpes_6M, 'drets': returns_1D, 'wrets': returns_5D, 'returns_6D': returns_6D, 'returns_1M': returns_1M, 'returns_3M': returns_3M, 'returns_5M': returns_5M, 'returns_6M': returns_6M, #'signals': (signals)*signals, 'shorts' : ashorts, #'wrets' : returns_5D, 'lower' : lower, 'middle' :middle, 'upper' :upper, #'rsi':rsi.top(3), 'rsi_longs': rsi.top(3), 'rsi_shorts': rsi.bottom(3), #'annualizedVolatility :annualizedVolatility_6M, }, screen = my_screen )