KevinMeng

V1

2022/02/20阅读:177主题:自定义主题1

绘制plotly金融股票图避坑指南——解决k线不连续问题

绘制plotly金融股票图避坑指南——解决k线不连续问题

引言

最近,在用 streamlit 开发股票分析系统,选择用plotly在绘制可交互的k线时走势图,踩了好几个坑。刚完美解决,趁热写写个文章,分享给大家。

目标:

1. k线与成交量线组合

类似于 东方财富的这种。

2.和交互,支持缩放

许多包都可以实现,因为对 plotly 相对熟悉,且streamlit支持好,就选择了它。

碰到的坑

k线成交时间不连续

由于周末、法定假期等因素导致,交易时间不连续,plotly 默认将x推断为日期,导致绘制的图形跳跃。但是这其中有些不连续是客观情况导致的不连续(停牌),这种应该保留。 如下图:

解决方案

网上的解决方案,大多将无交易数据的日期进行剔除,没有区别停牌情况,是有问题的。

正确的做法应该根据市场的(A股)交易日期,将非交易日期剔除,这样皆可以实现连续又可以避免个股停牌的影响。

直接上代码



import akshare as ak
import datetime
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots


def get_stock_price(share,start_date="20170301",end_date="20210218"):
    # 获取个股行情数据
    stock_zh_a_hist_df = ak.stock_zh_a_hist(symbol=share, period="daily", start_date=start_date, end_date=end_date)  # adjust="qfq"
    return stock_zh_a_hist_df

def get_trading_date():
    # 获取市场的交易时间
    trade_date = ak.tool_trade_date_hist_sina()['trade_date']
    trade_date = [d.strftime("%Y-%m-%d"for d in trade_date]
    return trade_date


def plot_cand_volume(data, dt_breaks):
    # Create subplots and mention plot grid size
    fig = make_subplots(rows=2, cols=1, shared_xaxes=True
                   vertical_spacing=0.03, subplot_titles=('''成交量'), 
                   row_width=[0.20.7])

    # 绘制k数据
    fig.add_trace(go.Candlestick(x=data["date"], open=data["open"], high=data["high"],
                    low=data["low"], close=data["close"], name=""), 
                    row=1, col=1
    )

    # 绘制成交量数据
    fig.add_trace(go.Bar(x=data['date'], y=data['volume'], showlegend=False), row=2, col=1)

    fig.update_xaxes(
        title_text = 'date',
        rangeslider_visible = True# 下方滑动条缩放
        rangeselector = dict(
            # 增加固定范围选择
            buttons = list([
                dict(count = 1, label = '1M', step = 'month', stepmode = 'backward'),
                dict(count = 6, label = '6M', step = 'month', stepmode = 'backward'),
                dict(count = 1, label = '1Y', step = 'year', stepmode = 'backward'),
                dict(count = 1, label = 'YTD', step = 'year', stepmode = 'todate'),
                dict(step = 'all')])))

    # Do not show OHLC's rangeslider plot 
    fig.update(layout_xaxis_rangeslider_visible=False)
    # 去除休市的日期,保持连续
    fig.update_xaxes(rangebreaks=[dict(values=dt_breaks)])
    
    return fig


data = get_stock_price(share='000792')
data = data.rename(columns = {'日期':'date''开盘':'open''收盘':'close''最高':'high''最低':'low''成交量':'volume'})
# 剔除不交易日期
dt_all = pd.date_range(start=data['date'].iloc[0],end=data['date'].iloc[-1])
dt_all = [d.strftime("%Y-%m-%d"for d in dt_all]
dt_breaks = list(set(dt_all) - set(trade_date))
# 绘制 复杂k线图
fig = plot_cand_volume(data, dt_breaks)

最终实现的效果:
  1. k线数据连续
  2. k与成交量同步变化
  3. 增加时间选择器,包括固定日期

参考资料

  • https://stackoverflow.com/questions/64689342/plotly-how-to-add-volume-to-a-candlestick-chart
  • Plotly中绘制三种经典的股票交易图表(含视频讲解)

分类:

其他

标签:

其他

作者介绍

KevinMeng
V1