关于程序员:量化投资系列之股票日行情数据可视化

7次阅读

共计 10153 个字符,预计需要花费 26 分钟才能阅读完成。

量化投资系列之《股票日行情数据可视化》

k 线图可视化很重要,西医有望闻问切,股票 k 线状态很重要,把握可视化技术,为后续可视化报告打下基础。

装置

装置 matplotlib 库,数据可视化库

pip install -U matplotlib

装置 mplfinance 库,股票 k 线图可视化库

pip install --upgrade mplfinance

matplotlib 根底

matplotlib Python 2D- 绘图畛域应用最宽泛的套件,它很轻松的将数据可视化,理解 matplotlib,请学习教程 1 链接[2],教程 2 链接[3]

plt 函数

函数 形容 函数 形容
plt.plot(x,y) 画线 plt.title(‘title’) 增加图标题目
plt.xlabel(‘x 轴 ’) x 轴标签 plt.ylabel(‘y 轴 ’) y 轴标签

中文问题

办法一

# 用来失常显示中文标签
plt.rcParams['font.sans-serif'] = ['SimHei']
# 解决负号显示方块问题
plt.rcParams['axes.unicode_minus'] = False

办法二

# 下载字体放在工程,例如 'font/SourceHanSansSC-Bold.otf',而后援用
zhfont1 = mpl.font_manager.FontProperties(fname='字体门路')
# 题目格局,字体为中文字体,色彩为彩色,粗体,程度核心对齐
title_font = {'fontproperties': zhfont1,
              'size': '16',
              'color': 'black',
              'weight': 'bold',
              'va': 'bottom',
              'ha': 'center'}
plt.title('测试', **title_font)

多图绘制

画布和多张子图概念,在画布 figure 上绘制多张子图 axes . 常采纳 subplot() 函数或 subplots() 函数进行绘制。

figure 对象

参数 类型 默认值 形容
num int 1 图像数量
figsize tuple figure.figsize 图像的长和宽(英寸)
dpi int figure.dpi 分辨率(点 / 英寸)
facecolor tuple figure.facecolor 绘制区域背景色
edgecolor tuple figure.edgecolor 绘图区域边缘的色彩
frameon bool True 是否绘制图像边缘

Axes 对象

plt.axes([left, bottom, width, height])

axes 对象是个列表,四个数值别离是绝对于 figure 对象左下角坐标的左间隔、底部间隔、宽、高。

示例代码

fig = plt.figure(figsize=(10, 8), dpi=80,
                 facecolor=(0.82, 0.83, 0.85),
                 edgecolor=(1, 1, 1),
                 frameon=True)
# 设置图片边缘间隔
plt.subplots_adjust(left=0.08, right=0.92, top=0.92, bottom=0.08)

# 用来失常显示中文标签
plt.rcParams['font.sans-serif'] = ['SimHei']
# 解决负号显示方块问题
plt.rcParams['axes.unicode_minus'] = False
plt.title('绘制多子图')
plt.xlabel('x 轴')
plt.ylabel('y 轴')
plt.grid(color='r', linestyle='--', linewidth=0.5)

plt.axes([0.1, 0.1, .5, .5])
# 设置横轴记号 设置纵轴记号
plt.xticks([]), plt.yticks([])
plt.text(0.1, 0.1, 'axes([0.1,0.1,.5,.5])', ha='left', va='center', size=16, alpha=.5)

plt.axes([0.2, 0.2, .5, .5])
plt.xticks([]), plt.yticks([])
plt.text(0.1, 0.1, 'axes([0.2,0.2,.5,.5])', ha='left', va='center', size=16, alpha=.5)

plt.axes([0.3, 0.3, .5, .5])
plt.xticks([]), plt.yticks([])
plt.text(0.1, 0.1, 'axes([0.3,0.3,.5,.5])', ha='left', va='center', size=16, alpha=.5)

plt.axes([0.4, 0.4, .5, .5])
plt.xticks([]), plt.yticks([])
plt.text(0.1, 0.1, 'axes([0.4,0.4,.5,.5])', ha='left', va='center', size=16, alpha=.5)
plt.show()

成果:

mplfinance 库应用

mplfinance 外面提供的函数,其实封装了 pyplot 库,实质上是 pyplot 库 k 线的定制版。

蜡烛图

画图之前,先理解下蜡烛图概念,蜡烛线将各种股票每日、每周、每月开盘价、收盘价、最高价、最低价等涨跌变动情况,用图形形式体现进去,即蜡烛图。如下图所示,K 线最上方细线称为上影线,两头条粗线为实体。上面的细线为下影线。

如图所示:

绘制

自定义格调

要害函数 mpf.make_mpf_style() 和 mpf.make_marketcolors()

# 设置 marketcolors
 # up: 设置 K 线线柱色彩,up 意为收盘价大于等于开盘价
 # down: 与 up 相同,这样设置与国内 K 线色彩规范相符
 # edge:K 线线柱边缘色彩(i 代表继承自 up 和 down 的色彩),下同。详见官网文档)
 # wick: 灯芯 (上下影线) 色彩
 # volume: 成交量直方图的色彩
 # inherit: 是否继承,选填
 mc = mpf.make_marketcolors(
     up='red',
     down='green',
     edge='in',
     wick='in',
     volume='in',
     inherit=True)

 # 设置图形格调
 # gridaxis: 设置网格线地位
 # gridstyle: 设置网格线线型
 # y_on_right: 设置 y 轴地位是否在右
 m_style = mpf.make_mpf_style(
     gridaxis='both',
     gridstyle='-.',
     figcolor='(0.82, 0.83, 0.85)',
     gridcolor='(0.82, 0.83, 0.85)',
     y_on_right=False,
     marketcolors=mc)

简略绘制

mpf.plot(df.iloc[20:147], style=m_style, type='candle', volume=True)

进阶绘制

按自定义格调,曾经能够失去了一张简略蕴含 k 线和成交量的图,但还想显示更多指标,例如 KDJ,MACD 等,表格顶部区域预留空白显示价格等指标。所以须要用到库的 External Axes Mode 模式绘制。

在 External Axes Mode 模式下,能够更自在画布上的每个图标和文字元素,取得更大的绘制自在。

定制对象

为了能更大的获取绘制自由度,须要获取画布对象 figure、子图 Axes、文字 Text。文字和图表的地位、大小、格局齐全自定义。参数应用解析,请查看下面的 matplotlib 多图绘制。

生成主画布 fig,日行情 k 线子图 ax1,成交量子图 ax2,macd 子图 ax3。

# 获取 figure 对象,以便对 Axes 对象和 figure 对象的自在管制
fig = mpf.figure(style=m_style, figsize=(12, 8),
                 facecolor=(0.82, 0.83, 0.85))
# 主图绝对 figure 底部 0.06,0.25,宽(0.88)、高(0.60)ax1 = fig.add_axes([0.06, 0.25, 0.88, 0.60])
# 指标图 sharex 关键字指明与 ax1 在 x 轴上对齐,且共用 x 轴
ax2 = fig.add_axes([0.06, 0.15, 0.88, 0.10], sharex=ax1)
# macd
ax3 = fig.add_axes([0.06, 0.05, 0.88, 0.10], sharex=ax1)
# 设置 y 轴标签
ax1.set_ylabel('price')
ax2.set_ylabel('volume')
ax3.set_ylabel('macd')

字体自定义

# 下载的字体门路
zhfont = mpl.font_manager.FontProperties(fname=sc.text_font)
# 题目格局,字体为中文字体,色彩为彩色,粗体,程度核心对齐
title_font = {'fontproperties': zhfont,
              'size': '16',
              'color': 'black',
              'weight': 'bold',
              'va': 'bottom',
              'ha': 'center'}
# 红色数字格局(显示收盘收盘价)粗体红色 24 号字
large_red_font = {'fontproperties': zhfont,
                  'size': '24',
                  'color': 'red',
                  'weight': 'bold',
                  'va': 'bottom'}
# 绿色数字格局(显示收盘收盘价)粗体绿色 24 号字
large_green_font = {'fontproperties': zhfont,
                    'size': '24',
                    'color': 'green',
                    'weight': 'bold',
                    'va': 'bottom'}
# 小数字格局(显示其余价格信息)粗体红色 12 号字
small_red_font = {'fontproperties': zhfont,
                  'size': '12',
                  'color': 'red',
                  'weight': 'bold',
                  'va': 'bottom'}
# 小数字格局(显示其余价格信息)粗体绿色 12 号字
small_green_font = {'fontproperties': zhfont,
                    'size': '12',
                    'color': 'green',
                    'weight': 'bold',
                    'va': 'bottom'}
# 标签格局,能够显示中文,一般彩色 12 号字
normal_label_font = {'fontproperties': zhfont,
                     'size': '12',
                     'color': 'black',
                     'va': 'bottom',
                     'ha': 'right'}
# 一般文本格式,一般彩色 12 号字
normal_font = {'fontproperties': zhfont,
               'size': '12',
               'color': 'black',
               'va': 'bottom',
               'ha': 'left'}

Ta-lib 获取金融指标 MA ,MACD

talib 是一个金融指标库,蕴含 150 种罕用金融指标,github 地址[5]

计算 5 日、10 日、20 日、60 日均线

N = [5, 10, 20, 60]
  for i in N:
      df['MA' + str(i)] = ta.EMA(df['Close'], timeperiod=i)

计算 macd 指标

# 通过金融库 talib 生成 MACD 指标,short_win = 12  # 短期 EMA 平滑天数
long_win = 26  # 长期 EMA 平滑天数
macd_win = 9  # DEA 线平滑天数
macd_tmp = ta.MACD(df['Close'], fastperiod=short_win, slowperiod=long_win, signalperiod=macd_win)
DIF = macd_tmp[0][start_index:end_index]
DEA = macd_tmp[1][start_index:end_index]
MACD = macd_tmp[2][start_index:end_index]

增加指标到子图

留神,最初 mpf.plot 绘制是须要增加指标参数 addplot=ap

ap = []
ap.append(mpf.make_addplot(df[['MA5', 'MA10', 'MA20', 'MA60']].iloc[start_index:end_index], ax=ax1))

mpf.plot(df_data,
            ax=ax1,
            volume=ax2,
            addplot=ap,
            style=m_style,
            type='candle')

残缺示例

绘制安全银行 2022-01-01 到 2022-09-30,残缺的日行情 k 线图,增加头部股票简述、均线指标、成交量指标、macd 指标。

代码

"""用于绘制股票 k 线"""
import matplotlib as mpl
import matplotlib.pyplot as plt
import mplfinance as mpf
import numpy as np
import talib as ta

import stock_constant as sc
import stock_db as sdb

# 下载的字体门路
zhfont = mpl.font_manager.FontProperties(fname=sc.text_font)
# 题目格局,字体为中文字体,色彩为彩色,粗体,程度核心对齐
title_font = {'fontproperties': zhfont,
              'size': '16',
              'color': 'black',
              'weight': 'bold',
              'va': 'bottom',
              'ha': 'center'}
# 红色数字格局(显示收盘收盘价)粗体红色 24 号字
large_red_font = {'fontproperties': zhfont,
                  'size': '24',
                  'color': 'red',
                  'weight': 'bold',
                  'va': 'bottom'}
# 绿色数字格局(显示收盘收盘价)粗体绿色 24 号字
large_green_font = {'fontproperties': zhfont,
                    'size': '24',
                    'color': 'green',
                    'weight': 'bold',
                    'va': 'bottom'}
# 小数字格局(显示其余价格信息)粗体红色 12 号字
small_red_font = {'fontproperties': zhfont,
                  'size': '12',
                  'color': 'red',
                  'weight': 'bold',
                  'va': 'bottom'}
# 小数字格局(显示其余价格信息)粗体绿色 12 号字
small_green_font = {'fontproperties': zhfont,
                    'size': '12',
                    'color': 'green',
                    'weight': 'bold',
                    'va': 'bottom'}
# 标签格局,能够显示中文,一般彩色 12 号字
normal_label_font = {'fontproperties': zhfont,
                     'size': '12',
                     'color': 'black',
                     'va': 'bottom',
                     'ha': 'right'}
# 一般文本格式,一般彩色 12 号字
normal_font = {'fontproperties': zhfont,
               'size': '12',
               'color': 'black',
               'va': 'bottom',
               'ha': 'left'}


def kline(code, start_time, end_time):
    """
    绘制某股票某时间段的日行情 k 线图
    :param code:
    :param start_time:
    :param end_time:
    :return:
    """
    # 数据库读取数据
    df = sdb.stock_daily(code=code, start_time=start_time, end_time=end_time)
    print(df)
    # 重命名列
    df.rename(
        columns={
            'date': 'Date', 'open': 'Open',
            'high': 'High', 'low': 'Low',
            'close': 'Close', 'volume': 'Volume'},
        inplace=True)
    start_index = 20
    end_index = 147
    df_data = df.iloc[start_index:end_index]
    # 读取显示区间最初一个交易日的数据
    last_data = df_data.iloc[-1]

    # 设置图片边缘间隔
    plt.subplots_adjust(left=0.08, right=0.92, top=0.92, bottom=0.08)

    # 设置 marketcolors
    # up: 设置 K 线线柱色彩,up 意为收盘价大于等于开盘价
    # down: 与 up 相同,这样设置与国内 K 线色彩规范相符
    # edge:K 线线柱边缘色彩(i 代表继承自 up 和 down 的色彩),下同。详见官网文档)
    # wick: 灯芯 (上下影线) 色彩
    # volume: 成交量直方图的色彩
    # inherit: 是否继承,选填
    mc = mpf.make_marketcolors(
        up='red',
        down='green',
        edge='in',
        wick='in',
        volume='in',
        inherit=True)

    # 设置图形格调
    # gridaxis: 设置网格线地位
    # gridstyle: 设置网格线线型
    # y_on_right: 设置 y 轴地位是否在右
    m_style = mpf.make_mpf_style(
        gridaxis='both', gridstyle='-.',
        figcolor='(0.82, 0.83, 0.85)',
        gridcolor='(0.82, 0.83, 0.85)',
        y_on_right=False,
        marketcolors=mc)

    # 获取 figure 对象,以便对 Axes 对象和 figure 对象的自在管制
    fig = mpf.figure(style=m_style, figsize=(12, 8),
                     facecolor=(0.82, 0.83, 0.85))
    # 主图绝对 figure 底部 0.06,0.25,宽(0.88)、高(0.60)ax1 = fig.add_axes([0.06, 0.25, 0.88, 0.60])
    # 指标图 sharex 关键字指明与 ax1 在 x 轴上对齐,且共用 x 轴
    ax2 = fig.add_axes([0.06, 0.15, 0.88, 0.10], sharex=ax1)
    # macd
    ax3 = fig.add_axes([0.06, 0.05, 0.88, 0.10], sharex=ax1)
    # 设置 y 轴标签
    ax1.set_ylabel('price')
    ax2.set_ylabel('volume')
    ax3.set_ylabel('macd')

    # 在 figure 对象上增加文本对象,用于显示各种价格和题目
    fig.text(0.50, 0.94, '安全银行', **title_font)
    fig.text(0.12, 0.90, '开 / 收:', **normal_label_font)
    fig.text(0.14, 0.89, '%.2f / %.2f' % (np.around(last_data["Open"], 2),
                                          np.round(last_data["Close"], 2)), **large_red_font)
    fig.text(0.12, 0.86, f'{last_data.name.date()}', **normal_label_font)
    change = last_data["Close"] - last_data["Open"]
    fig.text(0.14, 0.86, '%.2f' % change, **small_red_font)
    change_percent = (change / last_data["Open"]) * 100
    fig.text(0.22, 0.86, '%.2f%%' % change_percent, **small_red_font)
    fig.text(0.40, 0.90, '高:', **normal_label_font)
    fig.text(0.40, 0.90, '%.2f' % (last_data["High"]), **small_red_font)
    fig.text(0.40, 0.86, '低:', **normal_label_font)
    fig.text(0.40, 0.86, '%.2f' % (last_data["Low"]), **small_green_font)
    fig.text(0.55, 0.90, '量(万手):', **normal_label_font)
    fig.text(0.55, 0.90, '%.2f' % (np.round(last_data["Volume"] / 10000, 3)), **normal_font)
    fig.text(0.55, 0.86, '额(亿元):', **normal_label_font)
    fig.text(0.55, 0.86, '%.2f' % (last_data["amount"] / 100000000), **normal_font)

    ap = []
    # 通过金融库 talib 生成挪动平均线,为了生成没空白的,应用原数据
    N = [5, 10, 20, 60]
    for i in N:
        df['MA' + str(i)] = ta.EMA(df['Close'], timeperiod=i)
    # 通过 ax=ax1 参数指定把新的线条增加到 ax1 中,与 K 线图重叠
    # 通过 ax=ax1 参数指定把新的线条增加到 ax1 中,与 K 线图重叠,留神均线切片 iloc[20:147]与 ax1 工夫维度一样
    ap.append(mpf.make_addplot(df[['MA5', 'MA10', 'MA20', 'MA60']].iloc[start_index:end_index], ax=ax1))

    # 通过金融库 talib 生成 MACD 指标,short_win = 12  # 短期 EMA 平滑天数
    long_win = 26  # 长期 EMA 平滑天数
    macd_win = 9  # DEA 线平滑天数
    macd_tmp = ta.MACD(df['Close'], fastperiod=short_win, slowperiod=long_win, signalperiod=macd_win)
    DIF = macd_tmp[0][start_index:end_index]
    DEA = macd_tmp[1][start_index:end_index]
    MACD = macd_tmp[2][start_index:end_index]

    # 生成一个空列表用于存储多个 addplot
    # 在 ax3 图表中绘制 MACD 指标中的快线和慢线
    ap.append(mpf.make_addplot(DIF, ax=ax3))
    ap.append(mpf.make_addplot(DEA, ax=ax3))
    # 应用柱状图绘制快线和慢线的差值,依据差值的数值大小,别离用红色和绿色填充
    # 红色和绿色局部须要别离填充,因而学生成两组数据,别离蕴含大于零和小于等于零的数据
    bar_r = np.where(MACD > 0, MACD, 0)
    bar_g = np.where(MACD <= 0, MACD, 0)
    # 应用柱状图填充(type='bar'),设置色彩别离为红色和绿色
    ap.append(mpf.make_addplot(bar_r, type='bar', color='red', ax=ax3))
    ap.append(mpf.make_addplot(bar_g, type='bar', color='green', ax=ax3))

    # 留神增加均线参数,macd, addplot=ap
    mpf.plot(df_data,
             ax=ax1,
             volume=ax2,
             addplot=ap,
             style=m_style,
             type='candle')
    fig.show()


if __name__ == '__main__':
    kline('000001', '2022-01-01', '2022-09-30')
    pass

效果图:

下篇预报

回测神器框架 backtrader 的应用

学习到当初,曾经具备了股票代码本地化,k 线可视化,前面的重头戏是如何编写复利策略,并应用历史数据进行回测,测验策略是否无效。

考察了不少回测框架,最终抉择 backtrader 这个框架。这框架模块划分很明确,尽管回测速度慢点,然而社区曾经稳固齐全,全副由 python 编写,也不便后续的优化和接入机器学习。

就选它,就选它,就选它,回测神器 backtrader。

参考链接

[1] mplfinance 库地址: https://github.com/matplotlib…
[2] matplotlib 教程 1: https://www.runoob.com/matplo…
[3] matplotlib 教程 2: https://www.runoob.com/w3cnot…
[4] k 线可视化示例地址: https://blog.csdn.net/m0_6739…
[5] ta-lib 库地址: https://mrjbq7.github.io/ta-lib/

写于 2022 年 9 月 12 日 17:25:27

本文由 mdnice 多平台公布

正文完
 0