首先我们打开数据之后先了解一下数据有哪些元素。在这个表中,可以看到,第一列是公司名称,第二列是交易日期,第四列是开盘价,之后分别是是最高价,最低价,收盘价,成交量。(数据获取方式看文章末尾)
在这个例子中,将会利用python和numpy库进行苹果公司的股票交易数据的分析。
先读入数据文件:
import sys
import numpy as np
#读入文件
c,v = np.loadtxt(R'F:\data.csv',delimiter=',',usecols=(6,7),unpack=True) #利用delimiter=','分割,读取第7(收盘价)、8(成交量)列数据,将收盘价和成交量分别赋值给c和v两个数组
然后求一些简单的均价:
#计算成交量加权平均价
vwap = np.average(c,weights=v)
print("成交量加权平均价 = ",vwap)
#成交量加权平均价 = 350.589549353
#算术平均价函数
print("算术平均价 = ",np.mean(c))
#算术平均价 = 351.037666667
#时间加权平均价
t = np.arange(len(c))
print("时间加权平均价 = ",np.average(c,weights=t))
#时间加权平均价 = 352.428321839
接着可以求数据的最大最小值和它们的中位数和方差:
#寻找最大值和最小值
h,l = np.loadtxt(R'F:\data.csv',delimiter=',',usecols=(4,5),unpack=True) #第5列数据为最高价,第6列为最低价
print("最高价 = ",np.max(h))
#最高价 = 364.9
print("最低价 = ",np.min(l))
#最低价 = 333.53
print("最高价和最低价的平均值 = ",np.max(h)/2 + np.min(l)/2)
#最高价和最低价的平均值 = 349.215
print("最高价之间的极差",np.ptp(h)) #最高价当中最高值-最低值
#最高价之间的极差 24.86
print("最低价之间的极差",np.ptp(l)) #最低价当中最高值-最低值
#最低价之间的极差 26.97
#统计分析
c = np.loadtxt(R'F:\data.csv',delimiter=',',usecols=(6),unpack=True) #这次读入了收盘价
print("收盘价中位数 = ",np.median(c)) #计算中位数
#收盘价中位数 = 352.055
print("方差 = ",np.var(c)) #计算方差
#方差 = 50.1265178889
然后我们可以分析股票的收益率:
#股票收益率
#普通收益率
returns = np.diff(c)/c[:-1] #(整体的数据)/(这些数据减去最后一个值)
print("收益率 = ",np.std(returns))
#收益率 = 0.0129221344368
#对数收益率
#当天收盘价的对数前前一天收盘价的对数
logreturns = np.diff(np.log(c))
posretindices = np.where(returns>0) #0和负数没有对数,要去除
print("Indices with positive returns = ",posretindices)
#Indices with positive returns = (array([ 0, 1, 4, 5, 6, 7, 9, 10, 11, 12, 16, 17,18, 19, 21, 22, 23,25, 28], dtype=int64),)
再来求波动率,看看波动的情况怎么样:
# 年化波动
annual_volatility = np.std(logreturns)/np.mean(logreturns)
annual_volatility = annual_volatility / np.sqrt(1./252.) #一年的交易日为252天(用浮点数运算)
print("年化波动 = ",annual_volatility)
#年化波动 = 129.274789911
# 月化波动
print("月化波动", annual_volatility * np.sqrt(1./12.))
#月化波动 37.3184173773
也可以根据日期来分析:
#日期分析
from datetime import datetime
# 将日期映射为星期
# Monday 0
# Tuesday 1
# Wednesday 2
# Thursday 3
# Friday 4
# Saturday 5
# Sunday 6
#计算日期转为星期的函数
def datestr2num(s):
return datetime.strptime(s.decode('ascii'), "%d-%m-%Y").date().weekday() #返回的值字节字符串bytes,所以需要把它变回string,则对字符串解码用函数decode('asii'),变成string格式。
# 读取星期和收盘价,converters 将日期映射成星期
dates, close = np.loadtxt(R'F:\data.csv', delimiter=',', usecols=(1,6), converters={1: datestr2num}, unpack=True)
print("Dates =", dates)
#Dates = [ 4. 0. 1. 2. 3. 4. 0. 1. 2. 3. 4. 0. 1. 2. 3. 4. 1. 2. 3. 4. 0. 1. 2. 3. 4. 0. 1. 2. 3. 4.]
#创建一个包含5个元素的数组,用于保存周一到周五的股票数据
averages = np.zeros(5)
for i in range(5):
indices = np.where(dates == i)
prices = np.take(close,indices) #利用take取出相应的元素
avg = np.mean(prices) #日期内的平均价格
print("日期:",i,"价格",prices,"平均价格",avg)
averages[i] = avg
#日期: 0 价格 [[ 339.32 351.88 359.18 353.21 355.36]] 平均价格 351.79
#日期: 1 价格 [[ 345.03 355.2 359.9 338.61 349.31 355.76]] 平均价格 350.635
#日期: 2 价格 [[ 344.32 358.16 363.13 342.62 352.12 352.47]] 平均价格 352.136666667
#日期: 3 价格 [[ 343.44 354.54 358.3 342.88 359.56 346.67]] 平均价格 350.898333333
#日期: 4 价格 [[ 336.1 346.5 356.85 350.56 348.16 360. 351.99]] 平均价格 350.022857143
print("最高价",np.max(averages))
print("最高价的星期:",np.argmax(averages))
#最高价 352.136666667
#最高价的星期: 2
print("最低价",np.min(averages))
print("最低价的星期:",np.argmin(averages))
#最低价 350.022857143
#最低价的星期: 4
还可以根据一个周的数据,求出一周的开盘价、最高值、最低值和收盘价
#周汇总
def datestr2num(s):
return datetime.strptime(s.decode('ascii'), "%d-%m-%Y").date().weekday() #返回的值字节字符串bytes,所以需要把它变回string,则对字符串解码用函数decode('asii'),变成string格式。
dates,open,high,low,close = np.loadtxt(R'F:\data.csv', delimiter=',', usecols=(1,3,4,5,6), converters={1: datestr2num}, unpack=True)
close = close[:16] #为了方便计算,仅取前三周数据
dates = dates[:16]
#寻找第一个星期一
first_day = np.ravel(np.where(dates == 0))[0] #dates == 0时表示周一 where返回的是个多维数组,需要用ravel展平
print("第一个周一的数据所在的位置是",first_day) #输出的结果表示第5个数字表示周一(去除第一个不是周一开始的数字)
#第一个周一的数据所在的位置是 1
#寻找最后一个星期五
last_day = np.ravel(np.where(dates == 4))[-1] #dates == 4时表示周五
print("第一个周一的数据所在的位置是",last_day) #输出的结果表示第16个数字表示周五(去除第一个不是周一开始的数字)
#第一个周一的数据所在的位置是 15
#创建一个数组,存储3个周一到周五的索引值
week_indices = np.arange(first_day,last_day + 1)
print("这个索引值是",week_indices)
#这个索引值是 [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15][array([1, 2, 3, 4, 5], dtype=int64), array([ 6, 7, 8, 9, 10], dtype=int64), array([11, 12, 13, 14, 15], dtype=int64)]
week_indices = np.split(week_indices,3) #将这个索引数组切分成3个数组
print(week_indices)
def summarize(a, o, h, l, c):
monday_open = o[a[0]]
week_high = np.max(np.take(h, a))
week_low = np.min(np.take(l, a))
friday_close = c[a[-1]]
return ("APPL", monday_open, week_high, week_low, friday_close)
# apply_along_axis内涵很丰富
weeksummary = np.apply_along_axis(summarize, 1, week_indices, open, high, low, close) #输出3个周的开盘价、最高价、最低价、收盘价
print("weeksummary:",weeksummary)
#weeksummary: [['APPL' '335.8' '346.7' '334.3' '346.5']
# ['APPL' '347.8' '360.0' '347.6' '356.8']
# ['APPL' '356.7' '364.9' '349.5' '350.5']]
再来看看每天滑动均值:
# 每一天的简单滑动均值
# 就是当天与前 (N - 1) 天的均值
# 其中 N 是窗口大小
import numpy as np
import sys
from matplotlib.pyplot import plot
from matplotlib.pyplot import show
N = 20
# 使用 ones 函数创建大小为 N 的数组
# 并除以 N 来创建权重
weights = np.ones(N) / N
print("Weights", weights)
#Weights [ 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05]
# 假设 N 为 5:
# Weights [ 0.2 0.2 0.2 0.2 0.2]
# 读入收盘价
c = np.loadtxt(R'F:\data.csv', delimiter=',', usecols=(6,), unpack=True)
# 调用 convolve 函数来计算滑动平均
sma = np.convolve(weights, c)[N-1:-N+1]
# 绘制函数图像
# 要注意横轴从 (N - 1) 开始
t = np.arange(N - 1, len(c))
plot(t, c[N-1:], lw=1.0)
plot(t, sma, lw=2.0)
show()
最后得到股票波动图
数据获取方式:关注微信公众号 大鱼Tech,回复“苹果股票数据”即可获取。