Блог им. 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:
Фото
Актуальный состав портфеля и взгляд на рынок 2026: по-прежнему 0% позитива.
Добрый вечер! С момента предыдущего поста, касающегося моего портфеля, прошел квартал.  Пришло время актуализировать его состав. Также поделюсь...
Фото
Биткоин попробует разыграть «треугольную карту»?
«Цифровое золото» прорвало верхнюю границу восходящего треугольника на уровне 94 500 и сейчас тестирует пробитую горизонталь, формируя серию...
Фото
Индикатор Fractal: торговые сигналы и робот для OsEngine. Видео
В этом видео разбираем индикатор Fractal Билла Вильямса — один из самых известных инструментов в трейдинге. Покажем, как формируются фракталы,...
Фото
Стратегия 2026 по рынку акций от Mozgovik Research: трудный год, но, возможно, последний год низких цен
Сегодня у меня первый день официального отпуска. За окном темная звездная ночь, яркая белая луна, +24С и шум волн Андаманского моря. Неудачный...

теги блога Tenant

....все тэги



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