campo-sirio/gfm/bondyld.c
alex ba237a9d91 Patch level : no patch
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
Aggiunti i sorgenti per Greenleaf Math Library (gfm.dll)


git-svn-id: svn://10.65.10.50/trunk@10079 c028cbd2-c16b-5b4b-a496-9718f37d4682
2002-02-26 12:19:02 +00:00

123 lines
3.2 KiB
C
Executable File

/* DEC *BondYield(yield, price, coupon, ppy, mop, dap, yrp, mom, dam, yrm)
*
* ARGUMENT
* DEC *price;
* DEC *yield;
* DEC *coupon;
* int ppy;
* int mop, dap, yrp;
* int mom, dam, yrm;
*
* DESCRIPTION
* Calculate the yield of a bond given the price, coupon rate
* for receiving interest on a bond, number of payments per year, and the
* puchase and maturity dates.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* yield if successful, otherwise GM_NULL
*
* POSSIBLE ERRORS
* GM_NULLPOINTER
* GM_INIT
* GM_ARGVAL
*
* AUTHOR
* Jared Levy
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
* Mark Nelson
* Added one line to convert nominal interest rate to effective.
*
*/
#include <stdio.h>
#include "gmsystem.h"
DEC *BondYield(yield, price, coupon, ppy, mop, dap, yrp, mom, dam, yrm)
DEC *price, *yield, *coupon;
int ppy, mop, dap, yrp, mom, dam, yrm;
{
DEC dtemp, *temp=&dtemp, dtemp2, *temp2=&dtemp2;
DEC dnper, *nper=&dnper, dpmt, *pmt=&dpmt;
DEC dpv, *pv=&dpv, dfv, *fv=&dfv, *p;
DEC ddsc, *dsc=&ddsc, ddcs, *dcs=&ddcs;
int ndays, npay;
_MacStart(GM_BONDYLD);
_MacInVarD(coupon);
_MacInVarD(price);
_MacOutVarD(yield);
if (ppy<1||ppy>12) {
_MacErr(GM_ARGVAL);
_MacRet(GM_NULL);
}
/* calculate # of periods, including partial period */
ndays = DaysBetweenDates360(mom, dam, yrm, mop, dap, yrp);
if (ndays < 0) {
if (ndays!=GM_ARGVAL&&ndays!=GM_OVERFLOW)
_MacErr(GM_ARGVAL);
_MacRet(GM_NULL);
}
/* calculate number of interest payments remaining */
(void) ConvLongToDecimal(temp, (long)ppy * (long) ndays);
(void) ConvLongToDecimal(temp2, 360L);
(void) _DivDec80Bit(nper, temp, temp2);
(void) _TruncateDec80Bit(temp, nper, 0);
npay=temp->dc.sl[0];
(void) _SubDec80Bit(dsc, nper, temp); /* days purchase - next int */
(void) _SubDec80Bit(dcs, &decOne, dsc); /* days last int - purchass */
/* calculate coupon rate per period */
(void) ConvLongToDecimal(temp2, (long)ppy);
(void) _DivDec80Bit(pmt, coupon, temp2);
(void) _AddDec80Bit(fv, &decHundred, pmt);
(void) _MulDec80Bit(temp, pmt, dcs);
(void) _AddDec80Bit(pv, price, temp);
if (CompareDecimal(nper, &decOne)<=0) { /* < 1 period to maturity */
_DivDec80Bit(temp, fv, pv);
_SubDec80Bit(temp, temp, &decOne);
_DivDec80Bit(yield, temp, dsc);
_MulDec80Bit(yield, yield, &decHundred);
_ScaleDec80Bit(yield, yield, wIntrPrec);
}
else { /* > 1 period to maturity */
_MacDChgs(pv);
p = _InterestAux(3, npay, dsc, yield, pv, pmt, fv, GM_BEGIN);
if (!p)
_MacRet(GM_NULL);
}
/*
* At this point, yield contains the nominal interest rate for the bond.
* This needs to be converted to the effective interest rate. Rather than
* call the NominalToEffective routine, I import most of the code.
*/
yield->dc.id += 2;
_AddDec80Bit( yield, yield, &decOne );
if (_IntPwrDec80Bit( yield, yield, ppy ) != GM_SUCCESS ) {
_MacErr( GM_ARGVAL );
_MacRet( GM_NULL );
}
_SubDec80Bit( yield, yield, &decOne );
if (yield->dc.id >= GM_MINID+2)
yield->dc.id -= 2;
else
(void) _MulUnsArrByPwrOf10(yield->dc.sl, 5, 2);
if (_Sq5UnsTo4Uns(yield)!=GM_SUCCESS) {
_MacErr(GM_ARGVAL);
_MacRet(GM_NULL);
}
_MacRet(yield);
}