0
0

More than 1 year has passed since last update.

G++ Python

Posted at

import pandas as pd
import numpy as np
import math
import matplotlib.pyplot as plt
class G_n_plusplus:
def init(self, n_factor = 2) -> None:
"""
Augs
discount_factor_vec: 割引率のベクトル。スワップのCFに合う形を想定
"""
# ファクターの数を設定する。
self.n_factor = n_factor

    # 初期値を設定する
    self.variance_vec = np.array([1] * n_factor)
    self.drift_vec = np.array([1] * n_factor)
    self.a_vec = np.array([1] * n_factor)
    self.correlation_mat = np.eye(self.n_factor)


def _calc_swaption_price(self, maturity, strike, nominal_value, first_swap_time, time_fraction, n_swap, discount_factor_vec) -> float:
    """
    Augs
        marurity: スワップション満期(年)
        strike: スワップションの行使価格
        nominal_value: よくわからんけど、論文だと"N"
        first_swap_time: スワップ行使の開始時点(年)
        time_fraction: スワップ行使の時間幅(年)
        n_swap: スワップ回数
        discount_factor_vec: 割引率のベクトル。スワップのCFに合う形を想定(長さは"n_swap"と一致。)
    """ 
    # 入力を整理
    self.maturity = maturity
    self.strike = strike
    self.nominal_value = nominal_value
    self.first_swap_time = first_swap_time
    self.time_fraction = time_fraction
    self.n_swap = n_swap
    self.discount_factor_vec = discount_factor_vec

    # 最後のスワップの時刻をfinal_swap_timeとする
    self.final_swap_time = self.first_swap_time + self.time_fraction * self.n_swap

    # time fractionとDiscount Factorの積和を計算する。(ここでは、time fractionが定数と仮定しているため、Discount Factorの和にtime fractionをあとから掛けている)
    self.P = sum(self.discount_factor_vec) * self.time_fraction
    
    # Aのリストを作成する
    self._calc_A()

    # VOLを計算する
    self._calc_VOL()
    
    # 理論解を計算
    self.theoretical_swaption_price = self.nominal_value * self.VOL * self.P / math.sqrt(2 * np.pi)

def _calc_A(self) -> list:
    """
    A_i (i = 1, 2, ..., factor数)を作成する。
    calc_swaption_priceのサブ的な関数
    """
    self.A = []
    for i in range(self.n_factor):
        # A の二つ目の項と最後の項を分けて計算
        # self.discount_factor_vec[0]は"P(0, T)"を表す
        A = math.exp(- self.drift_vec[i] * self.maturity) * self.discount_factor_vec[0] / self.P - math.exp(- self.drift_vec[i] * self.final_swap_time) * self.discount_factor_vec[-1] / self.P

        final_term_of_A = 0
        for j in range(self.n_swap):
            # スワップの実行時刻
            t_j = self.first_swap_time + self.time_fraction * j

            final_term_of_A += math.exp(- self.drift_vec[i] * t_j) * self.time_fraction * self.discount_factor_vec[j]
        
        final_term_of_A *= - self.strike
        
        # 最後の項を加算
        A += final_term_of_A
        
        # リストに格納
        self.A.append(A)
    
def _calc_VOL(self) -> float:
    """
    VOLを計算する。calc_swaption_priceのサブ的な関数
    """
    VOL = 0
    for i in range(self.n_factor):
        for j in range(self.n_factor):
            VOL += self.variance_vec[i] * self.variance_vec[j] * self.correlation_mat[i, j] * self.A[i] * self.A[j] * \
                (math.exp((self.drift_vec[i] + self.drift_vec[j]) * self.maturity) - 1) / (self.drift_vec[i] + self.drift_vec[j])
            
    self.VOL = math.sqrt(VOL)

set a input
maturity = 10
strike = 0.05
nominal_value = 1
first_swap_time = 11
time_fraction = 0.5
n_swap = 6
discount_factor_vec = [0.99, 0.95, 0.85, 0.81, 0.8, 0.75]

plt.plot(discount_factor_vec)
[]

instance_G_2 = G_n_plusplus()

instance_G_2._calc_swaption_price(maturity=maturity, strike=strike, nominal_value=nominal_value, first_swap_time=first_swap_time, time_fraction=time_fraction, n_swap=n_swap, discount_factor_vec=discount_factor_vec)
instance_G_2.theoretical_swaption_price
0.3684090138614806
instance_G_2.VOL
0.35862697117441217

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0