Py学习  »  Python

量化交易必学:用 Python 计算资产相关性

数据科学实战 • 2 周前 • 62 次点击  

欢迎加入专注于财经数据与量化投研的【数据科学实战】知识星球!在这里,您将获取持续更新的《财经数据宝典》和《量化投研宝典》,这两部宝典相辅相成,为您在量化投研道路上提供明确指引。 我们提供了精选的国内外量化投研的 180+ 篇高质量文章,并每日更新最新研究成果,涵盖策略开发、因子分析、风险管理等核心领域。 无论您是量化投资新手还是经验丰富的研究者,星球社区都能帮您少走弯路,事半功倍,共同探索数据驱动的投资世界!

引言

在量化交易和投资组合管理中,了解不同资产之间的相关性至关重要。无论是构建分散化投资组合、设计配对交易策略,还是进行风险对冲,相关性分析都是不可或缺的工具。

本文将介绍如何使用 Python 中的 TA-Lib 库计算皮尔逊相关系数(Pearson's Correlation Coefficient),并通过实际案例展示如何分析两只股票之间的关系。这对于学习 Python 金融数据分析的朋友来说,是一个非常实用的技能。

什么是皮尔逊相关系数

皮尔逊相关系数(通常用 r 表示)是一个统计量,用于衡量两个连续变量之间线性关系的强度和方向。在金融领域,这两个变量通常是两种不同资产的价格序列。

相关系数的取值范围

相关系数的取值范围在 -1 到 +1 之间:

  • +1(完全正相关):两个资产完全同步移动,一个上涨时另一个也按比例上涨
  • -1(完全负相关):两个资产完全反向移动,一个上涨时另一个按比例下跌
  • 0(无线性相关):两个资产的价格变动在统计上是独立的
  • 0 到 +1 之间:表示不同程度的正相关(如 +0.7 表示强正相关,+0.2 表示弱正相关)
  • 0 到 -1 之间:表示不同程度的负相关(如 -0.7 表示强负相关,-0.2 表示弱负相关)

重要提示

需要注意的是,皮尔逊相关系数只能衡量线性关系。两个资产可能存在很强的非线性关系,但相关系数仍然接近于零。此外,相关性不等于因果关系。

相关性在金融中的应用

1. 投资组合分散化

分散化是现代投资组合理论的核心。通过组合相关性低或负相关的资产,可以在一个资产下跌时,用另一个资产的收益来抵消损失,从而降低整体投资组合的波动性。

2. 配对交易

配对交易策略利用历史上相关的资产之间的临时背离。如果两个资产通常一起移动但突然出现分歧,交易者可能会做多表现不佳的资产,同时做空表现较好的资产,预期它们会回归历史均值关系。

3. 风险评估

相关性有助于量化系统性风险。与大盘指数(如标普 500)高度相关的资产通常会与市场同步移动。这种关系是资本资产定价模型(CAPM)中 Beta 系数的基础。

4. 风险对冲

对冲策略通常依赖于相关性。如果你持有某个资产的多头头寸,可以通过做空正相关的资产或做多负相关的资产来对冲风险。

使用 TA-Lib 计算滚动相关性

TA-Lib 库提供了一个内置函数来计算滚动相关性:

talib.CORREL(prices1, prices2, timeperiod=N)

参数说明

  • prices1:第一个价格序列(例如资产 A)
  • prices2:第二个价格序列(例如资产 B),长度必须与 prices1 相同
  • timeperiod:滚动窗口的长度(期数)

完整代码示例

下面的代码展示如何下载两只股票的价格数据、对齐数据、计算滚动相关性,并可视化结果:

import yfinance as yf
import talib
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# --- 1. 数据获取和对齐 ---
asset1_symbol = "AAPL"  # 示例:苹果公司
asset2_symbol = "MSFT"  # 示例:微软公司(也可以使用 "SPY" 代表市场指数)
data_start_date = "2023-01-01"
data_end_date = "2024-05-01"

try:
    # 下载两个资产的价格数据
    data_asset1 = yf.download(asset1_symbol, start=data_start_date, end=data_end_date)
    data_asset2 = yf.download(asset2_symbol, start=data_start_date, end=data_end_date)
    
    if data_asset1.empty or data_asset2.empty:
         raise ValueError("一个或两个资产的数据下载失败。")
    
    # 如果存在多级列,删除额外的列级别
    if isinstance(data_asset1.columns, pd.MultiIndex) and data_asset1.columns.nlevels > 1:
        data_asset1.columns = data_asset1.columns.droplevel(level=1)
    if isinstance(data_asset2.columns, pd.MultiIndex) and data_asset2.columns.nlevels > 1:
        data_asset2.columns = data_asset2.columns.droplevel(level=1)
    
    # 使用收盘价并按日期对齐
    close_prices_asset1 = data_asset1[['Close']].rename(columns={'Close'f'Close_{asset1_symbol}'})
    close_prices_asset2 = data_asset2[['Close']].rename(columns={'Close'f'Close_{asset2_symbol}'})
    aligned_data = close_prices_asset1.join(close_prices_asset2, how='inner')
    
    if aligned_data.empty or len(aligned_data) 2:
        raise ValueError("对齐后没有足够的重叠数据。")
    
    prices1 = aligned_data[f'Close_{asset1_symbol}']
    prices2 = aligned_data[f'Close_{asset2_symbol}']
    aligned_date_index = aligned_data.index
    
except Exception as e:
    print(f"数据获取或对齐错误:{e}")
    aligned_data = pd.DataFrame()

if not aligned_data.empty:
    # --- 2. 滚动皮尔逊相关系数计算 ---
    time_period_correl = 30  # 例如,30 天滚动相关性
    
    if len(prices1) >= time_period_correl:
        correl_values = talib.CORREL(prices1, prices2, timeperiod=time_period_correl)
        indicator_name = f"CORREL({time_period_correl})"
        
        print(f"\n--- {indicator_name} - 皮尔逊相关系数({asset1_symbol} vs {asset2_symbol})---")
        valid_correl_values = correl_values[~np.isnan(correl_values)]
        
        if len(valid_correl_values) >= 5:
            print(f"{indicator_name} 输出(最后 5 个有效值):{valid_correl_values[-5:]}")
        elif len(valid_correl_values) > 0:
            print(f"{indicator_name} 输出(所有有效值):{valid_correl_values}")
        else:
            print(f"{indicator_name} 输出:未计算出有效值。")
        
        # --- 3. 可视化 ---
        fig, axes = plt.subplots(21, figsize=(1410), sharex=True, gridspec_kw={'hspace'0.1})
        
         # 绘制资产 1 价格
        axes[0].plot(aligned_date_index, prices1, label=f'{asset1_symbol} 价格', color='blue', linewidth=1.5)
        axes[0].set_title(f'{asset1_symbol} 价格和滚动相关性(与 {asset2_symbol})', fontsize=14)
        axes[0].set_ylabel(f'{asset1_symbol} 价格', fontsize=12)
        axes[0].legend(loc='upper left')
        axes[0].grid(True, linestyle=':', alpha=0.6)
        
        # 绘制滚动相关性
        axes[1].plot(aligned_date_index, correl_values, label=indicator_name, color='purple', linewidth=1.5)
        axes[1].axhline(1.0, color='red', linestyle='--', linewidth=0.8, label='完全正相关 (+1)')
        axes[1].axhline(0, color='gray', linestyle=':', linewidth=0.8, label='无相关 (0)')
        axes[1].axhline(-1.0, color='green', linestyle='--', linewidth=0.8, label='完全负相关 (-1)')
        axes[1].set_ylim(-1.11.1)
        axes[1].set_ylabel('相关系数', fontsize=12)
        axes[1].set_xlabel('日期', fontsize=12)
        axes[1].legend(loc='lower left')
        axes[1].grid(True, linestyle=':', alpha=0.6)
        
        plt.tight_layout()
        plt.show()
    else:
        print(f"\n跳过 CORREL 绘图:对齐数据不足(需要 > {time_period_correl} 个数据点)。")
        if not aligned_data.empty:
            print(f"可用的对齐数据点:{len(prices1)}。")
else:
    print(f"\n跳过 CORREL 绘图:数据准备失败。")

代码详解

1. 导入库

代码使用 yfinance 获取数据,TA-Lib 计算相关性,matplotlib 和 pandas 进行分析和可视化。

2. 数据获取和对齐

  • 下载两个资产的收盘价
  • 在共同的交易日期上对齐序列并删除缺失值,以确保有效的相关性计算

3. 滚动相关性计算

  • 设置窗口长度(time_period_correl)
  • 计算 talib.CORREL() 获得滚动相关性数组
  • 处理序列开始处出现的 NaN 值

4. 绘图

  • 上图:资产 1 的价格随时间变化
  • 下图:两个资产之间的滚动相关性
  • 在 +1、0 和 -1 处添加水平参考线,便于解读

5. 错误处理

如果数据下载或对齐失败,或数据不足,代码会提供有用的提示信息。

结果解读和实际应用

这个分析帮助我们可视化两个资产之间的关系如何随时间演变。例如:

  • 高正相关:表明市场暴露相似(如 AAPL 与 MSFT)
  • 负相关:意味着潜在的分散化收益
  • 相关性波动:可能预示着市场制度转变或资产关系的结构性变化

滚动相关性分析支持分散化投资、配对交易和风险管理,是现代投资组合分析中的重要量化工具。

总结

本文介绍了皮尔逊相关系数的基本概念,以及如何使用 Python 的 TA-Lib 库计算两个资产之间的滚动相关性。通过完整的代码示例,我们展示了从数据获取、计算到可视化的完整流程。

掌握相关性分析技能,对于任何从事量化交易、投资组合管理或金融数据分析的 Python 学习者来说都非常重要。希望这篇文章能帮助你更好地理解和应用相关性分析工具。

参考文章

加入专注于财经数据与量化投研的知识星球【数据科学实战】,获取本文完整研究解析、代码实现细节。

财经数据与量化投研知识社区

核心权益如下:

  1. 赠送《财经数据宝典》完整文档,汇集多年财经数据维护经验
  2. 赠送《量化投研宝典》完整文档,汇集多年量化投研领域经验
  3. 赠送《PyBroker-入门及实战》视频课程,手把手学习量化策略开发
  4. 每日分享高质量量化投研文章(已更新 180+篇)、代码和相关资料
  5. 定期更新高频财经数据
  6. 参与年度不少于 10 次专属直播与录播课程
  7. 与核心开发者直接交流,解决实际问题
  8. 获取专业微信群交流机会和课程折扣

星球已有丰富内容积累,包括量化投研论文、财经高频数据、 PyBroker 视频教程、定期直播、数据分享和答疑解难。适合对量化投研和财经数据分析有兴趣的学习者及从业者。欢迎加入我们!

好文推荐

1. 用 Python 打造股票预测系统:Transformer 模型教程(一)

2. 用 Python 打造股票预测系统:Transformer 模型教程(二)

3. 用 Python 打造股票预测系统:Transformer 模型教程(三)

4. 用 Python 打造股票预测系统:Transformer 模型教程(完结)

5. 揭秘隐马尔可夫模型:因子投资的制胜武器

6. YOLO 也能预测股市涨跌?计算机视觉在股票市场预测中的应用

7. 金融 AI 助手:FinGPT 让你轻松掌握市场分析

8. 量化交易秘籍:为什么专业交易员都在用对数收益率?

9. Python 量化投资利器:Ridge、Lasso 和 Elastic Net 回归详解

10. 掌握金融波动率模型:完整 Python 实现指南

好书推荐



Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/188664