编程技术文章分享与教程

网站首页 > 技术文章 正文

使用Python计算可转债到期收益率 可转债到期价值公式

hmc789 2024-11-09 13:06:32 技术文章 2 ℃

可转债同时具有债券和期权两种属性。利用这种特点,采用适合的策略可以获得更加稳健的投资回报。可转债作为债券,持有人每年可以得到约定的利息;如果可转债到期赎回,持有人还可以按照到期赎回价赎回可转债。通过计算从当前时间至到期日的利息总和,我们就可以得出可转债的到期价值,并进一步计算出可转债的到期收益率。下面我们来看看如何计算可转债的到期价值和收益率。

首先,我们了解一下计算到期价值及收益率需要用到的几个参数。

发行起始日,到期日期:发行日也就是起息日,每年的付息日跟起息日的日期相同。大部分可转债的存续期限为6年(少量存续期为5年),则对应的发行起始日与到期日期之间的间隔时间为6年。

年利率:可转债每年支付的利息。例如,某只可转债的利率约定为:第一年0.30%、第二年0.50%、第三年0.80%、第四年1.60%、第五年2.50%、第六年3.00%

到期赎回价:在可转债的赎回条款中,会约定债券到期时以面值乘以x%的价格赎回债券(x>100)。例如,在某个可转债的赎回条款中写到:“公司将按债券面值的115%(含最后一期利息)的价格赎回全部未转股的可转债。”,那么该转债的到期赎回价格就是100x115%=115, 注意这个价格包含了当期的利息。

以上参数为不变参数,下面的参数则是随着投资发生变化。

当前价格:当前价格表示以当前价格买入的成本,需要以该成本为基准计算到期收益率。

买入时间:买入时间决定了当时所处的付息周期和未付利息。

好了,接下来我们看一下到期价值的计算。

from datetime import datetime,date

#年利率,最后一项rates[-1] 使用(到期赎回价格-100)作为最后一期总的利息。
rates = [0.3, 0.5, 0.8, 1.6, 2.5, 3]

#到期赎回价格
r_price = 115

#当前时间
today = datetime.now().date()

#到期时间
expires = date(2028,1,12)

#计算剩余年数
remained_years = (expires - today).days/365

#计算未付息期数
unpaid_years = int(0.999+remained_years)

#每期的利息税率,按照个人所得税20%计
tax = 0.2

#最后一期的税率;考虑到部分转债到期赎回时价超过100部分不扣税,所以这里税率设为0
tax2= 0

#计算到期价值:未付息年利率之和(除最后一年)税后+到期赎回价格(税后)
value_til_expire = sum(rates[-unpaid_years:-1])*(1-tax) + (100+(r_price-100)*(1-tax2))

print("剩余{:2.2f}年,未付期数{},到期价值:{:2.2f}".format(remained_years,unpaid_years,value_til_expire))

通过上述程序得到的到期价值的意义在于:当我们以低于到期价值买入可转债时,如果债券不违约,不发生回售,那么该投资至少是保本的。

接下来,我们计算到期年化收益率。

方法一:采用简单的算术平均来计算收益率,即总收益率除以剩余年数。

#买入的价格
price = 109.3

#到期收益率(年化)
ytm = (value_til_expire - price)/price/remained_years
print("到期年化收益率:{:2.2f}%".format(ytm*100))

上述代码是通过算数平均来计算的收益率。对于普通个人投资者来说,这个收益率已经比较直观体现了转债到期年化收益率。

方法二:该方法为更精确也更复杂,通过净现值(NPV)计算到期收益率。这里,我们使用了scipy.optimize中的neoton函数来计算到期年化收益率。

import scipy.optimize as optimize
import math

values = []


rates2 = [r*(1-tax) for r in rates]
rates2[-1] = (r_price-100)*(1-tax2)

n = int(remained_years+1)

#初始猜测值
guess = 0.05

#数组的每项存放每期的利率及以年为单位的剩余时间
for i in range(n):
    values.append((rates2[-1-i],remained_years-i))

ytm_func = lambda y: \
        sum([v[0]/math.pow(1+y,v[1]) for v in values]) + \
        100/math.pow(1+y,remained_years) - price

ytm2 = optimize.newton(ytm_func, guess)
print("到期年化收益率2:{:2.2f}%".format(ytm2*100))

通过实际运行我们可以发现,两种方法计算得出的收益率差别并不是很大, 第一种简单易理解,第二种更精确一些。在实际应用中,可将上述代码改写成函数,以便重复使用。

以上代码在Python 3.7运行通过。

Tags:

标签列表
最新留言