在 Javascript 中构建求解器算法的最佳方法是什么?
我正在构建一个金融应用程序,其中我必须求解将现金流贴现回现值的利率(债券收益率)。我们正在解决费率问题。
在 Javascript 中执行此操作的最佳方法是什么?我所拥有的有效,但我觉得它可以优化,因为即使使用可靠的“最佳猜测”参数,目前它也可能需要 60/70 毫秒。
另外 - 是否有一种算法方法可以确定 iteratingIncrement 和允许的错误,以便永远不会出现 iteratingIncrement 太大而无法找到 allowedError 的情况?
非常欢迎所有建议。
非常感谢
const solveDcfYield = ( workoutCashflows, target, bestGuess=0.00, iteratingIncrement=0.000001, allowableError=0.0001, maxIterations=1000000) => {
/**
* @param {array} workoutCashflows Array of cashflows for specific settle and exchange.
* @param {float} target Value for which to solve toward.
* @param {float} bestGuess Best Guess to optimise algorithm solve time. As percentage e.g. 5.00.
* @param {float} iteratingIncrement Value to increment solver each iteration.
* @param {float} allowableError Minimum distance from target to solve, unless max iterations hit.
* @param {int} maxIterations Maximum number of iterations to un in the solver
*
* @return {float} r Rate/yield that discounts cashflows coto within allowableError of target
*/
let iteratingDifference = allowableError + 10;
let r = bestGuess/100;
let iterations = 0;
let startTime = new Date().getTime();
while ((( iteratingDifference > allowableError) || (iteratingDifference < -allowableError)) && (iterations <= maxIterations)) {
iteratingDifference = target - sumAndDiscountCashFlows(workoutCashflows, r);
r = (iteratingDifference > 0) ? (r - iteratingIncrement) : (r + iteratingIncrement);
iteratingDifference = parseFloat(iteratingDifference.toFixed(8));
iterations = iterations + 1;
if (iterations === (maxIterations - 1)){
console.log("maximum iterations hit...");
}
};
let endTime = new Date().getTime();
let time = endTime - startTime
console.log("Solver Algorithm Execution Time: ", time);
return r;
};
I am building a financial application in which I have to solve for a rate( bond yield ) that discounts cashflows back to a present value. We are solving for the rate.
What would the best way to do this in Javascript? What I have works, but I feel it can be optimised as it currently might take 60/70ms even with a solid 'best guess' parameter.
Also - is there a algorithmic way of determining the iteratingIncrement and allowable error such that there is never a time when the iteratingIncrement is too large to be able to find the allowableError?
All suggestions very welcome.
Many Thanks
const solveDcfYield = ( workoutCashflows, target, bestGuess=0.00, iteratingIncrement=0.000001, allowableError=0.0001, maxIterations=1000000) => {
/**
* @param {array} workoutCashflows Array of cashflows for specific settle and exchange.
* @param {float} target Value for which to solve toward.
* @param {float} bestGuess Best Guess to optimise algorithm solve time. As percentage e.g. 5.00.
* @param {float} iteratingIncrement Value to increment solver each iteration.
* @param {float} allowableError Minimum distance from target to solve, unless max iterations hit.
* @param {int} maxIterations Maximum number of iterations to un in the solver
*
* @return {float} r Rate/yield that discounts cashflows coto within allowableError of target
*/
let iteratingDifference = allowableError + 10;
let r = bestGuess/100;
let iterations = 0;
let startTime = new Date().getTime();
while ((( iteratingDifference > allowableError) || (iteratingDifference < -allowableError)) && (iterations <= maxIterations)) {
iteratingDifference = target - sumAndDiscountCashFlows(workoutCashflows, r);
r = (iteratingDifference > 0) ? (r - iteratingIncrement) : (r + iteratingIncrement);
iteratingDifference = parseFloat(iteratingDifference.toFixed(8));
iterations = iterations + 1;
if (iterations === (maxIterations - 1)){
console.log("maximum iterations hit...");
}
};
let endTime = new Date().getTime();
let time = endTime - startTime
console.log("Solver Algorithm Execution Time: ", time);
return r;
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
计算债券到期收益率1的有效方法是使用 牛顿法,需要计算导数,我在下面推导出来。
您可以如下表达您的问题。
让
i =待
p = α nf + c(1+α-0.5)Σj=1.. nαj
请注意α-0.5 是一种调整,稍微增加年中优惠券的价值,以便它们可以从同年年底开始打折以提供同等的现值。这是从以下恒等式得出的。
α(cα-0.5) = cα0.5
由于
Σj=1.. nαj
可见是我们可以写成的几何级数的和:
p = fαn + (1+α-0.5)cα(αn-1)/(1-α)
等价于:
p = (f(1-α) + (1+α-0.5)αc)αn - (1+α-0.5)αc)(1-α)-1
现在定义以下函数。
g1(α) = (1+α-0.5)ac
g2(α) = (f(1-α)+g1(α))
g3(α) = αn
g4(α) = (1-α)-1
g5(α) = g2(α)g3(α)-1
h(α) = g1(α)g5(α)g4(α)
我们希望找到 α+,其中
h(α+) = p
As α+ > = 1/(1+i),因此到期收益率等于 1/α+-1。
h
相对于α
的导数如下:h'(α) = g1'(α)g5(α)g4(α) + g1(α)g5 '(α)g4(α) + g1(α)g5(α)g4'(α)
其中
g1'(α) = (-0.5α-1.5)ac + (1+α-0.5)c
g2'(α) = -f+g1'(α)
g3'(α) = nαn-1
g4'(α ) = -1/(1-α)2
g5'(α) = g2'(α)g3(α) + g2(α)g3'(α)
我们可以首先将 α 设置为等于对某些人平均收益率 α0。然后使用直线近似(即牛顿法)估计 α 的新值:
h(α0) + (α0+d)*h'( α0) = p
并求解 d:
d = (ph(α0))/h'(α0) - α< sub>0
α 的新估计为因此 α + d。接下来,计算
d = (ph(α))/h'(α) - α
update α 并以这种方式继续,直到 α 的变化足够小。这应该很快收敛,当然比不使用导数的方法更快。
1.债券的到期收益率是导致债券购买价格等于息票支付现值(每年两次)加上到期日债券面值支付现值之和的年贴现率.
An efficient way to compute the yield to maturity of a bond1 is to use Newton's method, which requires the calculation of derivatives, which I derive below.
You can express your problem as follows.
Let
Then
p = αnf + c(1+α-0.5)Σj=1.. nαj
Note that α-0.5 is an adjustment that slightly increases the value of mid-year coupons so that they may be discounted from the end of the same year to provide an equivalent present value. This follows from the following identity.
α(cα-0.5) = cα0.5
As
Σj=1.. nαj
is seen to be the sum of a geometric series we can write:
p = fαn + (1+α-0.5)cα(αn-1)/(1-α)
which is equivalent to the following:
p = (f(1-α) + (1+α-0.5)αc)αn - (1+α-0.5)αc)(1-α)-1
Now define the following functions.
g1(α) = (1+α-0.5)ac
g2(α) = (f(1-α)+g1(α))
g3(α) = αn
g4(α) = (1-α)-1
g5(α) = g2(α)g3(α)-1
h(α) = g1(α)g5(α)g4(α)
We wish to find α+ for which
h(α+) = p
As α+ = 1/(1+i), the yield to maturity therefore equals 1/α+-1.
The derivative of
h
relative toα
is as follows:h'(α) = g1'(α)g5(α)g4(α) + g1(α)g5'(α)g4(α) + g1(α)g5(α)g4'(α)
where
g1'(α) = (-0.5α-1.5)ac + (1+α-0.5)c
g2'(α) = -f+g1'(α)
g3'(α) = nαn-1
g4'(α) = -1/(1-α)2
g5'(α) = g2'(α)g3(α) + g2(α)g3'(α)
We might begin by setting α equal to some average yield α0. Then estimate a new value of α using the straight-line approximation (i.e., Newton's method):
h(α0) + (α0+d)*h'(α0) = p
and solving for d:
d = (p-h(α0))/h'(α0) - α0
The new estimate of α is therefore α + d. Next, calculate
d = (p-h(α))/h'(α) - α
update α and continue in this fashion until the change in α is sufficiently small. This should quickly converge, certainly faster that methods that do not use derivates.
1. A bond's yield to maturity is the annual discount rate that causes the purchase price of the bond to equal the sum of the present values of coupon payments (two per year) plus the present value of the payment of the bond's face value on the maturity date.