🚀 AI 一键生成 joinquant 策略代码

如何在 JoinQuant 中计算自定义的市场情绪或恐慌指数?

joinquant | 发布时间: 2025/12/3
以下内容由 EasyQuant 生成。

问题描述

怎样计算一个可以衡量市场恐慌情绪的指标?

解决方案

在量化交易中,衡量“市场恐慌情绪”通常没有一个直接的API可以直接调用,但我们可以通过计算**波动率(Volatility)技术指标(如RSI)**来构建一个代理指标。

最常用的衡量恐慌情绪的指标是历史波动率(Historical Volatility, HV)。当市场恐慌时,价格通常会出现剧烈波动,导致波动率飙升。类似于美国的VIX指数(恐慌指数),我们可以计算沪深300指数的历史波动率来作为A股市场的恐慌指标。

以下是几种常见的计算思路:

  1. 历史波动率 (HV):计算指数(如沪深300)过去N天的收益率标准差。数值越高,代表市场越不稳定,恐慌情绪越重。
  2. RSI (相对强弱指标):当RSI极低(如低于20)时,通常代表市场处于超卖状态,往往伴随着恐慌性抛售。
  3. 跌停家数占比:统计全市场当日跌停股票的数量,数量越多,恐慌情绪越强。

下面我将提供一个基于 JoinQuant API 的策略代码,该代码实现了计算沪深300指数的历史波动率作为恐慌指标,并将其可视化。

策略代码实现

这个策略会每天计算沪深300指数过去20个交易日的年化波动率,并在图表中记录。

# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd

def initialize(context):
    """
    初始化函数
    """
    # 设定基准为沪深300
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    # 过滤掉order系列API产生的比error级别低的log
    log.set_level('order', 'error')
    
    # 定义要观察的指数:沪深300
    g.index_security = '000300.XSHG'
    
    # 设定计算波动率的时间窗口(例如过去20天)
    g.window_size = 20
    
    # 每天收盘前运行计算
    run_daily(calculate_market_fear, time='14:50')

def calculate_market_fear(context):
    """
    计算市场恐慌指标(基于历史波动率)
    """
    # 获取过去 N+1 天的收盘价(为了计算 N 个收益率)
    # g.window_size + 1 是因为收益率需要两个价格计算
    hist_data = attribute_history(g.index_security, g.window_size + 1, '1d', ['close'])
    
    if len(hist_data) < g.window_size + 1:
        return

    # 提取收盘价序列
    closes = hist_data['close'].values
    
    # 计算对数收益率: ln(Pt / Pt-1)
    # 使用对数收益率在统计上比简单收益率更优
    log_returns = np.log(closes[1:] / closes[:-1])
    
    # 计算收益率的标准差 (ddof=1 表示样本标准差)
    std_dev = np.std(log_returns, ddof=1)
    
    # 将日波动率转化为年化波动率
    # 股市通常假设一年有 250 个交易日
    annualized_volatility = std_dev * np.sqrt(250) * 100  # 乘以100转为百分比
    
    # 记录日志
    log.info("当前市场恐慌指数(年化波动率): %.2f%%" % annualized_volatility)
    
    # 在回测图表中绘制曲线
    # 如果该值突然飙升(例如超过30%或40%),通常意味着市场进入恐慌状态
    record(Fear_Index=annualized_volatility)
    
    # 简单的策略逻辑示例:
    # 如果恐慌指数过高(例如大于35),可能代表市场风险极大,可以选择空仓(仅作演示)
    if annualized_volatility > 35:
        log.info("恐慌指数过高,清仓避险")
        # order_target(g.index_security, 0) # 实际交易中需要操作具体的ETF或股票
    

代码原理解析

  1. 数据获取 (attribute_history):
    我们获取了沪深300指数(000300.XSHG)过去 N+1 天的收盘价。之所以是 N+1,是因为计算 N 天的涨跌幅需要用到前一天的价格作为基数。

  2. 对数收益率 (np.log):
    公式为 $R_t = \ln(P_t / P_{t-1})$。在金融量化中,计算波动率时通常使用对数收益率,因为它具有时间可加性,且假设价格服从对数正态分布。

  3. 标准差 (np.std):
    标准差衡量了数据的离散程度。收益率的标准差越大,说明价格忽上忽下跳动得越剧烈,代表市场不确定性(风险/恐慌)越高。

  4. 年化处理 (np.sqrt(250)):
    我们计算的是“日波动率”。为了符合通用的“波动率”概念(如VIX),我们需要将其年化。假设一年有250个交易日,年化波动率 = 日波动率 $\times \sqrt{250}$。

如何使用这个指标?

  • 低波动(例如 < 15%):市场情绪平稳,通常对应牛市的缓涨阶段或震荡市。
  • 中波动(例如 15% - 25%):市场正常波动。
  • 高波动(例如 > 30%)恐慌情绪。通常发生在暴跌初期或底部剧烈震荡时。
    • 注意:极高的波动率有时也意味着市场见底(恐慌盘涌出),但也可能意味着下跌趋势的确立。

常见问答 (Q&A)

Q: 为什么不直接使用VIX指数?
A: 中国市场目前没有官方发布的、涵盖全市场的VIX指数历史数据接口供直接回测使用(虽然有针对50ETF的期权波动率指数,但数据获取相对复杂)。使用历史波动率(Historical Volatility)是计算最简便且有效的替代方案。

Q: 除了波动率,还有什么能代表恐慌?
A: RSI指标。你可以使用 jqlib.technical_analysis 中的 RSI 函数。如果 RSI(6) < 10 或 RSI(24) < 20,通常代表短期极度恐慌(超卖)。

Q: 这个指标能预测大跌吗?
A: 波动率通常具有“聚集性”。即高波动往往伴随着后续的高波动。它更多是同步指标滞后指标,用来确认当前市场状态,而不是预测未来。但在量化风控中,当波动率突破阈值时降低仓位(Target Volatility Strategy)是一种非常经典的用法。