save demostrategy data in backtesting
This commit is contained in:
commit
94399f2250
25
vn.data/test_tushare.py
Normal file
25
vn.data/test_tushare.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
|
import tushare as ts
|
||||||
|
import pandas as pd
|
||||||
|
import ipdb
|
||||||
|
|
||||||
|
data = ts.get_hist_data('600848', start='2015-04-01', end='2015-10-20') #一次性获取全部日k线数据
|
||||||
|
|
||||||
|
#print data.tail(10)
|
||||||
|
|
||||||
|
data.plot()
|
||||||
|
|
||||||
|
data.high.plot()
|
||||||
|
|
||||||
|
with pd.plot_params.use('x_compat',True):
|
||||||
|
data.open.plot(color = 'g')
|
||||||
|
data.close.plot(color = 'y')
|
||||||
|
data.high.plot(color = 'r')
|
||||||
|
data.low.plot(color = 'b')
|
||||||
|
|
||||||
|
|
||||||
|
with pd.plot_params.use('x_compat',True):
|
||||||
|
data.high.plot(color ='r', figsize = (10,4), grid ='on')
|
||||||
|
data.low.plot(color ='b', figsize = (10,4), grid ='on')
|
||||||
|
|
||||||
|
#ipdb.set_trace()
|
51
vn.training/crawl_shenzhen_exchange.py
Normal file
51
vn.training/crawl_shenzhen_exchange.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
import selenium
|
||||||
|
|
||||||
|
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
|
||||||
|
# from selenium.common.exceptions import TimeoutException
|
||||||
|
# from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0
|
||||||
|
|
||||||
|
def wait_condition_01(driver):
|
||||||
|
return driver.find_element_by_id('dateList_container_pageid')
|
||||||
|
|
||||||
|
def extract_table(driver, stocklist):
|
||||||
|
tag_table= driver.find_element_by_class_name("tablestyle")
|
||||||
|
tabletext= tag_table.text
|
||||||
|
stocklist.extend(tabletext.split('\n')[1:])
|
||||||
|
|
||||||
|
driver= selenium.webdriver.Firefox()
|
||||||
|
driver.get("http://www.sse.com.cn/assortment/stock/list/name/")
|
||||||
|
|
||||||
|
stocklist= []
|
||||||
|
extract_table(driver=driver, stocklist=stocklist)
|
||||||
|
|
||||||
|
tag_meta= driver.find_element_by_id("staticPagination")
|
||||||
|
attr_total= int(tag_meta.get_attribute("total"))
|
||||||
|
attr_pageCount= int(tag_meta.get_attribute("pageCount"))
|
||||||
|
|
||||||
|
# 逐页提取内容
|
||||||
|
for pagenr in range(2, attr_pageCount+1):
|
||||||
|
id_input= 'dateList_container_pageid' if pagenr > 2 else 'xsgf_pageid'
|
||||||
|
id_button= 'dateList_container_togo' if pagenr > 2 else 'xsgf_togo'
|
||||||
|
|
||||||
|
tag_input= driver.find_element_by_id(id_input)
|
||||||
|
tag_button= driver.find_element_by_id(id_button)
|
||||||
|
tag_input.send_keys(str(pagenr))
|
||||||
|
tag_button.click()
|
||||||
|
WebDriverWait(driver, 10).until(wait_condition_01)
|
||||||
|
|
||||||
|
extract_table(driver=driver, stocklist=stocklist)
|
||||||
|
|
||||||
|
# 向主调进程发送结果
|
||||||
|
data= {
|
||||||
|
'个股总数': attr_total,
|
||||||
|
'个股列表': stocklist,
|
||||||
|
}
|
||||||
|
|
||||||
|
driver.quit()
|
||||||
|
pdata= pickle.dumps(data, protocol=2)
|
||||||
|
sys.stdout.write( pdata + b'\n' )
|
47
vn.training/display_bar.py
Normal file
47
vn.training/display_bar.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
|
|
||||||
|
import MySQLdb
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
try:
|
||||||
|
#连接数据库
|
||||||
|
conn = MySQLdb.connect(host='vnpy.cloudapp.net', user='stockcn', passwd='7uhb*IJN', db='BackTest', port=3306)
|
||||||
|
|
||||||
|
#获取指针
|
||||||
|
cur = conn.cursor(MySQLdb.cursors.DictCursor)
|
||||||
|
|
||||||
|
symbol = 'a'
|
||||||
|
|
||||||
|
#执行脚本,返回记录数
|
||||||
|
count = cur.execute('select open,high,low, close,datetime from TB_Bar where Id=\'20151019-161753\'')
|
||||||
|
print 'there has %s rows record' % count
|
||||||
|
|
||||||
|
|
||||||
|
results = cur.fetchall()
|
||||||
|
|
||||||
|
|
||||||
|
t = []
|
||||||
|
|
||||||
|
o = []
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
|
||||||
|
for r in results:
|
||||||
|
i = i+1
|
||||||
|
t.append(i)
|
||||||
|
# t.append(r['datetime'])
|
||||||
|
o.append(r['open'])
|
||||||
|
|
||||||
|
|
||||||
|
#关闭指针,关闭连接
|
||||||
|
cur.close()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
plt.plot(t,o,label='data')
|
||||||
|
plt.xlabel('Time')
|
||||||
|
plt.ylabel('price')
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
except MySQLdb.Error, e:
|
||||||
|
print "Mysql Error %d: %s" % (e.args[0], e.args[1])
|
553
vn.training/quotation.py
Normal file
553
vn.training/quotation.py
Normal file
@ -0,0 +1,553 @@
|
|||||||
|
# -*- 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线数据
|
||||||
|
|
||||||
|
print data.tail(100)
|
||||||
|
|
||||||
|
|
||||||
|
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['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
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
802
vn.training/qutation2.py
Normal 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 file,figpath 指定图片需存放的路径
|
||||||
|
"""
|
||||||
|
|
||||||
|
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])
|
Loading…
Reference in New Issue
Block a user