量化投资策略与技术学习PART1.1:量化选股之再谈多因子模型(二)

在上一个多因子模型中,我手动对各个因子进行了回测,但是数据结果并不是十分理想,难道基本面指标真的和股票走势关系不大么?
这里我还是准备再测试一下,策略如下:
(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'].values
                        return_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_A
                finance_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] = 0
                print("该因子无有效衍生指标数据参考"+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中证红利

在这里插入图片描述
换了不同时间段试了一下,效果不是很好,这个策略有时间还需要再研究一下,应该是看一下各个衍生指标变化率和收益之间的关系,而不是看衍生指标绝对值与股票之间的关系。
还有就是各个衍生指标披露时间如下:
年报披露的截至时间为每年的4月30日之前;
第一季报披露的截止时间为4月30日之前;
半年报披露的截止时间为8月31日之前;
第三季度报披露的截止时间为10月31日之前;
所以调仓时间可设置为5月6日、9月1日和11月1日。

time = “2022-05-01” #统计衍生指标的时间
time2 = “2022-07-01” # 统计衍生指标的时间
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值