前言:金融数据中最典型的就是资产价格的涨跌情况。想要分析金融资产的投资策略,第一步就是历史数据的获取。tushare
正是为导入历史金融资产数据而开发,它大大方便了用Python进行金融资产交易策略的探索和研究。
tushare
简介:中国的“挖地兔”团队开发并维护,是Python专用的“中国财经数据接口包”,返回的是pandas格式的数据框。当然了,接入数据之后,我们可能还需要NumPy
、pandas
、matplotlib
和sciki-learn
等包进行整理分析和可视化。
之前tushare一直免费,但最近该团队已经正式将tushare升级为pro版,需要用户捐赠购买积分才能使用。这其实就是变相地收费了嘛。当然了,这都是人家的劳动成果,要恰饭也恰得理所当然。看到这,不知道大家有没有想到之前用的NumPy、pandas收过费嘛?用Python和R有人问你要钱嘛?----统统不要啊。。。而且估计以后也不会要!这么一想,是不是觉得整天搞数据撸代码也挺幸福的,毕竟是坐享他人的辛劳成果啊。
baostock
号称提供国内财经数据的第二大Python包,其功能相对tushare要简单一些,但是全部功能免费,而且执行效率要好一些。
1 tushare包的使用
数据获取接口,以获取k线数据为例 :
get_k_data(code=None, start='', end='', ktype='D', autype='qfq', index=False, retry_count=3, pause=0.001)
参数说明:
- code: string,股票代码 ,如000001
- start: string,开始日期 format:YYYY-MM-DD 为空时取上市首日
- end: string,结束日期 format:YYYY-MM-DD 为空时取最近一个交易日
- autype: string,复权类型,qfq-前复权 hfq-后复权 None-不复权,默认为qfq
- ktype: string,数据类型,D=日k线/W=周/M=月/5=5分钟/15=15分钟/30=30分钟/60=60分钟,默认为D
- retry_countint,默认 3,如遇网络等问题重复执行的次数
- pauseint, 默认 0,重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题
- return DataFrame
- date,交易日期
- index ,股票指数
- open,开盘价
- high,最高价
- close,收盘价
- low,最低价
- volume,成交量
- amount,成交额
- turnoverratio,换手率
- code,股票代码
具体实现代码如下。
import tushare as ts ##导入tushare包
##我们先试下老版本的k线数据读取接口get_k_data()。免费,目前还能用
df1 = ts.get_k_data(code='000001', start='20000101', end='20201010') ##000001,代表平安银行
本接口即将停止更新,请尽快使用Pro版接口:https://waditu.com/document/2
##升级后pro版(收费)的读取接口是pro.daily()
df1.head()
Out[40]:
date open close high low volume code
238 2001-01-02 3.606 3.609 3.646 3.572 34122.68 000001
239 2001-01-03 3.611 3.581 3.624 3.564 54294.20 000001
240 2001-01-04 3.584 3.559 3.596 3.547 48404.44 000001
241 2001-01-05 3.554 3.522 3.554 3.502 66419.01 000001
242 2001-01-08 3.522 3.472 3.522 3.467 69944.94 000001
type(df1)
Out[41]: pandas.core.frame.DataFrame
str(df1)
Out[42]: ' date open close high low volume coden238 2001-01-02 3.606 3.609 3.646 3.572 34122.68 000001n239 2001-01-03 3.611 3.581 3.624 3.564 54294.20 000001n240 2001-01-04 3.584 3.559 3.596 3.547 48404.44 000001n241 2001-01-05 3.554 3.522 3.554 3.502 66419.01 000001n242 2001-01-08 3.522 3.472 3.522 3.467 69944.94 000001n... ... ... ... ... ... ... ...n4903 2020-11-30 19.900 19.740 20.880 19.590 1581441.00 000001n4904 2020-12-01 19.700 20.050 20.510 19.400 1263720.00 000001n4905 2020-12-02 19.930 19.630 20.060 19.520 889385.00 000001n4906 2020-12-03 19.780 19.540 19.860 19.170 714452.00 000001n4907 2020-12-04 19.470 19.300 19.470 18.970 891348.00 000001nn[4670 rows x 7 columns]'
sh = ts.get_k_data(code='000001', index=True) ##返回的是股指。上证综指,代码全称是"SH.000001
本接口即将停止更新,请尽快使用Pro版接口:https://waditu.com/document/2
sh.tail() ##数据框的最后6条数据
Out[56]:
date open close high low volume code
636 2020-12-01 3388.99 3451.94 3457.64 3386.91 316188980.0 sh000001
637 2020-12-02 3453.52 3449.38 3465.73 3435.87 312811114.0 sh000001
638 2020-12-03 3448.54 3442.14 3452.16 3428.80 298459930.0 sh000001
639 2020-12-04 3436.73 3444.58 3448.40 3417.05 256276705.0 sh000001
640 2020-12-07 3446.65 3416.60 3449.58 3414.31 254522508.0 sh000001
##保存到本地
df1.to_csv('D:/Spyder/000001.csv')
##选择部分变量,保存到本地
df1.to_csv(D:/Spyder/000001.csv', columns = ['open', 'low', 'high', 'close'])
2 数据和交易策略分析案例
案例分析要求
- 使用tushare下载平安银行(000001)的历史成交数据
- 输出平安银行所有当日涨幅超过5%的日期(如果没有,请调整至2%)
- 输出平安银行所有开盘价比前日收盘跌幅超过5%的日期(如果没有,请调整至2%)
- 假设从2000.1.1开始,每月第一个交易日买入1手平安银行股票,每年最后一个交易日卖出。请问迄今为止,该投资策略收益为多少?
实现代码如下:
##第0步,准备工作
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tushare as ts
第一步,使用tushare下载平安银行(000001)的历史成交数据
##第一步,使用tushare下载平安银行(000001)的历史成交数据
pingan = ts.get_k_data(code='000001', start='20000101', end='20201010')
本接口即将停止更新,请尽快使用Pro版接口:https://waditu.com/document/2
df = pd.read_csv('pingan.csv', index_col='date',
parse_dates=['date'])[['open', 'close', 'high', 'low']]
df.tail()
Out[156]:
open close high low
date
2020-11-30 19.90 19.74 20.88 19.59
2020-12-01 19.70 20.05 20.51 19.40
2020-12-02 19.93 19.63 20.06 19.52
2020-12-03 19.78 19.54 19.86 19.17
2020-12-04 19.47 19.30 19.47 18.97
df.head()
Out[157]:
open close high low
date
2001-01-02 3.606 3.609 3.646 3.572
2001-01-03 3.611 3.581 3.624 3.564
2001-01-04 3.584 3.559 3.596 3.547
2001-01-05 3.554 3.522 3.554 3.502
2001-01-08 3.522 3.472 3.522 3.467
##画一个简单的股价趋势图
import matplotlib.pyplot as plt
plt.plot(pingan['date'], pingan['open'])
plt.show()
第二步,输出平安银行所有当日涨幅超过5%的日期(如果没有,请调整至2%)
df[ (df['close'] - df['open']) / df['open'] >= 0.05 ]
Out[160]:
open close high low
date
2001-09-19 3.001 3.192 3.222 2.986
2002-01-23 2.381 2.565 2.567 2.359
2002-01-31 2.455 2.612 2.641 2.455
2002-03-07 2.679 2.830 2.837 2.659
2002-06-21 2.790 2.954 3.004 2.790
... ... ... ...
2019-02-25 11.700 12.550 12.640 11.570
2019-04-16 13.670 14.580 14.580 13.550
2020-07-03 13.570 14.250 14.320 13.560
2020-07-06 14.600 15.680 15.680 14.590
2020-08-28 14.260 15.130 15.180 14.260
[150 rows x 4 columns]
##结果共有150天
第三步,输出所有开盘价比前日收盘跌幅超过5%的日期(如果没有,请调整至2%)
df[ (df['open'] - df['close'].shift(1)) / df['close'].shift(1) <= -0.05 ]
Out[164]:
open close high low
date
2005-04-22 1.569 1.523 1.630 1.521
2006-06-12 2.012 2.012 2.012 2.012
2006-06-13 1.811 1.811 1.860 1.811
2007-02-28 4.646 4.853 4.886 4.646
2007-05-30 6.959 6.959 7.155 6.959
2007-06-27 8.070 8.207 8.607 8.070
2008-06-10 5.935 5.675 5.935 5.675
2009-01-13 2.951 3.147 3.200 2.951
2013-03-28 7.032 6.704 7.032 6.677
2015-01-19 9.216 9.097 9.584 9.097
2015-07-08 10.994 10.500 11.145 10.500
2019-05-06 13.100 12.870 13.350 12.710
2020-02-03 13.990 13.990 14.700 13.990
2020-03-13 13.900 14.520 14.580 13.900
第四步,假设从2000.1.1开始,每月第一个交易日买入1手平安银行股票,每年最后一个交易日卖出。请问迄今为止,该投资策略收益为多少?
df1 = df['2001-01':'2019-12']
df1
Out[167]:
open close high low
date
2001-01-02 3.606 3.609 3.646 3.572
2001-01-03 3.611 3.581 3.624 3.564
2001-01-04 3.584 3.559 3.596 3.547
2001-01-05 3.554 3.522 3.554 3.502
2001-01-08 3.522 3.472 3.522 3.467
... ... ... ...
2019-12-25 16.450 16.300 16.560 16.240
2019-12-26 16.340 16.470 16.480 16.320
2019-12-27 16.530 16.630 16.930 16.430
2019-12-30 16.460 16.570 16.630 16.100
2019-12-31 16.570 16.450 16.630 16.310
[4446 rows x 4 columns]
df_m1 = df1.resample('M').first() ##获取每个月的首个交易日数据
df_m1 #[228 rows x 4 columns],12个月*19年 = 228行数据
Out[170]:
open close high low
date
2001-01-31 3.606 3.609 3.646 3.572
2001-02-28 3.720 3.619 3.745 3.609
2001-03-31 3.522 3.547 3.596 3.497
2001-04-30 4.030 4.100 4.130 3.998
2001-05-31 3.852 3.844 3.882 3.837
... ... ... ...
2019-08-31 14.060 14.100 14.190 13.940
2019-09-30 14.150 14.450 14.500 14.110
2019-10-31 15.600 16.200 16.230 15.600
2019-11-30 16.350 16.860 17.000 16.280
2019-12-31 15.350 15.360 15.430 15.230
[228 rows x 4 columns]
df_m1 = df_m1['open']
df_ycost = df_m1.resample('A').mean()
df_ycost
Out[173]:
date
2001-12-31 3.589583
2002-12-31 3.128750
2003-12-31 2.672500
2004-12-31 2.230750
2005-12-31 1.538500
2006-12-31 1.983750
2007-12-31 7.594083
2008-12-31 6.056333
2009-12-31 6.021833
2010-12-31 6.663300
2011-12-31 5.505917
2012-12-31 5.018750
2013-12-31 6.487250
2014-12-31 6.611583
2015-12-31 10.111000
2016-12-31 8.658250
2017-12-31 10.018750
2018-12-31 10.897917
2019-12-31 13.395000
Freq: A-DEC, Name: open, dtype: float64
df_yl1 = df1.resample('A').last() ##获取每年最后一个交易日的数据
df_yl1
Out[175]:
open close high low
date
2001-12-31 3.026 3.038 3.051 3.001
2002-12-31 2.607 2.629 2.657 2.571
2003-12-31 2.216 2.168 2.226 2.155
2004-12-31 1.676 1.679 1.697 1.676
2005-12-31 1.587 1.564 1.590 1.562
2006-12-31 3.604 3.686 3.739 3.587
2007-12-31 9.909 9.833 10.001 9.833
2008-12-31 3.174 3.144 3.190 3.091
2009-12-31 8.102 8.099 8.205 8.006
2010-12-31 5.211 5.247 5.274 5.181
2011-12-31 5.101 5.181 5.181 5.085
2012-12-31 5.260 5.364 5.414 5.240
2013-12-31 6.340 6.621 6.697 6.297
2014-12-31 10.268 10.419 10.446 10.064
2015-12-31 9.632 9.545 9.656 9.537
2016-12-31 8.805 8.825 8.825 8.786
2017-12-31 13.000 13.089 13.217 12.892
2018-12-31 9.310 9.380 9.460 9.310
2019-12-31 16.570 16.450 16.630 16.310
df_yl1 = df_yl1['open'] ##19年共19行数据
df_earn = (df_yl1 - df_ycost) * 100 * 12
df_earn
Out[178]:
date
2001-12-31 -676.30
2002-12-31 -626.10
2003-12-31 -547.80
2004-12-31 -665.70
2005-12-31 58.20
2006-12-31 1944.30
2007-12-31 2777.90
2008-12-31 -3458.80
2009-12-31 2496.20
2010-12-31 -1742.76
2011-12-31 -485.90
2012-12-31 289.50
2013-12-31 -176.70
2014-12-31 4387.70
2015-12-31 -574.80
2016-12-31 176.10
2017-12-31 3577.50
2018-12-31 -1905.50
2019-12-31 3810.00
Freq: A-DEC, Name: open, dtype: float64
df_earn.sum()
Out[179]: 8657.039999999994
##第四步可以用循环来实现。但是没有必要,因为本身pandas已经把数据整理得很工整
##加上题目简单,直接矩阵向量的运算就可以了
2 中国金融数据导入包baostock
import baostock as bs
import pandas as pd
## 登陆
lg = bs.login()
##读入上证综指的历史数据
rs = bs.query_history_k_data("000001.SH", "date,code,open,high,low,close,preclose,volume,amount,adjustflag,turn,tradestatus,pctChg,peTTM,pbMRQ,psTTM,pcfNcfTTM,isST",
start_date='2010-01-01', end_date='2020-10-10', frequency="d", adjustflag="3")
导入后查看默认保存的数据格式
rs
Out[24]: <baostock.data.resultset.ResultData at 0x172569e37c0>
str(rs) ##查看结构
Out[28]: '<baostock.data.resultset.ResultData object at 0x00000172569E37C0>'
type(rs) ##查看类型
Out[29]: baostock.data.resultset.ResultData
将数据转换为data frame格式
data = []
while (rs.error_code == '0') & rs.next(): # 逐条获取数据并合并
data_list.append(rs.get_row_data())
df = pd.DataFrame(data_list, columns=rs.fields)
df
Out[31]:
date code open ... psTTM pcfNcfTTM isST
0 2010-01-04 sh.000001 3289.7500 ... 0
1 2010-01-05 sh.000001 3254.4680 ... 0
2 2010-01-06 sh.000001 3277.5170 ... 0
3 2010-01-07 sh.000001 3253.9910 ... 0
4 2010-01-08 sh.000001 3177.2590 ... 0
... ... ... ... ... ... ...
2610 2020-09-25 sh.000001 3234.3739 ... 0.000000 0.000000 0
2611 2020-09-28 sh.000001 3224.9769 ... 0.000000 0.000000 0
2612 2020-09-29 sh.000001 3231.8551 ... 0.000000 0.000000 0
2613 2020-09-30 sh.000001 3232.7104 ... 0.000000 0.000000 0
2614 2020-10-09 sh.000001 3262.6105 ... 0.000000 0.000000 0
[2615 rows x 18 columns]
将数据框导出为CSV文件
df.to_csv("D:/Spyder/history_A_stock_k_data.csv", index=False)
3 小结
本文向大家展示了两大中国的Python金融交易数据导入包。其中tushare
发展较为成熟,功能也稳定,可以搞了个捐钱换积分就让初学者会觉得有点啰嗦。如果不想搞得那么麻烦,baostock
也是个不错的备选。
另外,也向大家展示了一个简单的金融交易策略。使用策略基于历史价格数据进行验证,就是所谓的‘回测’。量化交易最核心的任务,就是研究出一个好的交易策略,通过真实的投资而实现盈利。
至于国外尤其是美股的数据导入库,后面还会陆续和大家介绍。
REF
2020,伊夫·希尔皮斯科,《Python金融大数据分析 第2版》
-----全文结束-----