Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
How can I close a position using a strategy signal.

Hello guys!, I´m analyzing the results provided by the backtest environment and I am wondering how can I close a position using a strategy signal rather than closing the order in the inmediatly next day as it is doing right now the algorithm.

The strategy to open positions is just a simple moving average condition, which one consist on open the trade if the price > sma20, price < sma50 and price < sma200, with a candle pattern signal of hammer or a bullish engulfing pattern.

I´m trying to close the trade with a strategy signal that is sma50 < sma20.

When I put all of this together and run the full backtest, when I load the transaction I see that every position I take is closed inmediatly on the next day and not taking the strategy signal of close that I want.

Any idea to fix this?

Thanks a lot.

5 responses

One thing to remember with the order_optimal_portfolio, and using the TargetWeights objective, is it will close anything that isn't explicitly given a weight. Therefore, all one really needs to define are the securities one ultimately wishes to hold. Any other securities in the current portfolio will be automatically closed.

There are of course a lot of ways to code for exiting positions, but I like using sets. Simply combine the securities currently held with those to open but then exclude anything to exit. Something like this

def my_rebalance(context, data):  
    # Get todays pipeline output.  
    pipe_results = pipeline_output('my_pipeline')

    # Get the current positions, stocks we want to go long, and exits  
    # Use sets for ease in combining by using boolean logic  
    current_positions = set(context.portfolio.positions.keys())  
    longs = set(pipe_results.query('longs1').index)  
    exits = set(pipe_results.query('exits1').index)  
    universe = set(pipe_results.index)

    # Hold anything in our current universe and we currently hold,  
    # (ie must be in the current universe),  
    # Exclude anything we have but want to exit.  
    # Include anything we want to go long.  
    holds = ((universe & current_positions)-exits) | longs

    # Make a series of equal weights for anything we want to hold  
    # If qty of holds is zero then set weight to zero (avoid divide by 0)  
    qty_of_holds = len(holds)  
    weight = 1.0 / qty_of_holds if qty_of_holds else 0  
    target_weights = pd.Series(weight, index=holds)

    # Place orders to get to our target_weights  
    # Anything not in holds will be closed  
    order_optimal_portfolio(  
            objective=opt.TargetWeights(target_weights),  
            constraints=[],  
        )

Notice this also closes anything which isn't in the current universe. This keeps any currently held securities, which happen to fall out of the trading universe, from remaining open indefinitely.

See the attached algo.

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.

Hey Dan!! thank you a lot for your early reply, it helps me a lot with my code development, I would not figure out that logical structure by myself haha

Hello Dan! how are you doing? I want to thanks again to you for the statement provided in order to hold trades day by day until the exit strategy get executed. But now I'm wondering how can I "freeze" the adding of stocks in the Target_weight series once the leverage reach specific level, I was trying to do something like this


if  context.account.leverage < 0.9:  
    holds = ((universe & current_positions)-exits) | longs  
 if context.account.leverage > 0.9:  
    holds = set([])

But what it does is to close all opened trades before the exit strategy get executed and once the leverage is below the level it starts to execute trades again, what I'm trying to code is, if the leverage is reached, stop trading but keep the opened positions until the exit strategy (or a fixed stop loss) is executed and start to freeing up space to the leverage for start to trade once again.

Thanks!

I think what may get you closer to what you want is this

if  context.account.leverage < 0.9:  
    holds = ((universe & current_positions)-exits) | longs  
 if context.account.leverage > 0.9:  
    holds =  ((universe & current_positions)-exits)

If the leverage is greater than .9, that will keep the current positions but exit anything you want to exit or isn't in the current universe. It won't add any new positions.

While this will function as you stated, it may not get you what you want. What is the motivation for 'freezing' the addition of new stocks? Is it to let the current holdings alone until they are explicitly closed? If so, maybe try simply adding a Frozen constraint. Something like this

freeze_current_holdings = opt.Frozen(current_positions)  
leverage_of_1 = opt.MaxGrossExposure(1)  
order_optimal_portfolio(  
            objective=opt.TargetWeights(target_weights),  
            constraints=[freeze_current_holdings, leverage_of_1],  
        )

While this is maybe closer to what you want it's not ideal. The issue you will have in both these cases is position sizing. As an example, if the algo starts off with 10 'longs' then each will be equally weighted with a position of .1. Now, one of those positions closes and there happens to be 10 more 'longs'. Because the existing positions are frozen, there is .9 of the portfolio in current holdings. The algo will allocate the remaining .1 to those 10 stocks. Each of those new positions would therefore get .01 weight.

You may consider a common approach and target a fixed number of holdings. As an example, assume you choose to always have a target of 10 holdings. Using the above example, after one of those 10 closes, only fill it with 1 long and not all the longs. Often there is some factor which is proportional to expected returns or the probability of success. Take the stock with this largest factor value to fill the 'hole' .

Just some ideas. Good luck.

Hey Dan! thank you again for your reply! what is happening is that I want to reduce the drawdown. So I´m trying to manage the risk with the next options: reducing the number of trades, reducing risk per trade, settings rules for low correlation with market movement, but nor of that works well, I will keep looking around in the community. Thank you for all your help!