Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
5 10 20 Crossover Strategy with Leveraged ETF

Hello Quantopian community,
I have implemented the classical 5-10-20 EMA crossover trend following strategy with one twist. Instead of buying the SPY, I am shorting SDS (ultra inverse ETF). The strategy buys when 5 day EMA > 10 day EMA and 10 day EMA > 20 day EMA. The strategy has checks in place to ensure that prior orders are executed before placing new and to make sure we do not exceed cash balance.

I am interested to know how this can be improved further including any drawbacks or pitfalls that I might be missing. Any comments about reducing volatility or increasing alpha are certainly welcome.

Thanks,
-Dev

17 responses

Hello Quantopian community,
Could somebody provide any critique to improve anything with this algorithm?

I would find out from your broker exactly what the rates are to short SDS and incorporate them into your transaction costs.

@Simon

Thanks. That is a good suggestion. Currently, IB lends it for approx 1.5%

Nice, that's not bad at all.

Instead of shorting SDS, why not go long SSO (ultra S&P). You will save the borrow cost.

There appears to be a bug in your "intradingwindow_check" function. As its written now, the function will only return True when the loc_dt hour is >= 10 AND loc_dt minute is == 45 therefore the function will only return True at times 10:45, 11:45, 12:45, 1:45 etc...., What I think you want there (I could be wrong though, perhaps you only want your strategy to execute once per hour) is for the if statement to say "if loc_dt.hour >= 10 or (loc_dt.hour == 9 and loc_dt.minute >= 45):" This version of the if statement should begin executing at 9:45AM which is what I think you want. Also, I am relatively new to the Quantopian community, but I would think that checking the time to make sure its in the market window wouldn't be necessary because the Quantopian backtester only feeds bars that are within the normal trading hours anyways? Or is that not the case? Does Quantopian feed premarket or postmarket data at all?

That's correct, Quantopian only feeds trading bars within the market hours. We don't use pre-market or post-market data

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.

@John, Thanks for your comments. Algorithm execution at every one hour has been designed deliberately. This works together with
if has_orders(context): return ::: This algorithm returns if there are any open orders. ( I don't wish to place another order if the existing order is outstanding)
if lastboughttoday(context): return ::: This block ensures that I do not place more than one trade in one day.

All of these will also ensure that there will be only one position at any time.

@Cody, thanks for your comments about buying SSO vs. shorting SDS. The reason behind shorting SDS is that leveraged ETFs and inverse or -2x in particular almost always lose a lot more money because of the effect of daily compounding. I attached a the same backtest with going long SSO and it returned about 105% vs. 165% for shorting SDS.

This strategy alone is just one idea that is not meant to sole position of any portfolio. I plan to extend the algorithm further to combine multiple strategies to improve risk adjusted returns.

Thanks for your suggestions.

@John, To further elaborate on the need to run this algorithm multiple times is because let us say, I stop and redeploy during trading hours, or if the order with the broker gets rejected etc. and more importantly my moving average threshold might not be crossed at lets say 10.45 AM but they may be crossed by 2.45 PM ( I am averaging out open, last, and close prices but still the moving averages can cross each other at any time)
Hope this helps.

@Dev, I understand the need to run it multiple times a day, but why not run it minutely instead of hourly? The checks for has_orders(context): return and lastboughttoday(context): return will ensure that you never place more than one order per day and that you don't place any orders if there are open orders unsettled, but the time frame check seems unnecessary and detrimental to the algorithm to me.

@John, I agree with you John on that. I think another reason I added that was to speed up the backtesting time but they are not needed for a live algo.

this will sting and bit with the margin reqs and borrow fees(http://ibkb.interactivebrokers.com/article/1124). They know these products decay and price the accordingly. You end up having to reserve too much capital (i.e will need 50k to short 25k of a leveraged). I would try something that went long or short based on market conditions.

For example take 2013. use the algo you have to go long SSO - i.e. buying dip all 2013 because it was a bull market. You could use a test by having the 50 above to 200 day = bull market. Then for times its bear you do the exact the sam thing expect you change the security to SDS. The thing is bear market are quicker down than bull markets are up - so you might want to us faster moving averages. Just my two cents - like the algo

Hi, Dev: try to run your code for a short time (i.e., after 2008-09 crash). After cloned the code, got an building error: Execution time out. no line number for the error. any idea what could be wrong in my process.

something is up with the site. I've ran this previously and its worked fine

Thanks, Jonathan, for your quick response. I will just wait till Monday to see if the error clears itself

The backtesting system was temporarily experiencing a technical problem. We've resolved it and you should now be able to successfully build your algorithms. Sorry for the inconvenience!

@Dev Bhosale if SDS is a leverage etf plus the effect of daily compounding then shorting it will give above average returns right? how come I'm getting this results ... ?