社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

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

数据科学实战 • 4 月前 • 167 次点击  

欢迎加入专注于财经数据与量化投研的【数据科学实战】知识星球!在这里,您将获取持续更新的《财经数据宝典》和《量化投研宝典》,这两部宝典相辅相成,为您在量化投研道路上提供明确指引。 我们提供了精选的国内外量化投研的 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