Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Fundamentals up the wazoo

I've been taking a break from Quantopian lately but decided to post this out of curiosity to see if anyone has comments, suggestions for improvements, or can spin off some other ideas from it.

Basically I just took every relevant fundamental indicator I could and tried to incorporate them and made a sloppy attempt to shuffle the factors and quantiles to diversify the results. Leverage is not tightly controlled because I did not have the patience for the minute by minute backtest which would go on for hours and hours.

The code is very sloppy. I try to get through new ideas quickly.

The backtest is really more about scouring the fundamentals which I think is the main driving force behind the excess returns. Thoughts are welcome.

10 responses

I like that you're exploring a ton of different fundamental factors. I have two recommendations:

1) Think about some ways in which you could dynamically weight between all the different factors as the algorithm went on. It looks like in this strategy you have some intentional combination logic, which you probably want to preserve. On the flip side you can think about how to adjust the weights between many different models depending on how well they've done recently or some conditions of the underlying market.

2) I would recommend using our portfolio optimization logic, as this will automatically control leverage along with a bunch of other risk factors. I'd also be curious to see a risk model breakdown of the returns of this strategy, as that would say how much of these returns are coming from a known factor like value. Here's an example strategy which uses our portfolio optimizer. You have to think of the output of your final model as weights, it's fine if they're -1, 0, and 1.

https://www.quantopian.com/lectures/example-long-short-equity-algorithm

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.

Here's the tearsheet. It looks like most of the returns come from momentum and short-term reversal after all.

Now I'm wondering how all of these fundamental factors ultimately resulted in a momo/reversal algo. Part of the intent was to find IMPROVING fundamentals, not just statically good fundamentals, but apparently that translates to traditional momentum and/or reversals after all? Or maybe the effect of the inclusion of marketcap eclipses the rest of the factors and ultimately generates a momentum factor?

And the returns from "value" are actually negative despite what I assumed was an intense focus on fundamental factors.

One thing to keep in mind is that this strategy is long only, so you're gonna capture a lot of effects that you might not if it were market neutral. That said, often times models end up just being re-hashed versions of known and common effects like short-term reversal.

One thing I would do is break down the model into sub-components and then study each individually. Look at what happens if you just use the raw signals, and then as you add more and more and start combining them in the way your model does, at what point does each effect get introduced. You can do all this with alphalens in research.

Basically, is your overall combined model better than a simple average of all the components? Is it significantly better to the point that it's worth it to accept the risk of overfitting from a more complex model?

I'm interested in this strategy. It has some redeeming qualities.

It only goes long. It does not issue shorts, and yet, even if the backtest analysis does report that no shorts were taken in one section, with the round_trips=True option it is stated that short positions were taken. The question is how so? If the strategy is designed to only take longs, why are there shorts reported?

Cash goes to minus $626,763. I didn't see any shorting with PvR but returns are a mere 271% margin-adjusted rather than the apparent 17,000%.

@Blue, thanks for the reply. Those are part of the problems to be corrected. And there are others. But, I want to investigate if the alpha generation is really there. Or more to the point, if it will remain after the mods, and can I improve on this scenario alpha wise.

However, your answer does not answer the question.

If the strategy is only making longs, how did it make its shorts? What turn of logic would convert a long to a short if only longs (positive weights) are executed? Either this is another bug in the tearsheet analysis program, or there is some procedure or circumstances somehow fabricating those shorts. How can you trust the numbers in the tearsheet if you cannot verify if they are right!

for security in context.longs:  
            if data.can_trade(security):  
                if security not in my_positions:  
                    order_target_percent(security, weight)  

They need to remove this line here:

                if security not in my_positions:  

Primarily because this leaves stocks that were in your portfolio with the original weight rather than the new weight.

i.e. you have two stocks in your portfolio, 0.5 each. You then run the portfolio again and there are 30 outputs, in which is one of the stocks already in your portfolio. You set the weights to 0.033... per stock, then perform the ordering sequence. You end up holding 1.46666x your portfolio as you don't rebalance the stock with weight 0.5 to weight 0.033...

Thank you for the advice everyone. I will look into trying your suggestions when I get a chance to.

@Quant Trader, thanks. But, it was not it. The shorts are still there as can be seen in the following screenshot. However, your suggestion of removing that line of code did improve overall performance.

Again, thanks. Now, I have to find out why it improved.

If you know a shorted stock and maybe a date then https://www.quantopian.com/posts/track-orders using 'symbols' and 'start' would show the orders that led to it (to avoid overwhelming the logging window).

If stock and date are unknown, one can be found like this:

After this line: amt = c.portfolio.positions[o.sid].amount ; style = ''
add

          if amt < 0:  
              log.info('{} {}'.format(amt, o.sid.symbol))  

and after def _trac(to_log):, add return, to turn off all of the other logging.