Nowadays, correlation between markets and different assets is more obvious than never before. A move in oil price for example is likely to impact several markets including the stock and bond markets. For this reason, and many others, it is important to learn how to create and backtest trading strategies based on different assets. In this post, I will show you how to trade a stock index ETF based on the movement of a Bond ETF. I chose these two markets because there is a strong relation between stocks (represented here by a stock index ETF) and bonds. Many traders and investors own bonds and stocks. They sell their stocks and buy bonds when inflation rises (bonds are more attractive because of higher interest rates) and they sell their bonds and buy stocks when inflation decreases. Bond and Stock Index ETFs The trading strategy consists of buying the SPDR S&P500 Index Trust (SPY) if the following two conditions are met: - SPY shows a 10-bar return lower than 2% - The ETF bond (iShares Barclays 20+ Year Treasury Bond ETF) shows a positive return for the past 10 trading bars The exit rule consists of 10-bar N-Stop, which means that any SPY position is closed after 10 bars. First of all, we must download end-of-day data for these ETFs. If you already have the necessary data, please move to the "QuantShare trading system" paragraph. Getting Symbols & Historical EOD ETFs Data - Select "Symbol -> Auto Manage Symbols" - In exchange list, select "Exchange Traded Funds" - Click on "Save" QuantShare will add ETF symbols and the EOD downloader to your account. You will be promoted to start downloading data, click on "Yes". QuantShare Trading System For those who are not familiar with the QuantShare programming language, I suggest you take a look at the following post: QuantShare Programming Language Tutorial If you haven't yet implemented and back tested trading systems in QuantShare, please check the following posts: How to create a trading system Example of a trading system Since our trading system trades only SPY, then we should add only this ETF in "Symbols" panel (under "Symbols & Dates" tab). We must also set the "Number of positions" field to "1". The first buy rule can be implemented like this: rule1 = perf(close, 10) < 2; // "perf" or "roc" is the function that calculates the performance/return. In this case, the return is for the past 10 trading bars. The second rule references an external symbol, which is the ETF Bond (TLT: iShares Barclays 20+ Year Treasury Bond ETF). To get the price series of an external symbol, we can use the "GetSeries" function: a = GetSeries("TLT", close); rule2 = perf(a, 10) > 0; As with the first rule, we used the "perf" function to calculate the return of the ETF bond over the past 10 trading bars then we compare it with "0" threshold. Here is the complete strategy's formula: rule1 = perf(close, 10) < 2; a = GetSeries("TLT", close); rule2 = perf(a, 10) > 0; buy = rule1 and rule2; // Enter long only if rule1 and rule2 conditions are met For the exit rule, you just have to select "N-Bar Stop" and set a stop value of 10 (below the formula control) Backtesting and Optimizing the ETF-based Strategy Once you click on the backtest button in the simulator manager, the backtester process starts and in few seconds, you will get your simulation report. Now, if you look back at the formula, you might notice that several values can be changed. We may for example change the return period (which is 10) or we can optimize the "higher than" or "lower than" thresholds. More about optimizing a strategy can be found here. Here is how our formula looks like after setting optimizable variables: Optimize("op1", 5, 50, 5); Optimize("op2", -5, 5, 1); rule1 = perf(close, op1) < 2; a = GetSeries("TLT", close); rule2 = perf(a, op1) > op2; buy = rule1 and rule2; Even the N-Bar stop can be optimized. Note that you can include the N-Bar stop directly in the formula (Without using the stops control) by using the following instruction: SetSimStop(_StopNBar, _Point, 10, 0); This can be helpful for example if you want to use the variable "op1" to optimize the stop rule.
|