C13-1 python对股票(科大讯飞)数据可视化

在大数据时代对数据按自己理解的进行可视化是非常关键的一部。我们以科大讯飞这一股票从14-11至17-11的数据进行可视化。我们还是以最简单的均线系统规律来确立简单的买卖点。版本python3。经历的步骤有:

1、提取数据;
2、解析数据,得到我们想要的数据;
3、对数据进行一定处理,便于可视化;
4、可视化;以下是代码:

  # !/usr/bin/env python
  # -*- encoding: utf-8 -*-

  import sys
  import importlib

  importlib.reload(sys)

  import pandas as pd
  import matplotlib as mpl
  import matplotlib.pyplot as plt
  import numpy as np


  def rowIndex(row):
      """添加需要的标记和标记位置"""
      global plt

      if row.signal > 0:
          #标图示annotate
          plt.annotate(u'b', xy=(row.date_o, row.signal),     #xy表示被标注的位置
                       arrowprops=dict(facecolor='red', shrink=0.05))

      if row.signal < 0:
          plt.annotate(u's', xy=(row.date_o, row.signal))


  if __name__ == '__main__':

      #用lambda表达式将日期转换为字符格式
      daterparse1 = lambda dates: pd.datetime.strptime(dates, "%Y-%m-%d")

      #以特定格式和方式读取csv文件,pandas读取文件成为DataFrame对象或者Series对象
      s_list = pd.read_csv('kd.csv', skiprows=0, encoding='utf-8',
                           index_col='date', parse_dates=True,
                           date_parser=daterparse1)

      s_list['date_o'] = s_list.index   #将DataFrame对象(本身就是字典)的索引存为            原日期的字典
      s_list['ma_sub'] = s_list['ma5'] - s_list['ma20']
      s_list['diff'] = np.sign(s_list['ma_sub'])     #返回数组中的正负号,分别用1和-1表示
      #shift为对齐操作
      s_list['signal'] = np.sign(s_list['diff'] - s_list['diff'].shift(1))

      s_list['signal'].plot(ylim=(-2, 2))
      (s_list['close']/40).plot(ylim=(-2, 2))

      s_list.apply(rowIndex, axis=1)      #对DataFrame对象的行(axis=1)使用apply方法#返回行索引对应的Series对象

      plt.legend(loc='upper right')       #设置图例显示的位置
      # plt.legend(loc=4)       #upper right/left=1/2;lower left/right=3/4
      plt.grid(b=True)
      plt.title(u'Ma5--Ma20 to When Buy Or Sell', fontsize=18)

      plt.show()
      # plt.savefig('002230_mod.png', bbox_inches='tight')      

代码解析:
1、需要用到的包,sys,matplotlib,pandas,numpy;

2、提取数据,我们用到的是csv格式数据,相应代码的功能在代码中已注释,首先以自定义方式读取数据,我们需要用到日期,收盘价,5日平均及20日平均价格;其中index_col关键字为指定以哪列数据为索引构建DataFrame数据;我们首先看看数据是什么样的:


数据示例.png

对其提取之前先要对日期格式做一个调整;lambda可实现这一功能。parse_dates是对时间序列进行解析(为真);data_parser为解析日期的函数——有一个默认函数,但使用我们自己定义的函数;

3、对数据进行一系列处理,提取日期数据;求出均线差值:得出变化范围的标志;得出标记信号;限制绘图数据范围,避免溢出看不出趋势。

4、定义标记函数:用annotate函数实现按预期指定标记——标记符号,位置,箭头颜色和大小;按照行的信号大小来标记;大于0,标为买,小余0,标为卖;

5、可视化,利用定义的信号及收盘价、日期来绘制图表。以下是输出结果:

002230_mod.png

投资时点是一个极其重要的参考指标,为使买卖信号更清晰,便于提示我们什么时候进行买卖,我们可以把出现转机的时点作为文本,标在图上。

  # !/usr/bin/env python
  # -*- encoding:utf-8 -*-

  import sys
  import importlib

  #importlib.reload(sys)
  #Python3不同,使用上述语句替代,但不建议使用
  #sys.setdefaultencoding('utf-8')    

  import matplotlib as mpl
  import pandas as pd
  import matplotlib.pyplot as plt
  import numpy as np

  #交错标注日期的转换标志
  cn = 1
  cnb = 1

  def rowIndex(row):
      """根据指示绘制买卖信号的标志"""
      global plt, cn, cnb

      #交错标注日期的位置常数
      buyt = 0.5
      buyb = 0.5

      if row.signal > 0:
          #xy表示被注释的位置坐标
          plt.annotate(u'B', xy=(row.date_o, row.signal),    
                       arrowprops=dict(facecolor='red', shrink=0.05))
          if cn == 1:
              buyt = 1
              cn = -1
          else:
              buyt = 0.5
              cn = 1
          plt.annotate(str(row.date_o).replace("-", "")[2:8], #日期字符化、替代、切片
                       xytext=(row.date_o, row.signal + buyt),      #文本标注的位置
                       xy = (row.date_o, row.signal + 0.5),             #指示标志的位置
                       arrowprops=dict(facecolor='red', shrink=0.5))

      if row.signal < 0:
          plt.annotate(u'S', xy=(row.date_o, row.signal))
          if cnb == 1:
              buyb = 1
              cnb = -1
          else:
              buyb = 0.5
              cnb = 1
          plt.annotate(str(row.date_o).replace("-", "")[2:8],
                       xytext = (row.date_o, row.signal - buyb),
                       xy = (row.date_o, row.signal + 0.5),
                       arrowprops=dict(facecolor='red', shrink=0.5))


  if __name__ =="__main__":
 
      mpl.rcParams['font.sans-serif'] = ['Arial Unicode MS']    #正常显示中文标签
      mpl.rcParams['axes.unicode_minus'] = False                    #正常显示负号         

      dateparse1 = lambda dates: pd.datetime.strptime(dates, '%Y-%m-%d')

      s_list = pd.read_csv("kd.csv", skiprows=0, encoding='utf-8',
                           index_col='date', parse_dates=True,
                           date_parser=dateparse1)

      s_list['date_o'] = s_list.index
      s_list['ma_sub'] = s_list['ma5'] - s_list['ma20']
      s_list['diff'] = np.sign(s_list['ma_sub'])
      s_list['signal'] =  np.sign(s_list['diff'] - s_list['diff'].shift(1))

      s_list['signal'].plot(ylim=(-2, 2))
      (s_list['close']/40).plot(ylim=(-2, 2))
      s_list.apply(rowIndex, axis=1)
      plt.legend(loc='upper right')
      plt.grid(b=True)

      #打开matplotlib查看器查看图形
      plt.show()      

    其中精妙之处在于,使用一个转换标志来交错的在图上标示提示信息,避免重叠,包括距离转换。以下是结果:
结果.png

注意的是:
1、提示标志和提示信息是两块图层内容,需要分别绘制;
2、绘制提示信息时,需要用到条件语句进行限制,并随之变更转换标志,将提示信息交错绘制;
3、row在python中是一关键字,可以直接应用于对数据的相关处理(定义函数),调用函数时,程序自动按行查找,不需要传递实参。
要显示汉字,请参考!c12-4.