01 前言
2020年高考的第一天到来了,不晓得你的心情如何,我想我们始终忘不了的是对追梦过程中的努力,希望长大以后的我们也不要忘记那种拼搏的精神,今天也会是元气满满的一天,接下来,开始我们的案例学习。
第二个案例分析是基于阿里巴巴的股票历史数据分析,观察日线和周线的走势,并对购买策略进行评估。今明的内容都是对阿里巴巴的股票行情进行分析,所使用的是同一份数据。今天的内容是了解股票走势的背景知识并进行简单分析对股票进行描述,明天进行的是规范性分析对于股票买卖策略的评估。
知识卡片
分析模型的类别
描述性 descriptive:“ 发生了什么?” 结合统计对发生的事件进行描述
预测性 predictive:“ 什么将会发生?” 预测某件事发生的可能性,在假设的基础上,可以通过线性回归,时间序列和判别分析得到因变量和自变量的关系得到
规范性 prescriptive:“应该做什么?” 对事件的过程进行模拟,根据建立的指标显示出的结果对所作出的决策进行评估,规范并优化过程。
公众号回复: DT16 获取数据 BABA_stock.csv
02 股票走势图
阿里股票历史数据下载:https://www.nasdaq.com/symbol/baba/historical
如果小伙伴有自己感兴趣的公司,也可以在课后试着在上面的网站中查找感兴趣公司的股票历史行情进行分析,需要注意的是由于Nasdaq网站是外网可能打不开。
我们可以打开雪球网对阿里股票走势进行观察:https://xueqiu.com/S/BABA
点击全屏显示来观看,k线图对于股票价格的描述是按照每分钟来报,我们可以分别点击五日和日K区间,会有不同颜色的线来代表这一时刻下的过去五天内或者一天内的平均价格。
红绿色的小柱子,类似于箱线图,在股票中叫k线图,收盘价高于开盘价时,也就是股票涨了,长方柱用红色或空心绘出,称之为阳线;其上影线的最高点为最高价,下影线的最低点为最低价。
收盘价低于开盘价时,股票跌了,则开盘价在上收盘价在下,二者之间的长方柱用绿色或实心绘出,称之为阴线,其上影线的最高点为最高价,下影线的最低点为最低价。
小柱子k线反映的统计时段内的股票变化,根据左上角均线的颜色和说明,颜色线反映的是当前时间点往前推5日,10日,20日,30日和60日内的股票平均值。当鼠标放在某一个位置时,代表起始的时间点,如 浅蓝色 MA10:222.19 浅蓝色的线表示过去十天线,222.19就是过去十天的股价均值。
观察不同颜色的线,绿色的六十日线,代表的周期长,走势更为平缓,周期更陡一些。
买卖股票的基本策略,以观察蓝紫色的线为例,在上图中的低位买入,高位卖出,获取差价。股票的行情数据分析是根据股票走势的历史对股票交易进行量化分析,以对于买卖股票的策略进行指导。
03 数据源观察
可以使用Excel打开数据源文件,对数据进行观察。
股票数据,包含date 交易日期,close 收盘价,volume 成交额, open 开盘价,high 最高价, low 最低价,共6列。每一行代表一天的相关交易数据,也就是日线,含有2016年到2019年的三年数据,有755条记录。接下来,建立一个Python文件对数据进行分析。
import numpy as np
# dateutil.parser 是日期相关库的一个解析器
# 用来将字符串转换为日期
from dateutil.parser import parse
# 使用numpy的loadtxt读取csv文件,读出来的数据是数组
# numpy.loadtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, encoding='bytes')
# fname 指定打开的文件名# skiprows不需要的行需要skip掉,第一行去掉
# pandas dataframe和numpy list,array的区别是,dataframe类似于excel表格,能识别第一行的表头,而numpy读取数据后存储的对象是列表和数组
# 默认没有分隔符,所以需要指定delimiter
# 不加载全部的情况下需要指定加载哪些列usecols
# 希望把每一列加载到单独的数组中需要设置unpack=True,并指定对应的变量名,列举下有unpack和没有的区别
stock_info = np.loadtxt('./BABA_stock.csv', delimiter=',', usecols=(1, 2, 3, 4, 5), skiprows=1)stock_info = np.loadtxt('./BABA_stock.csv', delimiter=',', usecols=(1, 2, 3, 4, 5), skiprows=1, unpack=True
stock_info.shape
stock_info = stock_info[:,::-1] # 遍历每行,步长为 -1 意为逆序排列 日期是后往前记录 但是分析时要倒过来
stock_info
array([[1.830700e+02, 1.889100e+02, 1.849800e+02, ..., 7.946000e+01,7.901000e+01, 7.897000e+01],[1.461019e+07, 1.256109e+07, 8.848863e+06, ..., 1.472746e+07,7.761672e+06, 1.169603e+07],[1.880600e+02, 1.877100e+02, 1.851500e+02, ..., 7.920000e+01,7.852000e+01, 7.945000e+01],[1.881700e+02, 1.897900e+02, 1.860600e+02, ..., 8.048000e+01,7.912000e+01, 7.975000e+01],[1.825600e+02, 1.871400e+02, 1.837500e+02, ..., 7.847000e+01,7.771000e+01, 7.846000e+01]])
# 取出开盘价和收盘价
close_info = stock_info[0]
open_info = stock_info[2]
# 上涨的天数
rise_count = len(close_info[open_info - close_info > 0])
print('rise count:' + str(rise_count))
# 第二种 写法 size属性
# rise_count = close_info[open_info - close_info > 0].size
395
# 下跌
fail_count = len(close_info[open_info - close_info <= 0])
print('fail count:' + str(fail_count))
fail count:360
# 上涨天数占比
rise_count / close_info.size
0.5231788079470199
04 日线转周线
什么是周线?
就是一周的K线,以周一开盘价为周线的开盘价,以周五收盘价为周线收盘价。以一周内最高价为周线最高价,以一周内最低价为最低价。
# 日线转换为周线
# 一周有五天
# loadtxt方法有一个converters参数,可以利用自定义的函数把string做转换
def convert_date(d):return parse(d).weekday() # 把日期转换成工作日stock_info = np.loadtxt('./BABA_stock.csv', delimiter=',', usecols=(0, 1, 3, 4, 5), skiprows=1, dtype='S', converters={0: convert_date})
print(stock_info) # b表示字节字符串
[[b'0' b'183.0700' b'188.0600' b'188.1700' b'182.5600'][b'4' b'188.9100' b'187.7100' b'189.7900' b'187.1400'][b'3' b'184.9800' b'185.1500' b'186.0600' b'183.7500']...[b'1' b'79.4600' b'79.2000' b'80.4800' b'78.4700'][b'0' b'79.0100' b'78.5200' b'79.1200' b'77.7100'][b'4' b'78.9700' b'79.4500' b'79.7500' b'78.4600']]
# date列需要从16年开始19年结束,因而date需要倒序排列,并将字符型转换为浮点型方便汇总计算
stock_info = stock_info[::-1, :].astype('f8')
[array([[ 4. , 78.97, 79.45, 79.75, 78.46]]), array([[ 0. , 79.01 , 78.52 , 79.12 , 77.71 ],[ 1. , 79.46 , 79.2 , 80.48 , 78.47 ],[ 2. , 81.21 , 79. , 81.735, 78.99 ],[ 3. , 80.78 , 81.08 , 81.78 , 80.2 ],[ 4. , 79.89 , 80.12 , 85.89 , 79.155]]), array([[ 0. , 78.84 , 79.8 , 79.84 , 78.68 ],[ 1. , 78.61 , 78.85 , 79.56 , 77.8001],[ 2. , 77.65 , 78.3 , 78.62 , 76.57 ],[ 3. , 76.4 , 77.65 , 77.9 , 76.09 ],[ 4. , 76.94 , 76.81 , 77.28 , 75.66 ]]), array([[ 0. , 76.61 , 76.89 , 77. , 75.94 ],[ 1. , 75.91 , 75.96 , 76.27 , 75.425],[ 2. , 75.82 , 75.64 , 75.91 , 75.01 ],[ 3. , 78.83 , 79.52 , 79.94 , 78.1 ],[ 4. , 79.2 , 78.35 , 79.72 , 78.25 ]]), array([[ 0. , 79.41 , 78.94 , 79.98 , 78.89 ],[ 1. , 79.72 , 79.79 , 79.98 , 79.15 ],[ 2. , 79.8 , 79.43 , 80.485, 79.41 ],[ 3. , 79.16 , 80.01 , 80.45 , 78.32 ],[ 4. , 77.16 , 78.825, 79.16 , 76.97 ]]), array([[ 0. , 79.29 , 77.86 , 79.93 , 77.59 ],
# 需要按照每周分组
# 先找到星期一的数据的索引
week_split = np.where(stock_info[:, 0] == 0)[0]
print(week_split)
<class 'numpy.ndarray'>
# 按照周一去分组,split返回给定索引的分组
# 可以指定任意间隔的索引,所以split以一个pothon list的形式返回
week_infos_temp = np.split(stock_info, week_split)
print(type(week_infos_temp))
<class 'list'>
# 简单起见,我们这里只使用一周数据有五天的,weeksplit中不足五天的数组过滤
week_info = [ x for x in week_infos_temp if len(x) == 5 ]
# 每个星期的数据都是一样的了,我们在把他转换成numpy ndarray
w = np.array(week_info)
print(w.shape) # ndarry的形状 (114, 5, 5)
print(w[:3]) # 输出前三行 五列分别是 weekday close open high low
(114, 5, 5)
[[[ 0. 79.01 78.52 79.12 77.71 ][ 1. 79.46 79.2 80.48 78.47 ][ 2. 81.21 79. 81.735 78.99 ][ 3. 80.78 81.08 81.78 80.2 ][ 4. 79.89 80.12 85.89 79.155 ]][[ 0. 78.84 79.8 79.84 78.68 ][ 1. 78.61 78.85 79.56 77.8001][ 2. 77.65 78.3 78.62 76.57 ][ 3. 76.4 77.65 77.9 76.09 ][ 4. 76.94 76.81 77.28 75.66 ]][[ 0. 76.61 76.89 77. 75.94 ][ 1. 75.91 75.96 76.27 75.425 ][ 2. 75.82 75.64 75.91 75.01 ][ 3. 78.83 79.52 79.94 78.1 ][ 4. 79.2 78.35 79.72 78.25 ]]]
week_close = w[:, -1, 1] #每周周五数据的第二列
print(week_close[:3])week_open = w[:, 0, 2] #每周周一数据的第三列
print(week_open[:3])week_high = w[:, :, 3].max(axis=1) # 每周所有第四列的数据
print(week_high[:3])week_low = w[:, :, 4].min(axis=1) # 每周所有第五列的数据
print(week_low[:3])
[79.89 76.94 79.2 ]
[78.52 79.8 76.89]
[85.89 79.84 79.94]
[77.71 75.66 75.01]
w_info = np.array([week_open, week_close, week_high, week_close])
# print(w_info[:3])# 一周的数据放到一行,可以直接用转置矩阵
print('result:', w_info.T)# 结果保存到文件
np.savetxt('./week_info_baba.csv', w_info.T, header='open, close, high, low', delimiter=',', fmt='%.2f')
result: [[ 78.52 79.89 85.89 79.89 ][ 79.8 76.94 79.84 76.94 ][ 76.89 79.2 79.94 79.2 ][ 78.94 77.16 80.485 77.16 ][ 77.86 78.79 80.2 78.79 ]
05 写在最后
今天的案例是对股票行情数据的描述分析,多为一些概念性的理解,学习股票走势中k线的含义以及组成k线的数据,此外还需掌握Numpy的一些用法。如果忘记Numpy中Ndarry如何操作,可以回看第二期Numpy用法。
学习后,不要忘记在文章下方留言打卡~
需要加群的同学,添加小助手微信 A2XF669 后,回复数字 4 拉你进入学习群,晚上八点半到九点半一起讨论,交流学习!
NumPy入门指南(一) | Day1
NumPy入门指南(二) | Day2
Day01| 第四期-北京积分落户数据分析