Серфим по волнам ставки ЦБ РФ

Сегодня 13 февраля 2026 состоится очередное заседание умных голов для обсуждения ключевой ставки Центрального банка РФ.

Чем это важно для инвестора? Чем ниже ставка - ниже ставка вкладов и ниже доходности ОФЗ; ставка RUONIA привязана к ставке ЦБ и следует за ней - чем она ниже, тем ниже и облигации-флоатеры, следующие за этим показателем.

Банки сейчас активно предлагают вклады с привязкой к ставке ЦБ - для них это "субпродукт" между облигациями-флоатерами и привычными всем депозитами. Ко всему их проще сопровождать, оценивать и рекомендовать населению особенно на волнах хайпа по ИскИнам.

Мы же попробуем спрогнозировать, какой будет ставка ЦБ дальше и для этого напишем свою программу на R с блекджеком и куртизанками!

Сначала заберем данные с сайта ЦБ РФ (я это уже сделал и оформил в виде CSV-файла INF_F17_09_2013_T12_02_2026.csv).

Весь код с файлом можно забрать из моего GitHub

В работе будем использовать библиотеки:

📦 tsibble

Назначение: Временные ряды в tidy-стиле (temporal tibble)

Что делает:

  • Превращает обычный data.frame в tsibble — специальный формат для временных рядов
  • Требует явно указать индекс (дату) и ключи (группы)
  • Понимает временную периодичность (месяц, квартал, год)
  • Умеет работать с пропусками во времени
  • Интегрирован с пакетами прогнозирования

Зачем здесь: as_tsibble(index = Дата) — делает данные "понятными" для fable, позволяет использовать new_data(), lag(), и другие временные функции.

📦 fable

Назначение: Прогнозирование временных рядов (Forecasting)

Что делает:

  • model() — спецификация и обучение моделей
  • TSLM() — временная линейная регрессия
  • forecast() — генерация прогнозов
  • report() — вывод статистики модели
  • accuracy() — оценка качества
  • Поддержка ARIMA, ETS, NNAR, VAR и др.

Зачем здесь: Это сердце анализа. Мы строим модель TSLM(Ставка ~ Инфляция + trend()), обучаем её и получаем прогноз.

📦 feasts

Назначение: Анализ и визуализация временных рядов (Feature Extraction And Statistics)

Что делает:

  • autoplot(), gg_season(), gg_subseries() — визуализация
  • ACF(), PACF() — автокорреляция
  • STL() — декомпозиция ряда
  • features() — извлечение признаков (тренд, сезонность, пики)

Зачем здесь: Хотя в текущем коде feasts не вызывается явно, он часто используется вместе с fable для диагностики модели и анализа остатков. Полезен для проверки: есть ли автокорреляция в остатках, нужна ли сезонность.

Пишем код на R

Загружаем данные из файла

# ====================================================== # 1. Загрузка и подготовка данных # ====================================================== library(tidyverse) library(tsibble) library(fable) library(feasts) library(lubridate) # Чтение данных df <- read.csv2("INF_F17_09_2013_T12_02_2026.csv", stringsAsFactors = FALSE, fileEncoding = "Windows-1251")

Немного магии преобразований чисел в нужный нам формат и фильтрация по полю "Ставка":

# Обработка данных df_clean <- df %>% # Переименовываем колонки для удобства rename( Дата = 1, Ставка = 2, Инфляция = 3, Цель = 4 ) %>% mutate( # Парсим дату в формате DD.MM.YYYY Дата = dmy(Дата), # dmy = день-месяц-год # Замена запятой на точку и преобразование в число Ставка = as.numeric(str_replace(Ставка, ",", ".")), Инфляция = as.numeric(str_replace(Инфляция, ",", ".")), Цель = as.numeric(str_replace(Цель, ",", ".")) ) %>% # Удаляем строки с NA filter(!is.na(Дата), !is.na(Ставка)) %>% # Сортируем по возрастанию даты arrange(Дата) %>% # Превращаем в tsibble as_tsibble(index = Дата)

Будем использовать общепринятый формат tsibble для работы с TimeSeries.

Также в R есть замечательный инструмент %>% - называется "пайп" или pipe, позволяющие производить быстрые преобразования.

select - выбираем наши данные, filter - фильтруем. Особенность пайпов - это работа кода справа налево - сначала преобразование данных в тип tsibble, затем фильтрация, затем выборка select, затем применение изменений через mutate.

# Смотрим структуру glimpse(df_clean)

Проверяем, что всё выглядит как нужно и значения не потеряны:

> glimpse(df_clean) Rows: 148 Columns: 4 $ Дата <date> 2013-09-01, 2013-10-01, 2013-11-01, 2013-12-01, 2014-01-01, 2014-02-… $ Ставка <dbl> 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 7.0, 7.5, 7.5, 7.5, 8.0, 8.0, 8.0, 8.0,… $ Инфляция <dbl> 6.14, 6.27, 6.50, 6.47, 6.07, 6.21, 6.92, 7.33, 7.59, 7.81, 7.45, 7.5… $ Цель <dbl> 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, … > head(df_clean) # A tsibble: 6 x 4 [1D] Дата Ставка Инфляция Цель <date> <dbl> <dbl> <dbl> 1 2013-09-01 5.5 6.14 4 2 2013-10-01 5.5 6.27 4 3 2013-11-01 5.5 6.5 4 4 2013-12-01 5.5 6.47 4 5 2014-01-01 5.5 6.07 4 6 2014-02-01 5.5 6.21 4

Всё цифры на месте, даты тоже выглядят как даты.

Строим график, посмотрим как это всё выглядит:

# ====================================================== # 2. График исходных рядов: ставка и инфляция # ====================================================== p1 <- df_clean %>% ggplot(aes(x = Дата)) + geom_line(aes(y = Ставка, color = "Ключевая ставка"), size = 1) + geom_line(aes(y = Инфляция, color = "Инфляция (г/г)"), size = 1) + geom_hline(aes(yintercept = 4, linetype = "Цель 4%"), color = "darkgreen", size = 0.8) + scale_color_manual(values = c("Ключевая ставка" = "steelblue", "Инфляция (г/г)" = "coral")) + scale_linetype_manual(name = "", values = "dashed") + labs( title = "Ключевая ставка и инфляция в России", y = "%", x = "Дата", color = "Показатель", linetype = "" ) + theme_minimal() + theme(legend.position = "bottom") print(p1)
График ставки ЦБ и уровня инфляции
График ставки ЦБ и уровня инфляции

Построение модели для прогнозирования

Классически, для обучения ИИ на фондовых рынках используют методы, которые используют все нейросети, в том числе LSTM - создание набора данных, обучающей выборки и тренировка модели.

Поскольку нам не нужна супер-точность, мы же не ЦБ РФ - используем метод TSLM (Time Series Linear Model) — метод линейной регрессии для временных рядов из пакета fable.

📌 Суть метода:

Обычная линейная регрессия, но с учётом временной структуры данных. Оценивается МНК (метод наименьших квадратов).

📐 Формула:

y_t = β₀ + β₁·x₁ + β₂·x₂ + … + ε_t

где t — время, x — предикторы (лаги, тренд, сезонность, иные факторы)

У метода много минусов, но и много плюсов - в нашем случае - хорошая прогнозируемость и простота применения.

# ====================================================== # 3. Построение модели TSLM (fable) # ====================================================== # Обучающая выборка — до последнего известного месяца (02.2026) train <- df_clean %>% filter(Дата < ymd("2026-03-01")) # Модель: Ставка ~ Инфляция + тренд + лаг? # Добавим лаг 1 месяца и лаг инфляции, чтобы модель "чувствовала" динамику train <- train %>% mutate( Ставка_лаг1 = lag(Ставка, 1), Инфляция_лаг1 = lag(Инфляция, 1) ) %>% filter(!is.na(Ставка_лаг1)) # Спецификация модели TSLM fit <- train %>% model( tslm_model = TSLM(Ставка ~ Инфляция + Инфляция_лаг1 + Ставка_лаг1 + trend()) ) # Отчёт по модели report(fit)

Смотрим в результаты:

Series: Ставка Model: TSLM Residuals: Min 1Q Median 3Q Max -5.4030 -0.4560 -0.1628 0.1700 11.1960 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 0.5508521 0.3191080 1.726 0.0865 . Инфляция 0.2205066 0.1077472 2.047 0.0426 * Инфляция_лаг1 -0.2436304 0.1045039 -2.331 0.0211 * Ставка_лаг1 0.9475354 0.0329862 28.725 <2e-16 *** trend() 0.0001012 0.0001033 0.980 0.3290 --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 1.388 on 142 degrees of freedom Multiple R-squared: 0.9159, Adjusted R-squared: 0.9135 F-statistic: 386.5 on 4 and 142 DF, p-value: < 2.22e-16

Теперь посмотрим, какая ставка ЦБ будет в марте 2026г:

# ====================================================== # 4. Прогноз на следующий месяц (03.2026) # ====================================================== # Создаём новые данные для прогноза future <- new_data(train, 1) %>% mutate( Инфляция = 5.59, # последнее известное значение (12.2025) Инфляция_лаг1 = 5.59, Ставка_лаг1 = 16.0 # последняя ставка ) # Прогноз fc <- fit %>% forecast(new_data = future) # Вывод прогноза print(fc)
> # Вывод прогноза > print(fc) # A fable: 1 x 7 [1D] # Key: .model [1] .model Дата Ставка <chr> <date> <dist> 1 tslm_mod… 2025-12-02 N(16, 2) # ℹ 4 more variables: .mean <dbl>, Инфляция <dbl>, Инфляция_лаг1 <dbl>, # Ставка_лаг1 <dbl>

Построим график, чтобы было наглядно:

# ====================================================== # 5. График с прогнозом # ====================================================== history_base <- df_clean[df_clean$Date >= as.Date("2024-01-01"), ] history_base$Date <- as.Date(history_base$Date) history_base <- as.data.frame(history_base) forecast_val <- as.numeric(fc$.mean) plot(x = c(1, 2), y = c(16, forecast_val), type = "b", col = c("blue", "red"), xlab = "", ylab = "Ставка (%)", xaxt = "n", main = paste("Прогноз ставки на март 2026:", round(forecast_val, 1), "%"), ylim = c(10, 20)) axis(1, at = 1:2, labels = c("Фев 2026\n(факт)", "Мар 2026\n(прогноз)"))
График ставки ЦБ на март 2026
График ставки ЦБ на март 2026

Итоги

Наш вердикт как профессионального серфера по волнам биржевых котировок - ставка останется на текущем уровне в 16%

Хотите знать больше?

Подписывайтесь на мой канал в Я.Дзен, Teletype и Telegram

ВАЖНО! Не является инвестиционной или финансовой рекомендацией. Все описанное - только отражение личного опыта автора и его размышления. Я никого не убеждаю и не побуждаю к действиям. Любые инвестиции это только Ваш выбор.

@drunkenpin
1
1
1 комментарий