Python与量化投资 第三章

Python与量化投资

从基础到实战

在这里插入图片描述

第三章 Python 进阶

3.1 NumPy 的使用

NumPy 是高性能科学计算和数据分析的基础包。

import numpy as np

一旦在代码中看到np,就是使用了NumPy。

  • 多维数组 ndarray
    一个快速、灵活的大数据容器。

一维数组

data=[1,2,3,4]
arr=np.array(data)
arr
array([1, 2, 3, 4])

多维数组

data1=[data,data]
arr1=np.array(data1)
arr1

array([[1, 2, 3, 4],
       [1, 2, 3, 4]])

其他函数也可以快速创建数组

np.zeros((3,3))

array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])

np.ones((3,3))

array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])

np.arange(1,10,2)

array([1, 3, 5, 7, 9])

np.linspace(1,10,4) # 创建一个等差数列

array([  1.,   4.,   7.,  10.])
  • ndarray 的数据类型
    dtype 代表ndarray 中元素的数据类型。
arr2=np.array([1,2,3,4])
arr2.dtype

dtype('int32')

arr3=np.array([1.1,2,3,4])
arr3.dtype

dtype('float64')

arr4=np.array(['量','化','分','析'])
arr4.dtype

dtype('<U1')

不同的数据类型之间也能互相转换

float_arr2=arr2.astype(np.float64)
float_arr2

array([ 1.,  2.,  3.,  4.])

int_arr3=arr3.astype(np.int32)
int_arr3

array([1, 2, 3, 4])

u_arr3=arr3.astype(np.unicode_)
u_arr3

array(['1.1', '2.0', '3.0', '4.0'], 
      dtype='<U32')
  • 数组索引、切片和赋值
arr4=np.array([[1,2,3],[4,5,6],[7,8,9]])
arr4

array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

arr4[1]   #索引
array([4, 5, 6])

arr4[:2] # 切片
array([[1, 2, 3],
       [4, 5, 6]])

arr4[:2,:2]   # 切片
array([[1, 2],
       [4, 5]])

arr4[:2, :2] = 10  # 赋值
arr4
array([[10, 10,  3],
       [10, 10,  6],
       [ 7,  8,  9]]

arr4.copy()[:2, :2] = 5    # 赋值
arr4
array([[10, 10,  3],
       [10, 10,  6],
       [ 7,  8,  9]])
  • 基本的数组运算
    代码向量化
arr5 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr5
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

arr5 + arr5
array([[ 1,  4,  9],
       [16, 25, 36],
       [49, 64, 81]])
       
arr5 * arr5
array([[ 1,  4,  9],
       [16, 25, 36],
       [49, 64, 81]])
       
arr5 * 2
array([[ 2,  4,  6],
       [ 8, 10, 12],
       [14, 16, 18]])

arr5 ** 0.5
array([[ 1.        ,  1.41421356,  1.73205081],
       [ 2.        ,  2.23606798,  2.44948974],
       [ 2.64575131,  2.82842712,  3.        ]])


arr5.sum()
45

arr5.std()
2.5819888974716112

arr5.mean()
5.0

arr5.max()
9

在这里插入图片描述

def f(x):
    return x ** 2
f(arr5)
array([[ 1,  4,  9],
       [16, 25, 36],
       [49, 64, 81]])   
  • 随机数
    伪随机数,字库numpy.random。
import numpy.random as npr
import matplotlib.pyplot as plt
%matplotlib inline

# npr.rand()函数可以用来生成[0,1) 的随机多维数组
npr.rand(3, 2)
array([[ 0.89298191,  0.03415187],
       [ 0.85438543,  0.26102217],
       [ 0.25366176,  0.7302258 ]])

# 随机区间可以转化
a = 2
b = 4
npr.rand(3, 2) * (b - a) + a
array([[ 2.26095239,  2.85244207],
       [ 2.90443128,  3.29532683],
       [ 2.60474432,  3.14618094]])

生成简单随机数的函数及其参数和描述可视化

size = 1000
rn1 = npr.rand(size, 2)
rn2 = npr.randn(size)
rn3 = npr.randint(0, 10, size)
rang = [0, 10, 20, 30, 40]
rn4 = npr.choice(rang, size = size)
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows = 2, ncols = 2, figsize = (10, 10))
ax1.hist(rn1, bins = 25, stacked = True)
ax1.set_title('rand')
ax1.set_ylabel('frequency')
ax1.grid(True)
ax2.hist(rn2, bins = 25)
ax2.set_title('randn')
ax2.grid(True)
ax3.hist(rn3, bins = 25)
ax3.set_title('randint')
ax3.set_ylabel('frequency')
ax3.grid(True)
ax4.hist(rn4, bins = 25)
ax4.set_title('choice')
ax4.grid(True)

在这里插入图片描述

3.2 Pandas 的使用

Pandas是基于NumPy 衍生出的一种工具,用于解决数据分析问题,他纳入了大量的库和一些标准的数据模型,提供了可用于高效操作大型数据集的工具。

import pandas as pd

一旦代码中看到了pd ,就是使用了Pandas。

  • Pandas 的数据结构
  1. Series(一维数组)
    Series 增加了对应的标签以用于索引,标签索引赋予了Series 强大的存取元素的功能。
obj = pd.Series([40, 12, -3, 25])
obj

0    40
1    12
2    -3
3    25
dtype: int64

obj[0]
40

obj.index   # 可以通过index 与value获取Series的索引与数据
RangeIndex(start=0, stop=4, step=1)

obj.values
array([40, 12, -3, 25], dtype=int64)

# Series 建立时就指定索引
obj = pd.Series([40, 12, -3, 25],index=['a','b','c','d'])
obj
a    40
b    12
c    -3
d    25
dtype: int64

# 通过索引获取数值
obj['c']
-3

# 对于Series 的各种计算,其他结果也会保留index
obj[obj>15]
a    40
d    25
dtype: int64

# 
obj.describe()
count     4.000000
mean     18.500000
std      18.339393
min      -3.000000
25%       8.250000
50%      18.500000
75%      28.750000
max      40.000000
dtype: float64

obj.mean()
18.5

# 转换为字典
obj.to_dict()
{'a': 40, 'b': 12, 'c': -3, 'd': 25}
  1. DataFrame(二维的表格型数据结构)
d = {'one' : pd.Series([1., 2., 3.], index=['a', 'b', 'c']),'two' : pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(d)
df

    one	two
a	1.0	1.0
b	2.0	2.0
c	3.0	3.0
d	NaN	4.0
  1. Panel(三维数组)
  • Pandas 输出设置
    通过设置set_option 设置Pandas 的输出格式。
import pandas as pd

pd.set_option("display.max_rows",1000)
pd.set_option("display.max_columns",20)
pd.set_option('precision',7)
pd.set_option('large_repr', 'truncate')

  • Pandas 数据读取与写入
    读取本地文件如CSV、TXT、xlsx等
a=pd.read_csv('closeprice.csv',encoding='gbk',dtype={'ticker': str})
a

Unnamed: 0  ticker	secShortName	tradeDate	closePrice
0	0	  000001	平安银行	    2017-06-20	  9.12
1	1	  000002	万科A	    2017-06-20	  21.03
2	2	  000004	国农科技	    2017-06-20	  27.03
3	3	  000005	世纪星源  	2017-06-20	  5.45
4	4	  000006	深振业A	    2017-06-20	  8.87
5	5	  000007	全新好	   2017-06-20	  15.87

保存文件

a.to_excel('closeprice.xls')
  • 数据集快速描述性统计分析

基本的统计分析

import pandas as pd

data = pd.read_csv('closeprice.csv',encoding='gbk')
data.describe().T

	        count	 mean	std	 min	25%	 50%	75%	 max
Unnamed: 0	6.0	  2.5000000	  1.8708287	0.00	1.2500	2.500	3.75	5.00
ticker	   6.0	4.1666667	2.3166067	1.00	2.5000	4.500	5.75	7.00
closePrice	6.0	14.5616667	8.2950550	5.45	8.9325	12.495	19.74	27.03
data.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 6 entries, 0 to 5
Data columns (total 5 columns):
Unnamed: 0      6 non-null int64
ticker          6 non-null int64
secShortName    6 non-null object
tradeDate       6 non-null object
closePrice      6 non-null float64
dtypes: float64(1), int64(2), object(2)
memory usage: 320.0+ bytes
  • 根据已有的列建立新列
    ticker.map 函数

  • DataFrame 按多列排序
    sort_values(by = ( ), ascending = (False, True) , inplace=True )方式调用

  • DataFrame 去重

data = pd.DataFrame({'k1': ['one'] * 3 + ['two'] * 4, 'k2': [3, 2, 1, 3, 3, 4, 4]})
data

k1	k2
0	one	3
1	one	2
2	one	1
3	two	3
4	two	3
5	two	4
6	two	4

# 在不加任何参数时,Pandas会将完全相同的行去重
data.drop_duplicates()

	k1	k2
0	one	3
1	one	2
2	one	1
3	two	3
5	two	4

# subset 为k1 时,只要k1 重复,就认为是重复的,
#可以通过keep 参数确定保留哪个,一般在使用keep 时先排序
data.drop_duplicates(subset=['k1'],keep='last')
k1	k2
2	one	1
6	two	4

# 查看重复的行
data[data.duplicated()]
	k1	k2
4	two	3
6	two	4
  • 删除已有的列
    drop()函数
    axis = ‘columns’ 或者axis = 1 都是按照列来处理的。

  • Pandas 替换数据
    批量替换数据中的指定数值,replace()

  • DataFrame 重命名
    重命名rename()

  • DataFrame 切片与筛选
    三种切片方法:loc 、 iloc、ix

  • 连续型变量分组
    bins 、 cut 操作

  • Pandas 分组技术
    groupby 函数

3.3 SciPy 的初步使用

SciPy 包含致力于解决在科学计算中的常见问题的各个工具箱,它的不同的子模块对应不用的应用,例如插值、积分、优化、图像处理和特殊函数等。
本章只选择与部分与金融量化分析相关的子库进行分析介绍。

  • 回归分析
    定义:是确定两种或两种以上变量之间相互依赖的定量关系的一种统计分析方法。
    按涉及变量的多少:一元回归分析和多元回归分析。
    按因变量的多少:简单回归分析和多重回归分析。
    按自变量和因变量之间的关系:线性回归分析和非线性回归分析。

在CAPM 模型中beta 系数的计算,本质上就是一元线性回归,代码如下分析:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import datetime as dt
%matplotlib inline

plt.rcParams['font.sans-serif']=['SimHei']  #用来正常显示中文标签
data = pd.read_csv('data.csv', index_col='Date')
data.index = [dt.datetime.strptime(x, '%Y-%m-%d') for x in data.index]plt.rcParams['axes.unicode_minus']=False  #用来正常显示负号

data.head()

            沪深300	  中国平安
2015-06-23	0.03214	    0.0496
2015-06-24	0.01965	    0.0052
2015-06-25	-0.03557	-0.0287
2015-06-26	-0.07868	-0.0605
2015-06-29	-0.03336	-0.0119


data.plot(figsize=(10, 6))
plt.ylabel('涨跌幅')

在这里插入图片描述可以发现,中国平安与沪深300的相关性还是比较大的。

接下来,使用StatsModels 模块。

import statsmodels.api as sm

x = data['沪深300'].values
X = sm.add_constant(x)  #添加常数项
y = data['中国平安'].values

# 对二者的收益率进行线性回归,斜率即beta 系数
model = sm.OLS(y, X)
results = model.fit()
results.params
array([ 0.00095063,  0.80946537])

plt.figure(figsize=(10, 6))
plt.plot(x, y, 'o', label='中国平安-沪深300')
plt.plot(x, results.fittedvalues, 'r--', label='ordinary least square')
plt.legend()
plt.xlabel('沪深300')
plt.ylabel('中国平安')
plt.grid(True)

在这里插入图片描述归因分析对于投资组合管理十分重要。我们认为一个虚拟投资组合是由两个随机因子和事先分配的权重构成的,这一过程类似于多元线性回归:

import numpy.random as npr

factor = npr.rand(1000, 3)
Factor = sm.add_constant(factor)  #添加常数项
fac1 = factor[:, 0]  #因子1
fac2 = factor[:, 1]  #因子2
fac3 = factor[:, 2]  #因子3
e = npr.random(1000)  #噪声
port = fac1 * 0.3 + fac2 * 0.7 + fac3 * 0.4 + e  #虚构投资组合及因子权重
model1 = sm.OLS(port, Factor)
results1 = model1.fit()
results1.params

array([ 0.53531625,  0.22141331,  0.70291227,  0.40377034])
  • 插值
    是在离散数据的基础上补插连续函数。使这条连续曲线通过全部给定的离散数据点。
    例子:
data1 = pd.read_csv('data1.csv')
data1.head()

      沪深300
0	3424.1940
1	3424.1669
2	3485.6581
3	3480.4345
4	3492.8845

import scipy.interpolate as spi

X = data1.index  #定义数据点
Y = data1.values  #定义数据点
x = np.arange(0, len(data1), 0.15)  #定义观测点

ipo1 = spi.splrep(X,Y,k=1) #k 样条拟合顺序(1<=k<=5)
ipo3 = spi.splrep(X,Y,k=3)

iy1 = spi.splev(x,ipo1)
iy3 = spi.splev(x,ipo3)

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10,12))
ax1.plot(X, Y, label='沪深300')
ax1.plot(x, iy1, 'r.', label='插值点')
ax1.set_ylim(Y.min() - 10, Y.max() + 10)
ax1.set_ylabel('指数')
ax1.set_title('线性插值')
ax1.legend()
ax2.plot(X, Y, label='沪深300')
ax2.plot(x, iy3, 'r.', label='插值点')
ax2.set_ylim(Y.min() - 10, Y.max() + 10)
ax2.set_ylabel('指数')
ax2.set_title('三次样条插值')
ax2.legend()

在这里插入图片描述

  • 正态检验

利用A股数据检验股票市场是否真的符合正态分布。

  • 凸优化
    指求最小值的目标函数为凸函数的一类优化问题。
    马科维茨利用方差-均值模型分析得出通过投资组合可以有效降低风险的结论。
    投资组合的优化关键在于对组合中各标的权重的优化,优化目标大致有:夏普最大化、收益最大化和风险最小化。

3.4 Matplotlib 的使用

Matplotlib 是Python 绘图的始祖。

虽然对于科学家而言,会吐的美观性可能并不重要,只要能清晰地表达出数据的含义就足够了,然而在金融领域或者互联网领域,绘图的美观性就显得尤为重要了,此时如果依旧使用Matplotlib ,代码的数量就会变得愈发冗长。Seaborn 就是为了解决这一问题而出现的。

3.5 Seaborn 的使用

Seaborn 的主要功能:

  • 通过内置主题改善Matplotlib 的外观
  • 有丰富的调色板工具,可更好的显示数据
  • 对变量分布进行可视化
  • 数据矩阵可视化,并使用聚类算法发现这些巨震中的结构
  • 对自变量和因变量之间的线性回归结果进行可视化
  • 绘制统计时间序列,并将其不确定性可视化
  • 构建高级、抽象的网格图,可轻松地将复杂的问题可视化
  1. 主题管理
    4个内置主题,分别为paper、 talk 、 poster 、 notebook,对应不同的场合。可使用set_context( ) 函数设置。
  2. 调色板
    大致分为循环 、渐变、混合三类。利用set_palette( ) 函数进行设置。
  3. 分布图
    distplot() 函数
  4. 回归图
    Implot()函数
  5. 矩阵图
    heatmap 是一种典型的矩阵图,通过颜色的深浅来表示数据的大小。
  6. 结构网格图
    pairplot()函数

3.6 Scikit-Learn 的初步使用

第三方模块,对一些常用的机器学习方法进行了封装,这样在需要进行机器学习时只要调用Scikit-Learn 里的模块就行。
机器学习的功能主要包括分类、回归、降维、聚类。主要的分类算法包括决策树、贝叶斯分类、支持向量机和随机森林等,主要的回归算法有SVR 、Lasso等。常见的降维方位有主成分分析、主题模型等。常用的聚类算法有K-Means、Gaussian等。
同时还包含了特征提取、数据预处理和模型评估这三大模块。

  • Scikit-Learn 学习准备
    安装
    模块列表:包含哪些模块
    应用于机器学习

  • 常见的机器学习模型

    1. 决策树
    2. 支持向量机
    3. 朴素贝叶斯分类器
    4. 神经网络
  • 模型的评价方法 --metric 模块

    1. 分类准确率
    2. 混淆矩阵
    3. ROC曲线
    4. 召回率
  • 深度学习
    大数据和云计算的到来,深度学习算法是对人工神经网络的进一步发展。
    监督学习和无监督学习

3.7 SQLAIchemy 与常用数据库的连接

开源库,提供了SQL工具包及对象关系映射(ORM)工具,基本操作:增删改查。

  • 连接数据库
    安装数据库驱动

在这里插入图片描述

  • 读取数据
    read_sql( )函数
  • 存储数据
    to_sql( ) 函数
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nsq_ai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值