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

基本画图简介

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

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

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

from matplotlib.lines import Line2D

from matplotlib.patches import Rectangle

def candlestick_K(ax, quotes, width=0.2, colorup='k', colordown='r', alpha=1):

'''ax:坐标轴quotes:zip(索引, 开盘价, 最高价, 最低价, 收盘价)colorup:上涨Kbar的颜色colordown:下跌kbar的颜色alpha:K线阴影值return:lines:线对象patch:矩阵对象'''

OFFSET = width/2.0

lines = []

patches = []

for q in quotes:

t, open, high, low, close = q[:5]

# 判断该Kbar是涨是跌从而决定颜色

if close >= open:

color = colorup

lower = open

height = close - open

else:

color = colordown

lower = close

height = open - close

# 线图图形

vline = Line2D(

xdata=(t, t), ydata=(low,high),

color=color,

linewidth=0.5,

antialiased=True,

)

# 矩阵图形

rect = Rectangle(

xy = (t-OFFSET, lower),

width = width,

height = height,

facecolor = color,

edgecolor = color,

)

rect.set_alpha(alpha)

lines.append(vline)

patches.append(rect)

ax.add_line(vline)

ax.add_patch(rect)

ax.autoscale_view()

return lines, patches

高级画图简介

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

效果图

代码

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

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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值