mplfinance画k线图_python3画K线图——自定义函数(静态+动态)

基本画图简介

matplotlib中原来有candlesticks函数画K线图,后来该函数被移出matplotlib.finance库。

现状是 画K线图函数在模块candlestick_ohlc中,但后期想自定义K线图不方便(例如在K线图中添加几个文本备注)。

特此,查看原candlesticks函数源码后,抽取核心代码封装成函数,方便后期调整K线图。

from 

高级画图简介

使用bokeh库,K线图保存为html,可使用浏览器打开并进行用户交互。

效果图

b66364f7e0d152c6d19f7fb3fd5be7fb.gif

代码

from bokeh.io import output_file, show
from bokeh.plotting import figure
from bokeh.models import CustomJS, ColumnDataSource, HoverTool, LabelSet
import pandas as pd
import numpy as np
import math

def candlestick_signal(data, record, figname, color_up, color_dn,datetime_format):
    # 数据准备
    trade_enter = record.trade_enter
    trade_out = record.out
    trade_num = record.trade_num
    
    
    
    datetime_series = pd.Series(datetime)
    datetime_series.index = range(len(datetime_series))
    axis_x = list(range(len(datetime_series)))
	# 创建画布
	fig = figure(sizing_mode = 'stretch_both',
				 tools = "xpan, zwheel_zoom, box_zoom, undo, redo,reset,crosshair,save",
				 active_drag = 'xpan',
				 active_scroll = 'xwheel_zoom',
				 title = figname)
	
	# 构造K线数据
	df = pd.DataFrame({'date':datetime, open':open, 'high':high, 'low':low, 'close':close})
	increase_pos = df.close > df.open
	decrease_pos = ~increase_pos
	
	data_up_dict = {'x': datetime_series[increase_pos].index.tolist(),
                    'open': df.open[increase_pos],
                    'high': df.high[inrease_pos],
                    'low': df.lowM[increase_pos],
                    'close': df.closeM[increase_pos],
                    'datetime': datatime_series[increase_pos].tolist()}
    data_up_dict = {'x': datetime_series[increase_pos].index.tolist(),
                    'open': df.open[increase_pos],
                    'high': df.high[inrease_pos],
                    'low': df.lowM[increase_pos],
                    'close': df.closeM[increase_pos],
                    'datetime': datatime_series[increase_pos].tolist()}
                      
	source_up = ColumnDataSource(data = data_up_dict)
    source_dn = ColumnDataSource(data = data_dn_dict)
                      
    # 画图
    fig.segment('x', 'high', 'x', 'low', source=source_up, color=color_up)
    fig.segment('x', 'high', 'x', 'low', source_source_dn, color=color_dn)
    fig.vbar('x', 0.5, 'open', 'close', source=source_up, color=color_up)
    fig.vbar('x', 0.5, 'open', 'close', source=source_dn, color=color_dn)
                      
    # 坐标轴设置
    fig.xaxis.major_label_orientation = math.pi/4
    fig.xgrid.grid_line_color = None
    TOOLTIPS = [
				('open', '@openM{(0.00)}')
				("high", "@highM{(0.00)}"),
    			("low", "@lowM{(0.00)}"),
    			("close", "@closeM{(0.00)}"),
    			("datetime", "@datetime"),
			   ]
    fig.add_tools(HoverTool(tooltips=TOOLTIPS, mode='vline'))
                      
    # 添加信号图
    datetime_time = pd.to_datetime(datetime, datetime_format)
    kaicang_time = pd.to_datetime(trade_enter, datetime_format)
    pingcang_time = pd.to_datetime(trade_out, datetime_format)
    if len(trade_enter) != len(trade_out):
         raise Exception('开仓次数不等于平常次数')        
    trade_counts = len(trade_enter):
    # 分笔画交易
    label_x_set = []
    label_y_set = []      
    for i in range(trade_counts):
    	kaicang_time_i = kaicang_time[i]
        pingcang_time_i = pingcang_time[i]
        trade_pos = (kaicang_time_i <= datetime_time <= pingcang_time_i)
        trade_x = tradetime_series[trade_pos].index.tolist()
        trade_x.extend([trade_x[-1], trade_x[0]])
        trade_y = df.close[trade_x].copy()
        trade_y.iloc[-2:] = 0
        if trade_pos > 0:
        	fig.patch(trade_x, trade_y, color=color_buy, alpha=0.1, line_width=1)
        elif trade_pos < 0:
            fig.patch(trade_x, trade_y, color=color_sell, alpha=0.1, line_width=1)
                      
        label_x = (trade_x[-1] + trade_x[-2]) // 2
        label_y = min(df.low)
        label_x_set.append(label_x)
        label_y_set.append(label_y)
    
    # 写收益标签
    try: 
    	profit = record.profit/ abs(trade_num)
    except:
        try:
        	profit = (record.out_price - record.enter_price) * np.sign(trade_num) 
        except:
            profit = [0] * trade_counts
    profit = round(profit, 1)
    label_profit = ['perPrf:{}'.format(temp) for temp in profit]
    color = ['black' if temp>0 else '#8B0000' for temp in profit]
    label_dict = {height: label_x_set,
                  weight: label_y_set,
                  names: label_profit,
                  color: color,
                 }
    source_label = ColumnDataSource(data = label_dict)
    labels = LabelSet(x='height', y='weight', text='names',text_color='color',
              x_offset=-20, y_offset=-30, source=source_label, render_mode='canvas')  
    fig.add_layout(labels)
                      
    # 添加日分割线
    datetime_day_shift1 = datetime_day.shift(1)
    dateBool = [True if today.day != yesterday.day else False for today, yesterday in zip(datetime_day, datetime_day_shift1)]
    datetime_num = len(dateBool)
    vline_x = np.arange(minNum)[dataBool].tolist()
    vline_y_top =  [max(high)] * datetime_num
    vline_y_bottom = [0] * datetime_num
    fig:.setment(vline_x, vline_y_bottom, vline_x, vline_y_top, color='grey', line_width=1, alpha=0.3, line_dash=[6,3])
    
    fig.xaxis.ticker = vline_x
    codestr = 'return datetime[tick]'
    fig.xaxis.formatter = FuncTickFormatter(code=codestr, args={'datetime': datetime})
                      
    # 互动调整
    source = ColumnDataSource({'date':aixs_x, 'high':high, 'low':low})
    codestr = '''
    clearTimeout(window._autoscale_timeout);
    
    var date = source.data.date
        low = source.data.low
        high = source.data.high
        start = cb_obj.start,
        end = cb_obj.end,
        min = Infinity,
        max = -Infinity;
    for (var i=0; i<date.length; ++i){
    	if (start <= date[i] && date[i] <= end){
    		max = Math.max(high[i], max);
    		min = Math.min(low[i], min);
    	}
    }
    var pad = (max - min) * .05;
    
    window._autoscale_timeout = setTimeout(function(){
    	y_range.start = min - pad;
    	y_range.end = max + pad;
    })
    '''
    callback = CustomJS(args={'y_range':fig.y_range, 'source':source}, code=codestr)
    fig.x_range.callback = callback
    show(fig)
                      
    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值