Notebook
In [5]:
from quantopian.pipeline.data import Fundamentals
from quantopian.pipeline import Pipeline
from quantopian.research import run_pipeline
from quantopian.pipeline.factors import SimpleMovingAverage,Latest,RSI, MACDSignal, SimpleBeta
from quantopian.pipeline.filters import Q1500US, QTradableStocksUS, Q500US, Q3000US
from quantopian.research import get_pricing
from quantopian.pipeline.data import USEquityPricing
from quantopian.pipeline.factors import CustomFactor
from alphalens.utils import get_clean_factor_and_forward_returns
from alphalens.tears import create_full_tear_sheet
from quantopian.pipeline import CustomFilter
import pandas as pd
import numpy as np

import talib
In [23]:
#This class is to create the price action pattern of engulging, 
class engulf(CustomFilter):
    
    inputs = [USEquityPricing.close, USEquityPricing.low, USEquityPricing.open, USEquityPricing.high]  

    window_length = 2
    
    def compute(self, today, assets, out, close, low, open1, high): 
        
        condition_1 = (high[-1] > high[-2]) & (low[-1]<low[-2])
        
        condition_2 = (close[-1] > close[-2]) & (open1[-1]<open1[-2])
        
        condition_3 = close[-1] > open1[-1]
        
        condition_4 = (close[-1] > open1[-2]) & (open1[-1]<close[-2])
        
        
        result = condition_1 & condition_2 & condition_3 & condition_4 
        
        out[:] = result   
        
        
class volume(CustomFilter):
    
    inputs = [USEquityPricing.volume]
    window_length = 6
    def compute(self, today, assets, out, vol):     
                
        low_condition_1 = vol[-1] / np.mean(vol, axis = 0)>0.29
        
        low_condition_2 = (vol[-1] / np.mean(vol, axis = 0))<1.54
                                
        out[:] =  low_condition_1 

        
        


def filtro():
    sector = Fundamentals.morningstar_sector_code.latest
    industry = Fundamentals.morningstar_industry_code.latest
    #universe= Q3000US() & sector.element_of([206]) 
    universe = Q3000US() & QTradableStocksUS()   
    sma20 = SimpleMovingAverage(inputs = [USEquityPricing.close], window_length=20 )
    sma50 = SimpleMovingAverage(inputs = [USEquityPricing.close], window_length=50, mask = universe )
    sma200 = SimpleMovingAverage(inputs = [USEquityPricing.close], window_length=200 )
    price = SimpleMovingAverage(inputs = [USEquityPricing.close], window_length=1, mask = universe )
    high = SimpleMovingAverage(inputs = [USEquityPricing.high], window_length=1, mask = universe )
    low = SimpleMovingAverage(inputs = [USEquityPricing.low], window_length=1, mask = universe )
    close = SimpleMovingAverage(inputs = [USEquityPricing.close], window_length=1, mask = universe )
    open1 = SimpleMovingAverage(inputs = [USEquityPricing.open], window_length=1, mask = universe )
    betaytd = SimpleBeta(target=symbols(8554)  , regression_length=100)
    betayty = SimpleBeta(target=symbols(8554),regression_length = 253) 
    rsi = RSI()
    macd = MACDSignal()
    
    
    condition_1 = rsi < 40
    condition_2 = macd < -1.5
    
    technical_condition =  condition_2 & condition_1
    
       
    condition_1 = price > sma20
    condition_2 = price < sma50
    condition_3 = price < sma200 
    condition_4 = 5 < price <120
    sma_condition = condition_1 & condition_4 & condition_3 & condition_2 

    mid_price = (high+low)/2
    box = (close-open1).abs()
    limit_box  = (high-low)*0.25
    condition_5 = close > mid_price
    condition_6 = open1 > mid_price
    condition_7 = box <= limit_box
    
    hammer = condition_5 & condition_6 & condition_7 
        
    price_action =    (hammer & volume()) | engulf()
                  
    filter1= technical_condition | sma_condition
                                
    return Pipeline(columns={"filter":filter1} ,screen = universe & price_action )
 
factor = run_pipeline(filtro(), start_date="2019-05-5", end_date="2020-06-11")

Pipeline Execution Time: 21.30 Seconds
In [12]:
asset_list = factor.index.levels[1].unique()
pricing = get_pricing(asset_list,start_date="2019-4-5", end_date="2020-6-10", fields= "close_price" )
merged_data = get_clean_factor_and_forward_returns(factor, pricing, periods=[1,2,3,4,5], quantiles=None, bins=[-1, 0.5, 2])
Dropped 1.8% entries from factor data: 1.8% in forward returns computation and 0.0% in binning phase (set max_loss=0 to see potentially suppressed Exceptions).
max_loss is 35.0%, not exceeded: OK!
In [15]:
merged_data[merged_data["factor_quantile"]==2].mean()
Out[15]:
1D                -0.003141
2D                -0.005695
3D                -0.006788
4D                -0.001240
5D                -0.003629
factor             1.000000
factor_quantile    2.000000
dtype: float64
In [13]:
create_full_tear_sheet(merged_data)
Quantiles Statistics
min max mean std count count %
factor_quantile
1 False False False 0.0 58471 84.600804
2 True True True 0.0 10643 15.399196
Returns Analysis
1D 2D 3D 4D 5D
Ann. alpha 0.071 0.074 0.065 0.065 0.066
beta 0.088 0.116 0.084 0.079 0.068
Mean Period Wise Return Top Quantile (bps) 3.485 3.549 2.894 3.386 3.685
Mean Period Wise Return Bottom Quantile (bps) -1.719 -1.677 -2.132 -1.853 -1.657
Mean Period Wise Spread (bps) 5.203 5.061 4.874 5.075 5.150
<matplotlib.figure.Figure at 0x7f6e4d1ace80>
Information Analysis
1D 2D 3D 4D 5D
IC Mean 0.001 0.001 0.002 0.006 0.007
IC Std. 0.116 0.123 0.121 0.118 0.118
Risk-Adjusted IC 0.011 0.007 0.019 0.048 0.055
t-stat(IC) 0.178 0.113 0.310 0.795 0.916
p-value(IC) 0.859 0.910 0.757 0.428 0.361
IC Skew 0.377 -0.057 0.332 0.239 0.167
IC Kurtosis 1.784 2.165 1.745 1.739 1.607
/venvs/py35/lib/python3.5/site-packages/statsmodels/nonparametric/kdetools.py:20: VisibleDeprecationWarning: using a non-integer number instead of an integer will result in an error in the future
  y = X[:m/2+1] + np.r_[0,X[m/2+1:],0]*1j
/venvs/py35/lib/python3.5/site-packages/alphalens/utils.py:912: UserWarning: Skipping return periods that aren't exact multiples of days.
  + " of days."
Turnover Analysis
1D 2D 3D 4D 5D
Quantile 1 Mean Turnover 0.870 0.876 0.876 0.878 0.881
Quantile 2 Mean Turnover 0.887 0.910 0.922 0.927 0.940
1D 2D 3D 4D 5D
Mean Factor Rank Autocorrelation 0.844 0.683 0.556 0.489 0.429
In [ ]: