437 lines
13 KiB
Python
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)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|