Back to Community
Filter on boolean

Hi,
I am filtering stocks based on the results of the Augmented Dickey Fuller test as follows:

class ADF_test(CustomFactor):  
    # Pre-declare inputs and window_length  
    inputs = [USEquityPricing.close]

    window_length = 100

    def compute(self, today, assets, out, close):


        for i in range(close.shape[1]):  
            price_col = close[:,i]  
            price_col = price_col[~np.isnan(price_col)]  
            if len(price_col) >= 100:  
                adf_result = adfuller(price_col)  
                if adf_result[0] < adf_result[4]['5%']:  
                    out[:] = True  
                else:  
                    out[:] = False  
            else:  
                out[:] = False  

Now, i dont know if its the right way but so far, the results seem to make sense.

Further in the code I call a filter based on the ADF result as follows:

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()  
    adf_result= ADF_test()  
    pipe.add(adf_result, 'adf_result')  
    pipe.set_screen(adf_result = True)  
    return pipe  

but I end up with this error:

TypeError: set_screen() got an unexpected keyword argument 'adf_result'  
...
USER ALGORITHM:76, in my_pipeline  
pipe.set_screen(adf_result = True)  

Can anyone help ? Is this the optimal way to do this ?

Thanks !

3 responses

Stephane,

You just forgot an equal sign. Your code

> pipe.set_screen(adf_result = True)

should be

> pipe.set_screen(adf_result == True)

Notice the double equal signs.

As far as the best way to do this, this is perfectly acceptable. You may however, want to make a custom filter using basically your same code but instead of class ADF_test(CustomFactor) use class ADF_test(CustomFilter). Then all you would do is pipe.set_screen(adf_result) where adf_result is now a filter. You won't be able to add it to a pipe to see the true/false data but it will filter for you. There's a bit of info on CustomFilters on the github site https://github.com/quantopian/zipline/blob/master/zipline/pipeline/filters/filter.py but I'm not sure it's officially released and I didn't see it in the Quantopian documentation.

Good luck,

Dan

THanks Dan !

I did the following change

pipe.set_screen(adf_result == True)  

but I now end up with the following error:

TypeError: zipline.pipeline.pipeline.set_screen() expected a value of type zipline.pipeline.filters.filter.Filter for argument 'screen', but got bool instead.  
There was a runtime error on line 54.  

I also tried the CustomFilter change and end up with this error

18  Warning Undefined name 'customfilter'  
18  Error   Runtime exception: NameError: name 'CustomFilter' is not defined  

Any thoughts ?

Hi Stephane,
I am also developping a custom factor using the ADF Test.
The following code is working fine for me:

def make_pipeline():  
    pipe = Pipeline()  
    adf_result = ADF_test(mask=initial_screen, window_length=200)  
    pipe.add(adf_result, "ADFTeststatistic")  
    mean_reverting = (adf_result !=0)  
    pipe.set_screen(mean_reverting)  

I guess you shoud change
out[:]

in
out[i]

in the difinition of ADF_test.

I hope it could help.