Dérivés appris en utilisant Python - (2) Draw Yield Curve (JPYLibor Curve) -

introduction

Le deuxième d'une série de dérivés que vous pouvez apprendre en utilisant Python. Cela fait un moment, mais je vais continuer jusqu'à la tarification des options. Si vous n'avez pas encore vu le premier, jetez un œil.

Série dérivée pour apprendre à utiliser Python

Premièrement: Calcul du taux de change à terme- 2ème: Tracez une courbe des taux (courbe du Libor JPY)

Contenu de cette époque

Expliquez comment dessiner une courbe de rendement simple. Nous ne considérons pas ici les collatéraux, les spreads de ténor ou les spreads de base. Le monde des courbes simples, pas des multi-courbes. Tout d'abord, cette fois est une courbe circulaire. La prochaine fois, j'écrirai un dollar.

jpy_yield.png

Comment dessiner une courbe

Il existe d'autres façons de dessiner une courbe en plus de la méthode de la sangle de démarrage, Ici, la méthode de la sangle de démarrage est expliquée.

En fait, il est nécessaire de considérer la méthode de calcul du nombre de jours (si une année équivaut à 360 jours ou 365 jours, etc.) et les jours fériés, mais Je m'en fiche ici. Seuls le taux au comptant et le taux de swap sont utilisés.

Comment dessiner une courbe par la méthode de la sangle de démarrage

Dans le cas d'un swap de taux d'intérêt sur le yen, l'échange sera un Libor à 6 mois du côté variable et un taux d'intérêt fixe à 6 mois du côté fixe.

Heure actuelle t, Maturité T, Le taux de swap du point temporel t de maturité T est S (t, T), Lorsque le facteur d'actualisation du point temporel t de maturité T est DF (t, T)

La valeur actuelle P (t) du côté des taux d'intérêt fixes est


P(t) = \frac{1}{2}S(t,T) \times DF(t, t_{0.5})) 
+ \frac{1}{2}S(t,T) \times DF(t, t_{1.0}))
+ ...
+ \frac{1}{2}S(t,T) \times DF(t, T))

Sera.

La valeur actuelle F (t) du côté des taux d'intérêt variables est


F(t) = \frac{1}{2}f(t, t_0, T_{0.5}) \times DF(t, t_{0.5})
+ \frac{1}{2}f(t, t_{0.5}, T_{1.0}) \times DF(t, t_{1.0})
+ ...
+ \frac{1}{2}f(t, T-0.5, T) \times DF(t, T)

Sera.

Ici, f (t, t1, t2) représente le taux à terme du yen au point temporel t1 commençant au point temporel t et au point temporel t2 de maturité. Le contrat de swap de taux d'intérêt est conclu lorsque la valeur actuelle du côté fixe et la valeur actuelle du côté variable sont égales.


P(t) = F(t)

Est établi.

Ensuite, dans le swap de taux d'intérêt réel, le principal notionnel est égal et le principal n'est pas échangé, mais pour des raisons de commodité, compte tenu du principal notionnel 1, la formule suivante est obtenue.


\frac{1}{2}S(t,T) \times DF(t, t_{0.5})) 
+ \frac{1}{2}S(t,T) \times DF(t, t_{1.0}))
+ ...
+ \frac{1}{2}S(t,T) \times DF(t, T))
+ 1 \times DF(t, T) \\
= 
\frac{1}{2}f(t, t_0, T_{0.5}) \times DF(t, t_{0.5})
+ \frac{1}{2}f(t, t_{0.5}, T_{1.0}) \times DF(t, t_{1.0})
+ ...
+ \frac{1}{2}f(t, T-0.5, T) \times DF(t, T)
+ 1 \times DF(t, T)

La valeur sur le côté droit est 1 car elle ne renvoie que le taux à terme à la valeur actuelle.

(Supplément) Pourquoi 1? Prenons une obligation à taux d'intérêt variable Libor d'une valeur nominale de 100. La valeur du coupon est équivalente à 100 cash out au moment de l'achat, 100 cash in au moment du remboursement (futur) et Libor. En d'autres termes, si le principal notionnel est 1, le taux d'intérêt variable Libor actualisé et le principal 1 seront 1.

pour cette raison,

Formule de base



\frac{1}{2}S(t,T) \times DF(t, t_{0.5})) 
+ \frac{1}{2}S(t,T) \times DF(t, t_{1.0}))
+ ...
+ \frac{1}{2}S(t,T) \times DF(t, T))
+ 1 \times DF(t, T)
= 1

Sera.

La méthode bootstrap utilise cette formule pour trouver séquentiellement le DF à partir de celui avec la maturité la plus courte.

Je l'ai écrit pendant longtemps, mais la méthode bootstrap elle-même Comme son nom l'indique, utilisez le résultat précédent et prenez les résultats suivants un par un.

Maintenant, calculons le DF séquentiellement.

Calcul DF en 1 an

Il a été dit que le DF sera calculé séquentiellement, mais dans un délai d'un an, le DF sera calculé en utilisant le taux d'intérêt Libor, ou le soi-disant taux de trésorerie, de sorte que le DF peut être calculé directement à partir du taux d'intérêt.

Calcul du DF à partir de 0,5 an

Le Libor à 6 mois est utilisé pour calculer le DF à 0,5 an. De plus, le calcul est effectué par simple calcul des intérêts.


DF(t, t_{0.5}) = \frac{1}{(1 + r(t, t_{0.5}) \times \frac{1}{2})}

Ici, r (t, T) représente le taux d'intérêt Libor yen d'échéance T au moment t.

Calcul du DF à partir de 1 an

Utilisez le Libor sur 12 mois pour calculer le DF à 1 an. (Parfois, utilisez le taux de swap 1Y)


DF(t, t_{1.0}) = \frac{1}{(1 + r(t, t_{1.0}))}

Résumé

Le DF jusqu'à 1 an en utilisant le taux d'intérêt Libor (taux au comptant) peut être calculé par la formule suivante.


DF = \frac{1}{1 + r(t) * t / 100} \\
r(t):Taux d'intérêt Libor à t(\%Convertir de en nombre réel)  \\
t:Ans\\

Calcul DF sur plus d'un an

A partir de là, l'histoire de la recherche séquentielle de DF. Après avoir complété le taux d'intérêt Libor Swap acquis sur le marché et le taux dit swap par incréments de 0,5 an, il est calculé selon la formule de la méthode bootstrap mentionnée ci-dessus.

La raison pour tous les 0,5 ans est que le coupon du swap de taux d'intérêt en yen présumé est un roll semestriel.

Calcul du DF à partir de 1,5 an

En considérant le temps de 1,5 an dans la formule de la méthode de la sangle de démarrage


\frac{1}{2}S(t, t_{1.5}) \times DF(t, t_{0.5}))
+ \frac{1}{2}S(t, t_{1.5}) \times DF(t, t_{1.0}))
+ \frac{1}{2}S(t, t_{1.5}) \times DF(t, t_{1.5}))
+ 1 \times DF(t, t_{1.5})
= 1

Sera. (La formule dérivée par la méthode de la sangle de démarrage est arrêtée dans 1,5 ans)

La seule variable inconnue ici est DF (t, t_ {1.5}). pour cette raison,


DF(t, t_{1.5}) = \frac{ 1 - ( DF(t, t_{0.5}) + DF(t, t_{1.0}) ) \times \frac{S(t, t_{1.5})}{2}}{ 1 + \frac{S(t, T_{1.5})}{2} } 

Par conséquent, le DF pour 1,5 an peut être calculé.

Calcul du DF à partir de 2 ans

De même pour DF à maturité de 2 ans


\frac{1}{2}S(t, t_{2.0}) \times DF(t, t_{0.5}))
+ \frac{1}{2}S(t, t_{2.0}) \times DF(t, t_{1.0}))
+ \frac{1}{2}S(t, t_{2.0}) \times DF(t, t_{1.5})) \\
+ \frac{1}{2}S(t, t_{2.0}) \times DF(t, t_{2.0}))
+ 1 \times DF(t, t_{2.0})
= 1

Parce que cela peut être fait


DF(t, t_{2.0}) = \frac{ 1 - ( DF(t, t_{0.5}) + DF(t, t_{1.0}) + DF(t, t_{1.5}) ) \times \frac{S(t, t_{2.0})}{2}}{ 1 + \frac{S(t, T_{2.0})}{2} } 

Et peut être calculé.

Résumé

Le DF pour une période de plus d'un an en utilisant le taux d'intérêt Libor Swap (taux de swap) peut être calculé par la formule suivante lors de l'utilisation de la méthode bootstrap.


DF(t, T) = \frac{ 1 - \sum_{i=0.5}^{T-0.5}DF(t, t_i) \times \frac{S(t, T)}{2}}{1 + \frac{S(t,T)}{2}} \\

(T > 1)

Calcul du taux zéro

Il est possible de calculer la base de taux d'intérêt continue (taux zéro) à partir du DF calculé.


y(t, T) = \frac{ \ln DF(t, T) }{ -(T - t) }

  

DF(t, T) = e^{-rτ}Déformation de
τ:période(T - t)
r:Taux d'intérêt au comptant du point t à l'échéance T(Taux zéro, y(t,T)Cette)

y (t, T) représente le taux zéro sur la base d'un taux d'intérêt continu à l'échéance t T. Pour les taux nuls autres que la maturité calculée, DF est calculé par interpolation linéaire ou interpolation spline.

Si vous tracez le taux zéro calculé, vous pouvez dessiner une courbe.

Supplément

Taux zéro et taux nominal

Le taux zéro est le rendement final des obligations à taux d'intérêt composé (obligations à coupon zéro). Les obligations décotées sont des produits financiers qui génèrent des flux de trésorerie uniquement à la date d'échéance. Le taux zéro est le taux d'intérêt qui commence à partir de l'heure actuelle et est également appelé taux au comptant pour le distinguer du taux à terme. Le taux zéro est utilisé lors de l'actualisation des flux de trésorerie futurs à la valeur actuelle car il n'y a pas de paiement d'intérêts au milieu et il n'y a pas de problème de ré-opération.

Le parrate est le rendement final des obligations à intérêts composés. Les obligations portant intérêt sont des produits financiers dans lesquels un certain montant d'intérêts est payé chaque année jusqu'à l'échéance.

Formule de calcul DF

Si vous généralisez avec 6 mois de paiement d'intérêts


DF_i = \frac{1 - r_i \sum_{k=1}^{i-1} DF_{i-1}}{ 1 + r_i} \\

i:Point dans le temps\\
r_i:Taux d'intérêt au moment i\\
DF_i:Facteur discant au point temporel i\\

Programme pour dessiner une courbe de rendement

Cela fait longtemps, mais je vais enfin dessiner une courbe en Python. Il semble que je vais réécrire diverses choses lors du dessin d'autres devises ou multi-courbes, mais c'est bien car cela fonctionne une fois. (excuse?)

Flux de processus

programme


# -*- coding: utf-8 -*-


#Préparation de ce qui est nécessaire pour la représentation graphique
import matplotlib
import matplotlib.pyplot as plt

#Bibliothèque requise pour le traitement des données
import numpy as np
from scipy import interpolate

#Autre
from enum import Enum

#La magie de matplotlib
plt.style.use('ggplot')
font = {'family': 'meiryo'}
matplotlib.rc('font', **font)

#Diverses données
# JPY Libor
cash_rate = {
    "ON": 0.1, "1W": 0.10357, "1M": 0.12014, "2M": 0.13857, "3M": 0.15429, "6M": 0.16123, "12M": 0.23875
}

# JPY Libor Swap
swap_rate = {
    "2Y": 0.26250, "3Y": 0.30250, "4Y": 0.36000, "5Y": 0.44813, "6Y": 0.55250,
    "7Y": 0.66750, "8Y": 0.77500, "9Y": 0.88250, "10Y": 0.98500, "12Y": 1.17750, "15Y": 1.44750, "20Y": 1.75000,
    "25Y": 1.89000, "30Y": 1.95813
}

input_market_data = cash_rate.copy()
input_market_data.update(swap_rate)


class RateType(Enum):
    CASH_RATE = 1
    SWAP_RATE = 2


class MarketData:
    def __init__(self, grid, rate):
        self.grid = grid
        self.rate = rate / 100  #D'entrée%Vers un nombre réel
        self.set_term()
        self.set_rate_type()

    def set_term(self):
        if self.grid == "ON":
            self.term = 1 / 365
        else:
            num = float(self.grid.replace("M", "").replace("W", "").replace("Y", ""))
            if "W" in self.grid:
                self.term = num * 7 / 365
            elif "M" in self.grid:
                self.term = num * 1 / 12
            elif "Y" in self.grid:
                self.term = num
            else:
                self.term = 0.0

    def set_rate_type(self):
        if self.term <= 1:
            self.rate_type = RateType.CASH_RATE
        else:
            self.rate_type = RateType.SWAP_RATE

    def value(self):
        print("Grid:{0}, RateType: {1}, Term:{2}, Rate: {3}".format(self.grid, self.rate_type, self.term, self.rate))


class YieldCurve:
    def __init__(self, market_data_list):
        self.market_data_list = market_data_list
        self.sigma_df = 0.0  # TODO:Faire mieux
        self.df_list = []
        self.zero_list = []

    def get_grids(self):
        return list(map(lambda x: x.term, self.market_data_list))

    def interpolate_swap_rate(self):
        i = 1.5  #Après 1 an, JPY est un rouleau semestriel, donc 1.À partir de 5
        original_rates = list(map(lambda x: x.rate * 100, self.market_data_list))
        f = interpolate.interp1d(self.get_grids(), original_rates)
        while i <= 30:
            r = list(filter(lambda x: x == i, self.get_grids()))
            if not r:
                m = MarketData(str(i) + "Y", f(i))
                self.market_data_list.append(m)
            i += 0.5  #JPY est pour un rouleau de six mois+0.5

        #Trier à la fin
        self.market_data_list.sort(key=lambda x: x.term)

    def output_market_data_list(self):
        for mkt in self.market_data_list:
            mkt.value()

    def generate_curve(self):
        for mkt in self.market_data_list:
            self.calc_df(mkt)

    def calc_df(self, mkt):
        if mkt.rate_type == RateType.CASH_RATE:
            d = 1 / (1 + mkt.term * mkt.rate)
            self.df_list.append(d)
        elif mkt.rate_type == RateType.SWAP_RATE:
            #Total de DF uniquement pour la grille de rouleau semestrielle
            d = (1 - self.sigma_df * mkt.rate / 2) / (1 + mkt.rate / 2)
            self.df_list.append(d)

        if mkt.term % 0.5 == 0:
            self.sigma_df += d

        self.calc_zero(mkt, d)

    def get_df(self, term):
        f = interpolate.interp1d(self.get_grids(), self.df_list, kind="cubic")
        return f(term)

    def calc_zero(self, mkt, d):
        if mkt.rate_type == RateType.CASH_RATE:
            self.zero_list.append(mkt.rate)
        elif mkt.rate_type == RateType.SWAP_RATE:
            zero = -1 * np.log(d) / mkt.term
            self.zero_list.append(zero)

    def output(self):
        print("Grid: DF: ZeroRate:")
        for i, v in enumerate(self.market_data_list):
            print("{0}: {1}: {2}".format(v.grid, self.df_list[i], self.zero_list[i] * 100))

    def plot(self):
        fig = plt.figure(figsize=(10, 10))
        ax_df = fig.add_subplot(2, 1, 1)
        plt.subplots_adjust(hspace=0.3)
        ax_df.set_ylim([0, 1.1])
        ax_df.plot(self.get_grids(), self.df_list)
        ax_df.set_title("Discount Factor")
        ax_df.set_xlabel("Grid")
        ax_df.set_ylabel("DF")
        ax_zero = fig.add_subplot(2, 1, 2)
        ax_zero.set_ylim([0, 3])
        ax_zero.plot(self.get_grids(), list(map(lambda z: z * 100, self.zero_list)))
        ax_zero.set_title("Zero Rate")
        ax_zero.set_xlabel("Grid")
        ax_zero.set_ylabel("Zero Rate")
        plt.show()


if __name__ == '__main__':
    # read market data
    market_data_list = list(map(lambda x: MarketData(x[0], x[1]), input_market_data.items()))

    # generate yield curve
    curve = YieldCurve(market_data_list)
    curve.interpolate_swap_rate()
    curve.generate_curve()
    curve.plot()


Livre de référence

[Tous les dérivés qui peuvent être compris par illustration](https://www.amazon.co.jp/ Tous les dérivés compréhensibles par illustration-avec feuille EXCEL CD-ROM utilisable en pratique-Tabuchi-Naoya / dp / 4534038186 / ref = sr_1_21? ie = UTF8 & qid = 1467724878 & sr = 8-21 & mots-clés = dérivés)

[Remise LIBOR et remise OIS comprise par EXCEL](https://www.amazon.co.jp/ Remise LIBOR et remise OIS comprise par EXCEL-avec CD-ROM-Nakahara-Genta / dp / 432123848 / ref = sr_1_2? Ie = UTF8 & qid = 1467724851 & sr = 8-2 & mots-clés = LIBOR)

finalement

Je ne suis pas familier avec cela, mais dans mon travail, je trace une courbe avec plus de considération.

Recommended Posts

Dérivés appris en utilisant Python - (2) Draw Yield Curve (JPYLibor Curve) -
Dessiner une courbe Silverstone en utilisant Python
Dessinez une structure arborescente en Python 3 à l'aide de graphviz
Dérivés appris en utilisant Python- (1) Calcul du taux de change à terme-
Implémentation d'un générateur en utilisant Python> link> yield et next ()> yield
Aplatir à l'aide du rendement Python de
Dessinez un cœur en Python
J'ai fait un Line-bot avec Python!
Essayez de dessiner une courbe de Bézier
Créer une interface graphique python à l'aide de tkinter
Dessinez une matrice de diagramme de dispersion avec python
Dessinez une courbe Koch avec Python Turtle
Dessinez un diagramme CNN en Python
Comment dessiner un graphique avec Matplotlib
[Python] Créer un environnement Batch à l'aide d'AWS-CDK
Dessiner un cœur avec Python Partie 2 (SymPy Edition)
Scraping de sites Web à l'aide de JavaScript en Python
[Python] Gratter une table avec Beautiful Soup
Un programme qui utilise Python pour lire des fichiers indésirables
Dessiner un graphique d'une fonction quadratique en Python
Créer un fichier GIF en utilisant Pillow en Python
[Python] Fractionner un gros fichier Flask en utilisant Blueprint
[Python] Dessinez un graphe orienté avec Dash Cytoscape
[Python] Dessinez un Mickey Mouse avec une tortue [Débutant]
Créer une carte Web en utilisant Python et GDAL
Afficher les avis sur les médicaments à l'aide de listes en Python
J'ai essayé de lire un fichier CSV en utilisant Python
Exemple pour dessiner une horloge simple en utilisant ebiten
Exécutez des fichiers Python à partir de HTML en utilisant Django
[Python] Comment dessiner un histogramme avec Matplotlib
Créez un fichier MIDI en Python en utilisant pretty_midi
Exécutez des scripts Python à partir d'Excel (en utilisant xlwings)