Back to Community
How to filter out the stocks from a sector in building customer factor?

Assumed I want to filter out the stocks from sectors 103.0 and 207.0?

context.sector_mappings = {  
   101.0: "Basic Materials",  
   102.0: "Consumer Cyclical",  
   103.0: "Financial Services",  
   104.0: "Real Estate",  
   205.0: "Consumer Defensive",  
   206.0: "Healthcare",  
   207.0: "Utilites",  
   308.0: "Communication Services",  
   309.0: "Energy",  
   310.0: "Industrials",  
   311.0: "Technology"  
}  
Clone Algorithm
28
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 575e4f896314e80f898dd07f
There was a runtime error.
13 responses

Hi Thomas,

You can use the .filter() method to filter out stocks from get_fundamentals().

In this case, your code will look something like this:

context.fundamendals_df = get_fundamentals(  
        query(  
            # put your query in here by typing "fundamentals."  
            fundamentals.valuation_ratios.pe_ratio, # the lower, the better  
            fundamentals.valuation.market_cap  
        )  
        .filter(  
            fundamentals.valuation.market_cap > 20**7  
        )  
        .filter(  
          fundamentals.asset_classification.morningstar_sector_code != 207  
        )  
        .filter(  
          fundamentals.asset_classification.morningstar_sector_code != 103  
        )  
        .order_by(  
            # sort your query from the smallest to ...  
            fundamentals.valuation_ratios.pe_ratio.asc()  
        )  
        .limit(20)  
    )  

More information about database queries with get_fundamentals() can be found in our API Documentation.

Best,
Lotanna Ezenwa

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

Hi Lotanna,

Many thanks to the reply.

Sorry that I forgot to take out the code about get_fundamental().

Originallly I want to know how can I set the filter or mask to filter out the sectors I don't want by customer built factor (you can see in my code I use the customer built factor to select the pe_ratio).

Cheers

Thomas

Hi Thomas,

Sorry about that, I see you wanted to make a custom factor that sorts or filters by sector.
You could use a Classifierwhich computes a categorical output. In this case, the built-in sector classifier could help you out.

It's API documentation goes over the names and values for each sector. I would suggest importing the sector classifier, then using the classifier to create a filter that selects the relevant sectors. After that, using the created filter to set a screen on your Pipeline.

Thanks,
Lotanna

Hi Lotanna,

I've tried as follow, similar to use the AverageDollarVolume():
... sector = Sector()
pipe.set_screen(sector == 103)
...

But I got 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 59.

Where the code in line 59:
attach_pipeline(my_pipeline(context), 'my_pipeline')

Cheers

Thomas

Hi Thomas,

When you create a filter based on equality of a classifier, you should use .eq() instead of ==, as it says here in the documentation. So your code should look like this:

pipe.set_screen(sector.eq(103))  
Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

Hi Nathan,

You are right. Many thanks!

Hi Nathan,

How about not equal? I want to choose stocks not from 103 and 207 for example?

Thomas

Bump - I would also like to know how to set it to NOT .eq to exclude a certain sector from the backtest.

Thanks

You can use the ~ operator to get the inverse or NOT of a filter. See attached notebook for an example of including and excluding specific sectors.

Loading notebook preview...
Notebook previews are currently unavailable.

Thanks again Dan. How would I use this to update the QS500() screen?

I was just using this before as a mask:

initial_screen = Q500US()  

I am trying to do the below to exclude sector[104] (Real Estate):

    sector = morningstar.asset_classification.morningstar_sector_code.latest

    not_sectors_104 = ~sector.element_of([104])  
    initial_screen = Q500US(), not_sectors_104  

Have also tried:

    sector = morningstar.asset_classification.morningstar_sector_code.latest  
    not_sectors_104 = ~sector.element_of([104])  
    initial_screen = Q500US()  
    initial_screen = not_sectors_104  

But this seems to not regard the previous QS500() & runs it on all USEquityPricing...

You can use the | and the & operators to OR and AND filters respectively. The documentation has more detail on the methods and operators one can use https://www.quantopian.com/help#quantopian_pipeline_filters_Filter. You also need to instantiate the Q500US filter first.

q500 = Q500US()  
not_sectors_104 = ~sector.eq(104)  
initial_screen = q500 & not_sector_104

See attached notebook for ANDing the q500 and not_sector_104 filters. The last cell of the notebook shows the universe filtered down to 482 stocks (Q500US minus the sector 104 stocks).

Loading notebook preview...
Notebook previews are currently unavailable.

You can also use the mask to mask out those stocks directly to your factor so it doesn't perform any computation on them
For example

q500 = Q500US()  
not_sectors_104 = ~sector.eq(104)  
combined_mask = (q500 | not_sector_104)    # Notice the | (or) symbol, you want to exclude something that appears in EITHER q500 and not_sector_104 

# your factor will now compute only over those securities that are not part of the combined set above  
my_factor_result = MyFactor(inputs=[USEquityPricing.close], window_length=3, mask=combined_mask)  

This doesn't seem to work even in the base case example when within the pipeline construction itself in backtest. Please see lines 62-68 of attached, this implements exactly as syntax above indicates it should and even categorizes correctly, but does not seem to work as securities in the filtered out sector are still included in context.

Please advise

Loading notebook preview...
Notebook previews are currently unavailable.