金融时间序列描述性统计分析【python复现】

金融时间序列描述性统计分析

前言

金融时间序列是金融市场的一个重要组成部分。在研究金融市场的各种现象以及对进行建模时,金融时间序列的描述性统计分析都是一项基础的且必不可少的工作。

本章主要介绍描述性统计分析的相关知识,并且利用python进行量化。

对于金融时间序列,本章主要通过几何布朗运动模拟的时间序列以及沪深300指数的时间序列进行分析。

一、描述性统计分析

波动率是分析期权和衍生品的重要概念。这里介绍一下几个波动率的概念。

历史波动率
指的是一个金融时间序列对数收益率的标准差。

计算历史收益率时,首先计算序列的对数收益率:
在这里插入图片描述
在这里插入图片描述
针对资产的对数收益率求平均数:
在这里插入图片描述
然后对历史波动率进行求解:
在这里插入图片描述
瞬时波动率:

瞬时波动率是指一个扩散过程的波动率因子。在BS模型中,瞬时波动率σ可以在随机微分方程中得到:

BSM的随机微分方程:dSt=rStdt+σStdZt

偏度:

用于测度样本对于其均值的位置。

对于n个样本值的偏度,计算方法如下:
在这里插入图片描述
这里 xi 是第i个样本,, sd是样本标准差. g1 是总体偏度的有偏估计。

峰度:

峰度用于测度分布的峰度以及分为的尾部大小。

金融时间序列描述性统计分析【python复现】_第1张图片

二、描述性统计分析的python计算

1.几何布朗运动模拟下的时间序列数据

import math
import numpy as np
import pandas as pd
import scipy.stats as scs
import statsmodels.api as sm
import matplotlib as mpl
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 标准正态分布的概率密度函数
# 假设x服从正态分布,即x~N(mu,sigma**2)
# z=(x-mu)/sigma则服从标准正态分布,即z~N(0,1)
def dN(x,mu,sigma):
    "'    mu:期望值,sigma:标准差,pdf:概率密度函数'"
    z=(x-mu)/sigma
    pdf=np.exp(-0.5*z**2)/math.sqrt(2*math.pi*sigma**2)
    return pdf

#几何布朗运动模型 
# BSM的随机微分方程:dSt=r*St*dt+σ*St*dZt
def simulate_gbm():
    # model parameters
    S0 = 2.7 #标的资产价格
    T = 1 # 到期期限
    r = 0.05  # 无风险利率
    vol = 0.2  # 瞬时波动率

    # 参数模拟
    np.random.seed(250000)
    rng = pd.date_range('2016-09-07','2020-06-30', freq='B') #生成起始时间和终止时间的若干个交易日
    gbm_dates = rng
    M = len(gbm_dates)  # 时间步长
    I = 1  # 
    dt = 1 / 252.  # 
    df = math.exp(-r * dt)  # 

    # 股票价格路径生成
    rand = np.random.standard_normal((M, I))  # random numbers
    S = np.zeros_like(rand)  # stock matrix
    S[0] = S0  # initial values
    for t in range(1, M):  # stock price paths
        S[t] = S[t - 1] * np.exp((r - vol ** 2 / 2) * dt +
                                 vol * rand[t] * math.sqrt(dt))

    gbm = pd.DataFrame(S[:, 0], index=gbm_dates, columns=['index'])
    gbm['returns'] = np.log(gbm['index'] / gbm['index'].shift(1))

    # Realized Volatility (eg. as defined for variance swaps)
    gbm['rea_var'] = 252 * np.cumsum(gbm['returns'] ** 2) / np.arange(len(gbm))
    gbm['rea_vol'] = np.sqrt(gbm['rea_var'])
    gbm = gbm.dropna()
    return gbm
# 收益率统计分析及正态分布检验
def print_statistics(data):
    print("样本收益率统计值")
    print("---------------------------------------------")
    print("日对数收益率均值 %9.6f" % np.mean(data['returns']))
    print("年对数收益率均值 %9.6f" %
          (np.mean(data['returns']) * 252))
    print("年对数收益率的标准差 %9.6f" %
          (np.std(data['returns']) * math.sqrt(252)))
    print("---------------------------------------------")
    print("样本对数收益率的偏度 %9.6f" % scs.skew(data['returns']))
    print("偏度的正态分布检验p值   %9.6f" %
          scs.skewtest(data['returns'])[1])
    print("---------------------------------------------")
    print("样本对数收益率的峰度 %9.6f" % scs.kurtosis(data['returns']))
    print("峰度的正态分布检验p值   %9.6f" %
          scs.kurtosistest(data['returns'])[1])
    print("---------------------------------------------")
    print("正态分布检验p值        %9.6f" %
          scs.normaltest(data['returns'])[1])
    print("---------------------------------------------")
    print("已实现波动率        %9.6f" % data['rea_vol'].iloc[-1])
    print("已实现方差         %9.6f" % data['rea_var'].iloc[-1])
# 日报价和日对数收益率

def quotes_returns(data):
    ''' Plots quotes and returns. '''
    plt.figure(figsize=(9, 6))
    plt.subplot(211)
    data['index'].plot()
    plt.ylabel('日报价')
    plt.grid(True)
    plt.axis('tight')

    plt.subplot(212)
    data['returns'].plot()
    plt.ylabel('日对数收益率')
    plt.grid(True)
    plt.axis('tight')

# histogram of annualized daily log returns


def return_histogram(data):
    ''' Plots a histogram of the returns. '''
    plt.figure(figsize=(9, 5))
    x = np.linspace(min(data['returns']), max(data['returns']), 100)
    plt.hist(np.array(data['returns']), bins=50, density=True) #normed改成density
    y = dN(x, np.mean(data['returns']), np.std(data['returns'])) #求收益率的均值和方差
    plt.plot(x, y, linewidth=2)
    plt.xlabel('对数收益率')
    plt.ylabel('频率/概率')
    plt.grid(True)

# Q-Q plot of annualized daily log returns


def return_qqplot(data):
    ''' Generates a Q-Q plot of the returns.'''
    plt.figure(figsize=(9, 5))
    sm.qqplot(data['returns'], line='s')
    plt.grid(True)
    plt.xlabel('理论分位数')
    plt.ylabel('样本分位数')


# realized volatility
def realized_volatility(data):
    ''' Plots the realized volatility. '''
    plt.figure(figsize=(9, 5))
    data['rea_vol'].plot()
    plt.ylabel('已实现波动率')
    plt.grid(True)

# mean return, volatility and correlation (252 days moving = 1 year)


def rolling_statistics(data):
    ''' Calculates and plots rolling statistics (mean, std, correlation). '''
    plt.figure(figsize=(11, 8))

    plt.subplot(311)
    mr = data['returns'].rolling(252).mean() * 252
    mr.plot()
    plt.grid(True)
    plt.ylabel('年收益率')
    plt.axhline(mr.mean(), color='r', ls='dashed', lw=1.5)

    plt.subplot(312)
    vo = data['returns'].rolling(252).std() * math.sqrt(252)
    vo.plot()
    plt.grid(True)
    plt.ylabel('年波动率')
    plt.axhline(vo.mean(), color='r', ls='dashed', lw=1.5)
    vx = plt.axis()

    plt.subplot(313)
    co = mr.rolling(252).corr(vo)
    co.plot()
    plt.grid(True)
    plt.ylabel('年相关系数')
    cx = plt.axis()
    plt.axis([vx[0], vx[1], cx[2], cx[3]])
    plt.axhline(co.mean(), color='r', ls='dashed', lw=1.5)

首先通过几何布朗运动来模拟一段时间序列的数据,几何布朗运动的介绍在前文已经给出了,这里不再赘述。

几何布朗运动的序列数据如下所示:

gbm = simulate_gbm()

金融时间序列描述性统计分析【python复现】_第2张图片

print_statistics(gbm)
样本收益率统计值
---------------------------------------------
日对数收益率均值 -0.000129
年对数收益率均值 -0.032411
年对数收益率的标准差  0.202453
---------------------------------------------
样本对数收益率的偏度 -0.128567
偏度的正态分布检验p值    0.096832
---------------------------------------------
样本对数收益率的峰度  0.294140
峰度的正态分布检验p值    0.073261
---------------------------------------------
正态分布检验p值         0.050657
---------------------------------------------
已实现波动率         0.202463
已实现方差          0.040991
quotes_returns(gbm) #日报价和日对数收益率

金融时间序列描述性统计分析【python复现】_第3张图片

return_histogram(gbm)#日对数收益率直方图和具有相同收益,方差的正态分布的概率密度函数图

金融时间序列描述性统计分析【python复现】_第4张图片

return_qqplot(gbm) #几何布朗运动的日对数收益率的QQ图

金融时间序列描述性统计分析【python复现】_第5张图片

realized_volatility(gbm)#模拟路径的实际波动率

金融时间序列描述性统计分析【python复现】_第6张图片

rolling_statistics(gbm)

金融时间序列描述性统计分析【python复现】_第7张图片
通过上述的描述性统计分析数值和分布图、QQ图可知,几何布朗运动模拟下生成的时间序列数据是符合正态分布的。

2.沪深300时间序列数据的描述性统计分析

通过数据库导入沪深300的数据,并且进行处理

df['returns']=np.log(df['close']/df['close'].shift(1))
df['rea_var']=np.cumsum(df['returns']**2)/np.arange(len(df))*252
df['rea_vol']=np.sqrt(df['rea_var'])
df=df.dropna()
df

金融时间序列描述性统计分析【python复现】_第8张图片

print_statistics(df)
样本收益率统计值
---------------------------------------------
日对数收益率均值  0.000250
年对数收益率均值  0.063086
年对数收益率的标准差  0.183886
---------------------------------------------
样本对数收益率的偏度 -0.603087
偏度的正态分布检验p值    0.000000
---------------------------------------------
样本对数收益率的峰度  5.390226
峰度的正态分布检验p值    0.000000
---------------------------------------------
正态分布检验p值         0.000000
---------------------------------------------
已实现波动率         0.183929
已实现方差          0.033830
df['index']=df['close']
quotes_returns(df) #日报价和日对数收益率

金融时间序列描述性统计分析【python复现】_第9张图片

return_histogram(df)#

金融时间序列描述性统计分析【python复现】_第10张图片

return_qqplot(df) #QQ图

金融时间序列描述性统计分析【python复现】_第11张图片

realized_volatility(df)#实际波动率

金融时间序列描述性统计分析【python复现】_第12张图片

rolling_statistics(df)

金融时间序列描述性统计分析【python复现】_第13张图片
通过上述描述性统计分析的数值和图可知,沪深300指数的收益率序列是不服从正态分布的。这也是金融市场的一个普遍现象。

总结

本章对金融时间序列的描述性统计分析进行了介绍,并且基于几何布朗运动模拟下的数据和沪深300指数数据进行了量化分析。

你可能感兴趣的:(期权量化,python,统计学,几何学,概率论,线性代数)