Розробка моделі прогнозування волатильності
Прогнозування волатильності — окремірозглад, висок цінна задача в трейдингу. Знання очікуваної волатильності дозволяє: адаптувати розмір позиції, вибрати оптимальну ширину спреду для маркет-мейкингу, правильно оцінити опціони та спланувати управління ризиком.
Метрики волатильності
Реалізована волатильність — історична волатильність, обчислена з історичних прибутків:
import numpy as np
import pandas as pd
def realized_volatility(returns, window=24, annualize=True):
"""
Оцінка Паркінсона RV — стандарт для денних даних
"""
rv = returns.rolling(window).std()
if annualize:
rv = rv * np.sqrt(365 * 24) # річна для годинних даних
return rv
def realized_volatility_parkinson(highs, lows, window=24, annualize=True):
"""
Оцінювач Паркінсона використовує High/Low — ефективніша оцінка
"""
log_hl = (np.log(highs) - np.log(lows)) ** 2
rv_parkinson = np.sqrt(log_hl.rolling(window).mean() / (4 * np.log(2)))
if annualize:
rv_parkinson = rv_parkinson * np.sqrt(365 * 24)
return rv_parkinson
def realized_volatility_garman_klass(opens, highs, lows, closes, window=24):
"""
Гарман-Клас: використовує O/H/L/C — найефективніший оцінювач
"""
log_hl = 0.5 * (np.log(highs/lows)) ** 2
log_co = (2*np.log(2) - 1) * (np.log(closes/opens)) ** 2
gk = np.sqrt((log_hl - log_co).rolling(window).mean() * 365 * 24)
return gk
Моделі GARCH
GARCH(1,1) — класична модель умовної волатильності. Волатильність сьогодні залежить від волатильності вчора та квадрата вчорашнього прибутку:
from arch import arch_model
import warnings
def fit_garch_model(returns, model_type='GARCH', p=1, q=1, vol='GARCH', dist='t'):
"""
dist='t': розподіл Стьюдента краще описує крипто-товстохвости
"""
# прибутки у відсотках для чисельної стійкості
returns_pct = returns * 100
model = arch_model(
returns_pct,
vol=vol, # 'GARCH', 'EGARCH', 'GJR-GARCH'
p=p, q=q,
dist=dist, # 'normal', 't', 'ged'
mean='Constant'
)
with warnings.catch_warnings():
warnings.simplefilter('ignore')
result = model.fit(disp='off', options={'maxiter': 500})
return result
def forecast_volatility_garch(garch_result, horizon=24):
"""Прогнозування волатильності на наступні N періодів"""
forecast = garch_result.forecast(horizon=horizon, reindex=False)
# Умовна дисперсія (потім беремо sqrt для std)
variance_forecast = forecast.variance.values[-1]
vol_forecast = np.sqrt(variance_forecast) / 100 # назад до одиниць
return vol_forecast
# EGARCH: асиметрична модель (погані новини > добрі новини в волатильності)
# GJR-GARCH: аналогічно, ефект левериджу
ML моделі для волатильності
HAR-RV (Гетерогенна авторегресійна реалізована волатильність): лінійна модель з різними горизонтами:
def create_har_features(realized_vol, horizons=[1, 5, 22]):
"""
Модель HAR: RV передбачається через власні лагові середні значення
"""
features = {}
for h in horizons:
features[f'rv_avg_{h}d'] = realized_vol.rolling(h).mean().shift(1)
return pd.DataFrame(features).dropna()
from sklearn.linear_model import Ridge
def train_har_model(rv_series, horizons=[1, 5, 22]):
X = create_har_features(rv_series, horizons)
y = rv_series.shift(-1).dropna() # передбачити завтрашню RV
# Вирівняти індекси
common_idx = X.index.intersection(y.index)
X, y = X.loc[common_idx], y.loc[common_idx]
model = Ridge(alpha=0.1)
model.fit(X, y)
return model
LSTM для волатильності: захоплює нелінійні паттерни та довгострокову пам'ять:
import torch
import torch.nn as nn
class VolatilityLSTM(nn.Module):
def __init__(self, input_size=10, hidden_size=64, output_horizon=24):
super().__init__()
self.lstm = nn.LSTM(input_size, hidden_size, 2, batch_first=True, dropout=0.2)
self.fc = nn.Sequential(
nn.Linear(hidden_size, 32),
nn.ReLU(),
nn.Linear(32, output_horizon) # передбачити весь горизонт
)
def forward(self, x):
out, _ = self.lstm(x)
return self.fc(out[:, -1, :])
Реалізована GARCH (комбінований підхід)
Поєднує переваги GARCH та реалізованої волатильності:
def realized_garch_forecast(returns, rv_history, omega=0.1, alpha=0.1,
beta=0.8, gamma=0.5):
"""
Спрощена реалізована GARCH:
h_t = omega + alpha * rv_{t-1} + beta * h_{t-1} + gamma * z_{t-1}^2
"""
h = np.zeros(len(returns))
h[0] = rv_history.iloc[0] ** 2
for t in range(1, len(returns)):
h[t] = (omega +
alpha * rv_history.iloc[t-1] ** 2 +
beta * h[t-1] +
gamma * returns.iloc[t-1] ** 2)
return np.sqrt(h)
Оцінювання якості прогнозу волатильності
def evaluate_vol_forecast(actual_rv, predicted_rv):
"""Метрики для оцінки якості прогнозу"""
mse = np.mean((actual_rv - predicted_rv) ** 2)
mae = np.mean(np.abs(actual_rv - predicted_rv))
# Регресія Мінцера-Заровіца (неупередженість прогнозу)
from scipy.stats import linregress
slope, intercept, r_value, p_value, _ = linregress(predicted_rv, actual_rv)
# QLIKE (quasi-likelihood) — стандартна метрика для vol прогнозування
qlike = np.mean(actual_rv / predicted_rv - np.log(actual_rv / predicted_rv) - 1)
return {
'mse': mse, 'mae': mae, 'r_squared': r_value**2,
'mz_slope': slope, 'mz_intercept': intercept,
'qlike': qlike
}
Застосування в торговлі
Розмір позиції: при високій прогнозованій волатильності → зменшити розмір позиції:
def vol_adjusted_position_size(base_size, predicted_vol, target_vol=0.02):
scaling = target_vol / max(predicted_vol, 1e-8)
return base_size * min(scaling, 2.0) # макс 2x від базового
Динамічний стоп-лосс: стоп на N × прогнозована волатильність від входу.
Ціноутворення опціонів: для крипто-опціонів прогнозована волатильність використовується як оцінка дразнівної волатильності.
Розробка системи прогнозування волатильності: GARCH/EGARCH, HAR-RV, LSTM моделі, усереднення ансамблю, інтеграція з розмірами позицій та моніторинг точності прогнозу.







