参考:
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()