Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Struggling With Fundamentals Filtering & Position Changes

I'm not great with python (I've finished an online course but am still struggling at times) and I've recently been playing around with trying to filter my universe of stocks based on fundamentals but have hit some roadblocks.

I was trying to grab 20 stocks based on my fundamental filters and have each of those stocks hold 5% of the portfolio.

So I wanted to sell stocks that weren't in the 20, and allocate 5% to those stocks that were in the 20 and to make sure it doesn't overdraw on cash as well.

This is what I put:

def before_trading_start(context):  
    fundamental_df = get_fundamentals(  
        query(

"""Fundamental Criteria"""

        .order_by(fundamentals.valuation_ratios.pe_ratio.asc())  
        .limit(20)  
    )  
    context.stocks = [stock for stock in fundamental_df]  
    context.fundamental_df = fundamental_df  
    update_universe(context.fundamental_df.columns.values) 

def handle_data(context, data):

    for stock in context.portfolio.positions:  
        if stock not in data:  
            order_target(stock, 0)  
    for stock in data:  
        if context.portfolio.cash >= 0.05 * context.portfolio.portfolio_value:  
            order_target_percent(stock, 0.05)  

The above seems to buy the stocks, but never sells out of a position.

And i also tried this:

def handle_data(context, data):

    for stock in context.portfolio.positions:  
        if stock not in context.fundamental_df:  
            order_target(stock, 0)  
    for stock in data:  
        if context.portfolio.cash >= 0.05 * context.portfolio.portfolio_value:  
            order_target_percent(stock, 0.05)  

Any insights would be appreciated.

5 responses

In your sell logic, the line

if stock not in data:  

probably out to be
if stock in data:

And your condition to buy only if you have 5% or more of your portfolio in cash will probably start to fail because the sell orders you placed before don't happen until the next bar tick. If you want to track cash, you'll have to fake it a bit yourself in this bar. See Tutorial 3 for a discussion of this and examples.

Good luck!

Thanks Dan for the response.

I tried the following, but this algo only buys and never sells...??

Hi Chris,

If you still have a position in a stock, then the security will still have a place in the data structure. So your else clause with order_target(stock, 0) will never be triggered.

One simple way to see this behavior in action is to use the debugger and check the length of data. Here's some info on the debugger: https://www.quantopian.com/posts/new-feature-debugging-in-the-ide

One way to get around this would be to check for the presence of a stock in context.fundamental_df rather than in data.

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 Chris,
I went ahead made some changes for you to check out. Since the context variables do not update mid handle_data calls you need to do some accounting inside your loop to track the money spent/received inside handle_data. Also, I only used order_target_percent if there was not already an open position for that stock.

Hope this helps!

David

Thank you David! That was very helpful.