How can I backtest my quantitative trading strategy, e.g. MACD signal?


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
where EMA_12 and EMA_26 are two different exponential moving averages with constants “const_l=12” and “”const_l=26”. The EMA is defined as:
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

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
    if signal > MACD & signal_old < MACD_old
      position = 1

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.

Get Data

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

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:

Matlab plot of IBM stock price

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

Plot of performance of MACD trading strategy

and with short selling, it looks like

Performance of MACD trading strategy with short selling

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.

1 Comment

Comments RSS
  1. TM

    I love what you guys are up too. This type of clever work and exposure! Keep up the awesome works guys I’ve included you guys to blogroll.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.