Python金融数据分析教程 解放你的python编程能力 第6关金融数据的统计分析 Python金融数据分析教程 1
课程内容 通过本课程学习,你将学习到 案例1:分析HS300股票的市值和PE的统计规律 案例2:个股日收益率的统计规律研究 案例3:金融数据分析中的随机数 闯关作业 Python金融数据分析教程
案例1:HS300股票的市值和PE的统计规律 数据准备(从quantos网站获取数据) # 获得HS300指数20180322的成份股 # 导入DataApi from jaqs.data import DataApi # 初始化api api = DataApi( 'tcp://data.quantos.org:8910' ) # 获取用户名和密码 import os user = os.environ.get("QUANTOS_USER") token = os.environ.get("QUANTOS_TOKEN") # 登录 info, msg = api.login(user, token) print(info, msg) # 获得HS300指数20180322的成份股 df, msg = api.query( view = 'lb.indexCons', filter="index_code=000300.SH&start_date=20180322&end_date=20180322" ) symbols = ",".join(df['symbol']) # 获得HS300成份股的日估值数据 df_data, msg = api.query( view = 'lb.secDailyIndicator', filter="start_date=20180322&end_date=20180322&symbol="+symbols, fields='total_mv,float_mv,pe_ttm,pb,trade_date' df_data.set_index('symbol', inplace=True) print(df_data, msg) Python金融数据分析教程
DataFrame基本数据操作 pandas.DataFrame pandas.Series df_data.head(10) df_data['pe_ttm'].head(10) pandas.DataFrame pandas.Series Python金融数据分析教程
统计分析(1) DataFrame.describe() # 用pandas的方法 df_data.describe() #df_data['total_mv'].describe() 指标 解释 Mean 平均值 Max 最大值 Min 最小值 Std 标准差 25% 25%分位点 50% 50%分位点Median 75% 75%分位点 skew 偏度 kurt 峰度 Sum 求和 Python金融数据分析教程
统计分析(2) # 用numpy更加通用的方法 import pandas as pd import numpy as np def calc_stat(label, data): # 最大、最小、平均值 print( "max", np.max(data) ) print( "min", np.min(data) ) print( "mean", np.mean(data) ) # 求和、标准差、中位数、分位数 print( "sum", np.sum(data) ) print( "std", np.std(data) ) print( "median", np.median(data) ) print( "quantile of 0.1", pd.Series(data).quantile(0.1) ) # Skew 偏度、Kurt 峰度 print( "skew", pd.Series(data).skew() ) print( "kurt", pd.Series(data).kurt() ) stat of total_mv(单位:万) --------------- max 230594848.3366 min 536334.9308 mean 11957514.437541667 sum 3587254331.2625003 std 24978620.577902168 median 5060955.281649999 quantile of 0.1 2373871.74536 skew 5.610982165125842 kurt 36.85379452009035 stat of pe_ttm max 430.9555 min 0.0 mean 35.61477733333333 sum 10684.4332 std 41.640231029982125 median 24.64495 quantile of 0.1 8.666369999999999 skew 4.907694046059864 kurt 34.897700821446975 # show total_mv calc_stat(‘total_mv(单位:万)', df_data['total_mv']) # show pe_ttm calc_stat('pe_ttm', df_data['pe_ttm']) calc_stat('pb', df_data['pb']) Python金融数据分析教程
统计分析(3) 直方图:Series.hist() # 直方图 fig = plt.figure(figsize=(16,6)) ax = fig.add_subplot(1,3,1) ax.set_title('histogram of total_mv') df_data['total_mv'].hist(bins=200, ax=ax) ax = fig.add_subplot(1,3,2) ax.set_title('histogram of pe_ttm') df_data['pe_ttm'].hist(bins=200, ax=ax) ax = fig.add_subplot(1,3,3) ax.set_title('histogram of pb') df_data['pb'].hist(bins=200, ax=ax) 直方图:Series.hist() Python金融数据分析教程
案例2 个股日收益率的统计规律研究 数据准备(从quantos网站获取数据招商银行600036.SH) # 查询日收盘价信息 df_zsyh, msg = api.daily( symbol='600036.SH', start_date='2010-01-01', end_date='2018-03-22', fields='open,high,low,close', freq='1d', adjust_mode='post' ) df_zsyh.set_index('trade_date', inplace=True) # 计算每日的对数收益率 change = df_zsyh['close'] / df_zsyh['close'].shift(1) df_zsyh['ret'] = np.log(change) # 删除第一个NA值 df_zsyh.dropna(inplace=True) print(df_zsyh) # 导入DataApi from jaqs.data import DataApi # 初始化api api = DataApi( 'tcp://data.quantos.org:8910' ) # 获取用户名和密码 import os user = os.environ.get("QUANTOS_USER") token = os.environ.get("QUANTOS_TOKEN") # 登录 info, msg = api.login(user, token) print(info, msg) DataFrame.set_index() DataFrame.dropna() Series.shift(1) Series +-*/ Series np.log(Series) Python金融数据分析教程
看看统计规律 stat of return on 600036.SH --------------- max 0.09554235997718125 min -0.10440311970149871 mean 0.0004691472226546667 sum 0.9364178564187147 std 0.01788339086714847 median 0.0 quantile of 0.1 -0.018850226358492064 skew 0.3917353762903529 kurt 4.584891892210756 # 计算一下日收益率的统计规律 calc_stat('return on 600036.SH', df_zsyh['ret']) # normalize return mean = np.mean(df_zsyh['ret']) std = np.std(df_zsyh['ret‘]) df_zsyh['ret_norm'] = ( df_zsyh['ret'] - mean ) / std # 画个直方图看看 df_zsyh['ret_norm'].hist(bins=100) Python金融数据分析教程
正态分布的检验 p值太小,不符合正态分布的特点 scipy.stats.probplot() 画出qq图 ## QQ-plot 图 import scipy.stats as stats import matplotlib.pyplot as plt plt.figure(figsize=(8,8)) stats.probplot( df_zsyh['ret_norm'], dist="norm", plot=plt ) # 正态分布检验 print(stats.normaltest(df_zsyh['ret_norm'])) print(stats.shapiro(df_zsyh['ret_norm'])) NormaltestResult(statistic=258.8425994377053, pvalue=6.20931498699053e-57) (0.9375563263893127, 3.5073531514411287e-28) p值太小,不符合正态分布的特点 scipy.stats.probplot() 画出qq图 Python金融数据分析教程
计算累计收益率 Series.apply(func) 对每个元素调用func 返回另一个Series Series.cumsum() import datetime def int2datetime(date): dt = datetime.datetime.strptime(str(date), '%Y%m%d') return dt # 累计收益率 cumsum, cumprod cum_ret = df_zsyh['ret'].cumsum().apply(np.exp) x_axis = pd.Series(cum_ret.index).apply(int2datetime) plt.figure(figsize=(12,8)) plt.plot(x_axis, cum_ret) Series.apply(func) 对每个元素调用func 返回另一个Series Series.cumsum() y1=x1 y2=x1+x2 y3=x1+x2+x3 y4=x1+x2+x3+x4 Python金融数据分析教程
案例3 金融数据分析中的随机数 np.random.random() np.random.normal() import numpy as np import math # 一维随机数组,【0,1】间的均匀分布 sim_data = np.random.random(1000000) pd.Series(sim_data).hist(bins = 100) # 一维随机数组,【0,1】间的正态分布 sim_data = np.random.normal(0,1,1000000) print(stats.normaltest(sim_data)) # 二维随机数组,【0,1】间的均匀分布 sim_data = np.random.rand(5,5) print(sim_data) print(stats.kstest(sim_data, 'uniform')) # 产生某一段区间内的随机数,均匀分布 sim_data = np.random.randint(10,20, 1000000) calc_stat('uniform sample data', sim_data) np.random.random() np.random.normal() np.random.randint() scipy.stats.normaltest() scipy.stats.kstest() Python金融数据分析教程
利用蒙特卡罗模拟计算 扇形面积 = 蓝点 / (蓝点 + 红点) 扔的点越多,结果误差越小 # 画一个扇形和一个正方形 r = 1.0 a, b = (0, 0) # 方法:参数方程 theta = np.arange(0, 0.5*np.pi, 0.01) x = a + r * np.cos(theta) y = b + r * np.sin(theta) fig = plt.figure() axes = fig.add_subplot(111) axes.plot(x, y, color='blue') axes.hlines(0, 0, 1, color='blue') axes.hlines(1, 0, 1, color='red') axes.vlines(0, 0, 1, color='blue') axes.vlines(1, 0, 1, color='red') axes.axis('equal') # 随机模拟,点落到扇形内部有效 size = 500 x = np.random.rand(size) y = np.random.rand(size) count = 0 for i in range(size): temp = math.pow(x[i], 2) + math.pow(y[i],2) if temp <= 1: axes.plot(x[i], y[i], 'bo') count = count + 1 else: axes.plot(x[i], y[i], 'ro') my_pi = count/size * 4 print(my_pi) 扇形面积 = 蓝点 / (蓝点 + 红点) 扔的点越多,结果误差越小 Python金融数据分析教程
闯关作业 获取沪深300(000300.SH)从2017年以来的每日收盘价数据,计算其日收益率,然后看看其统计规律,画出直方图。 Python金融数据分析教程
欢迎访问https://www.quantos.org Python金融数据分析教程