Calculating Geometrically Linked Returns in SQL SERVER 2008

空扰寡人 提交于 2021-02-10 12:11:34

问题


Calculating geometrically link returns

How do you multiply record2 * record1?

The desire is to return a value for actual rate and annulized rate

Given table unterval:

   EndDate    PctReturn
-------------------------------
1. 05/31/06   -0.2271835
2. 06/30/06   -0.1095986
3. 07/31/06    0.6984908
4. 08/31/06    1.4865360
5. 09/30/06    0.8938896

The desired output should look like this:

EndDate    PctReturn    Percentage   UnitReturn         
05/31/06   -0.2271835   -0.002272    0.997728               
06/30/06   -0.1095986   -0.001096    0.996634669                
07/31/06    0.6984908    0.006985    1.00359607             
08/31/06    1.4865360    0.014865    1.018514887                
09/30/06    0.8938896    0.008939    1.027619286


Percentage = PctReturn/100                          

UnitReturn  (1 + S1) x (1 + S2) x ... (1 + Sn) - 1                      

Aggregating values desired:

Actual Rate 2.761928596             
Annulized   6.757253223

Mathematics on aggregating value:

 Actual Rate    1.027619    1.027619-1  =   0.027619    * 100 = 2.761928596

 Annulized Rate 6.757253    (ActualRate^(12/number of intervals)-1)*100

 Number of intervals in Example = 5

there are only 5 records or intervals

I did try utilizing the sum in the select statement but this did not allow for multiplying record2 by record1 to link returns. I thought utilizing the while function would allow for stepping record by record to multiply up the values of unitreturn. My starter level in SQL has me looking for help.


回答1:


You have two option for getting a product in SQL Server.

1. Simulate using logs and exponents:

SQL Fiddle

create table returns
(
  returnDate date,
  returnValue float
)

insert into returns values('05/31/06', -0.002271835)
insert into returns values('06/30/06', -0.001095986)
insert into returns values('07/31/06', 0.006984908)
insert into returns values('08/31/06', 0.014865360)
insert into returns values('09/30/06', 0.008938896)

select totalReturn = power
  (
    cast(10.0 as float)
    , sum(log10(returnValue + 1.0))
  ) - 1
from returns;

with tr as
(
  select totalReturn = power
  (
    cast(10.0 as float)
    , sum(log10(returnValue + 1.0))
  ) - 1
  , months = cast(count(1) as float)
  from returns
)
select annualized = power(totalReturn + 1, (1.0 / (months / 12.0))) - 1
from tr;

This leverages logs and exponents to simulate a product calculation. More info: User defined functions.

The one issue here is that it will fail for return < -100%. If you don't expect these it's fine, otherwise you'll need to set any values < 100% to -100%.

You can then use this actual return to get an annualized return as required.

2. Define a custom aggregate with CLR:

See Books Online.

You can create a CLR custom function and then link this an aggregate for use in your queries. This is more work and you'll have to enable CLRs on your server, but once it's done once you can use it as much as required.



来源:https://stackoverflow.com/questions/14540724/calculating-geometrically-linked-returns-in-sql-server-2008

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!