[Mod]改进DataRecoder中的DrEngine使用BarManager来合成K线

This commit is contained in:
vn.py 2017-10-18 13:14:57 +08:00
parent f861132c5c
commit 9e1d73cff5
5 changed files with 100 additions and 138 deletions

View File

@ -5,17 +5,29 @@
[ [
["rb1801", "CTP"], ["rb1801", "CTP"],
["m1801", "CTP"], ["m1801", "CTP"],
["TA801", "CTP"] ["SR801", "CTP"],
["IF1712", "CTP"],
["IH1712", "CTP"],
["IC1712", "CTP"]
], ],
"bar": "bar":
[ [
["rb1801", "CTP"], ["rb1801", "CTP"],
["m1801", "CTP"], ["m1801", "CTP"],
["TA801", "CTP"] ["SR801", "CTP"],
["IF1712", "CTP"],
["IH1712", "CTP"],
["IC1712", "CTP"]
], ],
"active": "active":
{ {
"rb.HOT": "rb1801",
"m.HOT": "m1801",
"SR.HOT": "SR801",
"IF.HOT": "IF1712",
"IH.HOT": "IH1712",
"IC.HOT": "IC1712"
} }
} }

View File

@ -12,5 +12,7 @@
"logActive": false, "logActive": false,
"logLevel": "debug", "logLevel": "debug",
"logConsole": true, "logConsole": true,
"logFile": true "logFile": true,
"tdPenalty": ["IF", "IH", "IC"]
} }

View File

@ -3,16 +3,31 @@
"tick": "tick":
[ [
["rb1801", "CTP"],
["m1801", "CTP"],
["SR801", "CTP"],
["IF1712", "CTP"],
["IH1712", "CTP"],
["IC1712", "CTP"]
], ],
"bar": "bar":
[ [
["BTC_CNY_SPOT", "OKCOIN"], ["rb1801", "CTP"],
["LTC_CNY_SPOT", "OKCOIN"], ["m1801", "CTP"],
["ETH_CNY_SPOT", "OKCOIN"] ["SR801", "CTP"],
["IF1712", "CTP"],
["IH1712", "CTP"],
["IC1712", "CTP"]
], ],
"active": "active":
{ {
"rb.HOT": "rb1801",
"m.HOT": "m1801",
"SR.HOT": "SR801",
"IF.HOT": "IF1712",
"IH.HOT": "IH1712",
"IC.HOT": "IC1712"
} }
} }

View File

@ -19,9 +19,10 @@ from vnpy.event import Event
from vnpy.trader.vtEvent import * from vnpy.trader.vtEvent import *
from vnpy.trader.vtFunction import todayDate, getJsonPath from vnpy.trader.vtFunction import todayDate, getJsonPath
from vnpy.trader.vtObject import VtSubscribeReq, VtLogData, VtBarData, VtTickData from vnpy.trader.vtObject import VtSubscribeReq, VtLogData, VtBarData, VtTickData
from vnpy.trader.app.ctaStrategy.ctaTemplate import BarManager
from vnpy.trader.app.dataRecorder.drBase import * from .drBase import *
from vnpy.trader.app.dataRecorder.language import text from .language import text
######################################################################## ########################################################################
@ -44,10 +45,10 @@ class DrEngine(object):
self.activeSymbolDict = {} self.activeSymbolDict = {}
# Tick对象字典 # Tick对象字典
self.tickDict = {} self.tickSymbolSet = set()
# K线对象字典 # K线合成器字典
self.barDict = {} self.bmDict = {}
# 配置字典 # 配置字典
self.settingDict = OrderedDict() self.settingDict = OrderedDict()
@ -77,11 +78,13 @@ class DrEngine(object):
if not working: if not working:
return return
# Tick记录配置
if 'tick' in drSetting: if 'tick' in drSetting:
l = drSetting['tick'] l = drSetting['tick']
for setting in l: for setting in l:
symbol = setting[0] symbol = setting[0]
gateway = setting[1]
vtSymbol = symbol vtSymbol = symbol
req = VtSubscribeReq() req = VtSubscribeReq()
@ -97,16 +100,17 @@ class DrEngine(object):
req.currency = setting[3] req.currency = setting[3]
req.productClass = setting[4] req.productClass = setting[4]
self.mainEngine.subscribe(req, setting[1]) self.mainEngine.subscribe(req, gateway)
tick = VtTickData() # 该tick实例可以用于缓存部分数据目前未使用 #tick = VtTickData() # 该tick实例可以用于缓存部分数据目前未使用
self.tickDict[vtSymbol] = tick #self.tickDict[vtSymbol] = tick
self.tickSymbolSet.add(vtSymbol)
# 保存到配置字典中 # 保存到配置字典中
if vtSymbol not in self.settingDict: if vtSymbol not in self.settingDict:
d = { d = {
'symbol': symbol, 'symbol': symbol,
'gateway': setting[1], 'gateway': gateway,
'tick': True 'tick': True
} }
self.settingDict[vtSymbol] = d self.settingDict[vtSymbol] = d
@ -114,11 +118,13 @@ class DrEngine(object):
d = self.settingDict[vtSymbol] d = self.settingDict[vtSymbol]
d['tick'] = True d['tick'] = True
# 分钟线记录配置
if 'bar' in drSetting: if 'bar' in drSetting:
l = drSetting['bar'] l = drSetting['bar']
for setting in l: for setting in l:
symbol = setting[0] symbol = setting[0]
gateway = setting[1]
vtSymbol = symbol vtSymbol = symbol
req = VtSubscribeReq() req = VtSubscribeReq()
@ -132,16 +138,13 @@ class DrEngine(object):
req.currency = setting[3] req.currency = setting[3]
req.productClass = setting[4] req.productClass = setting[4]
self.mainEngine.subscribe(req, setting[1]) self.mainEngine.subscribe(req, gateway)
bar = VtBarData()
self.barDict[vtSymbol] = bar
# 保存到配置字典中 # 保存到配置字典中
if vtSymbol not in self.settingDict: if vtSymbol not in self.settingDict:
d = { d = {
'symbol': symbol, 'symbol': symbol,
'gateway': setting[1], 'gateway': gateway,
'bar': True 'bar': True
} }
self.settingDict[vtSymbol] = d self.settingDict[vtSymbol] = d
@ -149,114 +152,64 @@ class DrEngine(object):
d = self.settingDict[vtSymbol] d = self.settingDict[vtSymbol]
d['bar'] = True d['bar'] = True
# 创建BarManager对象
self.bmDict[vtSymbol] = BarManager(self.onBar)
# 主力合约记录配置
if 'active' in drSetting: if 'active' in drSetting:
d = drSetting['active'] d = drSetting['active']
self.activeSymbolDict = {vtSymbol:activeSymbol for activeSymbol, vtSymbol in d.items()}
# 注意这里的vtSymbol对于IB和LTS接口应该后缀.交易所
for activeSymbol, vtSymbol in d.items():
self.activeSymbolDict[vtSymbol] = activeSymbol
# 保存到配置字典中
if vtSymbol not in self.settingDict:
d = {
'symbol': symbol,
'gateway': setting[1],
'active': True
}
self.settingDict[vtSymbol] = d
else:
d = self.settingDict[vtSymbol]
d['active'] = True
##----------------------------------------------------------------------
#def loadCsvSetting(self):
#"""加载CSV配置"""
#with open(self.settingFileName) as f:
#drSetting = csv.DictReader(f)
#for d in drSetting:
## 读取配置
#gatewayName = d['gateway']
#symbol = d['symbol']
#exchange = d['exchange']
#currency = d['currency']
#productClass = d['product']
#recordTick = d['tick']
#recordBar = d['bar']
#activeSymbol = d['active']
#if exchange:
#vtSymbol = '.'.join([symbol, exchange])
#else:
#vtSymbol = symbol
## 订阅行情
#req = VtSubscribeReq()
#req.symbol = symbol
#req.exchange = exchange
#req.currency = currency
#req.productClass = productClass
#self.mainEngine.subscribe(req, gatewayName)
## 设置需要记录的数据
#if recordTick:
#tick = VtTickData()
#self.tickDict[vtSymbol] = VtTickData()
#if recordBar:
#self.barDict[vtSymbol] = VtBarData()
#if activeSymbol:
#self.activeSymbolDict[vtSymbol] = activeSymbol
## 保存配置到缓存中
#self.settingDict[vtSymbol] = d
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def getSetting(self): def getSetting(self):
"""获取配置""" """获取配置"""
return self.settingDict return self.settingDict, self.activeSymbolDict
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def procecssTickEvent(self, event): def procecssTickEvent(self, event):
"""处理行情推送""" """处理行情事件"""
tick = event.dict_['data'] tick = event.dict_['data']
vtSymbol = tick.vtSymbol vtSymbol = tick.vtSymbol
# 转化Tick格式 # 生成datetime对象
if not tick.datetime: if not tick.datetime:
tick.datetime = datetime.strptime(' '.join([tick.date, tick.time]), '%Y%m%d %H:%M:%S.%f') tick.datetime = datetime.strptime(' '.join([tick.date, tick.time]), '%Y%m%d %H:%M:%S.%f')
# 更新Tick数据 self.onTick(tick)
if vtSymbol in self.tickDict:
bm = self.bmDict.get(vtSymbol, None)
if bm:
bm.updateTick(tick)
#----------------------------------------------------------------------
def onTick(self, tick):
"""Tick更新"""
vtSymbol = tick.vtSymbol
if vtSymbol in self.tickSymbolSet:
self.insertData(TICK_DB_NAME, vtSymbol, tick) self.insertData(TICK_DB_NAME, vtSymbol, tick)
if vtSymbol in self.activeSymbolDict: if vtSymbol in self.activeSymbolDict:
activeSymbol = self.activeSymbolDict[vtSymbol] activeSymbol = self.activeSymbolDict[vtSymbol]
self.insertData(TICK_DB_NAME, activeSymbol, tick) self.insertData(TICK_DB_NAME, activeSymbol, tick)
# 发出日志
self.writeDrLog(text.TICK_LOGGING_MESSAGE.format(symbol=tick.vtSymbol, self.writeDrLog(text.TICK_LOGGING_MESSAGE.format(symbol=tick.vtSymbol,
time=tick.time, time=tick.time,
last=tick.lastPrice, last=tick.lastPrice,
bid=tick.bidPrice1, bid=tick.bidPrice1,
ask=tick.askPrice1)) ask=tick.askPrice1))
# 更新分钟线数据 #----------------------------------------------------------------------
if vtSymbol in self.barDict: def onBar(self, bar):
bar = self.barDict[vtSymbol] """分钟线更新"""
vtSymbol = bar.vtSymbol
# 如果第一个TICK或者新的一分钟 self.insertData(MINUTE_DB_NAME, vtSymbol, bar)
if (not bar.datetime or
bar.datetime.minute != tick.datetime.minute or
bar.datetime.hour != tick.datetime.hour):
if bar.vtSymbol:
newBar = copy.copy(bar)
self.insertData(MINUTE_DB_NAME, vtSymbol, newBar)
if vtSymbol in self.activeSymbolDict: if vtSymbol in self.activeSymbolDict:
activeSymbol = self.activeSymbolDict[vtSymbol] activeSymbol = self.activeSymbolDict[vtSymbol]
self.insertData(MINUTE_DB_NAME, activeSymbol, newBar) self.insertData(MINUTE_DB_NAME, activeSymbol, bar)
self.writeDrLog(text.BAR_LOGGING_MESSAGE.format(symbol=bar.vtSymbol, self.writeDrLog(text.BAR_LOGGING_MESSAGE.format(symbol=bar.vtSymbol,
time=bar.time, time=bar.time,
@ -265,26 +218,6 @@ class DrEngine(object):
low=bar.low, low=bar.low,
close=bar.close)) close=bar.close))
bar.vtSymbol = tick.vtSymbol
bar.symbol = tick.symbol
bar.exchange = tick.exchange
bar.open = tick.lastPrice
bar.high = tick.lastPrice
bar.low = tick.lastPrice
bar.close = tick.lastPrice
bar.date = tick.date
bar.time = tick.time
bar.datetime = tick.datetime.replace(second=0, microsecond=0)
bar.volume = tick.volume
bar.openInterest = tick.openInterest
# 否则继续累加新的K线
else:
bar.high = max(bar.high, tick.lastPrice)
bar.low = min(bar.low, tick.lastPrice)
bar.close = tick.lastPrice
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def registerEvent(self): def registerEvent(self):
"""注册事件监听""" """注册事件监听"""

View File

@ -115,7 +115,7 @@ class DrEngineManager(QtWidgets.QWidget):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def updateSetting(self): def updateSetting(self):
"""显示引擎行情记录配置""" """显示引擎行情记录配置"""
setting = self.drEngine.getSetting() setting, activeSetting = self.drEngine.getSetting()
for d in setting.values(): for d in setting.values():
if 'tick' in d and d['tick']: if 'tick' in d and d['tick']:
@ -128,10 +128,10 @@ class DrEngineManager(QtWidgets.QWidget):
self.barTable.setItem(0, 0, TableCell(d['symbol'])) self.barTable.setItem(0, 0, TableCell(d['symbol']))
self.barTable.setItem(0, 1, TableCell(d['gateway'])) self.barTable.setItem(0, 1, TableCell(d['gateway']))
if 'active'in d and d['active']: for vtSymbol, activeSymbol in activeSetting.items():
self.activeTable.insertRow(0) self.activeTable.insertRow(0)
self.activeTable.setItem(0, 0, TableCell(d['active'])) self.activeTable.setItem(0, 0, TableCell(activeSymbol))
self.activeTable.setItem(0, 1, TableCell(d['symbol'])) self.activeTable.setItem(0, 1, TableCell(vtSymbol))
self.tickTable.resizeColumnsToContents() self.tickTable.resizeColumnsToContents()
self.barTable.resizeColumnsToContents() self.barTable.resizeColumnsToContents()