Python 解决PV和“PV”之间的复利问题;“总和”;FV?
鉴于以下方面的投入:Python 解决PV和“PV”之间的复利问题;“总和”;FV?,python,math,quantitative-finance,Python,Math,Quantitative Finance,鉴于以下方面的投入: present value = 11, SUMMATIONS of future values that = 126, and n = 7 (periods of change) 我怎样才能解出一个链的速率,这个速率会产生一个和成FV的链?这与仅仅求解11到126之间的回报率不同。这是对收益率的求解,允许总和为126。我一直在尝试不同的想法,寻找内部收益率和净现值函数,但求和方面让我感到困惑 如果求和方面不清楚,如果我假设比率为1.1,那么PV=11将变成这样的列表(这几
present value = 11, SUMMATIONS of future values that = 126, and n = 7 (periods of change)
我怎样才能解出一个链的速率,这个速率会产生一个和成FV的链?这与仅仅求解11到126之间的回报率不同。这是对收益率的求解,允许总和为126。我一直在尝试不同的想法,寻找内部收益率和净现值函数,但求和方面让我感到困惑
如果求和方面不清楚,如果我假设比率为1.1,那么PV=11将变成这样的列表(这几乎等于FV 126),我如何才能只知道n,求和FV和PV来求解r
11
12.1
13.31
14.641
16.1051
17.71561
19.487171
21.4358881
总计=125.7947691
多谢各位
编辑:
我试图创建一种迭代器,但它在第一个循环后挂起
for r in (1.01,1.02,1.03,1.04,1.05,1.06,1.07,1.08,1.09,1.10,1.11,1.12):
print r
test = round(11* (1-r**8) / (1 - r),0)
print test
while True:
if round(126,0) == round(11* (1-r**8) / (1 - r),0):
answer = r
break
else:
pass
编辑2:
IV = float(11)
SV = float(126)
N = 8
# sum of a geometric series: (SV = IV * (1 - r^n) / (1 - r )
# r^n - (SV/PV)*r + ((SV - IV)/IV) = 0
# long form polynomial to be solved, with an n of 3 for example:
# 1r^n + 0r^n + 0r^n + -(SV/PV)r + ((SV - IV)/IV)
# each polynomial coefficient can go into numpy.roots to solve
# for the r that solves for the abcd * R = 0 above.
import numpy
array = numpy.roots([1.,0.,0.,0.,0.,0.,0.,(-SV)/IV,(SV-IV)/IV])
for i in array:
if i > 1:
a = str(i)
b = a.split("+")
answer = float(b[0])
print answer
我收到一个ValueError,字符串“1.10044876702”无法转换为float。有什么想法吗
解决方案:i.real得到了它的真实部分。无需拆分或字符串转换,即:
for i in array:
if i > 1:
a = i.real
answer = float(a)
print answer
潜入
126 = 11 * (1 - r**8) / (1 - r)
我们需要为r
解决的问题。重新安排后,
r**8 - (126/11)*r + (115/11) = 0
然后使用NumPy
import numpy as np
np.roots([1., 0., 0., 0., 0., 0., 0., -126./11, 115./11])
给予
其中前六个根是虚构的,而最后一个根无效(在原始方程中给出了一个div-by-0),因此唯一可用的答案是r=1.10044877
编辑:
根据,np.root
需要一个类似数组的对象(也称为列表),其中包含多项式系数。因此,上述参数可以理解为1.0*r^8+0.*r^7+0.*r^6+0.*r^5+0.*r^4+0.*r^3+0.*r^2+-126./11*r+115./11
,这是要求解的多项式
你的迭代解算器相当粗糙;它会给你一个大概的答案,但计算时间是与期望的准确度成指数关系的。我们可以做得更好
八阶方程没有通用的解析解,所以需要一些数值方法
如果你真的想从头开始编写自己的解算器,最简单的方法是牛顿-拉斐逊法-从猜测开始,然后迭代计算函数,用误差除以一阶导数抵消猜测,希望收敛到根上-希望你的初始猜测是好的,方程有真正的根
如果你更关心快速得到好的答案,np.root
是很难打败的-它计算伴随矩阵的特征向量,以同时找到所有根,包括实根和复根
编辑2:
您的迭代解算器挂起,因为您的while True
子句-r
不会在循环中更改,因此您永远不会中断
。另外,else:pass
是多余的,可以删除
经过一段时间的重新安排,您的代码变成:
import numpy as np
def iterative_test(rng, fn, goal):
return min(rng, key=lambda x: abs(goal - fn(x)))
rng = np.arange(1.01, 1.20, 0.01)
fn = lambda x: 11. * (1. - x**8) / (1. - x)
goal = 126.
sol = iterative_test(rng, fn, goal)
print('Solution: {} -> {}'.format(sol, fn(sol)))
导致
Solution: 1.1 -> 125.7947691
编辑3:
上一个解决方案看起来要好得多,但必须记住,多项式的阶数(因此传递给np.roots的数组长度)随着周期数的变化而变化
import numpy as np
def find_rate(present_value, final_sum, periods):
"""
Given the initial value, sum, and number of periods in
a geometric series, solve for the rate of growth.
"""
# The formula for the sum of a geometric series is
# final_sum = sum_i[0..periods](present_value * rate**i)
# which can be reduced to
# final_sum = present_value * (1 - rate**(periods+1) / (1 - rate)
# and then rearranged as
# rate**(periods+1) - (final_sum / present_value)*rate + (final_sum / present_value - 1) = 0
# Build the polynomial
poly = [0.] * (periods + 2)
poly[ 0] = 1.
poly[-2] = -1. * final_sum / present_value
poly[-1] = 1. * final_sum / present_value - 1.
# Find the roots
roots = np.roots(poly)
# Discard unusable roots
roots = [rt for rt in roots if rt.imag == 0. and rt.real != 1.]
# Should be zero or one roots left
if len(roots):
return roots[0].real
else:
raise ValueError('no solution found')
def main():
pv, fs, p = 11., 126., 7
print('Solution for present_value = {}, final_sum = {}, periods = {}:'.format(pv, fs, p))
print('rate = {}'.format(find_rate(pv, fs, p)))
if __name__=="__main__":
main()
这将产生:
Solution for present_value = 11.0, final_sum = 126.0, periods = 7:
rate = 1.10044876702
解多项式根太麻烦了。此计算通常使用求解器进行,如直接应用于指数公式的牛顿法。也适用于分数持续时间
例如,谢谢你帮我弄清楚我在想什么类型的数学概念!我记不起来了,但我要找的是“几何级数之和”。你能告诉我你对numpy.root的输入是什么吗?我知道需要取1/n根,但不确定numpy.roots参数的输入从何而来。我尝试装配一个迭代器:对于r in(1.01,1.02,1.03,1.04,1.05,1.06,1.07,1.08,1.09,1.10,1.11,1.12):print r test=round(11*(1-r8)/(1-r),0)print test而True:if round(126,0)==round(11*(1-r8)/(1-r),0:answer=r break-else:pass,但在第一次值测试时它就挂起了…谢谢你督促我写一个更好的解决方案。我确实觉得我离这更近了(见上面的编辑2)。知道如何绕过字符串“1.10044876702”无法转换为float的ValueError吗?非常感谢。
Solution for present_value = 11.0, final_sum = 126.0, periods = 7:
rate = 1.10044876702