零息票收益率曲線

零息票債券是指低于債券面值價格發(fā)行剩胁,債券發(fā)行人不需要給債券持有人支付利息诉植,只用在債券到期日支付給債券持有人債券面值金額的一類債券。本模型研究如何根據選擇的數據生成息票收益率曲線昵观。
數據如圖:


表格數據

一.收益率計算規(guī)則

復利計算

1.無年息票的計算:零息票年收益率YTM=YTM=(面值/價格)^1/期限-1

r1 = pow(100/97.5,1/0.25)-1
r2 = pow(100/94.5,1/0.5)-1
r3 = pow(100/90,1/1)-1
print('第0.25年年息票收益率:',round(r1,5))
print('第0.5年年息票收益率:',round(r2,5))
print('第1年年息票收益率:',round(r3,5))

2.每半年付息一次的有年息票的收益率YTM:
超過一年期的零息票年收益率YTM=(面值/價格)開期限n的次方根減1
零息票年收益率=[(年息票/2+面值)/(債券價格-年息票/2*(前期價格/面值))^1/期限]-1

# 有年息票的計算:
# 1.5年:96=4*e^(-r0.5*0.5)+4*e^(-r1*1)+104*e^(-r1.5*1.5)
#  r1.5=log(104/(96-4[e^(-r0.5*0.5)+e^(-r1*1)]))/1.5=0.1068
# 簡化[e^(-r0.5*0.5)+e^(-r1*1)]得到:
# r1.5=[log(104/(96-4*(94.5/100+90/100))]/1.5    連續(xù)復利的算法
# pow(104/((96-(90+94.5)/100*4)),2/3)-1   #復利的算法
rate2 = math.pow(100 / 84.99, float(1) / float(3))-1
print(rate2)
r4 = pow(104/((96-(90+94.5)/100*4)),2/3)-1#pow((104/88.604),2/3)
print('第1.5年年息票收益率:',round(r4,5))

r5 = pow(106/(101.6-(1.849*6+88.604/104*6)),1/2)-1#np.log(106/85.394)/2
print('第2年年息票收益率:',round(r5,5))

3.表中有數據就需要根據給定的數據來計算晾腔,表中沒有數據就需要用到線性插值


#線性插值
#第0.75年年息票收益率在0.5年和1年之間插值:
r6 = (r2+r3)/2
print('第0.75年年息票收益率:',round(r6,5))
#第1.25年年息票收益率在1年和1.5年之間插值:
r7 = (r3+r4)/2
print('第1.25年年息票收益率:',round(r7,5))
#第1.75年年息票收益率:
r8 = (r4+r5)/2
print('第1.75年年息票收益率:',round(r8,5))
#第2.25年年息票收益率:
r9 = 2(r5)/3 +(r'第2.75年年息票收益率')/3
print('第2.25年年息票收益率:',round(r9,5))

二.息票收益率曲線計算的完整代碼

input.csv
import pandas as pd 
import numpy as np
df = pd.read_csv("input.csv")
bondsCount = df.shape[0]

dicE4Calc = {}  #定義一個空的價格比計算表。價格/面值
dicResult = {}  #定義一個空的結果表

#定義一個價格合計啊犬,根據這個合計來進行迭代計算
def getPreSum(pCoupon, targetTerm, startTerm):  
    #前期價格合計
    sum = 0
    p = startTerm
    while (p < targetTerm):   #要小于目標的期限
        sum += dicE4Calc[str(p)] * pCoupon
        p += Period  #期限以0.5遞增
    return sum

#定義線性插值法計算灼擂,利用前后兩期數據可以求出中間的值
def LinearInterpolation(pCoupon, targetTerm, interval):
#線性插值法利用中位數求利率
    sum = 0
    p = interval
    while p < targetTerm:
        if str(p) not in dicResult:   #結果表中沒有的數據,left為前面一期椒惨,right為后面一期
            r_Left = str(p - interval)
            r_Right = str(p + interval)
            if r_Left in dicResult and r_Right in dicResult:   #結果表中有前后的數據就用插值法計算
                r = (dicResult[r_Left] + dicResult[r_Right]) / 2
            elif r_Left in dicResult and r_Right not in dicResult:
                r_Left2 = str(p - interval - interval)   #left為前2期
                r = dicResult[r_Left2] + (dicResult[r_Left] - dicResult[r_Left2]) / (interval) * (p - float(r_Left2))
            dicResult[str(p)] = r
            dicE4Calc[str(p)] = pow(math.e, -r * p)   #e的(-r*p)次方
        p += interval

Period = 1 / df['CouponFrequency'].max()  #付息頻率步長為0.5
df['Coupon']=df['Coupon'].fillna(0)
for i in range(bondsCount):
    FaceValue = df.loc[i, 'FaceValue']
    Price = df.loc[i, 'Price']
    Term = df.loc[i, 'Term_Y']
    Coupon = df.loc[i, 'Coupon']
    CouponFrequency = df.loc[i, 'CouponFrequency']
    YTM = 0   
    e4Calc = 0
    #計算有年息和無年息的收益率
    if Coupon == 0:
        e4Calc = Price / FaceValue   #價格/面值
        YTM = pow(FaceValue / Price,1/ Term) -1  #YTM=(面值/價格)^1/期限-1
    else:
        PeriodCoupon = Coupon * Period     ##年息票的0.5
        if Term % Period == 0:  #從0.5年開始
            LinearInterpolation(PeriodCoupon, Term, Period)
            e4Calc = (Price - getPreSum(PeriodCoupon, Term, Period)) / (FaceValue + PeriodCoupon)
        else:  #不是從0.5開始缤至,需要在起始日期以0.5年遞增
           LinearInterpolation(PeriodCoupon, Term, Term % Period)
            e4Calc = (Price - getPreSum(PeriodCoupon, Term, Term % Period)) / (FaceValue + PeriodCoupon)
        YTM = pow(1 / e4Calc,1/ Term) - 1

    dicE4Calc[str(Term)] = e4Calc
    dicResult[str(Term)] = round(YTM,6)

sorted_dicResult = sorted(dicResult.items(),key =operator.itemgetter(0))
print(sorted_dicResult)
Term = [i[0] for i in sorted_dicResult ]
Yield = [i[1] for i in sorted_dicResult ]

#數據輸出為DataFrame
data={"Term":Term,"Yield":Yield}
columns=['Term','Yield']
df=pd.DataFrame(data=data,columns=columns)
df['TermBase']='Y'
df = df.set_index("TermBase")
print(df)

#可視化展示
x = Term
y = Yield
plt.plot(x,y)
plt.xlabel('CouponFrequency')
plt.ylabel('YTM')
plt.title('Zero coupon yield curve')
plt.show()
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市康谆,隨后出現的幾起案子领斥,更是在濱河造成了極大的恐慌,老刑警劉巖沃暗,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件月洛,死亡現場離奇詭異,居然都是意外死亡孽锥,警方通過查閱死者的電腦和手機嚼黔,發(fā)現死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惜辑,“玉大人唬涧,你說我怎么就攤上這事∈⒊牛” “怎么了碎节?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長抵卫。 經常有香客問我狮荔,道長胎撇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任殖氏,我火速辦了婚禮晚树,結果婚禮上,老公的妹妹穿的比我還像新娘雅采。我一直安慰自己爵憎,他們只是感情好,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布总滩。 她就那樣靜靜地躺著纲堵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪闰渔。 梳的紋絲不亂的頭發(fā)上席函,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機與錄音冈涧,去河邊找鬼茂附。 笑死,一個胖子當著我的面吹牛督弓,可吹牛的內容都是我干的营曼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼愚隧,長吁一口氣:“原來是場噩夢啊……” “哼蒂阱!你這毒婦竟也來了?” 一聲冷哼從身側響起狂塘,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤录煤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后荞胡,有當地人在樹林里發(fā)現了一具尸體妈踊,經...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年泪漂,在試婚紗的時候發(fā)現自己被綠了廊营。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡萝勤,死狀恐怖露筒,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情敌卓,我是刑警寧澤邀窃,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響瞬捕,放射性物質發(fā)生泄漏。R本人自食惡果不足惜舵抹,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一肪虎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惧蛹,春花似錦扇救、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至靠娱,卻和暖如春沧烈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背像云。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工锌雀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人迅诬。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓腋逆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親侈贷。 傳聞我的和親對象是個殘疾皇子惩歉,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內容