In the last article, we saw how tactical asset allocation strategies can be implemented in QuantShare. We created a simple strategy than ranks ETFs based on momentum and volatility, we rebalanced that strategy monthly and also showed you how you can optimize different variables. In this article, we will introduce some other advanced techniques to create even more powerful TAA strategies. Here is the trading system's formula that we will be using in this article: SetSimSetting(_NbPositions, 3); p1 = perf(close, 25); p2 = perf(close, 50); rank1 = comp(p1, "percentile"); rank2 = comp(p2, "percentile"); rank3 = rank1 * 0.5 + rank2 * 0.5; rank3 = comp(rank3, "comp"); buy = rank3 <= 3; sell = month() != ref(month(), -1); As you can see, this strategy ranks ETFs based on the 25-bar and 50-bar rate of return. It then invests in the top 3 ETFs every month. Position Sizing Say your trading system invests in 3 ETFs. By default QuantShare will allocate 33% of existing capital to each position. You can change that default behavior by creating a custom money management script or by using the new "SetSimPosSize" function of QuantShare programming language. You can instruct QuantShare to take the new position based on percentage of equity, dollar amount or number of shares. Let us imagine now that in our above TAA strategy, we would like to invest 50% of equity in the ETF ranked number 1 and 25% in the remaining two ETFs. This can be accomplished by adding the following lines: per = iff(rank3 == 1, 50, 25); SetSimPosSize(per, _PercentOfEquity); First, we create a variable "per" that takes "50" if the ETF rank is equal to 1 and "25" otherwise. We then pass that variable to the "SetSimPosSize" function and we are done. You can optimize here the different position sizes as you would do with any variable. Example: Optimize("first", 10, 90, 10); per = iff(rank3 == 1, first, (100 - first) / 2); SetSimPosSize(per, _PercentOfEquity); Optimization 1: Rank1 = 10 Rank2 = 45 (100 - 10) / 2 Rank3 = 45 Optimization 2: Rank1 = 20 Rank2 = 40 (100 - 20) / 2 Rank3 = 40 ... Optimize Your Rules A great technique to quickly find profitable TAA strategies is to feed your system with hundreds of ranking rules and let the QuantShare optimizer find the best ranking system for you. This technique was introduced in a previous article that you can find here. The idea is to create a list that contains several trading rules (in this case, we need ranking measures such as 25-bar ROC, volatility...) Once done, we will add these rules in our systems and let the optimizer check the different combinations, backtest every system and give us a detailed report of the performance of each one. If there are too many combinations, we can use the PBIL or Generic algorithm optimizer to speed up the process. Here is an example applied to our TAA formula: // Make sure you update "LIST NAME" here and in the rest of the formula ct = ApplyRule("", "LIST NAME", -1); // Calculates the number of rules Optimize("r1", 0, ct - 1, 1); Optimize("r2", 0, ct - 1, 1); SetSimSetting(_NbPositions, 3); p1 = ApplyRule("", "LIST NAME", r1); p2 = ApplyRule("", "LIST NAME", r2); rank1 = comp(p1, "percentile"); rank2 = comp(p2, "percentile"); rank3 = rank1 * 0.5 + rank2 * 0.5; rank3 = comp(rank3, "comp"); buy = rank3 <= 3; sell = month() != ref(month(), -1); Optimize Traded Symbols Another advanced technique consists of optimizing the list of ETFs to be included in your system. You can for example add several ETFs to your system (say 50) and then add few lines to create millions of combinations that would trade each time a different set of ETFs. This technique was also previously introduced in a blog post. You can find it here. Say, you have added the following ETFs in your trading system: TLT SPY GLD SHY IWM MDY ILF EDV EPP EEM FEZ In your trading system, you would like to create a tactical asset allocation strategy that trades only 4 ETFs. The strategy will rank the ETFs and buy the first performing one based on momentum. Let me show you now, how you can create multiple trading systems that when optimized will trade a different set of ETF each time. First, you need to download this function: Combination Element from Lexicographical Index Second, you will need to get the number of combination given the list of ETFs and the number of ETFs to trade each time (four, in our case) nbelements = 4; SetSimSetting(_NbPositions, nbelements); str1 = "TLT;SPY;GLD;SHY;IWM;MDY;ILF;EDV;EPP;EEM;FEZ"; nb1 = CombinationIndex(str1, Name(), nbelements, -1); // Set -1 as index here to get the number of combinations We need the number of combination to create our optimizable variable Optimize("lexindex", 0, nb1 - 1, 1); Finally, the buy rule will detect whether the currently analyzed ETF belongs to the ETF set (as defined by the index value) or not. buy = CombinationIndex(str1, Name(), nbelements, lexindex) == 1; Of course you will have to combine the above buy rule with the buy rule of your TAA system. Example: buy = rule1 and rule2;
|