Many popular quantitative trading strategies are public for quite a while. Now, if you like to utilize such a strategy with real money, you must make sure that your strategy performs well. For simple strategies, MS Excel is perfect for this task. But, since we would like to use an optimization and a specific visualization later, we use Theta Suite and Matlab. This also allows the analysis of more complex strategies if you like.
Setting up a quantitative trading strategy: MACD – signal
One of the most popular technical indicators is the Moving Average Convergence/Divergence (MACD), which essentially the difference between two moving averages. The literature says, the zero crossing of an MACD line would give a good indication for buying of selling stock. Sometime, they add some trigger signal and claim, this would be even better. Let’s see if this is true.
More precisely trading MACD is usually defined as
MACD = EMA_12 - EMA_26
resp. in a loop over time this looks like
model MACD_from_Process import BasisProcess import const_l_12 "Exponential moving average 12 days" import const_l_26 "Exponential moving average 26 days" export MACD "Moving Average Convergence/Divergence" call EMA export BasisProcess export const_l_12 to const_l import EMA_12 from EMA call EMA export BasisProcess export const_l_26 to const_l import EMA_26 from EMA MACD = 0 loop inf Theta @dt MACD = EMA_12 - EMA_26 end end
model EMA import BasisProcess "Input Process" import const_l "Smoothing Factor" export EMA "Exponential Moving Average" % convert const_l into weight of exponential moving average alpha = 1 - 2/(const_l + 1) % initially, EMA is just the process value EMA = BasisProcess loop inf % let time pass Theta @dt % recompute EMA EMA = alpha * EMA + ( 1-alpha ) * BasisProcess end end
The appropriate trading system with a signal period of “const_l = 9” looks like
model trading import S "Stock price" import MACD "Buy-sell indicator" export Return "Performace of strategy" export position % compute signal as EMA with const_l=9 of MACD call EMA export MACD to BasisProcess export 9 to const_l import signal from EMA position = 0 Return = 1 loop inf S_old = S MACD_old = MACD signal_old = signal Theta @dt return_period = position * log(S / S_old) Return = Return * exp(return_period) if signal < MACD & signal_old > MACD_old position = -1 % or 0 if not short selling end if signal > MACD & signal_old < MACD_old position = 1 end end end
Testing the strategy with real historical data
This part is very important. I cannot stress this fact too much: in a later post, we will talk about back-testing much more.
First, we go and get some historical data, in this case IBM from yahoo. You can read here, how to get historical data into Matlab.
Assigning this data to a ThetaML process via
model historicalData import TimeGrid import Data export S loop t, data : TimeGrid, Data Theta t-@time S = data end end
allows the estimation of the performance of the MACD based trading strategy. Here is a graph of IBM stock prices from 2000-01-01 to 2011-12-31:
Backtesting the MACD trading strategy
We can run the above ThetaML models using the Theta Suite Orchestrator and connect it with the historical IBM data in Matlab in the Configurator. Then, in the Result Explorer, we get the performance of the corresponding MACD-signal trading strategy without short selling
and with short selling, it looks like
Note that during most years, the MACD-signal strategy does not perform better than the underlying itself. Taking transaction costs into account, this looks even worse. Interestingly, the year 2000 delivered a great performance of the MACD strategy, but all later years did not perform that well.
It is easy to verify if a strategy would have performed well using historical data. ThetaML and Matlab are excellent tools for this task. The MACD-based trading strategy we analyzed is not significantly better than holding the underlying itself. Other parameters of the trading strategy might lead to better results, so we can perform an optimization. We will see that next week.