使用mplfinance和matplotlib生成动态K线图

参考:
https://blog.csdn.net/Shepherdppz/article/details/108205721
https://blog.csdn.net/Shepherdppz/article/details/117575286
这两篇文章写的很详细,照着他的做基本可以弄出来的

其中注意点是
数据格式
中文乱码处理
独立窗口

数据格式

我所用到的数据是自己扒拉出来的
所以要进行格式化
def get_stock_data(file_path):
    '''
    数据来源
    :param file_path:
    :return:
    '''
    data = pd.read_csv(file_path, index_col=0)
    data['open'] = data['open_price']
    data['high'] = data['high_price']
    data['low'] = data['low_price']
    data['close'] = data['close_price']
    data['volume'] = data['deal_quantity']
    data['change'] = data['change_rate']
    data.index = pd.to_datetime(data['date'], format='%Y-%m-%d')
    data.rename(index=pd.Timestamp)
    # 提取自己需要的数据  其中 'open', 'high', 'low', 'close', 'volume' 名称要固定
    data= data[
        ['open', 'high', 'low', 'close', 'volume', 'ma_5', 'ma_20', 'ma_60', 'macd', 'diff', 'dea', 'date']]
    return data

中文乱码处理:
中文乱码处理实际上跟自己电脑上装的字体库有关的,可以使用下面代码查看

    from matplotlib.font_manager import FontManager
    fm = FontManager()
    # 字体
    print(fm.ttflist)

将fontname换成你查出来的name值就行了
在这里插入图片描述
独立窗口
没有独立窗口, 程序运行一下就没了,只有一张图片显示出来, 不是独立的窗口,K线是没办法根据键盘或者鼠标刷新的,可以添加’tkagg’或者’qt4agg’以及’qt5agg’来实现但是我的电脑只能是’tkagg’

# 独立窗口
import matplotlib
matplotlib.use('tkagg')

图片保存直接调用,但是只有在窗口关掉后,文件才保存出来

 plt.savefig(img_path + '.jpg')

画图展示:(完整代码在下面)
在这里插入图片描述

完整代码如下
我的环境 win10 python3.75
我将原代码中鼠标控制去掉了,只保留了方向键控制日期变化

代码中所用到的数据 https://download.csdn.net/download/xy3233/82009700

# coding=utf-8
import pandas as pd
import mplfinance as mpf
import numpy as np
import matplotlib.pyplot as plt

# 独立窗口
import matplotlib

matplotlib.use('tkagg')


def get_stock_data(file_path):
    '''
    数据来源
    :param file_path:
    :return:
    '''
    data = pd.read_csv(file_path, index_col=0)
    data['open'] = data['open_price']
    data['high'] = data['high_price']
    data['low'] = data['low_price']
    data['close'] = data['close_price']
    data['volume'] = data['deal_quantity']
    data['change'] = data['change_rate']
    data.index = pd.to_datetime(data['date'], format='%Y-%m-%d')
    data.rename(index=pd.Timestamp)
    return data


# 自定义风格和颜色
# 设置mplfinance的蜡烛颜色,up为阳线颜色,down为阴线颜色
my_color = mpf.make_marketcolors(up='r',  # 上涨K线的柱子的内部填充色
                                 down='g',  # 下跌K线的柱子的内部填充色
                                 edge='inherit',  # 边框设置“inherit”代表使用主配色 不设置则为黑色
                                 wick='inherit',  # wick设置的就是上下影线的颜色
                                 volume='inherit')  # volume设置的是交易量柱子的颜色
# 设置图表的背景色
my_style = mpf.make_mpf_style(marketcolors=my_color,
                              figcolor='(0.82, 0.83, 0.85)',
                              gridcolor='(0.82, 0.83, 0.85)')

# 标题格式,字体为中文字体,颜色为黑色,粗体,水平中心对齐
title_font = {'fontname': 'STZhongsong',
              'size': '16',
              'color': 'black',
              'weight': 'bold',
              'va': 'bottom',
              'ha': 'center'}

# 标签格式,可以显示中文,普通黑色12号字
normal_label_font = {'fontname': 'STZhongsong',
                     'size': '12',
                     'color': 'black',
                     'va': 'bottom',
                     'ha': 'right'}

# 小数字格式(显示其他价格信息)粗体红色12号字
small_red_font = {'fontname': 'STZhongsong',
                  'size': '12',
                  'color': 'red',
                  'weight': 'bold',
                  'va': 'bottom'}
# 小数字格式(显示其他价格信息)粗体绿色12号字
small_green_font = {'fontname': 'STZhongsong',
                    'size': '12',
                    'color': 'green',
                    'weight': 'bold',
                    'va': 'bottom'}

# 绿色数字格式(显示开盘收盘价)粗体绿色24号字
large_green_font = {'fontname': 'STZhongsong',
                    'size': '24',
                    'color': 'green',
                    'weight': 'bold',
                    'va': 'bottom'}


class InterCandle:
    def __init__(self, data):
        self.data = data
        self.start = 0  # 开始序号
        self.len = 50  # 显示长度
        # 添加三个图表,四个数字分别代表图表左下角在figure中的坐标,以及图表的宽(0.88)、高(0.60)
        self.fig = mpf.figure(figsize=(12, 8), facecolor=(0.82, 0.83, 0.85))
        # 添加三个图表,四个数字分别代表图表左下角在figure中的坐标,以及图表的宽(0.88)、高(0.60)
        self.price_axe = self.fig.add_axes([0.06, 0.25, 0.88, 0.60])  # 添加价格图表 K线图
        # 添加第二、三张图表时,使用sharex关键字指明与ax1在x轴上对齐,且共用x轴
        self.volume_axe = self.fig.add_axes([0.06, 0.15, 0.88, 0.10], sharex=self.price_axe)  # 添加成交量
        self.macd_axe = self.fig.add_axes([0.06, 0.05, 0.88, 0.10], sharex=self.price_axe)  # 添加macd
        # 设置三张图表的Y轴标签
        self.price_axe.set_ylabel('price')
        self.volume_axe.set_ylabel('volume')
        self.macd_axe.set_ylabel('macd')

        # 标题等文本
        # 初始化figure对象,在figure上预先放置文本并设置格式,文本内容根据需要显示的数据实时更新
        self.t1 = self.fig.text(0.50, 0.94, '513100.SH - 纳斯达克指数ETF基金', **title_font)
        self.t2 = self.fig.text(0.12, 0.90, '开/收: ', **normal_label_font)
        self.t2_1 = self.fig.text(0.22, 0.90, f'', **normal_label_font)
        self.t3 = self.fig.text(0.40, 0.90, '高: ', **normal_label_font)
        self.t3_1 = self.fig.text(0.40, 0.90, f'', **small_red_font)
        self.t4 = self.fig.text(0.55, 0.90, '低: ', **normal_label_font)
        self.t4_1 = self.fig.text(0.55, 0.90, f'', **small_green_font)
        self.t5 = self.fig.text(0.70, 0.90, '量(万手): ', **normal_label_font)
        self.t5_1 = self.fig.text(0.75, 0.90, f'', **normal_label_font)
        self.t6 = self.fig.text(0.45, 0.87, '当前时间: ', **normal_label_font)
        self.t6_1 = self.fig.text(0.55, 0.87, f' ', **normal_label_font)
        self.fig.canvas.mpl_connect('key_press_event', self.on_key_press)

    def plt_show(self):
        self.refresh_plot(self.data.iloc[self.start:self.start + self.len])

    def refresh_plot(self, plot_data):
        # 刷新图
        # 读取显示区间最后一个交易日的数据
        last_data = plot_data.iloc[-1]
        # 将这些数据分别填入figure对象上的文本中
        self.t2_1.set_text(f'{np.round(last_data["open"], 3)} / {np.round(last_data["close"], 3)}')
        self.t3_1.set_text(f'{last_data["high"]}')
        self.t4_1.set_text(f'{last_data["low"]}')
        self.t5_1.set_text(f'{np.round(last_data["volume"] / 10000, 3)}')
        self.t6_1.set_text(f'{last_data["date"]}')

        # 生成一个空列表用于存储多个addplot
        ap = []
        # 添加均线
        ap.append(mpf.make_addplot(plot_data[['ma_5', 'ma_20', 'ma_60']], ax=self.price_axe))
        # 添加 diff 和 dea
        ap.append(mpf.make_addplot(plot_data[['diff']], color='black', ax=self.macd_axe))
        ap.append(mpf.make_addplot(plot_data[['dea']], color='orange', ax=self.macd_axe))
        # 添加macd
        ap.append(mpf.make_addplot(plot_data[['macd']], type='bar', color='green', ax=self.macd_axe))
        #  调用mpf.plot()函数,这里需要指定ax=price_axe,volume=ax2,将K线图显示在ax1中,交易量显示在ax2中
        mpf.plot(plot_data, ax=self.price_axe, addplot=ap, volume=self.volume_axe, type='candle', style=my_style,
                 xrotation=0)
        mpf.show()

    def on_key_press(self, event):
        key = event.key
        if key == 'enter':
            # 保存图片
            img_path = str(self.start) + '-' + str(self.start + self.len)
            plt.savefig(img_path + '.jpg')
            return
        elif key == 'left' or key == 'down':
            if self.start > 1:
                self.start = self.start - 1
        elif key == 'right' or key == 'up':
            if self.start + self.len < self.data.shape[0]:
                self.start = self.start + 1
        self.price_axe.clear()
        self.macd_axe.clear()
        self.volume_axe.clear()
        self.refresh_plot(self.data.iloc[self.start:self.start + self.len])


if __name__ == '__main__':
    file_path = './../0_data/000001_stock.csv'
    all_data = get_stock_data(file_path)
    # 选取我需要的数据
    daily_data = all_data[
        ['open', 'high', 'low', 'close', 'volume', 'ma_5', 'ma_20', 'ma_60', 'macd', 'diff', 'dea', 'date']]
    candle = InterCandle(daily_data)
    candle.plt_show()
  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值