function [MACDLine,SignalLine] = macd(Data)
%Moving Average Convergence/Divergence (MACD).
%
% Syntax: 
%
%   [MACDLine,SignalLine] = macd(Data)
%
% Description:
%
%   MACD(DATA) calculates the Moving Average Convergence/Divergence (MACD) 
%   line from the series of data, as well as the 9-period exponential
%   moving average from the MACD line.
%
%   The MACD is calculated by subtracting the 26-period (7.5%) exponential 
%   moving average from the 12-period (15%) moving average.  The 9-period (20%)
%   exponential moving average of the MACD line is used as the "signal" line.
%
%   When the two lines are plotted, they can give you indications on when
%   to buy or sell a stock, when overbought or oversold is occurring, and
%   when the end of trend may occur. For example, when the MACD and the 20
%   moving average line has just crossed and the MACD line becomes below the
%   other line, it is time to sell.
%
% Input Argument:
%
%   DATA    - Matrix, table, or timetable of data. For matrix input, it
%             must be column-oriented.
%
%
% Output Argument:
%
%   MACDLine     - MACD series with the same number of rows (M) and type as
%                  the input data. The MACD is calculated by subtracting the
%                  26-period (7.5%) exponential 
%
%   SignalLine   - 9-period exponential series with the same number of rows (M) 
%                  and type as the input data. The 9-period (20%) exponential
%                  moving average of the MACD line is used as the "signal" line.
%
% Example:   
%
%              load SimulatedStock.mat
%              [MACDLine, SignalLine] = macd(TMW.Close);
%
%   See also ADLINE, WILLAD.
%
%   Reference: Achelis, Steven B., Technical Analysis From A To Z,
%              Second Printing, McGraw-Hill, 1995, pg. 166-168

%   Copyright 1995-2017 The MathWorks, Inc.

%--------------------- Parse/Validation ----------------------------------%

try
    narginchk(1,1);
    output = internal.finance.ftseriesInputParser({Data},{},{},{},{},{},{},{},0);
catch ME
    throwAsCaller(ME)
end

[data,~,dates,datatypeFlag] = output{:};

[numObs,~] = size(data);


validateattributes(numObs,{'numeric'},{'>=',26,'scalar'},'','number of observations');


%-------- Calculate the MACD and 9-period exponential moving average -----%

% Step1: Calculate the 26-period (7.5%)exp mov avg and the 12-period (15%) 
% exp mov avg
try
    % 26-period (7.5%) exp mov avg
    ema26p = movavg(data,'exponential',26);
    % 12-period (15%) exp mov avg
    ema12p = movavg(data,'exponential',12);
catch ME
    throwAsCaller(ME);
end

% Step2: Calculate the 9-period (20%) exp mov avg of the MACD line.
MACDLine = ema12p - ema26p;
try
    SignalLine = movavg(MACDLine,'exponential',9);
catch ME
    throwAsCaller(ME);
end

MACDLine(1:25,:) = NaN;
SignalLine(1:34,:) = NaN;

%--------------------- Output Preparation --------------------------------%
switch datatypeFlag
    case 0 % double
        if ~isempty(dates)
            MACDLine = [dates,MACDLine];
            SignalLine = [dates,SignalLine];
        end
    case 1 % table
        MACDLine = array2table(MACDLine, 'VariableNames', ...
                Data.Properties.VariableNames);
        MACDLine.Properties.Description = ...
            ['MACDLine: ', Data.Properties.Description];

        SignalLine = array2table(SignalLine, 'VariableNames', ...
                Data.Properties.VariableNames);
        SignalLine.Properties.Description = ...
            ['SignalLine: ', Data.Properties.Description];

    case 2 % timetable
        MACDLine = array2timetable(MACDLine, 'VariableNames', ...
                Data.Properties.VariableNames, 'RowTimes', dates);
        MACDLine.Properties.Description = ...
            ['MACDLine: ', Data.Properties.Description];

        SignalLine = array2timetable(SignalLine, 'VariableNames', ...
                Data.Properties.VariableNames, 'RowTimes', dates);
        SignalLine.Properties.Description = ...
            ['SignalLine: ', Data.Properties.Description];
end

end