Commit 27142cb7 authored by Dmitry.Shahtanov's avatar Dmitry.Shahtanov Committed by Alexander.Trofimov

fixed:

Bug 24933 - Функция YIELD рассчитывается некорректно когда менее одного периода купона укладывается до даты погашения

git-svn-id: svn://192.168.3.15/activex/AVS/Sources/TeamlabOffice/trunk/OfficeWeb@56964 954022d7-b5bf-4e40-9824-e11837661b57
parent 63942866
...@@ -241,22 +241,37 @@ ...@@ -241,22 +241,37 @@
function _getprice( nSettle, nMat, fRate, fYield, fRedemp, nFreq, nBase ){ function _getprice( nSettle, nMat, fRate, fYield, fRedemp, nFreq, nBase ){
var fE = getcoupdays( new Date(nSettle), new Date(nMat), nFreq, nBase ); var fdays = getcoupdays( new Date(nSettle), new Date(nMat), nFreq, nBase ),
var fDSC_E = getcoupdaysnc( new Date(nSettle), new Date(nMat), nFreq, nBase ) / fE; fdaybs = getcoupdaybs( new Date(nSettle), new Date(nMat), nFreq, nBase ),
var fN = getcoupnum( new Date(nSettle), (nMat), nFreq, nBase ); fnum = getcoupnum( new Date(nSettle), (nMat), nFreq, nBase ),
var fA = getcoupdaybs( new Date(nSettle), new Date(nMat), nFreq, nBase ); fdaysnc = ( fdays - fdaybs ) / fdays,
fT1 = 100 * fRate / nFreq,
fT2 = 1 + fYield / nFreq,
res = fRedemp / ( Math.pow( 1 + fYield / nFreq, fnum - 1 + fdaysnc ) );
var fRet = fRedemp / ( Math.pow( 1.0 + fYield / nFreq, fN - 1.0 + fDSC_E ) ); /*var fRet = fRedemp / ( Math.pow( 1.0 + fYield / nFreq, fnum - 1.0 + fdaysnc ) );
fRet -= 100.0 * fRate / nFreq * fA / fE; fRet -= 100.0 * fRate / nFreq * fdaybs / fdays;
var fT1 = 100.0 * fRate / nFreq; var fT1 = 100.0 * fRate / nFreq;
var fT2 = 1.0 + fYield / nFreq; var fT2 = 1.0 + fYield / nFreq;
for( var fK = 0.0 ; fK < fN ; fK++ ){ for( var fK = 0.0 ; fK < fnum ; fK++ ){
fRet += fT1 / Math.pow( fT2, fK + fDSC_E ); fRet += fT1 / Math.pow( fT2, fK + fdaysnc );
} }
return fRet; return fRet;*/
if( fnum == 1){
return (fRedemp + fT1) / (1 + fdaysnc * fYield / nFreq) - 100 * fRate / nFreq * fdaybs / fdays;
}
res -= 100 * fRate / nFreq * fdaybs / fdays;
for ( var i = 0; i < fnum; i++ ) {
res += fT1 / Math.pow( fT2, i + fdaysnc );
}
return res;
} }
function _getYield( nSettle, nMat, fCoup, fPrice, fRedemp, nFreq, nBase ){ function _getYield( nSettle, nMat, fCoup, fPrice, fRedemp, nFreq, nBase ){
......
...@@ -231,15 +231,18 @@ function getcoupncd( settl, matur, frequency ) { ...@@ -231,15 +231,18 @@ function getcoupncd( settl, matur, frequency ) {
function getprice( settle, mat, rate, yld, redemp, freq, base ) { function getprice( settle, mat, rate, yld, redemp, freq, base ) {
var cdays = getcoupdays( new Date( settle ), new Date( mat ), freq, base ), var cdays = getcoupdays( new Date( settle ), new Date( mat ), freq, base ),
cnum = getcoupnum( new Date( settle ), (mat), freq ), cnum = getcoupnum( new Date( settle ), new Date(mat), freq ),
cdaybs = getcoupdaybs( new Date( settle ), new Date( mat ), freq, base ), cdaybs = getcoupdaybs( new Date( settle ), new Date( mat ), freq, base ),
cdaysnc = ( cdays - cdaybs ) / cdays, cdaysnc = ( cdays - cdaybs ) / cdays,
fT1 = 100 * rate / freq, fT1 = 100 * rate / freq,
fT2 = 1 + yld / freq, fT2 = 1 + yld / freq,
res = redemp / ( Math.pow( 1 + yld / freq, cnum - 1 + cdaysnc ) ); res = redemp / ( Math.pow( 1 + yld / freq, cnum - 1 + cdaysnc ) );
res -= 100 * rate / freq * cdaybs / cdays; if( cnum == 1){
return (redemp + fT1) / (1 + cdaysnc * yld / freq) - 100 * rate / freq * cdaybs / cdays;
}
res -= 100 * rate / freq * cdaybs / cdays;
for ( var i = 0; i < cnum; i++ ) { for ( var i = 0; i < cnum; i++ ) {
res += fT1 / Math.pow( fT2, i + cdaysnc ); res += fT1 / Math.pow( fT2, i + cdaysnc );
...@@ -257,16 +260,18 @@ function getYield( settle, mat, coup, price, redemp, freq, base ) { ...@@ -257,16 +260,18 @@ function getYield( settle, mat, coup, price, redemp, freq, base ) {
for ( var i = 0; i < 100 && priceN != price; i++ ) { for ( var i = 0; i < 100 && priceN != price; i++ ) {
priceN = getprice( settle, mat, coup, yieldN, redemp, freq, base ); priceN = getprice( settle, mat, coup, yieldN, redemp, freq, base );
if ( price == price1 ) if ( price == price1 ){
return yield1; return yield1;
else if ( price == price2 ) }
else if ( price == price2 ){
return yield2; return yield2;
else if ( price == priceN ) }
else if ( price == priceN ){
return yieldN; return yieldN;
}
else if ( price < price2 ) { else if ( price < price2 ) {
yield2 *= 2; yield2 *= 2;
price2 = getprice( settle, mat, coup, yield2, redemp, freq, base ); price2 = getprice( settle, mat, coup, yield2, redemp, freq, base );
yieldN = ( yield2 - yield1 ) * 0.5; yieldN = ( yield2 - yield1 ) * 0.5;
} }
else { else {
...@@ -283,10 +288,12 @@ function getYield( settle, mat, coup, price, redemp, freq, base ) { ...@@ -283,10 +288,12 @@ function getYield( settle, mat, coup, price, redemp, freq, base ) {
} }
} }
if ( Math.abs( price - priceN ) > price / 100 ) if ( Math.abs( price - priceN ) > price / 100 ){
return new cError( cErrorType.not_numeric ); // result not precise enough return new cError( cErrorType.not_numeric ); // result not precise enough
}
return new cNumber( yieldN ); return new cNumber( yieldN );
} }
function getyieldmat( settle, mat, issue, rate, price, base ) { function getyieldmat( settle, mat, issue, rate, price, base ) {
...@@ -3744,7 +3751,7 @@ cODDFYIELD.prototype.Calculate = function ( arg ) { ...@@ -3744,7 +3751,7 @@ cODDFYIELD.prototype.Calculate = function ( arg ) {
i, xBegin, xEnd, x, y, currentIter = 0; i, xBegin, xEnd, x, y, currentIter = 0;
if ( guess <= min || guess >= max ) { if ( guess <= min || guess >= max ) {
return new cError( cErrorType.not_numeric ); return this.value = new cError( cErrorType.not_numeric );
} }
for ( i = 0; i < nIM; i++ ) { for ( i = 0; i < nIM; i++ ) {
...@@ -3760,12 +3767,12 @@ cODDFYIELD.prototype.Calculate = function ( arg ) { ...@@ -3760,12 +3767,12 @@ cODDFYIELD.prototype.Calculate = function ( arg ) {
high = (xEnd + step * (xEnd - xBegin)); high = (xEnd + step * (xEnd - xBegin));
} }
else { else {
return new cError( cErrorType.not_numeric ); return this.value = new cError( cErrorType.not_numeric );
} }
} }
if ( i == nIM ) { if ( i == nIM ) {
return new cError( cErrorType.not_numeric ); return this.value = new cError( cErrorType.not_numeric );
} }
var fXbegin = iterF( xBegin ), fXend = iterF( xEnd ), fXi, xI; var fXbegin = iterF( xBegin ), fXend = iterF( xEnd ), fXi, xI;
......
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