1. 图因子基础:图论基础回顾、图在金融中的应用、图因子定义与分类
各位同学好,我是老张。今天咱们开始聊图因子在量化回测中的验证。说实话,这个课题我琢磨了挺久,因为图因子这东西,听着高大上,但真正落地的时候坑不少。我最早接触图因子是在2019年做行业轮动策略的时候,当时被一个简单的“中心度因子”坑得差点怀疑人生——嗯,后来才发现是数据预处理出了问题。
咱们先打好基础。这一章主要讲三块:图论里跟量化最相关的几个概念、图在金融里到底能干啥、以及图因子到底是个什么东西。别急,慢慢来。
1.1 图论基础回顾:量化人该知道的那些概念
图论说白了就是研究“节点”和“边”的学问。节点可以是你、我、某只股票;边就是咱们之间的关系。在量化里,节点通常是股票、行业、或者某个因子,边就是它们之间的相关性、资金流向、或者供应链关系。
我个人习惯把图分成两类:
- 无向图:边没有方向。比如两只股票的相关系数,A和B相关,B和A也相关,没区别。
- 有向图:边有方向。比如资金从A流向B,那就不能反过来。
还有一个概念特别重要——邻接矩阵。说白了就是一个表格,行和列都是节点,格子里的数字表示它们之间有没有边、有多强的边。我建议你把这个矩阵想象成Excel里的相关性矩阵,只不过图论里叫它邻接矩阵。
核心要点:在量化回测中,图的构建方式直接决定了因子的有效性。我见过太多人随便拿个相关系数矩阵就当图用,结果回测曲线漂亮得不行,实盘一跑就崩。为什么?因为相关系数矩阵是满的,每个节点都跟其他所有节点相连,这种图没有信息量。
下面这张图展示了图因子研究的核心流程,我画了个框架图,你一看就明白:
1.2 图在金融中的应用:不只是画个网络图
你可能会问:图在金融里到底能干啥?我简单列几个实际场景:
- 行业关联分析:用图来表示行业之间的上下游关系。比如钢铁涨了,汽车板块会不会跟着动?这就是图的应用。
- 资金流向追踪:大单资金从哪个板块流出、流入哪个板块,画成有向图一目了然。
- 风险传导:2008年金融危机就是典型的图传播——雷曼兄弟倒了,通过关联边传导到整个金融系统。
- 因子组合优化:把因子当成节点,因子之间的相关性当成边,用图算法找最优组合。
我的经验:刚开始做图因子的时候,我犯过一个低级错误——把时间序列直接当成图来用。你想想看,时间序列是有顺序的,但图里的节点没有天然顺序。后来我学乖了,先问自己三个问题:节点是什么?边怎么定义?图是静态还是动态的?这三个问题想清楚,图因子就成功了一半。
1.3 图因子定义与分类:到底什么是图因子?
图因子,说白了就是从图结构中提取出来的、能用于预测股票收益的数值特征。它不是某个具体的指标,而是一类方法的统称。
我习惯把图因子分成三大类:
| 分类 | 定义 | 典型例子 | 我的评价 |
|---|---|---|---|
| 结构型图因子 | 基于图的拓扑结构计算 | 度中心度、介数中心度、PageRank | 最常用,但容易过拟合 |
| 关系型图因子 | 基于节点间的关系强度 | 平均邻居收益率、边权重聚合 | 信息量大,但计算复杂 |
| 动态图因子 | 考虑图随时间的变化 | 图结构熵变、社区稳定性 | 前沿方向,回测难度大 |
举个例子你就明白了。假设我们构建了一个股票关联图,节点是股票,边是它们过去60天的相关系数。那么:
- 度中心度:某只股票跟多少只股票高度相关。如果它跟100只股票都相关,那它可能就是系统重要性股票。
- 平均邻居收益率:跟这只股票相关的其他股票的平均收益率。如果它的“朋友们”都在涨,它大概率也会涨。
- 图结构熵变:今天这个图的结构跟昨天比变化了多少。如果变化很大,说明市场在发生结构性转变。
避坑指南:我曾经在回测中直接用全市场股票的相关系数矩阵构建图,结果发现度中心度因子跟市值因子相关性高达0.85。为什么?因为大市值股票天然跟更多股票相关。后来我做了两步处理:一是对相关系数做阈值处理(只保留绝对值大于0.3的边),二是对度中心度做市值中性化。嗯,效果好了很多。
说到代码实现,我习惯用NetworkX这个库来构建图。下面是一个简单的示例:
import networkx as nx
import pandas as pd
import numpy as np
# 假设我们有一个收益率矩阵,行是股票,列是时间
returns = pd.DataFrame(np.random.randn(100, 252),
index=[f'stock_{i}' for i in range(100)])
# 计算相关系数矩阵
corr_matrix = returns.T.corr()
# 构建图:只保留相关系数绝对值大于0.3的边
G = nx.Graph()
threshold = 0.3
for i in range(len(corr_matrix)):
for j in range(i+1, len(corr_matrix)):
if abs(corr_matrix.iloc[i, j]) > threshold:
G.add_edge(corr_matrix.index[i],
corr_matrix.columns[j],
weight=corr_matrix.iloc[i, j])
# 计算度中心度
degree_centrality = nx.degree_centrality(G)
# 计算PageRank
pagerank = nx.pagerank(G)
print(f"图中有 {G.number_of_nodes()} 个节点, {G.number_of_edges()} 条边")
print(f"度中心度最高的5只股票: {sorted(degree_centrality.items(), key=lambda x: x[1], reverse=True)[:5]}")
这段代码看着简单,但实际用的时候有几个坑:
- 相关系数矩阵的计算窗口期怎么选?我试过20天、60天、120天,最后发现60天在A股效果相对稳定。
- 阈值设多少?0.3还是0.5?这个得根据你的数据分布来调,没有标准答案。
- 图是静态的还是动态的?如果每天重新构建图,计算量会很大,但信息更新更及时。
好了,这一章的内容就到这儿。图因子的基础概念其实不难,难的是怎么把它用到回测里不出错。下一章咱们会深入讲图因子的计算细节,包括各种中心度指标的数学原理和代码实现。记住我今天说的:先搞清楚节点和边是什么,再谈因子计算。
本章核心要点:
- 图由节点和边组成,在量化中节点通常是股票,边是它们之间的关系
- 图因子分为结构型、关系型、动态型三大类
- 构建图时要注意阈值选择和中性化处理,避免跟已有因子高度共线
- NetworkX是Python中常用的图分析工具,上手简单但要注意参数调优