Investment Studio > Expressions > Functions > Indicator > MACD
float array[*][3] macd(float array[*][2] dc, integer n_long = 26, integer n_short = 12, integer n_signal = 9, float previous_long_ema = 0, float previous_short_ema = 0, float previous_signal_ema = 0)
Returns a three-column array containing dates and corresponding Moving Average Convergence/Divergence (MACD) values. Each row is structured as follows:
| Column # | Content |
| 1 | The quote date. |
| 2 | The MACD (or "fast line") value. |
| 3 | The signal (or "slow line") value. |
Given n input rows in dc, n rows are returned.
dc is a two-column array containing dates (first column) and corresponding daily closes (second column). The array is assumed to be time-sorted, with earlier dates preceding later dates.
Automatic type conversion allows the use of date strings as arguments instead of explicit date values.
n_long > 0 sets the timescale of the long EMA used to compute the MACD (fast) line from daily closes. If omitted, n_long defaults to 26.
n_short > 0 sets the timescale of the short EMA used to compute the MACD (fast) line from daily closes. If omitted, n_short defaults to 12.
n_signal > 0 sets the timescale of the EMA used to compute the signal (slow) line from the MACD ("fast") line. If omitted, n_signal defaults to 9.
previous_long_ema is the long EMA value on the trading date preceding the first date quoted in dc. If omitted, previous_long_ema defaults to 0.
previous_short_ema is the short EMA value on the trading date preceding the first date quoted in dc. If omitted, previous_short_ema defaults to 0.
previous_signal_ema is the signal EMA value on the trading date preceding the first date quoted in dc. If omitted, previous_signal_ema defaults to 0.
Interpretation
MACD is a medium term velocity indicator. The fast line is the difference of a long EMA and a short EMA, i.e. a simple resonator. The signal line is an EMA of the fast line.
To explore the MACD's behaviour, we can exploit the fact that the frequency response of any linear, time-invariant filter is just the Fourier transform of the filter's impulse response (the filter's output when the input sequence is a unit impulse, i.e. a single 1 surrounded by zeros, effectively all the way both to positive and to negative infinity). This means that we can visualize the frequency response of the MACD by passing a unit impulse through it and computing the Fourier transforms of its output.
With the definitions
_n = 1024
_dc = makevector(_n, 1, 1) * {1, 0} + subarray(swapcols(m1(_n + 1), 2, _n div 2 + 1), 2, _n + 1, 1, 2)
_macd = fftp(index(macd(array(_dc)), 0, 2))
_signal = fftp(index(macd(array(_dc)), 0, 3))
the graph sources
=_n * index(array(_macd), x + 1, 1)
=_n * index(array(_signal), x + 1, 1)
(where the "+ 1" is to skip the zeroth, constant "harmonic") yield the following amplitude response graph (red for the MACD line, blue for the signal line):

The amplitude response of the MACD line can be seen to peak at a cycle duration of 1024 / 24 » 43 days; the amplitude response of the signal line at a cycle duration of 1024 / 20 » 51 days.
Note that both these peaks lie outside the range set by the default EMA lengths (12, 26, 9), contrary to what one might naively expect from the definition of the MACD line. If band pass (rather than resonator) behaviour is wanted, i.e. a flat passband within a specified wavelength range and flat stopbands outside of it, consider cascading a hipass and a lopass filter instead.
There are three common ways to use MACD:
| Crossovers:
The basic rule is to sell when the MACD line crosses
below the signal line and buy when the MACD line crosses
above the signal line. Variations on this theme include trading on crosses of the zero line and requiring that MACD line crosses of the signal line occur sufficiently far away from the zero line to qualify as buy or sell signals. The significance of MACD crossovers is generally thought to increase with the distance from the zero line. |
|
| Overbought/oversold conditions: When the MACD pulls away sharply from the signal line, it's considered a sign that the current trend may be getting ahead of itself, setting up the stage for a reaction move. The separation between the two lines needed to qualify as an overbought/oversold condition is established from the past price history of the asset under study. | |
| Divergences: Price making new lows or new highs while the MACD fails to do the same is considered a sign that the current trend is running out of steam and may be about to reverse itself. Divergences are most significant when an overbought/oversold condition is in place. |
The MACD is considered most efficient in wide-swinging trading markets and (like other indicators relying on moving averages) better as confirmation of signals from faster indicators than as a leading buy or sell trigger.
For a real life example, consider the NASDAQ Composite in 2001:

The top chart shows prices: the red line is EMA(12) of daily closes; the blue line EMA(26); the red and green marks show the positions of crossovers in the bottom chart. The bottom chart shows the MACD line built from the same EMAs (in black) and the signal line given by its 9 day EMA (dotted); the red (sell) and green (buy) arrows show the positions of MACD/signal line crossovers.
Note how the MACD caught the big swings earlier than plain EMA crossovers, but also generated more false signals, especially near the zero line. The importance of MACD crossovers grows with their distance from the zero line, i.e. with trend strength. Other trend indicators like VHF can also be used to gauge the importance of such crossovers.
Example
Assuming standard US date format settings,
=macd({{"10/1/1990", 100}, {"10/2/1990", 120}})
returns the array {{33147, 7.97720797720798}, {33148, 15.7316904895252}}. Concentrating on the first row in the result, 33147 is the date code for October 1, 1990; 7.977... is the MA on that date (given default arguments).
The NASDAQ Composite MACD chart above uses the definitions
_NLONG = 26
_NSHORT = 12
_NSIGNAL = 9
_DMS = macd(asset_quotes(SELF, "C", FROM_DATE - _NLONG * 4, TO_DATE), _NLONG, _NSHORT, _NSIGNAL)
_CROSSES = crosses(array(_DMS), 2, array(_DMS), 3)
_MACD = vlookup(X, array(_DMS), 2, FALSE)
_SIGNAL = vlookup(X, array(_DMS), 2, FALSE)
the line sources
= _MACD
= _SIGNAL
and the image source
= choose(2 + vlookup(X, array(_CROSSES), 2, FALSE), {9, _MACD, -8}, "", {10, _MACD, 8})
The highlighting in the top chart is done with the image source
choose(2 + vlookup(X, array(_CROSSES), 2, FALSE), {13, asset_close(SELF, X)}, "", {12, asset_close(SELF, X)})
See also convolve, dpo, hipass, ema, lopass, ma, make_ema, resonate, trix, tsi.