一、IRR计算的原理:

  内部收益率(Internal Rate of Return (IRR)),就是资金流入现值总额与资金流出现值总额相等、净现值等于零时的折现率。

用公式 标识:-200+[30/(1+IRR)+30/(1+IRR)^2+....+30/(1+IRR)^10]=0。多次方程求解。

在计算机界求解高次方程的做法通常是利用牛顿插值法(Newton-Raphson)来实现,也有翻译牛顿迭代的。

二、关于牛顿迭代:

设r是  的根,选取 作为r的初始近似值,过点  做曲线  的切线L,L的方程为  ,求出L与x轴交点的横坐标

  ,称x1为r的一次近似值。过点  做曲线  的切线,并求该切线与x轴交点的横坐标  ,称 为r的二次近似值。重复以上过程,得r的近似值序列,其中,
  称为r的  次近似值。
 
三、Java的实现方式:
import java.math.BigDecimal;

public class IRRUtilMath2 {

    public static double irr(double[] income) {
return irr(income, 0.1D);
} public static double irr(double[] values, double guess) {
int maxIterationCount = 20;
double absoluteAccuracy = 1.0E-007D; double x0 = guess; int i = 0;
while (i < maxIterationCount) {
double fValue = 0.0D;
double fDerivative = 0.0D;
for (int k = 0; k < values.length; k++) {
fValue += values[k] / Math.pow(1.0D + x0, k);
fDerivative += -k * values[k] / Math.pow(1.0D + x0, k + 1);
}
double x1 = x0 - fValue / fDerivative;
if (Math.abs(x1 - x0) <= absoluteAccuracy) {
return x1;
}
x0 = x1;
i++;
}
return (0.0D / 0.0D);
} public static void main(String[] args) {
double[] income = {-359900,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,19413.67,18241.01,0,0};
double ret = irr(income,0.00001d)*12 ;
System.out.println(new BigDecimal(ret)); }
}

四、根据Java版实现的SQL版:

--定义type
create or replace type typ_cashflow_array is varray(60) of number; --实现函数
function IRR_ZEN(p_amount_array in typ_cashflow_array, p_guess in number)
RETURN NUMBER is
rtn_err number := -9999999;
maxIterationCount number := 20;
absoluteAccuracy number := 0.0000001;
x0 number := p_guess;
x1 number := 0;
i_num integer := 0; fValue number := 0.0;
fDerivative number := 0.0; BEGIN
--x0 :=p_guess;
while (i_num < maxIterationCount) loop
fValue := 0.0;
fDerivative := 0.0;
for k in 1..p_amount_array.count loop
fValue :=fValue+p_amount_array(k)/power(1.0 + x0, k);
fDerivative :=fDerivative+(-k *p_amount_array(k)/power(1.0 + x0, k + 1));
end loop;
x1 := x0 - fValue / fDerivative;
if (abs(x1 - x0) <= absoluteAccuracy) then
return x1;
end if;
x0 := x1;
i_num := i_num+1;
end loop;
return (0.0/0.0);
EXCEPTION
WHEN OTHERS THEN
return rtn_err;
END IRR_ZEN;

五、关于函数的调用:

  方法一,将现金流组成字符串,然后用函数拆解字符串。具体实现方式是

function IRR(in_varray in varchar2) return number
is
v_irr number;
v_amount_array typ_cashflow_array; begin
v_amount_array :=typ_cashflow_array();
declare
v_varray_str varchar2(1000);
v_length number;
v_split varchar2(2);
v_cnt integer;
begin
v_varray_str:=ltrim(rtrim(in_varray));
v_length:=0;
v_split :=',';
v_cnt :=1;
---劈开字符串,为数据赋值
while instr(v_varray_str,v_split)<>0 loop
v_length:=v_length+1;
v_amount_array.extend;
v_amount_array(v_cnt) :=to_number(substr(v_varray_str,1,instr(v_varray_str,v_split)-1));
v_varray_str:=substr(v_varray_str,instr(v_varray_str,v_split)+length(v_split),length(v_varray_str));
v_cnt :=v_cnt+1;
end loop; --循环的末尾追加最后一个数字
v_amount_array.extend;
v_amount_array(v_cnt) :=to_number(v_varray_str); end;
v_irr :=IRR_ZEN(p_amount_array => v_amount_array, p_guess =>0.1 );
return v_irr;
end ;

调用的时候:

select LES_FIN_TO_DW.IRR(listagg(t.fee_amt,',') within group( order by t.pay_pd))*12  from
F_LES_PAY_SCH_IRR_CAL_CASHFLOW t
where t.pay_sch_id=180605104121724
order by t.pay_pd;

方法二:  直接使用类型转换公式初始化数组

select les_fin_to_dw.IRR_ZEN(cast(collect(fee_amt) as typ_cashflow_array),0.1)*12
from(
select t.fee_amt
from F_LES_PAY_SCH_IRR_CAL_CASHFLOW t
where t.pay_sch_id=171218104072346
order by t.pay_pd
);

方法一的弊端:

listagg可连接的最大字节长度是4000byte.当金额比较大,现金流周期比较长的时候可能会有问题。

方法二的弊端:

 现金流的输入是有顺序的,必须先排序。

 
参考资料:
  https://baike.baidu.com/item/%E7%89%9B%E9%A1%BF%E8%BF%AD%E4%BB%A3%E6%B3%95/10887580?fr=aladdin
       

ORACLE SQL 实现IRR的计算的更多相关文章

  1. Oracle sql语句执行顺序

    sql语法的分析是从右到左 一.sql语句的执行步骤: 1)词法分析,词法分析阶段是编译过程的第一个阶段.这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构 ...

  2. Oracle SQL tuning 步骤

    Oracle SQL tuning 步骤 SQL是的全称是Structured Query Language(结构化查询语言).SQL是一个在80年代中期被使用的工业标准数据库查询语言.不要把SQL语 ...

  3. Oracle SQL语句执行过程

    前言 QQ群讨论的时候有人遇到这样的问题:where子句中无法访问Oracle自定义的字段别名.这篇 博客就是就这一问题做一个探讨,并发散下思维,谈谈SQL语句的执行顺序问题. 问题呈现 直接给出SQ ...

  4. Oracle SQL优化[转]

    Oracle SQL优化 1. 选用适合的ORACLE优化器 ORACLE的优化器共有3种: a. RULE (基于规则) b. COST (基于成本) c. CHOOSE (选择性) 设置缺省的优化 ...

  5. Oracle SQL高级编程——分析函数(窗口函数)全面讲解

    Oracle SQL高级编程--分析函数(窗口函数)全面讲解 注:本文来源于:<Oracle SQL高级编程--分析函数(窗口函数)全面讲解> 概述 分析函数是以一定的方法在一个与当前行相 ...

  6. 《精通Oracle SQL(第2版) 》

    <精通Oracle SQL(第2版) > 基本信息 作者: (美)Karen Morton    Kerry Osborne    Robyn Sands    Riyaj Shamsud ...

  7. Oracle SQL性能优化技巧大总结

    http://wenku.baidu.com/link?url=liS0_3fAyX2uXF5MAEQxMOj3YIY4UCcQM4gPfPzHfFcHBXuJTE8rANrwu6GXwdzbmvdV ...

  8. oracle sql 优化大全

    转自: http://panshaobinsb.iteye.com/blog/1718233 http://yulimeander.blog.sohu.com/115850824.html 最近遇到了 ...

  9. 7.26实习培训日志-Oracle SQL(二)

    Oracle SQL(二) 条件表达式 CASE 语句 或者DECODE 函数,两者均可实现 IF-THEN-ELSE 的逻辑,相比较而言,DECODE 更加简洁 SELECT last_name , ...

随机推荐

  1. MediaRecorder录像那些事

    最近在做一个项目需要运用到MediaRecorder的API,之前都没接触过这部分,开始着手弄的时候各种各样的问题,真是让人崩溃呀! 最后通过网上的资料和大神的指点,当然也有自己几天坚持不懈的努力,终 ...

  2. C#用GDI+解析Json文件绘制Chart

    using System.Collections.Generic; namespace Chart { public class Program { static void Main(string[] ...

  3. Quartz.Net分布式运用

    Quartz.Net的集群部署详解 标签(空格分隔): Quartz.Net Job 最近工作上要用Job,公司的job有些不满足个人的使用,于是就想自己搞一个Job站练练手,网上看了一下,发现Qua ...

  4. Gazebo学习随记3 图形界面的使用

    直接写模型的SDF文件实在是太反人类啦! 可以在gazebo图形界面中设置好模型的链接(碰撞外观惯性),关节等等参数-然后生成SDF文件

  5. jmeter:dubbo接口测试

    最近工作中接到一个需求,需要对一个MQ消息队列进行性能测试,测试其消费能力,开发提供了一个dubbo服务来供我调用发送消息. 这篇博客,介绍下如何利用jmeter来测试dubbo接口,并进行性能测试. ...

  6. JavaFx 实现画图工具

    制作一款类似于Windows画图工具程序 功能需求: (1)在画布上绘制直线.曲线.矩形.椭圆等图形 (2)实现输入文字,橡皮擦 (3)可以绘制填充图形以及设置画笔的颜色和粗细 (4)实现撤销操作.保 ...

  7. P4559 [JSOI2018]列队

    \(\color{#0066ff}{ 题目描述 }\) 作为一名大学生,九条可怜在去年参加了她人生中的最后一次军训. 军训中的一个重要项目是练习列队,为了训练学生,教官给每一个学生分配了一个休息位置. ...

  8. Flume启动报错[ERROR - org.apache.flume.sink.hdfs. Hit max consecutive under-replication rotations (30); will not continue rolling files under this path due to under-replication解决办法(图文详解)

    前期博客 Flume自定义拦截器(Interceptors)或自带拦截器时的一些经验技巧总结(图文详解)   问题详情 -- ::, (SinkRunner-PollingRunner-Default ...

  9. 谁能赢呢? BZOJ 2463

    题目描述 小明和小红经常玩一个博弈游戏.给定一个n×n的棋盘,一个石头被放在棋盘的左上角.他们轮流移动石头.每一回合,选手只能把石头向上,下,左,右四个方向移动一格,并且要求移动到的格子之前不能被访问 ...

  10. Django 06 Django模型基础1(ORM简介、数据库连接配置、模型的创建与映射、数据的增删改查)

    Django 06 Django模型基础1(ORM简介.数据库连接配置.模型的创建与映射.数据的增删改查) 一.ORM系统 #django模型映射关系 #模型类-----数据表 #类属性-----表字 ...