Back to Community
How to create a function that closes individual trades (not positions) after N days of being opened?

I have a spread trading strategy with a signal that runs once per day.

So each 'spread trade' involves two transactions:
- Long stock 1 with weighting 0.01,
- Short stock 2 with weighting 0.01.

For example, if there's a signal 4 days in a row, each of those days will be adding 0.01 to the position size. So after 4 days the total positions will be:
- Long stock 1 with a position size of 0.04
- Short stock 2 with a position size of 0.04

My question is, how to create a function that will close each individual 'spread trade' after N days?

This is what I've tried:

def initialize(context):  
    set_commission(commission.PerShare(cost=0.0075, min_trade_cost=1))  
    set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.10))  
    context.max_days_hold = 20  
    context.days_held = {}  
    schedule_function(my_system, date_rules.every_day(), time_rules.market_close(hours=1))  
    context.spy = sid(8554)  
    context.aapl = sid(24)  

def my_system(context, data):


    #Trade condition  
    if signal >= signal_threshold:  
        if gdx not in open_orders and nugt not in open_orders and (gdx_weight-nugt_weight)<=(cash/port*max_net_leverage):  
            order_percent(spy, spy_weight)  
            order_percent(aapl, -aapl_weight)    

    #Trade Management  
    for s in context.portfolio.positions:  
        if s in context.days_held:  
            if context.days_held[s] >= context.max_days_hold:  
                del context.days_held[s]  
                order_target(s, 0)  
                context.days_held[s] += 1  
            context.days_held[s] = 1  

The problem with this is that it will close out entire positions (not individual trades) after N days of it initially being opened. For example, if there is a signal on day 1, 2 and 3, The function will close out the entire position on day 21. When it should be closing out the positions over day 21, 22 and 23.

Does this make sense? If so, how would I work around this issue?