In this post, I will be documenting a few of my strategies.
The Two Divide in Universe Selection
From my personal experience of hacking up strategies and browsing the forums for interesting topics/ideas, I found that there are often two divides in setting up the universe of stocks to trade. The first being that a specific subset of stocks are hardcoded in the initialize phase, with most securities being a type of ETF that track some broad market. This method has particular advantages such that it provides low commission, large diversification benefits and global exposure. Disadvantages can include lack of alpha, high correlation and performance is dictated purely by strategy. An example of this is below as the investor hardcode a list of ETFs that should proxy the global markets. These ETFs are often chosen on the basis of volume traded and AUM.
1 2 3 4 5 6
def initialize(context): set_symbol_lookup_date('2015-05-20') context.sec_list = symbols("TLT", "JNK", "HYG", "BKLN", "USO", "UNG", "GLD", "UUP", "EUO", "YCS", "DBV", "SPY", "EEM", "EWJ", "IWM", "FXI", "EFA", "EWZ", "IYR", "VNQ") def handle_data(context,data): # Work with this specific universe only.
The second approach is using automated screening at each rebalancing period. This includes a wide range of techniques from fundamental financial ratios to price patterns. The advantages of this method can include more flexible and dynamic selection, new areas of alpha and low beta but not limited to high commission and risk of data-errors (some Q price and fundamental time-series are really messed up). Below is an example of an equity Carry screen that I have implemented.
1 2 3 4 5 6 7
context.n = 100 # screened stocks number def before_trading_start(context): dvd = get_fundamentals(query(fundamentals.valuation_ratios.dividend_yield) .filter(fundamentals.valuation.market_cap >= 2000000000) # Ensures that we get large market cap. thus liquid stocks .order_by(fundamentals.valuation_ratios.dividend_yield.desc()).limit(context.n)).T dvd = dvd.iloc[2:] # Remove the top two to control outliers update_universe(dvd.index)
Below I will show three sample strategies that I've coded up and tested. Some work better than the other and are tested over various periods including the 08' recession. It is worth noting that a lot of free-floating parameters exist but I have simplified them down to a few which worked well for me. With the exception of the Carry strategy, only the first method of universe selection will be used.
Bollinger Band Scaling
This strategy was originally cloned from Jamie Lunn's post on Q where he shared a strategy of positioning on the SP 500 index based on the current price level in a 150 day bollinger band. Position scaling was based off of which would be fully invested at a Z score of 0, 2x levered at approximately and fully cash at . The interesting thing about using the sin wave is that anything beyond those two bounds would result in scaling that didn't make much sense e.g a Z score of approximately -3 would cause the portfolio to be 100% invested in the S&P 500. I improved on this through a logistic function: . This function has nice properties such that it asymptotically approaches 2 as and 0 as
Therefore, any large Z scores would slowly approach its asymptotes. Lastly, I improved upon the strategy such that no idle cash will be held but rather allocated into a long-term treasury bond which can be proxied by price returns on the TLT ETF. Full results of the back test on minute data can be seen here. My improved strategy was able to produce an alpha of 39% at a low beta of 0.15 versus an alpha of 30% and beta of 0.69. Total returns for the improved and original were 295% vs 256% respectively.
Equity and FX Momentum
A Momentum strategy is to simply go long on stocks that have had the best historical performance for the last periods and conversely, go short on stocks that have had the worst. My various implementations are as follow:
At the start of each month,
- Equal-Weighted Simple Momentum - Sort the past month returns of USD denominated FX pairs or equity and invest in the top 3 securities
- Equal-Weighted Levered Momentum - Sort the past month returns of USD denominated FX pairs or equity and long the top 3 and short the top 3
- Equal Risk Contribution Momentum - Same as (1) except weight them such that each contribute the same amount of risk to the portfolio. Constant Correlation model plus Sample standard deviation are used to estimate weight. This methodology simplifies the process such that the th security receives the percentage weight
- Sort-Based Momentum - Using results from Almgren and Chriss (2005), Momentum list sorted from top 3 return followed by bottom 3 return are defined as rankings such that we believe the expected return at each asset in the list (starting from 1) is higher than the next . Centroids are then estimated using the Blom Approximation and the portfolio is weighted such that expected volatility and leverage cannot exceed five percent and 200% respectively. Likewise, the FX pairs are constructed such that they are USD neutral by allowing the long and short positions to sum to zero. I present results for this and (2) on the FX side starting from January 2008.
The results for the four strategies are below. Full details for (1) and (3) and be found on the community forum here.
Note that that the Benchmark for Global universe is still the regular SPY while the FX benchmark is the Short Treasury Bill. While not presented here, similar results are obtained when applying the same methodology to the opposite asset class.
Much like the popularized interest rate carry for FX pairs, equity carry involves being long in stocks with the greatest expected dividend yield and short stocks with the lowest expected dividend yield. Implementing a carry strategy in Q would require screening and thus no specific universe is hardcoded and a dynamic list of stocks appear at each rebalancing date. My various implementations of Carry is as follows:
At the end of each Quarter, filter all stocks in the universe mid-cap ($2B) and above and limit to top and bottom 50 T12M dividend yield stocks:
- Equal-Weighted Dividend Carry - Sort the trailing 12M dividend-yield in descending order and invest in the top 20/100 yield stocks. (Long Only)
- Equal-Weighted Dividend Carry w/ Short Sale - Same as (1) except we take an offsetting position through shorting the 20 lowest yielding stocks.
- GMVP Dividend Carry - Weight the portfolio such that the expected volatility is minimized for the top 20/100 stocks. A constraint of 10% max per stock is set to ensure diversification. Average number of stocks range between 10 to 15. (Long Only)
- Risk Aversion-based Carry - Similar to (2), using a risk-aversion parameter, the objective function is maximized: Where is the T12M dividend yield vector, is the risk aversion parameter (5000) and is the covariance matrix estimated with Ledoit and Wolf shrinkage. Lastly, a constraint of 3% max per stock is set to ensure diversification. Average number of stocks range between 40-60. (Long Only)
- Dynamic Dividend Carry - Portfolio is optimized to maximize dividend yield given a volatility constraint of 5% per annum max and a leverage constraint of 125%. Lastly, any remaining cash is invested into a long-term treasury bond (TLT). Average number of stocks range between 60-90!
Results of each strategy is presented below. Generally, long-only strategies tend to perform well in terms of stability of return. Likewise, optimized strategies tend to deliver less drawdown and fluctuations. In all the backtests except (5), there exists a large positive jump in return during 2010. I believe this is more due to a Q platform anomaly rather than real returns, thus, more detailed analysis would need to be done to safely say which strategy is preferable.
There are many strategies out there, especially in the community forums, to be tweaked and reused. Through my studies, I have found that momentum strategies tend to perform well in both the equity and FX sphere. Dividend carry tends to work well for long-only portfolios but can have severe draw-downs. In both risk factors, allocation routines often improve performance and should be considered for any strategy. Unfortunately, some of the tests show that these strategies have lost its efficacy during recent years in comparison with the older samples. Alpha is diminishing for a lot of these well-known strategies and we should be looking at new methodologies in portfolio construction. This is precisely why Quantopian is here to help us hack away at new ideas efficiently. In my next post, I will give more examples of reusable code within a specific framework that can save a lot of programming time. Furthermore, I'll give a detailed walk through in optimizing portfolios with SciPy solver.