From 9e1d73cff5abe77f3b579540efe31098f142b0a7 Mon Sep 17 00:00:00 2001 From: "vn.py" Date: Wed, 18 Oct 2017 13:14:57 +0800 Subject: [PATCH] =?UTF-8?q?[Mod]=E6=94=B9=E8=BF=9BDataRecoder=E4=B8=AD?= =?UTF-8?q?=E7=9A=84DrEngine=E4=BD=BF=E7=94=A8BarManager=E6=9D=A5=E5=90=88?= =?UTF-8?q?=E6=88=90K=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/DataRecording/DR_setting.json | 16 +- examples/DataRecording/VT_setting.json | 4 +- examples/VnTrader/DR_setting.json | 21 ++- vnpy/trader/app/dataRecorder/drEngine.py | 181 +++++++-------------- vnpy/trader/app/dataRecorder/uiDrWidget.py | 16 +- 5 files changed, 100 insertions(+), 138 deletions(-) diff --git a/examples/DataRecording/DR_setting.json b/examples/DataRecording/DR_setting.json index 008c647e..5ec30169 100644 --- a/examples/DataRecording/DR_setting.json +++ b/examples/DataRecording/DR_setting.json @@ -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" } } \ No newline at end of file diff --git a/examples/DataRecording/VT_setting.json b/examples/DataRecording/VT_setting.json index ef3bb771..b5b81f40 100644 --- a/examples/DataRecording/VT_setting.json +++ b/examples/DataRecording/VT_setting.json @@ -12,5 +12,7 @@ "logActive": false, "logLevel": "debug", "logConsole": true, - "logFile": true + "logFile": true, + + "tdPenalty": ["IF", "IH", "IC"] } \ No newline at end of file diff --git a/examples/VnTrader/DR_setting.json b/examples/VnTrader/DR_setting.json index 07030299..5ec30169 100644 --- a/examples/VnTrader/DR_setting.json +++ b/examples/VnTrader/DR_setting.json @@ -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" } } \ No newline at end of file diff --git a/vnpy/trader/app/dataRecorder/drEngine.py b/vnpy/trader/app/dataRecorder/drEngine.py index f8d334bd..198f1f22 100644 --- a/vnpy/trader/app/dataRecorder/drEngine.py +++ b/vnpy/trader/app/dataRecorder/drEngine.py @@ -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): diff --git a/vnpy/trader/app/dataRecorder/uiDrWidget.py b/vnpy/trader/app/dataRecorder/uiDrWidget.py index 78a898fc..42f5ee0e 100644 --- a/vnpy/trader/app/dataRecorder/uiDrWidget.py +++ b/vnpy/trader/app/dataRecorder/uiDrWidget.py @@ -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()