3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在量化交易中,ADF(Augmented Dickey-Fuller)检验是判断时间序列(如股票价格、价差、残差等)是否具有**平稳性(Stationarity)**的常用统计方法。
平稳性是许多统计套利策略(如配对交易、均值回归)的前提。如果一个序列是平稳的,它的均值和方差不随时间变化,价格偏离均值后有很大通过率会回归。
在 PTrade 中,我们可以使用 Python 标准的第三方库 statsmodels 来进行 ADF 检验。
以下是一个完整的策略示例,该策略在每天盘前获取某只股票过去 100 天的收盘价,并对其进行 ADF 检验。
# 导入 statsmodels 库中的 adfuller 函数
from statsmodels.tsa.stattools import adfuller
import numpy as np
def initialize(context):
"""
初始化函数
"""
# 设置要检验的标的,这里以 600519.SS (贵州茅台) 为例
g.security = '600519.SS'
set_universe(g.security)
def before_trading_start(context, data):
"""
盘前处理函数,执行 ADF 检验
"""
# 1. 获取历史数据
# 获取过去 100 天的收盘价数据
# 注意:为了统计检验的有效性,建议数据长度至少在 30 个以上
history_data = get_history(100, frequency='1d', field='close', security_list=g.security)
# 提取收盘价序列 (numpy array)
close_prices = history_data['close'].values
# 2. 进行 ADF 检验
# adfuller 返回值是一个元组,包含统计量、P值等信息
adf_result = adfuller(close_prices)
# 3. 解析结果
adf_statistic = adf_result[0] # t统计量
p_value = adf_result[1] # P值
usedlag = adf_result[2] # 使用的滞后阶数
nobs = adf_result[3] # 样本数量
critical_values = adf_result[4] # 临界值字典 (1%, 5%, 10%)
# 4. 打印详细日志
log.info("========== ADF 平稳性检验报告 ==========")
log.info("标的: %s" % g.security)
log.info("T-Statistic (t统计量): %f" % adf_statistic)
log.info("P-Value (P值): %f" % p_value)
log.info("Critical Values (临界值):")
for key, value in critical_values.items():
log.info(" %s: %f" % (key, value))
# 5. 判断结论 (使用 5% 作为显著性水平)
if p_value < 0.05:
log.info("结论: P值 < 0.05,拒绝原假设,序列是【平稳】的。")
else:
log.info("结论: P值 >= 0.05,无法拒绝原假设,序列是【不平稳】的。")
# 额外演示:通常价格本身不平稳,但收益率可能是平稳的
# 计算一阶差分(即收益率近似值)
diff_prices = np.diff(close_prices)
# 剔除 NaN (如果有)
diff_prices = diff_prices[~np.isnan(diff_prices)]
adf_result_diff = adfuller(diff_prices)
p_value_diff = adf_result_diff[1]
log.info("--- 尝试对一阶差分(收益率)进行检验 ---")
log.info("一阶差分 P-Value: %f" % p_value_diff)
if p_value_diff < 0.05:
log.info("结论: 一阶差分序列是【平稳】的。")
log.info("========================================")
def handle_data(context, data):
"""
盘中运行函数
"""
pass
get_history):
get_history 获取指定长度(如 100 天)的收盘价数据。ADF 检验对数据量有一定要求,数据太少会导致检验效力不足。adfuller:
from statsmodels.tsa.stattools import adfuller 是核心导入语句。adfuller(series) 接收一个一维数组或 Series。result[0]: Test Statistic。负得越多越好。result[1]: p-value。这是最直观的判断依据。result[4]: Critical Values。这是一个字典,展示了在 1%、5%、10% 置信度下的临界值。如果 Test Statistic 小于这些临界值,也可以判定为平稳。% 格式化字符串,而不是 f-string,以确保在 PTrade 可能使用的旧版本 Python(如 3.5)环境中也能正常运行。Q1: 为什么股票价格通常通不过 ADF 检验?
A1: 股票价格通常遵循“随机游走”模型,意味着当前的变动与过去无关,均值和方差随时间发散,因此是不平稳的。通常收益率(价格的变化量)才是平稳的。
Q2: 如果 P 值很小(例如 0.001),代表什么?
A2: P 值越小,拒绝原假设(不平稳)的证据越强。0.001 意味着有 99.9% 的信心认为该序列是平稳的,非常适合做均值回归策略。
Q3: 在 PTrade 中做配对交易,如何使用 ADF?
A3: 你需要获取两只股票的价格序列 $A$ 和 $B$,计算价差 $Spread = A - \beta \times B$($\beta$ 可通过 OLS 回归计算),然后对 $Spread$ 序列调用 adfuller。如果 $Spread$ 平稳,则两者存在协整关系。