量化交易backtrader实践(一)_数据获取篇(2)_tushare与akshare

上一节回顾

在上一节中,从股票的基本功能和主要数据进行小结,明确了进行backtrader回测所需要的数据,并且学习了backtrader的数据来源以及PandasData的格式要求,已经做到假设拿到.txt或.csv文件后,能把里面的股票基本数据(6项)处理成backtrader接受的格式,并加入backtrader进行回测。

本节实践目标

  • 某支股票的日线数据获取
  • 沪深京全股票列表获取与制作
  • ETF/LOF列表获取与制作
  • 根据全股票列表完成代码、拼音缩写以及中文名称的任意搜索
  • 自选股列表制作以及多股票循环回测

01_某支股票的日线数据获取

001_tushare.pro的获取

首先可以确定,当前2024年tushare已经不能用了,前几年的参考文档大多都是基于tushare来做的,这没过多久一眨眼世界就全变了。就像当年的小灵通,就像当年的诺基亚,就像当年的Adobe Flash,自己花了挺长时间去学习和研究,结果一转眼它就退出历史舞台了。

# 尝试老版本的数据调用
import tushare as ts
df1 = ts.get_hist_data('600848')
df1

---------------------
本接口即将停止更新,请尽快使用Pro版接口:https://tushare.pro/document/2
HTTP Error 404: Not Found
HTTP Error 404: Not Found
HTTP Error 404: Not Found

OSError: 获取失败,请检查网络.

由于它的报错里还给你提供了Pro版的接口,所以第一时间我们被引流到了tushare.pro这里。

Tushare数据

Tushare.pro采用的是积分制,应该是运营成本的问题,相当于数据调取是有权限的,每个用户都会有个token,调取数据会用到,新用户是120积分,很多的数据调取是没有权限的。

股票的历史行情数据调取是可以的。先在官网上--个人主页--接口Token中复制好你的专属Token,然后开始历史行情数据的获取。

mytoken = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

import tushare as ts
ts.set_token(mytoken)
pro = ts.pro_api()

df = pro.daily(ts_code='002519.SZ',adj='qfq' )
df

------------------------------
	ts_code	    trade_date	open	high	low	    close	pre_close    change	    pct_chg	vol	amount
0	002519.SZ	20240909	4.35	4.41	4.31	4.37	4.37	0.00	0.0000	102720.70	44840.7400
1	002519.SZ	20240906	4.46	4.47	4.36	4.37	4.46	-0.09	-2.0179	142496.70	62822.5690
2	002519.SZ	20240905	4.42	4.48	4.41	4.46	4.42	0.04	0.9050	134730.29	59894.7670
3	002519.SZ	20240904	4.43	4.49	4.42	4.42	4.48	-0.06	-1.3393	126888.00	56413.2490
4	002519.SZ	20240903	4.45	4.51	4.43	4.48	4.44	0.04	0.9009	133124.75	59516.6510
...	...	...	...	...	...	...	...	...	...	...	...
3201	002519.SZ	20101213	46.83	49.94	46.71	49.03	46.83	2.20	4.7000	25985.88	126183.4667
3202	002519.SZ	20101210	45.08	46.98	45.07	46.83	46.29	0.54	1.1700	19911.31	92133.9409
3203	002519.SZ	20101209	49.01	49.50	46.21	46.29	50.09	-3.80	-7.5900	42875.93	203500.2357
3204	002519.SZ	20101208	50.08	52.88	49.82	50.09	51.92	-1.83	-3.5200	52722.99	268521.1764
3205	002519.SZ	20101207	51.50	57.50	51.04	51.92	36.80	15.12	41.0900	110572.18	598764.3096

根据上节的交给backtrader前的处理,我们能看到tushare.pro得到的股票的历史行情数据有一些特点:

  • 索引是数字
  • 代码是6位数据加上市场的拼音缩写,比如深圳(SZ)
  • 日期是倒序的
  • 开、高、低、收的英文与backtrader接受的相同,成交量是vol,需要改为volume
  • 有些列不需要,日涨跌change及日涨跌幅度 pct_chg (这个相当于收益率,可用于评价)

002_数据的保存与更新

数据获取后应当保存在本地,避免重复的调用接口且可以在没有网络的情况下进行回测。另外,保存在本地可以追加数据。

要追加数据,就要用到索引,数字的索引可做不到正确的追回数据,必须使用datetime。

003_Akshare的获取

其实,除了tushare.pro外,现在有很多的可以获取股票数据的方式,比如Akshare,qstock...

这里就简单借用akshare来获取日线的历史行情数据。

import akshare as ak

stock_zh_a_hist_df = ak.stock_zh_a_hist(symbol="000001", 
                                        period="daily", 
                                        start_date="20200301", 
                                        end_date='20241028', 
                                        adjust="qfq")
stock_zh_a_hist_df

-----------------------------
	日期	股票代码	    开盘	收盘	最高	最低	成交量	成交额	振幅	涨跌幅	涨跌额	换手率
0	2020-03-02	000001	12.92	13.16	13.32	12.83	1116581	1.647432e+09	3.81	2.25	0.29	0.58
1	2020-03-03	000001	13.33	13.09	13.36	13.00	1153584	1.705816e+09	2.74	-0.53	-0.07	0.59
2	2020-03-04	000001	13.05	13.06	13.15	12.88	862595	1.261123e+09	2.06	-0.23	-0.03	0.44
3	2020-03-05	000001	13.17	13.76	14.01	13.10	2686602	4.089494e+09	6.97	5.36	0.70	1.38
4	2020-03-06	000001	13.55	13.40	13.64	13.39	1228531	1.858691e+09	1.82	-2.62	-0.36	0.63
...	...	...	...	...	...	...	...	...	...	...	...	...
1098	2024-09-04	000001	10.05	10.02	10.15	10.00	847992	8.522247e+08	1.49	-0.60	-0.06	0.44
1099	2024-09-05	000001	10.03	10.07	10.08	9.98	594209	5.958458e+08	1.00	0.50	0.05	0.31
1100	2024-09-06	000001	10.06	10.08	10.21	10.05	878865	8.915078e+08	1.59	0.10	0.01	0.45
1101	2024-09-09	000001	10.05	9.85	10.07	9.84	1639175	1.624858e+09	2.28	-2.28	-0.23	0.84
1102	2024-09-10	000001	9.86	9.90	9.92	9.78	767901	7.561248e+08	1.42	0.51	0.05	0.40

在获取了某股的历史行情后,我们再使用与第1节相同的处理方式,就可以把数据送到backtrader里进行回测了。

df = hist_df  
df.rename(columns={
    '日期':'date',
    '开盘':'open',
    '收盘':'close',
    '最高':'high',
    '最低':'low',
    '成交量':'volume',
},inplace=True)

df.index = pd.to_datetime(df.date)
df['openinterest'] = 0
df = df[['open','high','low','close','volume','openinterest']]
df

-----------------------
	    open	high	low	close	volume	openinterest
date						
2020-03-02	2.48	2.54	2.48	2.52	1010956	0
2020-03-03	2.53	2.55	2.52	2.54	1114739	0
2020-03-04	2.53	2.56	2.53	2.55	701546	0
2020-03-05	2.56	2.59	2.56	2.58	1194563	0
2020-03-06	2.57	2.58	2.55	2.55	808703	0
...	...	...	...	...	...	...
2024-08-07	4.61	4.66	4.59	4.62	1419535	0
2024-08-08	4.63	4.65	4.61	4.62	734659	0
2024-08-09	4.62	4.65	4.60	4.63	961159	0
2024-08-12	4.63	4.68	4.62	4.66	1027279	0
2024-08-13	4.65	4.72	4.64	4.70	1491920	0

02_股票全列表获取

这个在tushare.pro中是可以获取的,但积分需要2000,所以很多人是不能通过tushare.pro来调取的,所以这里我们用Akshare来获取。

使用Akshare也有几种方式可以来获取到全股票列表,其中的一种是直接调用东财接口获取

import akshare as ak

# 股票列表
stock_info_a_code_name_df = ak.stock_info_a_code_name()
stock_info_a_code_name_df

-------------------------------
	code	name
0	000001	平安银行
1	000002	万 科A
2	000004	国华网安
3	000006	深振业A
4	000007	全新好
...	...	...
5345	873806	云星宇
5346	873833	美心翼申
5347	920002	万达轴承
5348	920008	成电光信
5349	920118	太湖远大
5350 rows × 2 columns

另一种是通过调用实时行情,然后从里面把股票列表给取出来。两种方式获取到的排列顺序是不同的,上面是以代码000001开始的按数字顺序排序,而调用实时行情的是以涨跌幅进行的排序。

# 股票实时行情数据
import akshare as ak

stock_zh_a_spot_em_df = ak.stock_zh_a_spot_em()
stock_zh_a_spot_em_df.iloc[:,:5]

-----------------------------
	序号	代码	名称	最新价	涨跌幅
0	1	300134	大富科技	10.61	20.02
1	2	300925	法本信息	12.25	19.98
2	3	300030	阳普医疗	5.83	19.96
3	4	300510	金冠股份	3.85	19.94
4	5	300157	新锦动力	2.48	19.81
...	...	...	...	...	...
5636	5637	002520	日发精机	5.37	-10.05
5637	5638	600576	祥源文旅	5.00	-10.07
5638	5639	002596	海南瑞泽	1.69	-10.11
5639	5640	300068	南都电源	10.67	-11.31
5640	5641	300205	ST天喻	4.23	-12.24
5641 rows × 5 columns

03_ETF列表

ETF列表这里直接调用ETF实时行情,从里面取代码和名称即可

# ETF 列表 -- 按当天涨跌幅顺序
import akshare as ak

fund_etf_spot_em_df = ak.fund_etf_spot_em()
fund_etf_spot_em_df.iloc[:,:8]

--------------------------
	代码	名称	最新价	IOPV实时估值	基金折价率	涨跌额	涨跌幅	成交量
0	159527	数据ETF	0.930	0.9287	-0.14	0.029	3.22	25433.0
1	159890	云计算ETF	0.738	0.7373	-0.09	0.021	2.93	222770.0
2	561010	软件ETF基金	0.651	0.6510	0.00	0.018	2.84	20005.0
3	560660	云50ETF	0.700	0.6989	-0.16	0.019	2.79	26965.0
4	159852	软件ETF	0.490	0.4897	-0.06	0.013	2.73	1098940.0
...	...	...	...	...	...	...	...	...
950	560080	中药ETF	0.952	0.9494	-0.27	-0.019	-1.96	450444.0
951	561510	中医药ETF	0.931	0.9302	-0.09	-0.019	-2.00	59762.0
952	159647	中药ETF	0.882	0.8797	-0.26	-0.018	-2.00	325992.0
953	562390	中药50ETF	0.872	0.8704	-0.18	-0.019	-2.13	40116.0
954	159666	交通运输ETF	0.849	0.8494	0.05	-0.020	-2.30	20067.0
955 rows × 8 columns

04_添加拼音缩写

上面的步骤完成后,我们就有了全股票以及ETF的列表,这个时候我们就可以根据列表进行查找,然后再用tushare.pro或者akshare对这个股票/ETF的历史行情数据进行请示调取了。

这里就借鉴各股票软件文本输入框的功能,可以是数字代码,也可以是中文名称或者拼音缩写。在全股票列表中已经有代码和中文名称,我们只需要在它里面添加上一列拼音首字母缩写就可以了。

借用pypinyin库来制作,这个库的安装直接在cmd窗口里pip install即可。

pip install pypinyin

然后,直接问AI "使用pypinyin库获取中文名称的拼音首字母缩写,请提供代码",得到回答:

from pypinyin import lazy_pinyin

def get_initials(name):
    """
    获取中文名称的拼音首字母缩写。
    """

    initials = [pinyin[0].upper() for pinyin in lazy_pinyin(name)]
    return ''.join(initials)

# 示例使用
if __name__ == "__main__":
    name = "工商银行"
    initials = get_initials(name)
    print(f"拼音首字母缩写: {initials}")


-------------
拼音首字母缩写: GSYH

这里其实已经能满足大部分股票的需要了,但是在股票里还有一些比如ST开头的,我们需要把英文字符都显示出来,于是我们再次问AI,得到的回答:

from pypinyin import lazy_pinyin

def get_initials(mixed_string):
    """
    获取包含中文和英文的字符串的拼音首字母缩写。

    """

    # 分离中文和英文部分
    chinese_part = ''
    english_part = ''
    for char in mixed_string:
        if '\u4e00' <= char <= '\u9fff':  # 判断是否为中文字符
            chinese_part += char
        else:
            english_part += char
    
    # 获取中文部分的拼音首字母
    chinese_initials = [pinyin[0].upper() for pinyin in lazy_pinyin(chinese_part)]
    
    # 获取英文部分的首字母
    english_initials = [word[0].upper() for word in english_part.split()]
    
    # 合并结果
    initials = chinese_initials + english_initials
    return ''.join(initials)

# 示例使用
if __name__ == "__main__":
    mixed_string = "ST星光"
    initials = get_initials(mixed_string)
    print(f"拼音首字母缩写: {initials}")

-------------
拼音首字母缩写: XGS

但是这次,AI给出的代码出问题了,从代码上看,把中文字符和非中文分开来是没问题的,但是顺序上就变成了先中文后非中文,这样是不对的,这里需要再给AI说明一下,并且我们又在ETF里发现一堆例如“沪深300ETF天弘”,"中证1000ETF"等里面除了中文和英文还有数字的,一并交给AI进行,就得到了最终版的代码:

from pypinyin import lazy_pinyin

def get_initials(mixed_string):
    """
    获取包含中文和英文的字符串的拼音首字母缩写。

    参数:
    mixed_string (str): 包含中文和英文的字符串。

    返回:
    str: 拼音首字母缩写。
    """
    initials = []
    for char in mixed_string:
        if '\u4e00' <= char <= '\u9fff':  # 判断是否为中文字符
            # 对于中文字符,获取其拼音首字母
            pinyin = lazy_pinyin(char)[0]
            initials.append(pinyin[0].upper())
        elif char.isalpha():  # 对于英文字符,直接获取首字母
            initials.append(char.upper())
        else:  # 对于数字或其他字符,直接保留
            initials.append(char)
    return ''.join(initials)

# 示例使用
if __name__ == "__main__":
    mixed_string = "沪深300ETF天弘"
    initials = get_initials(mixed_string)
    print(f"拼音首字母缩写: {initials}")

---------------------
拼音首字母缩写: HS300ETFTH

完成了添加拼音首字母缩写之后,我们就可以在全股票列表添加一列“PY_ABBR”,然后apply刚上的函数

code_name_df['PY_ABBR'] = code_name_df.name.apply(get_initials)
code_name_df

---------------------------
	code	name	PY_ABBR
0	000001	平安银行	PAYX
1	000002	万 科A	W KA
2	000004	国华网安	GHWA
3	000006	深振业A	SZYA
4	000007	全新好	QXH
...	...	...	...
5345	873806	云星宇	YXY
5346	873833	美心翼申	MXYS
5347	920002	万达轴承	WDZC
5348	920008	成电光信	CDGX
5349	920118	太湖远大	THYD
5350 rows × 3 columns

至此,通过查表,就可以以任意一种方式返回我们所需要的股票的代码,然后再通过xxshare请求该股票的历史行情数据了。

05_自选股列表

当我们进行策略回测时,没有效率的做法是想起一支股票好像叫什么名字,然后查询得到这支股票,然后再做回测;而没有意义的做法是把全股票列表中的所有股票都回测一遍。

参考股票软件,都会有自选股,而且现在都可以分组,分很多组那种,有的股票软件称为自定义板块。所以,一般的情况下,我们都会有一组自己在意的股票,往往我们只要对这一组股票进行回测就可以了。

制作自选股列表非常简单,直接用一个list保存就可以了,或者保存在一个.csv或.txt文件中,每次读取这个文件就能得到自选股列表,当我们需要对其中某支或某几支进行回测时,我们输入它的index即可,而如果我们需要对全部的自选股进行回测,则简单使用for in循环就可以搞定。

在后续backtrader一系列实践完成后,假如我们做一个窗口程序,那么自选股列表就可以以checklist的形式显示出来,需要回测哪几支,直接勾选上就好。

本节小结

这一节我们对股票一系列数据的获取和制作进行了实践,通过实践我们知道了怎么通过tushare.pro或akshare获取某股票的历史行情数据,也知道了怎么制作全股票列表和ETF列表,并且我们添加了拼音首字母缩写以及自选股列表,让backtrader的回测在数据准备方面更加的方便有效,从而提高将来我们回测和分析的效率~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值