patchGNU Octave - Patches: patch #8670, macd function for financial package

 
 

patch #8670: macd function for financial package

Submitter:  None
Submitted:  Fri 08 May 2015 08:24:39 PM UTC
   
 
Category:  None Priority:  5 - Normal
Status:  Done Privacy:  Public
Assigned to:  None Originator Email:  -email is unavailable-
Open/Closed:  Closed
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Sat 23 May 2015 10:19:36 PM UTC, comment #8: 

Thank you for the patch. I have pushed Parsiad's commits which include the supplied function. See http://hg.code.sf.net/p/octave/financial/rev/75bd0862dd5e

It will be part of the next release of the financial package.

Carnë Draug <carandraug>
Group Member
Fri 22 May 2015 07:44:21 PM UTC, comment #7: 

William's modifications are correct.

Carnë: I have added the function to the fork at https://parsiad@bitbucket.org/parsiad/octave-financial (BitBucket page https://bitbucket.org/parsiad/octave-financial) under changeset 75bd086. When you have a chance, please pull and merge.http://savannah.gnu.org/account/login.php?uri=%2Fpatch%2F%3F8670

Parsiad Azimzadeh <parsiad>
Fri 22 May 2015 04:12:19 PM UTC, comment #6: 

## Copyright (C) 2015 Adam Thompson <adammilesthompson [at] gmail [dot] com>
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 3 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, see <http://www.gnu.org/licenses/>.

## -- texinfo --
## @deftypefn {Function File} {[@var{macdvec, nineperma}] =} macd (@var{data})
## @deftypefnx {Function File} {[@var{macdvec, nineperma}] =} macd (@var{data}, @var{dim})
##
## Calculate the Moving Average Convergence/Divergence (MACD)
## line of an asset from the vector of prices (@var{data}).
## Also calculate the nine-period exponential moving average
## from the MACD line. If given, @var{dim} indicates whether
## each row is a set of observations (dim = 2) or each
## column is a set of observations (dim = 1, the default).
##
## The MACD line is calculated as the twelve-period
## exponential moving average (EMA) minus the 26-period EMA.
## Closing prices are typically used for the moving
## averages. The nine-period EMA of the MACD line is used as
## the signal line.
## @end deftypefn

function [macdvec, nineperma] = macd (data, dim = 1)

## Constants:
S_PER = 12;
L_PER = 26;
SL_PER = 9;
## End constants

## Check input and set the defaults
if nargin < 1 || nargin > 2
print_usage ();
elseif nargin < 2
dim = 1;
endif

if dim == 2
data = data';
end
 
## MACD line:
## 12-day EMA:
alpha = 2 / (S_PER + 1);
sma = mean(data(1:12));
s_ema = filter (alpha, [1 (alpha - 1)], data(12:end), sma * (1 - alpha));
# Formula for calculating EMA provided by James Sherman, Jr.
# http://octave.1599824.n4.nabble.com/vectorized-moving-average-td2132090.html
## 26-day EMA:
alpha = 2 / (L_PER + 1);
sma = mean(data(1:26));
l_ema = filter (alpha, [1 (alpha - 1)], data(26:end), sma * (1 - alpha));
## MACD:
s_ema = [nan(1,11) s_ema];
l_ema = [nan(1,25) l_ema];

macdvec = s_ema - l_ema;
sma = mean(macdvec(26:34));
## Signal line:
alpha = 2 / (SL_PER + 1);
nineperma = filter (alpha, [1 (alpha - 1)], macdvec(34:end), sma * (1 - alpha));
nineperma = [nan(1,33) nineperma];

endfunction

## Tests
%!shared d, m, n, a, b
%! d = [46.84 47.07 45.92 47.24 47.64 47.3 48.22 46.98 46.41 44.78 46.29 47.99 47.47 49.19 48.85 48.13 49.13 50.91 51.01 50.48 50.88 51.2 50.85 50.16 48.44 49.1 47.67 45.43 46.47 48.76 50.08 50.74 51.91 51.11 49.36 48.96 49.28 49.02 48.24 49.71];
%! m = [NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1.10928 0.87603 0.50460 0.29081 0.30268 0.41383 0.54884 0.74170 0.82053 0.73334 0.62476 0.55810 0.47877 0.34894 0.36051];
%! n = [NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0.66262 0.67677 0.66636 0.64471 0.61152 0.55901 0.51931];
%! [a, b] = macd (d);
%!assert([a, b], [m, n], 0.0001)
%! [a, b] = macd (d, 1);
%!assert([a, b], [m, n], 0.0001)
%! [a, b] = macd (d', 2);
%!assert([a, b], [m, n], 0.0001)

william wright <wrigh347>
Wed 20 May 2015 08:47:24 PM UTC, comment #5: 

The way you calculate the exponential moving average is wrong. In a N-period exponential moving average the first n-1 values are blank and the nth value is the simple moving average of the first n periods and then then you use the remaining periods' prices from there. Check out the following web page for an example. http://stackoverflow.com/questions/13783419/perform-a-vectorized-exponential-moving-average-in-octave

william wright <wrigh347>
Wed 20 May 2015 04:58:22 AM UTC, comment #4: 

MATLAB test:

>> d = [46.84 47.07 45.92 47.24 47.64 47.3 48.22 46.98 46.41 44.78 46.29 47.99 47.47 49.19 48.85 48.13 49.13 50.91 51.01 50.48 50.88 51.2 50.85 50.16 48.44 49.1 47.67 45.43 46.47 48.76 50.08 50.74 51.91 51.11 49.36 48.96 49.28 49.02 48.24 49.71];
>> [a, b] = macd (d)


a =

  Columns 1 through 15

       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN

  Columns 16 through 30

       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN    1.1093    0.8760    0.5046    0.2908    0.3027

  Columns 31 through 40

    0.4138    0.5488    0.7417    0.8205    0.7333    0.6248    0.5581    0.4788    0.3489    0.3605


b =

  Columns 1 through 15

       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN

  Columns 16 through 30

       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN       NaN

  Columns 31 through 40

       NaN       NaN       NaN    0.6626    0.6768    0.6664    0.6447    0.6115    0.5590    0.5193

>> [a, b] = macd (d, 1)

Error using macd>errormessage (line 152)
There must be at least 26 nonNaN values in each set of observations.

Error in macd (line 91)
         errormessage(E, 26);
 

>> [a, b] = macd (d', 2);

Error using macd>errormessage (line 152)
There must be at least 26 nonNaN values in each set of observations.

Error in macd (line 108)
         errormessage(E, 26);
 

Parsiad Azimzadeh <parsiad>
Tue 19 May 2015 07:54:58 PM UTC, comment #3: 

I don't have access to MATLAB right now. I will on June 3. At that time, I'll take a look at this again to see what the MATLAB implementation does differently. MACD is pretty simple, so there's not much they could have done differently. But they may have adopted a different convention for the first 25 samples.

Adam Thompson <adammthompson>
Sat 09 May 2015 04:46:08 PM UTC, comment #2: 

Adam: The MATLAB implementation does not produce the same results. I am not familiar with MACD; could you explain the discrepancy?

Parsiad Azimzadeh <parsiad>
Sat 09 May 2015 04:09:42 PM UTC, comment #1: 

Adding proposed maintainer of the financial package to the CC list.

Carnë Draug <carandraug>
Group Member
Fri 08 May 2015 08:24:39 PM UTC, original submission:  

## Copyright (C) 2015 Adam Thompson <adammilesthompson [at] gmail [dot] com>
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 3 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, see <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn {Function File} {[@var{macdvec, nineperma}] =} macd (@var{data})
## @deftypefnx {Function File} {[@var{macdvec, nineperma}] =} macd (@var{data}, @var{dim})
##
## Calculate the Moving Average Convergence/Divergence (MACD)
## line of an asset from the vector of prices (@var{data}).
## Also calculate the nine-period exponential moving average
## from the MACD line.  If given, @var{dim} indicates whether
## each row is a set of observations (dim = 2) or each
## column is a set of observations (dim = 1, the default).
##
## The MACD line is calculated as the twelve-period
## exponential moving average (EMA) minus the 26-period EMA.
## Closing prices are typically used for the moving
## averages.  The nine-period EMA of the MACD line is used as
## the signal line.
## @end deftypefn

function [macdvec, nineperma] = macd (data, dim = 1)

## Constants:
S_PER = 12;
L_PER = 26;
SL_PER = 9;
## End constants

  ## Check input and set the defaults
  if nargin < 1 || nargin > 2
    print_usage ();
  elseif nargin < 2
    dim = 1;
  endif
 
  if dim == 2
  data = data';
  end

## MACD line:
## 12-day EMA:
alpha = 2 / (S_PER + 1);
s_ema = filter (alpha, [1 (alpha - 1)], data, data(1) * (1 - alpha));
# Formula for calculating EMA provided by James Sherman, Jr.
# http://octave.1599824.n4.nabble.com/vectorized-moving-average-td2132090.html
## 26-day EMA:
alpha = 2 / (L_PER + 1);
l_ema = filter (alpha, [1 (alpha - 1)], data, data(1) * (1 - alpha));
## MACD:
macdvec = s_ema - l_ema;

## Signal line:
alpha = 2 / (SL_PER + 1);
nineperma = filter (alpha, [1 (alpha - 1)], macdvec, macdvec(1) * (1 - alpha));

endfunction

## Tests
%!shared d, m, n, a, b
%! d = [46.84 47.07 45.92 47.24 47.64 47.3 48.22 46.98 46.41 44.78 46.29 47.99 47.47 49.19 48.85 48.13 49.13 50.91 51.01 50.48 50.88 51.2 50.85 50.16 48.44 49.1 47.67 45.43 46.47 48.76 50.08 50.74 51.91 51.11 49.36 48.96 49.28 49.02 48.24 49.71];
%! m = [0 0.0183 -0.0592 -0.014 0.0535 0.0786 0.1708 0.1421 0.0726 -0.1127 -0.1362 -0.0174 0.0344 0.2118 0.3212 0.3459 0.441 0.6525 0.8188 0.8974 0.9807 1.0603 1.0827 1.0329 0.8448 0.7405 0.5363 0.1915 0.0021 0.0364 0.1681 0.3221 0.5324 0.6272 0.5548 0.4598 0.4057 0.338 0.2188 0.2402];
%! n = [0 0.0037 -0.0089 -0.0099 0.0027 0.0179 0.0485 0.0672 0.0683 0.0321 -0.0016 -0.0047 0.0031 0.0448 0.1001 0.1493 0.2076 0.2966 0.401 0.5003 0.5964 0.6892 0.7679 0.8209 0.8257 0.8086 0.7542 0.6416 0.5137 0.4183 0.3682 0.359 0.3937 0.4404 0.4633 0.4626 0.4512 0.4286 0.3866 0.3573];
%! [a, b] = macd (d);
%!assert([a, b], [m, n], 0.0001)
%! [a, b] = macd (d, 1);
%!assert([a, b], [m, n], 0.0001)
%! [a, b] = macd (d', 2);
%!assert([a, b], [m, n], 0.0001)

Anonymous

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by wrigh347 (Posted a comment)
  • -email is unavailable- added by adammthompson (Posted a comment)
  • -email is unavailable- added by parsiad (Posted a comment)
  • -email is unavailable- added by carandraug (proposed maintainer for financial package)
  • -email is unavailable- added by None (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2015-05-23 carandraug StatusNone Done
        Open/ClosedOpen Closed
    2015-05-09 carandraug Carbon-Copy- Added -email is unavailable-

    Back to the top

    Powered by Savane 3.13-d3ae.
    Corresponding source code