在上一个多因子模型中,我手动对各个因子进行了回测,但是数据结果并不是十分理想,难道基本面指标真的和股票走势关系不大么?
这里我还是准备再测试一下,策略如下:
(1)首先我获取了一下掘金量化终端中可以提供成分股的几个指数代码,同时将衍生指标导入表格中,提取了衍生指标的关键字信息;
(2)总体建立了一个dataframe表格,其中纵坐标表示的是衍生指标,横坐标就是各个指数
(3)我们先选择一个指数,之后提取该指数的成分股,计算该指数N天之后的收益率,同时获得该指数第一个衍生指标数据,之后对一个指数内所有成分股的收益率和衍生指标数据做相关系数计算,并存储到表格中,首先对所有的衍生指标进行循环,之后对所有的指数进行循环,代码如下:
# coding=utf-8
from __future__ import print_function, absolute_import
from gm.api import *
import pandas as pd
import numpy as np
import datetime
import warnings
warnings.simplefilter(action='ignore', category=pd.errors.PerformanceWarning)
"""
函数名:get_finance_deriv_list():
输入参数:null
输出参数:null
函数作用:获取衍生指标与指数成分股之间的相关系数矩阵
"""def get_finance_deriv_list():# dfcf_data = pd.read_csv('2024年8月17日东方财富ETF基金列表去重版 -手动增强.csv')dfcf_data = pd.read_csv('掘金投资衍生指标数据CSV.csv')finance_deriv = dfcf_data[['字段名', '中文名称']] # 新建一个dataframe表格用于存储需要用到的数据return finance_deriv
"""
函数名:finance_deriv_symbol_corr():
输入参数:null
输出参数:finance_deriv 数据类型:dataframe
函数作用:获取衍生指标数据
"""
def finance_deriv_symbol_corr():A_share_list = {"SHSE.000010": "SHANG_ZHENG180", "SHSE.000009": "SHANG_ZHENG380", "SHSE.000300": "HU_SHEN300","SHSE.000905": "ZHONG_ZHENG500", "SHSE.000906": "ZHONG_ZHENG800","SHSE.000852": "ZHONG_ZHENG1000","SHSE.000015":"honglizhishu","SHSE.000922":"zhongzhenghongli"}# A_share_list = {"SHSE.000010": "SHANG_ZHENG180","SHSE.000009": "SHANG_ZHENG380"}time = "2021-05-01" #统计衍生指标的时间time2 = "2021-07-01" # 统计衍生指标的时间days = 40 # 用于统计数据的天数,用days天后的股票收盘价减去当初的股票收盘价,计算其收益率last_day = get_previous_n_trading_dates(exchange='SHSE', date=time2, n=1)[0]# 计算因子和收益率之间的相关系数,纵坐标应该为衍生指标,建立一个表格导入衍生指标finance_deriv_list = get_finance_deriv_list() #这个一定要在指数轮询之外,要不数据会被覆盖for index in A_share_list.keys():symbol_list = stk_get_index_constituents(index)["symbol"].values # 获取指数成分股数据index_abs = "%s %s" % (index, "abs")finance_deriv_list.insert(len(finance_deriv_list.columns),index, None) # 在指定位置添加空白列,存储该衍生指标和指数成分股之间的相关系数finance_deriv_list.insert(len(finance_deriv_list.columns),index_abs, None) # 在指定位置添加空白列,存储该衍生指标和指数成分股之间的相关系数的绝对值,用于排序print(finance_deriv_list)# 计算各个因子与该指数成分股之间的相关系数for i in finance_deriv_list.index: #每个因子进行轮询finance_deriv_name = finance_deriv_list.loc[i]['字段名']finance_deriv_value = stk_get_finance_deriv_pt(symbols=list(symbol_list), fields=finance_deriv_name,date=time,df=True) # 获取symbol_list的finance_deriv_name数据,需要转换为list类型finance_deriv_value = finance_deriv_value.dropna() #去除到查询不到的数据return_index = finance_deriv_value[['symbol', finance_deriv_name]]return_index.insert(len(return_index.columns), 'return', None) # 在指定位置添加空白列,存储该衍生指标和指数成分股之间的相关系数if len(return_index) > 0.5*len(symbol_list): # 至少有一半以上查询到衍生数据指标,做相关分析才有意义,要不数据太少了for j in return_index.index: #指数成分股中每个股票进行轮询,计算各个股票在这个统计期间的收益率return_index_his = history_n(symbol=return_index.loc[j]['symbol'], frequency='1d', count=days + 1, fields='close',fill_missing='Last', adjust=ADJUST_PREV, end_time=last_day, df=True)if not return_index_his.empty: #有部分股票有可能因为停牌等原因无法查询return_index_his = return_index_his['close'].valuesreturn_index.at[j, 'return'] = return_index_his[-1] / return_index_his[0] - 1 # 将最新的衍生指标值存储到dataframe中# else:# print(symbol_list[j]+"无法查询")return_index = return_index.dropna() # 去除到查询不到的数据factor_A = list(return_index[finance_deriv_name].values)factor_B = list(return_index["return"].values)coef_matrix_A = np.asarray(np.corrcoef(factor_A,factor_B)) #求factor_A 和 return_matrix 之间的相关系数coef_A = coef_matrix_A[0, 1] # 提取第0行,第1列的数值,即相关系数finance_deriv_list.at[i, index] = coef_Afinance_deriv_list.at[i, index_abs] = abs(coef_A)else:finance_deriv_list.at[i, index] = 0 # 无法得到足够的衍生指标数据,因此直接置0,该指标没有参考价值finance_deriv_list.at[i, index_abs] = 0print("该因子无有效衍生指标数据参考"+finance_deriv_name)print(finance_deriv_name)# finance_deriv_list = finance_deriv_list.dropna()# finance_deriv_list = finance_deriv_list.sort_values("abs", ascending=False) # 根据选择的因子对股票进行从小到大排序# finance_deriv_list = finance_deriv_list.reset_index(drop=True) # 重置索引值print(finance_deriv_list)finance_deriv_list.to_csv("衍生指标相关系数.csv", encoding='utf-8-sig')set_token("自己的token码")
finance_deriv_symbol_corr()
得到的结果如下:
原始数据如下图所示:
从上述数据中我们可以看出,有部分数据无效,而且大部分相关系数都小于0.2,因此我们先去除掉无效数据,再以相关系数大于0.2为界限,超过的标红,同时对于一些相似的衍生指标(比如ROE加权不加权等)进行了去重,得到的结果如下:
相关系数超过0.2的衍生指标缩减到了35条,而且从上述数据我们也可以看出,SHSE.000009/SHSE.000905/SHSE.000906/SHSE.000852这四个指数与衍生指标的关系都不大,其中三个都是中小盘股票,这说明大盘股相较于中小盘股和衍生指标的关系较大。因为我们把这三个也剔除掉,之后对各个指数相同的衍生指标进行求和排序,选择求和结果绝对值大于0.4的作为标的衍生指标,结果如下:
指数代码 | 指数名 |
---|---|
SHSE.000010 | 上证180 |
SHSE.000009 | 上证380 |
SHSE.000300 | 沪深300 |
SHSE.000905 | 中证500 |
SHSE.000906 | 中证800 |
SHSE.000852 | 中证1000 |
SHSE.000015 | 红利指数 |
SHSE.000922 | 中证红利 |
换了不同时间段试了一下,效果不是很好,这个策略有时间还需要再研究一下,应该是看一下各个衍生指标变化率和收益之间的关系,而不是看衍生指标绝对值与股票之间的关系。
time = “2022-05-01” #统计衍生指标的时间
time2 = “2022-07-01” # 统计衍生指标的时间