Back to Community
I think I just built my first 2.0+ sharpe contest strategy, tearsheet

I was exploring an alternative dataset and came up with this strategy. It combines three alpha factors taken from the same dataset and feeds those into MaximizeAlpha in order to generate portfolio weights. Originally it did not survive slippage, but I was able to resolve that by lengthening the holding times. It turns out the signal is weaker during high volatility regimes. So, not knowing what else I could do, I decided to scale up holding times in proportion to VIX in order to reduce portfolio churn and needless slippage while the signal is weak, which worked. The signal isn't symmetrical on the long and short sides, so that's why the position concentrations differ so much.

What do you guys think based on this tearsheet?

I'm going to keep working on it, and if I can resolve the Tradable Universe issue I'm running into I plan to submit it to the contest. I've tried everything I can think of though. I even tries an exclusion list to manually remove the non-QTU stocks from ever trading, and even that doesn't pass.

Loading notebook preview...
Notebook previews are currently unavailable.
19 responses

@Viridian, great work. My suggestion is: continue to push to increase the average holding period. It will increase the average overall net profit per trade and since your strategy does already exhibits a positive edge, it should improve on that too. Resulting in higher profits.

Also, look at your shorts more closely. They represent about 19.6% of your trades and yet do generate about 55.4% of your overall profits. Your question should be: does extending their holding time further increase their average net profit per trade too?

Hey Viridian,

Nice work !

Could you extend the backtest period ? Since 01/2016 - Today is one on the strongest upmarket phase in history, you should backtest on a more volatile period which include downmarket regimes (31/08/2018-31/12/2018 isn't sufficient to test that)

great work. My suggestion is: continue to push to increase the average holding period.

Thanks. I'm already nearing the limit at times, with rolling turnover getting as low as 6%, so I'm not sure how much more I can squeeze out in that department. I will look into handling the holding period for longs and shorts separately and see if there's room for improvement there. That's a pretty good idea.

My hunch is that since the shorts are the ones returning all the alpha, if I can trade more often on the short side I may be able to generate more returns. The longs on the other hand are simply hedging market exposure and not delivering any alpha, so they may as well be held as long as possible to reduce needless churn. I will test and see if this is the case.

My concern would be different holding periods for the long and short side would mess up the hedging. Once I close a short and open another one, the long hedge that I'm still holding may no longer be appropriate and I may experience increased exposure to some risk factor.

Could you extend the backtest period ? Since 01/2016 - Today is one on the strongest upmarket phase in history, you should backtest on a more volatile period which include downmarket regimes (31/08/2018-31/12/2018 isn't sufficient to test that)

I recognize that this is a major flaw. Unfortunately the data does not extend further back. I think most of the alpha is generated on the short side, and the longs are simply acting as neutral hedges. My sense is that it should still offer an edge even in a downturn, though perhaps maybe not be as strong.

Are you able to use self-serve data in the contest? I didn't realize that was possible, how are you updating the data regularly?

@Robert: Yes, self-serve data is allowed in the contest. For 'live load' datasets, we keep records of when each data point was uploaded to Quantopian and we apply our regular point-in-time techniques on the dataset to make sure that any data uploaded via self-serve after the initial historical load is only usable in the simulation after the upload date.

@Viridian: Thanks for sharing this. It looks like you're getting really good use out of the Quantopian toolkit! For the universe issue, if I get stuck trying to debug why an algorithm is below the minimum QTU threshold, I usually use the notebook in this tutorial lesson as it gives me a little more control/insight into the results of my backtest.

One other thought: have you tried running the same strategy with TargetWeights instead of MaximizeAlpha? I find the TargetWeights behavior to be a little more intuitive than MaximizeAlpha. I'm not sure how it will affect your results but maybe it will help clarify what's going on.

If you get stuck, feel free to email in to [email protected] and we'll see if we can come up with any other suggestions on how to debug it.

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.

@Viridian:

Have you tried calculating the weights with MaximizeAlpha first and then placing the order using TargetWeights?
Something like this:

objective = opt.MaximizeAlpha(your_alpha)  
target_weights = opt.calculate_optimal_portfolio(  
            objective = objective,  
            constraints = constraints,  
        )

# Assuming q_assets is the output from your pipeline  
final_weights = pd.Series(0, index=context.q_assets.index) 

for name in context.q_assets.index:  
    final_weights.loc[name] = target_weights.loc[name]

final_objective = opt.TargetWeights(final_weights)  
final_constraints = [opt.MaxGrossExposure(1.0)]  
order_optimal_portfolio(  
            objective = final_objective,  
            constraints = final_constraints,  
        )  

Thanks for the tips, Jamie. I've somehow managed to resolve the QTU issue. Looks to have been a mistake in my logic.

Thanks, Enigma. That's precisely what I've done, except I keep a rolling list of target_weights from previous days in a context. variable and combine them together before ordering. That's how I lengthen the holding period.

how are you updating the data regularly

I wrote a simple PHP script that pulls the data from its real-time source and outputs it in the the CSV format that Quantopian expects. The php script sits on my web server and translates the data on demand. Quantopian handles the rest.

I just came across this new alphalens tearsheet today. For comparison, here's the notebook for the last model I wrote.

I tried to design something that:

1) Was 100% specific return.
2) Exhibited slow alpha decay.
3) Centered sector and style exposures around zero.

I don't know if this type of thing is what the team are currently looking for, and I don't enter the contest, but it's one way of interpreting the guidelines.

Loading notebook preview...
Notebook previews are currently unavailable.

Wow, that looks incredible, well done @Antony!

Thank you, @Joakim!

Have you used it? Do you know whether the numbers include transaction costs?

I haven’t used this new version yet (which is great, thanks @Thomas), but I’m pretty sure it uses EOD positions from the backtest, so would include trading costs, unless it was set to 0 in the backtest. Maybe @Thomas can confirm?

Ah, if I run that version of the notebook it looks a little more flattering than my previous post. :)

Loading notebook preview...
Notebook previews are currently unavailable.

Also very impressive, well done @Viridian!

Yes, excellent!

What does the negative short-term reversal exposure mean on the chart? It always confused me whether these refer to net or gross exposure. Does it mean I'm more exposed short-term reversal the short side than the long side (net exposure to STR)? Or does it mean my gross exposure is negative (positions are generally inversely exposed to STR)?

Each day there is a return to a short-term reversal strategy, defined by Q as going long the bottom quintile of stocks with the lowest 15-day RSI score, and shorting the top quintile of stocks with the highest score.

The chart says that on average --- and holding everything else constant --- if the daily return to that RSI strategy is +1.0%, your strategy will return -0.15% (based on visually reading the STR beta as -0.15 from the chart).

If the RSI strategy makes, say, -2.5%, on average your strategy will make -0.15 x -2.5% = +0.375%.

This performance attribution is repeated for the 11 sectors and the other 4 common risk factors, and added up. This sum is referred to as the common return. Anything left over is attributed to your strategy and is called specific return.

Thanks, @Antony. That makes sense. So essentially inverse exposure to short-term reversal is basically the same as being exposed to 15-day momentum.