σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft Academy学习路线
Ctrl K
AO
+1.2k 位学习者
登录加入 ↗
学习路线
AO
+1.2k 位学习者
登录
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Python 学习路线›模块 7 · Alpha 研究与风险›主题 7.8·~1小时高级

ARIMA 模型

路线进度模块 7/11 · 主题 8/9
7.8 ARIMA 模型
—实验得分— / 100总 XP—连续天数—

有自身记忆的序列

许多序列带有关于自身未来的信息。利差、波动率,以及两种相关价格之间的价差,会向某个水平回归,而不是自由漫游。ARIMA 用三个想法捕捉它:I,对序列做差分使其平稳;AR,用序列自身的滞后项做回归;MA,利用最近的预测误差。股票收益率本身几乎没有这种记忆,所以 ARIMA 适用于具有持续性或均值回归的序列。

import numpy as np

prices = np.array([100.0, 101.5, 103.2, 104.1, 106.0, 107.2])

print(np.diff(prices))              # first differences: the changes             [1.5 1.7 0.9 1.9 1.2]
print(np.diff(prices, n=2))         # second differences: the change of the changes
print(np.diff(np.log(prices)))      # the differenced log price is the log return

差分与自相关

价格四处漂移,没有稳定的均值;而它们的变化往往有。取一阶差分(阶数 d = 1)去除趋势,二阶(d = 2)去除弯曲的趋势。随后自相关函数(ACF)展示记忆性:滞后 k 处的值,是序列与 k 步之前的自己之间的相关,sum((x[t] - m) * (x[t+k] - m)) / sum((x[t] - m)**2)。缓慢衰减的 ACF 提示 AR 模型;各滞后处都接近零则说明没有可预测的东西。

# The ACF of a persistent series decays slowly; the ACF of noise is near zero
import numpy as np

def acf(series, lags):
    dev = series - series.mean()
    total = np.sum(dev ** 2)
    return np.array([np.sum(dev[:len(series) - k] * dev[k:]) / total for k in range(1, lags + 1)])

rng = np.random.default_rng(1)
noise = rng.normal(size=500)
persistent = np.empty(500)
persistent[0] = 0.0
for t in range(1, 500):
    persistent[t] = 0.8 * persistent[t - 1] + noise[t]           # an AR(1) with phi = 0.8
print(np.round(acf(persistent, 4), 3))                           # decays slowly: 0.74, 0.58, 0.48, 0.39 in this sample
print(np.round(acf(noise, 4), 3))                                # all near 0
# Differencing a trending series makes its mean stable
import numpy as np

rng = np.random.default_rng(6)
trend = 100 + 0.5 * np.arange(200) + rng.normal(0, 1, size=200).cumsum()          # a trending random walk
changes = np.diff(trend)
print(round(float(trend[:100].mean()), 1), round(float(trend[100:].mean()), 1))     # the level drifts: the halves differ a lot
print(round(float(changes[:100].mean()), 2), round(float(changes[100:].mean()), 2))   # the changes have a similar mean in both halves

拟合 AR(1) 并预测

AR(1) 表示 x[t] = c + phi * x[t-1] + 噪声。它就是把每个值对前一个值做直线回归,所以 phi 是斜率、c 是截距,用的是与 CAPM 一节中贝塔相同的各项和。预测是递推的:第一步是 c + phi * last,之后每一步用上一步的预测。当 |phi| < 1 时,预测会收敛到长期均值 c / (1 - phi),速度由 phi 决定:这是一个均值回归的序列。

import numpy as np

def fit_ar1(series):
    a, b = series[:-1], series[1:]
    phi = np.sum((a - a.mean()) * (b - b.mean())) / np.sum((a - a.mean()) ** 2)
    return float(b.mean() - phi * a.mean()), float(phi)

def forecast_ar1(last, c, phi, steps):
    out, value = [], last
    for _ in range(steps):
        value = c + phi * value
        out.append(value)
    return np.array(out)

rng = np.random.default_rng(3)
x = np.empty(400)
x[0] = 2.0
for t in range(1, 400):
    x[t] = 0.5 + 0.75 * x[t - 1] + rng.normal(0, 0.3)             # true c = 0.5, phi = 0.75, mean 2.0
c, phi = fit_ar1(x)
print(round(c, 3), round(phi, 3))
print(np.round(forecast_ar1(4.0, c, phi, 5), 3), round(c / (1 - phi), 3))
预测不等于交易价差上统计显著的 phi 并不保证盈利:成本、相对于噪声的波动幅度以及估计的不稳定都很重要。要保持一贯的纪律:在一段时期拟合,预测下一段,并与“不变”的朴素预测比较。打不过它的模型就是什么也没发现。
  • ARIMA = 差分(I)+ 自回归(AR)+ 过去误差(MA);差分把有趋势的序列变平稳。
  • 滞后 k 的 ACF 是序列与 k 步之前的自己的相关系数;缓慢衰减提示 AR 模型。
  • AR(1) 拟合就是把 x[1:] 对 x[:-1] 回归;预测相互递推,当 |phi| < 1 时收敛到 c / (1 - phi);务必要打败“不变”预测。

下一节:GARCH 波动率模型,预测的不是收益的水平,而是它们波动得有多剧烈。

实验:评分内容

  • 用 difference 去除趋势25 分
  • 用 acf 度量记忆性25 分
  • 用 fit_ar1 拟合模型25 分
  • 用 forecast_ar1 向前预测25 分
资源管理器 · lab-100-1
▾ lab-100-1
…
bash · 浏览器内
learner@quantcraft:~/lab-100-1$
Python 尚未加载PythonLn 1, Col 1Spaces: 4UTF-8

要重置此主题吗?

lab-100-1 中的所有内容将恢复为初始文件,终端也会被清空。你当前的解答将丢失,且无法撤销。

将被重置
  • main.py → 初始代码
  • 终端历史与测试输出
  • 未提交的更改
将被保留
  • 实验最高得分
  • 你的 XP 与连续天数
  • 讲解进度与笔记

登录后即可运行你的代码。

所有讲解均可免费阅读。创建账户或登录后,即可运行代码、运行测试并提交此实验。

  • 浏览器内 IDE 与 bash 终端,无需安装
  • 即时评分、XP 以及你在学习路线中的位置
创建账户登录
或
使用 GitHub 继续