vnpy/vn.training/SubPlot/分时手数子图.py
2015-10-22 10:40:59 +08:00

437 lines
13 KiB
Python

# -*- coding: utf-8 -*-
import numpy
# import matplotlib.spines as spines
import matplotlib.ticker as ticker
import Public.Public as Public
class 分时手数子图:
def __init__(self, parent, 目标日期, 绘图数据):
'''
'''
self._parent= parent
self._ilogger= Public.IndentLogger(logger=parent._ilogger._logger, indent=parent._ilogger._indent+1)
# 原始数据
任务参数= 绘图数据['任务参数']
# 当日数据
当日数据= 绘图数据['分时数据'][目标日期]
self._本图日期= 目标日期
# self._日期对象= 当日数据['日期对象']
# self._时间常数= 当日数据['时间常数']
# 个股行情
#===================================================================================================
# 分时行情是否存在
self._个股行情有效= 当日数据['个股行情有效']
# 日线数据
self._个股平均成交= 当日数据['个股平均成交'] # 格式: 行情['平均手数']= {Public.计算均值(个股成交量[-n:]) for n in 个股量均参数}
if self._个股行情有效:
# 分时数据
个股分时行情= 当日数据['个股分时行情']
self._个股手数序列= 个股分时行情['手数序列']
self._个股金额序列= 个股分时行情['金额序列']
self._个股备注序列= 个股分时行情['备注序列']
# self._个股上涨标记= 个股分时行情['上涨标记']
# self._个股下跌标记= 个股分时行情['下跌标记']
# self._个股平盘标记= 个股分时行情['平盘标记']
self._个股买盘标记= [True if 备注.startswith('') else False for 备注 in self._个股备注序列]
self._个股卖盘标记= [True if 备注.startswith('') else False for 备注 in self._个股备注序列]
self._个股中性标记= [True if 备注.startswith('') else False for 备注 in self._个股备注序列]
# 分时衍生数据(均线等)
self._个股坐标序列= parent._个股坐标序列
self._个股平均手数= Public.计算均值(序列=[nr for nr in self._个股手数序列 if nr>0])
# TODO: 指数行情
#===================================================================================================
# 横轴参数、纵轴参数
#===================================================================================================
self._横轴参数= parent._横轴参数
self._纵轴参数= None
# 平面对象,留待后面初始化
#===================================================================================================
self._个股布局参数= None
self._指数布局参数= None
self._指数平面= None
self._指数横轴= None
self._指数纵轴= None
self._个股平面= None
self._个股横轴= None
self._个股纵轴= None
def 计算成交步进记录(self):
'''
本函数是 naive 的,只考虑本图。
'''
if self._个股行情有效:
# 决定个股步进值
个股平均手数= self._个股平均手数[0]
个股步进= 25 # 步进代表主坐标的间隔距离
while 个股平均手数/个股步进 > 1.0:
个股步进= 个股步进*2
else:
个股步进= 25
return {'个股步进': 个股步进}
def 计算纵轴参数(self, 步进记录=None):
'''
'''
纵轴参数= {}
# 大小固定
#=======================================================================================
纵轴尺寸= 4.0
纵轴倍率= 0.3
纵轴参数['纵轴倍率']= 纵轴倍率
纵轴参数['纵轴高度']= 纵轴尺寸 * 纵轴倍率
if 步进记录 is None:
步进记录= self.计算成交步进记录()
# 个股部分
#=======================================================================================
步进= 步进记录['个股步进']
# 坐标起点 与 坐标终点
个股坐标起点= 0.0
个股坐标终点= max(self._个股手数序列) if self._个股行情有效 else 步进*纵轴尺寸
纵轴参数['个股坐标起点']= 个股坐标起点
纵轴参数['个股坐标终点']= 个股坐标终点
个股纵轴尺寸= max(个股坐标终点/步进, 纵轴尺寸)
纵轴参数['个股纵轴尺寸']= 个股纵轴尺寸
纵轴参数['个股纵轴高度']= 个股纵轴尺寸 * 纵轴倍率
# 计算 坐标值 与 坐标点
个股主坐标值= [步进 * i for i in range(1, 4)]
个股副坐标值= [(步进/2.0) + 步进*i for i in range(4)]
if 个股副坐标值[-1] > 纵轴参数['个股坐标终点']: del 个股副坐标值[-1]
纵轴参数['个股主坐标值']= 个股主坐标值
纵轴参数['个股副坐标值']= 个股副坐标值
self._纵轴参数= 纵轴参数
def 返回纵轴高度(self):
'''
'''
return self._纵轴参数['纵轴高度']
def 返回指数平面(self):
'''
'''
return self._指数平面
def 平面初始化(self, 图片对象, 子图偏移, 全图大小):
'''
'''
子图横移, \
子图纵移= 子图偏移
全图宽度, \
全图高度= 全图大小
本图宽度= self._横轴参数['横轴宽度']
指数平面高度= self._纵轴参数['纵轴高度'] # XXX: 以后指数平面可以有自己的高度
个股平面高度= self._纵轴参数['个股纵轴高度']
指数布局参数= (子图横移/全图宽度, 子图纵移/全图高度, 本图宽度/全图宽度, 指数平面高度/全图高度)
个股布局参数= (子图横移/全图宽度, 子图纵移/全图高度, 本图宽度/全图宽度, 个股平面高度/全图高度)
self._指数布局参数= 指数布局参数
self._个股布局参数= 个股布局参数
# 指数部分
#=======================================================================================
指数平面= 图片对象.add_axes(指数布局参数, axis_bgcolor='black')
指数平面.set_frame_on(False) # XXX
指数平面.set_axisbelow(True) # 网格线放在底层
指数横轴= 指数平面.get_xaxis()
指数纵轴= 指数平面.get_yaxis()
self._指数平面= 指数平面
self._指数横轴= 指数横轴
self._指数纵轴= 指数纵轴
self.设置指数横轴()
self.设置指数纵轴()
# 个股部分
#=======================================================================================
# XXX: 不用 twinx(),原因见分时价格子图。
个股平面= 图片对象.add_axes(个股布局参数, axis_bgcolor='black')
个股平面.set_frame_on(False) # XXX
个股平面.set_axisbelow(True) # 网格线放在底层
for 方位, 边框 in 个股平面.spines.items():
边框.set_color(None)
个股横轴= 个股平面.get_xaxis()
个股纵轴= 个股平面.get_yaxis()
self._个股平面= 个股平面
self._个股横轴= 个股横轴
self._个股纵轴= 个股纵轴
self.设置个股横轴()
self.设置个股纵轴()
def 设置指数横轴(self):
'''
'''
指数平面= self._指数平面
指数横轴= self._指数横轴
横轴参数= self._横轴参数
指数横轴.grid(True, 'major', color='0.3', linestyle='solid', linewidth=0.2)
指数横轴.grid(True, 'minor', color='0.3', linestyle='dotted', linewidth=0.15)
指数横轴.set_ticks_position('none')
坐标起点= 横轴参数['坐标起点']
坐标终点= 横轴参数['坐标终点']
xMajorLocator= 横轴参数['xMajorLocator']
xMinorLocator= 横轴参数['xMinorLocator']
指数平面.set_xlim(坐标起点, 坐标终点)
指数横轴.set_major_locator(xMajorLocator)
指数横轴.set_minor_locator(xMinorLocator)
for 主坐标 in 指数平面.get_xticklabels(minor=False):
主坐标.set_visible(False)
for 副坐标 in 指数平面.get_xticklabels(minor=True):
副坐标.set_visible(False)
def 设置指数纵轴(self):
'''
'''
指数平面= self._指数平面
指数纵轴= self._指数纵轴
# 指数纵轴.set_label_position('right') # XXX: 不顶用
指数纵轴.set_ticks_position('none')
for 主坐标 in 指数平面.get_yticklabels(minor=False):
主坐标.set_visible(False)
for 副坐标 in 指数平面.get_yticklabels(minor=True):
副坐标.set_visible(False)
def 设置个股横轴(self):
'''
'''
个股平面= self._个股平面
个股横轴= self._个股横轴
横轴参数= self._横轴参数
个股横轴.set_ticks_position('none')
坐标起点= 横轴参数['坐标起点']
坐标终点= 横轴参数['坐标终点']
xMajorLocator= 横轴参数['xMajorLocator']
xMinorLocator= 横轴参数['xMinorLocator']
xMajorFormatter= 横轴参数['xMajorFormatter']
xMinorFormatter= 横轴参数['xMinorFormatter']
个股平面.set_xlim(坐标起点, 坐标终点)
个股横轴.set_major_locator(xMajorLocator)
个股横轴.set_minor_locator(xMinorLocator)
个股横轴.set_major_formatter(xMajorFormatter)
个股横轴.set_minor_formatter(xMinorFormatter)
for 主坐标 in 个股平面.get_xticklabels(minor=False):
主坐标.set_fontsize(5)
主坐标.set_horizontalalignment('right')
主坐标.set_rotation('45')
for 副坐标 in 个股平面.get_xticklabels(minor=True):
副坐标.set_fontsize(4)
副坐标.set_color('blue')
副坐标.set_horizontalalignment('right')
副坐标.set_rotation('45')
def 设置个股纵轴(self):
'''
'''
平面对象= self._个股平面
个股纵轴= self._个股纵轴
纵轴参数= self._纵轴参数
# 个股纵轴.set_label_position('right') # XXX: 不顶用
个股纵轴.set_ticks_position('none')
个股纵轴.grid(True, 'major', color='0.3', linestyle='solid', linewidth=0.2)
个股纵轴.grid(True, 'minor', color='0.3', linestyle='dotted', linewidth=0.15)
坐标起点= 纵轴参数['个股坐标起点']
坐标终点= 纵轴参数['个股坐标终点']
平面对象.set_ylim(坐标起点, 坐标终点)
# 主坐标点
#======================================================================================
主坐标值= 纵轴参数['个股主坐标值']
yMajorLocator= ticker.FixedLocator(numpy.array(主坐标值))
个股纵轴.set_major_locator(yMajorLocator)
# def y_major_formatter(num, pos=None):
# return str(num)
# yMajorFormatter= ticker.FuncFormatter(y_major_formatter)
# 个股纵轴.set_major_formatter(yMajorFormatter)
for 主坐标 in 平面对象.get_yticklabels(minor=False):
主坐标.set_visible(False)
# 副坐标点
#======================================================================================
副坐标值= 纵轴参数['个股副坐标值']
yMinorLocator= ticker.FixedLocator(numpy.array(副坐标值))
个股纵轴.set_minor_locator(yMinorLocator)
# def y_minor_formatter(num, pos=None):
# return str(num)
# yMinorFormatter= ticker.FuncFormatter(y_minor_formatter)
# 个股纵轴.set_minor_formatter(yMinorFormatter)
for 副坐标 in 平面对象.get_yticklabels(minor=True):
副坐标.set_visible(False)
def 绘图(self):
'''
'''
self.绘制辅助标记()
self.绘制个股手数()
def 绘制辅助标记(self):
'''
'''
个股平面= self._个股平面
标注位置组一= self._横轴参数['标注位置组一']
主标手数= self._纵轴参数['个股主坐标值']
副标手数= self._纵轴参数['个股副坐标值']
for 横标 in 标注位置组一:
for 纵标 in 主标手数:
个股平面.text(横标+30.0, 纵标, str(int(纵标)), color='0.3', fontsize=5.0, zorder=0)
for 纵标 in 副标手数:
个股平面.text(横标+30.0, 纵标, str(int(纵标)), color='0.3', fontsize=5.0, zorder=0)
def 绘制个股手数(self):
'''
'''
个股平面= self._个股平面
if self._个股行情有效:
坐标序列= numpy.array(self._个股坐标序列)
手数序列= numpy.array(self._个股手数序列)
序列长度= len(手数序列)
起点序列= numpy.zeros(序列长度)
# 正向标记= numpy.array(self._个股上涨标记)
# 负向标记= numpy.array(self._个股下跌标记)
# 中性标记= numpy.array(self._个股平盘标记)
正向标记= numpy.array(self._个股买盘标记)
负向标记= numpy.array(self._个股卖盘标记)
中性标记= numpy.array(self._个股中性标记)
lwidth, alpha= (0.15, 1.0)
if True in 正向标记:
个股平面.vlines(坐标序列[正向标记], 起点序列[正向标记], 手数序列[正向标记], edgecolor='red', linewidth=lwidth, label='_nolegend_', alpha=alpha)
if True in 负向标记:
个股平面.vlines(坐标序列[负向标记], 起点序列[负向标记], 手数序列[负向标记], edgecolor='green', linewidth=lwidth, label='_nolegend_', alpha=alpha)
if True in 中性标记:
个股平面.vlines(坐标序列[中性标记], 起点序列[中性标记], 手数序列[中性标记], edgecolor='white', linewidth=lwidth, label='_nolegend_', alpha=alpha)
# 绘制平均手数数值(直线)
平均手数= self._个股平均手数[0]
横轴参数= self._横轴参数
横标起点= 横轴参数['坐标起点']
横标终点= 横轴参数['坐标终点']
个股平面.plot([横标起点, 横标终点], [平均手数, 平均手数], '-', color='yellow', linewidth=0.2, alpha=0.7)