Commit 9ee37218 authored by Morten Welinder's avatar Morten Welinder Committed by Morten Welinder

Use yearfrac.

2003-07-01  Morten Welinder  <terra@gnome.org>

	* functions.c (gnumeric_yearfrac): Use yearfrac.

2003-07-01  Morten Welinder  <terra@gnome.org>

	* functions.c (gnumeric_yielddisc): Dump OO's and use yearfrac.

2003-07-01  Morten Welinder  <terra@gnome.org>

	* src/datetime.c (yearfrac): New function.
parent fef19b17
2003-07-01 Morten Welinder <terra@gnome.org>
* src/datetime.c (yearfrac): New function.
2003-07-01 Jody Goldberg <jody@gnome.org>
* src/Makefile.am : Be even more delicate about changeing built
......
......@@ -70,6 +70,7 @@ Morten:
* Implement ODDFYIELD.
* Reduce flicker in format selector widgets.
* Fix another O(n^2) problem in stf import.
* Fix YEARFRAC.
--------------------------------------------------------------------------
......
2003-07-01 Morten Welinder <terra@gnome.org>
* src/datetime.c (yearfrac): New function.
2003-07-01 Jody Goldberg <jody@gnome.org>
* src/Makefile.am : Be even more delicate about changeing built
......
2003-07-01 Morten Welinder <terra@gnome.org>
* src/datetime.c (yearfrac): New function.
2003-07-01 Jody Goldberg <jody@gnome.org>
* src/Makefile.am : Be even more delicate about changeing built
......
2003-07-01 Morten Welinder <terra@gnome.org>
* functions.c (gnumeric_yearfrac): Use yearfrac.
2003-06-30 Jody Goldberg <jody@gnome.org>
* functions.c (gnumeric_datevalue) : add mention of 1900 vs 1904
......
......@@ -1251,9 +1251,7 @@ gnumeric_yearfrac (FunctionEvalInfo *ei, Value **argv)
!g_date_valid (&start_date) || !g_date_valid (&end_date))
return value_new_error_NUM (ei->pos);
return value_new_float (
(double) days_between_basis (&start_date, &end_date, basis) /
(double) annual_year_basis (argv[0], basis, conv));
return value_new_float (yearfrac (&start_date, &end_date, basis));
}
/***************************************************************************/
......
......@@ -2,6 +2,7 @@
* functions.c (gnumeric_oddlprice, gnumeric_oddlyield): Dump OO's
implementation and roll our own. (Our date stuff is better.)
(gnumeric_yielddisc): Dump OO's and use yearfrac.
2003-06-29 Morten Welinder <terra@gnome.org>
......
......@@ -2596,9 +2596,10 @@ static char const *help_yielddisc = {
static Value *
gnumeric_yielddisc (FunctionEvalInfo *ei, Value **argv)
{
GDate nSettle, nMat;
GDate settlement, maturity;
gnm_float fPrice, fRedemp;
gint nBase;
gnm_float ret, yfrac;
GnmDateConventions const *date_conv =
workbook_date_conv (ei->pos->sheet->workbook);
......@@ -2606,12 +2607,20 @@ gnumeric_yielddisc (FunctionEvalInfo *ei, Value **argv)
fRedemp = value_get_as_float (argv[3]);
nBase = argv[4] ? value_get_as_int (argv[4]) : 0;
if (nBase < 0 || nBase > 4 ||
!datetime_value_to_g (&nSettle, argv[0], date_conv) ||
!datetime_value_to_g (&nMat, argv[1], date_conv))
if (!is_valid_basis (nBase) ||
!datetime_value_to_g (&settlement, argv[0], date_conv) ||
!datetime_value_to_g (&maturity, argv[1], date_conv))
return value_new_error_NUM (ei->pos);
if (fRedemp <= 0 ||
fPrice <= 0 ||
g_date_compare (&settlement, &maturity) >= 0)
return value_new_error_NUM (ei->pos);
return get_yielddisc (&nSettle, &nMat, fPrice, fRedemp, nBase);
ret = (fRedemp / fPrice) - 1;
yfrac = yearfrac (&settlement, &maturity, nBase);
return value_new_float (ret / yfrac);
}
/***************************************************************************/
......
......@@ -309,18 +309,6 @@ get_amorlinc (gnm_float fCost, GDate *nDate, GDate *nFirstPer,
/***************************************************************************/
Value * get_yielddisc (GDate *nSettle, GDate *nMat, gnm_float fPrice,
gnm_float fRedemp, gint nBase)
{
gnm_float fRet = (fRedemp / fPrice) - 1;
fRet /= GetYearFrac ( nSettle, nMat, nBase );
return value_new_float ( fRet );
}
/***************************************************************************/
Value * get_yieldmat (GDate *nSettle, GDate *nMat, GDate *nIssue,
gnm_float fRate, gnm_float fPrice, gint nBase)
{
......
......@@ -8,8 +8,6 @@ Value * get_amordegrc (gnm_float fCost, GDate *nDate, GDate *nFirstPer,
Value * get_amorlinc (gnm_float fCost, GDate *nDate, GDate *nFirstPer,
gnm_float fRestVal, gint nPer, gnm_float fRate,
gint nBase);
Value * get_yielddisc (GDate *nSettle, GDate *nMat, gnm_float fPrice,
gnm_float fRedemp, gint nBase);
Value * get_yieldmat (GDate *nSettle, GDate *nMat, GDate *nIssue,
gnm_float fRate, gnm_float fPrice, gint nBase);
Value * get_duration (GDate *nSettle, GDate *nMat, gnm_float fCoup,
......
......@@ -603,3 +603,41 @@ annual_year_basis (Value const *value_date, basis_t basis,
}
}
gnm_float
yearfrac (GDate const *from, GDate const *to, basis_t basis)
{
int days = days_between_basis (from, to, basis);
gnm_float peryear;
switch (basis) {
case BASIS_ACT_ACT: {
int y1 = g_date_get_year (from) + (g_date_get_month (from) <= 2 ? 0 : 1);
int y2 = g_date_get_year (to) + (g_date_get_month (to) <= 2 ? 0 : 1);
if (y1 == y2)
peryear = g_date_is_leap_year (y1) ? 366 : 365;
else {
GDate d1, d2;
int leaps;
g_date_clear (&d1, 1);
g_date_set_dmy (&d1, 1, 1, y1);
g_date_clear (&d2, 1);
g_date_set_dmy (&d2, 1, 1, y2);
leaps = g_date_get_julian (&d2) - g_date_get_julian (&d1) -
365 * (y2 - y1);
peryear = 365 + (gnm_float)leaps / (y2 - y1);
}
break;
}
default:
peryear = annual_year_basis (NULL, basis, NULL);
}
return days / peryear;
}
......@@ -73,6 +73,7 @@ typedef enum { /* see doc/fn-financial-basis.txt for details */
} basis_t;
gint32 days_between_basis (GDate const *from, GDate const *to, basis_t basis);
gnm_float yearfrac (const GDate *from, GDate const *to, basis_t basis);
int annual_year_basis (Value const *value_date, basis_t basis,
GnmDateConventions const *date_conv);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment