How to make a condition where all trades are individually closed out X days after they were opened?

I have a basic strategy where At the end of each day:

    if signal > 0.4:
if spy not in open_orders:
order_target_percent(spy, 0.01)
if signal < -0.2:
if spy not in open_orders:
order_target_percent(spy, -0.01)


For example, If the 'signal' was > 0.4 for 5 days in a row, then a long position was opened for each of those 5 days, resulting in a total long position worth 0.05 of the portfolio.

I need to create some function which will close out each individual trade 10 days after it was opened.

5 responses

Use context object to keep track of number of days for each trade. Something like

context.tradedays[‘spy’] ={t1: ndays_t1, t2: ndays_t2, ..., tn: ndays_n}


Keep updating the ndays till the count is 10. After that liquidate and remove the entry from the dictionary.

I haven’t tested this but I think it should work. Let me know if this helps.

Thanks Shiv. Is there an example of this function put to use? I'd like to get a more clear understanding of how to incorporate this into my algo

Try the following. This is just an example. Please test it!

import quantopian.algorithm as algo

def initialize(context):
"""
Called once at the start of the algorithm.
"""
# Rebalance every day, 1 hour after market open.
algo.schedule_function(
rebalance,
algo.date_rules.every_day(),
algo.time_rules.market_open(hours=1),
)
algo.schedule_function(
record_vars,
algo.date_rules.every_day(),
algo.time_rules.market_close(),
)

def rebalance(context, data):
"""
Execute orders according to our schedule_function() timing.
"""
ndays = v + 1
if ndays > 10:
order_percent(sid(8554), -0.1)
else:

order_percent(sid(8554), 0.1)

def record_vars(context, data):
"""
Plot variables at the end of each day.
"""
record("Leverage", context.account.leverage)

def handle_data(context, data):
"""
Called every minute.
"""
pass

def initialize(context):
context.max_days_to_hold = 10
context.days_held = {}

schedule_function(close_after_n_days, date_rules.every_day(), time_rules.market_close(hours=1))
# ... allowing some time for more thinly traded stocks

def close_after_n_days(context, data):
c = context

for s in c.portfolio.positions:   # s for stock or security id/object
if s in c.days_held:
c.days_held[s] += 1
else:
c.days_held[s]  = 1

for s in c.days_held:
if c.days_held[s] >= c.max_days_to_hold:
log.info('closing {} at {} days held'.format(s.symbol, c.days_held[s]))
del c.days_held[s]   # removing the record of it

order_target(s, 0)


To merge this with your basic strategy, avoiding two trades for the same stock in a day (and the extra commissions from that), one way would be to do a check before your signal check and order_target_percent()'s and skip if c.days_held[s] >= c.max_days_to_hold - 1 (that is, 9 here) since it would be incremented to 10 and closed near market close the way it is set.

Be aware that calling order_target_percent(spy, 0.01) five days in a row will only lead you to have 1% invested in SPY. I believe order_percent(spy, 0.01) will do what you want.