Фьючерсы на Brent являются международным эталоном для мировых цен на нефть, их мониторят нефтяные трейдеры во всем мире. Они представляют собой контракты, которые обязывают покупателя приобрести, а продавца продать определенное количество нефти в будущем по цене, согласованной сегодня.
Профессиональный анализ фьючерсов на нефть Brent может дать значительное преимущество трейдерам и инвесторам, особенно если применять современные методы анализа данных и машинного обучения. В этой статье я поделюсь методами анализа фьючерсов на нефть Brent с использованием Python и библиотек Pandas, Sklearn, Hmmlearn, которые я успешно применяю в своей работе с биржевыми данными.
Традиционные подходы к анализу фьючерсов на Brent, такие как технический анализ с использованием скользящих средних или индикаторов вроде RSI, часто оказываются недостаточно эффективными. Вместо этого, я предпочитаю использовать многофакторные модели, анализ временных рядов с учетом фундаментальных факторов и методы машинного обучения для выявления скрытых паттернов в данных.
Настройка окружения
Прежде чем углубиться в анализ, необходимо создать эффективное рабочее окружение с необходимыми инструментами. Я часто использую Jupyter Notebook для исследования данных и Python с библиотеками Pandas, NumPy, scikit-learn и PyTorch для анализа и моделирования.
Вот пример базовой настройки окружения:
# Импортируем необходимые библиотеки
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import yfinance as yf
from datetime import datetime, timedelta
import statsmodels.api as sm
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import warnings
# Отключаем предупреждения для более чистого вывода
warnings.filterwarnings('ignore')
# Настройка визуализации
plt.style.use('seaborn-v0_8-darkgrid')
plt.rcParams['figure.figsize'] = (14, 8)
plt.rcParams['font.size'] = 12
sns.set_palette('viridis')
# Настройка вывода Pandas
pd.set_option('display.max_columns', None)
pd.set_option('display.width', 200)
pd.set_option('display.float_format', '{:.4f}'.format)
Эта настройка позволяет эффективно работать с биржевыми данными и получать информативные визуализации.
Получение и предварительная обработка данных
Первым шагом в анализе фьючерсов является получение качественных исторических данных. Я обычно использую API Yahoo Finance через библиотеку yfinance, так как она обеспечивает доступ к историческим данным с достаточной частотой для большинства аналитических задач.
Вот пример кода для получения данных фьючерсов на Brent:
# Определяем период анализа - последние 5 лет
end_date = datetime.now()
start_date = end_date - timedelta(days=365*5)
# Используем тикер BZ=F для фьючерсов на нефть Brent
brent_data = yf.download('BZ=F', start=start_date, end=end_date)
# Выводим информацию о полученных данных
print(f"Период данных: {brent_data.index.min()} - {brent_data.index.max()}")
print(f"Количество торговых дней: {len(brent_data)}")
print(f"Процент пропущенных значений: {brent_data.isnull().mean().mean() * 100:.2f}%")
print("\nПервые 5 строк данных:")
print(brent_data.head())
Период данных: 2020-05-04 00:00:00 - 2025-05-01 00:00:00
Количество торговых дней: 1258
Процент пропущенных значений: 0.00%
Первые 5 строк данных:
Price Close High Low Open Volume
Ticker BZ=F BZ=F BZ=F BZ=F BZ=F
Date
2020-05-04 27.2000 28.0800 25.4800 26.2100 30309
2020-05-05 30.9700 31.6900 27.8000 27.9400 38518
2020-05-06 29.7200 32.4900 28.6700 31.8800 37505
2020-05-07 29.4600 31.8400 29.0700 30.1200 36701
2020-05-08 30.9700 31.1300 29.4000 29.4300 20277
После получения данных необходимо провести их предварительную обработку для обеспечения качества анализа. Данный этап включает в себя:
- Обработку пропущенных значений;
- Обнаружение и устранение выбросов;
- Проверку на стационарность;
- Создание дополнительных признаков.
Вот пример кода для предварительной обработки данных:
def preprocess_brent_data(df):
# Создаем копию данных для безопасной обработки
brent = df.copy()
# Обработка пропущенных значений
brent.fillna(method='ffill', inplace=True)
# Создание дополнительных признаков
# Логарифмические доходности
brent['log_return'] = np.log(brent['Close'] / brent['Close'].shift(1))
# Волатильность (скользящее стандартное отклонение)
brent['volatility_20d'] = brent['log_return'].rolling(window=20).std() * np.sqrt(252)
# Относительная сила (отношение к среднему за последние 60 дней)
brent['relative_strength'] = brent['Close'] / brent['Close'].rolling(window=60).mean()
# Индикатор объема (нормализованный объем)
brent['volume_norm'] = brent['Volume'] / brent['Volume'].rolling(window=20).mean()
# Временные признаки
brent['day_of_week'] = brent.index.dayofweek
brent['month'] = brent.index.month
brent['quarter'] = brent.index.quarter
# Удаление первых строк с NaN из-за сдвига
brent.dropna(inplace=True)
return brent
# Предобработка данных
brent_processed = preprocess_brent_data(brent_data)
# Выводим информацию о предобработанных данных
print("Статистика предобработанных данных:")
print(brent_processed.describe())
Статистика предобработанных данных:
Price Close High Low Open Volume log_return volatility_20d relative_strength volume_norm day_of_week month quarter
Ticker BZ=F BZ=F BZ=F BZ=F BZ=F
count 1199.0000 1199.0000 1199.0000 1199.0000 1199.0000 1199.0000 1199.0000 1199.0000 1199.0000 1199.0000 1199.0000 1199.0000
mean 78.7179 79.9293 77.4107 78.6838 30250.9199 0.0003 0.3246 1.0140 1.0119 2.0284 6.5830 2.5271
std 16.3957 16.8537 15.9536 16.4009 13297.4775 0.0219 0.1274 0.0822 0.3641 1.3961 3.5100 1.1378
min 37.4600 38.0200 35.7300 37.4200 0.0000 -0.1411 0.1268 0.8408 0.0000 0.0000 1.0000 1.0000
25% 72.2250 73.2050 71.1300 72.1000 22392.5000 -0.0112 0.2280 0.9562 0.8017 1.0000 3.0000 1.0000
50% 79.2100 80.3800 78.0800 79.2300 29152.0000 0.0020 0.3108 1.0044 1.0212 2.0000 7.0000 3.0000
75% 86.1950 87.2250 85.1850 86.3000 36260.0000 0.0135 0.3907 1.0626 1.2076 3.0000 10.0000 4.0000
max 127.9800 137.0000 122.5000 129.5700 127044.0000 0.0843 0.9174 1.4401 3.0108 4.0000 12.0000 4.000
При работе с фьючерсами важно также учитывать структуру контрактов и «контанго» (ситуация, когда цены фьючерсных контрактов с более длительным сроком истечения выше, чем с более коротким) или «бэквордацию» (обратная ситуация).
Исследовательский анализ данных фьючерсов на Brent
После предварительной обработки данных необходимо провести всесторонний исследовательский анализ для выявления характеристик и паттернов в данных фьючерсов на нефть марки Brent. Этот этап позволяет лучше понять природу движения цен на нефть и выявить потенциальные факторы, влияющие на рынок.
Вот примеры визуализаций и анализа, которые я обычно выполняю:
def exploratory_analysis(df):
# Визуализация изменения цены закрытия
plt.figure(figsize=(16, 8))
plt.plot(df.index, df['Close'], color='blue', linewidth=2)
plt.title('Динамика цены фьючерса на Brent', fontsize=16)
plt.xlabel('Дата', fontsize=14)
plt.ylabel('Цена (USD)', fontsize=14)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# Анализ дневных логарифмических доходностей
plt.figure(figsize=(16, 10))
plt.subplot(2, 1, 1)
plt.plot(df.index, df['log_return'], color='green', linewidth=1)
plt.title('Дневные логарифмические доходности', fontsize=16)
plt.xlabel('Дата', fontsize=14)
plt.ylabel('Лог. доходность', fontsize=14)
plt.grid(True, alpha=0.3)
plt.subplot(2, 1, 2)
sns.histplot(df['log_return'], kde=True, bins=50, color='green')
plt.title('Распределение логарифмических доходностей', fontsize=16)
plt.xlabel('Лог. доходность', fontsize=14)
plt.ylabel('Частота', fontsize=14)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# Анализ волатильности
plt.figure(figsize=(16, 6))
plt.plot(df.index, df['volatility_20d'], color='red', linewidth=2)
plt.title('20-дневная волатильность фьючерса на Brent (годовая)', fontsize=16)
plt.xlabel('Дата', fontsize=14)
plt.ylabel('Волатильность', fontsize=14)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# Анализ сезонности
plt.figure(figsize=(16, 12))
plt.subplot(2, 1, 1)
monthly_returns = df.groupby(df.index.month)['log_return'].mean() * 21 # приблизительно 21 торговый день в месяце
months = ['Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек']
sns.barplot(x=months, y=monthly_returns.values, palette='viridis')
plt.title('Средняя месячная доходность', fontsize=16)
plt.xlabel('Месяц', fontsize=14)
plt.ylabel('Доходность (%)', fontsize=14)
plt.grid(True, alpha=0.3)
plt.subplot(2, 1, 2)
dow_returns = df.groupby(df.index.dayofweek)['log_return'].mean() * 100 # в процентах
days = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт']
sns.barplot(x=days, y=dow_returns.values, palette='viridis')
plt.title('Средняя дневная доходность по дням недели', fontsize=16)
plt.xlabel('День недели', fontsize=14)
plt.ylabel('Доходность (%)', fontsize=14)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# Автокорреляция доходностей
plt.figure(figsize=(16, 6))
pd.plotting.autocorrelation_plot(df['log_return'])
plt.title('Автокорреляция логарифмических доходностей', fontsize=16)
plt.xlabel('Лаг (дни)', fontsize=14)
plt.ylabel('Автокорреляция', fontsize=14)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# Корреляция между признаками
plt.figure(figsize=(12, 10))
corr_matrix = df[['Close', 'log_return', 'volatility_20d', 'relative_strength', 'volume_norm']].corr()
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', vmin=-1, vmax=1, linewidths=0.5)
plt.title('Корреляционная матрица признаков', fontsize=16)
plt.tight_layout()
plt.show()
# Проводим исследовательский анализ
exploratory_analysis(brent_processed)
Рис. 1: График динамики цены фьючерса на Brent
Рис. 2: Дневные логарифмические доходности фьючерса на Brent
Рис. 3: График 20-дневной аннуализированной волатильности фьючерса на Brent
Рис. 4: Средняя месячная и средняя дневная доходность фьючерса на Brent
Рис. 5: Автокорреляция логарифмических доходностей
Рис. 6: Корреляционная матрица признаков
Этот анализ дает ценную информацию о характеристиках данных фьючерсов на Brent, включая:
- Общую динамику цен;
- Распределение доходностей;
- Изменение волатильности во времени;
- Наличие сезонных паттернов;
- Автокорреляцию доходностей;
- Взаимосвязь между различными признаками.
На основе этого анализа можно делать первые выводы о характере рынка и возможных стратегиях торговли.
Анализ рыночных режимов фьючерсов
Одним из наиболее мощных подходов к анализу рынка фьючерсов на Brent является выявление различных рыночных режимов. Вместо того, чтобы рассматривать рынок как единый непрерывный процесс, я анализирую его как смесь нескольких состояний или режимов, каждый из которых имеет свои уникальные характеристики.
Для этого я использую скрытые марковские модели (Hidden Markov Models, HMM), которые позволяют идентифицировать скрытые состояния на основе наблюдаемых данных. Это особенно полезно для рынка нефти, который часто демонстрирует различные режимы в зависимости от геополитической ситуации, состояния мировой экономики и других факторов.
!pip install hmmlearn
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler
from hmmlearn import hmm
def analyze_market_regimes(df, n_states=3):
# Подготовка данных для HMM
X = np.column_stack([df['log_return'].values, df['volatility_20d'].values])
X = StandardScaler().fit_transform(X) # Стандартизация данных
# Обучение HMM
model = hmm.GaussianHMM(n_components=n_states, covariance_type="full",
n_iter=1000, random_state=42)
model.fit(X)
# Определение скрытых состояний
hidden_states = model.predict(X)
# Создание DataFrame с состояниями
df_with_states = df.copy()
df_with_states['regime'] = hidden_states
# Анализ характеристик каждого режима
regime_stats = {}
for i in range(n_states):
regime_data = df_with_states[df_with_states['regime'] == i]
if regime_data.empty:
print(f"Режим {i} не найден в данных. Пропускаем.")
continue
regime_stats[i] = {
'count': len(regime_data),
'mean_return': regime_data['log_return'].mean() * 252,
'volatility': regime_data['log_return'].std() * np.sqrt(252),
'sharpe': (regime_data['log_return'].mean() * 252) / (regime_data['log_return'].std() * np.sqrt(252)),
'mean_price': float(regime_data['Close'].mean()),
'price_range': (float(regime_data['Close'].min()), float(regime_data['Close'].max()))
}
# Визуализация режимов
plt.figure(figsize=(16, 12))
plt.subplot(3, 1, 1)
for i in range(n_states):
regime_data = df_with_states[df_with_states['regime'] == i]
if not regime_data.empty:
plt.scatter(regime_data.index, regime_data['Close'], label=f'Режим {i+1}', s=15, alpha=0.7)
plt.title('Цены фьючерсов на Brent с выделенными рыночными режимами', fontsize=16)
plt.xlabel('Дата', fontsize=14)
plt.ylabel('Цена (USD)', fontsize=14)
plt.legend()
plt.grid(True, alpha=0.3)
plt.subplot(3, 1, 2)
for i in range(n_states):
regime_data = df_with_states[df_with_states['regime'] == i]
if not regime_data.empty:
plt.scatter(regime_data.index, regime_data['log_return'], label=f'Режим {i+1}', s=15, alpha=0.7)
plt.title('Доходности фьючерсов на Brent с выделенными рыночными режимами', fontsize=16)
plt.xlabel('Дата', fontsize=14)
plt.ylabel('Лог. доходность', fontsize=14)
plt.legend()
plt.grid(True, alpha=0.3)
plt.subplot(3, 1, 3)
for i in range(n_states):
regime_data = df_with_states[df_with_states['regime'] == i]
if not regime_data.empty:
plt.scatter(regime_data.index, regime_data['volatility_20d'], label=f'Режим {i+1}', s=15, alpha=0.7)
plt.title('Волатильность фьючерсов на Brent с выделенными рыночными режимами', fontsize=16)
plt.xlabel('Дата', fontsize=14)
plt.ylabel('Волатильность', fontsize=14)
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# Анализ переходов между режимами
transition_probs = model.transmat_
plt.figure(figsize=(10, 8))
sns.heatmap(transition_probs, annot=True, cmap='viridis',
xticklabels=[f'Режим {i+1}' for i in range(n_states)],
yticklabels=[f'Режим {i+1}' for i in range(n_states)])
plt.title('Матрица переходов между рыночными режимами', fontsize=16)
plt.xlabel('Конечный режим', fontsize=14)
plt.ylabel('Начальный режим', fontsize=14)
plt.tight_layout()
plt.show()
return df_with_states, regime_stats, model
# Пример использования функции:
brent_with_regimes, regime_statistics, hmm_model = analyze_market_regimes(brent_processed)
# Вывод статистики по режимам
print("Статистика рыночных режимов:")
for regime, stats in regime_statistics.items():
print(f"\nРежим {regime+1}:")
print(f"Количество дней: {stats['count']}")
print(f"Средняя годовая доходность: {stats['mean_return']*100:.2f}%")
print(f"Годовая волатильность: {stats['volatility']*100:.2f}%")
print(f"Коэффициент Шарпа: {stats['sharpe']:.2f}")
print(f"Средняя цена: ${stats['mean_price']:.2f}")
print(f"Диапазон цен: ${stats['price_range'][0]:.2f} - ${stats['price_range'][1]:.2f}")
Рис. 7: Цены фьючерсов на нефть Brent, их доходность и волатильность с выделенными режимами рынка методом HMM
Рис. 8: Матрица переходов между рыночными режимами (начальным и конечным)
Статистика рыночных режимов:
Режим 1:
Количество дней: 323
Средняя годовая доходность: 26.82%
Годовая волатильность: 20.39%
Коэффициент Шарпа: 1.32
Средняя цена: $76.33
Диапазон цен: $42.66 — $96.55
Режим 2:
Количество дней: 231
Средняя годовая доходность: 44.62%
Годовая волатильность: 25.73%
Коэффициент Шарпа: 1.73
Средняя цена: $76.55
Диапазон цен: $43.22 — $96.48
Режим 3:
Количество дней: 645
Средняя годовая доходность: -15.87%
Годовая волатильность: 42.31%
Коэффициент Шарпа: -0.38
Средняя цена: $80.69
Диапазон цен: $37.46 — $127.98
Анализ фьючерсов с помощью библиотеки hmmlearn дает представление о различных рыночных режимах. Например, можно выделить режимы с высокой волатильностью и отрицательной доходностью (кризисные периоды), режимы с низкой волатильностью и положительной доходностью (стабильный рост) и т.д.
Понимание текущего рыночного режима и вероятности перехода между режимами может дать значительное преимущество в прогнозировании будущего движения цен.
Анализ межрыночных взаимосвязей фьючерсов
Для полного понимания динамики фьючерсов на нефть Brent важно также анализировать их взаимосвязи с другими финансовыми инструментами и рынками. Я часто исследую корреляции между фьючерсами на Brent и индексами акций, валютными парами, другими товарами и процентными ставками.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import yfinance as yf
from statsmodels.tsa.vector_ar.var_model import VAR
def load_market_data(start_date, end_date):
tickers = {
'brent': 'BZ=F',
'sp500': '^GSPC',
'eurusd': 'EURUSD=X',
'gold': 'GC=F',
'natgas': 'NG=F',
'treasury': '^TNX'
}
raw = yf.download(
tickers=list(tickers.values()),
start=start_date,
end=end_date + pd.Timedelta(days=1),
progress=False,
group_by='ticker',
auto_adjust=True
)
closes = pd.DataFrame()
for name, ticker in tickers.items():
try:
closes[name] = raw[(ticker, 'Close')]
except KeyError:
print(f"[!] No data for {name} ({ticker})")
return closes
def analyze_cross_market_relationships(start_date='2020-01-01', end_date=None):
if end_date is None:
end_date = pd.Timestamp.today().normalize()
prices = load_market_data(pd.to_datetime(start_date), end_date).dropna()
returns = np.log(prices / prices.shift(1)).dropna()
returns.columns = [f"{c}_return" for c in returns.columns]
# Correlation heatmap
plt.figure(figsize=(12, 10))
sns.heatmap(returns.corr(), annot=True, cmap='coolwarm', vmin=-1, vmax=1, linewidths=0.5)
plt.title('Correlation matrix of log-returns', fontsize=16)
plt.tight_layout()
plt.show()
# Rolling correlations
window = 60
rolling_corrs = pd.DataFrame(index=returns.index)
for col in returns.columns:
if col != 'brent_return':
rolling_corrs[f"corr_brent_{col}"] = (
returns['brent_return'].rolling(window).corr(returns[col])
)
plt.figure(figsize=(16, 10))
for col in rolling_corrs:
plt.plot(rolling_corrs.index, rolling_corrs[col], label=col.replace('corr_brent_', '').replace('_return', ''))
plt.axhline(0, color='black', linestyle='--', alpha=0.3)
plt.title(f'Rolling correlation with Brent ({window} days)', fontsize=16)
plt.legend()
plt.grid(alpha=0.3)
plt.tight_layout()
plt.show()
# VAR analysis (min lags = 1)
var_cols = ['brent_return', 'sp500_return', 'gold_return', 'natgas_return']
var_df = returns[var_cols].dropna()
if len(var_df) > 60:
model = VAR(var_df)
selected = model.select_order(maxlags=10).selected_orders['aic']
# enforce at least 1 lag
lag = max(selected, 1)
print(f"Selected lags (AIC): {selected}. Using lag = {lag}.")
results = model.fit(lag)
print(results.summary())
irf = results.irf(10)
for imp in var_cols:
irf.plot(impulse=imp)
plt.suptitle(f"IRF: Shock to {imp}", fontsize=16)
plt.tight_layout()
plt.show()
else:
print("Not enough data for VAR model (need >60 observations).")
results = None
merged = prices.join(returns)
return merged, rolling_corrs, results
# Run function
df, rolling, var_res = analyze_cross_market_relationships(start_date='2024-10-01')
Рис. 9: Корреляционная матрица лог-доходностей между фьючерсом на Brent, индексом SP500, валютной парой EUR-USD, ценами на золото, фьючерсами на газ, 10-летними гос. облигациями США
Рис. 10: График скользящей 60-дневной корреляции фьючерса на нефть Brent с индексом SP500, валютной парой EUR-USD, ценами на золото, фьючерсами на газ, 10-летними гос. облигациями США
Selected lags (AIC): 0. Using lag = 1.
Summary of Regression Results
==================================
Model: VAR
Method: OLS
Date: Thu, 01, May, 2025
Time: 19:11:32
--------------------------------------------------------------------
No. of Equations: 4.00000 BIC: -31.0238
Nobs: 143.000 HQIC: -31.2698
Log likelihood: 1456.20 FPE: 2.22139e-14
AIC: -31.4382 Det(Omega_mle): 1.93607e-14
--------------------------------------------------------------------
Results for equation brent_return
===================================================================================
coefficient std. error t-stat prob
-----------------------------------------------------------------------------------
const -0.001456 0.001640 -0.888 0.375
L1.brent_return -0.015895 0.095397 -0.167 0.868
L1.sp500_return -0.087754 0.122993 -0.713 0.476
L1.gold_return 0.110820 0.148056 0.749 0.454
L1.natgas_return 0.025362 0.032547 0.779 0.436
===================================================================================
Results for equation sp500_return
===================================================================================
coefficient std. error t-stat prob
-----------------------------------------------------------------------------------
const -0.000113 0.001193 -0.095 0.925
L1.brent_return 0.023886 0.069371 0.344 0.731
L1.sp500_return -0.078986 0.089438 -0.883 0.377
L1.gold_return 0.044156 0.107664 0.410 0.682
L1.natgas_return -0.040390 0.023668 -1.707 0.088
===================================================================================
Results for equation gold_return
===================================================================================
coefficient std. error t-stat prob
-----------------------------------------------------------------------------------
const 0.001492 0.000996 1.497 0.134
L1.brent_return -0.019540 0.057949 -0.337 0.736
L1.sp500_return 0.161808 0.074713 2.166 0.030
L1.gold_return -0.064105 0.089937 -0.713 0.476
L1.natgas_return 0.011137 0.019771 0.563 0.573
===================================================================================
Results for equation natgas_return
===================================================================================
coefficient std. error t-stat prob
-----------------------------------------------------------------------------------
const 0.000831 0.004269 0.195 0.846
L1.brent_return -0.142671 0.248269 -0.575 0.566
L1.sp500_return 0.015541 0.320088 0.049 0.961
L1.gold_return 0.299757 0.385314 0.778 0.437
L1.natgas_return -0.165157 0.084704 -1.950 0.051
===================================================================================
Correlation matrix of residuals
brent_return sp500_return gold_return natgas_return
brent_return 1.000000 0.335626 0.373030 0.119037
sp500_return 0.335626 1.000000 0.151260 0.090234
gold_return 0.373030 0.151260 1.000000 0.013505
natgas_return 0.119037 0.090234 0.013505 1.000000
Рис. 11: Анализ функций импульсного отклика — отклик всех переменных на шок в ценах нефти Brent
Рис. 12: Отклик всех активов на шок в котировках SP500
Рис. 13: Отклик всех активов на шок в ценах на золото
Рис. 14: Отклик всех активов на шок в ценах на природный газ
Данный тип анализа помогает выявить, как фьючерсы на Brent взаимодействуют с другими рынками, что может быть использовано для прогнозирования цен и хеджирования рисков.
Заключение
В данной статье мы провели комплексный анализ фьючерсов на нефть марки Brent с использованием современных методов обработки данных. Применяя библиотеки Pandas, Sklearn и Hmmlearn, мы смогли выявить ключевые характеристики и закономерности в поведении цен на нефтяные фьючерсы.
Исследование показало, что рынок фьючерсов Brent не является однородным и характеризуется наличием различных рыночных режимов, которые можно эффективно идентифицировать с помощью скрытых марковских моделей.
Выделенные три режима демонстрируют существенные различия по уровню волатильности, средней доходности и коэффициенту Шарпа. Особенно интересно наблюдать контраст между режимом 2 с высокой годовой доходностью (44.62%) и положительным коэффициентом Шарпа (1.73), и режимом 3 с отрицательной доходностью (-15.87%) и более высокой волатильностью (42.31%). Понимание текущего режима рынка и вероятностей перехода между ними может дать трейдерам значительное преимущество при принятии торговых решений.
Проведенный межрыночный анализ выявил динамические взаимосвязи между фьючерсами Brent и другими финансовыми инструментами. Скользящие корреляции продемонстрировали изменчивость взаимоотношений нефтяных фьючерсов с индексом S&P 500, золотом, валютными парами и другими товарами, что подтверждает необходимость регулярного пересмотра стратегий хеджирования и диверсификации. Примененный VAR-анализ позволил оценить эффекты распространения шоков между рынками и выявить статистически значимые взаимосвязи.
Результаты исследовательского анализа данных показали наличие сезонных паттернов в доходности фьючерсов Brent как по месяцам, так и по дням недели, что может быть использовано при разработке краткосрочных торговых стратегий.
Представленные в статье методы и результаты демонстрируют, что современные технологии анализа данных открывают новые горизонты для понимания и прогнозирования рынка нефтяных фьючерсов, позволяя преодолеть ограничения традиционных подходов к техническому и фундаментальному анализу.