0%

利用Tushare和Pandas进行金融数据收集

写在前面


TuShare是一个免费、开源的python财经数据接口包。主要实现对股票等金融数据从数据采集、清洗加工到数据存储的过程,能够为金融分析人员提供快速、整洁和多样的便于分析的数据,为他们在数据获取方面极大地减轻工作量,使他们更加专注于策略和模型的研究与实现上。考虑到Python pandas包在金融量化分析中体现出的优势,TuShare返回的绝大部分的数据格式都是pandas DataFrame类型,非常便于用pandas/NumPy/Matplotlib进行数据分析和可视化。

Tushare在ubuntu14.04版本中可以直接使用以下bash命令安装:

1
pip install tushare

收集目标

收集目标上市公司指定时间内成交价日均值数据,每个上市公司专门存储为一个csv文件。csv文件可以很容易地使用Excel、MATLAB等数据分析软件进行进一步分析处理。

思路

Tushare提供的API中可使用以下数据可以获取某日成交价tick数据:

1
2
import tushare as ts
df = ts.get_tick_data(stock0, date = date0)

注:在这里不选择ts.get_hist_data或者get_k_data函数,因为所求成交价日均值数据要通过日成交价tick数据来求全天均值,数据受开盘价或收盘价的偶然因素影响小。

ts.get_tick_data函数返回一个DataFrame格式的数据,可以使用Python里的Pandas模块进行处理。其中stock0为string格式的股票代码,data0为string格式的日期。示例如下所示:

1
df = ts.get_tick_data('600848', date='2014-01-09')

PS: 来自Tushare官方网站 - 交易数据栏目。另外,Tushare API的详细使用方法可查看Tushare官方网站

接下来,所得到的DataFrame格式数据df,可以被转化为Series格式来求得指定日期的日成交价均值。然后,多个日期成交价均值可以再组成Series格式数据,Series格式数据再组成DataFrame格式数据,最后输出到csv文件中。详细命令笔者会在后面进行讨论。

源代码

运行环境

  • Ubuntu 14.04, 64bit
  • python 2.7.6
  • Python Tushare模块
  • Python Pandas模块

变量说明

STOCKS: Python list数据格式,对象为int.
DATES: Python list数据格式,对象为string.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import tushare as ts
import pandas as pd
from pandas import Series, DataFrame

for stocki in STOCKS:
day_date = Series([]); day_mean = Series([]); # 初始化Series
for datei in DATES:
df = ts.get_tick_data(str(stocki), date = datei)
mean = sum(df.price)/len(df.price)
day_date = day_date.append(Series([datei], index = [len(day_mean)]))
day_mean = day_mean.append(Series([mean], index = [len(day_mean)]))
print 'In'+str(stocki)+', '+datei+'completed'

day_date_mean = DataFrame([day_date,day_mean]).T
day_date_mean.columns = ['Date', 'Price']
print day_date_mean
location = '/home/theone/文档/data/' + str(stocki) + '.csv'
day_date_mean.to_csv(location)

如果因为采集速度太快导致数据出现采集缺失或者IP被禁止,可以考虑使用sleep函数:

1
2
from time import sleep
sleep(1) #休息一秒

代码解析

Tushare模块

首先需要确认Tushare模块已经被正常安装,可以使用简洁的python命令:

1
python -c "import tushare"

若未返回任何错误信息,则证明Tushare模块已被正常安装。

Pandas模块

Pandas是一个开源的Python模块,为使用Python进行数据分析提供了高效便捷的数据结构和分析工具。

Pandas模块有时候会比较麻烦。建议直接安装Anaconda的Python模块包,笔者正是这么做的。Anaconda是关于Python数据分析和科学计算的分发包,可以轻松地在网络上搜索到。

如果希望直接安装Pandas模块也是可以的,详细方法可以从百度上轻松得到。

下面的的说明仅针对本例中使用到的进行讨论,若需要更详细的Pandas命令说明,可以参考Pandas Documentation - cookbook.

本例中着重讨论的是Pandas模块所提供的数据结构Series和DataFrame。对Tushare API所返回的DataFrame结构数据进行处理并存储,正是本文的主要目的。

以下例子我们首先从Tushare获得DataFrame数据df开始。

1
2
3
import tushare as ts
df = ts.get_tick_data('600848', date='2014-01-09')
print(df)

以上例子会返回一个DataFrame数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
        time  price change  volume  amount type
0 14:59:59 9.05 -- 28 25340 买盘
1 14:59:54 9.05 -- 70 63350 买盘
2 14:59:44 9.05 -- 61 55205 买盘
3 14:59:39 9.05 -- 61 55205 买盘
4 14:59:29 9.05 -- 47 42535 买盘
5 14:59:24 9.05 -0.01 23 20815 卖盘
6 14:59:19 9.06 0.01 40 36240 买盘
7 14:59:14 9.05 0.01 10 9050 中性盘
8 14:59:09 9.04 -0.01 104 94015 卖盘
9 14:59:04 9.05 -- 117 105885 买盘
10 14:58:54 9.05 -- 12 10860 买盘
11 14:58:49 9.05 -- 79 71495 卖盘
12 14:58:44 9.05 -- 5 4525 卖盘
13 14:58:39 9.05 -- 5 4525 卖盘
14 14:58:29 9.05 0.01 68 61540 买盘
15 14:58:19 9.04 -- 14 12990 卖盘
16 14:58:14 9.04 -0.01 103 93111 卖盘
17 14:58:09 9.05 -- 1 905 买盘
18 14:57:59 9.05 -- 25 22625 买盘
19 14:57:54 9.05 -0.01 58 52490 中性盘
20 14:57:49 9.06 -- 110 99660 买盘
21 14:57:44 9.06 -- 5 4530 买盘
22 14:57:39 9.06 -- 20 18120 买盘
23 14:57:34 9.06 -- 60 54360 买盘
24 14:57:23 9.06 -- 100 90600 买盘
25 14:57:18 9.06 -- 85 77010 买盘
26 14:57:08 9.06 -- 9 8154 买盘
27 14:57:03 9.06 0.02 7 6342 买盘
28 14:56:58 9.04 -0.02 10 9040 卖盘
29 14:56:53 9.06 0.01 50 45300 买盘
30 14:56:43 9.05 -- 117 105885 买盘
31 14:56:38 9.05 -- 11 9955 买盘
32 14:56:23 9.05 0.01 18 16290 买盘
33 14:56:18 9.04 -- 3 2711 卖盘
34 14:56:13 9.04 0.01 457 413652 买盘
35 14:56:08 9.03 -- 49 44247 卖盘
36 14:56:03 9.03 -0.01 18 16253 卖盘
37 14:55:58 9.04 0.01 2 1807 买盘
38 14:55:53 9.03 -- 5 4515 卖盘
39 14:55:48 9.03 -0.01 5 4515 卖盘
40 14:55:43 9.04 -- 16 14463 买盘
41 14:55:38 9.04 0.01 5 4520 买盘
42 14:55:33 9.03 -- 35 31604 买盘
43 14:55:28 9.03 -0.01 53 47859 卖盘
44 14:55:23 9.04 0.01 10 9040 买盘
45 14:55:13 9.03 -- 28 25284 卖盘
46 14:55:13 9.03 -- 10 9030 卖盘
47 14:55:08 9.03 -0.01 74 66822 卖盘
48 14:55:03 9.04 -- 8 7231 买盘
49 14:54:58 9.04 0.01 50 45199 买盘
50 14:54:53 9.03 -- 10 9030 卖盘
51 14:54:48 9.03 -0.01 51 46053 卖盘
52 14:54:43 9.04 -- 29 26215 买盘
53 14:54:38 9.04 0.01 96 86783 买盘
54 14:54:33 9.03 -0.01 1 902 卖盘
55 14:54:23 9.04 -- 5 4520 买盘
56 14:54:18 9.04 0.01 3 2711 买盘
57 14:54:08 9.03 -0.01 13 11739 卖盘
58 14:54:03 9.04 -- 16 14463 买盘
59 14:53:53 9.04 0.02 10 9040 买盘
... ... ... ... ... ...

[1540 rows x 6 columns]

DataFrame数据类型

因为通过Tushare模块返回的df是DataFrame类型数据,所以我们先从DataFrame开始讨论。

从上面命令的输出中可以看出,DataFrame类型数据类似于一个二维表,因此我们可以对其行、列及表中单个数据进行操作。接下来是具体的命令实例。

选取列数据

执行:

1
print(df.price)

返回:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
0     9.05
1 9.05
2 9.05
3 9.05
4 9.05
5 9.05
6 9.06
7 9.05
8 9.04
9 9.05
10 9.05
11 9.05
12 9.05
13 9.05
14 9.05
...
1525 8.80
1526 8.82
1527 8.83
1528 8.80
1529 8.81
1530 8.80
1531 8.80
1532 8.82
1533 8.80
1534 8.83
1535 8.80
1536 8.83
1537 8.76
1538 8.80
1539 8.76
Name: price, Length: 1540, dtype: float64

选取行数据

执行:

1
print(df[0:10])

返回:
1
2
3
4
5
6
7
8
9
10
11
12
13
       time  price change  volume  amount type
0 14:59:59 9.05 -- 28 25340 买盘
1 14:59:54 9.05 -- 70 63350 买盘
2 14:59:44 9.05 -- 61 55205 买盘
3 14:59:39 9.05 -- 61 55205 买盘
4 14:59:29 9.05 -- 47 42535 买盘
5 14:59:24 9.05 -0.01 23 20815 卖盘
6 14:59:19 9.06 0.01 40 36240 买盘
7 14:59:14 9.05 0.01 10 9050 中性盘
8 14:59:09 9.04 -0.01 104 94015 卖盘
9 14:59:04 9.05 -- 117 105885 买盘

[10 rows x 6 columns]

选取单个数据

执行:

1
print(df.price[10])

返回:
1
9.05

在理解了以上三类操作之后,对DataFrame数据基本上就能够进行简单的处理了。

其它

选取多行

执行:

1
print(df.price[5:10])

返回:
1
2
3
4
5
6
5    9.05
6 9.06
7 9.05
8 9.04
9 9.05
Name: price, dtype: float64

选取多列

执行:

1
2
from pandas import DataFrame
print(DataFrame(df, columns = ['time', 'price']))

返回:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
        time  price
0 14:59:59 9.05
1 14:59:54 9.05
2 14:59:44 9.05
3 14:59:39 9.05
4 14:59:29 9.05
5 14:59:24 9.05
6 14:59:19 9.06
7 14:59:14 9.05
8 14:59:09 9.04
9 14:59:04 9.05
10 14:58:54 9.05
11 14:58:49 9.05
12 14:58:44 9.05
13 14:58:39 9.05
14 14:58:29 9.05
15 14:58:19 9.04
16 14:58:14 9.04
17 14:58:09 9.05
18 14:57:59 9.05
19 14:57:54 9.05
20 14:57:49 9.06
21 14:57:44 9.06
22 14:57:39 9.06
23 14:57:34 9.06
24 14:57:23 9.06
25 14:57:18 9.06
26 14:57:08 9.06
27 14:57:03 9.06
28 14:56:58 9.04
29 14:56:53 9.06
30 14:56:43 9.05
31 14:56:38 9.05
32 14:56:23 9.05
33 14:56:18 9.04
34 14:56:13 9.04
35 14:56:08 9.03
36 14:56:03 9.03
37 14:55:58 9.04
38 14:55:53 9.03
39 14:55:48 9.03
40 14:55:43 9.04
41 14:55:38 9.04
42 14:55:33 9.03
43 14:55:28 9.03
44 14:55:23 9.04
45 14:55:13 9.03
46 14:55:13 9.03
47 14:55:08 9.03
48 14:55:03 9.04
49 14:54:58 9.04
50 14:54:53 9.03
51 14:54:48 9.03
52 14:54:43 9.04
53 14:54:38 9.04
54 14:54:33 9.03
55 14:54:23 9.04
56 14:54:18 9.04
57 14:54:08 9.03
58 14:54:03 9.04
59 14:53:53 9.04
... ...

[1540 rows x 2 columns]

Name: price, dtype: float64

删除特定行
1
2
df = df.drop('change', 1)
print(df[0:10])
1
2
3
4
5
6
7
8
9
10
11
12
13
       time  price  volume  amount type
0 14:59:59 9.05 28 25340 买盘
1 14:59:54 9.05 70 63350 买盘
2 14:59:44 9.05 61 55205 买盘
3 14:59:39 9.05 61 55205 买盘
4 14:59:29 9.05 47 42535 买盘
5 14:59:24 9.05 23 20815 卖盘
6 14:59:19 9.06 40 36240 买盘
7 14:59:14 9.05 10 9050 中性盘
8 14:59:09 9.04 104 94015 卖盘
9 14:59:04 9.05 117 105885 买盘

[10 rows x 5 columns]

Series数据类型

从DataFrame数据中提取其中一列,所得到的数据就是Series数据。其与一般的“列”数据不同,它是有“序号 (Index)”的(或者理解成“索引号”更恰当)。因此我们可以清楚看出,一个Series数据,由两列数据组成:一列是列数据本身,一列是数据的索引号。

索引序号可以自动生成,也可以人工指定。我们可以通过序号索引数据,也可以通过一般与对list数据类似的操作这提高了Series数据的灵活性。

在这里我们不讨论对Series数据的基本操作,入门操作在网络上资源很充足也很完善。

在本例中需要重点关注的是如何生成一个Series数据,并不断在尾部添加数据。

生成Series

执行:

1
2
3
from pandas import Series
obj = Series([4, 7, -5, 3])
print(obj)

返回:
1
2
3
4
5
0    4
1 7
2 -5
3 3
dtype: int64

生成空的Series

1
2
3
from pandas import Series
obj = Series([])
print(obj)

返回:
1
Series([], dtype: float64)

在Series尾部添加数据

执行:

1
2
3
4
5
from pandas import Series
obj = Series([4, 7, -5, 3])
data = 8
obj = obj.append(Series([data], index = [len(obj)]))
print(obj)

返回:
1
2
3
4
5
6
0    4
1 7
2 -5
3 3
4 8
dtype: int64

注意事项

在使用DataFrame和Series命令时,一定记住先导入pandas相关模块,使用:

1
from pandas import DataFrame, Series

写在后面

笔者水平有限,在某朋友邀请下共同完成本次需求。如果内容有所错漏,还请见谅。欢迎联系笔者。
Email: mozheyang@outlook.com