最近在计算基金内部收益率的时候首先选择的是用纯python编写的sympy科学计算库,sympy在计算常微分方程,偏微分方程,一般线性方程组以及取微分、积分、极限等方面依靠其强大的符号体系游刃有余,并且编程语法更简单易懂,但是当用其求解高阶非线性方程的时候就暴露出python运行速度慢的短板,而在求解基金内部收益率的时候往往样本区间数据量很多,比如本文接下来将要采用的这支基金的数据就有80期。(其实我之前写完代码点击运行之后就去睡觉了,第二天起来仍然没有算出结果,可以说python面对这种问题从来不耽误人睡觉休息)
  其实python的numpy库已经内置了内部收益率计算函数,可以直接调用numpy.irr([NCF],round(n))。(就不要追问我写这篇博客的意义在哪里了!)接下来本文将会展示调用scipy.optimize最优化函数求内部收益率的高阶非线性方程的数值解。
  开始之前,需要介绍一下基金内部收益率(Internal Rate of Return, IRR)的计算方法,基金内部收益率的计算需要用到基金期末、期初的总净值(Total Net Asset, TNA)和各期现金流(Net Cash Flow, NCF),其计算公式如下:
TNA0(1+IRR)T+∑t=1TNCFt(1+IRR)(T−t)=TNAT(1)TNA_0{(1+IRR)^T}+\sum_{t=1}^TNCF_t{(1+IRR)^{(T-t)}}=TNA_T \tag{1}TNA0​(1+IRR)T+t=1∑T​NCFt​(1+IRR)(T−t)=TNAT​(1)
  其中NCFtNCF_tNCFt​的计算为:
NCFt=TNAt−TNAt−1(1+Rt)(2)NCF_t=TNA_t-TNA_{t-1}(1+R_t)\tag{2}NCFt​=TNAt​−TNAt−1​(1+Rt​)(2)
  这里的RtR_tRt​表示的是基金第ttt期的收益率,TNA0TNA_0TNA0​和TNATTNA_TTNAT​分别为基金期初的总资产净值和期末的总资产净值。可见利用python的求解内部收益率IRRIRRIRR速度主要就取决于TTT的大小。
  首先,展示本文所使用到的数据,数据已经上传到百度云盘(提取码:6whe)。

  导入数据,这里所使用的是基金月度的单月回报RRR和单月总净值TNATNATNA。

>>>import pandas as pd
...Fund=pd.read_csv("C:\\Users\\psj\\Desktop\\Fund.csv",index_col="Date",header=0)
...Fund.index=pd.to_datetime(Fund.index)
>>>print(Fund.tail())R          TNA
Date
2019-07-31  0.029619  14488.49821
2019-08-30  0.001370  14508.34547
2019-09-30  0.024624  17798.16869
2019-10-31 -0.006676  17679.35582
2019-11-29 -0.012097  17465.49264

  这里的T=80T=80T=80,当然如果有好奇用sympy求解内部收益率到底是什么情况的小伙伴,在本文末尾我将展示用sympy计算内部收益率的代码。
   按照公式(2)计算出基金各期的净现金流NCFtNCF_tNCFt​

NCF=Fund.TNA-Fund.TNA.shift(1)*(1+Fund.R)
...print(NCF.head())
Date
2013-03-29             NaN
2013-04-26        0.000013
2013-05-31       -0.000081
2013-06-28       -0.000014
2013-07-31   -59842.034588
dtype: float64

  Python的科学计算库scipy的优化器optimize中提供了基于hybrd和hybrj算法的内置函数fsolve,可以求高阶的非线性方程的数值解。这里需要设定求解内部收益率的方程,其实就是基于本文的数据按照公式(1)编写函数

def func(x):function=Fund.TNA[0]*(1+x)**(len(NCF)-1)-Fund.TNA[-1]#len(NCF)包括了NaN空值for i in range(1,len(NCF)):   #由于NCF的第一期值为空function+=NCF[i]*(1+x)**(len(NCF)-i-1) #i只能取到(len(NCF)-1)return function

  fsolve(func,x0)主要有两个参数,func为被求解方程,方程的等号右边为0,左边就是上面所定义的函数;x0为方程func的初始值,以列表的新式输入,返回值也为列表形式。将初始值设定为0,求解最终得到基金的内部收益率为-0.00419273。

from scipy.optimize import fsolve
root=fsolve(func,[0]) # x的初始值设为0,需要用list的形式输入
>>>print(root)
[-0.00419273]

  由于fsolve在优化过程中采用迭代的方式求解非线性方程的数值解,所以我们只得到了一个解,熟悉一元二次抛物线方程的小伙伴都知道这类方程的未知数xxx最高次有几次就会有多少个解,如果是严格按照这种方法求解,我们应该得到80个解,当然其中包括了复数解。求出这80个解其实是没有必要的,而纯python编写的科学计算库sympy就可以做到,先附上代码

import pandas as pd
import sympy as sy
Fund=pd.read_csv("C:\\Users\\psj\\Desktop\\Fund.csv",index_col="Date",header=0)
Fund.index=pd.to_datetime(Fund.index)
NCF=Fund.TNA-Fund.TNA.shift(1)*(1+Fund.R)
x=sy.symbols("x")
f=Fund.TNA[0]*(1+x)**(len(NCF)-1)-Fund.TNA[-1]
for j in range(1,len(NCF)):f=f+NCF[j]*(1+x)**(len(NCF)-j-1)
result=sy.solve(f,x)
print(result)

  要得到运行结果可能是很久之后的事情了,当然也不是本人写的代码有bug算不出来,当我们把TTT设定为5时,只需要一段小小的等待就能得到方程的全部5个解。

Fund=Fund.iloc[:6,:]
NCF=Fund.TNA-Fund.TNA.shift(1)*(1+Fund.R)
x=sy.symbols("x")
f=Fund.TNA[0]*(1+x)**(len(NCF)-1)-Fund.TNA[-1]
for j in range(1,len(NCF)):f=f+NCF[j]*(1+x)**(len(NCF)-j-1)
result=sy.solve(f,x)
>>>print(result)
[-0.00685850972132560, -1.62439354544479 - 0.206726589366808*I, -1.62439354544479 + 0.206726589366808*I, -0.872177199759201 - 0.925545835792086*I, -0.872177199759201 + 0.925545835792086*I]

  最后,我们可以发现采用sympy.solve()求解得到的内部收益率只有第一个是实数,其余全部为复数,这在我之前的实践当中也得到了反复验证,所以可见采用数值计算是完全合理科学高效的。

用python计算基金内部收益率-基于scipy科学计算库的数值解相关推荐

  1. python 三维凸包_浅尝则止 - SciPy科学计算 in Python

    本文节选自作者的<Python编程基础及应用>视频教程.Python编程基础及应用_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili​www.bilibili.com 21. 浅尝则止 ...

  2. 浅尝则止 - SciPy科学计算

    21. 浅尝则止 - SciPy科学计算 SciPy以NumPy为基础,提供了众多数学.科学.工程计算用的模块,包括但不限于:线性代数.常微分方程求解.信号处理.图像处理.稀疏矩阵处理. 本章适合那些 ...

  3. Python Scipy 科学计算库

    Python机器学习及分析工具:Scipy篇 原文:https://www.jianshu.com/p/6c742912047f   Scipy是一个用于数学.科学.工程领域的常用软件包,可以处理插值 ...

  4. scipy是python下的什么_Python下科学计算包numpy和SciPy的安装

    Python下大多数工具包的安装都很简单,只需要执行 "python setup.py install"命令即可.然而,由于SciPy和numpy这两个科学计算包的依赖关系较多,安 ...

  5. python中符号计算输出数学_Python科学计算与数据处理—符号运算库.doc

    Python 科学计算与数据处理 - 符号运算库 符号运算库目录从示例开始欧拉恒等式球体体积数学表达 式符号数值运算符和函数符号运算表达式转换和简化方程目录微分 方程积分其他函数符号运算库. 它的目标 ...

  6. Python编程及应用--数据分析与科学计算可视化培训班

    附件: 一.[培训对象] 各高等院校大数据相关学科.计算机.软件.数字媒体.信息管理.统计.电子商务等专业教师,在读高年级本科生及研究生.从事计算机.云计算.大数据.互联网等相关领域项目的科研院所的项 ...

  7. python科学计算模块有什么_Python科学计算—numpy模块总结(1)

    作为一个本科学数学专业,目前研究非线性物理领域的研究僧.用什么软件进行纯科学计算好,Fortran永远是第一位的:matlab虽然很强大,可以很容易的处理大量的大矩阵,但是求解我们的模型(有时可能是几 ...

  8. python科学计算包与matlab_做科学计算用Python还是MATLAB?

    网友解答: 用Python,我给出用Python的几点个人见解: 1.2017人工智能(其中也包括科学计算)也火了一年了,Python的使用人数大大上升,大势所趋. 2.Python的开发效率要远远高 ...

  9. python 科学计算设计_Python程序设计与科学计算

    章Python概述1 1.1Python语言发展史1 1.2Python语言特点2 1.3Python语言主要应用领域4 1.4本章练习5 第2章开启Python之旅6 2.1部署Python环境6 ...

  10. python科学计算是什么意思_Python科学计算和数据分析(NumPy详细介绍)

    本文介绍的科学计算.数据分析必备基础知识. 本文全文约2600字,阅读时间约15分钟,请你耐心观看. 本文使用的开发环境是Python3.8,Numpy版本是1.19,本文的例子全部经过验证,你可以直 ...

最新文章

  1. 《跃迁 从技术到管理的硅谷路径》读后感
  2. linux设备驱动学习(一)——简单的helloworld模块
  3. P5591 小猪佩奇学数学(单位根反演)
  4. Android ToolBar 使用完全解析
  5. PyQt5 QTreeWidget更改item项前的展开折叠三角图标
  6. oracle 10046详解,Oracle 10046事件详解
  7. db2 语句包括不必要的列表_列表推导和生成器表达式的滥用
  8. 20191001:String,StringBuffer,StringBuilder类异同辨析
  9. centos7 安装 php7
  10. 【LeetCode】【数组】题号:628,三个数组成的乘积最大
  11. 基于ssm整合的web考勤管理系统
  12. 测试驱动开发(TDD)实践与技巧
  13. python turtle 画蜡笔小新_蜡笔小新有几集?作者到底怎么死的啊?
  14. 基于PHP+MySQL的图书馆图书借阅系统
  15. hangfire支持mysql_abp 使用 hangfire结合mysql
  16. hyper用vnc连接,hyper用vnc连接该如何设置vnc
  17. java web 开发问题总结 1 原创-胡志广
  18. Android Studio开发工具的设置
  19. 字符串日期 转换成 需要的格式的 字符串日期(超强)
  20. Spring Boot+JSP

热门文章

  1. 朗兰兹纲领:关于数学大一统的伟大构想
  2. 说说Stack Overflow和Quora
  3. NLP之文本分类方法之基础知识
  4. 叩丁狼学院Java入门 项目代码
  5. Qt FlowLayout升级版
  6. 对于女生来说,软件测试和前端,学哪一个更好啊
  7. 编写一个520表白网站并发布Web教程
  8. 如何确定直流电机驱动的 PWM 频率
  9. [Qt] 基于Tcp协议的聊天室实现(Chat Room 局域网通信)
  10. python求小于n的最大素数_小于或等于n的素数