制定符合需要的资产组合需要了解每支的波动率,波动率高的资产意味着价格波动大,风险高,为了降低资产组合的风险,通常会在波动率较低的资产中分配更多的资金。同时波动率也和市场参与者的情绪有关,波动率大,资产不确定性越高,波动率低,可以反应市场或行业的相对平稳。
预测波动率时,可以使用arch模型和Heston模型,下文会提供代码,同时更多与金融、大数据等有关的代码、方案、数据可以关注gzh ‘finance褪黑素’获取。
目录
- 一、波动率的简单定义
- 二、ARCH模型预测
- 三、Heston模型预测
一、波动率的简单定义
根据下图所示的收盘价计算波动率
日收益率 = 当日收盘价 − 前一日收盘价 前一日收盘价 × 100 \text{日收益率} = \frac{\text{当日收盘价} - \text{前一日收盘价}}{\text{前一日收盘价}} \times 100 日收益率=前一日收盘价当日收盘价−前一日收盘价×100
将日收益率数据计算一个给定时间窗口内的标准差,标准差用于表示价格的波动性。
标准差 = ∑ i = 1 N ( 日收益率 i − 平均日收益率 ) 2 N \text{标准差} = \sqrt{\frac{\sum_{i=1}^{N}(\text{日收益率}_i - \text{平均日收益率})^2}{N}} \ 标准差=N∑i=1N(日收益率i−平均日收益率)2
其中,(N) 是时间窗口内的交易日数量。
二、ARCH模型预测
arch模型认为当前时刻的波动性收到过去的影响,过去的波动率对当前的波动率有自回归的影响。
-
ARCH(1) 模型:
σ t 2 = α 0 + α 1 ε t − 1 2 \sigma_t^2 = \alpha_0 + \alpha_1 \varepsilon_{t-1}^2 \ σt2=α0+α1εt−12
其中:- σ t 2 \sigma_t^2 σt2是在时刻 ( t ) 的条件方差(波动性)。
- α 0 \alpha_0 α0 是模型中的常数项。
- α 1 \alpha_1 α1 是自回归系数,表示过去方差对当前方差的影响。
- ε t − 1 2 \varepsilon_{t-1}^2 εt−12 是在 t − 1 \ t-1 t−1 时刻的残差平方。
-
ARCH ( p ) 模型:
对于更一般的ARCH§模型,方程可表示为:
σ t 2 = α 0 + ∑ i = 1 p α i ε t − i 2 \sigma_t^2 = \alpha_0 + \sum_{i=1}^{p} \alpha_i \varepsilon_{t-i}^2 \ σt2=α0+i=1∑pαiεt−i2
其中 p \ p p 是模型中的滞后阶数。
这里的关键是 ε t \varepsilon_t εt 是残差项,表示观测值与其期望值的差异。ARCH模型的训练通常使用最大似然估计等方法,以估计模型参数 α 0 , α 1 , … , α p \alpha_0, \alpha_1, \ldots, \alpha_p α0,α1,…,αp。
ARCH模型通常与GARCH模型使用,arch-garch模型,GARCH模型在ARCH模型的基础上引入了过去的条件方差项,使模型更加灵活,这里只展示arch模型,arch-garch可以看博主其他文章,有介绍。
通过ACF和PACF可以确定模型参数p与q,这里建立arch(1,1)模型。
from arch import arch_model
rolling_predictions = []
window_size = 1000
test_size = len(returns) - window_size
for i in range(test_size):train = returns[i:i+window_size]am = arch_model(train,p=1,q=1)res = am.fit()pred = res.forecast(horizon=1)forecasted_variance = pred.variance.values[-1, :][0]rolling_predictions.append(forecasted_variance)
这里时间窗为1000,通过for循环函数迭代,预测波动率。在建立模型后,观察结果,该模型的参数估计表明市场波动率在一定程度上受到了先前时刻波动率的影响,符合ARCH模型的基本假设。
预测结果显示:
作图观察真实波动率和预测波动率的图形:
其实这张图是处理了异常值后的波动率图,原始图像存在远远超出其他值的点,我观察到大部分数据围绕0.05下的某个数据进行变化,但有一个值在0.3以上,不合理,于是用了平均值替代该异常值。
代码处理如下:
t = np.where(tt > 0.3, tt.mean(), tt)
三、Heston模型预测
Heston模型是动态预测,是随机波动率的一种,捕捉了波动率的动态演变。这个模型的公式包含了股票价格漂移、随机波动和波动率演化,其中有随机参数和需要通过市场情况确定的参数,下面用了最大似然估计参数。
Heston模型的核心方程包括漂移、随机波动和波动率的演化方程。以下是Heston模型的主要方程:
-
股票价格漂移:
d S t = μ S t d t + v t S t d W t S \ dS_t = \mu S_t dt + \sqrt{v_t} S_t dW_t^S \ dSt=μStdt+vtStdWtS- S t \ S_t St 是时刻 t \ t t的股票价格。
- m u \ mu mu 是漂移率。
- v t \ v_t vt是时刻 t \ t t的波动率。
- d W t S \ dW_t^S dWtS是股票价格的随机项(布朗运动)。
-
波动率演化:
d v t = κ ( θ − v t ) d t + ξ v t d W t v \ dv_t = \kappa (\theta - v_t) dt + \xi \sqrt{v_t} dW_t^v \ dvt=κ(θ−vt)dt+ξvtdWtv- v t \ v_t vt 是时刻 t \ t t 的波动率。
- k a p p a \ kappa kappa 是波动率回复速度。
- θ \theta θ是波动率的长期均值。
- ξ \xi ξ 是波动率的波动项。
- d W t v \ dW_t^v dWtv 是波动率的随机项(布朗运动)。
-
股票价格和波动率的协方差项:
d W t S ⋅ d W t v = ρ d t \ dW_t^S \cdot dW_t^v = \rho dt \ dWtS⋅dWtv=ρdt- ρ \rho ρ 是股票价格和波动率之间的相关系数。
# HESTON模型的随机微分方程
def heston_model(params, spot_price, maturity, num_steps):kappa, theta, sigma, rho, v0 = paramsdt = maturity / num_stepsstock_prices = np.zeros(num_steps + 1)volatility = np.zeros(num_steps + 1)stock_prices[0] = spot_pricevolatility[0] = v0for i in range(1, num_steps + 1):dW1 = np.random.normal(0, np.sqrt(dt))dW2 = rho * dW1 + np.sqrt(1 - rho**2) * np.random.normal(0, np.sqrt(dt))stock_prices[i] = stock_prices[i-1] * np.exp((kappa * (theta - volatility[i-1]) - 0.5 * volatility[i-1]) * dt + np.sqrt(volatility[i-1] * dt) * dW1)volatility[i] = np.maximum(0, volatility[i-1] + sigma * np.sqrt(volatility[i-1] * dt) * dW2)return stock_prices, volatilitydef loss_function(params, spot_price, maturity, num_steps, market_data):simulated_prices, simulated_volatility = heston_model(params, spot_price, maturity, num_steps)loss = np.mean((simulated_volatility - market_data)**2)return loss
def loss_function(params, spot_price, maturity, num_steps, market_data):simulated_prices, simulated_volatility = heston_model(params, spot_price, maturity, num_steps)loss = np.mean((simulated_volatility[:len(market_data)] - market_data)**2)return loss
spot_price = data['收盘'].iloc[0]
maturity = len(returns) / 252 # 252个交易日一年
num_steps = len(returns)
market_data = returns.values
initial_params = [1.0, 0.04, 0.1, -0.5, 0.04] # 初始参数猜测值
result = minimize(loss_function, initial_params, args=(spot_price, maturity, num_steps, market_data))
estimated_params = result.x
print("Estimated Parameters:", estimated_params)
结果显示模型参数:
Estimated Parameters: [ 0.99999113 0.03999434 0.09999449 -0.50000155 0.04000012]
导出数据:
import csv
my_single_column_list = t
header = ['结果']
data = [header] + [[item] for item in my_single_column_list]
csv_file_path = '波动率.csv'
with open(csv_file_path, 'w', newline='') as csv_file:csv_writer = csv.writer(csv_file)csv_writer.writerows(data)
print(f'CSV文件已保存至 {csv_file_path}')
更多与金融、大数据等有关的代码、方案、数据可以关注gzh ‘finance褪黑素’获取。