十月 6, 2009

hoamon's sandbox
hoamon
hoamon's sandbox is about »

tag cloud

» 在工程專案中,我們如何評定資金的機會成本!

當我們評估一投資方案或是生產方案是否實行時,就現金流量而言,我們可用 IRR(Internal rate of return) 來作評估。然在比較機會成本上,試問你該以什麼樣的利率作為訂定報酬率的依據,選定 5% 而不是 3% 的理由是什麼呢?

用銀行報價的存款利率可以嗎? 那用那一家呢? 台新銀行、國泰銀行還是台中銀行? 試問萬泰銀行的存款利率高還是國泰銀行的利率高?

請記住重點:利率就是資金的機會成本,也就是如果不接這個工程案,我們手頭上的資金可以有利息的收入,那麼如果接了工程案後,它的利潤就應該比利息的水準還高,否則我們就不應該去接此工程。當然,這是純以資金面的角度來看該不該投標,但有的時候考慮了機具、人員的沉沒成本後,不得不接一些達不到市場利率的工程來作。

而我們評估方案的標準應是以無風險利率來作評估較為合理。原因是無風險利率代表著貸放者鐵定可以回收本利,而其他比「無風險利率」高的利率都是隱藏著拿不回本金的風險。所以,比無風險利率高的部份,我們稱之為「risk premium 風險補貼(貼水)」,那是資金貸放者承受風險的報酬。所以我們常選用政府公債殖利率來當作無風險利率,因為政府如果還不出錢的話,它會直接印鈔票,保證本利和一毛不少。

而一個工程案少者一年,多者 10 年、 20 年,如此長天期的無風險利率又該去那裡找呢? 而且有時候,我們的工程預估是 17.5 年,那這時又怎麼辦呢?

所以我們要利用國內政府公債的交易資訊來求出一條「零息債券的殖利率曲線」。因為「零息債券」的殖利率才等於即期利率(也就是以當下時間點來推估資金的機會成本)。成果應如下圖:


  • 綠色線為零息債券殖利率曲線
  • 紅色線為附息債券殖利率曲線

「零息債券的殖利率曲線」作法請參考債券殖利率曲線計算。其中,因為我們的債券交易資訊都是附息債券的交易,所以我們須利用Macaulay duration調整法來消除息票效應,將附息債券轉成零息債券。

而一債券的殖利率計算方式請見如何計算債券殖利率

又如果你不會用數值方式來求方程式的根,你可以參考二分逼近法求債券殖利率

PS 如果你對本主題完全沒概念的話,請依下列順序閱讀之。

如何計算債券殖利率 > 二分逼近法求債券殖利率 > Macaulay duration調整法 > 債券殖利率曲線計算

六月 30, 2009

hoamon's sandbox
hoamon
hoamon's sandbox is about »

tag cloud

» FOClass: 債券殖利率曲線計算

前篇文章中,我們已可算出零息債券的殖利率,但如果要套用在實務上的應用中,我們必須將觀察到的各點作一迴歸函式,讓我們可以找到各天期的殖利率。

運用原理為 Cubic Spline 方法。假設債券的 Discount 因子為一個三次方程式:



而每張債券的現金流量再套入下方方程式:



可得到類似 3.3a + 1.2b + 5.5c = 30 的等式。像是代入前篇文章的九張債券可得如下式子:





透過 OLS(ordinary least square) 方法求出 a, b, c 的適當值後,再代入:



即可算出殖利率曲線。如下圖:


  • 綠色線為零息債券殖利率曲線
  • 紅色線為附息債券殖利率曲線
我們可以看到 20~30年期的殖利率下降的十分奇怪。原因是我們的觀察值債券的年期最大只有 20 年,所以這一條函式在預測 20~30 年期的數據應該是有問題。

相關的 Python 程式如下:
 1 class CubicSpline:
2 """ 使用最小平方和原則作三次方方程式的迴歸
3 """
4 def __init__(self):
5 self.PVs = array([])
6 self.X = array([])
7
8 def addBondData(self, PV=0, Ci=[], Ni=[]):
9 self.PV = PV < 0 and PV or -1*PV
10 if Ni[0] == 0:
11 self.PVs = append(self.PVs, -1*self.PV-Ci[0])
12 self.Ci = array(Ci[1:])
13 self.Ni = array([[1, t, t**2, t**3] for t in Ni[1:]])
14 else:
15 self.PVs = append(self.PVs, -1*self.PV)
16 self.Ci = array(Ci)
17 self.Ni = array([[1, t, t**2, t**3] for t in Ni])
18
19 self.dt = dot(self.Ci, self.Ni)
20 if len(self.X):
21 self.X = append(self.X, [self.dt[1:]], axis=0)
22 else:
23 self.X = array([self.dt[1:]])
24
25 self.PVs[-1] -= self.dt[0]
26
27 def runOLS(self):
28 self.X = matrix(self.X)
29 self.PVs = matrix(self.PVs).T
30 self.b = linalg.inv(self.X.T * self.X) * self.X.T * self.PVs
31 return self.b


五月 7, 2009

hoamon's sandbox
hoamon
hoamon's sandbox is about »

tag cloud

» FOClass: 零息債券殖利率計算

市場上,我們能觀察到的公債交易標的多半都是附息債券,而此附息債券因為有息票收入的關係,所以無法視為即期利率。在本文中,我們將利用存續期間(Macaulay duration)調整法來消除息票影響。

存續期限最先由 Macaulay(1938) 提出。依 Macaulay duration 之定義,存續期限相同的債券,不論 Coupon rate 為何,不論是附息或零息債券,皆視為有著相同「有效」到期期限 (effective maturities) 或「真正」到期期限(true term to maturities)之債券。

也可將存續期限視為回收本金時間。

由於債券市場之交易型態中,存續期限是買賣報價之重要依據,亦即在流動性與稅負等條件皆相同之情況下,市場上對一張附息債券與另一張有著相同存續期限之零息債券所要求的殖利率是相同的。

因而可透過此種定義來作期限調整,將各附息債券之殖利率與其存續期限之關係描繪出一條存續期限殖利率曲線 (yield to duration) ,以此當作零息債券殖利率曲線之估計值。

以下則是在 2009/4/16 所觀察的中央政府公債交易資訊:

||公債碼||交易價格||票面利率%||到期日     ||
||A93109||110.4412|| 3 ||2024/11/18 ||
||A94107||100.3904|| 1.63 ||2015/9/12 ||
||A95101||102.3168|| 1.75 ||2011/1/6 ||
||A95103||100.6188|| 1.75 ||2016/3/31 ||
||A96101||103.0834|| 1.88 ||2012/1/26 ||
||A97106||103.8367|| 2.13 ||2018/9/24 ||
||A98101||99.2679 || 0.875 ||2014/1/21 ||
||A98102||98.8824 || 2.125 ||2029/2/16 ||
||A98103||98.5211 || 1.375 ||2019/3/5 ||
首先利用二分逼近法求各債券殖利率 y,接下來代入下列公式:


  • ti: 期別
  • Ci: ti 期別的現金流量
  • B: 債券現值,也就是交易價格
  • D: 存續期間
  • y: 殖利率

再代入下列公式得到修正後的存續期間:

  • m: 為每幾個月配息一次
 1 class ModifiedDuration:
2 """ 存續期間 D 的公式定義如下:
3 D = \frac{\sum_{i=1}^{n} \frac{t_{i}C_{i}}{(1+y)^{t_{i}}}}{B}
4
5 再經殖利率 y 的修正後,得到 D^{*}
6
7 D^{*} = \frac{D}{1+\frac{y}{m}}
8 y: 為年化殖利率
9 m: 為每幾個月配息一次
10
11 """
12 def __init__(self, PV=0, Ci=[], Ni=[], yieldrate=0, coupon_duration=12):
13 self.PV = PV < 0 and -1*PV or PV
14 self.Ci = Ci
15 self.Ni = len(Ni) != 0 and Ni or range(len(Ci))
16 self.yieldrate = yieldrate
17 self.coupon_duration = coupon_duration
18
19 equations = []
20 for i, c in enumerate(Ci):
21 equations.append('%s*%s/(1+%s)**(%s)'%(self.Ni[i], c,
22 self.yieldrate, self.Ni[i]))
23 self.equation = ' + '.join(equations)
24 self.D = eval(self.equation) / self.PV
25 self.modified_duration = round(self.D/(1+
26 self.yieldrate/(self.coupon_duration/12)), 2)
最後,我們可以把附息債券的存續期間繪製出來如下圖,我們可以知道在相同存續期間下,該附息債券殖利率也就是零息債券殖利率:


  • 紅十字的 X 軸為附息債券的到期日
  • 綠三角的 X 軸為附息債券的存續期限
  • X 軸表期別
  • Y 軸表殖利率


下篇中,我們將討論如何迴歸一條殖利率函式供實務應用。


五月 5, 2009

hoamon's sandbox
hoamon
hoamon's sandbox is about »

tag cloud

» FOClass: 計算債券殖利率

P.S. FO 就是 Futures and Options (期貨與選擇權)。

債券殖利率是投資人在買進債券後,一直持有至債券到期日為止,這段持有期間的年平均報酬率。故殖利率又稱「到期殖利率(YTM,Yield to Maturity)」。而公債殖利率則是我們用來評價期貨與選擇權的主要工具之一。因為它代表了資金在無風險情況下的機會成本。

對主修營建管理的學生而言,計算債券殖利率的原理即是工程經濟中計算某一型態現金流量的 IRR (Internal Return Rate 內部報酬率) 。我們以一中央政府公債作為範例,介紹該殖利率計算方式。

「A98101 98央債甲1」其給息及基本條件如下:

  • 2009/1/21 發行
  • 2009/4/16 以 99.2679 購入
  • 到期日為 2014/1/21
  • 每年發放一次債息,配息日為每年 1/21
  • 票面利率為 0.00875
  • 面額為 100 元
所以可知該債券的現金流量為:
  1. 2009/4/16: -99.2679
  2. 2010/1/21: +0.875
  3. 2011/1/21: +0.875
  4. 2012/1/21: +0.875
  5. 2013/1/21: +0.875
  6. 2014/1/21: +100.875
使用公式如下:

  • PV: 現值
  • i : 期別
  • n : 總期別
  • Ci: i期年金
  • FV: 未來值
  • r : IRR,也就是債券殖利率
在代入公式時,有一件事須注意,因為 4/16 距配息日 1/21 並不是剛好一年,所以公式中的 i 並不為整數而是 (i + 280/365) ,且 i 從 0 到 4 。

求解方程式如下:



作到上述式子為止,已經把整個現金流量模式都定義好,基本上,是可以數值方式去求出 r 為何了。然而,在債息分配上,因為已經過了配息日,而債券賣方應可享有從 1/21 ~ 4/16 之間的債息 (0.875 * (1-280/365)) ,且在債券賣出日即歸屬賣方,所以上式須再減去賣方的可得利息,式子修改如下:



這樣就可以用數值方法求 r 了。

» 二分逼近法求債券殖利率

一債券殖利率等式(原理)如下,試求 r 值:



如果該等式中 (1+r)^t 的期別 t 皆為大於 0 的整數時,我們可以直接使用 numpy.lib.financial.irr([0.875*(1-280/365.), 0.875, 0.875, 0.875, 0.875, 100.875]) 求解債券殖利率 r 。但可惜它不是,所以我們使用二分逼近法來求得近似解。

概念乃是先把等式左邊移位至右邊,變成 -99.2679 - .... + 0.875/(1+r)^(4+280/365) = f(r) ,再將 r0=0, r1=1 代入 f(r),則會得到一正值及一負值,所以我們可相信真實的 r' 值的確位於 0 ~ 1 之間。

接下來,就進行一系列的迭代。令新 r 值等於 (r0 + r1)/2 ,再代入 f(r) 中,若 f(r) 為正,則表 r' 必在 (r0+r1)/2 ~ r1 之間; 若 f(r) 為負,則表 r' 必在 r0 ~ (r0+r1)/2 之間。持續進行此一動作,直到 r 值的差異值小於設定值為止。

以下則是我的 Python 程式:

 1 class AnnumYield:
2 """ 求解年化殖利率。
3 """
4
5 def __init__(self, PV=0, Ci=[], Ni=[], precision=6, start_rate=0, end_rate=1):
6 """ Ci: 第 i 個現金流量
7 Ni: 第 i 個期別的真實時間
8 PV: 現值。為債券購入價格,其值應為負值。
9 precision: 數值分析時的精度,當殖利率變化值小於 10**(-1*precision) ,則停止求解。
10 start_rate,end_rate: 起始利率。
11
12 self.equation: 現金流量的方程式
13 self.yieldrate: 債券殖利率
14 """
15 self.Ci = Ci
16 self.Ni = Ni != [] and Ni or range(len(Ci))
17 self.PV = PV < 0 and PV or -1*PV
18 self.precision = precision
19 self.start_rate = start_rate
20 self.end_rate = end_rate
21
22 equations = []
23 for i, c in enumerate(Ci):
24 equations.append('%s/(1+r)**(%s)'%(c, Ni[i]))
25 self.equation = '%s + ' % self.PV + ' + '.join(equations)
26
27 self.yieldrate = self.getYield()
28
29 def getYield(self):
30 """ 利用二分逼近法求 self.equation 的根。
31 當所求出的 yieldrate 與前一個解的差值小於 10 ** (-1*precision) 即停止求解。
32
33 預設代入 start_rate 及 end_rate 去作逼近,
34 所以真實的 yieldrate 必須滿足 start_rate < yieldrate < end_rate 的條件,
35 否則無解。
36 """
37 r = self.start_rate
38 self.list = [(self.start_rate, eval(self.equation))]
39 r = self.end_rate
40 self.list.append((self.end_rate, eval(self.equation)))
41
42 i0, (r0, res0) = 0, self.list[0]
43 i1, (r1, res1) = 1, self.list[1]
44 precision = 10 ** (-1*self.precision)
45 while abs(r0 - r1) > precision:
46 r = (r0 + r1)/2.
47 res = eval(self.equation)
48 self.list.insert(i1, (r, res))
49 if res * res0 < 0:
50 i0, (r0, res0) = i1-1, self.list[i1-1]
51 i1, (r1, res1) = i1 , self.list[i1]
52 elif res * res1 < 0:
53 i0, (r0, res0) = i1 , self.list[i1]
54 i1, (r1, res1) = i1+1, self.list[i1+1]
55 elif res == 0:
56 break
57 else:
58 raise ValueError, \
59 '無解。 end_rate 設定為 %s ,此數值比 yieldrate 解還小' % self.end_rate
60
61 return round((r0 + r1)/2., self.precision)
62
63 if __name__ == '__main__':
64 t = 280./365
65 Ci = [-0.875*(1-t), 0.875, 0.875, 0.875, 0.875, 100.875]
66 Ni = [0, 0+t, 1+t, 2+t, 3+t, 4+t]
67 annumyield = AnnumYield(Ci=Ci, Ni=Ni, PV=99.2679)
68 print annumyield.yieldrate

biggo.com.tw

A Django site.