[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"],
["m1801", "CTP"],
["TA801", "CTP"]
["SR801", "CTP"],
["IF1712", "CTP"],
["IH1712", "CTP"],
["IC1712", "CTP"]
],
"bar":
[
["rb1801", "CTP"],
["m1801", "CTP"],
["TA801", "CTP"]
["SR801", "CTP"],
["IF1712", "CTP"],
["IH1712", "CTP"],
["IC1712", "CTP"]
],
"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,
"logLevel": "debug",
"logConsole": true,
"logFile": true
"logFile": true,
"tdPenalty": ["IF", "IH", "IC"]
}

View File

@ -3,16 +3,31 @@
"tick":
[
["rb1801", "CTP"],
["m1801", "CTP"],
["SR801", "CTP"],
["IF1712", "CTP"],
["IH1712", "CTP"],
["IC1712", "CTP"]
],
"bar":
[
["BTC_CNY_SPOT", "OKCOIN"],
["LTC_CNY_SPOT", "OKCOIN"],
["ETH_CNY_SPOT", "OKCOIN"]
["rb1801", "CTP"],
["m1801", "CTP"],
["SR801", "CTP"],
["IF1712", "CTP"],
["IH1712", "CTP"],
["IC1712", "CTP"]
],
"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.vtFunction import todayDate, getJsonPath
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 vnpy.trader.app.dataRecorder.language import text
from .drBase import *
from .language import text
########################################################################
@ -44,10 +45,10 @@ class DrEngine(object):
self.activeSymbolDict = {}
# Tick对象字典
self.tickDict = {}
self.tickSymbolSet = set()
# K线对象字典
self.barDict = {}
# K线合成器字典
self.bmDict = {}
# 配置字典
self.settingDict = OrderedDict()
@ -77,11 +78,13 @@ class DrEngine(object):
if not working:
return
# Tick记录配置
if 'tick' in drSetting:
l = drSetting['tick']
for setting in l:
symbol = setting[0]
gateway = setting[1]
vtSymbol = symbol
req = VtSubscribeReq()
@ -97,16 +100,17 @@ class DrEngine(object):
req.currency = setting[3]
req.productClass = setting[4]
self.mainEngine.subscribe(req, setting[1])
self.mainEngine.subscribe(req, gateway)
tick = VtTickData() # 该tick实例可以用于缓存部分数据目前未使用
self.tickDict[vtSymbol] = tick
#tick = VtTickData() # 该tick实例可以用于缓存部分数据目前未使用
#self.tickDict[vtSymbol] = tick
self.tickSymbolSet.add(vtSymbol)
# 保存到配置字典中
if vtSymbol not in self.settingDict:
d = {
'symbol': symbol,
'gateway': setting[1],
'gateway': gateway,
'tick': True
}
self.settingDict[vtSymbol] = d
@ -114,11 +118,13 @@ class DrEngine(object):
d = self.settingDict[vtSymbol]
d['tick'] = True
# 分钟线记录配置
if 'bar' in drSetting:
l = drSetting['bar']
for setting in l:
symbol = setting[0]
gateway = setting[1]
vtSymbol = symbol
req = VtSubscribeReq()
@ -132,158 +138,85 @@ class DrEngine(object):
req.currency = setting[3]
req.productClass = setting[4]
self.mainEngine.subscribe(req, setting[1])
bar = VtBarData()
self.barDict[vtSymbol] = bar
self.mainEngine.subscribe(req, gateway)
# 保存到配置字典中
if vtSymbol not in self.settingDict:
d = {
'symbol': symbol,
'gateway': setting[1],
'gateway': gateway,
'bar': True
}
self.settingDict[vtSymbol] = d
else:
d = self.settingDict[vtSymbol]
d['bar'] = True
d['bar'] = True
# 创建BarManager对象
self.bmDict[vtSymbol] = BarManager(self.onBar)
# 主力合约记录配置
if 'active' in drSetting:
d = drSetting['active']
# 注意这里的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
self.activeSymbolDict = {vtSymbol:activeSymbol for activeSymbol, vtSymbol in d.items()}
##----------------------------------------------------------------------
#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):
"""获取配置"""
return self.settingDict
return self.settingDict, self.activeSymbolDict
#----------------------------------------------------------------------
def procecssTickEvent(self, event):
"""处理行情推送"""
"""处理行情事件"""
tick = event.dict_['data']
vtSymbol = tick.vtSymbol
# 转化Tick格式
# 生成datetime对象
if not tick.datetime:
tick.datetime = datetime.strptime(' '.join([tick.date, tick.time]), '%Y%m%d %H:%M:%S.%f')
self.onTick(tick)
# 更新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)
if vtSymbol in self.activeSymbolDict:
activeSymbol = self.activeSymbolDict[vtSymbol]
self.insertData(TICK_DB_NAME, activeSymbol, tick)
# 发出日志
self.writeDrLog(text.TICK_LOGGING_MESSAGE.format(symbol=tick.vtSymbol,
time=tick.time,
last=tick.lastPrice,
bid=tick.bidPrice1,
ask=tick.askPrice1))
# 更新分钟线数据
if vtSymbol in self.barDict:
bar = self.barDict[vtSymbol]
# 如果第一个TICK或者新的一分钟
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:
activeSymbol = self.activeSymbolDict[vtSymbol]
self.insertData(MINUTE_DB_NAME, activeSymbol, newBar)
self.writeDrLog(text.BAR_LOGGING_MESSAGE.format(symbol=bar.vtSymbol,
time=bar.time,
open=bar.open,
high=bar.high,
low=bar.low,
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 onBar(self, bar):
"""分钟线更新"""
vtSymbol = bar.vtSymbol
self.insertData(MINUTE_DB_NAME, vtSymbol, bar)
if vtSymbol in self.activeSymbolDict:
activeSymbol = self.activeSymbolDict[vtSymbol]
self.insertData(MINUTE_DB_NAME, activeSymbol, bar)
self.writeDrLog(text.BAR_LOGGING_MESSAGE.format(symbol=bar.vtSymbol,
time=bar.time,
open=bar.open,
high=bar.high,
low=bar.low,
close=bar.close))
#----------------------------------------------------------------------
def registerEvent(self):

View File

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