assume a value of 50 for the signal threshold:
In [ 41 ]: SD = 50
sp500[‘Regime’] = np.where(sp500[‘42-252’] > SD, 1 , 0 )
sp500[‘Regime’] = np.where(sp500[‘42-252’] < -SD, - 1 , sp500[‘Regime’])
sp500[‘Regime’].value_counts()
Out[41]: 1 1489
0 1232
-1 871
dtype: int64
In words, on 1,489 trading dates, the 42d trend lies more than SD points above the 252d
trend. On 1,232 days, the 42d trend is more than SD points below the 252d trend.
Obviously, if the short-term trend crosses the line of the long-term trend it tends to rest
there for a (longer) while. This is what we call regime and what is illustrated in Figure 3-7,
which is generated by the following two lines of code:
In [ 42 ]: sp500[‘Regime’].plot(lw=1.5)
plt.ylim([-1.1, 1.1])
Figure 3-7. Signal regimes over time
Everything is now available to test the investment strategy based on the signals. We
assume for simplicity that an investor can directly invest in the index or can directly short
the index, which in the real world must be accomplished by using index funds, exchange-
traded funds, or futures on the index, for example. Such trades inevitably lead to
transaction costs, which we neglect here. This seems justifiable since we do not plan to
trade “too often.”
Based on the respective regime, the investor either is long or short in the market (index) or
parks his wealth in cash, which does not bear any interest. This simplified strategy allows
us to work with market returns only. The investor makes the market return when he is long
(1), makes the negative market returns when he is short (–1), and makes no returns (0)
when he parks his wealth in cash. We therefore need the returns first. In Python, we have
the following vectorized pandas operation to calculate the log returns. Note that the shift
method shifts a time series by as many index entries as desired — in our case by one
trading day, such that we get daily log returns:
In [ 43 ]: sp500[‘Market’] = np.log(sp500[‘Close’] / sp500[‘Close’].shift( 1 ))
Recalling how we constructed our regimes, it is now simple to get the returns of the trend-
based trading strategy — we just have to multiply our Regime column, shifted by one day,
by the Returns columns (the position is built “yesterday” and yields “today’s” returns):
In [ 44 ]: sp500[‘Strategy’] = sp500[‘Regime’].shift( 1 ) * sp500[‘Market’]