量化策略二几种Python工具包

1、numpy包

1.1numpy安装及加载

1.1.1安装

下载:https://pypi.org/project/numpy/#files

放入python安装目录下的Scripts文件夹。将此路径添加到计算机属性-高级系统设置-环境变量-系统变量-path。

1.1.2加载numpy:

>>> import numpy as np

 

1.2numpy数组:Ndarray

1.2.1数组属性:ndim(维度),shape(形状),size(元素个数),dtype(元素的数据类型对象)

>>> #创建Ndarray,通过list

>>> list=[1,2,3]

>>> a=np.array(list)

>>> type(a)

numpy.ndarray

>>> b=np.random.randn(3,5)#新建随机数组,符合正态分布。维度为三行五列

>>> b

array([[-1.81810715,  0.07028648,  0.268396  , -0.52517799, -0.1521735 ],

[-0.05492686, -0.54682043,  0.12443828, -1.13229014,  0.1846318 ],

[ 1.14833746, -1.33237822, -0.63548405,  0.63879423, -0.9867965 ]])

>>> b.ndim

2

>>> a.shape

(3,)

1.2.2操作:索引、切片

>>> b[2]

array([-0.05492686, -0.54682043,  0.12443828, -1.13229014,  0.1846318])

>>> b[2,2]

0.12443828

>>> b[[1,2],3]#取第二行第四列,第三行第四列两数

array([-1.13229014, 0.63879423])

>>> c=np.arange(10)#生成长度为10的数组

>>> print c

>>> print c[c>5]#选出大于5的元素组成子数组

[0 1 2 3 4 5 6 7 8 9]

[6 7 8 9]

1.2.3 计算

>>> a = np.arange(20).reshape(4,5)

>>> print “a:”

>>> print a

>>> print “sum of all elements in a: ” + str(a.sum())

>>> print “maximum element in a: ” + str(a.max())

>>> print “minimum element in a: ” + str(a.min())

>>> print “maximum element in each row of a: ” + str(a.max(axis=1))

>>> print “minimum element in each column of a: ” + str(a.min(axis=0))

a:

[[ 0  1  2  3  4]

[ 5  6  7  8  9]

[10 11 12 13 14]

[15 16 17 18 19]]

sum of all elements in a: 190

maximum element in a: 19

minimum element in a: 0

maximum element in each row of a: [ 4  9 14 19]

minimum element in each column of a: [0 1 2 3 4]

 

2、scipy包

2.1加载

>>> import numpy as np

>>> import scipy.stats as stats#加载统计部分

>>> import scipy.optimize as opt#加载优化部分

 

2.2生成随机数

>>> x_norm=stats.norm.rvs(size=500,loc=1,scale=0.5)#生成500个点符合正态分布,均值1,方差0.5。均匀分布(uniform)、正态分布(norm)、贝塔分布(beta)、伯努利分布(bernoulli)、几何分布(geom)、泊松分布(poisson)

>>> print stats.norm.fit(x_norm)#分析对象的参数,均值、方差

(1.0495313705036946, 0.49857065555009966)

 

2.3优化

#求解函数f(x)=2x2+5x+3

>>> def fun(x):#定义函数

        return 2*x**2+5*x+3

>>> print “根1:”

>>> print opt.fsolve(fun,0)#从0开始搜索,打印根1

>>> print “根2:”

>>> print opt.fsolve(fun,-10)#从-10开始搜索,打印根2

>>> print “最小值:”

>>> print opt.minimize(f,0)#求最小值

>>> print “条件限制下的最小值:”

>>> y=({“type”:”ineq”,”fun”:lambda x:x+4})#定义限制变量x>=-4

>>> print opt.minimize(f,0,constraints=y)#求此条件下最值

根1:

[-1.]

根2:

[-1.5]

最小值:

status: 0

success: True

njev: 3

nfev: 9

hess_inv: array([[1]])

fun: -0.12499999999999956

x: array([-1.24999999])

message: ‘Optimization terminated successfully.’

jac: array([  5.96046448e-08])

条件限制下的最小值:

status: 0

success: True

njev: 2

nfev: 7

fun: array([-0.125])

x: array([-1.25])

message: ‘Optimization terminated successfully.’

jac: array([  2.98023224e-08,   0.00000000e+00])

nit: 2

 

3、pandas包

3.1加载

>>> import pandas as pd

>>> from pandas import Series, DataFrame#导入两种数据结构模块

 

3.2数据结构一:Series

3.2.1Series的创建

>>> s = Series(np.random.randn(5), index=[‘a’, ‘b’, ‘c’, ‘d’, ‘e’], name=’my_series’)#创建Series,并指定index,取名my_series

>>> print s

a    0.076719

b   -1.064217

c   -0.234663

d    0.472426

e   -2.266664

Name: my_series, dtype: float64

>>> print s.index#显示index

Index([u’a’, u’b’, u’c’, u’d’, u’e’], dtype=’object’)

>>> print s.name#显示数据名

my_series

>>> d = {‘a’: 0., ‘b’: 1, ‘c’: 2}#创建dict,可以通过dict创建Series

>>> print d

>>> print ‘_________’#分隔

>>> s = Series(d)#转换为Series数据类型

>>> print s

{‘a’: 0.0, ‘c’: 2, ‘b’: 1}

_________

a    0.0

b    1.0

c    2.0

dtype: float64

#与直接创建Series的index长度要和data的长度一致不同。通过字典创建的Series,数据将按index的顺序重新排列。并且index长度可以和字典长度不一致,如果多了的话,pandas将自动为多余的index分配NaN,index少的话就截取部分的字典内容

3.2.2Series数据查看

>>> print s[2]

>>> print ‘_________’

>>> print s[:2]

>>> print ‘_________’

>>> print s[[2,0,1]]

>>> print ‘_________’

>>> print s[[‘e’, ‘i’]]

>>> print ‘_________’

>>> ‘e’ in s

2.0

_________

a    0.0

b    1.0

dtype: float64

_________

c    2.0

a    0.0

b    1.0

dtype: float64

_________

e   NaN

i   NaN

dtype: float64

_________

False

 

3.3数据结构二:DataFrame

3.3.1创建DataFrame

#DataFrame是一个二维的数据结构,是多个Series的集合体

>>> d = {‘one’: Series([1., 2., 3.], index=[‘a’, ‘b’, ‘c’]), ‘two’: Series([1., 2., 3., 4.], index=[‘a’, ‘b’, ‘c’, ‘d’])}#创建两个Series

>>> df = DataFrame(d)#通过Series创建DataFrame

>>> print df

one  two

a  1.0  1.0

b  2.0  2.0

c  3.0  3.0

d  NaN  4.0

>>> df = DataFrame(d, index=[‘r’, ‘d’, ‘a’], columns=[‘two’, ‘three’])#指定按行、列名检索,没有值则显示NaN

>>> print df

two three

r  NaN   NaN

d    4   NaN

a    1   NaN

>>> d = {‘one’: [1., 2., 3., 4.], ‘two’: [4., 3., 2., 1.]}

>>> df = DataFrame(d, index=[‘a’, ‘b’, ‘c’, ‘d’])#通过dict创建,当dict的值是数组时各个数据组的长度要相同

>>> print df

one  two

a    1    4

b    2    3

c    3    2

d    4    1

>>> df = DataFrame()#创建空DataFrame

>>> print df

Empty DataFrame

Columns: []

Index: []

>>> a = Series(range(5))

>>> b = Series(np.linspace(4, 20, 5))

>>> df = pd.concat([a, b], axis=1)#通过concat创建。axis参数为0时按行合并,为1的话按列合并

>>> print df

0   1

0  0   4

1  1   8

2  2  12

3  3  16

4  4  20

3.3.2DataFrame数据查看

>>> df = DataFrame()#创建空函数

>>> index = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’]#命名行名

>>> for i in range(5):

        a = DataFrame([np.linspace(i, 5*i, 5)], index=[index[i]])

        df = pd.concat([df, a], axis=0)#合并生成新数据

>>> print df

0    1     2     3     4

a  0.0  0.0   0.0   0.0   0.0

b  1.0  2.0   3.0   4.0   5.0

c  2.0  4.0   6.0   8.0  10.0

d  3.0  6.0   9.0  12.0  15.0

e  4.0  8.0  12.0  16.0  20.0

>>> print df[1]#按列的下标查看

>>> print type(df[1])

>>> df.columns = [‘A’, ‘B’, ‘C’, ‘D’, ‘E’]#为每一列取名

>>> print df[‘B’]#按列名查看

>>> print type(df[‘B’])

>>> print df.B

>>> print type(df.B)

>>> print df[[‘A’, ‘D’]]#选取查看任意两列

>>> print type(df[[‘A’, ‘D’]])

a    0.0

b    2.0

c    4.0

d    6.0

e    8.0

Name: 1, dtype: float64

<class ‘pandas.core.series.Series’>

a    0.0

b    2.0

c    4.0

d    6.0

e    8.0

Name: B, dtype: float64

<class ‘pandas.core.series.Series’>

a    0.0

b    2.0

c    4.0

d    6.0

e    8.0

Name: B, dtype: float64

<class ‘pandas.core.series.Series’>

A     D

a  0.0   0.0

b  1.0   4.0

c  2.0   8.0

d  3.0  12.0

e  4.0  16.0

<class ‘pandas.core.frame.DataFrame’>

>>> print df

>>> print df[‘B’][2]#按坐标查看数据,先列后行

>>> print df[‘B’][‘d’]

A    B     C     D     E

a  0.0  0.0   0.0   0.0   0.0

b  1.0  2.0   3.0   4.0   5.0

c  2.0  4.0   6.0   8.0  10.0

d  3.0  6.0   9.0  12.0  15.0

e  4.0  8.0  12.0  16.0  20.0

4.0

6.0

>>> print df.iloc[1]#选取行

>>> print df.loc[‘b’]

a    1

b    2

c    3

d    4

e    5

Name: b, dtype: float64

a    1

b    2

c    3

d    4

e    5

Name: b, dtype: float64

>>> print df[[‘B’, ‘D’]].iloc[[1, 3]]#用复合条件选取数据查看

>>> print df.iloc[[1, 3]][[‘B’, ‘D’]]

>>> print df[[‘B’, ‘D’]].loc[[‘b’, ‘d’]]

B     D

b  2.0   4.0

d  6.0  12.0

B     D

b  2.0   4.0

d  6.0  12.0

B     D

b  2.0   4.0

d  6.0  12.0

>>> print df.ix[‘d’, 4]#dataframe.ix可以混合使用索引和下标进行访问,唯一需要注意的地方是行列内部需要一致,不可以同时使用索引和标签访问行或者列

>>> print df.ix[[‘e’, ‘c’], [1, 4]]

>>> print df.ix[[1, 2], [‘B’, ‘E’]]

>>> print “Unwanted result:”

>>> print df.ix[[‘b’, 2], [‘B’, ‘E’]]

>>> print df.ix[[1, 2], [‘B’, 4]]

A    B     C     D     E

a  0.0  0.0   0.0   0.0   0.0

b  1.0  2.0   3.0   4.0   5.0

c  2.0  4.0   6.0   8.0  10.0

d  3.0  6.0   9.0  12.0  15.0

e  4.0  8.0  12.0  16.0  20.0

15.0

B     E

e  8.0  20.0

c  4.0  10.0

B     E

b  2.0   5.0

c  4.0  10.0

Unwanted result:

B    E

b  2.0  5.0

2  NaN  NaN

B   4

b  2.0 NaN

c  4.0 NaN

3.3.3在优矿平台使用pandas

>>> stock_list = [‘000001.XSHE’, ‘000002.XSHE’, ‘000568.XSHE’, ‘000625.XSHE’, ‘000768.XSHE’, ‘600028.XSHG’, ‘600030.XSHG’, ‘601111.XSHG’, ‘601390.XSHG’, ‘601998.XSHG’]#选取以上股票

>>> raw_data = DataAPI.MktEqudGet(secID=stock_list, beginDate=’20150101′, endDate=’20150131′, pandas=’1′)#选取时间区间

>>> df = raw_data[[‘secID’, ‘tradeDate’, ‘secShortName’, ‘openPrice’, ‘highestPrice’, ‘lowestPrice’, ‘closePrice’, ‘turnoverVol’]]#日行情信息

>>> print df.shape#查看数据大小

(200, 8)#200条记录,每条记录8字段

>>> print df.head()#查看前五行,默认五行

>>> print df.tail(3)#查看末尾三行

secID   tradeDate secShortName  openPrice  highestPrice  lowestPrice  closePrice  turnoverVol

0  000001.XSHE  2015-01-05         平安银行      15.99         16.28        15.60       16.02    286043643

1  000001.XSHE  2015-01-06         平安银行      15.85         16.39        15.55       15.78    216642140

2  000001.XSHE  2015-01-07         平安银行      15.56         15.83        15.30       15.48    170012067

3  000001.XSHE  2015-01-08         平安银行      15.50         15.57        14.90       14.96    140771421

4  000001.XSHE  2015-01-09         平安银行      14.90         15.87        14.71       15.08    250850023

secID   tradeDate secShortName  openPrice  highestPrice  lowestPrice  closePrice  turnoverVol

197  601998.XSHG  2015-01-28         中信银行       7.04          7.32         6.95        7.15    163146128

198  601998.XSHG  2015-01-29         中信银行       6.97          7.05         6.90        7.01     93003445

199  601998.XSHG  2015-01-30         中信银行       7.10          7.14         6.92        6.95     68146718

>>> print df.describe()#显示表中数值型数据的统计信息

openPrice  highestPrice  lowestPrice  closePrice   turnoverVol

count  200.00000    200.000000    200.00000  200.000000  2.000000e+02

mean    15.17095     15.634000     14.86545   15.242750  2.384811e+08

std      7.72807      7.997345      7.56136    7.772184  2.330510e+08

min      6.14000      6.170000      6.02000    6.030000  1.242183e+07

25%      8.09500      8.250000      7.98750    8.127500  7.357002e+07

50%     13.96000     14.335000     13.75500   13.925000  1.554569e+08

75%     19.95000     20.500000     19.46250   20.012500  3.358617e+08

max     36.40000     37.250000     34.68000   36.150000  1.310855e+09

>>> print df.sort_index(axis=1, ascending=True).head()#排序。axis为1按列排序,为0按行排序。默认ascending升序,False为降序

>>> print df.sort(columns=’tradeDate’).head()#按值排序。按tradeDate排序,默认升序

>>> print df.sort(columns=[‘tradeDate’, ‘secID’], ascending=[False, True]).head()#按两个值排序

closePrice  highestPrice  lowestPrice  openPrice        secID secShortName   tradeDate  turnoverVol

19       13.93         14.12        13.76      13.93  000001.XSHE         平安银行  2015-01-30     93011669

39       13.12         13.49        12.80      13.09  000002.XSHE          万科A  2015-01-30    209624706

59       19.12         19.51        19.11      19.15  000568.XSHE         泸州老窖  2015-01-30     14177179

79       19.18         19.45        18.92      19.16  000625.XSHE         长安汽车  2015-01-30     21233495

99       24.60         25.65        24.28      25.38  000768.XSHE         中航飞机  2015-01-30     59550293

secID   tradeDate secShortName  openPrice  highestPrice  lowestPrice  closePrice  turnoverVol

180  601998.XSHG  2015-01-05         中信银行       8.15          8.33         7.91        8.16    337368242

0    000001.XSHE  2015-01-05         平安银行      15.99         16.28        15.60       16.02    286043643

20   000002.XSHE  2015-01-05          万科A      14.39         15.29        14.22       14.91    656083570

40   000568.XSHE  2015-01-05         泸州老窖      20.50         21.99        20.32       21.90     59304755

60   000625.XSHE  2015-01-05         长安汽车      16.40         18.07        16.32       18.07     82087982

secID   tradeDate secShortName  openPrice  highestPrice  lowestPrice  closePrice  turnoverVol

19  000001.XSHE  2015-01-30         平安银行      13.93         14.12        13.76       13.93     93011669

39  000002.XSHE  2015-01-30          万科A      13.09         13.49        12.80       13.12    209624706

59  000568.XSHE  2015-01-30         泸州老窖      19.15         19.51        19.11       19.12     14177179

79  000625.XSHE  2015-01-30         长安汽车      19.16         19.45        18.92       19.18     21233495

99  000768.XSHE  2015-01-30         中航飞机      25.38         25.65        24.28       24.60     59550293

>>> print df[df.closePrice > df.closePrice.mean()].head()#过滤收盘价在均值以上的数据

secID   tradeDate secShortName  openPrice  highestPrice  lowestPrice  closePrice  turnoverVol

59   000568.XSHE  2015-01-30         泸州老窖      19.15         19.51        19.11       19.12     14177179

79   000625.XSHE  2015-01-30         长安汽车      19.16         19.45        18.92       19.18     21233495

99   000768.XSHE  2015-01-30         中航飞机      25.38         25.65        24.28       24.60     59550293

139  600030.XSHG  2015-01-30         中信证券      28.50         28.72        27.78       27.86    304218245

58   000568.XSHE  2015-01-29         泸州老窖      19.04         19.23        19.00       19.15     12421826

>>> print df[df[‘secID’].isin([‘601628.XSHG’, ‘000001.XSHE’, ‘600030.XSHG’])].head()#选取需要的值

secID   tradeDate secShortName  openPrice  highestPrice  lowestPrice  closePrice  turnoverVol

19   000001.XSHE  2015-01-30         平安银行      13.93         14.12        13.76       13.93     93011669

139  600030.XSHG  2015-01-30         中信证券      28.50         28.72        27.78       27.86    304218245

18   000001.XSHE  2015-01-29         平安银行      13.82         14.01        13.75       13.90    101675329

138  600030.XSHG  2015-01-29         中信证券      28.10         28.58        27.81       28.18    386310957

17   000001.XSHE  2015-01-28         平安银行      13.87         14.30        13.80       14.06    124087755

———————————-

>>> df.fillna(0,0)#填充空值为0.0

>>> df.dropna()#删除带空值的行。默认axis=0为删除行,axis=1删除列。默认how=’any’表示‘只要有’就满足条件,how=‘all’表示需全部为空值

>>> df.mean(0)#按列求平均数

>>> df.sum(1)#按行求和

>>> df[‘closePrice’].value_counts().head()#依closePrice变量值统计频次

>>> df1.merge(df2, on=[‘secID’, ‘tradeDate’])#按secID和tradeDate两列合并df1和df2

>>> df.groupby(‘secID’)#依secID分组

———————————-

>>> df1 = df.sort(columns=[‘secID’, ‘tradeDate’], ascending=[True, False])#按日期排序

>>> print df1.drop_duplicates(subset=’secID’)#再按secID去重。可以获得每只股票的最新数据

secID   tradeDate secShortName  openPrice  highestPrice  lowestPrice  closePrice  turnoverVol

19   000001.XSHE  2015-01-30         平安银行      13.93         14.12        13.76       13.93     93011669

39   000002.XSHE  2015-01-30          万科A      13.09         13.49        12.80       13.12    209624706

59   000568.XSHE  2015-01-30         泸州老窖      19.15         19.51        19.11       19.12     14177179

79   000625.XSHE  2015-01-30         长安汽车      19.16         19.45        18.92       19.18     21233495

99   000768.XSHE  2015-01-30         中航飞机      25.38         25.65        24.28       24.60     59550293

119  600028.XSHG  2015-01-30         中国石化       6.14          6.17         6.02        6.03    502445638

139  600030.XSHG  2015-01-30         中信证券      28.50         28.72        27.78       27.86    304218245

159  601111.XSHG  2015-01-30         中国国航       7.92          8.03         7.65        7.69     61877792

179  601390.XSHG  2015-01-30         中国中铁       8.69          8.69         8.12        8.14    352357431

199  601998.XSHG  2015-01-30         中信银行       7.10          7.14         6.92        6.95     68146718

3.3.4pandas可视化数据

>>> dat = df[df[‘secID’] == ‘000568.XSHE’].set_index(‘tradeDate’)[‘closePrice’]#选取泸州老窖,将DataFrame的’tradeDate’这一列作为索引,将’closePrice’这一列作为Series的值,返回一个Series对象

>>> print dat

>>> dat.plot(title=”Close Price of (000568) during Jan, 2015″)

tradeDate

2015-01-30    19.12

2015-01-29    19.15

2015-01-28    19.25

2015-01-27    19.59

2015-01-26    19.53

2015-01-23    19.22

2015-01-22    19.26

2015-01-21    19.14

2015-01-20    18.66

2015-01-19    18.32

2015-01-16    19.45

2015-01-15    19.34

2015-01-14    19.24

2015-01-13    19.10

2015-01-12    19.37

2015-01-09    21.42

2015-01-08    21.64

2015-01-07    21.59

2015-01-06    21.58

2015-01-05    21.90

Name: closePrice, dtype: float64

<matplotlib.axes._subplots.AxesSubplot at 0xa233d90>

量化策略一Python

 

《量化策略》系列文章的部分内容来自于优矿网(UQER)的量化学堂和量化社区。