Блог им. 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.1К | ★5
3 комментария
А почему это в оффтопе?
avatar
вот чем меня удивляет смартлаб. какой-нибудь бесполезный лудоманский шлак собирает сотни комментариев, а такой полезный и редкий пост как этот — два) автору спасибо, у меня весь код работает
avatar

Читайте на SMART-LAB:
Фото
Новосибирскэнергосбыт. Надбавки на 26г. установлены. Изменение целевой цены
Департамент по тарифам Новосибирской области опубликовал приказ №681 от 30.12.2025г. об установлении сбытовых надбавок гарантирующего...
Фото
Результаты Софтлайн за 2025 год — уже 19 февраля!
Друзья, 19 февраля 2026 года мы раскроем основные финансовые показатели за 4 квартал и 12 месяцев 2025 года (неаудированные). В этот же день...
Российский рынок поддерживают геополитические перспективы
Торги 22 января на российских фондовых площадках начались на положительной территории. К 13:00 мск индексы Мосбиржи и РТС прибавляли по 0,42%...
Фото
Сбер РПБУ 2025 г. - дешевле было только в 2022 году
Сбер опубликовал результаты по РПБУ за 2025 год Чистая прибыль за 2025 год составила 1,69 трлн руб. (+8,4% год к году). В декабре 126 млрд руб....

теги блога Tenant

....все тэги



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