Python数据风险案例54——人工智能热门概念股爬虫分析其价值(三因子模型)

news2024/11/26 18:29:10

案例背景

人工智能概念如火如荼的夏天,在这个2024年,我觉得需要提早布局一下这个概念。所以我们找一下A股里面人们的人工智能概念股,然后分析他们的数据应用三因子模型,也就是最经典的资本资产定价模型的衍生版去研究他们各自的投资价值。

(本案例仅用于研究学术分享,不构成任何投资建议。)


数据介绍

本次案例只有三因子数据是本地的,其他的数据都爬虫或者API接口获得,从互联网上爬取,首先从这个网站上获取:人工智能概念股名单一览_2024A股、B股人工智能概念上市公司有哪些 – 华西证券,热门的概念的股票名称,然后再使用akshare这个非常好用且免费的金融数据库,获取这些股票的交易数据,然后再采用三因子模型进行回归对比评估。

当然数据我也下载到本地了,和三因子数据打包一起放在这里,需要的这些数据和全部代的同学可以参考:人工智能data


代码实现

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt 
import seaborn as sns
import statsmodels.api as sm
plt.rcParams ['font.sans-serif'] ='SimHei'               #显示中文
plt.rcParams ['axes.unicode_minus']=False               #显示负号

获取人工智能概念股票

下面直接进行爬虫,懂网页文件的同学可以看看代码,不懂的同学直接用就行

import requests
from bs4 import BeautifulSoup
# 目标网页地址
url = 'https://m.hx168.com.cn/stock/concept/BK2196.html'
# 发送HTTP请求获取网页内容
response = requests.get(url)
response.encoding = 'utf-8'  # 确保中文正确显示
# 解析网页
soup = BeautifulSoup(response.text, 'html.parser')

def get_code(class_name=''):
    # 定位到目标表格
    tables = soup.find_all('table', {'class': 'am-table am-table-bordered am-table-striped am-text-nowrap'})
    #print(len(tables))
    dfs=pd.DataFrame()
    for table in tables:
        # 解析表格标题
        headings = [th.get_text().strip() for th in table.find('thead').find_all('th')]
        # 解析表格数据
        data = []
        for row in table.find('tbody').find_all('tr'):
            cells = row.find_all('td')
            if len(cells) > 0:  # 确保行内有数据
                data_row = []
                for cell in cells:
                    a_tag = cell.find('a')
                    if a_tag:
                        data_row.append(a_tag.get_text().strip())  # 如果单元格内有链接,则获取链接文本
                    else:
                        data_row.append(cell.get_text().strip())
                data.append(data_row)
        df=pd.DataFrame(data=data,columns=headings)
        dfs=pd.concat([dfs,df],axis=0,ignore_index=True)
    # 打印结果
    return dfs

运行然后,查看:

dfs=get_code()
dfs.head()

然后我们用列表跟字典把它们这些名称和代码都装起来。

code_name=dict(zip(dfs['股票代码'],dfs['股票简称']))
code_list=dfs['股票代码'].to_list()

获取这些股票的交易数据

自定义一个函数从ak share这个库里面获取

import akshare as ak
# 定义获取A股历史交易数据的函数
def get_stock_data(stock_code, start_date, end_date):
    """
    :param stock_code: 股票代码,如 '000001'
    :param start_date: 开始日期,格式为 'YYYYMMDD'
    :param end_date: 结束日期,格式为 'YYYYMMDD'
    :return: 指定时间段内的股票交易数据(DataFrame)
    """
    # 使用 AkShare 的 stock_zh_a_hist 接口获取数据
    stock_df = ak.stock_zh_a_hist(symbol=stock_code, period="daily", start_date=start_date, end_date=end_date, adjust="qfq")
    stock_df['收益率'] = stock_df['收盘'].pct_change() 
    return stock_df.dropna()

 下面开始循环遍历所有的代码,然后获取他们的交易数据。

return_dict={}
 #创建一个 ExcelWriter 对象
#writer = pd.ExcelWriter('股票数据.xlsx', engine='xlsxwriter')
for code in code_list:
    try:
        return_dict[code]=get_stock_data(stock_code=code,start_date='20230201',end_date='20240201')[['日期','收盘','收益率']].set_index('日期')
        #get_stock_data(stock_code=code,start_date='20230201',end_date='20240201').to_excel(writer, sheet_name=code)
    except:
        pass
    
#writer.save()
#writer.close()

 因为存的是字典,我们拿出来看一下其中的一个数据的情况。

return_dict['002415'].head(4)

数据没有什么问题,下面我们开始使用三因子模型去进行分析。


三因子模型

这是gpt写的模型的简介,我觉得还写的挺好的,大家可以看看。

 下面读取三因子的数据,三因子的数据。我的数据里面有五个因子。但是我这里只用了三因子就没搞那么多。

#读取三因子数据
three_factors=pd.read_csv('fivefactor_daily.csv')[['trddy','mkt_rf','smb','hml']].rename(columns={'trddy':'日期'}).set_index('日期')
three_factors=three_factors.loc['2023-02-01':'2024-02-01',:]
three_factors.index=pd.to_datetime(three_factors.index)
three_factors.head(3)

  • trddy [交易日期]
  • mkt_rf [市场风险因子]
  • smb [规模风险因子]
  • hml [账面市值比风险因子]
  • rf [无风险利率]

自定义一些股票里面常用的,评价一个资产表现的函数。

def sum_return_ratio(price_list):
    '''实际总收益率'''
    price_list = price_list.to_numpy()
    return (price_list[-1] - price_list[0]) / price_list[0]

def MaxDrawdown(price_list):
    '''最大回撤率'''
    i = np.argmax((np.maximum.accumulate(price_list) - price_list) / np.maximum.accumulate(price_list))  # 结束位置
    if i == 0:
        return 0
    j = np.argmax(price_list[:i])  # 开始位置
    return (price_list[j] - price_list[i]) / (price_list[j])

def sharpe_ratio(price_list, rf=0.000041):
    '''夏普比率'''
    # 公式 夏普率 = (回报率均值 - 无风险率) / 回报率的标准差
    # pct_change()是pandas里面的自带的计算每日增长率的函数
    daily_return = price_list.pct_change()
    return (daily_return.mean() - rf) / daily_return.std()

def Information_Ratio(price_list, rf=0.000041):
    '''信息比率'''
    chaoer = sum_return_ratio(price_list) - ((1 + rf) ** 365 - 1)
    return chaoer / np.std(price_list.pct_change() - rf)

def skewness_return(price_list):
    '''负偏态收益'''
    daily_return = price_list.pct_change()
    return daily_return.skew()

def downside_upside_volatility_ratio(price_list):
    '''下跌波动比率'''
    daily_return = price_list.pct_change()
    # 获取下跌和上涨的日子的收益率
    returns_down = daily_return[daily_return < 0]
    returns_up = daily_return[daily_return > 0]
    
    # 计算各自的天数和收益率平方和
    n_down = len(returns_down)
    n_up = len(returns_up)
    sum_squared_returns_down = (returns_down ** 2).sum()
    sum_squared_returns_up = (returns_up ** 2).sum()
    
    # 计算DUVOL
    if n_down == 0 or n_up == 0:  # 避免除以0
        return np.nan
    duvol = np.log((n_up * sum_squared_returns_down) / (n_down * sum_squared_returns_up))
    return duvol

 自定义一个函数,输入这个股票的代码,我们就能够去计算它这些所有的资产表现的评价指标。方便复用。

def deal(code=''): 
    day_return = return_dict[code]#['收益率']
    day_return.index=pd.to_datetime(day_return.index)
    
    zgpa_threefactor = pd.merge(three_factors, day_return,left_index=True, right_index=True)
    result = sm.OLS(zgpa_threefactor['收益率'], sm.add_constant(zgpa_threefactor.loc[:,['mkt_rf','smb','hml']])).fit()
    betas=result.params
    
    实际总收益率=sum_return_ratio(day_return['收盘'])
    最大回测率=MaxDrawdown(day_return['收盘'])
    夏普比率=sharpe_ratio(day_return['收盘'])
    信息比率=Information_Ratio(day_return['收盘'])
    负偏态收益 = skewness_return(day_return['收盘'])
    下跌波动比率 = downside_upside_volatility_ratio(day_return['收盘'])
    
    return pd.DataFrame({'阿尔法': betas[0], '市场风险因子MKT': betas[1], '市值因子SMB': betas[2], '账面市值因子HML': betas[3],
                         '实际总收益率': 实际总收益率, '最大回测率': 最大回测率, '夏普比率': 夏普比率, '信息比率': 信息比率, 
                         '负偏态收益': 负偏态收益, '下跌波动比率': 下跌波动比率, '股票代码': code}, index=[0])

循环遍历去计算 

df_results=pd.DataFrame()
for code,df_one in return_dict.items():
    result=deal(code=code) ;  result['股票名称']=code_name[code]
    df_results=pd.concat([df_results,result],axis=0,ignore_index=True)

我们来查看结果

df_results


选出阿尔法前十的股票 来分析画图

阿尔法就是超额收益嘛,也就是回归里面的截距,我们选出前10的来画图看看。

df_results=df_results[['股票代码', '股票名称','阿尔法', '市场风险因子MKT', '市值因子SMB', '账面市值因子HML', '实际总收益率', '最大回测率', '夏普比率', '信息比率','负偏态收益','下跌波动比率']].sort_values(by='阿尔法',ascending=False)
df_results.head(10)

plt.figure(figsize=(10, 8),dpi=128)

# 创建多子图布局
for i, column in enumerate(['阿尔法', '市场风险因子MKT', '市值因子SMB', '账面市值因子HML', '实际总收益率', '最大回测率', '夏普比率', '信息比率','负偏态收益','下跌波动比率'], 1):
    plt.subplot(5, 2, i)
    plt.bar(df_results.head(10)['股票名称'], df_results.head(10)[column], color='skyblue')
    plt.title(column)
    plt.xticks(rotation=45)  # 旋转标签,避免重叠

# 调整布局
plt.tight_layout()
plt.show()

通过对比各股票的阿尔法值(Alpha)、贝塔值(Beta)、市值因子(SMB)、账面市值因子(HML)、实际总收益率、最大回测率、夏普比率和信息比率这些指标来分析和比较不同股票的表现。

阿尔法值(Alpha): 表示投资组合相对于基准业绩的超额回报,是投资者获取的与市场无关的回报。阿尔法值越高,说明股票表现越好。在您的列表中,昆仑万维的阿尔法值最高,表示在考虑风险因素后,其超额回报最高。

贝塔值(Beta): 表示股票相对于整个市场的波动性。贝塔值大于1意味着股票的价格波动大于市场平均水平,小于1则表示波动性小于市场。例如,昆仑万维的贝塔值是2.564679,这意味着它比市场波动性大,风险较高。

市值因子(SMB)和账面市值因子(HML): SMB表示小市值公司相对于大市值公司的超额回报,HML表示高账面市值比的公司相对于低账面市值比公司的超额回报。在您的数据中,鸿博股份的SMB值最高,表明它在小市值公司中表现较好;而同样的鸿博股份的HML值也是正的,意味着高账面市值比的公司表现更好。

实际总收益率: 表明股票在某段时间内的总回报。例如,中科信息的实际总收益率最高,说明它在过去一段时间内的表现最好。

最大回撤率: 表示在选定的周期内,投资组合可能遭受的最大损失。低最大回撤率意味着下跌风险较小。例如,柯力传感的最大回撤率最低,说明其价格下跌的风险相对较小。

夏普比率: 表示投资的每单位风险带来的超额回报,夏普比率越高,意味着单位风险带来的超额回报越高。鸿博股份的夏普比率最高,表明它在风险调整后的回报上表现最佳。

信息比率: 表示投资组合超额回报相对于跟踪误差的比率,信息比率越高,说明投资经理超越基准指数的能力越强。万兴科技的信息比率最高,表明其相对于其跟踪基准的表现最为出色。

综上所述,如果是在寻找高风险高回报的股票,可能会考虑昆仑万维中科信息,因为它们具有较高的阿尔法值和实际总收益率。如果更注重稳定性和低风险,柯力传感可能是一个更好的选择,因为其最大回撤率较低。另外,从风险调整后的回报来看,鸿博股份万兴科技表现较好,它们的夏普比率和信息比率较高。


储存结果

### 储存结果
df_results.to_csv('人工智能三因子结果.csv',index=False)


创作不易,看官觉得写得还不错的话点个关注和赞吧,本人会持续更新python数据分析领域的代码文章~(需要定制类似的代码可私信)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1938501.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

内网穿透原理解析及软件

&#x1f308;所属专栏&#xff1a;【其它】✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您的点…

OpenGL笔记十四之GLM数学库的配置与使用

OpenGL笔记十四之GLM数学库的配置与使用 —— 2024-07-20 中午 bilibili赵新政老师的教程看后笔记 code review! 文章目录 OpenGL笔记十四之GLM数学库的配置与使用1.旋转变换运行效果2.平移变换运行效果3.缩放变换运行效果4.复合变换&#xff1a;先旋转 再平移运行效果5.复合…

Linux网络:应用层协议HTTP(一)

一、什么是HTTP协议 虽然我们说, 应用层协议是我们程序猿自己定的. 但实际上, 已经有大佬们定义了一些现成的, 又非常好用的应用层协议, 供我们直接参考使用. HTTP(超文本传输协议)就是其中之一。 在互联网世界中&#xff0c;HTTP&#xff08;HyperText Transfer Protocol&…

8 个实用写歌词技巧,让歌词富有感染力

在音乐的领域中&#xff0c;一首好歌往往离不开充满感染力的歌词。这些歌词能够触动人们的心灵&#xff0c;引发共鸣&#xff0c;让人沉浸其中。接下来&#xff0c;为您分享 8 个实用技巧&#xff0c;帮助您创作出富有感染力的歌词&#xff0c;同时为您介绍“妙笔生词智能写歌词…

OpenAI突发新模型GPT-4o mini,GPT-3.5退役!

OpenAI突发新模型&#xff0c;全面取代老去的GPT-3.5——GPT-4o mini&#xff01; 免费用户已可使用GPT-4o mini模型。 GPT-4o mini&#xff0c;能力接近原版GPT-4&#xff0c;价格却要便宜一个数量级&#xff1a; GPT-4o mini:每百万输入tokens&#xff0c;15美分&#xff0…

降雨量预测 | Matlab基于ARIMA-RBF降雨量预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 降雨量预测 | Matlab基于ARIMA-RBF降雨量预测 注&#xff1a;程序和数据放在一个文件夹。 程序语言为matlab&#xff0c;程序可出预测效果图&#xff0c;指标图; 代码特点&#xff1a;参数化编程、参数可方便更改、代…

SQL每日一题:寻找用户推荐人

题干 表: Customer -------------------- | Column Name | Type | -------------------- | id | int | | name | varchar | | referee_id | int | -------------------- 在 SQL 中&#xff0c;id 是该表的主键列。 该表的每一行表示一个客户的 id、姓名以及推荐他们的客户的 …

如何建立一颗二叉树?(数据结构:树 + hash表 / 广搜BFS)

一个二叉树&#xff0c;树中每个节点的权值互不相同。 现在给出它的后序遍历和中序遍历&#xff0c;请你输出它的层序遍历。 输入格式 第一行包含整数 N&#xff0c;表示二叉树的节点数。 第二行包含 N 个整数&#xff0c;表示二叉树的后序遍历。 第三行包含 N 个整数&…

pytest常用命令行参数解析

简介&#xff1a;pytest作为一个成熟的测试框架&#xff0c;它提供了许多命令行参数来控制测试的运行方式&#xff0c;以配合适用于不同的测试场景。例如 -x 可以用于希望出现错误就停止&#xff0c;以便定位和分析问题。–rerunsnum适用于希望进行失败重跑等个性化测试策略。 …

ue5笔记

1 点光源 聚光源 矩形光源 参数比较好理解 &#xff08;窗口里面&#xff09;环境光混合器&#xff1a;快速创造关于环境光的组件 大气光源&#xff1a;太阳光&#xff0c;定向光源 天空大气&#xff1a;蓝色的天空和大气 高度雾&#xff1a;大气下面的高度感的雾气 体积…

开源PDF解析工具marker 和 MinerU的解析效果对比

RAG中的文档解析需求&#xff1a;需要的是文档的完整段落&#xff0c;标题&#xff0c;图片&#xff0c;表格。我们希望删除的是md格式&#xff0c;或者josn格式。 MinerU 和 maker恰好。都是能够满足此需求的开源工具。这篇文章分享一下对两者的对比。整理出来目前还存在的问题…

英伟达DGX、EGX、IGX、HGX、MGX架构解析

一文了解英伟达DGX、EGX、IGX、HGX、MGX 英伟达市值上涨5.2%&#xff0c;收盘市值达3.019万亿美元&#xff0c;超越苹果公司&#xff0c;成为了美股市值第二大的公司&#xff0c;仅次于微软。在当今的科技领域&#xff0c;GPU已经成为了推动人工智能、深度学习、高性能计算等领…

docker自建rustdesk-server远程桌面

rustdesk简介 RustDesk 是一款可以平替 TeamViewer 的开源软件&#xff0c;旨在提供安全便捷的自建方案。 RustDesk 是一款功能齐全的远程桌面应用&#xff0c;具有以下特性&#xff1a; 支持 Windows、macOS、Linux、iOS、Android、Web 等多个平台。支持 VP8 / VP9 / AV1 …

第一百七十四节 Java IO教程 - Java字符集

Java IO教程 - Java字符集 我们可以使用编码方案将Unicode字符转换为字节序列&#xff0c;反之亦然。 java.nio.charset包提供了将CharBuffer编码/解码为ByteBuffer的类&#xff0c;反之亦然。 Charset类的对象表示编码方案。 CharsetEncoder类执行编码。 CharsetDecoder类执…

Java笔试分享

1、设计模式&#xff08;写>3种常用的设计模式&#xff09; 设计模式是在软件工程中解决常见问题的经验性解决方案。以下是一些常用的设计模式&#xff1a; 单例模式&#xff08;Singleton&#xff09;&#xff1a; 意图&#xff1a;确保一个类只有一个实例&#xff0c;并…

SVN 服务 安装部署 Docker(compose) 方式

通过 dockerhub 或者 命令行运行 &#xff1a; docker search svn 查看 svn 的镜像 如命令行&#xff1a; [rootSGP ~]# docker search svn NAME DESCRIPTION STARS OFFICIAL AUTOMATED garethflower…

Unity3d打包到Android

本文参考&#xff1a; Unity3D新手教程&#xff1a;如何打包发布到Android_哔哩哔哩_bilibili 一、Unity 打包Android的环境搭建 1、工具安装 Unity Hub已经集成了Android的环境搭建。 选择Add modules 然后安装Android Build Support下的所有工具。 如果各个工具都安装成功…

FastGPT 知识库搜索测试功能解析

目录 一、代码解析 1.1 searchTest.ts 1.2 controller.ts 本文接上一篇文章FastGPT 知识库搜索测试功能解析 对具体代码进行解析。 一、代码解析 FastGPT 知识库的搜索测试功能主要涉及两个文件&#xff0c;分别是 searchTest.ts 和 controller.ts 文件&#xff0c;下面分…

【HarmonyOS】HarmonyOS NEXT学习日记:五、交互与状态管理

【HarmonyOS】HarmonyOS NEXT学习日记&#xff1a;五、交互与状态管理 在之前我们已经学习了页面布局相关的知识&#xff0c;绘制静态页面已经问题不大。那么今天来学习一下如何让页面动起来、并且结合所学完成一个代码实例。 交互 如果是为移动端开发应用&#xff0c;那么交…

暑假第一周学习内容-ZARA仿写

仿写ZARA总结 文章目录 仿写ZARA总结前言无限轮播图分栏控制器与UIScrollViewUIScorllView的协议部分UISegmentedControl的协议部分 自定义cell 前言 本文主要是用来总结仿写ZARA中遇到的一些问题&#xff0c;以及ZARA中学习到的一些新知识。 无限轮播图 这里我们先给出无限…