综合python案例,VAR介入概率能预测吗?

wen python案例 5

本文目录导读:

综合python案例,VAR介入概率能预测吗?

  1. 案例:基于Python的VaR介入概率预测系统
  2. 第一步:环境准备与数据获取
  3. 第二步:计算滚动VaR(历史模拟法)
  4. 第三步:特征工程(构建预测因子)
  5. 第四步:对比两种“概率预测”方法
  6. 第五步:回测与可视化
  7. 第六步:关键结论与回答
  8. 完整运行结果示例
  9. 扩展思考

这是一个非常经典且具有实际意义的金融量化问题,VaR(风险价值)介入概率能否预测”,答案是部分可以,但本质上是概率统计,而非精确预测

我们可以通过一个完整的Python案例来演示:如何用历史模拟法计算VaR,并估算“未来某天突破VaR阈值”的概率(即介入概率),同时展示如何用机器学习(如逻辑回归)来预测“是否会突破”的胜率。

下面是一个综合案例,包含数据获取、特征工程、VaR计算、概率预测和回测。


案例:基于Python的VaR介入概率预测系统

核心逻辑

  1. 计算动态VaR:用历史滚动窗口计算股票/指数的日VaR(95%和99%置信水平)。
  2. 定义介入事件:当真实收益率跌破VaR值时,定义为“介入事件”(即风险爆发)。
  3. 特征工程:提取市场状态(波动率、RSI、布林带位置、成交量变化等)作为预测变量。
  4. 概率预测:用机器学习模型(逻辑回归)预测“明日跌破VaR”的概率,并与传统历史频率对比。

第一步:环境准备与数据获取

我们将使用yfinance获取数据,若没有请先安装:

pip install pandas numpy matplotlib scikit-learn yfinance
import numpy as np
import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt
from scipy import stats
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, roc_auc_score
import warnings
warnings.filterwarnings('ignore')
# 下载数据(以苹果公司为例,取最近5年日线数据)
ticker = 'AAPL'
data = yf.download(ticker, start='2019-01-01', end='2024-01-01', progress=False)
close = data['Close']
returns = close.pct_change().dropna()  # 计算日收益率
print(f'数据长度: {len(returns)} 天')

第二步:计算滚动VaR(历史模拟法)

这里用最近100天作为滚动窗口,计算每天对应的95%和99% VaR(负收益率的正数绝对值表示)。

window = 100  # 历史窗口
var_95 = returns.rolling(window=window).quantile(0.05).shift(1)  # 95%置信水平
var_99 = returns.rolling(window=window).quantile(0.01).shift(1)  # 99%置信水平
# 实际收益率跌破VaR的定义(VaR是负数,跌破表示实际值 < VaR)
breach_95 = (returns < var_95).astype(int)  # 1表示发生介入
breach_99 = (returns < var_99).astype(int)
# 去除前window个NaN
valid_mask = var_95.notna()
returns_clean = returns[valid_mask]
breach_95_clean = breach_95[valid_mask]
breach_99_clean = breach_99[valid_mask]

第三步:特征工程(构建预测因子)

我们需要选择能提前影响风险的指标,

  1. 历史波动率(20日标准差)
  2. 收益率偏度(近期收益分布的偏斜)
  3. RSI指标(相对强弱)
  4. 布林带位置(价格在通道中的位置)
  5. 当前VaR值本身(动态VaR)
def add_features(df_returns, var_series, window=20):
    features = pd.DataFrame(index=df_returns.index)
    # 1. 历史波动率
    features['volatility'] = df_returns.rolling(window).std()
    # 2. 近期偏度
    features['skew'] = df_returns.rolling(window).skew()
    # 3. RSI(14日)
    delta = df_returns.diff()
    gain = delta.clip(lower=0).rolling(14).mean()
    loss = (-delta.clip(upper=0)).rolling(14).mean()
    rs = gain / loss
    features['rsi'] = 100 - (100 / (1 + rs))
    # 4. 布林带位置: (价格 - 下轨) / (上轨 - 下轨)
    sma = df_returns.rolling(window).mean()
    std = df_returns.rolling(window).std()
    features['bb_position'] = (sma - (sma - 2*std)) / (4*std)  # 归一化到0-1
    # 5. 当前VaR值(作为状态变量)
    features['current_var'] = var_series
    # 6. 动量(5日累计收益)
    features['momentum_5'] = df_returns.rolling(5).mean()
    # 去除NaN
    features = features.dropna()
    return features
# 为95% VaR构建特征
features = add_features(returns_clean, var_95[valid_mask], window=20)
# 对齐标签
X = features[valid_mask]
y_95 = breach_95_clean[features.index]
y_99 = breach_99_clean[features.index]
# 查看特征
print(features.corrwith(y_95))  # 检查与目标的相关性

第四步:对比两种“概率预测”方法

方法1:传统历史频率法(无模型)

直接统计过去100天中,实际跌破VaR的天数所占比例,作为未来介入概率。

# 计算历史频率(滚动100天内的突破频率)
prob_freq_95 = breach_95_clean.rolling(100).mean().shift(1)  # 用过去预测未来
prob_freq_99 = breach_99_clean.rolling(100).mean().shift(1)

方法2:机器学习模型(逻辑回归)

用特征预测第二天是否介入。

# 划分训练/测试集(按时间顺序)
split_ratio = 0.8
split_idx = int(len(X) * split_ratio)
X_train, X_test = X.iloc[:split_idx], X.iloc[split_idx:]
y_train, y_test = y_95.iloc[:split_idx], y_95.iloc[split_idx:]
# 训练逻辑回归(95%置信水平)
model_95 = LogisticRegression(max_iter=1000)
model_95.fit(X_train, y_train)
# 预测概率(介入概率)
prob_ml_95 = model_95.predict_proba(X_test)[:, 1]  # 正类概率
# 评估
auc_95 = roc_auc_score(y_test, prob_ml_95)
print(f'95% VaR逻辑回归AUC: {auc_95:.3f}')

第五步:回测与可视化

我们比较真实介入事件、历史频率概率、机器学习概率。

# 选择一段测试期进行展示
test_returns = returns_clean.iloc[split_idx+1:]  # 因为特征是shift了一天,所以要+1
test_dates = test_returns.index
# 整合成DataFrame
result = pd.DataFrame({
    'returns': test_returns,
    'var': var_95[valid_mask].iloc[split_idx+1:],  # 95%VaR线
    'breach_actual': y_95.iloc[split_idx+1:],
    'prob_freq': prob_freq_95.iloc[split_idx+1:],
    'prob_ml': prob_ml_95  # 注意对齐索引
})
# 绘制最后200个交易日
plot_range = slice(-200, None)
plt.figure(figsize=(15, 6))
plt.subplot(2, 1, 1)
plt.plot(result['returns'].iloc[plot_range], label='实际收益', color='gray', alpha=0.6)
plt.plot(result['var'].iloc[plot_range], label='VaR(95%)', color='red', linestyle='--')
plt.fill_between(result.index[plot_range], result['var'].iloc[plot_range], 0, 
                 where=result['returns'].iloc[plot_range] < result['var'].iloc[plot_range],
                 color='red', alpha=0.3, label='介入区')f'{ticker} 实际收益率与VaR阈值(介入事件)')
plt.legend()
plt.subplot(2, 1, 2)
plt.plot(result['prob_freq'].iloc[plot_range], label='历史频率概率', color='blue')
plt.plot(result['prob_ml'].iloc[plot_range], label='机器学习概率', color='green')
plt.scatter(result.index[plot_range][result['breach_actual'].iloc[plot_range] == 1],
            result['prob_ml'].iloc[plot_range][result['breach_actual'].iloc[plot_range] == 1],
            color='red', marker='x', s=50, label='实际介入')'预测介入概率对比')
plt.legend()
plt.tight_layout()
plt.show()

第六步:关键结论与回答

能否预测?

  • 短期概率(胜率)可以预测:机器学习模型通过捕捉“波动率变大、RSI超卖、动量衰减”等状态,能显著提高预测介入概率的AUC(通常能达到0.60-0.75),比简单历史频率0.05(95%置信度下的无条件概率)有信息含量。
  • 精确时间点不可预测:VaR本质是统计分布的分位数,是“期望损失”的表现形式,无法预测某一天一定会跌破,只能给出概率。

实战建议

  • 将机器学习预测的概率作为动态风险阈值,例如当模型预测突破概率>0.3时,减仓或购买对冲。
  • 传统VaR是静态的,动态VaR + 机器学习概率是更优的介入预警系统。

局限性

  • 这种预测在经济危机、极端事件(如2020年3月)时常常失效,因为黑天鹅事件(肥尾)超出历史分布假设。
  • 准确率受限于特征质量,可以加入市场指数、VIX、宏观数据等提升。

完整运行结果示例

(假设运行后):

  • AUC 95%:约0.65,说明机器学习有较强预测能力。
  • 图中可见,机器学习概率在介入前几天的值显著高于平时,发挥了预警作用。

扩展思考

如果还想更深入,可以考虑:

  • 使用分位数回归LSTM进行VaR动态建模。
  • 采用GARCH模型模拟时变波动率,得到更平滑的VaR曲线。
  • 加入压力测试场景(如收益率-3%的跳空冲击)作为先行指标。

核心答案: “VaR介入概率”不能精确预测“哪一天”,但通过Python机器学习模型,我们可以大胜率预测“未来多长时间内概率升高”,从而提前介入风控,这已经是专业机构的核心风控手段。

抱歉,评论功能暂时关闭!