채권 가격 계산 라이브러 개발을 위해 일반 채권 중 가장 기본이 되는 할인채와 이표채에 대한 설명을 한데 이어 단리채와 복리채에 대한 설명을 하고자 한다.
단리채는 매년 채권의 표면 이자율로 계산한 이자를 누적하여 만기에 일시 상환하는 채권이다. 즉 매년 이자 얼마 ( 원금 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 ));