Back

Fundamental Factor Long/Short Strategy: A New Core Equiity Paradigm by AQR

This algorithm can be used as a template for fundamental factor stock picking strategies. You can build your own version by changing the factors, ranking rule, rebalance frequency, weight etc.

The Idea comes from AQR white book. This paper talks about a long only strategy which uses more than one measures of value, momentum and quality. I used the simple version but rebalanced more frequently(once per month).

Please find the fundamental data available here. If you discover some powerful factors, it's a good thing to share to the thread so that we can generate more interesting ideas :) 

 

Update Backtest








Going to play around a bit with this later, seems like a very simple yet effective way to do a factors strategy.

Tested quick; the cloned project seems to get a margin call at some point and terminates with error marker without showing statistics for some reason.

0

Interesting stuff. Nice looking returns and stats for a fundamental algo. Anyone want to port it to C#?

0

I will have an attempt to it once I get around to it... hoping tomorrow will be clear.

0

Attached C# version, there's some error somewhere though that makes performance worse, let me know if you can fix it.

Also, I found that orginal version actually is using 2x leverage which means IB is going to send a margin call to it almost immediately if you try to live trade it. That's why you also get a margin call in backtest (but it takes some time for some reason).

3


This part is fascinating, a massive rally and its worst performance period  

1

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 QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect 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. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


@Jared Broad: I guess it's a common difficulty with short equity strategies during strong bull movements.

Anyway, I'm somewhat interested in automatically generating a similar ranking rule to this one (or periodically automatically re-optimizing the weights) to avoid the risk of overfitting. Haven't tried to use fundamental data like that yet. Still, it sounds like something everyone would have tried in-depth by now so I'm not expecting superb results.

0

I went over the C# version briefly.

Line 139 should be a _short not a _long should it not?

I changed the variable type to decimal for Rank1, Rank2, and Rank3. C# does funny things like rounding off your calculations at inconvenient times if you mix ints and doubles or ints and decimals.

I moved the Reverse on line 115 to line 117, it profits that way :p I think that's where it's supposed to go actually.

If I made any other changes I can't remember them.

The returns are not spectacular with my version but the drawdown is excellent.

It should be gone over more thoroughly, looks interesting....

Thanks Petter.

0


Here's one that beats the market, leverage is at 1.

4


Thanks Warren. I was pretty tired yesterday, can't believe I missed that I was shorting _long list since I double checked it before posting...

Interesting that reducing number of positions has such a dramatic impact on performance. However, I'm a bit worried about the impact of a few super trades (assuming these are not split/reverse split data issues). I'll have to analyze trade record I guess.

0

Reducing the number of positions forces the algo to take the cream of the crop with regards to ranking. So performance should rise if the ranking system is effective. Volatility and drawdown are the price you pay though.

0

I've found some very suspcious issue where the return is massively reduced when I add additional symbols to the universe returned from fine universe selection, I'm preparing a bug report at the moment.

E.g. compare (original)

2016-02-01T14:35:00Z,CHS,10.486874197,-952,0,Filled,-9983.504235544, 

2016-03-01T14:35:00Z,CHS,10.486874197,952,0,Filled,9983.504235544, 

versus (added a lot more symbols to universe while generating exactly the same trades)

2016-02-01T14:35:00Z,CHS,10.486874197,-952,0,Filled,-9983.504235544,

2016-03-01T14:35:00Z,CHS,12.255512925,952,0,Filled,11667.2483046, 

0

Thanks Petter Hansson we've got that hunch too -- Stefano Raggi is already working on it and we were going to post back here when its resolved. 

0

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 QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect 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. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Petter Hansson is right, those fills are very suspect. In fact the data files are good, so the logged prices are incorrect.
The reason for this issue is a bug in the algorithm, in both Coarse and Fine selection functions:

if (!_rebalance)
return new List<Symbol>();

These lines are actually telling the universe selection engine to remove all symbols, instead of leaving the universe unchanged. This is called the day after the symbols are added to the universe, causing the symbols to be unsubscribed and prices to be frozen.

This is a simple fix:

if (!_rebalance)
{
return _long != null && _short != null ? _long.Union(_short) : new List<Symbol>();
}

Sadly, the new backtest results won't look so good :)
 

0

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 QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect 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. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Is this flaw limited to the C# port, or is the original Python verson suffering from it as well?

0

The original version, in Python, has the same issue. We can use the fix Stefano has proposed.

0

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 QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect 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. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Yan, Stefano, Alexandre Catarino,                                            

Hi, For Python code, do we need to fix the original code as Stefano suggested? 

if (!_rebalance)
{
return _long != null && _short != null ? _long.Union(_short) : new List<Symbol>();
}
And Stefano said above, "...These lines are actually telling the universe selection engine to remove all symbols, instead of leaving the universe unchanged...". Does removing symbols mean liquidating symbols? or just removing symbols from the list? If it simply removes the symbols from the list, the open positions are supposed to remain same, aren't they? If so, what is the difference? Can you explain and clarify about this?Thank you.
0

Hi hanbyul_P, returning an empty list in universe selection will not liquidate the existing positions in your current portfolio. It means symbols from the universe are removed but the data subscription is maintained for all symbols with open positions and/or orders. The difference is that if your universe returns an empty list and you log the price of those symbols with no open positions, the price will remain unchanged because those symbols are unsubscribed from the universe. 

0

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 QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect 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. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Hi Jing Wu, Isn't it ok to have an empty list when it's not the time for rebalance? The algo (Python) rebalances once a month and we don't care about the rest of the time, do we? As I don't see any problems in the original algo (Python), I don't understand the difference. If I'm missing something, please correct me. And finally can you post a fixed algo (Python)?

0

You could fix the empty return by changing all the return [] to 

self.topFine = self.long + self.short
return [i.Symbol for i in self.topFine] if self.topFine is not None else []
0

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 QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect 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. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Hi Jing Wu, Thank you for posting the fixed (for empty list) algo (Python). However, I found that this algo liquidated and rebalanced (long/short) in an weird manner. I attached the algo that is exactly same as yours but with a different period of time. As you can see below, it liquidates some of stocks from the previous month and buys (shorts) back some of the exactly same stocks again. It is not supposed to do this, right? It is supposed to liquidate only if the stocks are not in the 'long/short list'. It should keep same stocks that are already in the 'long/shrot list' and buy (short) new stocks that are listed newly in the list every month.    


# Liquidated 'NEE', which was in the previous month list
2017-04-03T13:35:00Z NEE 125.8529681 -35 0 Filled -4404.853883 Liquidated
# Bought back 'NEE' this month again
2017-04-03T13:35:00Z NEE 125.8529681 35 0 Filled 4404.853883

Can you take a look and fix this? Thank you.

 

       

0


Hi HanByul_p, it is a bug in the original algorithm.

def FineSelectionFunction(self, fine):

self.long = [x for x in sorted_symbol[:self.num_fine]]
self.short = [x for x in sorted_symbol[-self.num_fine:]]
self.topFine = self.long + self.short

return [i.Symbol for i in self.topFine]
long_short_list = self.long + self.short
if (i.Invested) and (i.Symbol not in long_short_list):
self.Liquidate(i.Symbol)

From the above code, long_short_list is not a list of symbol object, it's a list of fineFundamental object.  So i.Symbol will not be in long_short_list forever, which means all the invested stocks will be liquidated. Here is a fixed version

0

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 QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect 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. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Jing Wu, Thanks !

0

Update Backtest





0

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 QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect 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. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Loading...

This discussion is closed