Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Issue with CustomFactor to calculate share opened with gaps

Dear all

I am trying to implement Pipeline and CustomFactor in it to get liquid stocks open with gaps compared to previous close. Pipeline works and produces output but the results are weird and not corresponding to reality. My code listing for Notebook Env is attached. Could you spot an error? I guess it sits in CustomFactor (window_length=2? something between (close[-1] - open[0])/close[-1].

Also why argument open in def compute(self, today, asset_ids, out, close, open) is in red color?

Sorry for a rookie questions.

from quantopian.pipeline import CustomFactor, Pipeline  
from quantopian.pipeline.data.builtin import USEquityPricing  
from quantopian.research import run_pipeline  
from quantopian.pipeline.filters.fundamentals import Q1500US

# Define class for a CustomFactor outputting signed gaps as %

class SignedGapPct(CustomFactor):  
    # Default input  
    inputs = [USEquityPricing.close, USEquityPricing.open]  
    window_length = 1  
    def compute(self, today, asset_ids, out, close, open):  
        # Calculates the column-wise gaps, how to ignore NaNs?  
        out[:] = (open[0] - close[-1])/close[-1]

def make_pipeline():  
    """  
    Create our pipeline.  
    """

    # Base universe set to the Q1500US.  
    base_universe = Q1500US()

    # Factor to calculate gap up/down (signed) in percent normalized to previous day close

    signed_gap_pct = SignedGapPct(mask=base_universe)  
    # filter out NaN  
    filter_not_nan = signed_gap_pct.notnan()  
    # filter for top 5 gap up  
    filter_top_gap_up = signed_gap_pct.top(5)  
    # filter for bottom 5 gap down  
    filter_bottom_gap_down = signed_gap_pct.bottom(5)  
    # aggregated filter for pipeline screen  
    aggr_screen = ((filter_not_nan & filter_top_gap_up) |  
                  (filter_not_nan & filter_bottom_gap_down))

    return Pipeline(  
        columns={  
            'signed_gap_pct': signed_gap_pct,  
        },  
        screen = (aggr_screen),  
        )

my_pipe = make_pipeline()  
result = run_pipeline(my_pipe, '2017-12-19', '2017-12-19')  
result
1 response

The problem (as you noted) is the window_length. This should be 2 since you are needing 2 days of data (yesterdays open and the day before yesterdays close). The following works. Using -1 and -2 for indexing maybe makes it more clear which days are being referred to?


class SignedGapPct(CustomFactor):  
    # Default input  
    inputs = [USEquityPricing.close, USEquityPricing.open]  
    # Need a window length of 2 because we want 2 days of data (yesterday and the day before that)  
    window_length = 2


    def compute(self, today, asset_ids, out, close, open):  
        # Calculates the column-wise gaps, how to ignore NaNs?  
        # Take yesterdays open (-1) and divide by the previous days close (-2)  
        out[:] = (open[-1] - close[-2]) / close[-2]

Another way to do this same calculation is

        out[:] = (open[-1] / close[-2]) - 1.0

You want to ignore NaNs? What value do you want to return if open or close is a NaN? Just leave alone and the factor will return NaN. Also, you don't really need to filter the NaNs out explicitly. The '.top' and '.bottom' methods do that for you.

You asked "why argument open in def compute(self, today, asset_ids, out, close, open) is in red color?" The word 'open' is a command in a Jupyter notebook and Jupyter is smart (or maybe not so smart) to highlight it. Similar to the way 'self' and 'compute' are highlighted. It doesn't hurt anything using 'open' as a name but perhaps just change it to 'open_price" and there won't be any confusion. One can see the Jupyter docs at http://jupyter.readthedocs.io/en/latest/

See attached notebook. Good luck.