问题
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