ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

ORACLE SQL 实现IRR的计算(二)

2019-12-27 15:50:44  阅读:603  来源: 互联网

标签:cashValue end IRR number value irrGuess SQL ORACLE irr


上一版实现:https://www.cnblogs.com/Alex-Zeng/p/9334582.html

上一版实现在某些情况下会计算出负值,与Excel的计算有差异。所以修改了实现方法。

实现的具体代码如下:

function IRR_ZEN(p_amount_array in typ_cashflow_array) RETURN NUMBER is
    rtn_err      number := 0;
    irrGuess     number := 0.01; -- default: 10%
    irr          number := 0.0;
    minDistance  number := 1E-15; --iteration: the smaller the distance, the smaller the interpolation
    maxIteration integer := 1000;
  
    wasHi         boolean := false;
    noOfCashFlows integer := 0;
    cashValue     number := 0.0;
    cashFlowStart number := 0.0;
  
    result_value number := 0.0;
  
  BEGIN
    irr           := irrGuess;
    result_value  := -999999;
    noOfCashFlows := p_amount_array.count;
  
    -- business startup costs
    cashFlowStart := p_amount_array(1); 
    
    for i in 1 .. maxIteration loop
      -- calculate cash value with current irr:
      cashValue := cashFlowStart; -- init with startup costs
    
      -- for each cash flow
      for j in 2 .. noOfCashFlows loop
        cashValue := cashValue + p_amount_array(j) / power(1.0 + irr, j-1);
      end loop;
    
      -- cash value is nearly zero
      if (abs(cashValue) < 0.0000000001) then
        -- dbms_output.put_line('abs(cashValue) < 0.0000000001 : '||to_char(cashValue));
        result_value := irr;
        exit;
      end if;
    
      -- adjust irr for next iteration:
      -- cash value > 0 => next irr > current irr
      if (cashValue > 0) then
        if wasHi then
          irrGuess := irrGuess / 2;
        end if;
      
        irr := irr + irrGuess;
      
        if wasHi then
          irrGuess := irrGuess - minDistance;
          wasHi    := false;
        end if;
      
      else
        -- cash value < 0 => next irr < current irr
        irrGuess := irrGuess / 2;
        irr      := irr - irrGuess;
        wasHi    := true;
      end if;
    
      -- estimated result too small to continue => end
      -- calculation
      if (irrGuess <= minDistance) then
        -- dbms_output.put_line('irrGuess <= minDistance : '||to_char(irrGuess));
        result_value := irr;
        exit;
      end if;
    end loop;
  
    return result_value;
  EXCEPTION
    WHEN OTHERS THEN
      dbms_output.put_line(substr(sqlerrm, 1, 640)); 
      return rtn_err;
  END IRR_ZEN;

 

标签:cashValue,end,IRR,number,value,irrGuess,SQL,ORACLE,irr
来源: https://www.cnblogs.com/Alex-Zeng/p/12107703.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有