Buying within certain days of crossover happening?

I have an algo I'm working on transitioning to Quantopian, but I've run into an issue. I have a custom factor and I'm wanting my trades to happen within a certain period of the close price crossing this indicator. For example say the SMA50>SMA200. I only want to buy once the SMA50>SMA200, BUT only if the cross happened in the last 5 trading days. I don't wanna buy just because the 50day is above the 200day, but within a period of the cross happening.

Thanks

4 responses

Still seeking some answers, would appreciate any help.

Thanks

Take a look at this post for some ideas and sample algorithms https://www.quantopian.com/posts/how-to-create-function-that-returns-time-since-last-crossover .

Maybe that can help?

Dan, I did see that when I was searching the forum, but I still ran into issues. I think I'm just running into issues because I'm using two different factors for the crossover, instead of one. One being the close price and the other being a custom factor.

If you want to base a trade decision on whether a stock has met some criteria AND how long since it met that criteria, then one would need to store those two pieces of data. I like storing all my data in a single dataframe but one could also put these in separate dictionaries or some other structures.

Basically just add two more columns to the pipeline output dataframe

    # Add two other columns to the dataframe for storing days sma50_above_sma200
# And if a crossover was ever observed
output = output.assign(days_sma50_above_sma200 = 0, crossed_over = False)


Next, update these columns.

    # Get a list of all securities that are in todays dataframe but NOT yesterdays
# These are the securities which are 'recent crossed over'
# Set 'crossed_over' to True for those. The days_sma50_above_sma200 will remain 0
recent_cross_over = list(set(output.index.tolist()) - set(context.output.index.tolist()))
output.loc[recent_cross_over, 'crossed_over'] = True

# Get a list of any existing securities in todays dataframe AND yesterdays (ie haven't dropped off)
# Copy the crossed_over value and increment the days_since_crossover value
existing = list(set(output.index.tolist()) & set(context.output.index.tolist()))
output.loc[existing, 'crossed_over'] = context.output.crossed_over
output.loc[existing, 'days_sma50_above_sma200'] = context.output.days_sma50_above_sma200 + 1


Finally, use these pieces of data in your ordering logic. Maybe something like this.

    # Create the open rules
# In this case a crossover must have happened (ie True) and the days since must be < 5
open_rules = 'crossed_over and (days_sma50_above_sma200 < 5)'
open_these = context.output.query(open_rules).index.tolist()


See the attached algo. This is just one way but in any case one needs to store the count of days since crossover somehow. Then use that count in the order logic.

Good luck.

0
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
 Returns 1 Month 3 Month 6 Month 12 Month
 Alpha 1 Month 3 Month 6 Month 12 Month
 Beta 1 Month 3 Month 6 Month 12 Month
 Sharpe 1 Month 3 Month 6 Month 12 Month
 Sortino 1 Month 3 Month 6 Month 12 Month
 Volatility 1 Month 3 Month 6 Month 12 Month
 Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 5a340b66da974f40a358945f
There was a runtime error.