Исходный код
Для анализа мы загрузим исторические данные BTC-USD с помощью библиотеки yfinance, рассчитаем логарифмическую доходность и построим линейную регрессию с фиктивными переменными (dummy variables) без константы. Это позволит напрямую оценить среднюю доходность для каждого периода и проверить гипотезу о равенстве нулю коэффициентов.
import yfinance as yf
import pandas as pd
import numpy as np
import statsmodels.formula.api as smf
# 1. Загрузка исторических данных BTC-USD
df = yf.download('BTC-USD', start='2015-01-01', end='2024-12-31')
df['Returns'] = np.log(df['Close'] / df['Close'].shift(1))
df = df.dropna()
# 2. Добавление временных категориальных признаков
df['DayOfWeek'] = df.index.day_name()
df['Month'] = df.index.month_name()
# Сортировка категорий для корректного отображения в результатах
days_order = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
months_order = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
df['DayOfWeek'] = pd.Categorical(df['DayOfWeek'], categories=days_order, ordered=True)
df['Month'] = pd.Categorical(df['Month'], categories=months_order, ordered=True)
# 3. Регрессия по дням недели с поправкой Ньюи-Веста (HAC)
model_day = smf.ols('Returns ~ C(DayOfWeek) - 1', data=df).fit(cov_type='HAC', cov_kwds={'maxlags': 1})
print('=== СЕЗОННОСТЬ ПО ДНЯМ НЕДЕЛИ ===')
print(model_day.summary().tables[1])
# 4. Регрессия по месяцам с поправкой Ньюи-Веста (HAC)
model_month = smf.ols('Returns ~ C(Month) - 1', data=df).fit(cov_type='HAC', cov_kwds={'maxlags': 1})
print('\n=== СЕЗОННОСТЬ ПО МЕСЯЦАМ ===')
print(model_month.summary().tables[1])
Разбор параметров
Returns ~ C(DayOfWeek) - 1: Формула спецификации модели вstatsmodels. ФункцияC()указывает, что переменная категориальная, а- 1убирает свободный член (intercept), чтобы получить абсолютные средние значения для каждого дня, а не отклонения от базового.cov_type='HAC': Использование робастных стандартных ошибок Ньюи-Веста (HAC — Heteroskedasticity and Autocorrelation Consistent) с лагом 1 для корректировки гетероскедастичности и автокорреляции в остатках финансовых временных рядов.pvalues: Значения p-value для каждого коэффициента. Еслиp-value < 0.05, мы отвергаем нулевую гипотезу и считаем сезонность в этот день/месяц статистически значимой.
Как запустить
Установите необходимые библиотеки: pip install pandas numpy yfinance statsmodels. Скопируйте код в файл seasonality_analysis.py и запустите его. Скрипт автоматически выведет сводные таблицы регрессии и подсветит статистически значимые периоды.
После выявления сезонных паттернов и построения торговой стратегии на их основе, критически важно оценить ее эффективность. Для этого отлично подойдет расчет Calmar Ratio и Sortino Ratio на Python.
Также не забывайте про классические метрики риска: вы можете выполнить расчет коэффициента Шарпа и просадки в Python с pandas-ta для полной картины.
Если вы хотите понять, как сезонность биткоина коррелирует с традиционным рынком, полезно провести расчет Бета-коэффициента крипто-портафеля к S&P 500 (SPY) с NumPy Cov.




