Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Problem with restrictions. Any help?

Hello community,
I am starting with quantopian and I would really appreciate some help. I am working on improving this algorithm that buys the best 4 Sector ETFs each month, but when the SPY<MA200_SPY (bear market) it buys a bond instead and no ETFs. In this sense, I can't seem to find out why if one month I have a bond, and next I need 4 ETFs (and therefore I need to sell the bond), it doesn't actually sell it (that's why I have 5 positions, and double leverage). Any one could help me find out what's the problem with the restrictions below?
Furthemore, I have tried to tell the algorithm not to sell an ETF I already have, if next month it keeps being in the top 4 (I don't want to sell the same thing I need to immediately buy).

for stock in context.portfolio.positions:

    #If the SP>SP_MA200  
    if spy_ma1>spy_ma200:  
        #If I have the bond in my portfolio, sell the bond  
        if sid(23921) in context.portfolio.positions:  
            order_target_percent(sid(23921), 0)  

        #If I don't have the bond (because I have ETFs)  
        else:  
            #If the ETFs on my portfolio are not on the Top 4 this month, sell the ETFs I have  
            if stock not in context.longs:  
                order_target_percent(stock, 0)  

    #If SP<SP_MA200  
    else:  
        #If we don't have the bond in the portfolio, sell the ETFs  
        if context.shy not in context.portfolio.positions:  
            order_target_percent(stock, 0)  
6 responses

The problem is that the above logic is within a for loop

for stock in context.portfolio.positions:

The code above is being executed as many times as there are open positions. Therefore, if you have 4 ETFs in your portfolio, you will sell sid(23921) 4 times. You really just want to sell it once. The fix is to move that statement outside of the for loop. There are a few other problems with the code too. You don't need to call close each month for example. You also do not need to check if a security is currently held to close the position

if sid(23921) in context.portfolio.positions:  
    order_target_percent(sid(23921), 0)

Just do this

order_target_percent(sid(23921), 0)  

Anyway, attached is an algorithm which I think does what what you want...

Good luck.

Hey Dan,
First of all, thanks for your time and effort! However, in the second part (bull market), I think you are buying but not selling the ETFs that you already have. For example:
Month 1 I have the following ETFs: A, B, C, D
Month 2 (I need to have the new top 4): A, B, C, E >> You just need to sell D, and replace it for E. In the algo you kindly attached, it doesn't sell.

else:  
    # Sell Treasury Bond 1-3 years if held and buy sector ETFs #that's fine for selling the bond  
    if data.can_trade(context.shy):  
        order_target_percent(context.shy, 0.0)  

    for stock in context.longs:  
        if data.can_trade(stock):  
            order_target_percent(stock, 1.0 / len(context.longs))  
            log.info("Buy" + str(stock))  

    log.info("ETF Month")  

In bear markets the problem is this:
Month 1 (bear): I buy the bond
Month 2 (bear): I don't need to sell the bond (which in your algorithm it does), I just need to keep it and don't buy or sell.

Thank you very much for helping! Best regards

Oops. Correct. Forgot to sell anything that isn't currently in 'context.longs'.

This should be what you want. See attached algo.

Hey Dan! Thanks again for your time and patience, I truly appreciate it.
The bond keeps being bought and sold each month. Maybe I should add something like:
if spy_ma1 < spy_ma200:
if context.shy not in context.portfolio.positions:
order_target_percent(stock, 0)

A condition that says:
If it's a bear market and I have the bond in my portfolio, pass
and if it's a bear market and I don't have the bond, buy the bond and sell the stocks

Third times a charm? Maybe do your ordering a bit differently. Separate the algo logic from the actual trading logic. That might keep things cleaner. So, put in your algo logic

    if spy_ma1 < spy_ma200:  
        # Go long 100% of Treasury Bond  
        longs = [context.shy]  
        log.info("Safety Month")  

    else:  
        # Go long the ETFs returned in the pipeline  
        longs = context.output.index.tolist()  
        log.info("ETF Month")  

Then do your trading logic which simply buys everything in 'longs' and sells everything else...

    # Now do actual trading  
    # Buy everything in longs  
    for stock in longs:  
        if data.can_trade(stock):  
            order_target_percent(stock, 1.0 / len(longs))  
            log.info("Buy" + str(stock))


    # Sell everything in current positions but not in longs  
    for stock in context.portfolio.positions:  
        if not stock in longs:  
            if data.can_trade(stock):  
                order_target_percent(stock, 0.0)  
                log.info("Sell" + str(stock))  

See attached backtest...

Hey Dan! That look's pretty good. Thanks so much for the help! Separating the algo logic from the actual orders was the key. Thanks again