ORACLE SQL 实现IRR的计算
一、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轴交点的横坐标
![](https://gss3.bdstatic.com/-Po3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D113/sign=4759ab76e9f81a4c2232e8c8e42b6029/adaf2edda3cc7cd9c67a2ddb3b01213fb80e9158.jpg)
![](https://gss2.bdstatic.com/-fo3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D71/sign=43308263f1deb48fff69a3dff11f38a8/c995d143ad4bd113cd3aaf3058afa40f4bfb0538.jpg)
![](https://gss3.bdstatic.com/7Po3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D59/sign=a638fa186259252da7171d0d359bf9a9/810a19d8bc3eb1354c3bafb9a41ea8d3fd1f4437.jpg)
![](https://gss2.bdstatic.com/9fo3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D113/sign=265ea26696eef01f49141cc4d3ff99e0/71cf3bc79f3df8dc43d19493cf11728b461028c7.jpg)
![](https://gss2.bdstatic.com/-fo3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D15/sign=4e7e68110bf79052eb1f433b0df3edbc/5d6034a85edf8db1a5c967660b23dd54574e74c8.jpg)
![](https://gss0.bdstatic.com/94o3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D129/sign=763132a7087b020808c93be35bd9f25f/6a63f6246b600c339f73c4ca184c510fd9f9a1ad.jpg)
![](https://gss2.bdstatic.com/-fo3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D33/sign=670fbe609a22720e7fcee4f97acbeb58/5d6034a85edf8db1a5eb67660b23dd54574e74ee.jpg)
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) loopfValue := 0.0;fDerivative := 0.0;for k in 1..p_amount_array.count loopfValue :=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) thenreturn x1;end if;x0 := x1;i_num := i_num+1;end loop; return (0.0/0.0);EXCEPTIONWHEN OTHERS THENreturn rtn_err; END IRR_ZEN;
五、关于函数的调用:
方法一,将现金流组成字符串,然后用函数拆解字符串。具体实现方式是
function IRR(in_varray in varchar2) return numberis v_irr number;v_amount_array typ_cashflow_array;beginv_amount_array :=typ_cashflow_array();declarev_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 loopv_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://www.cnblogs.com/Alex-Zeng/p/9334582.html
ORACLE SQL 实现IRR的计算相关推荐
- Oracle中使用SQL根据出生日期精确计算年龄
Oracle中使用SQL根据出生日期精确计算年龄 提示:以下是本篇文章正文内容,下面案例可供参考 代码如下(示例): select XM,CSNY as 出生日期,-- extract函数用于提取日期 ...
- oracle发票验证,通过使用Oracle SQL脚本进行计算(总发票)的多个表的更新记录...
我有一个SERVICE表,该表存储一个表中的服务数量,然后链接到连接到INVOICE的LINE表.通过使用Oracle SQL脚本进行计算(总发票)的多个表的更新记录 我想要创建一个触发器,根据SER ...
- Oracle SQL高级编程——分析函数(窗口函数)全面讲解
Oracle SQL高级编程--分析函数(窗口函数)全面讲解 注:本文来源于:<Oracle SQL高级编程--分析函数(窗口函数)全面讲解> 概述 分析函数是以一定的方法在一个与当前行相 ...
- oracle sql 执行计划分析_《真正读懂Oracle SQL执行计划》
maclean_0071人评论1235人阅读2013-10-25 15:18:12 [视频教学:性能优化]Maclean Liu的Oracle性能优化讲座第一回<真正读懂Oracle SQL执行 ...
- Oracle SQL语句执行过程
前言 QQ群讨论的时候有人遇到这样的问题:where子句中无法访问Oracle自定义的字段别名.这篇 博客就是就这一问题做一个探讨,并发散下思维,谈谈SQL语句的执行顺序问题. 问题呈现 直接给出SQ ...
- Oracle SQL性能优化的40条军规
Oracle SQL性能优化的40条军规 1. SQL语句执行步骤 语法分析> 语义分析> 视图转换 >表达式转换> 选择优化器 >选择连接方式 >选择连接顺序 & ...
- Oracle SQL性能优化40条,值得收藏
1. SQL语句执行步骤 语法分析> 语义分析> 视图转换 >表达式转换> 选择优化器 >选择连接方式 >选择连接顺序 >选择数据的搜索路径 >运行&q ...
- Oracle SQL 基础要点
Oracle SQL 基础要点 本文是学习<程序员的SQL金典>时的读书摘要,记录一些自己不太熟悉或者很重要的知识点.方便后期对照复习. 1.各种主流数据库的优缺点比较 - DB2由IBM ...
- Oracle SQL开发考试试题
Oracle SQL开发考试试题,主要围绕Oracle SQL的基础开发,以及SQL优化的相关知识点,主要的考点: (1) DML考点: (2) DDL考点: (3)SELECT考点 (4)子查询考点 ...
最新文章
- 关于spring service层的mybatis缓存问题,待解决
- 8天学通MongoDB——第二天 细说增删查改
- kafka实战最佳经验,阿里又现海王!某程序员同时约两个女生十一出游
- DiscuX END - 553 Envolope sender mismatch with header from..
- mysql sql乱码怎么解决_MYSQL数据库导入SQL文件出现乱码如何解决
- 苏区振兴下的赣州发展状况分析
- c语言汉字属于什么类型_你知道你的身体属于什么类型么?
- idea补全代码快捷键
- VMware10 安装centos6.7 设置NAT模式固定ip
- Java构造字符串算法题_LeetCode算法题-Repeated Substring Pattern(Java实现)
- 类创建几种java_Java创建对象的几种方式
- 非对称加密提交表单到PHP
- opencv java 人脸识别_Java OpenCV实现人脸识别过程详解
- 2013年最新热门软件分享第一季
- 计算机丢失cxcore100.dll,cxcore100.dll
- 2dpca matlab程序,simulink基于2DPCA的人脸识别
- picker插件 vue 移动端_基于 vue 的 picker 组件 vue-awesome-picker
- 编程计算1!+2!+3!+…+N!
- flowable中强制结束流程
- Three.js学习二——Three.js极简入门
热门文章
- 永久禁用Win10驱动程序强制签名
- 距离成为科技“爆款”,“眼动追踪”还有多远?
- 03、矢量图形查询工具(Symbol Unicode)
- OKR团队绩效管理学习1
- CSS使图片变模糊,亲测非常好用
- 放开那三国服务器维护中是什么意思,《放开那三国2》游戏11月25日更新维护公告...
- Pixhawk学习6.2——姿态解算
- ubuntu server 安装中文字库
- 备忘录莫名其妙的没了_苹果手机备忘录突然消失了该怎么办
- Wine完全使用完全指南(从初级到高级)