Given the starting value @pStartingValue and a table which contains rorDate and ror what is the most efficient way to get the NAV at each date using just TSQL?
This mathematically trivial, and simple in code. I have a naive SQL implementation currently that relies on cursors.
On the first date, the NAV is @pStartingValue * ror
On every subsequent date, it’s the previously calculated nav * ror or it’s @pStartingValue * every previous ror
How would you efficiently do this only in MSSQL2005+?
DECLARE @rorDate DATE
DECLARE @getDate CURSOR
DECLARE @lastNAV as DECIMAL(19,7)
DECLARE @datedRoR as float
DECLARE @NAVTotals TABLE
(
NAV DECIMAL(19,7),
navDate DATE
)
SET @lastNAV = 100
SET @getDate = CURSOR FOR
SELECT
p.[DATE]
FROM
performance p
ORDER BY
p.[DATE]
OPEN @getDate
FETCH NEXT
FROM @getDate INTO @rorDate
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT
@datedRoR = b.finalNetReturn
FROM
performance b
WHERE
b.date = @rorDate
INSERT INTO @NAVTotals (NAV, navDate)
VALUES (@lastNAV * (1 + @datedRoR), @rorDate)
SELECT
@lastNAV = c.NAV
FROM
@NAVTotals c
WHERE
c.navDate = @rorDate
FETCH NEXT
FROM @getDate INTO @rorDate
END
CLOSE @getDate
DEALLOCATE @getDate
select * from @NAVTotals
You’ll have to do some testing to see if the performance improves but this is a way to do that same thing without using a cursor. It’s untested so you’ll want to make sure to test it. I also cast
b.finalNetReturnas a float, if it’s already a float you can remove that part.By dropping the lastNAV variable into the update statement you can update both. It works similar to:
There is an example of this same approach here. Including some good numbers that compare the efficiency of the approach to other approaches such as cursors.