daily update
This commit is contained in:
parent
e5158b096b
commit
e48ba99820
@ -44,3 +44,6 @@ create table TB_Ema
|
||||
|
||||
);
|
||||
|
||||
delete from TB_Trade;
|
||||
delete from TB_Bar;
|
||||
delete from TB_Ema;
|
||||
|
@ -5,7 +5,7 @@ import ipdb
|
||||
|
||||
data = ts.get_hist_data('600848', start='2015-04-01', end='2015-10-20') #一次性获取全部日k线数据
|
||||
|
||||
#print data.tail(10)
|
||||
print data.tail(10)
|
||||
|
||||
data.plot()
|
||||
|
||||
|
@ -380,7 +380,7 @@ class BacktestingEngine(object):
|
||||
def saveTradeDataToMysql(self):
|
||||
"""保存交易记录到mysql,added by Incense Lee"""
|
||||
if self.__mysqlConnected:
|
||||
sql='insert into BackTest.TB_Trade (Id,symbol,orderRef,tradeID,direction,offset,price,volume,tradeTime) values '
|
||||
sql='insert into BackTest.TB_Trade (Id,symbol,orderRef,tradeID,direction,offset,price,volume,tradeTime,amount) values '
|
||||
values = ''
|
||||
|
||||
print u'共{0}条交易记录.'.format(len(self.listTrade))
|
||||
|
@ -22,7 +22,7 @@ def main():
|
||||
be.connectMysql()
|
||||
# be.loadMongoDataHistory(symbol, datetime(2015,5,1), datetime.today())
|
||||
# be.loadMongoDataHistory(symbol, datetime(2012,1,9), datetime(2012,1,14))
|
||||
be.loadMysqlDataHistory(symbol, datetime(2012,6,9), datetime(2012,6,20))
|
||||
be.loadMysqlDataHistory(symbol, datetime(2012,6,9), datetime(2012,7,20))
|
||||
|
||||
# 创建策略对象
|
||||
setting = {}
|
||||
|
@ -382,7 +382,7 @@ def main():
|
||||
# 创建策略对象
|
||||
setting = {}
|
||||
setting['fastAlpha'] = 0.2
|
||||
setting['slowAlpha'] = 0.05
|
||||
setting['slowAlpha'] = 0.09
|
||||
#se.createStrategy(u'EMA演示策略', 'IF1506', SimpleEmaStrategy, setting)
|
||||
se.createStrategy(u'EMA演示策略', 'a', SimpleEmaStrategy, setting)
|
||||
|
||||
|
@ -300,7 +300,7 @@ class StrategyEngine(object):
|
||||
self.writeLog(u'策略引擎连接MysqlDB成功')
|
||||
except ConnectionFailure:
|
||||
self.writeLog(u'策略引擎连接MysqlDB失败')
|
||||
#----------------------------------------------------------------------
|
||||
#----------------------------------------------------------------------
|
||||
def __recordTickToMysql(self, data):
|
||||
"""将Tick数据插入到MysqlDB中"""
|
||||
#if self.__mongoConnected:
|
||||
@ -309,6 +309,27 @@ class StrategyEngine(object):
|
||||
# self.__mongoTickDB[symbol].insert(data)
|
||||
pass
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __executeMysql(self, sql):
|
||||
"""执行mysql语句"""
|
||||
if not self.__mysqlConnected:
|
||||
self.__connectMysql()
|
||||
|
||||
cur = self.__mysqlConnection.cursor(MySQLdb.cursors.DictCursor)
|
||||
|
||||
try:
|
||||
cur.execute(sql)
|
||||
self.__mysqlConnection.commit()
|
||||
|
||||
except Exception, e:
|
||||
print e
|
||||
print sql
|
||||
|
||||
self.__connectMysql()
|
||||
cur = self.__mysqlConnection.cursor(MySQLdb.cursors.DictCursor)
|
||||
cur.execute(sql)
|
||||
self.__mysqlConnection.commit()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def loadTickFromMysql(self, symbol, startDate, endDate=None):
|
||||
"""从MysqlDB中读取Tick数据"""
|
||||
@ -424,7 +445,7 @@ class StrategyEngine(object):
|
||||
if len(barList) == 0:
|
||||
return
|
||||
|
||||
steps = 0
|
||||
counts = 0
|
||||
|
||||
for bar in barList:
|
||||
|
||||
@ -444,30 +465,25 @@ class StrategyEngine(object):
|
||||
bar.volume,
|
||||
bar.openInterest)
|
||||
|
||||
if steps > 3600:
|
||||
if counts >= 3600:
|
||||
|
||||
cur = self.__mysqlConnection.cursor(MySQLdb.cursors.DictCursor)
|
||||
|
||||
steps = 0
|
||||
|
||||
values = EMPTY_STRING
|
||||
self.__executeMysql(sql+values)
|
||||
|
||||
try:
|
||||
cur.execute(sql+values)
|
||||
self.__mysqlConnection.commit()
|
||||
except Exception, e:
|
||||
print e
|
||||
print u'写入{0}条Bar记录'.format(counts)
|
||||
|
||||
counts = 0
|
||||
values = ''
|
||||
|
||||
else:
|
||||
steps = steps + 1
|
||||
counts = counts + 1
|
||||
|
||||
cur = self.__mysqlConnection.cursor(MySQLdb.cursors.DictCursor)
|
||||
if counts > 0:
|
||||
|
||||
self.__executeMysql(sql+values)
|
||||
print u'写入{0}条Bar记录'.format(counts)
|
||||
|
||||
try:
|
||||
cur.execute(sql+values)
|
||||
self.__mysqlConnection.commit()
|
||||
except Exception, e:
|
||||
print e
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def saveEmaToMysql(self, id, emaList):
|
||||
@ -484,7 +500,7 @@ class StrategyEngine(object):
|
||||
if len(emaList) == 0:
|
||||
return
|
||||
|
||||
steps = 0
|
||||
counts = 0
|
||||
|
||||
for ema in emaList:
|
||||
|
||||
@ -500,31 +516,21 @@ class StrategyEngine(object):
|
||||
ema.time,
|
||||
ema.datetime.strftime('%Y-%m-%d %H:%M:%S'))
|
||||
|
||||
if steps > 3600:
|
||||
if counts >= 3600:
|
||||
|
||||
cur = self.__mysqlConnection.cursor(MySQLdb.cursors.DictCursor)
|
||||
self.__executeMysql(sql+values)
|
||||
print u'写入{0}条EMA记录'.format(counts)
|
||||
|
||||
steps = 0
|
||||
|
||||
values = EMPTY_STRING
|
||||
|
||||
try:
|
||||
cur.execute(sql+values)
|
||||
self.__mysqlConnection.commit()
|
||||
except Exception, e:
|
||||
print e
|
||||
counts = 0
|
||||
values = ''
|
||||
|
||||
else:
|
||||
steps = steps + 1
|
||||
counts = counts + 1
|
||||
|
||||
cur = self.__mysqlConnection.cursor(MySQLdb.cursors.DictCursor)
|
||||
if counts > 0:
|
||||
|
||||
try:
|
||||
cur.execute(sql+values)
|
||||
self.__mysqlConnection.commit()
|
||||
|
||||
except Exception, e:
|
||||
print e
|
||||
self.__executeMysql(sql+values)
|
||||
print u'写入{0}条EMA记录'.format(counts)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
480
vn.training/Public/Public.py
Normal file
480
vn.training/Public/Public.py
Normal 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)
|
||||
|
||||
|
||||
|
5
vn.training/Public/__init__.py
Normal file
5
vn.training/Public/__init__.py
Normal file
@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
|
||||
|
3
vn.training/SubPlot/__init__.py
Normal file
3
vn.training/SubPlot/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
284
vn.training/SubPlot/公司信息子图.py
Normal file
284
vn.training/SubPlot/公司信息子图.py
Normal 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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
580
vn.training/SubPlot/分时价格子图.py
Normal file
580
vn.training/SubPlot/分时价格子图.py
Normal 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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
436
vn.training/SubPlot/分时手数子图.py
Normal file
436
vn.training/SubPlot/分时手数子图.py
Normal 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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
23
vn.training/SubPlot/实盘价格子图.py
Normal file
23
vn.training/SubPlot/实盘价格子图.py
Normal file
@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class 实盘价格子图:
|
||||
'''
|
||||
|
||||
'''
|
||||
|
||||
def __init__(self, parent, 绘图数据):
|
||||
'''
|
||||
|
||||
'''
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
22
vn.training/SubPlot/实盘手数子图.py
Normal file
22
vn.training/SubPlot/实盘手数子图.py
Normal file
@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class 实盘手数子图:
|
||||
'''
|
||||
|
||||
'''
|
||||
|
||||
def __init__(self, parent, 绘图数据, 价格子图):
|
||||
'''
|
||||
|
||||
'''
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
1327
vn.training/SubPlot/日线价格子图.py
Normal file
1327
vn.training/SubPlot/日线价格子图.py
Normal file
File diff suppressed because it is too large
Load Diff
488
vn.training/SubPlot/日线换手子图.py
Normal file
488
vn.training/SubPlot/日线换手子图.py
Normal 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.绘制换手提示()
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -13,32 +13,49 @@ try:
|
||||
|
||||
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
|
||||
backtestingId = '20151021-170626'
|
||||
|
||||
#执行脚本,返回记录数
|
||||
count = cur.execute('select open,high,low, close,datetime from TB_Bar where Id=\'{0}\''.format(backtestingId))
|
||||
print 'there has %s rows bar record' % count
|
||||
|
||||
results = cur.fetchall()
|
||||
|
||||
|
||||
t = []
|
||||
|
||||
t1 = []
|
||||
o = []
|
||||
|
||||
i = 0
|
||||
|
||||
for r in results:
|
||||
i = i+1
|
||||
t.append(i)
|
||||
t1.append(i)
|
||||
# t.append(r['datetime'])
|
||||
o.append(r['open'])
|
||||
|
||||
count = cur.execute('select fastEMA,slowEMA,datetime from TB_Ema where Id=\'{0}\''.format(backtestingId))
|
||||
print 'there has %s rows ema record' % count
|
||||
|
||||
results = cur.fetchall()
|
||||
|
||||
fastEma = []
|
||||
slowEma = []
|
||||
t2 = []
|
||||
i = 0
|
||||
|
||||
for r in results:
|
||||
i = i+1
|
||||
t2.append(i)
|
||||
|
||||
fastEma.append(r['fastEMA'])
|
||||
slowEma.append(r['slowEMA'])
|
||||
|
||||
|
||||
#关闭指针,关闭连接
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
plt.plot(t,o,label='data')
|
||||
plt.plot(t1,o,label='data')
|
||||
plt.plot(t2,fastEma,label='fastEma')
|
||||
plt.plot(t2,slowEma,label='slowEma')
|
||||
plt.xlabel('Time')
|
||||
plt.ylabel('price')
|
||||
plt.show()
|
||||
|
1002
vn.training/draw.py
Normal file
1002
vn.training/draw.py
Normal file
File diff suppressed because it is too large
Load Diff
BIN
vn.training/draw_data.pickle
Normal file
BIN
vn.training/draw_data.pickle
Normal file
Binary file not shown.
@ -514,23 +514,30 @@ class Test(QtGui.QWidget):
|
||||
|
||||
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))
|
||||
#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] #开盘价
|
||||
|
Loading…
Reference in New Issue
Block a user