[Stick to the top] I used advanced mathematics at the beginning of N: I used PL/SQL to calculate IRR.

Source: Internet
Author: User

I have been working as an internal enterprise system for N years.

A few years ago, its department came to a country (not USA) and was younger than ours. Of course, I grew up drinking foreign ink. English is very slippery. Once I had a good time, I was very rude to you. What do you use to read so many books? I have never been in college, and I am still at a higher level than you. I was very depressed. But if you want to think about it carefully, do it in the company's internal system. At the elementary level, there will be four arithmetic operations, and the logic is not confused. You can eat it in the its Department of the world's top 500 enterprises.

After a few years, the Chinese people are far away, and we are still doing what primary school students can do. This is just a knot and never ends.

Recently, we finally had a chance to use advanced mathematics. It's useless to read a book.

 

This is the truth about doing business and returning the image. How much is invested and how long can it be recovered? This requires calculating IRR. It is easy to use Excel. It is troublesome to use Oracle. (This is not a joke)

If you are interested in how to calculate IRR, refer

Wikipedia: http://en.wikipedia.org/wiki/Internal_rate_of_return

Or http://zainco.blogspot.jp/2008/08/internal-rate-of-return-using-newton.html

Or http://www.corality.com/tutorials/iterative-approach-calculating-internal-rate-return-irr

 

When NPV = 0, the R is IRR.

After expansion, it is a polynomial,

When polynomial is equal to 0, what is r equal?

This problem does not have a precise solution (resolution), but only an approximate solution (numerical solution ).

Generally, the Newton-Raphson method is used.

 

Let's look at the code first.

For the principle, refer to the above URLs.

 

PL/SQL Encoding

1. Calculate the xirr Function

This code was copied from Oracle Forum, http://forums.oracle.com/forums/thread.jspa? Threadid = 549939

Two types must be pre-defined:

Create or replace type p_date_array is varray (250) of date;

Create or replace type t_amount_array is varray (250) of number;

 

create or replace FUNCTION            "XIRR" (p_date_array in p_date_array,                                  p_amount_array in t_amount_array,                                  p_guess in number default 0                                 )  RETURN NUMBER  IS  ----- Reference: http://forums.oracle.com/forums/thread.jspa?threadID=549939   -- pre-defined types:  -- create or replace type p_date_array is varray(250) of date;  -- create or replace type t_amount_array is varray(250) of number;  BEGIN    declare      z number := 0;      step_limit number := 0;      temp number;      rtn_err number := -9999999;      step number := 0.1;      d number := 0.5;      l_MaxDate date;      l_MinDate date;      srok number;    begin      l_MaxDate := p_date_array(1);      l_MinDate := p_date_array(1);      -- 5@2K9 ?@>E>4: ?>8A: <0:A. 40BK 8 =0;8G8O E>BO 1K >4=>3> <8=CA0 8 ?;NA0 2 ?>B>:0E      for i in 1 .. p_date_array.count      loop        if p_date_array(i) > l_MaxDate then           l_MaxDate := p_date_array(i);        end if;        if p_date_array(i) < l_MinDate then           l_MinDate := p_date_array(i);        end if;      end loop;      select months_between(l_MaxDate, l_MinDate)      into srok      from dual;      loop        temp := p_amount_array(1);        for i in 2 .. p_amount_array.count        loop          temp := temp + p_amount_array(i)/power((1 + d),(p_date_array(i) - p_date_array(1))/365);        end loop;        if (temp > 0) and (z = 0) then           step := step / 2;           z := 1;        end if;        if (temp < 0) and (z = 1) then            step := step / 2;            z := 0;        end if;        if (z = 0) then            d := d - step;        else            d := d + step;        end if;        step_limit := step_limit + 1;        if (step_limit = 10000) then          return rtn_err; -- a kind of error          exit;        end if;        exit when(round(temp * 100000) = 0);      end loop;        return d;    EXCEPTION        WHEN OTHERS THEN        return rtn_err;        end; END XIRR; 

2. Calculate IRR Functions

create or replace FUNCTION            "IRR" ( p_amount_array in t_amount_array,                                p_guess in number default 0                               )  RETURN NUMBER  IS  PDA P_DATE_ARRAY;BEGINPDA := P_DATE_ARRAY() ; -- initialize Varray with NULL, count=0  for i in 1 .. p_amount_array.count  loop    PDA.EXTEND; -- Add 1 element to Varray    PDA(i) := sysdate + 365*(i-1) ;  end loop;  Return XIRR(P_DATE_ARRAY => PDA,P_AMOUNT_ARRAY => p_amount_array, P_GUESS => P_GUESS);END; 

3. Related functions: xnpv and NPV

create or replace FUNCTION            "XNPV" (p_date_array in p_date_array,                                  p_amount_array in t_amount_array,                                  p_discount_rate in number                                 )  RETURN NUMBER  IS  ----- Reference: http://forums.oracle.com/forums/thread.jspa?threadID=549939   -- pre-defined types:  -- create or replace type p_date_array is varray(250) of date;  -- create or replace type t_amount_array is varray(250) of number;      z number := 0;      step_limit number := 0;      temp number;      step number := 0.1;      xnpv number := 0.5;      l_MaxDate date;      l_MinDate date;      srok number;    begin/*********** Formular *************XNPV = I(1) + I(2)/(1+r)^(d(2)-d(1))/365 + ........ + I(n)/(1+r)^(d(n)-d(1))/365***********************************/  xnpv := p_amount_array(1);  for i in 2 .. p_amount_array.count    loop       xnpv := xnpv + p_amount_array(i)/power((1 + p_discount_rate),(p_date_array(i) - p_date_array(1))/365);    end loop;   return xnpv;end; 

create or replace FUNCTION            "NPV" ( p_amount_array in t_amount_array,                                p_discount_rate in number                               )  RETURN NUMBER  IS  PDA P_DATE_ARRAY;BEGINPDA := P_DATE_ARRAY() ; -- initialize Varray with NULL, count=0  for i in 1 .. p_amount_array.count  loop    PDA.EXTEND; -- Add 1 element to Varray    PDA(i) := sysdate + 365*(i-1) ;--htp.p(PDA(i));      end loop;  Return XNPV(P_DATE_ARRAY => PDA,P_AMOUNT_ARRAY => p_amount_array, P_DISCOUNT_RATE => p_discount_rate);END; 

4. Use Cases

Raw Data

 

2001/1/1 2002/1/1 2003/1/1 2004/1/1 2005/1/1 2006/1/1
-6264695 667885.4979 329584.128 329584.128 329584.1 3527014

 

DECLARE    PDA P_DATE_ARRAY;    PAA T_AMOUNT_ARRAY;    P_GUESS NUMBER;    P_DISCOUNT_RATE Number := 0.0743;    v_Return NUMBER;  BEGIN    -- Modify the code to initialize the variable    PDA := P_DATE_ARRAY(                        to_date('2007/01/01','yyyy/mm/dd'),                        to_date('2008/01/01','yyyy/mm/dd'),                        to_date('2009/01/01','yyyy/mm/dd'),                        to_date('2010/01/01','yyyy/mm/dd'),                         to_date('2011/01/01','yyyy/mm/dd'),                        to_date('2012/01/01','yyyy/mm/dd'),                        to_date('2013/01/01','yyyy/mm/dd'),                        to_date('2014/01/01','yyyy/mm/dd'));    -- Modify the code to initialize the variable    PAA := T_AMOUNT_ARRAY(-112651.395506849,274684.931506849);     P_GUESS := NULL;        v_Return := XIRR(P_DATE_ARRAY => PDA,P_AMOUNT_ARRAY => PAA,P_GUESS => P_GUESS);    DBMS_OUTPUT.PUT_LINE('XIRR = ' || v_Return);    v_Return := IRR(P_AMOUNT_ARRAY => PAA,P_GUESS => P_GUESS);    DBMS_OUTPUT.PUT_LINE('IRR = ' || v_Return);    v_Return := XNPV(P_DATE_ARRAY => PDA,P_AMOUNT_ARRAY => PAA,P_DISCOUNT_RATE => P_DISCOUNT_RATE);    DBMS_OUTPUT.PUT_LINE('XNPV = ' || v_Return);    v_Return := NPV(P_AMOUNT_ARRAY => PAA,P_DISCOUNT_RATE => P_DISCOUNT_RATE);    DBMS_OUTPUT.PUT_LINE('NPV = ' || v_Return);  END;

Result:

Xirr= 1.4383624397218227386474609375
Irr= 1.4383624397218227386474609375
Xnpv= 143035.9651064331372056222656613608861584
Npv= 143035.9651064331372056222656613608861584

Statement processed.


0.23 seconds

 

5. Comparison with Excel computing results

 

  Excel Oracle Difference
Xirr -0.04458783 -044584477263 -3.35245e-06
IRR -4% -0446097485299 -3.67924e-11
Xnpv -2379917.807 -2380026.06389 108.2568879
NPV ¥-2,214,823.89 -2379385.302111 164561.4141

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.