Filters

A Filter is a function from an asset and a moment in time to a boolean:

F(asset, timestamp) -> boolean

In Pipeline, Filters are used for narrowing down the set of securities included in a computation or in the final output of a pipeline. There are two common ways to create a Filter: comparison operators and Factor/Classifier methods.

In [1]:
from zipline.pipeline import Pipeline
from zipline.research import run_pipeline
from zipline.pipeline.data import EquityPricing
from zipline.pipeline.factors import SimpleMovingAverage

Comparison Operators

Comparison operators on Factors and Classifiers produce Filters. Since we haven't looked at Classifiers yet, let's stick to examples using Factors. The following example produces a filter that returns True whenever the latest close price is above $20.

In [2]:
last_close_price = EquityPricing.close.latest
close_price_filter = last_close_price > 20

And this example produces a filter that returns True whenever the 10-day mean is below the 30-day mean.

In [3]:
mean_close_10 = SimpleMovingAverage(inputs=[EquityPricing.close], window_length=10)
mean_close_30 = SimpleMovingAverage(inputs=[EquityPricing.close], window_length=30)
mean_crossover_filter = mean_close_10 < mean_close_30

Remember, each security will get its own True or False value each day.

Factor/Classifier Methods

Various methods of the Factor and Classifier classes return Filters. Again, since we haven't yet looked at Classifiers, let's stick to Factor methods for now (we'll look at Classifier methods later). The Factor.top(n) method produces a Filter that returns True for the top n securities of a given Factor. The following example produces a filter that returns True for exactly 200 securities every day, indicating that those securities were in the top 200 by last close price across all known securities.

In [4]:
last_close_price = EquityPricing.close.latest
top_close_price_filter = last_close_price.top(200)

For a full list of Factor methods that return Filters, see the Factor API Reference.

For a full list of Classifier methods that return Filters, see the Classifier API Reference.

Dollar Volume Filter

As a starting example, let's create a filter that returns True if a security's 30-day average dollar volume is above $10,000,000. To do this, we'll first need to create an AverageDollarVolume factor to compute the 30-day average dollar volume. Let's include the built-in AverageDollarVolume factor in our imports:

In [5]:
from zipline.pipeline.factors import AverageDollarVolume

And then, let's instantiate our average dollar volume factor.

In [6]:
dollar_volume = AverageDollarVolume(window_length=30)

By default, AverageDollarVolume uses EquityPricing.close and EquityPricing.volume as its inputs, so we don't specify them.

Now that we have a dollar volume factor, we can create a filter with a boolean expression. The following line creates a filter returning True for securities with a dollar_volume greater than 10,000,000:

In [7]:
high_dollar_volume = (dollar_volume > 10000000)

To see what this filter looks like, let's can add it as a column to the pipeline we defined in the previous lesson.

In [8]:
def make_pipeline():

    mean_close_10 = SimpleMovingAverage(inputs=[EquityPricing.close], window_length=10)
    mean_close_30 = SimpleMovingAverage(inputs=[EquityPricing.close], window_length=30)

    percent_difference = (mean_close_10 - mean_close_30) / mean_close_30
    
    dollar_volume = AverageDollarVolume(window_length=30)
    high_dollar_volume = (dollar_volume > 10000000)

    return Pipeline(
        columns={
            'percent_difference': percent_difference,
            'high_dollar_volume': high_dollar_volume
        }
    )

If we make and run our pipeline, we now have a column high_dollar_volume with a boolean value corresponding to the result of the expression for each security.

In [9]:
result = run_pipeline(make_pipeline(), start_date='2015-05-05', end_date='2015-05-05')
result
Out[9]:
high_dollar_volumepercent_difference
2015-05-05 00:00:00+00:00Equity(FIBBG000C2V3D6 [A])True-0.000111
Equity(FIBBG00B3T3HD3 [AA])FalseNaN
Equity(QI000000004076 [AABA])True-0.017429
Equity(FIBBG006T1NZ18 [AAC])False0.048123
Equity(FIBBG001B9VR83 [AAC])FalseNaN
Equity(FIBBG000V2S3P6 [AACG])False0.052646
Equity(FIBBG000BDYRW6 [AADR])False0.021066
Equity(FIBBG002MYG6B3 [AAIT])False0.007100
Equity(FIBBG005P7Q881 [AAL])True0.007729
Equity(FIBBG003PNL136 [AAMC])False0.008597
Equity(FIBBG000B9XB24 [AAME])False-0.004582
Equity(FIBBG000D9V7T4 [AAN])True0.095343
Equity(FIBBG000D6VW15 [AAOI])False0.042447
Equity(FIBBG000C2LZP3 [AAON])False0.016510
Equity(FIBBG000F7RCJ1 [AAP])True-0.010067
Equity(FIBBG008651TF3 [AAPC])False0.000000
Equity(FIBBG000B9XRY4 [AAPL])True0.016827
Equity(FIBBG00161BCR0 [AAT])False-0.025473
Equity(FIBBG000DGFSY4 [AAU])False-0.039844
Equity(FIBBG000C5QZ62 [AAV])False0.054398
Equity(FIBBG000Q57YP0 [AAWW])True0.023100
Equity(FIBBG000G6GXC5 [AAXJ])True0.030521
Equity(FIBBG000BHJWG1 [AAXN])True0.102930
Equity(FIBBG000B9WM03 [AB])False0.013725
Equity(FIBBG000CP4WX9 [ABAX])False-0.019617
Equity(FIBBG000DK5Q25 [ABB])True0.009474
Equity(FIBBG0025Y4RY4 [ABBV])True0.056309
Equity(FIBBG000MDCQC2 [ABC])True0.006168
Equity(FIBBG000CDY3H5 [ABCB])False-0.031080
Equity(FIBBG000Q05Q43 [ABCD])False-0.020143
.........
Equity(FIBBG004HQMCJ4 [ZIONN])False0.000579
Equity(FIBBG0043FW0J8 [ZIONO])False0.015711
Equity(FIBBG000002FJ2 [ZIONP])False0.001309
Equity(FIBBG000RMX9Z7 [ZIONW])False0.028649
Equity(FIBBG000PQQH62 [ZIONZ])False0.053310
Equity(FIBBG000FWCC57 [ZIOP])True-0.059584
Equity(FIBBG0019HMFX6 [ZIV])False0.025061
Equity(FIBBG000H04C72 [ZIXI])False0.060999
Equity(FIBBG006MJFPW3 [ZJPN])False0.011783
Equity(FIBBG007XHN059 [ZLRG])False-0.001470
Equity(FIBBG001J2P4Y9 [ZLTQ])True0.014219
Equity(FIBBG005WX1JJ7 [ZMLP])False0.024929
Equity(FIBBG000RFZLM7 [ZN])False0.076209
Equity(FIBBG000VD6768 [ZNGA])True-0.044151
Equity(FIBBG000BXQ7R1 [ZNH])False0.139522
Equity(FIBBG0064MY238 [ZOES])True-0.006636
Equity(FIBBG006G0NHM1 [ZPIN])False-0.008053
Equity(FIBBG000FTMSF7 [ZQK])False-0.068626
Equity(FIBBG000PN8QP8 [ZROZ])False-0.032259
Equity(FIBBG006TL19Y0 [ZSAN])False-0.052960
Equity(FIBBG000F9CW36 [ZSL])False0.031028
Equity(FIBBG007XHMYS1 [ZSML])False0.002779
Equity(FIBBG003LFL2G1 [ZSPH])True-0.032424
Equity(FIBBG000BXB8X8 [ZTR])False-0.001181
Equity(FIBBG0039320N9 [ZTS])True-0.006740
Equity(FIBBG001Z7M393 [ZU])True-0.043705
Equity(FIBBG000PYX812 [ZUMZ])True-0.082763
Equity(FIBBG000C3CQP1 [ZVO])False-0.041755
Equity(FIBBG001NFC923 [ZX])False0.040279
Equity(FIBBG00VT0KNC3 [MTCH])True0.020778

8422 rows × 2 columns

Applying a Screen

By default, a pipeline produces computed values each day for every asset in the data bundle. Very often however, we only care about a subset of securities that meet specific criteria (for example, we might only care about securities that have enough daily trading volume to fill our orders quickly). We can tell our Pipeline to ignore securities for which a filter produces False by passing that filter to our Pipeline via the screen keyword.

To screen our pipeline output for securities with a 30-day average dollar volume greater than $10,000,000, we can simply pass our high_dollar_volume filter as the screen argument. This is what our make_pipeline function now looks like:

In [10]:
def make_pipeline():

    mean_close_10 = SimpleMovingAverage(inputs=[EquityPricing.close], window_length=10)
    mean_close_30 = SimpleMovingAverage(inputs=[EquityPricing.close], window_length=30)

    percent_difference = (mean_close_10 - mean_close_30) / mean_close_30

    dollar_volume = AverageDollarVolume(window_length=30)
    high_dollar_volume = dollar_volume > 10000000

    return Pipeline(
        columns={
            'percent_difference': percent_difference
        },
        screen=high_dollar_volume
    )

When we run this, the pipeline output only includes securities that pass the high_dollar_volume filter on a given day. For example, running this pipeline on May 5th, 2015 results in an output for ~2,200 securities

In [11]:
result = run_pipeline(make_pipeline(), start_date='2015-05-05', end_date='2015-05-05')
print(f'Number of securities that passed the filter: {len(result)}')
result
Number of securities that passed the filter: 2253
Out[11]:
percent_difference
2015-05-05 00:00:00+00:00Equity(FIBBG000C2V3D6 [A])-0.000111
Equity(QI000000004076 [AABA])-0.017429
Equity(FIBBG005P7Q881 [AAL])0.007729
Equity(FIBBG000D9V7T4 [AAN])0.095343
Equity(FIBBG000F7RCJ1 [AAP])-0.010067
Equity(FIBBG000B9XRY4 [AAPL])0.016827
Equity(FIBBG000Q57YP0 [AAWW])0.023100
Equity(FIBBG000G6GXC5 [AAXJ])0.030521
Equity(FIBBG000BHJWG1 [AAXN])0.102930
Equity(FIBBG000DK5Q25 [ABB])0.009474
Equity(FIBBG0025Y4RY4 [ABBV])0.056309
Equity(FIBBG000MDCQC2 [ABC])0.006168
Equity(FIBBG000CG1LX6 [ABCO])-0.004414
Equity(FIBBG000BN5VZ4 [ABEV])0.028177
Equity(FIBBG000BKDWB5 [ABG])0.018068
Equity(FIBBG000C101X4 [ABMD])-0.024680
Equity(FIBBG000B9ZXB4 [ABT])0.011940
Equity(FIBBG000RR8V85 [ABUS])-0.040721
Equity(FIBBG000BHG9K0 [ACAD])0.046260
Equity(FIBBG000BYR208 [ACAS])0.003447
Equity(FIBBG000M9KP89 [ACC])-0.013120
Equity(FIBBG000HXNN20 [ACGL])-0.011854
Equity(FIBBG000FPNN38 [ACHC])-0.007405
Equity(FIBBG000BPPV05 [ACHN])-0.048416
Equity(FIBBG000PMBV39 [ACIW])0.023291
Equity(FIBBG000F61RJ8 [ACM])0.016854
Equity(FIBBG000D9D830 [ACN])0.000050
Equity(FIBBG000FD10V8 [ACOR])-0.042520
Equity(FIBBG000TH6VB3 [ACWI])0.013665
Equity(FIBBG000TH7DF8 [ACWX])0.019894
......
Equity(FIBBG000D73SW9 [XPH])-0.009123
Equity(FIBBG000L5CJF3 [XPO])0.015871
Equity(FIBBG000BX57K1 [XRAY])0.009448
Equity(FIBBG000D80VV4 [XRT])-0.009868
Equity(FIBBG00NNG2ZJ8 [XRX])-0.048730
Equity(FIBBG001D8R5D0 [XYL])0.018219
Equity(FIBBG000BX6BJ3 [Y])-0.012859
Equity(FIBBG000CTBTW1 [YCS])-0.002571
Equity(FIBBG000Q2HM09 [YELP])-0.000711
Equity(FIBBG000PY4FX3 [YINN])0.178304
Equity(FIBBG001NVJ6W4 [YNDX])0.101750
Equity(FIBBG001924FR6 [YOKU])0.155375
Equity(FIBBG000BHPFQ0 [YPF])0.019707
Equity(FIBBG000BH3GZ2 [YUM])0.057707
Equity(FIBBG003H0XV18 [YY])0.060564
Equity(FIBBG002ZM63J5 [ZAYO])-0.012197
Equity(FIBBG000BKPL53 [ZBH])-0.007930
Equity(FIBBG000CC7LQ7 [ZBRA])0.019113
Equity(FIBBG001HRFJG4 [ZEN])0.014139
Equity(FIBBG000D13GN8 [ZG])0.003626
Equity(FIBBG000BX9WL1 [ZION])0.018272
Equity(FIBBG000FWCC57 [ZIOP])-0.059584
Equity(FIBBG001J2P4Y9 [ZLTQ])0.014219
Equity(FIBBG000VD6768 [ZNGA])-0.044151
Equity(FIBBG0064MY238 [ZOES])-0.006636
Equity(FIBBG003LFL2G1 [ZSPH])-0.032424
Equity(FIBBG0039320N9 [ZTS])-0.006740
Equity(FIBBG001Z7M393 [ZU])-0.043705
Equity(FIBBG000PYX812 [ZUMZ])-0.082763
Equity(FIBBG00VT0KNC3 [MTCH])0.020778

2253 rows × 1 columns

Inverting a Filter

The ~ operator is used to invert a filter, swapping all True values with Falses and vice-versa. For example, we can write the following to filter for low dollar volume securities:

In [12]:
low_dollar_volume = ~high_dollar_volume

This will return True for all securities with an average dollar volume below or equal to $10,000,000 over the last 30 days.


Next Lesson: Combining Filters