【发布时间】:2014-01-25 04:04:34
【问题描述】:
我正在尝试在 SQL 中找到一个体面的 excels XIRR 计算实现。
我在网上找到了以下功能:
CREATE TYPE dbo.MyXirrTable AS TABLE
(
theValue DECIMAL(19, 9) NOT NULL,
theDate DATETIME NOT NULL
)
GO
CREATE FUNCTION dbo.XIRR
(
@Sample MyXirrTable READONLY,
@Rate DECIMAL(19, 9) = 0.1
)
RETURNS DECIMAL(38, 9)
AS
BEGIN
DECLARE @LastRate DECIMAL(19, 9),
@RateStep DECIMAL(19, 9) = 0.1,
@Residual DECIMAL(19, 9) = 10,
@LastResidual DECIMAL(19, 9) = 1,
@i TINYINT = 0
IF @Rate IS NULL
SET @Rate = 0.1
SET @LastRate = @Rate
WHILE @i < 100 AND ABS((@LastResidual - @Residual) / @LastResidual) > 0.00000001
BEGIN
SELECT @LastResidual = @Residual,
@Residual = 0
SELECT @Residual = @Residual + theValue / POWER(1 + @Rate, theDelta / 365.0E)
FROM (
SELECT theValue,
DATEDIFF(DAY, MIN(theDate) OVER (), theDate) AS theDelta
FROM @Sample
) AS d
SET @LastRate = @Rate
If @Residual >= 0
SET @Rate += @RateStep
ELSE
SELECT @RateStep /= 2,
@Rate -= @RateStep
SET @i += 1
END
RETURN @LastRate
END
GO
(取自here)
在测试此功能后取得了很大的成功(结果与 excel 匹配)。我已经意识到它似乎不适用于会导致负 XIRR 的一组事务。
我并不完全了解算法的内部原理,并且尝试过调试但运气不佳。
这是一个失败的测试用例:
DECLARE @Test MyXirrTable
INSERT @Test
VALUES (-4471762.56680002, '2008-11-13 00:00:00.000'),
(+2607759.77, '2008-11-14 00:00:00.000'),
(+12263.33, '2008-11-25 00:00:00.000'),
(+1658.89, '2008-11-25 00:00:00.000'),
(+1834423.33, '2008-12-04 00:00:00.000'),
(-0.000245418674579822,'2013-11-14 00:00:00.000')
SELECT dbo.XIRR(@Test, 0.1)
计算值 = -0.000000001
预期值 = -0.12879
有没有比我更了解金融算法的人有解决这个测试用例或更好的 SQL 解决方案的方法?
【问题讨论】:
-
我复制了你的代码,测试用例返回10.00000! (SQL 2012)。似乎至少有 2 个 XIRR 计算(如果不是更多的话),加上它的商业实现以及其他 Excel 函数。
-
haha 哎呀,我在示例中交换了否定和肯定...这不重要(即第一个和最后一个值应该是 -ve 和 +ive 之间的值,如 excel例子)。我现在将更改示例