From: <car...@us...> - 2012-04-17 12:03:52
|
Revision: 10262 http://octave.svn.sourceforge.net/octave/?rev=10262&view=rev Author: carandraug Date: 2012-04-17 12:03:41 +0000 (Tue, 17 Apr 2012) Log Message: ----------- time/financial: moving functions from time to financial package since they belong to Matlab's financial toolbox and time package has no maintainer Added Paths: ----------- trunk/octave-forge/main/financial/inst/busdate.m trunk/octave-forge/main/financial/inst/busdays.m trunk/octave-forge/main/financial/inst/datefind.m trunk/octave-forge/main/financial/inst/day.m trunk/octave-forge/main/financial/inst/daysact.m trunk/octave-forge/main/financial/inst/eomdate.m trunk/octave-forge/main/financial/inst/fbusdate.m trunk/octave-forge/main/financial/inst/holidays.m trunk/octave-forge/main/financial/inst/hour.m trunk/octave-forge/main/financial/inst/isbusday.m trunk/octave-forge/main/financial/inst/lbusdate.m trunk/octave-forge/main/financial/inst/lweekdate.m trunk/octave-forge/main/financial/inst/m2xdate.m trunk/octave-forge/main/financial/inst/minute.m trunk/octave-forge/main/financial/inst/month.m trunk/octave-forge/main/financial/inst/months.m trunk/octave-forge/main/financial/inst/nweekdate.m trunk/octave-forge/main/financial/inst/second.m trunk/octave-forge/main/financial/inst/thirdwednesday.m trunk/octave-forge/main/financial/inst/today.m trunk/octave-forge/main/financial/inst/x2mdate.m trunk/octave-forge/main/financial/inst/year.m trunk/octave-forge/main/financial/inst/yeardays.m Removed Paths: ------------- trunk/octave-forge/main/time/inst/busdate.m trunk/octave-forge/main/time/inst/busdays.m trunk/octave-forge/main/time/inst/datefind.m trunk/octave-forge/main/time/inst/day.m trunk/octave-forge/main/time/inst/daysact.m trunk/octave-forge/main/time/inst/eomdate.m trunk/octave-forge/main/time/inst/fbusdate.m trunk/octave-forge/main/time/inst/holidays.m trunk/octave-forge/main/time/inst/hour.m trunk/octave-forge/main/time/inst/isbusday.m trunk/octave-forge/main/time/inst/lbusdate.m trunk/octave-forge/main/time/inst/lweekdate.m trunk/octave-forge/main/time/inst/m2xdate.m trunk/octave-forge/main/time/inst/minute.m trunk/octave-forge/main/time/inst/month.m trunk/octave-forge/main/time/inst/months.m trunk/octave-forge/main/time/inst/nweekdate.m trunk/octave-forge/main/time/inst/second.m trunk/octave-forge/main/time/inst/thirdwednesday.m trunk/octave-forge/main/time/inst/today.m trunk/octave-forge/main/time/inst/x2mdate.m trunk/octave-forge/main/time/inst/year.m trunk/octave-forge/main/time/inst/yeardays.m Copied: trunk/octave-forge/main/financial/inst/busdate.m (from rev 10260, trunk/octave-forge/main/time/inst/busdate.m) =================================================================== --- trunk/octave-forge/main/financial/inst/busdate.m (rev 0) +++ trunk/octave-forge/main/financial/inst/busdate.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,97 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {b =} busdate (refdate) +## @deftypefnx {Function File} {b =} busdate (refdate, direction) +## @deftypefnx {Function File} {b =} busdate (refdate, direction, holiday) +## @deftypefnx {Function File} {b =} busdate (refdate, direction, holiday, weekend) +## +## Return the datenum of the next or previous business day from +## @var{refdate}. @var{direction} indicates the next day (default) if 1 +## and the previous day if -1. @var{holiday} is a vector of datenums +## that defines the holidays observed (the holidays function is used if +## not given). @var{weekend} defines the days of the week that should +## be considered weekends; [1 0 0 0 0 0 1] (default) indicates that +## Sunday and Saturday are holidays. +## +## If any of the optional inputs (@var{direction}, @var{holiday}, +## @var{weekend}) are empty, then the default is used. +## +## @seealso{holidays, lbusdate, isbusday, fbusdate} +## @end deftypefn + +function rd = busdate (rd, d, hol, wkend) + + if ~isnumeric (rd) + rd = datenum ( rd); + endif + if nargin < 2 || isempty (d) + d = 1; + elseif ~ all (abs (d) == 1) + ## People could use other numbers to skip days, but that is not + ## supported. + error ("directions must all be either 1 or -1.") + endif + if nargin < 3 + hol = []; + end + if nargin < 4 + wkend = []; + elseif nargin > 4 + print_usage (); + endif + + rd += d; + mask = ~isbusday (rd, hol, wkend); + while any (mask) + ## Only recompute for the days that are not yet business days + if isscalar (d) + rd(mask) += d; + else + rd(mask) += d(mask); + endif + mask(mask) = ~isbusday (rd(mask), hol, wkend); + endwhile + +endfunction + +## Tests +## A normal day +%!assert(busdate(datenum(2008,1,2)), datenum(2008,1,3)) +## A holiday +%!assert(busdate(datenum(2007,12,31)), datenum(2008,1,2)) +## Go over a weekend and start in a weekend +%!assert(busdate(datenum(2007,1,5)), datenum(2007,1,8)) +%!assert(busdate(datenum(2007,1,6)), datenum(2007,1,8)) +## Backward +%!assert(busdate(datenum(2008,1,3), -1), datenum(2008,1,2)) +## Backward holiday +%!assert(busdate(datenum(2008,1,2), -1), datenum(2007,12,31)) +## Backward with alternate holidays +%!assert(busdate(datenum(2008,1,2), -1, datenum(2007,1,1):datenum(2008,1,1)), datenum(2006,12,29)) +## Multiple dates in both orientations +%!assert(busdate([datenum(2008,1,2) datenum(2007,1,1)]), [datenum(2008,1,3) datenum(2007,1,2)]) +%!assert(busdate([datenum(2008,1,2) datenum(2007,1,1)], [1 1]), [datenum(2008,1,3) datenum(2007,1,2)]) +%!assert(busdate([datenum(2008,1,2) datenum(2007,1,1)], 1), [datenum(2008,1,3) datenum(2007,1,2)]) +%!assert(busdate([datenum(2008,1,2);datenum(2007,1,1)], [1;1]), [datenum(2008,1,3);datenum(2007,1,2)]) +## Multiple dates with opposite directions holidays and weekends +%!assert(busdate([datenum(2008,1,2);datenum(2007,1,2)], [1;-1]), [datenum(2008,1,3);datenum(2006,12,29)]) +## Alternate weekends +%!assert(busdate(datenum(2008,1,2), 1, holidays(datenum(2008,1,1), datenum(2008,1,31)), [1 0 0 0 0 0 0]), datenum(2008,1,3)) +%!assert(busdate(datenum(2008,1,4), 1, holidays(datenum(2008,1,1), datenum(2008,1,31)), [1 0 0 0 0 0 0]), datenum(2008,1,5)) +%!assert(busdate(datenum(2008,1,5), 1, holidays(datenum(2008,1,1), datenum(2008,1,31)), [1 0 0 0 0 0 0]), datenum(2008,1,7)) +%!assert(busdate(datenum(2008,1,6), 1, holidays(datenum(2008,1,1), datenum(2008,1,31)), [1 0 0 0 0 0 0]), datenum(2008,1,7)) +%!assert(busdate(datenum(2008,1,1), 1, holidays(datenum(2008,1,1), datenum(2008,1,31)), [1 1 1 1 1 1 0]), datenum(2008,1,5)) Copied: trunk/octave-forge/main/financial/inst/busdays.m (from rev 10260, trunk/octave-forge/main/time/inst/busdays.m) =================================================================== --- trunk/octave-forge/main/financial/inst/busdays.m (rev 0) +++ trunk/octave-forge/main/financial/inst/busdays.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,127 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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{bdates} =} busdays (@var{sdate}, @var{edate}) +## @deftypefnx {Function File} {@var{bdates} =} busdays (@var{sdate}, @var{edate}, @var{bdmode}) +## @deftypefnx {Function File} {@var{bdates} =} busdays (@var{sdate}, @var{edate}, @var{bdmode}, @var{holvec}) +## Generate a list of business dates at the end of the periods defined +## between (including) @var{sdate} and @var{edate}. +## +## @var{sdate} is the starting date, @var{edate} is the ending date, +## both are in serial date format (see datenum). @var{bdmode} is the +## business day frequency ("daily", "weekly", "monthly", "quarterly", +## "semiannual", or "annual"); these can be abbreviated by the first +## letter and they may also use an integer corresponding to the order in +## the above list (i.e. "daily" = 1). @var{holvec} is an optional list +## of holidays. If the holidays are not given, then the holidays +## function is used. +## @seealso{holidays, busdate, lbusdate, isbusday, fbusdate, datenum} +## @end deftypefn + +function bd = busdays (sd, ed, mode=1, hol=[]) + + if nargin < 2 || nargin > 4 + print_usage (); + endif + if ~isnumeric (sd) + sd = datenum (sd); + endif + if ~isnumeric (ed) + ed = datenum (ed); + endif + if ed < sd + error ("busdays: the start date must be less than the end date") + endif + if isempty (hol) + ## make the holidays take into account the whole ending year because + ## the day may extend beyond the actual ending date + edtmp = datevec (ed); + edtmp(2:3) = [12 31]; + hol = holidays (sd, datenum (edtmp)); + endif + ## Convert the mode to the numeric + modestr = "dwmqsa"; + if ischar (mode) + mode = find (lower (mode(1)) == modestr); + if isempty (mode) + error ("busdays: mode must be one of '%s'", modestr) + endif + elseif isnumeric (mode) + if mode < 1 || mode > length (modestr) + error ("busdays: mode must be between 1 and %d", length (modestr)) + endif + else + error ("busdays: mode must be a number or string") + endif + + ## do the computation + if mode == 1 + ## daily + bd = (sd:ed)'(isbusday (sd:ed, hol)); + elseif mode < 6 + if mode == 2 + ## weekly make the start and end dates Fridays and then move back + ## from there + wd = weekday ([sd;ed]); + d = [sd;ed] - wd + 7; + ## there are generally not more than one week of holidays at a + ## time, but the call to unique will make certain of that. + bd = unique (busdate ([d(1):7:d(2)]', -1, hol)); + else + d = datevec ([sd:ed]); + ## unique year and month list within the date range + ym = unique (d(:,1:2), "rows"); + if mode == 3 + ## monthly, do nothing to the ym list + elseif mode == 4 + ## quarterly + if mod (ym(end), 3) != 0 + ## make the last month an end of quarter month + ym(end) = ym(end) + 3 - mod (ym(end), 3); + endif + ym(mod (ym(:,2), 3) != 0, :) = []; + elseif mode == 5 + ## semi-annually + if mod (ym(end), 6) != 0 + ## make the last month an end of semi-annual month (6, 12) + ym(end) = ym(end) + 6 - mod (ym(end), 6); + endif + ym(mod (ym(:,2), 6) != 0, :) = []; + endif + bd = lbusdate (ym(:,1), ym(:,2), hol); + endif + elseif mode == 6 + ## annual + d = datevec ([sd;ed]); + bd = lbusdate ((d(1,1):d(2,1))', 12, hol); + else + ## this should have been caught before now + error ("busdays: invalid mode") + endif + +endfunction + +## Tests +%!assert (busdays (datenum (2008, 1, 1), datenum (2008, 1, 12)), datenum (2008, 1, [2;3;4;7;8;9;10;11])) +%!assert (busdays (datenum (2008, 1, 1), datenum (2008, 1, 12), "d"), datenum (2008, 1, [2;3;4;7;8;9;10;11])) +%!assert (busdays (datenum (2001, 1, 2), datenum (2001, 1, 9), "w"), datenum (2001, 1, [5;12])) +%!assert (busdays (datenum (2008, 1, 1), datenum (2008, 1, 2), "m"), datenum (2008, 1, 31)) +%!assert (busdays (datenum (2008, 1, 1), datenum (2010, 5, 2), "m"), lbusdate ([2008*ones(12,1);2009*ones(12,1);2010*ones(5,1)], [1:12 1:12 1:5]')) +%!assert (busdays (datenum (2008, 1, 1), datenum (2008, 1, 2), "q"), datenum (2008, 3, 31)) +%!assert (busdays (datenum (2008, 1, 1), datenum (2010, 5, 2), "q"), lbusdate ([2008*ones(4,1);2009*ones(4,1);2010*ones(2,1)], [3:3:12 3:3:12 3 6]')) +%!assert (busdays (datenum (2008, 1, 1), datenum (2008, 1, 2), "s"), datenum (2008, 6, 30)) +%!assert (busdays (datenum (2008, 1, 1), datenum (2010, 5, 2), "s"), lbusdate ([2008;2008;2009;2009;2010], [6 12 6 12 6]')) +%!assert (busdays (datenum (2008, 1, 1), datenum (2011, 1, 2), "a"), datenum ([2008;2009;2010;2011], [12;12;12;12], [31;31;30;30])) Copied: trunk/octave-forge/main/financial/inst/datefind.m (from rev 10260, trunk/octave-forge/main/time/inst/datefind.m) =================================================================== --- trunk/octave-forge/main/financial/inst/datefind.m (rev 0) +++ trunk/octave-forge/main/financial/inst/datefind.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,44 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {indices =} datefind (subset, superset, tol) +## +## Find any instances of the @code{subset} in the @code{superset} with +## the @code{tol}erance. @code{tol} is 0 by default. +## +## @seealso{date, datenum} +## @end deftypefn + +function idx = datefind (subset, superset, tol=0) + + if (nargin < 2 || nargin > 3) + print_usage (); + elseif ! isscalar (tol) + error ("datefind: tol must be a scalar") + endif + + idx = []; + for i = 1:numel (superset) + if any (subset(:) - tol <= superset(i) & superset(i) <= subset(:) + tol) + idx(end+1, 1) = i; + endif + endfor + +endfunction + +## Tests +%!assert (datefind (datenum (1999, 7, [10;20]), datenum (1999, 7, 1:31)), [10;20]) +%!assert (datefind (datenum (1999, 7, [10;20]), datenum (1999, 7, 1:31), 1), [9;10;11;19;20;21]) Copied: trunk/octave-forge/main/financial/inst/day.m (from rev 10260, trunk/octave-forge/main/time/inst/day.m) =================================================================== --- trunk/octave-forge/main/financial/inst/day.m (rev 0) +++ trunk/octave-forge/main/financial/inst/day.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,31 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {dom =} day (Date) +## +## Returns the day of the month from a serial date number or a date +## string. +## +## @seealso{date, datevec, now, month, year} +## @end deftypefn + +function t = day (dates) + + t = datevec (dates); + t = t (:,3); + +endfunction + Copied: trunk/octave-forge/main/financial/inst/daysact.m (from rev 10260, trunk/octave-forge/main/time/inst/daysact.m) =================================================================== --- trunk/octave-forge/main/financial/inst/daysact.m (rev 0) +++ trunk/octave-forge/main/financial/inst/daysact.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,76 @@ +## Copyright (C) 2007 David Bateman +## +## 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} {} daysact (@var{d1}) +## @deftypefnx {Function File} {} daysact (@var{d1}, @var{d2}) +## Calculates the number of days between two dates. If the second date is not +## given, calculate the number of days since 1-Jan-0000. The variables @var{d1} +## and @var{d2} can either be strings or an @var{n}-row string matrix. If both +## @var{d1} and @var{d2} are string matrices, then the number of rows must +## match. An example of the use of @code{daysact} is +## +## @example +## @group +## daysact ("01-Jan-2007", ["10-Jan-2007"; "23-Feb-2007"; "23-Jul-2007"]) +## @result{} 9 +## 53 +## 203 +## @end group +## @end example +## @seealso{datenum} +## @end deftypefn + +function days = daysact (d1, d2) + if (nargin == 1) + nr = size (d1, 1); + if (nr != 1) + days = zeros (nr,1); + for i = 1 : nr + days (i) = datenum (d1 (i,:)); + endfor + else + days = datenum(d1); + endif + elseif (nargin == 2) + nr1 = size (d1, 1); + nr2 = size (d2, 1); + if (nr1 != nr2 && nr1 != 1 && nr2 != 1) + error ("daysact: size mismatch"); + endif + if (nr1 == 1 && nr2 == 1) + days = datenum (d2) - datenum(d1); + elseif (nr1 == 1) + days = zeros (nr2, 1); + for i = 1 : nr2 + days(i) = datenum (d2 (i,:)) - datenum (d1); + endfor + elseif (nr2 == 1) + days = zeros (nr1, 1); + for i = 1 : nr1 + days(i) = datenum (d2) - datenum (d1 (i,:)); + endfor + else + days = zeros (nr1, 1); + for i = 1 : nr1 + days(i) = datenum (d2 (i, :)) - datenum (d1 (i,:)); + endfor + endif + else + print_usage(); + endif +endfunction + +%!assert (daysact ("01-Jan-2007", ["10-Jan-2007"; "23-Feb-2007"; "23-Jul-2007"]),[9;53;203]) Copied: trunk/octave-forge/main/financial/inst/eomdate.m (from rev 10260, trunk/octave-forge/main/time/inst/eomdate.m) =================================================================== --- trunk/octave-forge/main/financial/inst/eomdate.m (rev 0) +++ trunk/octave-forge/main/financial/inst/eomdate.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,40 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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{e} =} eomdate (@var{y}, @var{m}) +## Return the last day of the month @var{m} for the year @var{y} in +## datenum format. +## @seealso{datenum, datevec, weekday, eomday} +## @end deftypefn + +function e = eomdate (y, m) + + if (nargin != 2) + print_usage (); + endif + + d = eomday (y, m); + e = datenum (y, m, d); + +endfunction + +## Tests +## Leap years +%!assert(eomdate(2008, 2), datenum(2008, 2, 29)) +%!assert(eomdate(2007, 2), datenum(2007, 2, 28)) +## Vectors +%!assert(eomdate([2008 2007], [3 4]), [datenum(2008, 3, 31) datenum(2007, 4, 30)]) +%!assert(eomdate([2008;2007], [3;4]), [datenum(2008, 3, 31);datenum(2007, 4, 30)]) Copied: trunk/octave-forge/main/financial/inst/fbusdate.m (from rev 10260, trunk/octave-forge/main/time/inst/fbusdate.m) =================================================================== --- trunk/octave-forge/main/financial/inst/fbusdate.m (rev 0) +++ trunk/octave-forge/main/financial/inst/fbusdate.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,58 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {b =} fbusdate (year, month) +## @deftypefnx {Function File} {b =} fbusdate (year, month, holiday) +## @deftypefnx {Function File} {b =} fbusdate (year, month, holiday, weekend) +## +## Return the datenum of the first business day of the @var{year} and +## @var{month}. @var{holiday} is a vector of datenums that defines the +## holidays observed (the holidays function is used if not given). +## @var{weekend} defines the days of the week that should be considered +## weekends; [1 0 0 0 0 0 1] (default) indicates that Sunday and +## Saturday are holidays. +## +## If any of the optional inputs (@var{holiday}, @var{weekend}) are +## empty, then the default is used. +## +## @seealso{holidays, lbusdate, isbusday, busdate} +## @end deftypefn + +function rd = fbusdate (y, m, hol, wkend) + + rd = datenum (y, m, 1); + if nargin < 3 + hol = []; + end + if nargin < 4 + wkend = []; + elseif nargin < 3 || nargin > 4 + print_usage (); + endif + + ## Test from the day before the beginning of the month so that the + ## first day of the month is captured. + rd = busdate (rd-1, 1, hol, wkend); + +endfunction + +## Tests +## A normal day +%!assert(fbusdate(2008,2), datenum(2008,2,1)) +## A holiday +%!assert(fbusdate(2008,1), datenum(2008,1,2)) +## A weekend +%!assert(fbusdate(2008,3), datenum(2008,3,3)) Copied: trunk/octave-forge/main/financial/inst/holidays.m (from rev 10260, trunk/octave-forge/main/time/inst/holidays.m) =================================================================== --- trunk/octave-forge/main/financial/inst/holidays.m (rev 0) +++ trunk/octave-forge/main/financial/inst/holidays.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,91 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {h =} holidays (startdate, enddate) +## +## Return a vector of datenums that were holidays between +## @var{startdate} and @var{enddate}, inclusive. These holidays are +## trading holidays observed by the NYSE according to its rule 51.10. It +## does not take into account the exceptions for "unusual business +## conditions" or for additional days that have been called as holidays +## for one-time purposes. +## +## The complete list can be found at +## http://www.chronos-st.org/NYSE_Observed_Holidays-1885-Present.html +## +## @seealso{busdate, lbusdate, isbusday, fbusdate} +## @end deftypefn + +function hol = holidays (sd, ed) + + sd = datenum (datevec (sd)); + ed = datenum (datevec (ed)); + + ## just get the start and end years and generate all holidays in that range + yrs = year(sd):year(ed); + + hol = []; + ## New Year's Day + tmphol = datenum (yrs, 1, 1); + hol = [hol; tmphol(:)]; + ## Martin Luther King Day, the third Monday in January + tmphol = nweekdate (3, 2, yrs, 1); + hol = [hol; tmphol(:)]; + ## Washington's Birthday, the third Monday in February + tmphol = nweekdate (3, 2, yrs, 2); + hol = [hol; tmphol(:)]; + ## Good Friday + tmphol = easter (yrs) - 2; + hol = [hol; tmphol(:)]; + ## Memorial Day, the last Monday in May + tmphol = lweekdate (2, yrs, 5); + hol = [hol; tmphol(:)]; + ## Independence Day, July 4 + tmphol = datenum (yrs, 7, 4); + hol = [hol; tmphol(:)]; + ## Labor Day, the first Monday in September + tmphol = nweekdate (1, 2, yrs, 9); + hol = [hol; tmphol(:)]; + ## Thanksgiving Day, the fourth Thursday in November + tmphol = nweekdate (4, 5, yrs, 11); + hol = [hol; tmphol(:)]; + ## Christmas Day + tmphol = datenum (yrs, 12, 25); + hol = [hol; tmphol(:)]; + + ## Adjust for Saturdays and Sundays + wd = weekday (hol); + if any (wd == 1) + hol(wd == 1) = hol(wd == 1) + 1; + endif + if any (wd == 7) + hol(wd == 7) = hol(wd == 7) - 1; + endif + + ## Trim out the days that are not in the date range + hol(hol > ed | hol < sd) = []; + hol = sort (hol); + +endfunction + +## Tests +%!assert(holidays(datenum(2008,1,1), datenum(2008,12,31)), datenum(2008*ones(9,1), [1;1;2;3;5;7;9;11;12], [1;21;18;21;26;4;1;27;25])) +## Test Independence day observing on a Monday (July 5) and Christmas +## observing on a Friday (Dec 24) +%!assert(holidays(datenum(2004,1,1), datenum(2004,12,31)), datenum(2004*ones(9,1), [1;1;2;4;5;7;9;11;12], [1;19;16;9;31;5;6;25;24])) +%!assert(holidays(datenum(2008,3,5), datenum(2008,3,8)), zeros(0,1)) +%!assert(holidays(datenum(2008,3,5), datenum(2008,3,5)), zeros(0,1)) +%!assert(holidays(datenum(2008,1,1), datenum(2008,1,1)), datenum(2008,1,1)) Copied: trunk/octave-forge/main/financial/inst/hour.m (from rev 10260, trunk/octave-forge/main/time/inst/hour.m) =================================================================== --- trunk/octave-forge/main/financial/inst/hour.m (rev 0) +++ trunk/octave-forge/main/financial/inst/hour.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,30 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {h =} hour (Date) +## +## Returns the hour from a serial date number or a date string. +## +## @seealso{date, datevec, now, minute, second} +## @end deftypefn + +function t = hour (dates) + + t = datevec (dates); + t = t (:,4); + +endfunction + Copied: trunk/octave-forge/main/financial/inst/isbusday.m (from rev 10260, trunk/octave-forge/main/time/inst/isbusday.m) =================================================================== --- trunk/octave-forge/main/financial/inst/isbusday.m (rev 0) +++ trunk/octave-forge/main/financial/inst/isbusday.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,72 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {r =} isbusday (refdate) +## @deftypefnx {Function File} {r =} isbusday (refdate, holiday) +## @deftypefnx {Function File} {r =} isbusday (refdate, holiday, weekend) +## +## Return true if the @var{refdate} is a business date @var{refdate}. +## @var{holiday} is a vector of datenums that defines the holidays +## observed (the holidays function is used if not given). @var{weekend} +## defines the days of the week that should be considered weekends; +## [1 0 0 0 0 0 1] (default) indicates that Sunday and Saturday are +## weekends. +## +## @seealso{holidays, lbusdate, busdate, fbusdate} +## @end deftypefn + +function mask = isbusday (rd, hol=[], wkend=[]) + + if ~ isnumeric (rd) + rd = datenum (rd); + endif + if isempty (hol) + ## Get all possible holidays that could affect the output. + hol = holidays (min(rd), max(rd)); + end + if isempty (wkend) + wkend = [1 0 0 0 0 0 1]; + elseif numel (wkend) ~= 7 + error ("wkend must have 7 elements") + elseif nargin > 3 + print_usage (); + endif + + mask = reshape (wkend (weekday (rd)), size (rd)); + if ~ isempty (hol) + ## Is it a holiday? + mask = mask | ismember(rd, hol); + endif + mask = ~mask; +endfunction + +## Tests +## A normal day +%!assert(isbusday(datenum(2008,1,2)), true()) +## A holiday +%!assert(isbusday(datenum(2008,1,1)), false()) +%!assert(isbusday(datenum(2008,1,1), []), false()) +## A weekend +%!assert(isbusday(datenum(2008,2,2)), false()) +## An alternate holiday +%!assert(isbusday(datenum(2008,1,2), datenum(2008,1,2)), false()) +## An alternate weekend +%!assert(isbusday(datenum(2008,1,2), [], zeros(1,7)), true()) +%!assert(isbusday(datenum(2008,1,2), [], ones(1,7)), false()) +## A vector +%!assert(isbusday([datenum(2008,1,2) datenum(2008,2,2)]), [true() false()]) +## A vector in the other direction +%!assert(isbusday([datenum(2008,1,2);datenum(2008,2,2)]), [true();false()]) Copied: trunk/octave-forge/main/financial/inst/lbusdate.m (from rev 10260, trunk/octave-forge/main/time/inst/lbusdate.m) =================================================================== --- trunk/octave-forge/main/financial/inst/lbusdate.m (rev 0) +++ trunk/octave-forge/main/financial/inst/lbusdate.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,56 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {b =} lbusdate (year, month) +## @deftypefnx {Function File} {b =} lbusdate (year, month, holiday) +## @deftypefnx {Function File} {b =} lbusdate (year, month, holiday, weekend) +## +## Return the datenum of the last business day of the @var{year} and +## @var{month}. @var{holiday} is a vector of datenums that defines the +## holidays observed (the holidays function is used if not given). +## @var{weekend} defines the days of the week that should be considered +## weekends; [1 0 0 0 0 0 1] (default) indicates that Sunday and +## Saturday are holidays. +## +## If any of the optional inputs (@var{holiday}, @var{weekend}) are +## empty, then the default is used. +## +## @seealso{holidays, fbusdate, isbusday, busdate} +## @end deftypefn + +function rd = lbusdate (y, m, hol, wkend) + + rd = eomdate (y, m); + if nargin < 3 + hol = []; + end + if nargin < 4 + wkend = []; + elseif nargin < 3 || nargin > 4 + print_usage (); + endif + + ## Test from the day after the end of the month so that the + ## last day of the month is captured. + rd = busdate (rd+1, -1, hol, wkend); + +endfunction + +## Tests +## A normal day +%!assert(lbusdate(2008,4), datenum(2008,4,30)) +## A weekend +%!assert(lbusdate(2008,5), datenum(2008,5,30)) Copied: trunk/octave-forge/main/financial/inst/lweekdate.m (from rev 10260, trunk/octave-forge/main/time/inst/lweekdate.m) =================================================================== --- trunk/octave-forge/main/financial/inst/lweekdate.m (rev 0) +++ trunk/octave-forge/main/financial/inst/lweekdate.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,37 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {last =} lweekdate (weekday, year, month, nextday) +## +## Returns the last occurrence of @var{weekday} from the @var{month} and +## @var{year}. If the optional @var{nextday} argument is given, then +## the week must also contain @var{nextday}. +## +## @seealso{eomdate, nweekdate, weekday} +## @end deftypefn + +function t = lweekdate (varargin) + if nargin < 3 || nargin > 4 + error ("3 or 4 input arguments are required") + elseif nargin == 3 + varargin{4} = 0; + endif + + t = nweekdate ("lweekdate", varargin{:}); + +endfunction + +## Tests are in nweekdate Copied: trunk/octave-forge/main/financial/inst/m2xdate.m (from rev 10260, trunk/octave-forge/main/time/inst/m2xdate.m) =================================================================== --- trunk/octave-forge/main/financial/inst/m2xdate.m (rev 0) +++ trunk/octave-forge/main/financial/inst/m2xdate.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,74 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {exceldatenums =} m2xdate (datenums) +## @deftypefnx {Function File} {exceldatenums =} m2xdate (datenums, convention) +## @deftypefnx {Function File} {exceldatenums =} m2xdate (datenums, convention, "ExcelBug") +## +## Convert @var{datenums} from the internal date format to the format +## used by Microsoft Excel. If set to 0 (default, Excel for Windows), +## @var{convention} specifies to use the Excel 1900 convention where Jan +## 1, 1900 corresponds to Excel serial date number 1. If set to 1 +## (Excel for Mac), @var{convention} specifies to use the Excel 1904 +## convention where Jan 1, 1904 corresponds to Excel serial date number +## 0. +## +## Note that this does not take into account the Excel bug where 1900 is +## considered to be a leap year unless you give the "ExcelBug" option. +## +## Excel does not represent dates prior to 1 January 1900 using this +## format, so a warning will be issued if any dates preceed this date. +## +## @seealso{datenum, x2mdate} +## @end deftypefn + +function dates = m2xdate (dates, convention, excelbug) + + if nargin == 1 + convention = 0; + excelbug = false(); + elseif nargin == 2 + excelbug = false(); + elseif nargin == 3 + excelbug = strcmpi(excelbug, "ExcelBug"); + else + print_usage (); + endif + + if convention == 0 + adj = datenum(1900, 1, 1) - 2; + elseif convention == 1 + adj = datenum(1904, 1, 1); + endif + + if excelbug + datemask = (dates < datenum(1900, 3, 1)); + dates(datemask) = dates(datemask) - 1; + endif + dates = dates - adj; + if any (dates < 0) + warning ("Negative date found, this will not work within MS Excel.") + endif + +endfunction + +## Tests +%!assert(m2xdate(datenum(2008, 1, 1)), 39448) +%!assert(m2xdate(datenum(2007:2008, 1, 1)), [39083 39448]) +%!assert(m2xdate(datenum(1900, 1, 1)), 2) +%!assert(m2xdate(datenum(1900, 1, 1), 0, "ExcelBug"), 1) +%!assert(m2xdate(datenum(1904, 1, 1), 1), 0) + Copied: trunk/octave-forge/main/financial/inst/minute.m (from rev 10260, trunk/octave-forge/main/time/inst/minute.m) =================================================================== --- trunk/octave-forge/main/financial/inst/minute.m (rev 0) +++ trunk/octave-forge/main/financial/inst/minute.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,30 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {m =} minute (Date) +## +## Returns the minute from a serial date number or a date string. +## +## @seealso{date, datevec, now, hour, second} +## @end deftypefn + +function t = minute (dates) + + t = datevec (dates); + t = t (:,6); + +endfunction + Copied: trunk/octave-forge/main/financial/inst/month.m (from rev 10260, trunk/octave-forge/main/time/inst/month.m) =================================================================== --- trunk/octave-forge/main/financial/inst/month.m (rev 0) +++ trunk/octave-forge/main/financial/inst/month.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,31 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {mon =} month (Date) +## +## Returns the day of the month from a serial date number or a date +## string. +## +## @seealso{date, datevec, now, day, year} +## @end deftypefn + +function t = month (dates) + + t = datevec (dates); + t = t (:,2); + +endfunction + Copied: trunk/octave-forge/main/financial/inst/months.m (from rev 10260, trunk/octave-forge/main/time/inst/months.m) =================================================================== --- trunk/octave-forge/main/financial/inst/months.m (rev 0) +++ trunk/octave-forge/main/financial/inst/months.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,60 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {mos =} months (startdate, enddate) +## @deftypefnx {Function File} {mos =} months (startdate, enddate, endmonthflag) +## +## Return the number of whole months between @var{startdate} and +## @var{enddate}. @var{endmonthflag} defaults to 1. +## +## If @var{endmonthflag} is true, then if both the @var{startdate} and +## the @var{enddate} are end of month dates and @var{enddate} has fewer +## days in the month than @var{startdate}, @var{endmonthflag} = 1 treats +## @var{enddate} as the end of a month, but @var{endmonthflag} = 0 does +## not. +## +## @seealso{yeardays, yearfrac} +## @end deftypefn + +function mos = months (startdate, enddate, endmonthflag) + + if nargin == 2 + endmonthflag = 1; + elseif nargin != 3 + print_usage (); + endif + + s = datevec (startdate); + e = datevec (enddate); + s_eom = (s(:,3) == eomday(s(:,1), s(:,2))); + e_eom = (e(:,3) == eomday(e(:,1), e(:,2))); + + ## Handle the end of the month correctly + dayadj = ((s(:,3) > e(:,3)) & endmonthflag & s_eom & e_eom); + + mos = 12*(e(:,1) - s(:,1)) + (e(:,2) - s(:,2)) - (s(:,3) > e(:,3)) + dayadj; + +endfunction + +## Tests +%!assert(months('may 31 2004', 'jun 30 2004'), 1) +%!assert(months({'may 31 2004' 'may 30 2004'}, 'jun 30 2004'), [1;1]) +%!assert(months('may 31 2004', 'jun 30 2004', 1), 1) +%!assert(months({'may 31 2004' 'may 30 2004'}, 'jun 30 2004', 1), [1;1]) +%!assert(months('may 31 2004', 'jun 30 2004', 0), 0) +%!assert(months({'may 31 2004' 'may 30 2004'}, 'jun 30 2004', 0), [0;1]) +%!assert(months('jun 30 2005', 'june 30 2006'), 12) +%!assert(months('jun 30 2005', 'june 29 2006'), 11) Copied: trunk/octave-forge/main/financial/inst/nweekdate.m (from rev 10260, trunk/octave-forge/main/time/inst/nweekdate.m) =================================================================== --- trunk/octave-forge/main/financial/inst/nweekdate.m (rev 0) +++ trunk/octave-forge/main/financial/inst/nweekdate.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,152 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {last =} nweekdate (n, weekday, year, month, nextday) +## +## Returns the @var{n}th occurrence of @var{weekday} from the +## @var{month} and @var{year}. If the optional @var{nextday} argument +## is given, then the week must also contain @var{nextday}. If @var{n} +## is greater than the number of occurrences of that day in the month, 0 +## is returned. +## +## @seealso{eomdate, lweekdate, weekday} +## @end deftypefn + +function t = nweekdate (varargin) + if nargin < 4 || nargin > 5 + error ("4 or 5 input arguments are required") + elseif nargin == 4 + varargin{5} = 0; + endif + + ## special handling so that most of this code will not need to be + ## duplicated in lweekdate + do_lweekdate = is_lweekdate(varargin{1}); + if do_lweekdate + varargin{1} = 1; + endif + + scale = cellfun (@numel, varargin); + if ~ all (scale == 1 | scale == max(scale)); + error("All inputs must be either scalars or have the same number of elements"); + else + ## make sure that the sizes are the same for any non-scalar inputs + ind = find (scale > 1); + if length(ind) > 1 + for i = 2:length (ind) + if ndims (varargin{ind(1)}) ~= ndims (varargin{ind(i)}) + error("Mismatching dimensions on inputs %d and %d", ind(1), ind(i)); + elseif ~ all (size (varargin{ind(1)}) == size (varargin{ind(i)})) + error("The sizes of inputs %d and %d do not match", ind(1), ind(i)); + endif + endfor + endif + endif + + if max(scale) > 1 + t = zeros (size (varargin{ind(1)})); + for i = 1:numel (varargin{ind(1)}) + args = cell(5,1); + for j = 1:5 + if isscalar (varargin{j}) + args{j} = varargin{j}; + else + args{j} = varargin{j}(i); + endif + endfor + if do_lweekdate + args{1} = "lweekdate"; + end + t(i) = nweekdate (args{:}); + endfor + else + ## Do the real work. + n = varargin{1}; + wd = varargin{2}; + y = varargin{3}; + mon = varargin{4}; + nextday = varargin{5}; + + ## Find the day of the week for the last day of the mon. + doml = eomday (y, mon); + dowl = weekday (datenum (y, mon, doml)); + ## Make sure that the day is in the weeks for the last then the + ## first week. + if (wd < nextday) || (dowl < wd) + ## adjust the last day + adjust = 7; + else + adjust = 0; + endif + dom = sort((doml - dowl + wd - adjust):-7:1); + if nextday && (dom(1) <= wd - nextday) + # adjust the first day + dom(1) = []; + endif + if do_lweekdate + t = datenum (y, mon, dom(end)); + elseif n > length(dom) + t = 0; + else + t = datenum (y, mon, dom(n)); + end + endif + +endfunction + +function v = is_lweekdate(v) + if ischar(v) + if strcmp (v, "lweekdate") + v = true(); + else + error("Invalid input for n") + endif + else + v = false(); + endif +endfunction + +# Tests for all calling options +# Find the first Wednesday in Jan 2008 +%!assert(nweekdate(1, 4, 2008, 1), datenum(2008, 1, 2)) +# Find the second Wednesday in Jan 2008 +%!assert(nweekdate(2, 4, 2008, 1), datenum(2008, 1, 9)) +# Find the third Wednesday in Jan 2008 +%!assert(nweekdate(3, 4, 2008, 1), datenum(2008, 1, 16)) +# Find the fourth Wednesday in Jan 2008 +%!assert(nweekdate(4, 4, 2008, 1), datenum(2008, 1, 23)) +# Find the fifth Wednesday in Jan 2008 +%!assert(nweekdate(5, 4, 2008, 1), datenum(2008, 1, 30)) +# Find the sixth Wednesday in Jan 2008, it doesn't exist, so return 0 +%!assert(nweekdate(6, 4, 2008, 1), 0) +# Find the fifth Friday in Jan 2008, it doesn't exist, so return 0 +%!assert(nweekdate(5, 6, 2008, 1), 0) +# Find the first Wednesday in Jan 2008 in the same week as a Monday +# WARNING: it is unclear from the Matlab docs if this should work or if +# this should be called the second Wednesday in Jan 2008. +%!assert(nweekdate(1, 4, 2008, 1, 2), datenum(2008, 1, 9)) +# Find the fifth Wednesday in Jan 2008 in the same week as a Friday. +# It doesn't exist, so return 0 +%!assert(nweekdate(5, 4, 2008, 1, 6), 0) +# Try vector arguments +%!assert(nweekdate(1:6, 4, 2008, 1, 6), [datenum(2008, 1, 2:7:23), 0, 0]) + +# Try the lweekdate operation of this function: +# Find the last Wednesday in Jan 2008 +%!assert(nweekdate('lweekdate', 4, 2008, 1), datenum(2008, 1, 30)) +# Find the last Wednesday in Jan 2008 with a Friday +%!assert(nweekdate('lweekdate', 4, 2008, 1, 6), datenum(2008, 1, 23)) + Copied: trunk/octave-forge/main/financial/inst/second.m (from rev 10260, trunk/octave-forge/main/time/inst/second.m) =================================================================== --- trunk/octave-forge/main/financial/inst/second.m (rev 0) +++ trunk/octave-forge/main/financial/inst/second.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,30 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {s =} second (Date) +## +## Returns the second from a serial date number or a date string. +## +## @seealso{date, datevec, now, hour, minute} +## @end deftypefn + +function t = second (dates) + + t = datevec (dates); + t = t (:,6); + +endfunction + Copied: trunk/octave-forge/main/financial/inst/thirdwednesday.m (from rev 10260, trunk/octave-forge/main/time/inst/thirdwednesday.m) =================================================================== --- trunk/octave-forge/main/financial/inst/thirdwednesday.m (rev 0) +++ trunk/octave-forge/main/financial/inst/thirdwednesday.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,68 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {[begindate, enddate]} = thirdwednesday (month, year) +## +## Find the third Wednesday of the month specified by the @var{month} +## and @var{year}. The @var{begindate} is the third Wednesday of the +## month, and the @var{enddate} is three months after that. Outputs are +## in the form of datenums. +## +## The third Wednesday is used for Eurodollar futures. +## +## @seealso{nweekdate, datenum} +## @end deftypefn + +function [wednesdays, enddate] = thirdwednesday (month, year) + + if nargin ~= 2 + print_usage (); + elseif ~ ((numel(year) == 1) || + (numel(month) == 1) || + ~isequal (size (month), size (year))) + error("month and year must have the same size or one of them must be a scalar") + endif + + if numel (year) == 1 + sz = size (month); + else + sz = size (year); + endif + + wednesdays = nweekdate (3, 4, year, month); + dates = datevec (wednesdays); + ## adjust the year when the date will wrap + dates(:,1) += dates (:,2) > 9; + ## adjust the month by three + dates(:,2) = mod (dates(:,2) + 2, 12) + 1; + enddate = reshape (datenum (dates), sz); + +endfunction + +## Tests +%!shared m, y, bt, et +%! m = (1:12)'; +%! y = 2008; +%! bt = datenum(2008, m, [16;20;19;16;21;18;16;20;17;15;19;17]); +%! et = datenum([2008*ones(9,1);2009*ones(3,1)], [4:12 1:3]', [16;20;19;16;21;18;16;20;17;15;19;17]); +%!test +%! [b e] = thirdwednesday (m, y); +%! assert(b, bt) +%! assert(e, et) +%!test +%! [b e] = thirdwednesday (m', y); +%! assert(b, bt') +%! assert(e, et') Copied: trunk/octave-forge/main/financial/inst/today.m (from rev 10260, trunk/octave-forge/main/time/inst/today.m) =================================================================== --- trunk/octave-forge/main/financial/inst/today.m (rev 0) +++ trunk/octave-forge/main/financial/inst/today.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,32 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {datenum =} today () +## Returns the current local date as the number of days since Jan 1, 0000. +## By this reckoning, Jan 1, 1970 is day number 719529. +## +## The returned number corresponds to 00:00:00 today. +## +## The returned value is also called a "serial date number" +## (see @code{datenum}). +## @seealso{clock, date, datenum, now} +## @end deftypefn + +function t = today () + + t = floor (now ()); + +endfunction Copied: trunk/octave-forge/main/financial/inst/x2mdate.m (from rev 10260, trunk/octave-forge/main/time/inst/x2mdate.m) =================================================================== --- trunk/octave-forge/main/financial/inst/x2mdate.m (rev 0) +++ trunk/octave-forge/main/financial/inst/x2mdate.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,75 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {datenums =} x2mdate (exceldatenums) +## @deftypefnx {Function File} {datenums =} x2mdate (exceldatenums, convention) +## @deftypefnx {Function File} {datenums =} x2mdate (exceldatenums, convention, "ExcelBug") +## +## Convert @var{datenums} from the Microsoft Excel date format to the +## format used by @code{datenum}. If set to 0 (default, Excel for +## Windows), @var{convention} specifies to use the Excel 1900 convention +## where Jan 1, 1900 corresponds to Excel serial date number 1. If set +## to 1 (Excel for Mac), @var{convention} specifies to use the Excel +## 1904 convention where Jan 1, 1904 corresponds to Excel serial date +## number 0. +## +## Note that this does not take into account the Excel bug where 1900 is +## considered to be a leap year unless you give the "ExcelBug" option. +## +## Excel does not represent dates prior to 1 January 1900 using this +## format, so a warning will be issued if any dates preceed this date. +## +## @seealso{datenum, x2mdate} +## @end deftypefn + +function dates = x2mdate (dates, convention, excelbug) + + if nargin == 1 + convention = 0; + excelbug = false(); + elseif nargin == 2 + excelbug = false(); + elseif nargin == 3 + excelbug = strcmpi(excelbug, "ExcelBug"); + else + print_usage (); + endif + + if any (dates < 0) + warning ("Negative date found, this will not work within MS Excel.") + endif + + if convention == 0 + adj = datenum(1900, 1, 1) - 2; + elseif convention == 1 + adj = datenum(1904, 1, 1); + endif + + if excelbug + datemask = (dates < 61); + dates(datemask) = dates(datemask) + 1; + endif + dates = dates + adj; + +endfunction + +## Tests +%!assert(x2mdate(39448), datenum(2008, 1, 1)) +%!assert(x2mdate([39083 39448]), datenum(2007:2008, 1, 1)) +%!assert(x2mdate(2), datenum(1900, 1, 1)) +%!assert(x2mdate(1, 0, "ExcelBug"), datenum(1900, 1, 1)) +%!assert(x2mdate(0, 1), datenum(1904, 1, 1)) + Copied: trunk/octave-forge/main/financial/inst/year.m (from rev 10260, trunk/octave-forge/main/time/inst/year.m) =================================================================== --- trunk/octave-forge/main/financial/inst/year.m (rev 0) +++ trunk/octave-forge/main/financial/inst/year.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,30 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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} {y =} year (Date) +## +## Returns the year from a serial date number or a date string. +## +## @seealso{date, datevec, now, day, month} +## @end deftypefn + +function t = year (dates) + + t = datevec (dates); + t = t (:,1); + +endfunction + Copied: trunk/octave-forge/main/financial/inst/yeardays.m (from rev 10260, trunk/octave-forge/main/time/inst/yeardays.m) =================================================================== --- trunk/octave-forge/main/financial/inst/yeardays.m (rev 0) +++ trunk/octave-forge/main/financial/inst/yeardays.m 2012-04-17 12:03:41 UTC (rev 10262) @@ -0,0 +1,111 @@ +## Copyright (C) 2008 Bill Denney <bi...@de...> +## +## 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) an... [truncated message content] |