zoukankan      html  css  js  c++  java
  • ORACLE SQL 实现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;
  • 相关阅读:
    Cocos2dx 3.0 交流篇
    android获取ip和本机的物理地址
    半平面交总结and模板
    页面跳转的三种方式
    83. 从视图索引说Notes数据库(上)
    IE7IE8兼容性设置_服务器端设定
    [置顶] 王志成30岁前自传-我曾创造过的“第一”
    Android CTS 结果 testResult.xml 修改 fail 项 为 notExecuted 项 分析
    java android面试题分析总结
    android之写文件到sd卡
  • 原文地址:https://www.cnblogs.com/Alex-Zeng/p/12107703.html
Copyright © 2011-2022 走看看