前言
这个系列,从这一篇起,我就不一一编号了。想到哪儿写到哪儿,学到哪儿写到哪儿。
本系列文章是用Python对数据进行简单的分析,最终实现程序化交易的目的。比较琐碎。
要想代码写得好,一个重要的因素就是,记得住的函数比较多。
对上证指数进行简单分析
time | open | high | low | close | volume | amt |
12/19/1990 | 96.05 | 99.98 | 95.79 | 99.98 | 126000 | 494311 |
12/20/1990 | 104.3 | 104.39 | 99.98 | 104.39 | 19700 | 84992 |
12/21/1990 | 109.07 | 109.13 | 103.73 | 109.13 | 2800 | 16096 |
12/24/1990 | 113.57 | 114.55 | 109.13 | 114.55 | 3200 | 31063 |
12/25/1990 | 120.09 | 120.25 | 114.55 | 120.25 | 1500 | 6510 |
12/26/1990 | 125.27 | 125.27 | 120.25 | 125.27 | 10000 | 53730 |
12/27/1990 | 125.27 | 125.28 | 125.27 | 125.28 | 6600 | 104644 |
12/28/1990 | 126.39 | 126.45 | 125.28 | 126.45 | 10800 | 88031 |
读取数据
CSV文件,内容如上表所示。
import numpy as np
import pandas as pd
''' 读数据、画图 '''
shIdxDir = 'D:/data_index/'
shIdxFileName = '000001.SH.csv'
shIndexFilePath = shIdxDir + shIdxFileName
shIdxDataFrame = pd.read_csv(shIndexFilePath, thousands=',')
shIdxDataFrame.close = shIdxDataFrame.close.astype(float)
基本绘图
画出每日收盘价、MA60、60日标准差
shIdxCloseSeries = shIdxDataFrame.close
# print(shIdxCloseSeries)
import matplotlib.pyplot as plt
# plt.clf()
plt.figure(1)
plt.grid()
plt.plot(shIdxCloseSeries, color='blue', label='original')
wLen = 60
shIdxCloseMaSeries = shIdxCloseSeries.rolling(wLen).mean()
plt.plot(shIdxCloseMaSeries, color='red', label='ma')
shIdxDataFrame.time = pd.to_datetime(shIdxDataFrame.time)
shIdxTimeSeries = shIdxDataFrame.time
shIdxCloseStdSeries = shIdxCloseSeries.rolling(wLen).std()
plt.plot(shIdxCloseStdSeries, color='green', label='std')
plt.legend(['original','rolling_mean','rolling_std'])
还可以通过plt.title('xxx')写标题,plt.show()显示
收益的简单分析
我不是学金融的。术语有些不妥当。
主要包括:每日收益率、7日的平均每天收益率、7日年化收益率、收益的算术平均值。
需要注意的是,7日的平均每天收益,(第(k+7)天 - 第k天)/7。
尽管每一天都有一个收益率,但连续7天的收益率的算术平均值,似乎不代表7日的平均收益。
我在想,这就像,去的速度是30km/h,回的速度是40km/h,平均速度不是(30+40)/2,这只是速度的算术平均,不是平均速度。
举个例子。第一天100元,第2天跌到1元,第3天为2元,第4天-第8天分别为4,8,16,32,64元。用每日收益率的算术平均算,并不是平均的每日收益率。
希望有权威人士帮忙解决一下
。
今天去百度了一下年化收益率。
百度百科:年化收益率
然而就是用的算术平均值算的……
''' 计算收益 '''
# 每日收益率
shIdxDailyReturnSeries = shIdxCloseSeries / shIdxCloseSeries.shift(1) - 1
plt.figure(2)
plt.clf()
plt.grid()
plt.subplot(411)
plt.plot(shIdxDailyReturnSeries,color = 'blue')
plt.title('Daily Return Rate')
# 7日的收益率(1周的收益率)
shIdx7DaysReturn = shIdxCloseSeries / shIdxCloseSeries.shift(7) - 1
plt.subplot(412)
plt.plot(shIdx7DaysReturn,color = 'blue')
plt.title('Weekly Return Rate')
# 直接用mid-term feature(7日)算年化
yearlyTradingDays = 250
shIdx7DaysYearlyReturn = shIdx7DaysReturn / 7 * yearlyTradingDays
plt.subplot(413)
plt.plot(shIdx7DaysYearlyReturn,color = 'blue')
plt.title('7-Day Yearly Return Rate')
#plt.show()
# 用收益的算术平均算年化
wLen = 7
shIdxYearlyArithMeanReturn = shIdxDailyReturnSeries.rolling(wLen).mean() * yearlyTradingDays
plt.subplot(414)
plt.plot(shIdxYearlyArithMeanReturn,color = 'blue')
plt.title('7-Day Arithmetic Average Return Rate')
年化也有两种算法。暂时不清楚哪一种是权威的。
另外,这里有“子图”的画法。
两种年化算法做比较。
# 两种年化收益的算法做比较
delta = shIdx7DaysYearlyReturn - shIdxYearlyArithMeanReturn
plt.figure(3)
plt.grid()
plt.plot(delta)
plt.show()
真是个悲伤的故事。差这么多。
而且还有一个问题,用shift(7)去算,遇到休市,很有可能根本就不止7天 -_-! 而且交易日还设置的250天。总之,是有问题的。
而且还有一个问题,用shift(7)去算,遇到休市,很有可能根本就不止7天 -_-! 而且交易日还设置的250天。总之,是有问题的。
每日收益率的分布
调用hist绘制直方图。看随机变量的分布。
# 每日收益的分布
# data = np.random.normal(5.0, 3.0, 1000)
bins = np.arange(-0.15, 0.15, .005) #浮点数版本的range
shIdxDailyReturnArray = np.array(shIdxDailyReturnSeries.fillna(0))
plt.figure(4)
plt.grid()
plt.hist(shIdxDailyReturnArray,bins)
plt.title('Daily Return Rate Histogram')
plt.show()
有点像正态。
对每日收益率做归一化处理(减均值,除以标准差),再与标准正态分布做比较。
# 对每日收益率标准化
normalizedShIdxDailyReturnArray =\
(shIdxDailyReturnArray-shIdxDailyReturnArray.mean()) / shIdxDailyReturnArray.std()
# 标准正态分布的曲线
mu = 0
sigma = np.sqrt(1)
x = np.linspace(mu - 3*sigma, mu + 3*sigma,100)
y = 1/np.sqrt(2*np.pi)/sigma * np.exp(-(x-mu)**2 /2/sigma)
plt.figure(5)
plt.grid()
bins = np.arange(-3,3,0.1)
plt.hist(normalizedShIdxDailyReturnArray,bins,normed=1) # normed = 1 代表显示频率
plt.title('Normalized Daily Return Rate Histogram')
plt.plot(x,y,color='red')
plt.show()
所谓的“尖峰厚尾”现象。
百度百科:
厚尾
每日收益率的其他特性
均值、极差、最大、最小、分位数、中位数median、方差、众数mode、变异系数 stdByMean…
偏度skew、峰度kurt……
还有自相关函数、谱……
说明:当把每日收益率作为随机变量X时,这个X的mean、median、mode看起来都是0,分布也像个正态,偏度也不偏……
所以,基本上没有办法准确地预测明天的收益如何!纯属赌博了……
如果把每日收益率X(n)的前几个,和这一时刻的X(n)结合起来看,会不会有新的发现呢?
每日收益率的对数分布
并不是很清楚对数分布有什么用。若对随机变量取log,会怎样?
平稳性
稳定性
重要问题
这是一个重要的问题。基于以下几点发现。
1. 从收益率来看,基本像是一个对称的分布。
2. 如果第一天跌10%,第二天涨10%,赔钱;如果先涨再跌,还是赔钱。
那么,结合1&2,为什么指数可以涨??神奇!