A tactical asset allocation strategy is an active strategy that rebalances the percentage held in each asset category in order to profit from momentum and/or market pricing anomalies. In this article, we will show you how easy it is to implement tactical asset allocation strategies in QuantShare. The strategy we are going to implement will have the following specifications: - Trade 8 different exchange-traded funds (ETFs) - Purchase the top two most performing ETFs based on momentum and volatility - Rebalance monthly First, let us create a new trading system - Select "Analysis -> Simulator" then click on "New" to create a new trading system Trade 8 different exchange-traded funds To select the ETFs you want to trade: - Select "Symbols & Dates" button at the top - Select the start and end dates of the simulation in the "Period" panel - Remove any existing condition in the "Symbols" panel - Click on "Add a new condition" and select "Custom Symbols" - Click on the cell under "Values" column then type your ETFs Example: MDY SSO IEV EEM ILF EPP DIA GLD Info: Here is an advanced technique that will allow you to pick the best combination of ETFs Rank ETFs based on Momentum Let us now create the formula that ranks ETFs based on Momentum. - Change the "Number of positions" setting to 2 (We want only 2 positions to be held in our portfolio at the same time) - Click on "Strategy" button at the top - Click on "Create trading system using formula editor" tab to bring the formula editor. To rank securities, you will need to use the "comp" function. Here is for example how to rank ETFs based on their 25-bar rate of change: rank1 = comp(roc(25), "rank"); The ETF that has the highest rank will get a value of 1, the second one will get a value of 2 and so on. To buy the top 2 ETFs, you need also to add the following line: buy = rank1 <= 2; // Buy an ETF only if its rank is below or equal to 2 Rank ETFs based on momentum and volatility If you want to rank ETFs based on two or more metrics, you just need to use the "comp" function for each metric. // Rank based on momentum rank1 = comp(roc(25), "rank"); // Calculate annualized volatility based on the previous 21 bars logchange=log(close/Ref(close,1)); sdlogchange=stddev(logchange,21); hisVol=sdlogchange*100*sqrt(252); // Rank based on volatility // Note that we used the minus sign here so that lower volatility gets higher rank rank2 = comp(-hisVol, "rank"); // Create a combined ranking 60% momentum and 40% volatility rank3 = 0.6 * rank1 + 0.4 * rank2; After typing the above formula, we have now two choices to buy the top 2 ETFs based on "rank3" Using the "comp" function again: rank3 = comp(-rank3, "rank"); buy = rank3 <= 2; Or using the "SetSimLongRank" function. This function ranks securities internally so that in case the simulator has many securities to choose from, it will always buy/short the one that has the best rank. SetSimLongRank(-rank3); buy = 1; // Normally this instructs QuantShare to buy every security but since the "Number of positions" setting is set to 2, only 2 ETFs will be bought Info: The Ultimate Guide to Create Trading Systems in QuantShare Rebalance monthly Since we are using daily data, we need to tell QuantShare when to exit our positions so that new ones can be bought. For this, we can add the following line to compare the current bar's month to the next bar's month. If they are different, then the current bar is the last bar of the month sell = month() != ref(month(), -1); The function "ref" references a past or future bar. ref(month(), 1) => Returns the month value of the previous bar ref(month(), -1) => Returns the month value of the next bar If you want to rebalance weekly, then you just need to use: sell = week() != ref(week(), -1); After our positions are closed (end of month), new ones will be bought thanks to the "buy" rule specified previously. Info: You can display any indicator on a chart to have a visual confirmation of how it works. For example, right click on a chart's pane, select "Edit Formula" then type: sell = week() != ref(week(), -1); plot(sell, "New Week"); Order Timing By default, positions are bought or sold at the open of the next bar. If you want to change this, you can use the "SetSimTiming" function. For example, to buy and sell at the close of the signal bar, just type these lines in your trading system's formula: SetSimTiming(_Buy, _Close, -1); SetSimTiming(_Sell, _Close, -1); By default the following formula is used: SetSimTiming(_Buy, _Open, 0); SetSimTiming(_Sell, _Open, 0); Optimize your tactical asset allocation strategy In QuantShare, you can optimize any variable using the "Optimize" function. For example, the maximum number of positions allowed in your trading system can be set programmatically using this formula: SetSimSetting(_NbPositions, 2); We can optimize that value and test different strategies by varying the number of positions from, say 1 to 10. Here is what you should type to perform this: Optimize("nb", 1, 10, 1); // Optimize the variable "nb" by varying its value from 1 to 10 with 1 as step - This will backtest 10 trading systems during the optimization. SetSimSetting(_NbPositions, nb); // Note how updated the value "2" here by the variable "nb" As you can see, everything can be optimized. Here is our TAA strategy with 3 variables optimized (Number of positions, rate of change period and volatility weight) Optimize("nb", 1, 10, 1); Optimize("period", 25, 100, 25); Optimize("w2", 0.2, 0.8, 0.2); SetSimSetting(_NbPositions, nb); // We optimized here the number of positions - nb rank1 = comp(roc(period), "rank"); // We optimized here the rate of change period - period logchange=log(close/Ref(close,1)); sdlogchange=stddev(logchange,21); hisVol=sdlogchange*100*sqrt(252); rank2 = comp(-hisVol, "rank"); w1 = 1 - w2; rank3 = w1 * rank1 + w2 * rank2; // We optimized here the volatility weight - w2 SetSimLongRank(-rank3); buy = 1; sell = month() != ref(month(), -1); Use the screener to verify your system/formula The screener tool can be very helpful for debugging purposes. You can for example use it to see ranking data for a particular date. - Select "Analysis -> Screener" from QuantShare main menu then click on "Create a new screen". - Click on "Select Symbols" then insert the securities you are using in your TAA system - Select a particular date - Type a formula. Example: r = roc(25); rank1 = comp(r, "rank"); logchange=log(close/Ref(close,1)); sdlogchange=stddev(logchange,21); hisVol=sdlogchange*100*sqrt(252); rank2 = comp(-hisVol, "rank"); rank3 = 0.6 * rank1 + 0.4 * rank2; filter = 1; // Display all securities AddColumn("ROC", r); AddColumn("Rank ROC", rank1); AddColumn("Volatility", hisVol); AddColumn("Rank Volatility", rank2); AddColumn("Final Rank", rank3); - Click on "Start" button In a future article, we will introduce you to some advanced techniques you can use to create powerful tactical asset allocation strategies.
|