Commit 416a4884 authored by Jukka Pekka's avatar Jukka Pekka Committed by jpekka
Browse files

Implemented.

2002-07-07  Jukka Pekka  <jiivonen@hutcs.cs.hut.fi>

	* functions (gnumeric_cumprinc): Implemented.

	* sc-fin.c (GetRmz,GetZw,get_cumprinc): Added.
parent 3591445a
2002-07-07 Jukka Pekka <jiivonen@hutcs.cs.hut.fi>
* functions (gnumeric_cumprinc): Implemented.
* sc-fin.c (GetRmz,GetZw,get_cumprinc): Added.
2002-07-07 Jukka Pekka <jiivonen@hutcs.cs.hut.fi>
* functions.c (gnumeric_duration): Renamed DURATION() as
......
......@@ -2149,6 +2149,7 @@ gnumeric_duration (FunctionEvalInfo *ei, Value **argv)
GDate *nSettle, *nMat;
gnum_float fCoup, fYield;
gint nFreq, nBase;
gnum_float fNumOfCoups;
Value *result;
nSettle = datetime_value_to_g (argv[0]);
......@@ -2164,7 +2165,9 @@ gnumeric_duration (FunctionEvalInfo *ei, Value **argv)
goto out;
}
result = get_duration (nSettle, nMat, fCoup, fYield, nFreq, nBase);
fNumOfCoups = coupnum (nSettle, nMat, nFreq, nBase, FALSE);
result = get_duration (nSettle, nMat, fCoup, fYield, nFreq, nBase,
fNumOfCoups);
out:
datetime_g_free (nSettle);
......@@ -3322,7 +3325,29 @@ static const char *help_cumprinc = {
static Value *
gnumeric_cumprinc (FunctionEvalInfo *ei, Value **argv)
{
return value_new_error (ei->pos, "#UNIMPLEMENTED!");
gnum_float fRate, fVal;
gint nNumPeriods, nStartPer, nEndPer, nPayType;
Value *result;
fRate = value_get_as_float (argv[0]);
nNumPeriods = value_get_as_int (argv[1]);
fVal = value_get_as_float (argv[2]);
nStartPer = value_get_as_int (argv[3]);
nEndPer = value_get_as_int (argv[4]);
nPayType = value_get_as_int (argv[5]);
if ( nStartPer < 1 || nEndPer < nStartPer || fRate <= 0
|| nEndPer > nNumPeriods || nNumPeriods <= 0
|| fVal <= 0 || (nPayType != 0 && nPayType != 1) ) {
result = value_new_error (ei->pos, gnumeric_err_NUM);
goto out;
}
result = get_cumprinc (fRate, nNumPeriods, fVal, nStartPer, nEndPer,
nPayType);
out:
return result;
}
/***************************************************************************/
......
......@@ -161,6 +161,49 @@ GetYearFrac (GDate *nStartDate, GDate *nEndDate, gint nMode)
return nYears + (gnum_float) nDayDiff / nDaysInYear;
}
static gnum_float
GetRmz ( gnum_float fZins, gnum_float fZzr, gnum_float fBw, gnum_float fZw,
gint nF )
{
gnum_float fRmz;
if ( fZins == 0.0 )
fRmz = ( fBw + fZw ) / fZzr;
else {
gnum_float fTerm = pow ( 1.0 + fZins, fZzr );
if ( nF > 0 )
fRmz = ( fZw * fZins / ( fTerm - 1.0 ) + fBw * fZins /
( 1.0 - 1.0 / fTerm ) ) / ( 1.0 + fZins );
else
fRmz = fZw * fZins / ( fTerm - 1.0 ) + fBw * fZins /
( 1.0 - 1.0 / fTerm );
}
return -fRmz;
}
static gnum_float
GetZw ( gnum_float fZins, gnum_float fZzr, gnum_float fRmz, gnum_float fBw,
gint nF )
{
gnum_float fZw;
if ( fZins == 0.0 )
fZw = fBw + fRmz * fZzr;
else {
gnum_float fTerm = pow ( 1.0 + fZins, fZzr );
if ( nF > 0 )
fZw = fBw * fTerm + fRmz * ( 1.0 + fZins ) *
( fTerm - 1.0 ) / fZins;
else
fZw = fBw * fTerm + fRmz * ( fTerm - 1.0 ) / fZins;
}
return -fZw;
}
/***************************************************************************/
Value *
get_amordegrc (gnum_float fCost, GDate *nDate, GDate *nFirstPer,
gnum_float fRestVal, gint nPer, gnum_float fRate,
......@@ -209,6 +252,7 @@ get_amordegrc (gnum_float fCost, GDate *nDate, GDate *nFirstPer,
#undef Round
}
/***************************************************************************/
Value *
get_amorlinc (gnum_float fCost, GDate *nDate, GDate *nFirstPer,
......@@ -233,6 +277,7 @@ get_amorlinc (gnum_float fCost, GDate *nDate, GDate *nFirstPer,
return value_new_float ( result );
}
/***************************************************************************/
Value * get_yielddisc (GDate *nSettle, GDate *nMat, gnum_float fPrice,
gnum_float fRedemp, gint nBase)
......@@ -246,6 +291,7 @@ Value * get_yielddisc (GDate *nSettle, GDate *nMat, gnum_float fPrice,
return value_new_float ( fRet );
}
/***************************************************************************/
Value * get_yieldmat (GDate *nSettle, GDate *nMat, GDate *nIssue,
gnum_float fRate, gnum_float fPrice, gint nBase)
......@@ -262,6 +308,7 @@ Value * get_yieldmat (GDate *nSettle, GDate *nMat, GDate *nIssue,
return value_new_float ( y );
}
/***************************************************************************/
Value * get_oddlprice (GDate *nSettle, GDate *nMat, GDate *nLastCoup,
gnum_float fRate, gnum_float fYield,
......@@ -278,6 +325,7 @@ Value * get_oddlprice (GDate *nSettle, GDate *nMat, GDate *nLastCoup,
return value_new_float ( p );
}
/***************************************************************************/
Value * get_oddlyield (GDate *nSettle, GDate *nMat, GDate *nLastCoup,
gnum_float fRate, gnum_float fPrice,
......@@ -296,12 +344,13 @@ Value * get_oddlyield (GDate *nSettle, GDate *nMat, GDate *nLastCoup,
return value_new_float ( y );
}
/***************************************************************************/
Value * get_duration (GDate *nSettle, GDate *nMat, gnum_float fCoup,
gnum_float fYield, gint nFreq, gint nBase)
gnum_float fYield, gint nFreq, gint nBase,
gnum_float fNumOfCoups)
{
gnum_float fYearfrac = GetYearFrac ( nSettle, nMat, nBase );
gnum_float fNumOfCoups = coupnum (nSettle, nMat, nFreq, nBase, FALSE);
gnum_float fDur = 0.0;
gnum_float t, p = 0.0;
......@@ -316,7 +365,7 @@ Value * get_duration (GDate *nSettle, GDate *nMat, gnum_float fCoup,
fDur += fNumOfCoups * ( fCoup + f100 ) / pow ( fYield, fNumOfCoups );
for( t = 1.0 ; t < fNumOfCoups ; t++ )
for ( t = 1.0 ; t < fNumOfCoups ; t++ )
p += fCoup / pow ( fYield, t );
p += ( fCoup + f100 ) / pow ( fYield, fNumOfCoups );
......@@ -326,3 +375,38 @@ Value * get_duration (GDate *nSettle, GDate *nMat, gnum_float fCoup,
return value_new_float ( fDur );
}
/***************************************************************************/
Value * get_cumprinc (gnum_float fRate, gint nNumPeriods, gnum_float fVal,
gint nStart, gint nEnd, gint nPayType)
{
gnum_float fRmz, fKapZ;
gint i;
fRmz = GetRmz ( fRate, nNumPeriods, fVal, 0.0, nPayType );
fKapZ = 0.0;
if ( nStart == 1 ) {
if ( nPayType <= 0 )
fKapZ = fRmz + fVal * fRate;
else
fKapZ = fRmz;
nStart++;
}
for ( i = nStart ; i <= nEnd ; i++ ) {
if ( nPayType > 0 )
fKapZ += fRmz - ( GetZw ( fRate, ( i - 2 ), fRmz,
fVal, 1 ) - fRmz ) * fRate;
else
fKapZ += fRmz - GetZw( fRate, ( i - 1 ), fRmz, fVal,
0 ) * fRate;
}
return value_new_float ( fKapZ );
}
/***************************************************************************/
......@@ -2,11 +2,6 @@
#ifndef __SC_FIN_H__
#define __SC_FIN_H__
extern gnum_float
coupnum (GDate *settlement, GDate *maturity, int freq, basis_t basis,
gboolean eom);
Value * get_amordegrc (gnum_float fCost, GDate *nDate, GDate *nFirstPer,
gnum_float fRestVal, gint nPer, gnum_float fRate,
gint nBase);
......@@ -24,7 +19,10 @@ Value * get_oddlyield (GDate *nSettle, GDate *nMat, GDate *nLastCoup,
gnum_float fRate, gnum_float fYield,
gnum_float fRedemp, gint nFreq, gint nBase);
Value * get_duration (GDate *nSettle, GDate *nMat, gnum_float fCoup,
gnum_float fYield, gint nFreq, gint nBase);
gnum_float fYield, gint nFreq, gint nBase,
gnum_float fNumOfCoups);
Value * get_cumprinc (gnum_float fRate, gint nNumPeriods, gnum_float fVal,
gint nStartPer, gint nEndPer, gint nPayType);
#endif
......
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