sqlserver存储过程实现Excel中npv和irr函数
/*************************/ -- net present value -- npv = sum(cf(t)/(1+r)^t) for t=0 to n -- where cf(t) is the cash flow at time t -- and r is the discount rate if exists (select * from dbo.sysobjects where id = object_id('dbo.npv') and xtype in ('FN','IF','TF')) drop function dbo.npv GO create function dbo.npv (@rate real) returns real begin declare @npv real -- return value declare @t int declare @cf money set @npv=0 set @t=0 declare cur cursor for select cf from test open cur fetch next from cur into @cf while @@FETCH_STATUS = 0 begin set @npv = @npv + @cf * power(1+@rate,-@t) set @t = @t+1 fetch next from cur into @cf end close cur deallocate cur return(@npv) end go /*************************/ -- internal rate of return -- irr is defined as the discount rate at which the npv of the cash flows is --exactly zero -- the only way to solve for irr is through iteration -- the irr can be multivariate or undefined,therefore a guess value is --required -- irr and npv are inverse functions -- a good test is the npv of the cash flows at a discount rate equal to the --irr should -- equal zero (or very close to zero) if exists (select * from dbo.sysobjects where id = object_id('dbo.irr') and xtype in ('FN','TF')) drop function dbo.irr GO create function dbo.irr (@rateguess real) returns real begin declare @delta real -- rate delta in 2-point formula set @delta=.0001 -- .0001 equals one hundreth of one percent declare @epsilon real -- criteria for success,npv must be within +/-epsilon of zero set @epsilon=.005 -- .005 equals one half cent declare @maxtry smallint -- number of iterations allowed set @maxtry=10 declare @irr real -- return value set @irr=null -- assume failure declare @rate1 real declare @rate2 real declare @npv1 real declare @npv2 real declare @done smallint declare @try smallint set @done=0 set @try=0 while @done=0 and @try<@maxtry begin set @rate1 = @rateguess set @npv1 = dbo.npv(@rate1) if abs(@npv1) < @epsilon begin -- success set @done=1 set @irr=@rate1 end else begin -- try again with new rateguess set @rate2 = @rate1 + @delta set @npv2 = dbo.npv(@rate2) set @rateguess = @rate1 - @npv1*(@rate2-@rate1)/(@npv2-@npv1) set @try = @try + 1 end end return(@irr) end go /*************************/ -- setup test table of cash flows,first cash flow at t=0 if exists (select * from sysobjects where id = object_id('test') and sysstat & 0xf = 3) drop table test GO create table test (cf money not null) go set nocount on insert test (cf) values (-100) insert test (cf) values (10) insert test (cf) values (10) insert test (cf) values (10) insert test (cf) values (10) insert test (cf) values (10) insert test (cf) values (10) insert test (cf) values (10) insert test (cf) values (10) insert test (cf) values (10) insert test (cf) values (10) insert test (cf) values (10) set nocount off go select dbo.npv(.1) go select dbo.irr(.05) go -- the net present value of the internal rate of return should be very close to zero select dbo.npv(dbo.irr(.05)) go --另一种带顺序的写法:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 关于SqlServer Identity列的常用操作
- 我使用Azure表存储或SQL Azure作为我们的CQRS读取系统?
- sql-server – IsNumeric失败,出现“当前命令发生严重错误.
- SQLSERVER如何获取一个数据库中的所有表的名称、一个表中所
- sql-server – 在SQL Server 2008中的符号之前的字符串中隔
- .net – 重构LINQ IQueryable表达式以删除重复的查询部分
- sql-server – 在NHibernate和SqlServer中的数据审计
- 函数QUOTENAME
- EDWorkFlow工作流
- sqlserver2008中在实现limit功能的同时实现order by 排序功