Блог им. imagic

Код для построения графика КБД Мосбиржи

    • 08 октября 2024, 09:56
    • |
    • Tenant
  • Еще
0. Импортируем нужные библиотеки

import requests
import pandas as pd 
import numpy as np
import matplotlib.pyplot as plt


1. Извлекаем данные о расчетных параметрах КБД
Расчетные параметры на конкретную дату указаны внизу страницы
www.moex.com/ru/marketdata/indices/state/g-curve/
# URL для API MOEX, данные по ZCYC (zero coupon yield curve)
url = "https://iss.moex.com/iss/engines/stock/zcyc/securities.json"

# Запрос на получение данных
response = requests.get(url)
data = response.json()

# Извлекаем данные из секции 'params'
columns = data['params']['columns']
values = data['params']['data']

# Преобразуем в DataFrame
df = pd.DataFrame(values, columns=columns)

# Выбираем нужные столбцы: B1, B2, B3, T1, G1, ..., G9
df_selected = df[['tradedate', 'tradetime', 'B1', 'B2', 'B3', 'T1', 'G1', 'G2', 'G3', 'G4', 'G5', 'G6', 'G7', 'G8', 'G9']]

# Извлекаем параметры для функции GT из df_selected
beta0 = df_selected['B1'].values[0]  
beta1 = df_selected['B2'].values[0]  
beta2 = df_selected['B3'].values[0]  
tau = df_selected['T1'].values[0]   
g_values = df_selected[['G1', 'G2', 'G3', 'G4', 'G5', 'G6', 'G7', 'G8', 'G9']].values[0].tolist() 



2. Определяем функции для расчета G-curve для непрерывного начисления  и КБД (в процентах годовых) 

# Функция для расчета бескупонной доходности по методу Нельсона-Сигеля 

def GT(t, beta0, beta1, beta2, tau, g_values): #Непрерывная доходность 
    # Основные члены модели
    term1 = beta0 + beta1 * tau*(1 - np.exp(-t / tau))/t 
    term2 = beta2 *((1 - np.exp(-t / tau))*tau/t  - np.exp(-t / tau))

    # Инициализация параметров a_i и b_i
    a_values = np.zeros(9)
    b_values = np.zeros(9)
    
    # Инициализация первых значений
    a_values[0] = 0  # a_1 = 0
    a_values[1] = 0.6  # a_2 = 0.6
    b_values[0] = a_values[1]  # b_1 = a_2

    k = 1.6  # параметр для рекуррентного расчета

    # Рекуррентное вычисление a_i и b_i
    for i in range(2, 9):
        a_values[i] = a_values[i - 1] + k**(i - 1)
        b_values[i - 1] = b_values[i - 2] * k

    # Расчет суммы по экспоненциальным членам
    term3 = 0
    for i in range(9):
        if b_values[i] != 0:  # Добавляем проверку на нулевые значения b_i
            term3 += g_values[i] * np.exp(-((t - a_values[i])**2) / (b_values[i]**2))
    
    GT = term1 + term2 + term3
    
    return GT/10000

def KBD(t, beta0, beta1, beta2, tau, g_values): #Кривая бескупонной доходности в % годовых
    YT = 100 * (np.exp(GT(t, beta0, beta1, beta2, tau, g_values)) - 1)
    return YT
3. Построение графика

# Временные точки для расчета (например, от 0 до 30 лет)
t_vals = np.linspace(0.01, 30, 1500)

# Расчет КБД  для всех точек
KBD_vals = KBD(t_vals, beta0, beta1, beta2, tau, g_values)

# Построение графика
plt.figure(figsize=(12, 6))

plt.tick_params(axis='both', which='major', labelsize=18)
plt.plot(t_vals, KBD_vals, label='КБД',linewidth=3, linestyle='-',color = 'darkred')
plt.title('КБД Мосбиржи',fontsize=22)
plt.xlabel('Срок до погашения, лет',fontsize=20)
plt.ylabel('Доходность, %',fontsize=20)
plt.grid(False)
#plt.legend()
plt.show()
Результат:

Код для построения графика КБД Мосбиржи


График нужен скорее для иллюстрации статей, а вот функции GT и KBD понадобятся для исследования различных моделей. Они хороши тем, что достаточно гладкие и по ним легко построить форвардную кривую и ее производную. Некоторые авторы берут дискретные точки на КБД Мосбиржи  и затем приближают кривую сплайнами, но это часто вызывает проблемы при дальнейшем моделировании. Например, попытки рассчитать форвардные ставки, чтобы найти «ожидания» рынка по будущим краткосрочным ставкам, могут привести к достаточно волатильным результатам. Построение КБД непосредственно по формулам из документации Мосбиржи позволяет избежать подобных проблем. 

Код сам по себе довольно сырой и каждый желающий может его дополнить и улучшить.

upd: Можно построить на одном графике спотовую и форвардные кривые, чтобы посмотреть «ожидаемую» рынком динамику коротких ставок  (без учета премии за риск) Используются данные за 07.10.2024. Грубо говоря, форвардная кривая — это «предсказание» будущих ставок RUONIA на основе текущей спотовой кривой.  Понятно, что дальний конец нерелевантен, т.к. ставки не могут застыть на плато. Это результат теоретической модели. Кроме того, КБД не учитывает «реальные ожидания» многих участников о повышении коротких ставок вплоть до 22% в ближайшие месяцы.   
#Построение графиков спотовой и форвардной кривой 

# Функция для расчета цены бескупонной облигации P(0,T) на основе данных Мосбиржи
def P_0_T(beta0, beta1, beta2, tau, g_values, T):
    R_T = GT(T, beta0, beta1, beta2, tau, g_values)  # Бескупонная непрерывно начисляемая ставка
    return np.exp(-R_T * T) 

# Форвардная ставка F(0,T) 
def F_0_T(T, beta0, beta1, beta2, tau, g_values, dt=1e-4):
    P_T_plus_dt = P_0_T(beta0, beta1, beta2, tau, g_values, T + dt)
    P_T = P_0_T(beta0, beta1, beta2, tau, g_values, T)
    F_0_T = -(np.log(P_T_plus_dt) - np.log(P_T)) / dt
    return F_0_T

def F_0_T_eff(T, beta0, beta1, beta2, tau, g_values, dt=1e-4): #форвардная ставка при годовом (эффективном) начислении, в % годовых
    FT = 100*(np.exp(F_0_T(T, beta0, beta1, beta2, tau, g_values, dt=1e-4)) - 1)
    return FT

# Временные точки для расчета (например, от 0 до 30 лет)
t_vals = np.linspace(0.1, 30, 1500)

# Расчет кривых  для всех точек
KBD_vals = KBD(t_vals, beta0, beta1, beta2, tau, g_values)
F_0_T_eff_vals = F_0_T_eff(t_vals, beta0, beta1, beta2, tau, g_values, dt=1e-4)

# Построение графика
plt.figure(figsize=(12, 6))

plt.tick_params(axis='both', which='major', labelsize=18)
plt.plot(t_vals, KBD_vals, label='КБД Мосбиржи' ,linewidth=3, linestyle='-',color = 'darkred')
plt.plot(t_vals, F_0_T_eff_vals, label='Форвардная кривая',linewidth=3, linestyle='-',color = 'darkgreen')
plt.title('Спотовая и форвардная кривые',fontsize=22)
plt.xlabel('Срок до погашения, лет',fontsize=20)
plt.ylabel('Доходность, %',fontsize=20)
plt.grid(False)
plt.legend(fontsize=18)
plt.show()
 
Код для построения графика КБД Мосбиржи
Данная публикация является личным мнением автора. Мнение владельца сайта может не совпадать с мнением автора.
1.4К | ★5
3 комментария
А почему это в оффтопе?
avatar
вот чем меня удивляет смартлаб. какой-нибудь бесполезный лудоманский шлак собирает сотни комментариев, а такой полезный и редкий пост как этот — два) автору спасибо, у меня весь код работает
avatar

Читайте на SMART-LAB:
Фото
Записки инвестора. Ключевые тренды и события на рынке
«Записки инвестора» — еженедельная рубрика для быстрого погружения в рынок. Мы выделяем самые важные события, за которыми стоит следить — и...
Фото
Мировой страховой рынок покажет рост в 2,3% в 2027 году – Swiss Re Institute
Swiss Re, одна из крупнейших и старейших в мире перестраховочных компаний, поделилась своим прогнозов в отношении мирового страхового рынка....
Фото
Что ждет застройщиков в октябре, когда в России вернутся к обсуждению изменений в семейной ипотеке?
В последние две недели июня случился ажиотажный спрос на недвижимость по программе семейной ипотеки, ведь с 1 июля ожидался ввод...
Фото
Сбер РПБУ 6 мес. 2026 г. - кому нужны 30% доходности?
Сбер опубликовал финансовые результаты по РСБУ за 6 месяцев 2026 года. Чистая прибыль за полгода работы составила 995 млрд руб. (+20,4%). За...

теги блога Tenant

....все тэги



UPDONW
Новый дизайн