채권 가격 계산 라이브러 개발을 위해 일반 채권 중 가장 기본이 되는 할인채와 이표채에 대한 설명을 한데 이어 단리채와 복리채에 대한 설명을 하고자 한다.

단리채는 매년 채권의 표면 이자율로 계산한 이자를 누적하여 만기에 일시 상환하는 채권이다. 즉 매년 이자 얼마 ( 원금 X 표면이자율 )를 계산해서 만기에는 “원금 + 그동안의 누적이자” 로 지급한다.
복리채는 채권의 이자를 복리로 계산해서 만기일에 일시 상환하는 채권이다. 즉, 채권의 원금을 지급하는 만기에 이자까지 한꺼번에 지급하는데 이 때 첫 해부터 지급되는 이자가 복리로 계속 쌓인다는 조건이다. ( 복리라 함은 이자에도 이자가 붙는 개념 )

복리채의 로직은 크게 어려울 것이 없다. 단리채와 동일한데 이자를 누적해서 그 누적된 이자에도 이자 계산을 해서 다시 누적해 주어야 한다.

/*-----------------------------------------------------------------------------
 * fnSBCompoundBond : 복리채에 대한 가격 계산 함수
 *		Spot/YTM 모두 사용가능
 *		YTM의 갯수를 1개만 지정하는 경우 해당 YTM을 사용할 수 있으며,
 *		YTM의 갯수가 여러개인 경우 보간 하여 해당 YTM 사용
 *
 * total_coupon : total_year + days from issue to first coupon day
 *
 *---------------------------------------------------------------------------*/

UINT fnSBCompoundBond( DATETYPE dtPriceDay,     /* 계산일                           */
                       BONDINFO *pBondInfo,   /* Bond Info Structure              */
                       CURVE  *pCurve,        /* ytm/sport curve                  */
                       BONDPRICE *pBondPrice, /* Price Info Structure             */
                       INT    *error_code)
{
	DATETYPE	nextCouponDate;
	DATETYPE	prevCouponDate;
	UINT 		nTotalCoupon;
	UINT 		nResidueYear;
	UINT		nDaysToMaturity;
	DOUBLE		nBondPrice;
	DOUBLE		nDuration;
	DOUBLE		nMD;
	DOUBLE		nConvexity;
	DOUBLE		nFace;
	DOUBLE		nDiscountToday;
	DOUBLE		nIntRatio;
	UINT		nNextCouponRemDay;
	UINT		nCouponTermDay;

	nDuration  = 0.0;
	nMD        = 0.0;
	nConvexity = 0.0;

	nFace = 10000.0;
	nIntRatio  = pBondInfo->nIntMonth / 12.0;

	/*------------------------------------------------------
	 * cashflow = face * 만기상환율 + coupon / 횟수 * ( rem / term + N - 1 )
	 *-----------------------------------------------------*/

	nResidueYear = 0;

	prevCouponDate = pBondInfo->dtDueDay;
        while ( fnDatetoInt( prevCouponDate ) >= fnDatetoInt( dtPriceDay ) ) {
		nextCouponDate = prevCouponDate;
		prevCouponDate = fnAddDateInt( prevCouponDate, YEAR, -1 );
		nResidueYear++;
	}

	if ( nResidueYear > 0 ) nResidueYear--;
	nNextCouponRemDay = fnCountDate( dtPriceDay, nextCouponDate, DAY );
	nCouponTermDay    = fnCountDate( prevCouponDate, nextCouponDate, DAY ) ;
	nDiscountToday = (DOUBLE) nNextCouponRemDay / (DOUBLE) nCouponTermDay;

	nTotalCoupon = fnCountDate( pBondInfo->dtIssueDay, pBondInfo->dtDueDay, MONTH) / pBondInfo->nIntMonth;

	nBondPrice = 0.0;

	nDaysToMaturity = fnCountDate( dtPriceDay, pBondInfo->dtDueDay, DAY );

        /* 해당 수익률이 하나만 입력되는 경우 하나의 YTM을 이용 */
	if ( pCurve->nYieldCount == 1 )
	{
		pBondPrice->nYtm = pCurve->nYield[ 0 ];
	}
	else
	{
		/* 여러개의 YTM이 입력되는 경우 해당 잔존만기의 수익률을 선형보간으로 가져옴  */
		pBondPrice->nYtm = fnGetRate( pCurve, nDaysToMaturity , LINEAR );
	}
        /* Spot 커브에 대한 부분은 생략 */
	nBondPrice = nFace * pBondInfo->nReturnRate / 100.0 + nFace * pow( 1 + pBondInfo->nCouponRate * nIntRatio, nTotalCoupon ) - nFace;
	nBondPrice = floor(nBondPrice) / ( (1 + pBondPrice->nYtm * nDiscountToday ) * pow( 1.0 + pBondPrice->nYtm, nResidueYear  ) ); 

	nDuration = nDaysToMaturity / 365.0;
	nMD = Math_Round( nDuration / ( 1 + pBondPrice->nYtm ), 5 );
	nConvexity = Math_Round( ( Math_Round( nDuration, 6 ) * ( Math_Round( nDuration, 6 ) + 1 ) ) / pow( 1.0 + pBondPrice->nYtm * pBondInfo->nIntMonth /12.0, 2 ), 5 );

	pBondPrice->nPrice = nBondPrice;
	pBondPrice->nDuration = Math_Round( nDuration, 5 );
	pBondPrice->nMD = nMD;
	pBondPrice->nConvexity = nConvexity;

	return SUCCESS;
}

 

 
단리채는 채권 가격 계산 부분이 다음과 같이 변경되면 된다.


	nBondPrice = floor( nFace * ( pBondInfo->nReturnRate / 100.0 + pBondInfo->nCouponRate / nCouponPerYear * (nTotalYear * nCouponPerYear + nRemDay / nLastCouponTermDay ) ) );
	nBondPrice = nBondPrice / ( pow( 1.0 + pBondPrice->nYtm, nResidueYear ) * ( 1.0 + pBondPrice->nYtm * nDiscountToday ));

 

 

 

By yaplab

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다