[Mod]改进DataRecoder中的DrEngine使用BarManager来合成K线
This commit is contained in:
parent
f861132c5c
commit
9e1d73cff5
@ -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"
|
||||
}
|
||||
}
|
@ -12,5 +12,7 @@
|
||||
"logActive": false,
|
||||
"logLevel": "debug",
|
||||
"logConsole": true,
|
||||
"logFile": true
|
||||
"logFile": true,
|
||||
|
||||
"tdPenalty": ["IF", "IH", "IC"]
|
||||
}
|
@ -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"
|
||||
}
|
||||
}
|
@ -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,16 +138,13 @@ 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
|
||||
@ -149,141 +152,71 @@ class DrEngine(object):
|
||||
d = self.settingDict[vtSymbol]
|
||||
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
|
||||
|
||||
##----------------------------------------------------------------------
|
||||
#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
|
||||
self.activeSymbolDict = {vtSymbol:activeSymbol for activeSymbol, vtSymbol in d.items()}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
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')
|
||||
|
||||
# 更新Tick数据
|
||||
if vtSymbol in self.tickDict:
|
||||
self.onTick(tick)
|
||||
|
||||
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]
|
||||
#----------------------------------------------------------------------
|
||||
def onBar(self, bar):
|
||||
"""分钟线更新"""
|
||||
vtSymbol = bar.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)
|
||||
self.insertData(MINUTE_DB_NAME, vtSymbol, bar)
|
||||
|
||||
if vtSymbol in self.activeSymbolDict:
|
||||
activeSymbol = self.activeSymbolDict[vtSymbol]
|
||||
self.insertData(MINUTE_DB_NAME, activeSymbol, newBar)
|
||||
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))
|
||||
|
||||
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
|
||||
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):
|
||||
|
@ -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()
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user