一. 股票数据说明
以如下图片解释股票数据中的影响因素:
图片是比亚迪公司在2023-10-18的收市时的数据;其中:
股票代码:002594;
开盘价(open):245.60
最高价(high):251.00
最低价(low):244.00
收盘价(close):249.07
成交量(volume):30.79万
以上5个是股票基本数据,缩写为(OHLCV);
市净率,市盈率,总股本,流通股份,股息率之类的,是公司的基本数据;一般由公司的净利润,增长率之类的计算得到。
下面图中的方块,一般称为K线,也叫蜡烛图;是由开盘价,最高价,最低价,收盘价绘制而成的。开盘价和收盘价组成了实体部分,上涨为红色,下跌为绿色;最高价和最低价形成了上下两条窄线。
图1. 股票数据
图2. K线示意图
二. 数据获取及存储
一般股票数据可以从各个数据网站获取,比如Wind,tushare,yfinance等;一般获取到的数据是pandas的DataFrame;
可以使用pandas的接口将数据存入csv文件或者存入数据库。一般由如下选择:
CSV:逗号分隔的标准平面文本文档格式.
HDF5:分层数据格式,最初由国家超级计算应用中心开发。它是一种快速且可扩展的数值数据存储格式,可以使用 PyTables 库在 pandas 中使用。
Parquet:Apache Hadoop生态系统的一部分,是一种二进制的列式存储格式,提供高效的数据压缩和编码,由Cloudera和Twitter开发。
MySql:关系型数据库。
mongdb:no-sql数据库。
本文选择从tushare上获取数据,使用CSV和HDF5作为数据存储方式。pandas提供了相关的保存接口;
三. 实践说明
IDE选择pycharm;
安装如下库:
numpy;
pandas;
tushare;
1.首先安装tushare的python库;使用如下安装方式:
pip install tushare
2.导入tushare,配置token;
import tushare as ts
ts.set_token('************************') #设置token; 注册trshare账号,在账号管理界面可见
pro = ts.pro_api()
3.获取上证50的股票列表
df = pro.index_weight(index_code='000016.SH', start_date='20230801', end_date='20230901')
codeList = df['con_code'].to_list()
print(codeList)
#结果如下:
['600048.SH', '600745.SH', '603799.SH', '601899.SH', '600690.SH', '600104.SH', '600030.SH', '600010.SH'...]
4.调用pro_bar接口,获取单只股票的数据;可传入起止时间;我们获取 2018-01-01到2023-10-01的数据;
result = pd.DataFrame()
with pd.HDFStore(DATA_STORE) as store:
for str in codeList: #pro_bar只接受单只股票输入
data = ts.pro_bar(ts_code=str, adj='qfq', start_date='20200101',
end_date='20230901', factors='E', adjfactor=True) #adj表示获取的前复权值
result = pd.concat([result, data], axis=0) #将获取到的dataFrame拼接在一起
store.put('tushare/stocks', result) #存入HDF5文件,后续直接读取该文件即可; 不用每次都去tushare上拉去数据
5.读取数据,进行预处理:获取的五年数据,对发行时长不足五年的股票剔除掉; 在时间段内,有些股票有停盘时段是没有数据的;用停盘之前的数据补全。
with pd.HDFStore(DATA_STORE) as store:
data = store['tushare/stocks']
print(data.head())
print(data.info())
#结果如下:
ts_code trade_date open ... vol amount adj_factor
0 600048.SH 20230928 12.81 ... 345159.85 440720.304 24.619
1 600048.SH 20230927 12.81 ... 453786.61 579854.895 24.619
2 600048.SH 20230926 12.90 ... 371257.96 477586.802 24.619
3 600048.SH 20230925 13.28 ... 931652.04 1208734.229 24.619
4 600048.SH 20230922 13.20 ... 443568.24 588948.762 24.619
<class 'pandas.core.frame.DataFrame'>
Index: 68878 entries, 0 to 1456
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 ts_code 68878 non-null object
1 trade_date 68878 non-null object
2 open 68878 non-null float64
3 high 68878 non-null float64
4 low 68878 non-null float64
5 close 68878 non-null float64
6 pre_close 68878 non-null float64
7 change 68878 non-null float64
8 pct_chg 68878 non-null float64
9 vol 68878 non-null float64
10 amount 68878 non-null float64
11 adj_factor 68878 non-null float64
dtypes: float64(10), object(2)
memory usage: 6.8+ MB
None
# 使用to_datetime函数将日期列转换为日期时间对象,并指定日期格式
data['trade_date'] = pd.to_datetime(data['trade_date'], format='%Y%m%d')
#数据处理
#设置df的索引为 trade_date,ts_code
#data.set_index(['trade_date', 'ts_code'], inplace=True)
data.set_index(['ts_code', 'trade_date'], inplace=True)
#索引先排序
data = data.sort_index()
#看看每只股票的数据量,看是否有缺失
nums = data.groupby(level='ts_code').size()
print(nums)
#有些股票没有6年的发行时长,给去掉
min_obs = 1400
nobs = data.groupby(level='ts_code').size()
keep = nobs[nobs > min_obs].index
data = data.loc[idx[keep, :], :]
对于期间有停盘的数据进行补齐:
#获取所有的交易日期
df = pro.trade_cal(exchange='', start_date='20200101', end_date='20230901', is_open=1)
df['cal_date'] = pd.to_datetime(df['cal_date'], format='%Y%m%d')
dateList = df['cal_date'].to_list()
dateList = dateList[::-1]
print(len(dateList))
data = data.swaplevel('ts_code', 'trade_date')
data = data.groupby(level='ts_code').apply(computeDate, dateList=dateList)
最后得到47支股票6年间的数据。后续进行特征计算和标签处理。