[Python] 債券価格

現在割引価値を使った債券価格を Python で実装します。

現在割引価値 割引現在価値(わりびきげんざいかち)とは、将来に受け取れる価値が、もし現在受け取れるとしたらどの程度の価値をもつかを表すもの。たとえば利率が5%のとき、1年後の105万円の割引現在価値は100万円となる。 出典: フリー百科事典『ウィキペディア(W...

債券

債券(さいけん、: Bond)とは、社会的に一定の信用力のある発行体が資金を調達する際に、金銭消費貸借契約類似の法律関係に基づく金銭債権の内容を券面上に実体化させて発行する有価証券のこと。広義には券面が発行されない場合も含む。

出典: フリー百科事典『ウィキペディア(Wikipedia)』

債券とは、国や企業が投資家からお金を借りた時に発行される証明書のようなもので、普通の借金と同じように、額面、つまり借金の額や返済の期日、利息が決まっています。債券では、この利息のことをクーポンと呼びます。

普通の人がする借金と異なるのは、債券は発行された後も多くの人が参加する市場で取引され、その価格と利回りが変動していきます。 債券価格が下がれば利回りは上がり、債券価格が上がれば利回りは下がる、という関係になります。

将来発生するお金を考慮するので、現在の視点で債券を評価するためには、現在割引価値を使う必要があります。

ゼロクーポン債 ( 割引債 )

割引債(わりびきさい)は、額面より低い価格で発行される、利息がゼロの債券である。利付債にはあるクーポンが、割引債には付随しない事から、ゼロクーポン債とも呼ばれる[1]

出典: フリー百科事典『ウィキペディア(Wikipedia)』

ゼロクーポン債は、クーポンがない債券のことです。

額面1000円の国債で、現在の利率が2%、3年後に償還されるとします。

利率が変わらないとすると、この国債の現在価値は、現在割引価値そのままで、以下のように考えることができます。

$$ \frac {1000} {(1 + 0.02)^3} =942.3223… $$

債券額面\(Par Value\)、利率 \(r\)、期間\(n\)を使って、ゼロクーポン債の債券価格 \( Bond Price \)は以下のように表せます。

$$ Bond Price = \frac {Par Value} {(1 + r)^n} $$

利付債

利付債(りつきさい)は、償還期日に至る間、決まった時期に利息を受け取る事が出来る債券を指す。

出典: フリー百科事典『ウィキペディア(Wikipedia)』

クーポン、つまり利息の発生する債券です。

額面1000円の国債で、現在の利率が2%、1年ごとに50円の利息、3年後に償還されるとして、この国債の現在価値を考えます。

利息部分の現在価値は以下のような等比数列の和になります。

$$ \frac { 50 } { (1 + 0.02)^1} + \frac{50} { (1+0.02)^2} + \frac{50} { (1+0.02)^3} = 144.1941…$$

額面部分は、ゼロクーポン債と同様に以下になります。

$$ \frac {1000} {(1 + 0.02)^3} =942.3223… $$

よってこの国債の割引現在価値は以下になります。

$$ 144.1941 + 942.3223 = 1086.5164 $$

クーポンの期間ごとの支払い\(c\)、利率 \(r\)、期間\(n\)を使って、 利息の現在割引価値を一般化します。

$$ \begin{eqnarray} & & \frac {c} {1+r} \cdot \frac { 1 – ( \frac {1} {1+r}) ^n } { 1 – \frac {1} {1 +r} } \\ &=& \frac {c} {1+r} \cdot \left[ 1 – \frac {1} {(1+r)^n} \right] \cdot \frac {1+r}{r} \\ &=& \frac {c} {r} \cdot \left[ 1 – \frac {1} {(1+r)^n} \right] \end{eqnarray} $$

よって、債券額面\( Par Value\)、利率\( r\)、期間\(n\)、期間ごとのクーポンの支払い \(c\)を使って、 利付債の債券価格\(Bond Price\)は以下のように表せます。

$$ Bond Price = \frac {c} {r} \cdot \left[ 1 – \frac {1} {(1+r)^n} \right] + \frac {Par Value} {(1 + r)^n} $$

Python で実装

以上を Python で実装します。

def zero_coupon_bond_price(par_value, market_rate, n):
    present_val = par_value / (1 + market_rate) ** n
    return present_val

def fixed_coupon_rate_bond_price(par_value, market_rate, n, coupon_rate):
    coupon_payment = par_value * coupon_rate
    present_val_coupon = coupon_payment / market_rate * (1 - (1/(1+market_rate)**n))
    present_val = present_val_coupon + zero_coupon_bond_price(par_value, market_rate, n)
    return present_val


if __name__ == '__main__':
    par_value = 1000
    market_rate = 0.02
    n = 3
    coupon_rate = 0.05
    
    # 942.3223345470444
    print(zero_coupon_bond_price(par_value, market_rate, n))
    # 1086.5164981794335
    print(fixed_coupon_rate_bond_price(par_value, market_rate, n, coupon_rate))