Ruey S. Tsay《时间序列分析》Python实现笔记:移动平均模型与ARMA模型

  • 时间:2025-12-03 21:54 作者: 来源: 阅读:1
  • 扫一扫,手机访问
摘要:第三章深度解析:移动平均模型(MA)与ARMA模型 在上一章我们掌握了AR模型的核心逻辑——用历史数据预测当前趋势,而第三章则进一步拓展了线性时间序列的工具箱:MA(移动平均)模型聚焦“随机冲击的持续影响”,ARMA模型则融合AR与MA的优势,成为更强大的建模工具。这一章的理论不仅能深化对时间序列“记忆性”的理解,更能提炼出适配量化交易的高效因子。 一、MA模型:捕捉随机冲击的持续回响 提到

第三章深度解析:移动平均模型(MA)与ARMA模型

在上一章我们掌握了AR模型的核心逻辑——用历史数据预测当前趋势,而第三章则进一步拓展了线性时间序列的工具箱:MA(移动平均)模型聚焦“随机冲击的持续影响”,ARMA模型则融合AR与MA的优势,成为更强大的建模工具。这一章的理论不仅能深化对时间序列“记忆性”的理解,更能提炼出适配量化交易的高效因子。

一、MA模型:捕捉随机冲击的持续回响

提到“移动平均”,很多人会立刻联想到价格的SMA/EMA指标,但时间序列中的MA模型完全是另一回事。它的核心是追踪“不可预测的随机误差”对市场的持续影响,这是量化分析中极易混淆的关键点,必须首先厘清。

1. 核心思想与数学本质

MA模型的逻辑是:当前市场收益(R)是过去若干期“随机冲击”(白噪声a)的线性组合。这里的“随机冲击”可以理解为突发利好、利空消息等无法提前预判的事件,MA模型要捕捉的正是这些事件影响在市场中的“消散过程”。

MA(q)模型的数学表达式为:

R = μ + a + θ·a + θ·a + ... + θ·a

其中各参数含义:

μ:序列均值(金融收益率序列的均值通常接近0,可简化处理)

a:当期白噪声,满足均值为0、方差恒定的特性

θ~θ:冲击的持续影响系数,系数越大说明该期冲击对当前的影响越强

q:模型阶数,代表纳入“过去q期冲击”进行分析

2. 金融直觉与应用场景

MA模型的金融意义非常直观:一次突发消息(如央行加息、公司暴雷)不会只影响当天的价格,其冲击力会在后续交易日逐渐减弱。例如,某利好消息导致当期收益暴涨(a为正),θ为0.3意味着次日收益仍会受到该消息30%的正向影响,θ为0.1则说明第三日影响降至10%。

3. 关键识别特征:ACF截尾、PACF拖尾

判断一个序列是否适合MA模型,核心看ACF(自相关函数)和PACF(偏自相关函数)的图形特征:

ACF图:在滞后q阶后“突然截尾”(即滞后超过q阶的自相关系数变得不显著),这是MA模型最核心的识别标志——说明超过q期的冲击对当前已无影响。

PACF图:呈现“拖尾”特征(自相关系数逐渐衰减至0),无明显截尾点。

二、ARMA模型:融合趋势与冲击的强大工具

AR模型擅长捕捉序列的“自相关趋势”(动量/反转),MA模型擅长捕捉“随机冲击的持续影响”,而ARMA模型将两者结合,用更简约的参数描述更复杂的时间序列规律,是线性时间序列分析的“中坚力量”。

1. 核心思想与数学模型

ARMA(p, q)模型的本质是AR(p)与MA(q)的叠加,其逻辑是:当前收益由“自身历史收益”和“过去随机冲击”共同决定。数学表达式为:

R = φ + φ·R + ... + φ·R + a + θ·a + ... + θ·a

其中φ系列为AR部分的自回归系数,θ系列为MA部分的冲击系数,p和q分别代表AR和MA的阶数。

2. 为什么ARMA模型更强大?

金融时间序列往往同时具备两种特性:既受前期价格的动量影响(AR特征),又受突发消息的持续冲击(MA特征)。ARMA模型的优势在于:

简约性:用更少的参数(p+q个)就能拟合出比高阶AR或MA模型更精准的效果,避免过度拟合。

全面性:同时覆盖“可预测趋势”和“不可预测冲击”,解释力更强。

3. 识别难点:ACF与PACF均拖尾

与AR、MA模型明确的截尾特征不同,ARMA(p, q)的ACF和PACF图均呈现“拖尾”现象,无法直接通过图形判断p和q的取值。此时需要借助信息准则(如AIC、BIC)来筛选最优模型——对不同(p, q)组合的模型计算AIC值,选择AIC最小的组合(AIC值越小,模型拟合效果越好且越简约)。

三、时间序列建模的黄金流程:识别→估计→诊断

第三章的核心价值不仅在于模型本身,更在于提出了一套可复用的时间序列建模流程,这套流程适用于所有量化因子开发,务必掌握:

1. 模型识别(Identification):明确“用什么模型”

这是建模的基础,核心任务是确定模型类型和阶数:

第一步:检验序列平稳性(如ADF单位根检验),非平稳序列需通过差分等方式转化为平稳序列(如收益率序列)。

第二步:绘制ACF和PACF图,根据截尾/拖尾特征初步判断模型类型(AR看PACF截尾,MA看ACF截尾,ARMA看两者均拖尾)。

第三步:结合信息准则(AIC/BIC)确定具体阶数,如ARMA(1,1)、ARMA(2,1)等。

2. 参数估计(Estimation):算出“模型的系数”

在确定模型结构后,需要估计其中的系数(φ和θ),常用方法有两种:

最小二乘法(OLS):适用于简单模型,通过最小化“实际值与预测值的误差平方和”来求解系数。

最大似然估计(MLE):更适用于ARMA这类复杂模型,通过寻找“使当前序列出现概率最大”的系数组合来估计参数。

3. 模型诊断(Diagnostic Checking):验证“模型好不好”

模型拟合后必须经过诊断,确保其有效性,核心标准是“残差为白噪声”——即模型已捕捉序列中所有可预测信息,剩余误差无法再被预测:

残差ACF图:残差的自相关系数应全部落入置信区间内(无显著自相关)。

Ljung-Box检验:原假设为“残差是白噪声”,若检验p值>0.05(通常显著性水平),则接受原假设,模型有效;否则需重新回到识别阶段。

四、实战落地:从ARMA/MA模型提炼量化因子

直接滚动拟合ARMA模型计算量较大,不适合高频场景,但我们可以提取其核心思想,设计轻量化的实战因子。以下三个因子均基于第三章理论,可直接嵌入策略框架。

1. 残差动量因子:捕捉“未被预测的异常波动”

ARMA模型的精髓是“分离可预测部分与随机冲击”,残差(实际收益-预测收益)代表了“意想不到的新信息”,这类信息的动量往往具有交易价值。



def residual_momentum_factor(*args):
    """
    残差动量因子 - 基于ARMA思想,捕捉模型无法解释的异常波动动量
    参数说明:
        args[0] (DataFrame): 输入数据,含"close"列,索引为时间
        args[1] (int): 滚动窗口大小,建议30-60
        args[2] (str): 输出因子列名称
    返回:
        DataFrame: 含原始数据及因子列的数据框
    """
    df = args[0].copy().sort_index()
    n = args[1]
    factor_name = args[2]
    
    # 计算收益率序列
    returns = df['close'].pct_change().fillna(0)
    
    # 步骤1:用简单模型(AR(1))拟合"可预测部分"
    # 实际应用中可替换为更精准的ARMA模型
    predicted_returns = returns.shift(1)  # 简化版AR(1):用前一期收益预测当期
    # 若需更精准,可调用statsmodels的ARIMA函数(ARIMA(p,0,q)即ARMA(p,q))
    
    # 步骤2:计算残差(实际收益 - 可预测收益)
    residuals = returns - predicted_returns
    
    # 步骤3:残差滚动均值作为因子(捕捉异常冲击的持续影响)
    df[factor_name] = residuals.rolling(window=n).mean()
    
    return df
2. 波动集群性因子:MA思想的直接应用

MA模型描述的“冲击持续性”对应金融学中的“波动集群效应”(大波动后跟随大波动),该因子通过捕捉这种效应,为仓位管理和止损设置提供依据。



import numpy as np
 
def volatility_clustering_factor(*args):
    """
    波动集群性因子 - 基于MA模型思想,捕捉波动率的持续性特征
    参数说明:与残差动量因子一致
    """
    df = args[0].copy().sort_index()
    n = args[1]
    factor_name = args[2]
    
    # 计算收益率及波动幅度(收益绝对值)
    returns = df['close'].pct_change().fillna(0)
    abs_returns = np.abs(returns)  # 绝对值代表当期波动大小
    
    # 核心逻辑:用过去波动与未来波动的相关性衡量集群效应
    # 相关性越高,说明波动持续性越强(MA冲击持续影响越明显)
    df[factor_name] = abs_returns.rolling(window=n).corr(abs_returns.shift(1))
    
    # 填充NaN值(前n+1个数据)
    df[factor_name] = df[factor_name].fillna(0)
    
    return df
3. 模型拟合优度因子:衡量“市场的可预测性”


def model_fit_factor(*args):
    """
    模型拟合优度因子 - 衡量市场的可预测性
    """
    df = args[0]
    n = args[1]
    factor_name = args[2]
 
    returns = df['close'].pct_change().fillna(0)
    df[factor_name] = np.nan
 
    for i in range(n, len(df)):
        window_returns = returns.iloc[i-n:i]
        if len(window_returns) < 10:
            continue
 
        # 拟合一个简单模型(如AR(1))并计算R²
        # R²越高,说明序列自相关性越强,越容易预测
        try:
            x = window_returns[:-1].values.reshape(-1, 1)
            y = window_returns[1:].values
            if len(x) == 0 or len(y) == 0:
                continue
 
            from sklearn.linear_model import LinearRegression
            model = LinearRegression()
            model.fit(x, y)
            r_squared = model.score(x, y)
            df.iloc[i, df.columns.get_loc(factor_name)] = r_squared
        except:
            pass
 
    return df

  • 全部评论(0)
最新发布的资讯信息
【系统环境|】创建一个本地分支(2025-12-03 22:43)
【系统环境|】git 如何删除本地和远程分支?(2025-12-03 22:42)
【系统环境|】2019|阿里11面+EMC+网易+美团面经(2025-12-03 22:42)
【系统环境|】32位单片机定时器入门介绍(2025-12-03 22:42)
【系统环境|】从 10 月 19 日起,GitLab 将对所有免费用户强制实施存储限制(2025-12-03 22:42)
【系统环境|】价值驱动的产品交付-OKR、协作与持续优化实践(2025-12-03 22:42)
【系统环境|】IDEA 强行回滚已提交到Master上的代码(2025-12-03 22:42)
【系统环境|】GitLab 15.1发布,Python notebook图形渲染和SLSA 2级构建工件证明(2025-12-03 22:41)
【系统环境|】AI 代码审查 (Code Review) 清单 v1.0(2025-12-03 22:41)
【系统环境|】构建高效流水线:CI/CD工具如何提升软件交付速度(2025-12-03 22:41)
手机二维码手机访问领取大礼包
返回顶部