commit before merge

commit before merge
This commit is contained in:
msincenselee 2016-07-02 10:20:07 +08:00
parent 2349499747
commit 44046e3a12
18 changed files with 7844 additions and 0 deletions

View File

@ -0,0 +1,480 @@
# -*- coding: utf-8 -*-
import os
import copy
import itertools
import math
import datetime
import logging
import logging.handlers
class IndentLogger:
'''
'''
def __init__(self, logger, indent):
self._logger= logger
self._indent= indent
def indent_levelup(self, level=1):
self._indent= self._indent - level
def indent_leveldown(self, level=1):
self._indent= self._indent + level
def set_indent_level(self, level):
self._indent= level
#---------------------------------------------------------------
def set_critical(self):
self._logger.setLevel(logging.CRITICAL)
def set_error(self):
self._logger.setLevel(logging.ERROR)
def set_warning(self):
self._logger.setLevel(logging.WARNING)
def set_info(self):
self._logger.setLevel(logging.INFO)
def set_debug(self):
self._logger.setLevel(logging.DEBUG)
def set_notset(self):
self._logger.setLevel(logging.NOTSET)
#---------------------------------------------------------------
def critical(self, message):
self._logger.critical('\t' * self._indent + message)
def error(self, message):
self._logger.error('\t' * self._indent + message)
def warning(self, message):
self._logger.warning('\t' * self._indent + message)
def info(self, message):
self._logger.info('\t' * self._indent + message)
def debug(self, message):
self._logger.debug('\t' * self._indent + message)
def noset(self, message):
self._logger.noset('\t' * self._indent + message)
def TempLogger(loggername, filename=None, taskdir=None):
'''
'''
if not taskdir:
taskdir= __dir_tmpfiles__
if not os.path.exists(taskdir):
os.mkdir(taskdir, 0o700)
if not filename:
timestamp= datetime.datetime.now()
filename= os.path.join(taskdir, loggername + '_' + timestamp.strftime('%Y-%m-%d_%H:%M:%S,%f'))
else:
filename= os.path.join(taskdir, filename)
if not os.path.exists(filename):
os.mknod(filename, 0o700)
myformatstr= "%(asctime)s %(levelname)-9s>> %(message)s"
myformatter= logging.Formatter(myformatstr)
myhandler= logging.handlers.RotatingFileHandler(filename=filename, mode='a', encoding='utf-8')
myhandler.setFormatter(myformatter)
mylogger= logging.getLogger(name=loggername)
mylogger.setLevel(level=logging.DEBUG)
mylogger.addHandler(myhandler)
ilogger= IndentLogger(logger=mylogger, indent=0)
return ilogger
def 计算个股换手率(个股行情, 个股股本变更记录):
'''
'''
个股股本变更列表= [rec for rec in 个股股本变更记录 if rec['流通股'] != 0 and rec['变更日期'] <= 个股行情['日期'][-1]]
个股股本变更字典= {}
for rec in 个股股本变更列表:
if rec['变更日期'] in 个股行情['日期']:
个股股本变更字典[rec['变更日期']]= rec
else:
个股股本变更字典[ [ds for ds in 个股行情['日期'] if ds > rec['变更日期']][0] ]= rec
当前流通股= 个股股本变更字典[min(个股股本变更字典.keys())]['流通股']
换手率= []
for ds, vol in zip(个股行情['日期'], 个股行情['成交量']):
if ds in 个股股本变更字典:
当前流通股= 个股股本变更字典[ds]['流通股']
换手率.append( vol*100000/当前流通股 )
个股行情['换手率']= 换手率
def 计算复权行情(个股行情, 均线参数=None):
'''
'''
日期= 个股行情['日期']
复权开盘= copy.copy(个股行情['开盘'])
复权最高= copy.copy(个股行情['最高'])
复权收盘= copy.copy(个股行情['收盘'])
复权最低= copy.copy(个股行情['最低'])
复权开收中= copy.copy(个股行情['开收中'])
复权记录= []
sidx= 1
done= False
while not done:
done= True
for idx, date in enumerate(日期[sidx:], start=sidx):
涨幅= (复权开盘[idx] - 复权收盘[idx-1]) / 复权收盘[idx-1]
if 涨幅 <= -0.12:
复权因子= round(复权收盘[idx-1]/复权开盘[idx], 2)
调整因子= round(复权因子, 1)
if abs(round(复权因子-调整因子, 2)) <= 0.01:
复权因子= 调整因子
复权开盘[:idx]= [nr/复权因子 for nr in 复权开盘[:idx]]
复权最高[:idx]= [nr/复权因子 for nr in 复权最高[:idx]]
复权收盘[:idx]= [nr/复权因子 for nr in 复权收盘[:idx]]
复权最低[:idx]= [nr/复权因子 for nr in 复权最低[:idx]]
复权开收中[:idx]= [nr/复权因子 for nr in 复权开收中[:idx]]
复权记录.append( (date, 复权因子) )
sidx= idx
done= False
break
复权行情= {}
复权行情['复权记录']= 复权记录
复权行情['日期']= copy.copy(日期)
复权行情['开盘']= 复权开盘
复权行情['最高']= 复权最高
复权行情['收盘']= 复权收盘
复权行情['最低']= 复权最低
复权行情['开收中']= 复权开收中
if 均线参数:
复权行情['均线集']= { n : 计算序列加权均线(复权开盘, 复权最高, 复权收盘, 复权最低, n) for n in 均线参数 }
return 复权行情
def 计算序列加权均线(开盘序列, 最高序列, 收盘序列, 最低序列, n):
'''
'''
length= len(开盘序列)
if length < n:
return [None] * length
sumhilo= sum(最高序列[:n]) + sum(最低序列[:n])
sumopen= sum(开盘序列[:n])
sumclose= sum(收盘序列[:n])
输出序列= [ ((sumhilo / 2 + sumopen) / 2 + sumclose) / (2*n) ]
for idx in range(n, length):
sumhilo= sumhilo - 最高序列[idx-n] - 最低序列[idx-n] + 最高序列[idx] + 最低序列[idx]
sumopen= sumopen - 开盘序列[idx-n] + 开盘序列[idx]
sumclose= sumclose - 收盘序列[idx-n] + 收盘序列[idx]
输出序列.append( ((sumhilo / 2 + sumopen) / 2 + sumclose) / (2*n) )
return [None] * (n-1) + 输出序列
def 补全个股行情(完整日期, 个股行情):
'''
'''
代码= 个股行情.pop('代码') if '代码' in 个股行情 else None
日期= 个股行情.pop('日期')
for idx, dstr in enumerate(完整日期):
if dstr not in 日期:
日期.insert(idx, dstr)
for seq in 个股行情.values():
seq.insert(idx, None)
if 代码:
个股行情['代码']= 代码
个股行情['日期']= 日期
def 计算个股行情衍生数据(ilogger, 个股行情, 均线参数=None):
'''
'''
length= len(个股行情['开盘'])
开盘= 个股行情['开盘']
最高= 个股行情['最高']
收盘= 个股行情['收盘']
最低= 个股行情['最低']
if 均线参数 and '均线集' not in 个股行情:
个股行情['均线集']= {n : 计算序列加权均线(开盘, 最高, 收盘, 最低, n) for n in 均线参数}
if '均线集' in 个股行情:
个股行情['均线走势标记集']= {n : [None]*(n-1)+计算走势标记(序列=序列[n-1:]) if length>=n else [None]*length for n, 序列 in 个股行情['均线集'].items()}
开收中= 个股行情['开收中']
开收中线走势标记= 计算走势标记(序列=开收中)
个股行情['开收中线走势标记']= 开收中线走势标记
最小长度= 个股行情.pop('目标偏移') if '目标偏移' in 个股行情 else 0
截去行情头部无效片断(行情数据=个股行情, 最小长度=最小长度)
开收中线走势拐点= 计算走势拐点(目标序列=开收中, 走势标记=开收中线走势标记)
个股行情['开收中线走势拐点']= 开收中线走势拐点
def 截去行情头部无效片断(行情数据, 最小长度):
'''
'''
length= len(行情数据['开盘'])
dirlists= [seq for seq in 行情数据.values() if (type(seq) is list) and (len(seq)==length)]
subkeys= ('均线集', '均线走势标记集')
sublists= [行情数据[key].values() for key in subkeys if key in 行情数据]
cntlist= [seq.count(None) for seq in dirlists]
itor= itertools.chain.from_iterable(seq for seq in sublists)
cntlist.extend( [seq.count(None) for seq in itor] )
截去长度= max(最小长度, max(cntlist))
for seq in dirlists:
del seq[:截去长度]
itor= itertools.chain.from_iterable(seq for seq in sublists)
for seq in itor:
del seq[:截去长度]
def 计算均值(序列):
'''
'''
if not 序列:
return None
长度= len(序列)
均值= sum(序列)/长度
最大值= max(序列)
最小值= min(序列)
标准差= math.sqrt(sum([(nr-均值)**2 for nr in 序列]) / 长度)
return (均值, 最大值, 最小值, 标准差, 长度)
def 计算日内定时均线(价格序列, 调整时间序列, 格点粒度, 间隔点数, 定时点数, 需要规整=True):
'''
'''
日期对象= 调整时间序列[0].date()
datetime_0925= datetime.datetime.combine(日期对象, datetime.time(hour=9, minute=25))
格点序列= [datetime_0925 + datetime.timedelta(seconds=格点粒度*i) for i in range(int((3600*4+1000)/格点粒度))]
if 需要规整:
规整时间序列= []
格点当前位置= 0
for 时间 in 调整时间序列:
while 格点序列[格点当前位置] < 时间:
格点当前位置 += 1
前方格点= 格点序列[格点当前位置]
后方格点= 格点序列[格点当前位置-1]
规整时间= 前方格点 if 前方格点-时间 <= 时间-后方格点 else 后方格点
规整时间序列.append(规整时间)
else:
规整时间序列= 调整时间序列
目标格点序列= [时间 for 时间 in 格点序列 if 时间>=规整时间序列[0] and 时间<=规整时间序列[-1]]
补全价格序列= []
当前价格= 价格序列[0]
for 格点 in 目标格点序列:
if 格点 in 规整时间序列:
当前价格= 价格序列[规整时间序列.index(格点)]
补全价格序列.append(当前价格)
定时均线= {}
for 点数 in 定时点数:
偏移序列= range(点数-1, len(目标格点序列), 间隔点数)
时间序列= [目标格点序列[偏移] for 偏移 in 偏移序列]
均线序列= [ sum(补全价格序列[偏移-点数+1 : 偏移+1]) / 点数 for 偏移 in 偏移序列 ]
定时均线[点数]= {
'时间序列': 时间序列,
'均线序列': 均线序列,
}
return 定时均线
def 计算走势标记(序列):
'''
'''
length= len(序列)
if length < 2:
return ['-'] * length
标记序列= []
当前方向= '/' if 序列[1] > 序列[0] else \
'\\' if 序列[1] < 序列[0] else \
'-'
for idx in range(1, length-1):
sign= '/' if 序列[idx] > 序列[idx-1] and 序列[idx+1] >= 序列[idx] else \
'\\' if 序列[idx] < 序列[idx-1] and 序列[idx+1] <= 序列[idx] else \
'^' if 序列[idx] > 序列[idx-1] and 序列[idx+1] < 序列[idx] else \
'v' if 序列[idx] < 序列[idx-1] and 序列[idx+1] > 序列[idx] else \
'/' if 当前方向 in '/-' and 序列[idx+1] > 序列[idx] else \
'\\' if 当前方向 in '\\-' and 序列[idx+1] < 序列[idx] else \
'^' if 当前方向 == '/' and 序列[idx+1] < 序列[idx] else \
'v' if 当前方向 == '\\' and 序列[idx+1] > 序列[idx] else \
'-'
当前方向= '/' if sign in '/v' else \
'\\' if sign in '\\^' else \
当前方向
标记序列.append(sign)
return ['-'] + 标记序列 + ['/' if 序列[-1] > 序列[-2] else '\\' if 序列[-1] < 序列[-2] else '-']
def 计算走势拐点(目标序列, 走势标记, 扩展=True):
'''
'''
length= len(目标序列)
if length <= 2:
return []
走势拐点= []
for idx, sign in [(i, s) for i, s in enumerate(走势标记) if s in ('^', 'v')]:
拐点记录= {}
拐点记录['偏移']= idx
拐点记录['类型']= sign
if 扩展:
# 计算关键度
拐点记录['关键度']= 计算最新极点关键度(序列=目标序列[:idx+1], 类型=sign)['关键度']
走势拐点.append(拐点记录)
return 走势拐点
def 计算最新极点关键度(序列, 类型=None):
'''
'''
长度= len(序列)
if 类型 is None:
for i in range(1, 长度):
if 序列[-i] > 序列[-(i+1)]:
类型= '^'
break
elif 序列[-i] < 序列[-(i+1)]:
类型= 'v'
break
结果= {
'类型': 类型,
'关键度': 长度,
'偏移': 长度-1,
}
if 长度 < 2:
return 结果
if 类型 == '^':
chunk= [idx for idx, item in enumerate(reversed(序列)) if item > 序列[-1]]
elif 类型 == 'v':
chunk= [idx for idx, item in enumerate(reversed(序列)) if item < 序列[-1]]
else:
return 长度
结果['关键度']= chunk[0] if chunk else 长度
return 结果
def repr_data(data, indent=0):
'''
'''
tlist= (list, dict, set, tuple)
dtype= type(data)
if dtype is list:
head= '\t'*indent + '['
body= ',\n'.join( [repr_data(data=item, indent=indent+1) for item in data] )
tail= '\n' + '\t'*indent + ']'
return head + '\t' + body.lstrip() + tail
elif dtype is dict:
head= '\t'*indent + '{'
body= ',\n'.join( ['\t'*(indent+1) + str(key) + ' :' + ( ('\n' + repr_data(data=val, indent=indent+1)) if type(val) in tlist else ('\t' + str(val)) ) for key, val in sorted(data.items())] )
tail= '\n' + '\t'*indent + '}'
return head + '\t' + body.lstrip() + tail
elif dtype is set:
head= '\t'*indent + '{'
body= ',\n'.join( [repr_data(data=item, indent=indent+1) for item in sorted(data)] )
tail= '\n' + '\t'*indent + '}'
return head + '\t' + body.lstrip() + tail
elif dtype is tuple:
head= '\t'*indent + '('
body= ',\n'.join( [repr_data(data=item, indent=indent+1) for item in data] )
tail= '\n' + '\t'*indent + ')'
return head + '\t' + body.lstrip() + tail
else:
return '\t'*indent + str(data)

View File

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-

View File

@ -0,0 +1,284 @@
# -*- coding: utf-8 -*-
import matplotlib.ticker as ticker
import matplotlib.font_manager as font_manager
__font_properties__= font_manager.FontProperties(fname='/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc')
__横轴倍率__= 10.0 / 230.0
__纵轴倍率__= 0.3
class 公司信息子图:
'''
公司的基本信息
'''
def __init__(self, parent, 绘图数据):
self._parent= parent
self._公司信息= 绘图数据['公司信息']
self._Axes= None
self._横轴尺寸, \
self._纵轴尺寸= self.计算本图尺寸()
self._横轴宽度= self._横轴尺寸 * __横轴倍率__
self._纵轴高度= self._纵轴尺寸 * __纵轴倍率__
def 计算本图尺寸(self):
return (300.0, 1.8)
def 返回本图大小(self):
return (self._横轴尺寸*__横轴倍率__, self._纵轴尺寸*__纵轴倍率__)
def 平面初始化(self, 图片对象, 子图偏移, 全图大小):
子图横移, \
子图纵移= 子图偏移
本图宽度= self._横轴宽度
本图高度= self._纵轴高度
全图宽度, \
全图高度= 全图大小
布局参数= ( 子图横移/全图宽度, 子图纵移/全图高度, 本图宽度/全图宽度, 本图高度/全图高度 )
axes= 图片对象.add_axes(布局参数)
axes.set_frame_on(False)
self._Axes= axes
self.设置横轴参数()
self.设置纵轴参数()
def 设置横轴参数(self):
axes= self._Axes
xaxis= axes.get_xaxis()
# 设定 X 轴坐标的范围
#==================================================================================================================================================
axes.set_xlim(0, self._横轴尺寸)
xaxis.set_major_locator(ticker.NullLocator())
for mal in axes.get_xticklabels(minor=False):
mal.set_visible(False)
for mil in axes.get_xticklabels(minor=True):
mil.set_visible(False)
def 设置纵轴参数(self):
axes= self._Axes
yaxis= axes.get_yaxis()
# 设定 X 轴坐标的范围
#==================================================================================================================================================
axes.set_ylim(0, self._纵轴尺寸)
yaxis.set_major_locator(ticker.NullLocator())
for mal in axes.get_yticklabels(minor=False):
mal.set_visible(False)
for mil in axes.get_yticklabels(minor=True):
mil.set_visible(False)
def 绘图(self):
self.绘制公司代码简称(xbase=0.0, ybase=self._纵轴尺寸)
self.绘制指数简称(xbase=self._横轴尺寸, ybase=self._纵轴尺寸)
self.绘制公司名称(xbase=0.0, ybase=self._纵轴尺寸-0.8)
self.绘制公司地域行业(xbase=48.0, ybase=self._纵轴尺寸)
self.绘制公司主营业务(xbase=48.0, ybase=self._纵轴尺寸)
self.绘制公司简介(xbase=90.0, ybase=self._纵轴尺寸)
self.绘制公司分类信息(xbase=165.0, ybase=self._纵轴尺寸)
def 绘制公司代码简称(self, xbase, ybase):
'''
交易代码公司简称
'''
txtstr= self._公司信息['个股代码'] + ' ' + self._公司信息['个股简称']
label= self._Axes.text(xbase, ybase, txtstr, fontproperties=__font_properties__, verticalalignment='top', horizontalalignment='left')
label.set_fontsize(16.0)
def 绘制指数简称(self, xbase, ybase):
txtstr= self._公司信息['指数简称']
label= self._Axes.text(xbase, ybase, txtstr, fontproperties=__font_properties__, verticalalignment='top', horizontalalignment='right')
label.set_fontsize(16.0)
def 绘制公司名称(self, xbase, ybase):
'''
曾用名全名英文名
'''
txtstr= self._公司信息['基本情况']['曾用名']
txtlist= txtstr.split('->')
if len(txtlist) > 15:
txtstr= ' -> '.join(txtlist[:5]) + ' ->\n' + ' -> '.join(txtlist[5:10]) + ' ->\n' + ' -> '.join(txtlist[10:15]) + ' ->\n' + ' -> '.join(txtlist[15:]) + '\n'
elif len(txtlist) > 10:
txtstr= ' -> '.join(txtlist[:5]) + ' ->\n' + ' -> '.join(txtlist[5:10]) + ' ->\n' + ' -> '.join(txtlist[10:]) + '\n'
elif len(txtlist) > 5:
txtstr= ' -> '.join(txtlist[:5]) + ' ->\n' + ' -> '.join(txtlist[5:]) + '\n'
else:
txtstr= ' -> '.join(txtlist) + '\n'
txtstr += self._公司信息['基本情况']['公司名称'] + '\n'
txtstr += self._公司信息['基本情况']['英文名称']
label= self._Axes.text(xbase, ybase, txtstr, fontproperties=__font_properties__, verticalalignment='top', horizontalalignment='left')
label.set_fontsize(4.5)
def 绘制公司地域行业(self, xbase, ybase):
'''
地域所属行业上市日期
'''
txtstr= self._公司信息['公司概况']['区域'] + ' ' + self._公司信息['公司概况']['所属行业'] + ' ' + self._公司信息['发行相关']['上市日期']
label= self._Axes.text(xbase, ybase, txtstr, fontproperties=__font_properties__, verticalalignment='top', horizontalalignment='left')
label.set_fontsize(6.5)
def 绘制公司主营业务(self, xbase, ybase):
'''
主营业务
'''
# 查找表: (<文字长度>, <每行字数>, <字体大小>, <Y轴偏移量>)
lookups= (
(20, 10, 12.0, 0.5),
(45, 15, 8.2, 0.5),
(80, 20, 6.2, 0.5),
(125, 25, 5.0, 0.5),
(180, 30, 4.1, 0.5),
(245, 35, 3.5, 0.4),
(999999, 37, 3.4, 0.4)
)
txtstr= self._公司信息['基本情况']['主营业务']
length= len(txtstr)
for sizelimit, linelimit, fontsize, yshift in lookups:
if length <= sizelimit:
txtstr= '\n'.join([txtstr[linelimit*idx : linelimit*(idx+1)] for idx in range(length//linelimit + 1)])
fsize= fontsize
ycoord= ybase - yshift
break
label= self._Axes.text(xbase, ycoord, txtstr, fontproperties=__font_properties__, verticalalignment='top', horizontalalignment='left', color='blue')
label.set_fontsize(fsize)
def 绘制公司简介(self, xbase, ybase):
'''
公司简介
'''
# 查找表: (<文字长度>, <每行字数>, <字体大小>)
lookups= (
(150, 30, 7.0),
(240, 40, 5.6),
(329, 47, 4.8),
(432, 54, 4.2),
(576, 64, 3.5),
(670, 67, 3.4),
(792, 72, 3.1),
(960, 80, 2.8),
(1222, 94, 2.4),
(1428, 102, 2.26),
(1620, 108, 2.12),
(1938, 114, 2.00),
(999999, 130, 1.75)
)
txtstr= self._公司信息['公司概况']['公司简介'] # 26 ~ 2600 字符
length= len(txtstr)
for sizelimit, linelimit, fontsize in lookups:
if length <= sizelimit:
txtstr= '\n'.join([txtstr[linelimit*idx : linelimit*(idx+1)] for idx in range(length//linelimit + 1)])
fsize= fontsize
break
label= self._Axes.text(xbase, ybase, txtstr, fontproperties=__font_properties__, verticalalignment='top', horizontalalignment='left')
label.set_fontsize(fsize)
def 绘制公司分类信息(self, xbase, ybase):
'''
行业板块信息
'''
infolist= self._公司信息['行业板块']
for idx in range(len(infolist)//10 + 1):
txtstr= '\n'.join(infolist[10*idx : 10*(idx+1)])
if not txtstr:
break
xcoord= xbase + 25.0*idx
label= self._Axes.text(xcoord, ybase, txtstr, fontproperties=__font_properties__, verticalalignment='top', horizontalalignment='left', color='blue')
label.set_fontsize(3.4)

View File

@ -0,0 +1,580 @@
# -*- coding: utf-8 -*-
import datetime
import numpy
import math
import matplotlib.ticker as ticker
import matplotlib.font_manager as font_manager
import Public.Public as Public
__font_properties__= font_manager.FontProperties(fname='/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc')
__纵轴倍率__= 3.0
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._横轴参数= parent._横轴参数
self._纵轴参数= None # XXX: 现在还不能计算,因为上下限与其他子图有关。
self._坐标底数= 1.1
# 个股行情
#===================================================================================================
# 分时行情是否存在
self._个股行情有效= 当日数据['个股行情有效']
# 日线数据
self._个股当日开盘= 当日数据['个股当日开盘']
self._个股当日最高= 当日数据['个股当日最高']
self._个股前日收盘= 当日数据['个股前日收盘'] # 前日收盘可能是 None
self._个股当日最低= 当日数据['个股当日最低']
if self._个股行情有效:
# 分时数据
个股分时行情= 当日数据['个股分时行情']
self._个股价格序列= 个股分时行情['价格序列']
# 分时行情坐标序列
self._个股调整时间= parent._个股调整时间
self._个股坐标序列= parent._个股坐标序列
# 分时衍生数据(均线等)
self._分时格点粒度= 格点粒度= 任务参数['分时格点粒度']
间隔点数= 任务参数['均线间隔点数']
定时点数= 任务参数['均线定时点数']
self._个股定时均线= Public.计算日内定时均线( \
价格序列=self._个股价格序列, \
调整时间序列=self._个股调整时间, \
格点粒度=格点粒度, \
间隔点数=间隔点数, \
定时点数=定时点数, \
需要规整=False \
)
for 均线 in self._个股定时均线.values():
均线['坐标序列']= self._parent.计算调整时间序列坐标(调整时间序列=均线['时间序列'])
均线['走势标记']= Public.计算走势标记(序列=均线['均线序列'])
# TODO: 指数行情
#===================================================================================================
# 日线数据
self._指数当日开盘= 当日数据['指数当日开盘']
self._指数当日最高= 当日数据['指数当日最高']
self._指数前日收盘= 当日数据['指数前日收盘'] # 前日收盘可能是 None
self._指数当日最低= 当日数据['指数当日最低']
# 平面对象,留待后面初始化
#===================================================================================================
self._布局参数= None
self._指数平面= None
self._指数横轴= None
self._指数纵轴= None
self._个股平面= None
self._个股横轴= None
self._个股纵轴= None
def 计算纵轴坐标区间(self):
'''
'''
个股开盘= self._个股当日开盘
指数开盘= self._指数当日开盘
个股最高= max(self._个股前日收盘, self._个股当日最高) * 1.01 if self._个股前日收盘 else self._个股当日最高 * 1.01
个股最低= min(self._个股前日收盘, self._个股当日最低) * 0.99 if self._个股前日收盘 else self._个股当日最低 * 0.99
指数最高= self._指数当日最高 * 1.01
指数最低= self._指数当日最低 * 0.99
个股综合最高= max(个股最高, 指数最高*个股开盘/指数开盘)
个股综合最低= min(个股最低, 指数最低*个股开盘/指数开盘)
指数综合最高= max(指数最高, 个股最高*指数开盘/个股开盘)
指数综合最低= min(指数最低, 个股最低*指数开盘/个股开盘)
纵标区间= {}
纵标区间['个股最高']= 个股综合最高
纵标区间['个股最低']= 个股综合最低
纵标区间['指数最高']= 指数综合最高
纵标区间['指数最低']= 指数综合最低
return 纵标区间
def 计算纵轴参数(self, 坐标区间=None):
'''
'''
def 计算个股坐标参数(基准价格, 坐标起点, 坐标终点):
'''
'''
# 计算主坐标值
步进= 基准价格 / 100.0
主坐标值= [基准价格]
当前价格= 基准价格 + 步进
while 当前价格 < 坐标终点:
主坐标值.append( round(当前价格, -1) )
当前价格= 当前价格 + 步进
当前价格= 基准价格 - 步进
while 当前价格 > 坐标起点:
主坐标值.append( round(当前价格, -1) )
当前价格= 当前价格 - 步进
主坐标值= sorted(set(主坐标值))
# 计算副坐标值
步进= max(round(基准价格*0.01/4.0, -1), 10.0) # 选择一个步进值10.0 代表最小刻度: 0.01元
副坐标值= []
当前价格= round(坐标起点+5.0, -1)
while 当前价格 < 坐标终点:
副坐标值.append(当前价格)
当前价格= 当前价格 + 步进
副坐标值= [价格 for 价格 in 副坐标值 if 价格 not in 主坐标值]
坐标参数= {
'个股主坐标值': 主坐标值,
'个股副坐标值': 副坐标值,
}
return 坐标参数
if 坐标区间 is None:
坐标区间= self.计算纵轴坐标区间()
个股坐标起点= 坐标区间['个股最低']
个股坐标终点= 坐标区间['个股最高']
纵轴尺寸= math.log(个股坐标终点, self._坐标底数) - math.log(个股坐标起点, self._坐标底数)
纵轴高度= 纵轴尺寸 * __纵轴倍率__
纵轴参数= {}
纵轴参数['个股坐标起点']= 个股坐标起点
纵轴参数['个股坐标终点']= 个股坐标终点
纵轴参数['纵轴尺寸']= 纵轴尺寸
纵轴参数['纵轴高度']= 纵轴高度
# 指数部分,暂时这样
纵轴参数['指数坐标起点']= 坐标区间['指数最低']
纵轴参数['指数坐标终点']= 坐标区间['指数最高']
基准价格= self._个股前日收盘 if self._个股前日收盘 else self._个股当日开盘
纵轴参数['基准价格']= 基准价格
纵轴参数.update( 计算个股坐标参数(基准价格=基准价格, 坐标起点=个股坐标起点, 坐标终点=个股坐标终点) )
self._纵轴参数= 纵轴参数
def 返回纵轴高度(self):
'''
'''
return self._纵轴参数['纵轴高度']
def 返回指数平面(self):
'''
'''
return self._指数平面
def 平面初始化(self, 图片对象, 子图偏移, 全图大小, sharex):
'''
'''
# 计算自身的布局参数
子图横移, \
子图纵移= 子图偏移
全图宽度, \
全图高度= 全图大小
本图宽度= self._横轴参数['横轴宽度']
本图高度= self._纵轴参数['纵轴高度']
布局参数= (子图横移/全图宽度, 子图纵移/全图高度, 本图宽度/全图宽度, 本图高度/全图高度)
self._布局参数= 布局参数
坐标底数= self._坐标底数
# 指数部分
#=======================================================================================
# XXX: 指数与个股布局参数一样的话label 一定要设成不一样,见 add_axes() 官方文档。
指数平面= 图片对象.add_axes(布局参数, axis_bgcolor='none', label='指数平面', sharex=sharex)
指数平面.set_frame_on(False)
指数平面.set_axisbelow(True) # 网格线放在底层
指数平面.set_yscale('log', basey=坐标底数) # 使用对数坐标
指数横轴= 指数平面.get_xaxis()
指数纵轴= 指数平面.get_yaxis()
self._指数平面= 指数平面
self._指数横轴= 指数横轴
self._指数纵轴= 指数纵轴
self.设置指数横轴()
self.设置指数纵轴()
# 个股部分
#=======================================================================================
# 个股平面= 指数平面.twinx() # XXX: twinx 有问题,使用了以后指数的 ticks 就关不掉。可能是 bug
# XXX: 指数与个股布局参数一样的话label 一定要设成不一样,见 add_axes() 官方文档。
个股平面= 图片对象.add_axes(布局参数, axis_bgcolor='none', label='个股平面', sharex=sharex)
个股平面.set_frame_on(False)
个股平面.set_axisbelow(True) # 网格线放在底层
个股平面.set_yscale('log', basey=坐标底数) # 使用对数坐标
个股横轴= 个股平面.get_xaxis()
个股纵轴= 个股平面.get_yaxis()
self._个股平面= 个股平面
self._个股横轴= 个股横轴
self._个股纵轴= 个股纵轴
self.设置个股横轴()
self.设置个股纵轴()
def 设置指数横轴(self):
'''
'''
指数平面= self._指数平面
指数横轴= self._指数横轴
横轴参数= self._横轴参数
指数横轴.set_ticks_position('none')
#=================================================================================
坐标起点= 横轴参数['坐标起点']
坐标终点= 横轴参数['坐标终点']
xMajorLocator= 横轴参数['xMajorLocator']
xMinorLocator= 横轴参数['xMinorLocator']
xMajorFormatter= 横轴参数['xMajorFormatter']
xMinorFormatter= 横轴参数['xMinorFormatter']
指数横轴.grid(True, 'major', color='0.3', linestyle='solid', linewidth=0.2)
指数横轴.grid(True, 'minor', color='0.3', linestyle='dotted', linewidth=0.15)
指数平面.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._指数纵轴
纵轴参数= self._纵轴参数
坐标起点= 纵轴参数['指数坐标起点']
坐标终点= 纵轴参数['指数坐标终点']
指数平面.set_ylim(坐标起点, 坐标终点)
# 指数纵轴.set_label_position('left') # 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')
坐标起点= 横轴参数['坐标起点']
坐标终点= 横轴参数['坐标终点']
个股平面.set_xlim(坐标起点, 坐标终点)
# xMajorLocator= 横轴参数['xMajorLocator']
# xMinorLocator= 横轴参数['xMinorLocator']
# xMajorFormatter= 横轴参数['xMajorFormatter']
# xMinorFormatter= 横轴参数['xMinorFormatter']
# 个股横轴.grid(True, 'major', color='0.3', linestyle='solid', linewidth=0.2)
# 个股横轴.grid(True, 'minor', color='0.3', linestyle='dotted', linewidth=0.15)
# 个股横轴.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._个股纵轴
纵轴参数= self._纵轴参数
个股纵轴.set_ticks_position('none')
坐标起点= 纵轴参数['个股坐标起点']
坐标终点= 纵轴参数['个股坐标终点']
主坐标值= 纵轴参数['个股主坐标值']
副坐标值= 纵轴参数['个股副坐标值']
# 个股纵轴.set_label_position('right') # XXX: 不顶用
个股纵轴.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(round(num/1000.0, 3))
# 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(round(num/1000.0, 3))
# yMinorFormatter= ticker.FuncFormatter(y_minor_formatter)
# 个股纵轴.set_minor_formatter(yMinorFormatter)
for 副坐标 in 个股平面.get_yticklabels(minor=True):
副坐标.set_visible(False)
def 绘图(self):
'''
'''
self.绘制辅助标记()
self.绘制个股价格走势()
if self._个股行情有效:
self.绘制个股价格均线()
def 绘制个股价格走势(self):
'''
'''
个股平面= self._个股平面
# 特征价格
横标起点, 横标终点= self._横轴参数['坐标起点'], self._横轴参数['坐标终点']
if self._个股前日收盘:
个股平面.plot((横标起点, 横标终点), (self._个股前日收盘, self._个股前日收盘), '-', color='lightblue', linewidth=0.7, alpha=0.5)
个股平面.plot((横标起点, 横标终点), (self._个股当日开盘, self._个股当日开盘), '-', color='yellow', linewidth=0.7, alpha=0.5)
个股平面.plot((横标起点, 横标终点), (self._个股当日最高, self._个股当日最高), '-', color='red', linewidth=0.7, alpha=0.3)
个股平面.plot((横标起点, 横标终点), (self._个股当日最低, self._个股当日最低), '-', color='green', linewidth=0.7, alpha=0.5)
if self._个股行情有效:
坐标阵列= numpy.array(self._个股坐标序列)
价格阵列= numpy.array(self._个股价格序列)
# 价格走势
个股平面.plot(坐标阵列, 价格阵列, 'o-', color='white', linewidth=0.15, label='_nolegend_', \
markersize=0.3, markeredgecolor='white', markeredgewidth=0.1, alpha=1.0)
def 绘制个股价格均线(self):
'''
'''
个股平面= self._个股平面
格点粒度= self._分时格点粒度
定时均线= self._个股定时均线
for 类别, 均线 in 定时均线.items():
坐标序列= 均线['坐标序列']
均线序列= 均线['均线序列']
走势标记= 均线['走势标记']
# 绘制均线
坐标阵列= numpy.array(坐标序列)
均线阵列= numpy.array(均线序列)
lcolor= 'yellow' if 类别*格点粒度 <= 300 else \
'cyan' if 类别*格点粒度 <= 600 else \
'magenta'
个股平面.plot(坐标阵列, 均线阵列, 'o-', color=lcolor, linewidth=0.1, label='_nolegend_', \
markersize=0.2, markeredgecolor=lcolor, markeredgewidth=0.1, alpha=0.7)
# 绘制均线拐点
底点阵列= numpy.array([均值 if 标记=='v' else None for 均值, 标记 in zip(均线序列, 走势标记)])
顶点阵列= numpy.array([均值 if 标记=='^' else None for 均值, 标记 in zip(均线序列, 走势标记)])
个股平面.plot(坐标阵列, 底点阵列, '^', color=lcolor, label='均线底点', \
markersize=1.5, markeredgecolor=lcolor, markeredgewidth=0.0, alpha=1.0)
个股平面.plot(坐标阵列, 顶点阵列, 'v', color=lcolor, label='均线顶点', \
markersize=1.5, markeredgecolor=lcolor, markeredgewidth=0.0, alpha=1.0)
def 绘制辅助标记(self):
'''
'''
指数平面= self._指数平面
个股平面= self._个股平面
横轴参数= self._横轴参数
纵轴参数= self._纵轴参数
公司信息= self._公司信息
目标日期= self._目标日期
指数纵标起点= 纵轴参数['指数坐标起点']
指数纵标终点= 纵轴参数['指数坐标终点']
个股纵标起点= 纵轴参数['个股坐标起点']
个股纵标终点= 纵轴参数['个股坐标终点']
标注位置= 横轴参数['标注位置']
# 画公司名称、目标日期
#============================================================================================================
标注内容= 公司信息['个股代码'] + ' ' + 公司信息['个股简称'] + ' ' + 目标日期
纵标= (指数纵标起点*指数纵标终点)**0.5
指数平面.text( 标注位置['09:30'], 纵标, 标注内容, fontproperties=__font_properties__, \
color='0.3', fontsize=27, alpha=0.3, verticalalignment='center')
指数平面.text( 标注位置['15:00']-300.0, 纵标, 标注内容, fontproperties=__font_properties__, \
color='0.3', fontsize=27, alpha=0.3, horizontalalignment='right', verticalalignment='center')
# 画时间标记
#============================================================================================================
# 15 分钟主时间点
for iy in [指数纵标起点*1.004, 指数纵标终点*0.993]:
for ix, 时间, 表示 in zip(横轴参数['主坐标值'], 横轴参数['主标时间'], 横轴参数['主标表示']):
标注= 指数平面.text(ix, iy, 表示, color='0.3', fontsize=8, zorder=0)
if 表示 in ('11:30', '15:00'): 标注.set_horizontalalignment('right')
# 5 分钟副时间点
for iy in [指数纵标起点*1.001, 指数纵标终点*0.997]:
for ix, 时间, 表示 in zip(横轴参数['副坐标值'], 横轴参数['副标时间'], 横轴参数['副标表示']):
指数平面.text(ix, iy, 表示, color='0.3', fontsize=5, zorder=0)
# 画价格标记
#============================================================================================================
标注位置组一= 横轴参数['标注位置组一']
主标价格= [nr for nr in 纵轴参数['个股主坐标值'] if nr > 个股纵标起点*1.01 and nr < 个股纵标终点*0.99]
副标价格= [nr for nr in 纵轴参数['个股副坐标值'] if nr > 个股纵标起点*1.01 and nr < 个股纵标终点*0.99]
for 横标 in 标注位置组一:
for 纵标 in 主标价格:
个股平面.text(横标-30.0, 纵标, str(纵标/1000.0), color='0.3', fontsize=3.0, horizontalalignment='right', zorder=0)
for 纵标 in 副标价格:
个股平面.text(横标+30.0, 纵标, str(纵标/1000.0), color='0.3', fontsize=3.0, zorder=0)
# 画档位标记
#============================================================================================================
标注位置组二= 横轴参数['标注位置组二']
基准价格= 纵轴参数['基准价格']
正向档位= [nr for nr in 纵轴参数['个股主坐标值'] if nr >= 基准价格 and nr < 个股纵标终点*0.99]
负向档位= list(reversed([nr for nr in 纵轴参数['个股主坐标值'] if nr < 基准价格 and nr > 个股纵标起点]))
for 横标 in 标注位置组二:
for 档位, 纵标 in enumerate(正向档位, start=1):
个股平面.text(横标+30.0, 纵标*1.001, str(档位), color='red', fontsize=25, alpha=0.17, zorder=0)
for 档位, 纵标 in enumerate(负向档位, start=1):
个股平面.text(横标+30.0, 纵标*1.001, str(档位), color='green', fontsize=25, alpha=0.2, zorder=0)

View File

@ -0,0 +1,436 @@
# -*- 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)

View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
class 实盘价格子图:
'''
'''
def __init__(self, parent, 绘图数据):
'''
'''
pass

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
class 实盘手数子图:
'''
'''
def __init__(self, parent, 绘图数据, 价格子图):
'''
'''
pass

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,488 @@
# -*- coding: utf-8 -*-
import itertools
import numpy
import matplotlib.spines as spines
import matplotlib.ticker as ticker
import matplotlib.font_manager as font_manager
import Public.Public as Public
__color_gold__= '#FDDB05'
__font_properties__= font_manager.FontProperties(fname='/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc')
__横轴倍率__= 10.0 / 230.0
__纵轴倍率__= 0.3
class 日线换手子图:
def __init__(self, parent, 绘图数据):
'''
'''
self._parent= parent
self._ilogger= Public.IndentLogger(logger=parent._ilogger._logger, indent=parent._ilogger._indent+1)
# 原始数据
self._任务参数= 绘图数据['任务参数']
# 行情数据
日线价格子图= parent._日线价格子图
日线行情= 日线价格子图.返回目标日线数据()
self._目标指数日线= 日线行情['目标指数日线']
self._目标绘图日线= 日线行情['目标绘图日线']
self._目标指数换手= self._目标指数日线['换手率']
self._目标绘图换手= self._目标绘图日线['换手率']
# 行情衍生数据
附加行情= 日线价格子图.返回行情附加数据()
self._横轴坐标序列= 附加行情['横轴坐标序列']
self._目标行情长度= 附加行情['目标行情长度']
self._目标指数上涨= 附加行情['目标指数上涨']
self._目标指数下跌= 附加行情['目标指数下跌']
self._目标指数平盘= 附加行情['目标指数平盘']
self._目标绘图上涨= 附加行情['目标绘图上涨']
self._目标绘图下跌= 附加行情['目标绘图下跌']
self._目标绘图平盘= 附加行情['目标绘图平盘']
# 平面对象
self._指数平面= None
self._指数横轴= None
self._指数纵轴= None
self._个股平面= None
self._个股横轴= None
self._个股纵轴= None
# 横轴参数、纵轴参数
self._横轴参数= 日线价格子图.返回横轴参数()
self._纵轴参数= self.计算纵轴参数()
def 计算纵轴参数(self):
'''
'''
def _compute_torange(maxto, tostep):
return int(round((maxto + tostep/2.0 - 1) / float(tostep), 0))
def _compute_tostep(maxto):
'''
maxto 换手率 最大值返回每格单位最小 500, 代表 0.5%以及格数
'''
for i in range(9):
if maxto > (4 * 500 * (2**i)): # 换手率最大是 100000, 代表 100%
continue
else:
tostep= 500 * (2**i)
torange= _compute_torange(maxto, tostep)
break
return (tostep, torange)
指数换手= self._目标指数换手
个股换手= self._目标绘图换手
个股最大= max( [nr for nr in 个股换手 if nr is not None] )
个股步进, \
个股格数= _compute_tostep(个股最大)
指数最大= max(指数换手)
指数步进, \
指数格数= _compute_tostep(指数最大)
纵轴格数= max(个股格数, 指数格数)
纵轴尺寸= 纵轴格数 * 1.0
指数坐标终点= 指数步进 * 纵轴格数
个股坐标终点= 个股步进 * 纵轴格数
指数主坐标值= [指数步进*i for i in range(纵轴格数)]
指数副坐标值= list( itertools.chain.from_iterable( mi for mi in [[ma + (指数步进/4.0)*i for i in range(1, 4)] for ma in 指数主坐标值] ) )
个股主坐标值= [个股步进*i for i in range(纵轴格数)]
个股副坐标值= list( itertools.chain.from_iterable( mi for mi in [[ma + (个股步进/4.0)*i for i in range(1, 4)] for ma in 个股主坐标值] ) )
纵轴参数= {
'指数步进': 指数步进,
'个股步进': 个股步进,
'纵轴格数': 纵轴格数,
'纵轴尺寸': 纵轴尺寸,
'纵轴高度': 纵轴尺寸 * __纵轴倍率__,
'指数坐标终点': 指数坐标终点,
'个股坐标终点': 个股坐标终点,
'指数主坐标值': 指数主坐标值,
'指数副坐标值': 指数副坐标值,
'个股主坐标值': 个股主坐标值,
'个股副坐标值': 个股副坐标值,
}
return 纵轴参数
def 返回纵轴高度(self):
'''
'''
return self._纵轴参数['纵轴高度']
def 平面初始化(self, 图片对象, 子图偏移, 全图大小, sharex):
'''
'''
# 计算 布局参数
#==================================================================================================================================================
子图横移, \
子图纵移= 子图偏移
全图宽度, \
全图高度= 全图大小
本图宽度= self._横轴参数['横轴宽度']
本图高度= self._纵轴参数['纵轴高度']
布局参数= ( 子图横移/全图宽度, 子图纵移/全图高度, 本图宽度/全图宽度, 本图高度/全图高度 )
# 指数部分
#==================================================================================================================================================
指数平面= 图片对象.add_axes(布局参数, axis_bgcolor='black', sharex=sharex)
指数平面.set_axisbelow(True) # 网格线放在底层
for 方位, 边框 in 指数平面.spines.items(): # 方位: 'left' | 'right' | 'top' | 'bottom'
边框.set_color(__color_gold__)
指数横轴= 指数平面.get_xaxis()
指数纵轴= 指数平面.get_yaxis()
self._指数平面= 指数平面
self._指数横轴= 指数横轴
self._指数纵轴= 指数纵轴
self.设置指数横轴()
self.设置指数纵轴()
# 个股部分
#==================================================================================================================================================
个股平面= 指数平面.twinx()
个股平面.set_axis_bgcolor('black')
个股平面.set_axisbelow(True) # 网格线放在底层
# for 方位, 边框 in 个股平面.spines.items(): # 方位: 'left' | 'right' | 'top' | 'bottom'
# 边框.set_color(__color_gold__)
个股横轴= 个股平面.get_xaxis()
个股纵轴= 个股平面.get_yaxis()
self._个股平面= 个股平面
self._个股横轴= 个股横轴
self._个股纵轴= 个股纵轴
self.设置个股横轴()
self.设置个股纵轴()
def 设置指数横轴(self):
'''
'''
任务参数= 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_xlim(坐标起点, 坐标终点)
xMajorLocator= 横轴参数['xMajorLocator']
xMinorLocator= 横轴参数['xMinorLocator']
xMajorFormatter= 横轴参数['xMajorFormatter']
xMinorFormatter= 横轴参数['xMinorFormatter']
指数横轴.set_major_locator(xMajorLocator)
指数横轴.set_minor_locator(xMinorLocator)
指数横轴.set_major_formatter(xMajorFormatter)
指数横轴.set_minor_formatter(xMinorFormatter)
if 任务参数['绘制实盘']:
# 设为不可见
for 主坐标 in axes.get_xticklabels(minor=False):
主坐标.set_visible(False)
for 副坐标 in axes.get_xticklabels(minor=True):
副坐标.set_visible(False)
else:
for 主坐标 in 指数平面.get_xticklabels(minor=False):
主坐标.set_fontsize(4)
主坐标.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._纵轴参数
主坐标值= 纵轴参数['指数主坐标值']
副坐标值= 纵轴参数['指数副坐标值']
坐标终点= 纵轴参数['指数坐标终点']
指数纵轴.grid(True, 'major', color='0.3', linestyle='solid', linewidth=0.2)
指数纵轴.grid(True, 'minor', color='0.3', linestyle='solid', linewidth=0.1)
平面对象.set_ylim(0, 坐标终点)
yMajorLocator= ticker.FixedLocator(numpy.array(主坐标值))
def y_major_formatter(num, pos=None):
return str(round(num/1000.0, 2)) + '%'
yMajorFormatter= ticker.FuncFormatter(y_major_formatter)
指数纵轴.set_major_locator(yMajorLocator)
指数纵轴.set_major_formatter(yMajorFormatter)
for 主坐标 in 平面对象.get_yticklabels(minor=False):
主坐标.set_font_properties(__font_properties__)
主坐标.set_fontsize(5) # 这个必须放在前一句后面,否则作用会被覆盖
yMinorLocator= ticker.FixedLocator(numpy.array(副坐标值))
def y_minor_formatter(num, pos=None):
return str(round(num/1000.0, 3)) + '%'
yMinorFormatter= ticker.FuncFormatter(y_minor_formatter)
指数纵轴.set_minor_locator(yMinorLocator)
指数纵轴.set_minor_formatter(yMinorFormatter)
for 副坐标 in 平面对象.get_yticklabels(minor=True):
副坐标.set_font_properties(__font_properties__)
副坐标.set_fontsize(4) # 这个必须放在前一句后面,否则作用会被覆盖
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_xlim(坐标起点, 坐标终点)
xMajorLocator= 横轴参数['xMajorLocator']
xMinorLocator= 横轴参数['xMinorLocator']
个股横轴.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._个股纵轴
纵轴参数= self._纵轴参数
主坐标值= 纵轴参数['个股主坐标值']
副坐标值= 纵轴参数['个股副坐标值']
坐标终点= 纵轴参数['个股坐标终点']
# 坐标线
# 个股纵轴.grid(True, 'major', color='0.3', linestyle='solid', linewidth=0.2)
# 个股纵轴.grid(True, 'minor', color='0.3', linestyle='solid', linewidth=0.1)
# 设置坐标范围
平面对象.set_ylim(0, 坐标终点)
# 主坐标点
yMajorLocator= ticker.FixedLocator(numpy.array(主坐标值))
def y_major_formatter(num, pos=None):
return str(round(num/1000.0, 2)) + '%'
yMajorFormatter= ticker.FuncFormatter(y_major_formatter)
个股纵轴.set_major_locator(yMajorLocator)
个股纵轴.set_major_formatter(yMajorFormatter)
for 主坐标 in 平面对象.get_yticklabels(minor=False):
主坐标.set_font_properties(__font_properties__)
主坐标.set_fontsize(5) # 这个必须放在前一句后面,否则作用会被覆盖
# 副坐标点
yMinorLocator= ticker.FixedLocator(numpy.array(副坐标值))
def y_minor_formatter(num, pos=None):
return str(round(num/1000.0, 3)) + '%'
yMinorFormatter= ticker.FuncFormatter(y_minor_formatter)
个股纵轴.set_minor_locator(yMinorLocator)
个股纵轴.set_minor_formatter(yMinorFormatter)
for 副坐标 in 平面对象.get_yticklabels(minor=True):
副坐标.set_font_properties(__font_properties__)
副坐标.set_fontsize(4) # 这个必须放在前一句后面,否则作用会被覆盖
def 绘制指数换手(self):
'''
'''
横轴坐标序列= self._横轴坐标序列
平面对象= self._指数平面
行情长度= self._目标行情长度
上涨序列= self._目标指数上涨
下跌序列= self._目标指数下跌
平盘序列= self._目标指数平盘
换手序列= self._目标指数换手
换手阵列= numpy.array(换手序列)
起点阵列= numpy.zeros(行情长度)
lwidth, alpha= (0.7, 0.5)
if True in 上涨序列:
平面对象.vlines(横轴坐标序列[上涨序列], 起点阵列[上涨序列], 换手阵列[上涨序列], edgecolor='0.7', linewidth=lwidth, label='_nolegend_', alpha=alpha)
if True in 下跌序列:
平面对象.vlines(横轴坐标序列[下跌序列], 起点阵列[下跌序列], 换手阵列[下跌序列], edgecolor='0.3', linewidth=lwidth, label='_nolegend_', alpha=alpha)
if True in 平盘序列:
平面对象.vlines(横轴坐标序列[平盘序列], 起点阵列[平盘序列], 换手阵列[平盘序列], edgecolor='0.7', linewidth=lwidth, label='_nolegend_', alpha=1.0)
def 绘制个股换手(self):
'''
'''
横轴坐标序列= self._横轴坐标序列
平面对象= self._个股平面
行情长度= self._目标行情长度
上涨序列= self._目标绘图上涨
下跌序列= self._目标绘图下跌
平盘序列= self._目标绘图平盘
换手序列= self._目标绘图换手
横轴参数= self._横轴参数
横标起点= 横轴参数['坐标起点']
横标终点= 横轴参数['坐标终点']
每月首日偏移= 横轴参数['每月首日偏移']
换手阵列= numpy.array(换手序列)
起点阵列= numpy.zeros(行情长度)
lwidth= 3.0
if True in 上涨序列:
平面对象.vlines(横轴坐标序列[上涨序列], 起点阵列[上涨序列], 换手阵列[上涨序列], edgecolor='red', linewidth=lwidth, label='_nolegend_', alpha=0.5)
if True in 下跌序列:
平面对象.vlines(横轴坐标序列[下跌序列], 起点阵列[下跌序列], 换手阵列[下跌序列], edgecolor='green', linewidth=lwidth, label='_nolegend_', alpha=0.5)
if True in 平盘序列:
平面对象.vlines(横轴坐标序列[平盘序列], 起点阵列[平盘序列], 换手阵列[平盘序列], edgecolor='0.7', linewidth=lwidth, label='_nolegend_', alpha=1.0)
# 绘制 平均换手数值(直线)
个股换手= [nr for nr in 换手序列 if nr is not None]
平均换手= sum(个股换手) / float(len(个股换手))
平面对象.plot([横标起点, 横标终点], [平均换手, 平均换手], '-', color='yellow', linewidth=0.2, alpha=0.7)
# 平均换手率数值在图中间的显示
for ix in 每月首日偏移[2:-1:3]:
newlab= 平面对象.text(ix+8, 平均换手, str(round(平均换手/1000.0, 2)) + '%')
newlab.set_font_properties(__font_properties__)
newlab.set_color('yellow')
newlab.set_fontsize(3)
def 绘制换手提示(self):
'''
'''
def formatter(nr):
return str(round(nr/1000.0, 2)) + '%'
平面对象= self._指数平面
纵轴参数= self._纵轴参数
指数步进= 纵轴参数['指数步进']
个股步进= 纵轴参数['个股步进']
纵轴格数= 纵轴参数['纵轴格数']
shift= 7
横轴参数= self._横轴参数
每月首日偏移= 横轴参数['每月首日偏移']
for iy, iy2 in zip( range(int(指数步进/2.0), 指数步进*纵轴格数, int(指数步进/2.0)), range(int(个股步进/2.0), 个股步进*纵轴格数, int(个股步进/2.0)) ):
for ix in 每月首日偏移[1:-1:3]:
newlab= 平面对象.text(ix+shift, iy, formatter(iy2) + ' / ' + formatter(iy))
newlab.set_font_properties(__font_properties__)
newlab.set_color('0.3')
newlab.set_fontsize(3)
newlab.set_zorder(0) # XXX: 放在底层
def 绘图(self):
'''
'''
self.绘制指数换手()
self.绘制个股换手()
self.绘制换手提示()

View File

@ -0,0 +1,22 @@
#coding=utf8
import tushare as ts
import pymongo
import json
#import csv
import time
#conn = pymongo.Connection('222.73.15.21', port=7017)
i=0
while i < 10000:
print time.localtime
i=i+1
code = "%06d" % i
print code
df = ts.get_hist_data(code)
#conn.db.DayAll.insert(json.loads(df.to_json(orient='index')))

View File

@ -0,0 +1,30 @@
import numpy as np
import matplotlib.pyplot as plt
#first generate some datapoint for a randomly sampled noisy sinewave
x = np.random.random(1000)*10
noise = np.random.normal(scale=0.3,size=len(x))
y = np.sin(x) + noise
#plot the data
plt.plot(x,y,'ro',alpha=0.3,ms=4,label='data')
plt.xlabel('Time')
plt.ylabel('Intensity')
#define a moving average function
def moving_average(x,y,step_size=.1,bin_size=1):
bin_centers = np.arange(np.min(x),np.max(x)-0.5*step_size,step_size)+0.5*step_size
bin_avg = np.zeros(len(bin_centers))
for index in range(0,len(bin_centers)):
bin_center = bin_centers[index]
items_in_bin = y[(x>(bin_center-bin_size*0.5) ) & (x<(bin_center+bin_size*0.5))]
bin_avg[index] = np.mean(items_in_bin)
return bin_centers,bin_avg
#plot the moving average
bins, average = moving_average(x,y)
plt.plot(bins, average,label='moving average')
plt.show()

560
vn.training/quotation.py Normal file
View File

@ -0,0 +1,560 @@
# -*- coding: utf-8 -*-
#!/usr/bin/python
import sys
import random
from PyQt4 import QtGui, QtCore,Qt
import tushare as ts
class report_painter:
'''绘制行情类'''
def __init__(self,parent):
#初始化
self.parent = parent
self.paint = QtGui.QPainter()
self.paint.begin(self.parent)
#设置抗锯齿
#self.paint.setRenderHint(QtGui.QPainter.Antialiasing)
#度量尺对象
self.metrics = self.paint.fontMetrics()
#设置字体库
self.fonts = dict()
self.fonts['default'] = QtGui.QFont('Serif', 9, QtGui.QFont.Light)
self.fonts['yahei_14_bold']= QtGui.QFont('Serif',12,QtGui.QFont.Bold)
self.fonts['yahei_14']= QtGui.QFont('Serif',12,QtGui.QFont.Light)
self.setFont('default')
#设置笔刷样式库
self.pens = dict()
#红色 1px粗 1px点 2px距 线条
self.pens['red_1px_dashline'] = QtGui.QPen( QtCore.Qt.red, 1, QtCore.Qt.DashLine)
self.pens['red_1px_dashline'].setDashPattern([1,2])
#红色 1px粗 实线条
self.pens['red'] = QtGui.QPen( QtCore.Qt.red, 1, QtCore.Qt.SolidLine)
#红色 3px粗 实线条
self.pens['red_2px'] = QtGui.QPen( QtCore.Qt.red, 2, QtCore.Qt.SolidLine)
#红色 2px粗 实线条
self.pens['red_3px'] = QtGui.QPen( QtCore.Qt.red, 3, QtCore.Qt.SolidLine)
#黄色 1px粗 实线条
self.pens['yellow'] = QtGui.QPen( QtCore.Qt.yellow, 1, QtCore.Qt.SolidLine)
#白色 1px粗 实线条
self.pens['white'] = QtGui.QPen( QtCore.Qt.white , 1, QtCore.Qt.SolidLine)
#灰色 1px粗 实线条
self.pens['gray'] = QtGui.QPen( QtCore.Qt.gray, 1, QtCore.Qt.SolidLine)
#绿色 1px粗 实线条
self.pens['green'] = QtGui.QPen( QtCore.Qt.green, 1, QtCore.Qt.SolidLine)
#绿色 3px粗 实线条
self.pens['green_2px'] = QtGui.QPen( QtCore.Qt.green, 2, QtCore.Qt.SolidLine)
#亮蓝 1px粗 1px点 2px距 线条
self.pens['cyan_1px_dashline'] = QtGui.QPen( QtCore.Qt.cyan, 1, QtCore.Qt.DashLine)
self.pens['cyan_1px_dashline'].setDashPattern([3,2])
#获得窗口的长和宽
size = self.parent.size()
self.w = size.width()
self.h = size.height()
#设置grid的上下左右补丁边距
self.grid_padding_left = 45 #左侧补丁边距
self.grid_padding_right = 245 #右侧补丁边距
self.grid_padding_top = 25 #顶部补丁边距
self.grid_padding_bottom = 17 #底部补丁边距
#开始绘制
self.start_paint()
self.paint.end() #结束
'''绘制流程步骤'''
def start_paint(self):
self.PriceGridPaint()
self.rightGridPaint()
self.timelinePaint()
self.topInfoPaint()
self.rulerPaint()
self.VolumeGridPaint()
self.volumePaint()
self.pricePaint()
self.xyPaint()
'''设置使用的字体'''
def setFont(self,code='default'):
self.paint.setFont(self.fonts[code])
'''设置使用的笔刷'''
def setPen(self,code='default'):
self.paint.setPen(self.pens[code])
'''绘制股价走势表格'''
def PriceGridPaint(self):
self.setPen('red')
self.paint.setBrush(QtCore.Qt.NoBrush)
sum_width = self.grid_padding_left+self.grid_padding_right
sum_height = self.grid_padding_top+self.grid_padding_bottom
grid_height = self.h-sum_height
#画边框
self.paint.drawRect(self.grid_padding_left,self.grid_padding_top,
self.w-sum_width,self.h-sum_height)
#成交量和走势的分界线
self.paint.drawLine(self.grid_padding_left,grid_height*0.7+self.grid_padding_top,
self.w-self.grid_padding_right,grid_height*0.7+self.grid_padding_top)
#股票昨收中间线
self.paint.drawLine(self.grid_padding_left+1,
grid_height*0.35+self.grid_padding_top,
self.w-self.grid_padding_right
,grid_height*0.35+self.grid_padding_top)
#其他线条
self.paint.drawLine(0,self.h-self.grid_padding_bottom,self.w-self.grid_padding_right+44,self.h-self.grid_padding_bottom)
self.paint.drawLine(0,self.h-self.grid_padding_bottom+16,self.w,self.h-self.grid_padding_bottom+16)
self.paint.drawLine(self.w-self.grid_padding_right,0,
self.w-self.grid_padding_right,self.h-self.grid_padding_bottom+16)
self.paint.drawLine(self.w-self.grid_padding_right+44,0,
self.w-self.grid_padding_right+44,self.h-self.grid_padding_bottom+16)
self.setPen('yellow')
self.paint.drawText(self.w-self.grid_padding_right+5,self.h-self.grid_padding_bottom-4,QtCore.QString(u'成交量'))
self.setPen('white')
#右下角文字
self.paint.drawText(self.w-self.grid_padding_right+12,self.h-self.grid_padding_bottom+12,QtCore.QString(u'实时'))
'''绘制成交量走势表格'''
def VolumeGridPaint(self):
sum_width = self.grid_padding_left + self.grid_padding_right
sum_height = self.grid_padding_top + self.grid_padding_bottom
grid_height = self.h-sum_height
max_volume = self.parent.stk_data['max_vol']
px_h_radio = max_volume/(grid_height*0.3)
self.setPen('red_1px_dashline')
grid_num = 6
x = grid_num
cnt = grid_height*0.3/grid_num
for i in range(0,grid_num):
self.setPen('red_1px_dashline')
#计算坐标
y1 = self.grid_padding_top+(grid_height*0.7)+i*cnt
x1 = self.grid_padding_left
x2 = self.grid_padding_left+self.w-sum_width
self.paint.drawLine(x1,y1,x2,y1) #画价位虚线
vol_int = int(cnt*x*px_h_radio)
vol_str = str(vol_int)
fw = self.metrics.width(vol_str) #获得文字宽度
fh = self.metrics.height()/2 #获得文字高度
self.setPen('yellow')
self.paint.drawText(x2+40-fw,y1+fh,vol_str) #写入文字
self.setPen('white')
self.paint.drawText(x1-2-self.metrics.width(str(x)),y1+fh,str(x)) #写入文字
x-=1
'''绘制左侧信息栏和盘口等内容'''
def rightGridPaint(self):
self.setPen('red')
#绘制信息内容之间的分割线
_h = 0
_x = self.w-self.grid_padding_right+44
self.paint.drawLine(self.w-1,0,self.w-1,self.h-self.grid_padding_bottom+16)
self.paint.drawLine(0,0,0,self.h-self.grid_padding_bottom+16)
self.paint.drawLine(0,_h,self.w,_h)
_h+=23
self.paint.drawLine(_x,_h,self.w,_h)
_h+=24
self.paint.drawLine(_x,_h,self.w,_h)
_h+=93
self.paint.drawLine(_x,_h,self.w,_h)
_h+=20
self.paint.drawLine(_x,_h,self.w,_h)
_h+=93
self.paint.drawLine(_x,_h,self.w,_h)
_h+=123
self.paint.drawLine(_x,_h,self.w,_h)
_h+=23
self.paint.drawLine(_x,_h,self.w,_h)
#股票名称和代码
self.setFont('yahei_14_bold')
self.setPen('yellow')
name_str = QtCore.QString(u'%s %s'%(self.parent.stk_info['code'],self.parent.stk_info['name']))
self.paint.drawText(_x+35,18,name_str)
#委比和委差
self.setFont('yahei_14')
zx_str = QtCore.QString(u'最新')
self.paint.drawText(_x+3 ,156,zx_str)
self.setPen('gray')
wb_str = QtCore.QString(u'委比')
wc_str = QtCore.QString(u'委差')
xs_str = QtCore.QString(u'现手')
self.paint.drawText(_x+3 ,39,wb_str)
self.paint.drawText(_x+100,39,wc_str)
self.paint.drawText(_x+100,156,xs_str)
fh = self.metrics.height()
left_field_list = [u'涨跌',u'涨幅',u'振幅',u'总手',u'总额',u'换手',u'分笔']
i = 1
for field in left_field_list:
field_str = QtCore.QString(field)
self.paint.drawText(_x+3,253+(i*17),field_str)
i+=1
right_field_list = [u'均价',u'前收',u'今开',u'最高',u'最低',u'量比',u'均量']
i = 1
for field in right_field_list:
field_str = QtCore.QString(field)
self.paint.drawText(_x+100,253+(i*17),field_str)
i+=1
wp_str = QtCore.QString(u'外盘')
np_str = QtCore.QString(u'内盘')
self.paint.drawText(_x+3,395,wp_str)
self.paint.drawText(_x+100,395,np_str)
#卖①②③④⑤
i = 0
sell_queue = [u'卖⑤',u'卖④',u'卖③',u'卖②',u'卖①']
for sell in sell_queue:
sell_str = QtCore.QString(sell)
self.paint.drawText(_x+3,62+(i*18),sell_str)
i+=1
#买①②③④⑤
buy_queue = [u'买①',u'买②',u'买③',u'买④',u'买⑤']
for buy in buy_queue:
buy_str = QtCore.QString(buy)
self.paint.drawText(_x+3,87+(i*18),buy_str)
i+=1
self.setPen('red_2px')
self.paint.drawLine(_x+1,377,_x+99,377)
self.paint.drawLine(_x+1,46,_x+65,46)
self.setPen('green_2px')
self.paint.drawLine(_x+102,377,_x+199,377)
self.paint.drawLine(_x+67,46,_x+199,46)
self.setFont('default')
'''绘制左右侧的价格刻度'''
def rulerPaint(self):
sum_width = self.grid_padding_left+self.grid_padding_right
sum_height = self.grid_padding_top+self.grid_padding_bottom
grid_height = self.h-sum_height
high = self.parent.stk_data['high']
low = self.parent.stk_data['low']
lastclose = self.parent.stk_data['lastclose']
top = high-lastclose
bottom = lastclose-low
if top>bottom:
padding = top
else:
padding = bottom
limit_top = lastclose+padding
limit_low = lastclose-padding
px_h_radio = (grid_height*0.7)/((limit_top-limit_low)*100)
self.setPen('red_1px_dashline')
grid_num = 16
cnt = grid_height*0.7/grid_num
for i in range(0,grid_num):
self.setPen('red_1px_dashline')
#计算坐标
y1 = self.grid_padding_top+i*cnt
x1 = self.grid_padding_left
x2 = self.grid_padding_left+self.w-sum_width
self.paint.drawLine(x1,y1,x2,y1) #画价位虚线
price_float = (limit_top - ((i*cnt)/px_h_radio/100)) #计算价格
price = '%4.2f'%(price_float) #格式化价格成str
fw = self.metrics.width(price) #获得文字宽度
fh = self.metrics.height()/2 #获得文字高度
radio_float = (price_float/lastclose-1)*100 #计算波动百分比
radio_str = "%2.2f%%"%(radio_float) #格式化百分比成str
r_fw = self.metrics.width(radio_str)
r_fh = self.metrics.height()/2
#判断文字使用的颜色
if price_float == lastclose:
self.setPen('white')
if price_float < lastclose:
self.setPen('green')
self.paint.drawText(x1-fw-2,y1+fh,price) #写入文字
self.paint.drawText(x2+40-r_fw,y1+r_fh,radio_str) #写入文字
'''绘制x,y准星'''
def xyPaint(self):
if self.parent.m_x >= self.grid_padding_left and self.parent.m_x<=self.w-self.grid_padding_right and self.parent.m_y>=self.grid_padding_top and self.parent.m_y<=self.h-self.grid_padding_bottom:
self.setPen('gray')
x1 = self.grid_padding_left
x2 = self.w-self.grid_padding_right
y1 = self.grid_padding_top
y2 = self.h-self.grid_padding_bottom
self.paint.drawLine(x1+1,self.parent.m_y,x2-1,self.parent.m_y)
self.paint.drawLine(self.parent.m_x,y1+1,self.parent.m_x,y2-1)
'''绘制时间轴刻度'''
def timelinePaint(self):
fw = self.metrics.width(u'00:00') #计算文字的宽度
sum_width = self.grid_padding_left+self.grid_padding_right
sum_height = self.grid_padding_top+self.grid_padding_bottom
grid_width = self.w-sum_width-2
y1 = self.grid_padding_top
y2 = y1+(self.h-sum_height)
#时间轴中线
self.setPen('red')
x_pos = grid_width/2+self.grid_padding_left
self.paint.drawLine(x_pos,y1,x_pos,y2)
self.paint.drawText(x_pos-fw/2,y2+12,QtCore.QString(u'13:00'))
#时间轴09点30分
x_pos = self.grid_padding_left
self.paint.drawText(x_pos,y2+12,QtCore.QString(u'09:30'))
#时间轴10点30分
x_pos = grid_width*0.25+self.grid_padding_left
self.paint.drawLine(x_pos,y1,x_pos,y2)
self.paint.drawText(x_pos-fw/2,y2+12,QtCore.QString(u'10:30'))
#时间轴14点00分
x_pos = grid_width*0.75+self.grid_padding_left
self.paint.drawLine(x_pos,y1,x_pos,y2)
self.paint.drawText(x_pos-fw/2,y2+12,QtCore.QString(u'14:00'))
#时间轴15点00分
x_pos = grid_width+self.grid_padding_left
self.paint.drawText(x_pos-fw,y2+12,QtCore.QString(u'15:00'))
#时间虚线 by 30min
self.setPen('red_1px_dashline')
x_pos_array = [0.125,0.375,0.625,0.875]
for i in x_pos_array:
x_pos = grid_width*i+self.grid_padding_left
self.paint.drawLine(x_pos,y1,x_pos,y2)
'''绘制表格上方的股票信息'''
def topInfoPaint(self):
self.setPen('yellow')
self.paint.drawText(4+self.grid_padding_left,self.grid_padding_top-4
,QtCore.QString(self.parent.stk_info['name'])) #股票名称
self.paint.drawText(4+self.grid_padding_left+120,self.grid_padding_top-4
,QtCore.QString(u'均价线:')) #均价线
lastclose = self.parent.stk_data['lastclose']
close = self.parent.stk_data['close']
mma = self.parent.stk_data['list']['mma'][-1]
if lastclose>close:
self.setPen('green')
str_1 = '%.2f -%.2f'%(close,lastclose-close)
if lastclose==close:
self.setPen('white')
str_1 = '%.2f +%.2f'%(close,0.00)
if lastclose<close:
self.setPen('red')
str_1 = '%.2f +%.2f'%(close,close-lastclose)
if mma>close:
self.setPen('green')
if mma==close:
self.setPen('white')
if mma<close:
self.setPen('red')
self.paint.drawText(4+self.grid_padding_left+55,self.grid_padding_top-4,QtCore.QString(str_1))
self.paint.drawText(4+self.grid_padding_left+165,self.grid_padding_top-4,QtCore.QString('%.2f'%mma)) #均价
#涨停价
self.setPen('red')
self.paint.drawText(4+self.grid_padding_left+200,self.grid_padding_top-4,QtCore.QString(u'涨停价:%.2f'%(lastclose*1.1))) #均价
#跌停价
self.setPen('green')
self.paint.drawText(4+self.grid_padding_left+280,self.grid_padding_top-4,QtCore.QString(u'跌停价:%.2f'%(lastclose*0.9))) #均价
'''绘制股价走势'''
def pricePaint(self):
sum_width = self.grid_padding_left+self.grid_padding_right
sum_height = self.grid_padding_top+self.grid_padding_bottom
grid_height = self.h-sum_height-2
high = self.parent.stk_data['high']
low = self.parent.stk_data['low']
lastclose = self.parent.stk_data['lastclose']
top = high-lastclose
bottom = lastclose-low
if top>bottom:
padding = top
else:
padding = bottom
limit_top = lastclose+padding
limit_low = lastclose-padding
h_radio = (grid_height*0.7)/((limit_top-limit_low)*100)
w_radio = (self.w-sum_width-2)/240.00
w = self.grid_padding_left
self.setPen('white')
path = QtGui.QPainterPath()
path.moveTo(w,(limit_top-self.parent.stk_data['open'])*100*h_radio+self.grid_padding_top)
i = 1
for price in self.parent.stk_data['list']['close']:
w = i*w_radio+self.grid_padding_left
y = (limit_top-price)*100*h_radio+self.grid_padding_top
path.lineTo(w,y)
i+=1
self.paint.drawPath(path)
self.setPen('cyan_1px_dashline')
self.paint.drawLine(self.grid_padding_left+1,y,w-1,y)
self.setPen('yellow')
path = QtGui.QPainterPath()
w = self.grid_padding_left
path.moveTo(w,(limit_top-self.parent.stk_data['open'])*100*h_radio+self.grid_padding_top)
i = 1
for price in self.parent.stk_data['list']['mma']:
w = i*w_radio+self.grid_padding_left
y = (limit_top-price)*100*h_radio+self.grid_padding_top
path.lineTo(w,y)
i+=1
self.paint.drawPath(path)
'''绘制成交量'''
def volumePaint(self):
sum_width = self.grid_padding_left + self.grid_padding_right
sum_height = self.grid_padding_top + self.grid_padding_bottom
max_volume = self.parent.stk_data['max_vol'] #最大分钟成交量
w_radio = (self.w-sum_width-2)/240.00
h_radio = ((self.h-sum_height-2)*0.3)/max_volume
y = (self.h-sum_height)+self.grid_padding_top
self.setPen('yellow')
for i in range(1,len(self.parent.stk_data['list']['vol'])+1):
x = i*w_radio+self.grid_padding_left
y2 = h_radio*self.parent.stk_data['list']['vol'][i-1]
self.paint.drawLine(x,y-1,x,y-y2)
class Test(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setMinimumSize(640, 430) #设置窗口最小尺寸
self.setGeometry(300, 300, 960, 650)
self.setWindowTitle(QtCore.QString(u'超级狙击手[内部开发测试版]-行情实时走势'))
self.setStyleSheet("QWidget { background-color: black }")
self.setWindowIcon(QtGui.QIcon('ruby.png'))
self.setMouseTracking(True)
self.m_x = 0 #光标x轴位置
self.m_y = 0 #光标y轴位置
self.stk_info = {}
self.stk_info['name'] = u'浙江东方'
self.stk_info['code'] = u'600120'
self.stk_info['market'] = 'SH'
self.stk_data = {}
self.stk_data['list'] = {} #股价序列
self.stk_data['list']['time'] = [] #时间
self.stk_data['list']['open'] = [] #开盘价
self.stk_data['list']['high'] = [] #最高价
self.stk_data['list']['low'] = [] #最低价
self.stk_data['list']['close'] = [] #收盘价
self.stk_data['list']['vol'] = [] #成交量
self.stk_data['list']['amount']= [] #成交额
self.stk_data['list']['mma']= [] #分时均价
self.stk_data['list']['buy_port'] = [(0.00,0),(0.00,0),(0.00,0),(0.00,0),(0.00,0)] #买盘前五
self.stk_data['list']['sell_port'] = [(0.00,0),(0.00,0),(0.00,0),(0.00,0),(0.00,0)] #卖盘前五
#读取数据
# f = open('SH600120.txt','r')
# data = f.readlines()
# f.close ()
data = ts.get_hist_data('600120') #一次性获取全部日k线数据
#for row in data:
# vars = row.split(' ')
# self.stk_data['list']['time'].append(vars[1])
# self.stk_data['list']['open'].append(float(vars[2]))
# self.stk_data['list']['high'].append(float(vars[3]))
# self.stk_data['list']['low'].append(float(vars[4]))
# self.stk_data['list']['close'].append(float(vars[5]))
# self.stk_data['list']['vol'].append(int(float(vars[6])))
# self.stk_data['list']['amount'].append(int(float(vars[7])))
#
# sum_vol = sum(self.stk_data['list']['vol'])
# sum_amt = sum(self.stk_data['list']['amount'])
#
# self.stk_data['list']['mma'].append(float(sum_amt)/(sum_vol*100.00))
self.stk_data['list'] = data.datetime
self.stk_data['list']
self.stk_data['list']
self.stk_data['list']
self.stk_data['list']
self.stk_data['list']
self.stk_data['list']
self.stk_data['lastclose'] = 10.12 #上一个交易日收盘价
self.stk_data['open'] = self.stk_data['list']['open'][0] #开盘价
self.stk_data['high'] = max(self.stk_data['list']['high']) #最高价
self.stk_data['low'] = min(self.stk_data['list']['low']) #最低价
self.stk_data['close']= self.stk_data['list']['close'][-1] #收盘价
self.stk_data['max_vol'] = max(self.stk_data['list']['vol']) #当日最高成交量
def mouseMoveEvent(self, event):
self.m_x = int(event.x())
self.m_y = int(event.y())
self.repaint()
def paintEvent(self, event):
report_painter(self)
app = QtGui.QApplication(sys.argv)
dt = Test()
dt.show()
app.exec_()

2597
vn.training/quotation_ext.py Normal file

File diff suppressed because it is too large Load Diff

802
vn.training/qutation2.py Normal file
View File

@ -0,0 +1,802 @@
# -*- coding: utf-8 -*-
import os
import sys
import pickle
import math
import datetime
import matplotlib
matplotlib.use("WXAgg", warn=True) # 这个要紧跟在 import matplotlib 之后,而且必须安装了 wxpython 2.8 才行。
import matplotlib.pyplot as pyplot
import matplotlib.font_manager as font_manager
import numpy
from matplotlib.ticker import FixedLocator, MultipleLocator, FuncFormatter, NullFormatter
__font_properties__=font_manager.FontProperties(fname='/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc')
__color_lightsalmon__= '#ffa07a'
__color_pink__= '#ffc0cb'
__color_navy__= '#000080'
def Plot(pfile, figpath):
"""
pfile 指明存放绘图数据的 pickle filefigpath 指定图片需存放的路径
"""
fileobj= open(name=pfile, mode='rb')
pdata= pickle.load(fileobj)
fileobj.close()
os.remove(pfile)
# 计算图片的尺寸(单位英寸)
# 注意Python2 里面, "1 / 10" 结果是 0, 必须写成 "1.0 / 10" 才会得到 0.1
#==================================================================================================================================================
length= len(pdata[u'日期']) # 所有数据的长度,就是天数
open_price_pri= pdata[u'开盘'][0] # int 类型
open_price_sec= pdata[u'开盘二'][0] # 同上
highest_price_pri= max( [phigh for phigh in pdata[u'最高'] if phigh != None] ) # 第一个行情的最高价
highest_price_sec= max( [phigh for phigh in pdata[u'最高二'] if phigh != None] ) # 第二个行情的最高价
highest_price= max(highest_price_pri, highest_price_sec*open_price_pri/open_price_sec) # 以第一个行情为基准修正出的总最高价
lowest_price_pri= min( [plow for plow in pdata[u'最低'] if plow != None] ) # 最低价
lowest_price_sec= min( [plow for plow in pdata[u'最低二'] if plow != None] ) # 最低价
lowest_price= min(lowest_price_pri, lowest_price_sec*open_price_pri/open_price_sec) # 以第一个行情为基准修正出的总最低价
yhighlim_price= int(highest_price * 1.1) # K线子图 Y 轴最大坐标
ylowlim_price= int(lowest_price / 1.1) # K线子图 Y 轴最小坐标
xfactor= 10.0/230.0 # 一条 K 线的宽度在 X 轴上所占距离(英寸)
yfactor= 0.3 # Y 轴上每一个距离单位的长度(英寸),这个单位距离是线性坐标和对数坐标通用的
expbase= 1.1 # 底数,取得小一点,比较接近 1。股价 3 元到 4 元之间有大约 3 个单位距离
# XXX: 价格在 Y 轴上的 “份数”。注意,虽然最高与最低价是以第一个行情为基准修正出来的,但其中包含的倍数因子对结果无影响,即:
# log(base, num1) - log(base, num2) ==
# log(base, num1/num2) ==
# log(base, k*num1/k*num2) ==
# log(base, k*num1) - log(base, k*num2)
# ,这是对数运算的性质。
ymulti_price= math.log(yhighlim_price, expbase) - math.log(ylowlim_price, expbase)
ymulti_vol= 3.0 # 成交量部分在 Y 轴所占的 “份数”
ymulti_top= 1.2 # 顶部空白区域在 Y 轴所占的 “份数”
ymulti_bot= 1.2 # 底部空白区域在 Y 轴所占的 “份数”
xmulti_left= 12.0 # 左侧空白区域所占的 “份数”
xmulti_right= 12.0 # 右侧空白区域所占的 “份数”
xmulti_all= length + xmulti_left + xmulti_right
xlen_fig= xmulti_all * xfactor # 整个 Figure 的宽度
ymulti_all= ymulti_price + ymulti_vol + ymulti_top + ymulti_bot
ylen_fig= ymulti_all * yfactor # 整个 Figure 的高度
rect_1= (xmulti_left/xmulti_all, (ymulti_bot+ymulti_vol)/ymulti_all, length/xmulti_all, ymulti_price/ymulti_all) # K线图部分
rect_2= (xmulti_left/xmulti_all, ymulti_bot/ymulti_all, length/xmulti_all, ymulti_vol/ymulti_all) # 成交量部分
# 建立 Figure 对象
#==================================================================================================================================================
figfacecolor= __color_pink__
figedgecolor= __color_navy__
figdpi= 300
figlinewidth= 1.0
figobj= pyplot.figure(figsize=(xlen_fig, ylen_fig), dpi=figdpi, facecolor=figfacecolor, edgecolor=figedgecolor, linewidth=figlinewidth) # Figure 对象
# 整个 figure 的标题
title_pri= (pdata[u'代码'] + ' ' if u'代码' in pdata else '') + pdata[u'简称']
title_sec= (pdata[u'代码二'] + ' ' if u'代码二' in pdata else '') + pdata[u'简称二']
figobj.suptitle(title_pri + ' / ' + title_sec, fontsize=12, fontproperties=__font_properties__)
#==================================================================================================================================================
#==================================================================================================================================================
#=======
#======= XXX: 第一只:成交量部分
#=======
#==================================================================================================================================================
#==================================================================================================================================================
# 第一只:添加 Axes 对象
#==================================================================================================================================================
axes_2= figobj.add_axes(rect_2, axis_bgcolor='black')
axes_2.set_axisbelow(True) # 网格线放在底层
# 第一只:改变坐标线的颜色
#==================================================================================================================================================
for child in axes_2.get_children():
if isinstance(child, matplotlib.spines.Spine):
child.set_color('lightblue')
# 第一只:得到 X 轴 和 Y 轴 的两个 Axis 对象
#==================================================================================================================================================
xaxis_2= axes_2.get_xaxis()
yaxis_2= axes_2.get_yaxis()
# 第一只:设置两个坐标轴上的 grid
#==================================================================================================================================================
xaxis_2.grid(True, 'major', color='0.3', linestyle='solid', linewidth=0.2)
xaxis_2.grid(True, 'minor', color='0.3', linestyle='dotted', linewidth=0.1)
yaxis_2.grid(True, 'major', color='0.3', linestyle='solid', linewidth=0.2)
yaxis_2.grid(True, 'minor', color='0.3', linestyle='dotted', linewidth=0.1)
#==================================================================================================================================================
#======= 第一只:成交量绘图
#==================================================================================================================================================
xindex= numpy.arange(length) # X 轴上的 index一个辅助数据
zipoc= zip(pdata[u'开盘'], pdata[u'收盘'])
up= numpy.array( [ True if po < pc and po != None else False for po, pc in zipoc] ) # 标示出该天股价日内上涨的一个序列
down= numpy.array( [ True if po > pc and po != None else False for po, pc in zipoc] ) # 标示出该天股价日内下跌的一个序列
side= numpy.array( [ True if po == pc and po != None else False for po, pc in zipoc] ) # 标示出该天股价日内走平的一个序列
if u'成交额' in pdata:
volume= pdata[u'成交额']
else:
volume= pdata[u'成交量']
rarray_vol= numpy.array(volume)
volzeros= numpy.zeros(length) # 辅助数据
# XXX: 如果 up/down/side 各项全部为 False那么 vlines() 会报错。
if True in up:
axes_2.vlines(xindex[up], volzeros[up], rarray_vol[up], edgecolor='red', linewidth=3.0, label='_nolegend_')
if True in down:
axes_2.vlines(xindex[down], volzeros[down], rarray_vol[down], edgecolor='green', linewidth=3.0, label='_nolegend_')
if True in side:
axes_2.vlines(xindex[side], volzeros[side], rarray_vol[side], edgecolor='0.7', linewidth=3.0, label='_nolegend_')
# 第一只:设定 X 轴坐标的范围
#==================================================================================================================================================
axes_2.set_xlim(-1, length)
# 第一只:设定 X 轴上的坐标
#==================================================================================================================================================
datelist= [ datetime.date(int(ys), int(ms), int(ds)) for ys, ms, ds in [ dstr.split('-') for dstr in pdata[u'日期'] ] ]
# 确定 X 轴的 MajorLocator
mdindex= [] # 每个月第一个交易日在所有日期列表中的 index
years= set([d.year for d in datelist]) # 所有的交易年份
for y in sorted(years):
months= set([d.month for d in datelist if d.year == y]) # 当年所有的交易月份
for m in sorted(months):
monthday= min([dt for dt in datelist if dt.year==y and dt.month==m]) # 当月的第一个交易日
mdindex.append(datelist.index(monthday))
xMajorLocator= FixedLocator(numpy.array(mdindex))
# 第一只:确定 X 轴的 MinorLocator
wdindex= {} # value: 每周第一个交易日在所有日期列表中的 index; key: 当周的序号 week number当周是第几周
for d in datelist:
isoyear, weekno= d.isocalendar()[0:2]
dmark= isoyear*100 + weekno
if dmark not in wdindex:
wdindex[dmark]= datelist.index(d)
xMinorLocator= FixedLocator(numpy.array( sorted(wdindex.values()) ))
# 第一只:确定 X 轴的 MajorFormatter 和 MinorFormatter
def x_major_formatter_2(idx, pos=None):
return datelist[idx].strftime('%Y-%m-%d')
def x_minor_formatter_2(idx, pos=None):
return datelist[idx].strftime('%m-%d')
xMajorFormatter= FuncFormatter(x_major_formatter_2)
xMinorFormatter= FuncFormatter(x_minor_formatter_2)
# 第一只:设定 X 轴的 Locator 和 Formatter
xaxis_2.set_major_locator(xMajorLocator)
xaxis_2.set_major_formatter(xMajorFormatter)
xaxis_2.set_minor_locator(xMinorLocator)
xaxis_2.set_minor_formatter(xMinorFormatter)
# 第一只:设定 X 轴主要坐标点与辅助坐标点的样式
for malabel in axes_2.get_xticklabels(minor=False):
malabel.set_fontsize(4)
malabel.set_horizontalalignment('right')
malabel.set_rotation('45')
for milabel in axes_2.get_xticklabels(minor=True):
milabel.set_fontsize(4)
milabel.set_color('blue')
milabel.set_horizontalalignment('right')
milabel.set_rotation('45')
# 第一只:设定成交量 Y 轴坐标的范围
#==================================================================================================================================================
maxvol= max(volume) # 注意是 int 类型
axes_2.set_ylim(0, maxvol)
# 第一只:设定成交量 Y 轴上的坐标
#==================================================================================================================================================
vollen= len(str(maxvol))
volstep_pri= int(round(maxvol/10.0+5000, -4))
yMajorLocator_2= MultipleLocator(volstep_pri)
# 第一只:确定 Y 轴的 MajorFormatter
dimsuffix= u'' if u'成交额' in pdata else u''
def y_major_formatter_2(num, pos=None):
if num >= 10**8: # 大于 1 亿
return (str(round(num/10.0**8, 2)) + u'亿' + dimsuffix) if num != 0 else '0'
else:
return (str(num/10.0**4) + u'' + dimsuffix) if num != 0 else '0'
# def y_major_formatter_2(num, pos=None):
# return int(num)
yMajorFormatter_2= FuncFormatter(y_major_formatter_2)
# 确定 Y 轴的 MinorFormatter
# def y_minor_formatter_2(num, pos=None):
# return int(num)
# yMinorFormatter_2= FuncFormatter(y_minor_formatter_2)
yMinorFormatter_2= NullFormatter()
# 第一只:设定 X 轴的 Locator 和 Formatter
yaxis_2.set_major_locator(yMajorLocator_2)
yaxis_2.set_major_formatter(yMajorFormatter_2)
# yaxis_2.set_minor_locator(yMinorLocator_2)
yaxis_2.set_minor_formatter(yMinorFormatter_2)
# 第一只:设定 Y 轴主要坐标点与辅助坐标点的样式
for malab in axes_2.get_yticklabels(minor=False):
malab.set_font_properties(__font_properties__)
malab.set_fontsize(4.5) # 这个必须放在前一句后面,否则作用会被覆盖
# 第一只:成交量数值在图中间的显示
#==================================================================================================================================================
for iy in range(volstep_pri, maxvol, volstep_pri):
for ix in mdindex[1:-1:3]:
newlab= axes_2.text(ix+8, iy, y_major_formatter_2(iy))
newlab.set_font_properties(__font_properties__)
newlab.set_color('0.3')
newlab.set_fontsize(3)
newlab.set_zorder(0) # XXX: 放在底层
# newlab.set_verticalalignment('center')
#==================================================================================================================================================
#==================================================================================================================================================
#=======
#======= XXX: 第二条成交量图线
#=======
#==================================================================================================================================================
#==================================================================================================================================================
# 添加 Axes 对象
#==================================================================================================================================================
axes_2_sec= axes_2.twinx()
# axes_2_sec.set_axisbelow(True) # 网格线放在底层
axes_2_sec.set_axisbelow(True) # 网格线放在底层
# 改变坐标线的颜色
#==================================================================================================================================================
# for child in axes_2_sec.get_children():
# if isinstance(child, matplotlib.spines.Spine):
# child.set_color('lightblue')
# 得到 X 轴 和 Y 轴 的两个 Axis 对象
#==================================================================================================================================================
xaxis_2_sec= axes_2_sec.get_xaxis()
yaxis_2_sec= axes_2_sec.get_yaxis()
# 设置两个坐标轴上的 grid
#==================================================================================================================================================
# xaxis_2_sec.grid(True, 'major', color='0.3', linestyle='solid', linewidth=0.2)
# xaxis_2_sec.grid(True, 'minor', color='0.3', linestyle='dotted', linewidth=0.1)
# yaxis_2_sec.grid(True, 'major', color='0.3', linestyle='solid', linewidth=0.2)
# yaxis_2_sec.grid(True, 'minor', color='0.3', linestyle='dotted', linewidth=0.1)
#==================================================================================================================================================
#======= 绘图
#==================================================================================================================================================
if u'成交额二' in pdata:
volume_sec= pdata[u'成交额二']
else:
volume_sec= pdata[u'成交量二']
zipoc_sec= zip(pdata[u'开盘二'], pdata[u'收盘二'])
up_sec= numpy.array( [ True if po < pc and po != None else False for po, pc in zipoc_sec] ) # 标示出该天股价日内上涨的一个序列
down_sec= numpy.array( [ True if po > pc and po != None else False for po, pc in zipoc_sec] ) # 标示出该天股价日内下跌的一个序列
side_sec= numpy.array( [ True if po == pc and po != None else False for po, pc in zipoc_sec] ) # 标示出该天股价日内走平的一个序列
rarray_vol_sec= numpy.array(volume_sec)
volzeros_sec= numpy.zeros(length) # 辅助数据
# XXX: 如果 up_sec/down_sec/side_sec 各项全部为 False那么 vlines() 会报错。
if True in up_sec:
axes_2_sec.vlines(xindex[up_sec], volzeros_sec[up_sec], rarray_vol_sec[up_sec], edgecolor='pink', linewidth=1.0, label='_nolegend_', alpha=0.3)
if True in down_sec:
axes_2_sec.vlines(xindex[down_sec], volzeros_sec[down_sec], rarray_vol_sec[down_sec], edgecolor='lightgreen', linewidth=1.0, label='_nolegend_', alpha=0.3)
if True in side_sec:
axes_2_sec.vlines(xindex[side_sec], volzeros_sec[side_sec], rarray_vol_sec[side_sec], edgecolor='0.7', linewidth=1.0, label='_nolegend_', alpha=0.3)
# 设定 X 轴坐标的范围
#==================================================================================================================================================
# XXX: 不用了,与 axes_2 共用。
# 设定 Y 轴坐标的范围
#==================================================================================================================================================
maxvol_sec= max(volume_sec) # 注意是 int 类型
axes_2_sec.set_ylim(0, maxvol_sec)
# 设定 Y 轴上的坐标
#==================================================================================================================================================
volstep_sec= volstep_pri*maxvol_sec/float(maxvol)
yMajorLocator_2_sec= MultipleLocator(volstep_sec)
# 确定 Y 轴的 MajorFormatter
dimsuffix_sec= u'' if u'成交额二' in pdata else u''
def y_major_formatter_2_sec(num, pos=None):
if num >= 10**8: # 大于 1 亿
print(('num= ' + str(num) + ', result= ' + str(round(num/10.0**8, 3)) + u'亿' + dimsuffix_sec).encode('utf8'))
return (str(round(num/10.0**8, 3)) + u'亿' + dimsuffix_sec) if num != 0 else '0'
else:
return (str(round(num/10.0**4, 2)) + u'' + dimsuffix_sec) if num != 0 else '0'
# def y_major_formatter_2_sec(num, pos=None):
# return int(num)
yMajorFormatter_2_sec= FuncFormatter(y_major_formatter_2_sec)
# 确定 Y 轴的 MinorFormatter
# def y_minor_formatter_2(num, pos=None):
# return int(num)
# yMinorFormatter_2_sec= FuncFormatter(y_minor_formatter_2)
yMinorFormatter_2_sec= NullFormatter()
# 设定 X 轴的 Locator 和 Formatter
yaxis_2_sec.set_major_locator(yMajorLocator_2_sec)
yaxis_2_sec.set_major_formatter(yMajorFormatter_2_sec)
# yaxis_2_sec.set_minor_locator(yMinorLocator_2_sec)
yaxis_2_sec.set_minor_formatter(yMinorFormatter_2_sec)
# 设定 Y 轴主要坐标点与辅助坐标点的样式
for malab in axes_2_sec.get_yticklabels(minor=False):
malab.set_font_properties(__font_properties__)
malab.set_fontsize(4.5) # 这个必须放在前一句后面,否则作用会被覆盖
#==================================================================================================================================================
#==================================================================================================================================================
#=======
#======= XXX: K 线图部分
#=======
#==================================================================================================================================================
#==================================================================================================================================================
# 添加 Axes 对象
#==================================================================================================================================================
axes_1= figobj.add_axes(rect_1, axis_bgcolor='black', sharex=axes_2)
axes_1.set_axisbelow(True) # 网格线放在底层
axes_1.set_yscale('log', basey=expbase) # 使用对数坐标
# 改变坐标线的颜色
#==================================================================================================================================================
for child in axes_1.get_children():
if isinstance(child, matplotlib.spines.Spine):
child.set_color('lightblue')
# 得到 X 轴 和 Y 轴 的两个 Axis 对象
#==================================================================================================================================================
xaxis_1= axes_1.get_xaxis()
yaxis_1= axes_1.get_yaxis()
# 设置两个坐标轴上的 grid
#==================================================================================================================================================
xaxis_1.grid(True, 'major', color='0.3', linestyle='solid', linewidth=0.2)
xaxis_1.grid(True, 'minor', color='0.3', linestyle='dotted', linewidth=0.1)
yaxis_1.grid(True, 'major', color='0.3', linestyle='solid', linewidth=0.2)
yaxis_1.grid(True, 'minor', color='0.3', linestyle='dotted', linewidth=0.1)
#==================================================================================================================================================
#======= 绘图
#==================================================================================================================================================
# 绘制 K 线部分
#==================================================================================================================================================
# 对开收盘价进行视觉修正
for idx, poc in enumerate( zip(pdata[u'开盘'], pdata[u'收盘']) ):
if poc[0] == poc[1] and None not in poc:
variant= round((poc[1]+1000)/2000, 0)
pdata[u'开盘'][idx]= poc[0] - variant # 稍微偏离一点,使得在图线上不致于完全看不到
pdata[u'收盘'][idx]= poc[1] + variant
rarray_open= numpy.array(pdata[u'开盘'])
rarray_close= numpy.array(pdata[u'收盘'])
rarray_high= numpy.array(pdata[u'最高'])
rarray_low= numpy.array(pdata[u'最低'])
# XXX: 如果 up, down, side 里有一个全部为 False 组成,那么 vlines() 会报错。
# XXX: 可以使用 alpha 参数调节透明度
if True in up:
axes_1.vlines(xindex[up], rarray_low[up], rarray_high[up], edgecolor='red', linewidth=0.6, label='_nolegend_')
axes_1.vlines(xindex[up], rarray_open[up], rarray_close[up], edgecolor='red', linewidth=3.0, label='_nolegend_')
if True in down:
axes_1.vlines(xindex[down], rarray_low[down], rarray_high[down], edgecolor='green', linewidth=0.6, label='_nolegend_')
axes_1.vlines(xindex[down], rarray_open[down], rarray_close[down], edgecolor='green', linewidth=3.0, label='_nolegend_')
if True in side:
axes_1.vlines(xindex[side], rarray_low[side], rarray_high[side], edgecolor='0.7', linewidth=0.6, label='_nolegend_')
axes_1.vlines(xindex[side], rarray_open[side], rarray_close[side], edgecolor='0.7', linewidth=3.0, label='_nolegend_')
# 绘制均线部分
#==================================================================================================================================================
if u'5日均' in pdata:
rarray_5dayave= numpy.array(pdata[u'5日均'])
axes_1.plot(xindex, rarray_5dayave, 'o-', color='white', linewidth=0.1, label='ave_5', \
markersize=0.7, markeredgecolor='white', markeredgewidth=0.1) # 5日均线
if u'10日均' in pdata:
rarray_10dayave= numpy.array(pdata[u'10日均'])
axes_1.plot(xindex, rarray_10dayave, 'o-', color='yellow', linewidth=0.1, label='ave_10', \
markersize=0.7, markeredgecolor='yellow', markeredgewidth=0.1) # 10日均线
if u'30日均' in pdata:
rarray_30dayave= numpy.array(pdata[u'30日均'])
axes_1.plot(xindex, rarray_30dayave, 'o-', color='cyan', linewidth=0.1, label='ave_30', \
markersize=0.7, markeredgecolor='cyan', markeredgewidth=0.1) # 30日均线
# 绘制 复权提示
#==================================================================================================================================================
if u'复权' in pdata:
adjdict= dict(pdata[u'复权'])
for idx, dstr in enumerate(pdata[u'日期']):
if dstr in adjdict:
axes_1.plot([idx, idx], [ylowlim_price, yhighlim_price], '-', color='purple', linewidth=0.3)
# 设定 X 轴坐标的范围
#==================================================================================================================================================
axes_1.set_xlim(-1, length)
# 先设置 label 位置,再将 X 轴上的坐标设为不可见。因为与 成交量子图 共用 X 轴
#==================================================================================================================================================
# 设定 X 轴的 Locator 和 Formatter
xaxis_1.set_major_locator(xMajorLocator)
xaxis_1.set_major_formatter(xMajorFormatter)
xaxis_1.set_minor_locator(xMinorLocator)
xaxis_1.set_minor_formatter(xMinorFormatter)
# 将 X 轴上的坐标设为不可见。
for malab in axes_1.get_xticklabels(minor=False):
malab.set_visible(False)
for milab in axes_1.get_xticklabels(minor=True):
milab.set_visible(False)
# 用这一段效果也一样
# pyplot.setp(axes_1.get_xticklabels(minor=False), visible=False)
# pyplot.setp(axes_1.get_xticklabels(minor=True), visible=False)
# 设定 Y 轴坐标的范围
#==================================================================================================================================================
axes_1.set_ylim(ylowlim_price, yhighlim_price)
# 设定 Y 轴上的坐标
#==================================================================================================================================================
# XXX: 不用 LogLocator 了,因为不能控制坐标点的位置。
# 主要坐标点
#----------------------------------------------------------------------------
yticks_major_pri= []
for i in range(1, 999):
newloc= ylowlim_price * (expbase**i)
if newloc <= yhighlim_price:
yticks_major_pri.append(newloc)
else:
break
yMajorLocator_1= FixedLocator(numpy.array(yticks_major_pri))
# 确定 Y 轴的 MajorFormatter
def y_major_formatter_1(num, pos=None):
return str(round(num/1000.0, 2))
yMajorFormatter_1= FuncFormatter(y_major_formatter_1)
# 设定 X 轴的 Locator 和 Formatter
yaxis_1.set_major_locator(yMajorLocator_1)
yaxis_1.set_major_formatter(yMajorFormatter_1)
# 设定 Y 轴主要坐标点与辅助坐标点的样式
for mal in axes_1.get_yticklabels(minor=False):
mal.set_fontsize(6)
# 辅助坐标点
#----------------------------------------------------------------------------
yticks_minor_pri= []
mtstart= ylowlim_price * (1.0+(expbase-1.0)/2)
for i in range(999):
newloc= mtstart * (expbase**i)
if newloc <= yhighlim_price:
yticks_minor_pri.append(newloc)
else:
break
yMinorLocator_1= FixedLocator(numpy.array(yticks_minor_pri)) # XXX minor ticks 已经在上面一并设置,这里不需要了。
# 确定 Y 轴的 MinorFormatter
def y_minor_formatter_1(num, pos=None):
return str(round(num/1000.0, 2))
yMinorFormatter_1= FuncFormatter(y_minor_formatter_1)
# 设定 X 轴的 Locator 和 Formatter
yaxis_1.set_minor_locator(yMinorLocator_1)
yaxis_1.set_minor_formatter(yMinorFormatter_1)
# 设定 Y 轴主要坐标点与辅助坐标点的样式
for mal in axes_1.get_yticklabels(minor=True):
mal.set_fontsize(5)
mal.set_color('blue')
# 第一只:价格数值在图中间的显示
#==================================================================================================================================================
for iy in yticks_major_pri:
for ix in mdindex[1:-1:3]:
newlab= axes_1.text(ix+8, iy*1.001, y_major_formatter_1(iy))
newlab.set_font_properties(__font_properties__)
newlab.set_color('0.3')
newlab.set_fontsize(3)
newlab.set_zorder(0) # XXX: 放在底层
# newlab.set_verticalalignment('center')
# 第一只:日期在图中间的显示
#==================================================================================================================================================
for iy in yticks_minor_pri[1:-1:5]:
for ix in mdindex:
newlab= axes_1.text(ix-1, iy, pdata[u'日期'][ix])
newlab.set_font_properties(__font_properties__)
newlab.set_color('0.3')
newlab.set_fontsize(4)
newlab.set_rotation('vertical')
# newlab.set_horizontalalignment('left')
# newlab.set_verticalalignment('bottom')
newlab.set_zorder(0) # XXX: 放在底层
# newlab.set_verticalalignment('center')
#==================================================================================================================================================
#==================================================================================================================================================
#=======
#======= XXX: 第二条 K 线图
#=======
#==================================================================================================================================================
#==================================================================================================================================================
# 添加 Axes 对象
#==================================================================================================================================================
axes_1_sec= axes_1.twinx()
# axes_1_sec.set_axisbelow(True) # 网格线放在底层
axes_1_sec.set_yscale('log', basey=expbase) # 使用对数坐标
# 得到 X 轴 和 Y 轴 的两个 Axis 对象
#==================================================================================================================================================
xaxis_1_sec= axes_1_sec.get_xaxis()
yaxis_1_sec= axes_1_sec.get_yaxis()
#==================================================================================================================================================
#======= 绘图
#==================================================================================================================================================
# 绘制 K 线部分
#==================================================================================================================================================
# 对开收盘价进行视觉修正
for idx, poc in enumerate( zipoc_sec ):
if poc[0] == poc[1] and None not in poc:
pdata[u'开盘二'][idx]= poc[0] - 5 # 稍微偏离一点,使得在图线上不致于完全看不到
pdata[u'收盘二'][idx]= poc[1] + 5
rarray_open= numpy.array(pdata[u'开盘二'])
rarray_close= numpy.array(pdata[u'收盘二'])
rarray_high= numpy.array(pdata[u'最高二'])
rarray_low= numpy.array(pdata[u'最低二'])
# XXX: 如果 up_sec, down_sec, side_sec 里有一个全部为 False 组成,那么 vlines() 会报错。
# XXX: 可以使用 alpha 参数调节透明度
if True in up_sec:
axes_1_sec.vlines(xindex[up_sec], rarray_low[up_sec], rarray_high[up_sec], edgecolor='red', linewidth=0.6, label='_nolegend_', alpha=0.3)
axes_1_sec.vlines(xindex[up_sec], rarray_open[up_sec], rarray_close[up_sec], edgecolor='red', linewidth=3.0, label='_nolegend_', alpha=0.3)
if True in down_sec:
axes_1_sec.vlines(xindex[down_sec], rarray_low[down_sec], rarray_high[down_sec], edgecolor='green', linewidth=0.6, label='_nolegend_', alpha=0.3)
axes_1_sec.vlines(xindex[down_sec], rarray_open[down_sec], rarray_close[down_sec], edgecolor='green', linewidth=3.0, label='_nolegend_', alpha=0.3)
if True in side_sec:
axes_1_sec.vlines(xindex[side_sec], rarray_low[side_sec], rarray_high[side_sec], edgecolor='0.7', linewidth=0.6, label='_nolegend_', alpha=0.3)
axes_1_sec.vlines(xindex[side_sec], rarray_open[side_sec], rarray_close[side_sec], edgecolor='0.7', linewidth=3.0, label='_nolegend_', alpha=0.3)
# 设定 X 轴坐标的范围
#==================================================================================================================================================
axes_1_sec.set_xlim(-1, length)
# 先设置 label 位置,再将 X 轴上的坐标设为不可见。因为与 成交量子图 共用 X 轴
#==================================================================================================================================================
# 设定 X 轴的 Locator 和 Formatter
xaxis_1_sec.set_major_locator(xMajorLocator)
xaxis_1_sec.set_major_formatter(xMajorFormatter)
xaxis_1_sec.set_minor_locator(xMinorLocator)
xaxis_1_sec.set_minor_formatter(xMinorFormatter)
# 将 X 轴上的坐标设为不可见。
for malab in axes_1_sec.get_xticklabels(minor=False):
malab.set_visible(False)
for milab in axes_1_sec.get_xticklabels(minor=True):
milab.set_visible(False)
# 设定 Y 轴坐标的范围
#==================================================================================================================================================
axes_1_sec.set_ylim(ylowlim_price*open_price_sec/open_price_pri, yhighlim_price*open_price_sec/open_price_pri)
# 设定 Y 轴上的坐标
#==================================================================================================================================================
# 主要坐标点
#----------------------------------------------------------------------------
yticks_major_sec= []
ylowlim_price_sec= ylowlim_price*open_price_sec/open_price_pri
yhighlim_price_sec= yhighlim_price*open_price_sec/open_price_pri
for i in range(1, 999):
newloc= ylowlim_price_sec * (expbase**i)
if newloc <= yhighlim_price_sec:
yticks_major_sec.append(newloc)
else:
break
yMajorLocator_1_sec= FixedLocator(numpy.array(yticks_major_sec))
# 确定 Y 轴的 MajorFormatter
def y_major_formatter_1_sec(num, pos=None):
return str(round(num/1000.0, 2))
yMajorFormatter_1_sec= FuncFormatter(y_major_formatter_1_sec)
# 设定 X 轴的 Locator 和 Formatter
yaxis_1_sec.set_major_locator(yMajorLocator_1_sec)
yaxis_1_sec.set_major_formatter(yMajorFormatter_1_sec)
# 设定 Y 轴主要坐标点与辅助坐标点的样式
for mal in axes_1_sec.get_yticklabels(minor=False):
mal.set_fontsize(6)
# 辅助坐标点
#----------------------------------------------------------------------------
yticks_minor_sec= []
mtstart_sec= ylowlim_price_sec * (1.0+(expbase-1.0)/2)
for i in range(999):
newloc= mtstart_sec * (expbase**i)
if newloc <= yhighlim_price_sec:
yticks_minor_sec.append(newloc)
else:
break
yMinorLocator_1_sec= FixedLocator(numpy.array(yticks_minor_sec)) # XXX minor ticks 已经在上面一并设置,这里不需要了。
# 确定 Y 轴的 MinorFormatter
def y_minor_formatter_1_sec(num, pos=None):
return str(round(num/1000.0, 2))
yMinorFormatter_1_sec= FuncFormatter(y_minor_formatter_1_sec)
# 设定 X 轴的 Locator 和 Formatter
yaxis_1_sec.set_minor_locator(yMinorLocator_1_sec)
yaxis_1_sec.set_minor_formatter(yMinorFormatter_1_sec)
# 设定 Y 轴主要坐标点与辅助坐标点的样式
for mal in axes_1_sec.get_yticklabels(minor=True):
mal.set_fontsize(5)
mal.set_color('blue')
# 显示图片
#==================================================================================================================================================
# pyplot.show()
# 保存图片
#==================================================================================================================================================
figobj.savefig(figpath, dpi=figdpi, facecolor=figfacecolor, edgecolor=figedgecolor, linewidth=figlinewidth)
if __name__ == '__main__':
Plot(pfile=sys.argv[1], figpath=sys.argv[2])

7
vn.training/t1.py Normal file
View File

@ -0,0 +1,7 @@
# encoding: UTF-8
import matplotlib.pyplot as plt
plt.plot([10,20,30])
plt.xlabel('times')
plt.ylabel('numbers')
plt.show()

BIN
vnctptd.pyd Normal file

Binary file not shown.

178
vnpy.pyproj Normal file
View File

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{5c9c864b-1736-4189-81b1-d32b67b54740}</ProjectGuid>
<ProjectHome />
<StartupFile>vn.event\eventEngine.py</StartupFile>
<SearchPath />
<WorkingDirectory>.</WorkingDirectory>
<OutputPath>.</OutputPath>
<ProjectTypeGuids>{888888a0-9f3d-457c-b088-3a5042f75d52}</ProjectTypeGuids>
<LaunchProvider>Standard Python launcher</LaunchProvider>
<InterpreterId>{2af0f10d-7135-4994-9156-5d01c9c11b7e}</InterpreterId>
<InterpreterVersion>2.7</InterpreterVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'" />
<PropertyGroup Condition="'$(Configuration)' == 'Release'" />
<PropertyGroup>
<VisualStudioVersion Condition=" '$(VisualStudioVersion)' == '' ">10.0</VisualStudioVersion>
<PtvsTargetsFile>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets</PtvsTargetsFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="vn.cs\vncshshlp\test\cstest.py" />
<Compile Include="vn.ctp\pyscript\ctp_data_type.py" />
<Compile Include="vn.ctp\pyscript\ctp_struct.py" />
<Compile Include="vn.ctp\pyscript\generate_data_type.py" />
<Compile Include="vn.ctp\pyscript\generate_md_functions.py" />
<Compile Include="vn.ctp\pyscript\generate_struct.py" />
<Compile Include="vn.ctp\pyscript\generate_td_functions.py" />
<Compile Include="vn.ctp\vnctpmd\test\mdtest.py" />
<Compile Include="vn.ctp\vnctptd\test\tdtest.py" />
<Compile Include="vn.datayes\api.py" />
<Compile Include="vn.datayes\errors.py" />
<Compile Include="vn.datayes\storage.py" />
<Compile Include="vn.datayes\tests.py" />
<Compile Include="vn.datayes\__init__.py" />
<Compile Include="vn.demo\ctpdemo\ctp_data_type.py" />
<Compile Include="vn.demo\ctpdemo\demoApi.py" />
<Compile Include="vn.demo\ctpdemo\demoEngine.py" />
<Compile Include="vn.demo\ctpdemo\demoMain.py" />
<Compile Include="vn.demo\ctpdemo\demoMain.pyw" />
<Compile Include="vn.demo\ctpdemo\demoUi.py" />
<Compile Include="vn.demo\ctpdemo\eventEngine.py" />
<Compile Include="vn.demo\ctpdemo\eventType.py" />
<Compile Include="vn.demo\ctpdemo\mdtest.py" />
<Compile Include="vn.demo\ctpdemo\tdtest.py" />
<Compile Include="vn.demo\ltsdemo\demoApi.py" />
<Compile Include="vn.demo\ltsdemo\demoEngine.py" />
<Compile Include="vn.demo\ltsdemo\demoMain.py" />
<Compile Include="vn.demo\ltsdemo\demoMain.pyw" />
<Compile Include="vn.demo\ltsdemo\demoUi.py" />
<Compile Include="vn.demo\ltsdemo\eventEngine.py" />
<Compile Include="vn.demo\ltsdemo\eventType.py" />
<Compile Include="vn.demo\ltsdemo\lts_data_type.py" />
<Compile Include="vn.event\eventEngine.py" />
<Compile Include="vn.event\eventType.py" />
<Compile Include="vn.lts\pyscript\generate_data_type.py" />
<Compile Include="vn.lts\pyscript\generate_md_functions.py" />
<Compile Include="vn.lts\pyscript\generate_struct.py" />
<Compile Include="vn.lts\pyscript\generate_td_functions.py" />
<Compile Include="vn.lts\pyscript\l2\generate_data_type.py" />
<Compile Include="vn.lts\pyscript\l2\generate_l2_functions.py" />
<Compile Include="vn.lts\pyscript\l2\generate_struct.py" />
<Compile Include="vn.lts\pyscript\l2\l2_data_type.py" />
<Compile Include="vn.lts\pyscript\l2\l2_struct.py" />
<Compile Include="vn.lts\pyscript\lts_data_type.py" />
<Compile Include="vn.lts\pyscript\lts_struct.py" />
<Compile Include="vn.lts\vnltsl2\test\l2test.py" />
<Compile Include="vn.lts\vnltsmd\test\mdtest.py" />
<Compile Include="vn.lts\vnltstd\test\lts_data_type.py" />
<Compile Include="vn.lts\vnltstd\test\tdtest.py" />
<Compile Include="vn.strategy\backtestingEngine.py" />
<Compile Include="vn.strategy\strategydemo\backtestingEngine.py" />
<Compile Include="vn.strategy\strategydemo\ctp_data_type.py" />
<Compile Include="vn.strategy\strategydemo\demoApi.py" />
<Compile Include="vn.strategy\strategydemo\demoBacktesting.py" />
<Compile Include="vn.strategy\strategydemo\demoEngine.py" />
<Compile Include="vn.strategy\strategydemo\demoStrategy.py" />
<Compile Include="vn.strategy\strategydemo\eventEngine.py" />
<Compile Include="vn.strategy\strategydemo\eventType.py" />
<Compile Include="vn.strategy\strategydemo\strategyEngine.py" />
<Compile Include="vn.strategy\strategyEngine.py" />
<Compile Include="vn.trader\ctpGateway.py" />
<Compile Include="vn.trader\eventEngine.py" />
<Compile Include="vn.trader\eventType.py" />
<Compile Include="vn.trader\gateway.py" />
</ItemGroup>
<ItemGroup>
<Content Include="vn.cs\hshlp\Hsconfig.ini" />
<Content Include="vn.cs\hshlp\t2sdk.ini" />
<Content Include="vn.cs\vncshshlp\test\Hsconfig.ini" />
<Content Include="vn.cs\vncshshlp\test\t2sdk.ini" />
<Content Include="vn.cs\vncshshlp\vncshshlp\ReadMe.txt" />
<Content Include="vn.ctp\vnctpmd\vnctpmd\ReadMe.txt" />
<Content Include="vn.ctp\vnctptd\vnctptd\ReadMe.txt" />
<Content Include="vn.datayes\static\figs\fig1.png" />
<Content Include="vn.datayes\static\figs\fig2.png" />
<Content Include="vn.datayes\static\figs\fig3.png" />
<Content Include="vn.datayes\static\figs\fig4.png" />
<Content Include="vn.datayes\static\figs\fig5.png" />
<Content Include="vn.datayes\static\figs\fig6.png" />
<Content Include="vn.demo\ctpdemo\exe\mdconnection\empty.txt" />
<Content Include="vn.demo\ctpdemo\exe\tdconnection\empty.txt" />
<Content Include="vn.demo\ctpdemo\mdconnection\empty.txt" />
<Content Include="vn.demo\ctpdemo\tdconnection\empty.txt" />
<Content Include="vn.demo\ctpdemo\vnpy.ico" />
<Content Include="vn.demo\ltsdemo\exe\l2connection\empty.txt" />
<Content Include="vn.demo\ltsdemo\exe\mdconnection\empty.txt" />
<Content Include="vn.demo\ltsdemo\exe\tdconnection\empty.txt" />
<Content Include="vn.demo\ltsdemo\l2connection\empty.txt" />
<Content Include="vn.demo\ltsdemo\mdconnection\empty.txt" />
<Content Include="vn.demo\ltsdemo\tdconnection\empty.txt" />
<Content Include="vn.demo\ltsdemo\vnpy.ico" />
<Content Include="vn.lts\vnltsl2\vnltsl2\ReadMe.txt" />
<Content Include="vn.lts\vnltsmd\pyltsmd\ReadMe.txt" />
<Content Include="vn.lts\vnltstd\pyltstd\ReadMe.txt" />
<Content Include="vn.strategy\strategydemo\mdconnection\empty.txt" />
<Content Include="vn.strategy\strategydemo\tdconnection\empty.txt" />
<Content Include="vn.strategy\strategydemo\vnpy.ico" />
</ItemGroup>
<ItemGroup>
<Folder Include="vn.cs\" />
<Folder Include="vn.cs\hshlp" />
<Folder Include="vn.cs\vncshshlp\" />
<Folder Include="vn.cs\vncshshlp\test" />
<Folder Include="vn.cs\vncshshlp\vncshshlp" />
<Folder Include="vn.ctp\" />
<Folder Include="vn.ctp\pyscript" />
<Folder Include="vn.ctp\vnctpmd\" />
<Folder Include="vn.ctp\vnctpmd\test" />
<Folder Include="vn.ctp\vnctpmd\vnctpmd" />
<Folder Include="vn.ctp\vnctptd\" />
<Folder Include="vn.ctp\vnctptd\test" />
<Folder Include="vn.ctp\vnctptd\vnctptd" />
<Folder Include="vn.datayes" />
<Folder Include="vn.datayes\static\" />
<Folder Include="vn.datayes\static\figs" />
<Folder Include="vn.demo\" />
<Folder Include="vn.demo\ctpdemo" />
<Folder Include="vn.demo\ctpdemo\exe\" />
<Folder Include="vn.demo\ctpdemo\exe\mdconnection" />
<Folder Include="vn.demo\ctpdemo\exe\tdconnection" />
<Folder Include="vn.demo\ctpdemo\mdconnection" />
<Folder Include="vn.demo\ctpdemo\tdconnection" />
<Folder Include="vn.demo\ltsdemo" />
<Folder Include="vn.demo\ltsdemo\exe\" />
<Folder Include="vn.demo\ltsdemo\exe\l2connection" />
<Folder Include="vn.demo\ltsdemo\exe\mdconnection" />
<Folder Include="vn.demo\ltsdemo\exe\tdconnection" />
<Folder Include="vn.demo\ltsdemo\l2connection" />
<Folder Include="vn.demo\ltsdemo\mdconnection" />
<Folder Include="vn.demo\ltsdemo\tdconnection" />
<Folder Include="vn.event" />
<Folder Include="vn.lts\" />
<Folder Include="vn.lts\pyscript" />
<Folder Include="vn.lts\pyscript\l2" />
<Folder Include="vn.lts\vnltsl2\" />
<Folder Include="vn.lts\vnltsl2\test" />
<Folder Include="vn.lts\vnltsl2\vnltsl2" />
<Folder Include="vn.lts\vnltsmd\" />
<Folder Include="vn.lts\vnltsmd\pyltsmd" />
<Folder Include="vn.lts\vnltsmd\test" />
<Folder Include="vn.lts\vnltstd\" />
<Folder Include="vn.lts\vnltstd\pyltstd" />
<Folder Include="vn.lts\vnltstd\test" />
<Folder Include="vn.strategy" />
<Folder Include="vn.strategy\strategydemo" />
<Folder Include="vn.strategy\strategydemo\mdconnection" />
<Folder Include="vn.strategy\strategydemo\tdconnection" />
<Folder Include="vn.trader" />
</ItemGroup>
<ItemGroup>
<InterpreterReference Include="{2af0f10d-7135-4994-9156-5d01c9c11b7e}\2.7" />
</ItemGroup>
<Import Project="$(PtvsTargetsFile)" Condition="Exists($(PtvsTargetsFile))" />
<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" Condition="!Exists($(PtvsTargetsFile))" />
</Project>