From 75d631a495b4bf500e34263bf32a0f467513f6ea Mon Sep 17 00:00:00 2001 From: caimeng <862786917@qq.com> Date: Mon, 8 Apr 2019 09:47:44 +0800 Subject: [PATCH 1/8] composoryClose on volume --- vnpy/trader/utils/templates/spotOrderTemplate.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/vnpy/trader/utils/templates/spotOrderTemplate.py b/vnpy/trader/utils/templates/spotOrderTemplate.py index f442a3d..a9f33b7 100644 --- a/vnpy/trader/utils/templates/spotOrderTemplate.py +++ b/vnpy/trader/utils/templates/spotOrderTemplate.py @@ -1,4 +1,4 @@ -from vnpy.trader.utils.templates.orderTemplate import OrderTemplate, DIRECTION_MAP, ctaBase, constant +from vnpy.trader.utils.templates.orderTemplate import OrderTemplate, DIRECTION_MAP, ctaBase, constant, STATUS_FINISHED, showOrder import numpy as np @@ -15,6 +15,8 @@ class SpotOrderTemplate(OrderTemplate): _MAXIMUM_VOLUME_ADJUST = 1 + _ORIGIN_TRADED_VOLUME = "_ORIGIN_TRADED_VOLUME" + def maximumOrderVolume(self, vtSymbol, orderType, price=None): if self.getEngineType() != ctaBase.ENGINETYPE_TRADING: return np.inf @@ -47,4 +49,12 @@ def adjustVolume(self, vtSymbol, volume): if contract.minVolume: return int(volume/contract.minVolume) * contract.minVolume else: - return volume \ No newline at end of file + return volume + + def composoryClose(self, op, expire=None, volume=None): + if volume: + if op.order.status not in STATUS_FINISHED: + raise ValueError("Order not finished: %s" % showOrder(op.order, "vtOrderID", "status", "tradedVolume")) + op.order.tradedVolume = volume + op.info[self._ORIGIN_TRADED_VOLUME] = op.order.tradedVolume + return super().composoryClose(op, expire) From 081a37dcdd26de4be52e9ed1cff0d85e178f74d4 Mon Sep 17 00:00:00 2001 From: zef Date: Mon, 8 Apr 2019 13:57:46 +0800 Subject: [PATCH 2/8] merge --- vnpy/trader/gateway/okexGateway/spot.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vnpy/trader/gateway/okexGateway/spot.py b/vnpy/trader/gateway/okexGateway/spot.py index 745034d..25afeb2 100644 --- a/vnpy/trader/gateway/okexGateway/spot.py +++ b/vnpy/trader/gateway/okexGateway/spot.py @@ -27,6 +27,8 @@ # 方向和开平映射 typeMap = {} typeMap[(DIRECTION_LONG, OFFSET_OPEN)] = 'buy' +typeMap[(DIRECTION_LONG, OFFSET_CLOSE)] = 'buy' +typeMap[(DIRECTION_SHORT, OFFSET_OPEN)] = 'sell' typeMap[(DIRECTION_SHORT, OFFSET_CLOSE)] = 'sell' typeMapReverse = {v:k for k,v in typeMap.items()} From 796a769ae21ac2f2eec8a2ebfb917325788bf13e Mon Sep 17 00:00:00 2001 From: zef Date: Mon, 8 Apr 2019 14:24:14 +0800 Subject: [PATCH 3/8] merge --- vnpy/trader/utils/templates/orderTemplate.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/vnpy/trader/utils/templates/orderTemplate.py b/vnpy/trader/utils/templates/orderTemplate.py index c0056c4..6903896 100644 --- a/vnpy/trader/utils/templates/orderTemplate.py +++ b/vnpy/trader/utils/templates/orderTemplate.py @@ -418,9 +418,10 @@ def _round(self, value): def makeOrder(self, orderType, vtSymbol, price, volume, priceType=constant.PRICETYPE_LIMITPRICE, stop=False, **info): volume = self._round(volume) - assert volume > 0 + assert volume > 0, volume + price = self.adjustPrice(vtSymbol, price, "send order") - assert price > 0 + assert price > 0, price vtOrderIDList = self.sendOrder(orderType, vtSymbol, price, volume, priceType, stop) logging.debug("%s | makeOrder: %s, %s, %s, %s | into: %s", self.currentTime, orderType, vtSymbol, price, volume, info) @@ -1041,7 +1042,7 @@ def currentTime(self): def getExecPrice(self, vtSymbol, orderType): if orderType in self._ORDERTYPE_LONG: if vtSymbol in self._tickInstance: - return self._tickInstance[vtSymbol].upperLimit*0.99 + return self._tickInstance[vtSymbol].lastPrice * 1.02 elif vtSymbol in self._barInstance: return self._barInstance[vtSymbol].high else: @@ -1049,7 +1050,7 @@ def getExecPrice(self, vtSymbol, orderType): elif orderType in self._ORDERTYPE_SHORT: if vtSymbol in self._tickInstance: - return self._tickInstance[vtSymbol].lowerLimit*1.01 + return self._tickInstance[vtSymbol].lastPrice * 0.98 elif vtSymbol in self._barInstance: return self._barInstance[vtSymbol].low else: From ef52a80f3550b9838cac31c09ba12929a163081d Mon Sep 17 00:00:00 2001 From: ukamoy Date: Wed, 10 Apr 2019 14:36:54 +0800 Subject: [PATCH 4/8] fix - spot- datetime --- vnpy/trader/gateway/okexGateway/spot.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/vnpy/trader/gateway/okexGateway/spot.py b/vnpy/trader/gateway/okexGateway/spot.py index 25afeb2..f820ec8 100644 --- a/vnpy/trader/gateway/okexGateway/spot.py +++ b/vnpy/trader/gateway/okexGateway/spot.py @@ -741,9 +741,7 @@ def onSpotTick(self, d): tick.volume = float(data['quote_volume_24h']) tick.askPrice1 = float(data['best_ask']) tick.bidPrice1 = float(data['best_bid']) - tick.datetime = datetime.strptime(data['timestamp'], ISO_DATETIME_FORMAT) - tick.date = tick.datetime.strftime('%Y%m%d') - tick.time = tick.datetime.strftime('%H:%M:%S.%f') + tick.datetime, tick.date, tick.time = self.gateway.convertDatetime(data['timestamp']) tick.localTime = datetime.now() tick.volumeChange = 0 tick.lastVolume = 0 @@ -773,9 +771,7 @@ def onSpotDepth(self, d): tick.__setattr__(f'bidPrice{(idx + 1)}', float(price)) tick.__setattr__(f'bidVolume{(idx + 1)}', float(volume)) - tick.datetime = datetime.strptime(data['timestamp'], ISO_DATETIME_FORMAT) - tick.date = tick.datetime.strftime('%Y%m%d') - tick.time = tick.datetime.strftime('%H:%M:%S.%f') + tick.datetime, tick.date, tick.time = self.gateway.convertDatetime(data['timestamp']) tick.localTime = datetime.now() tick.volumeChange = 0 tick.lastVolume = 0 @@ -793,6 +789,7 @@ def onSpotTrades(self,d): tick.lastTradedTime = data['timestamp'] tick.type = data['side'] tick.volumeChange = 1 + tick.datetime, tick.date, tick.time = self.gateway.convertDatetime(data['timestamp']) tick.localTime = datetime.now() if tick.askPrice1: tick=copy(tick) From 250f311224a2a3b79df5856b29d3927e15b7a017 Mon Sep 17 00:00:00 2001 From: caimeng <862786917@qq.com> Date: Wed, 10 Apr 2019 15:02:25 +0800 Subject: [PATCH 5/8] update readme --- vnpy/trader/utils/templates/Readme.MD | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/vnpy/trader/utils/templates/Readme.MD b/vnpy/trader/utils/templates/Readme.MD index 730c2cb..15950a0 100644 --- a/vnpy/trader/utils/templates/Readme.MD +++ b/vnpy/trader/utils/templates/Readme.MD @@ -410,13 +410,17 @@ OrderPack.info 用于记录自定义信息,但是有一些字段已被占用 |price|float|限制价格。| |volume|float|下单数。| |expire|float|存在时间,秒数| -|vtOrderIDs|set|与该信息绑定的订单号| +|vtOrderIDs|set|与该信息绑定的未结束的订单号| +|closedOrderIDs|set|结束/有成交的订单号| +|inValidOrderIDs|set|结束/无成交的订单号| + ### 构造方法 **` TimeLimitOrderInfo.__init__(vtSymbol, orderType, volume, price, expire) `** + |name|type|description| |:-|:-|:-| |orderType|str|发单类型,支持ctaBase.CTAORDER_BUY, ctaBase.CTAORDER_COVER, ctaBase.CTAORDER_SELL, ctaBase.CTAORDER_SHORT。| @@ -434,11 +438,16 @@ TimeLimitOrderInfo.__init__(vtSymbol, orderType, volume, price, expire) 基础属性继承自TimeLimitOrderInfo -额外属性: - |name|type|description| |:-|:-|:-| |TYPE|str: "_ComposoryOrderInfo"|强制单单标记字段| +|orderType|str|发单类型,支持ctaBase.CTAORDER_BUY, ctaBase.CTAORDER_COVER, ctaBase.CTAORDER_SELL, ctaBase.CTAORDER_SHORT。| +|vtSymbol|str|品种名。| +|volume|float|下单数。| +|expire|float|存在时间,秒数| +|vtOrderIDs|set|与该信息绑定的未结束的订单号| +|closedOrderIDs|set|结束/有成交的订单号| +|inValidOrderIDs|set|结束/无成交的订单号| ## `class` AutoExitInfo From 96a1f4fdd5a3f6a97c8009e3c50e11684b5efb69 Mon Sep 17 00:00:00 2001 From: tianrq10 Date: Wed, 10 Apr 2019 18:56:18 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E3=80=90debug=E3=80=91=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BA=86tickdbName=E4=B8=BANone=E7=9A=84=E6=83=85=E5=86=B5?= =?UTF-8?q?=E4=B8=8B,=E8=BF=9B=E8=A1=8Ctick=E5=9B=9E=E6=B5=8B=E4=BC=9A?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E6=95=B0=E6=8D=AE=E5=BA=93=E5=87=BA=E9=94=99?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnpy/trader/app/ctaStrategy/ctaBacktesting.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/vnpy/trader/app/ctaStrategy/ctaBacktesting.py b/vnpy/trader/app/ctaStrategy/ctaBacktesting.py index 4618666..b2c0ce4 100644 --- a/vnpy/trader/app/ctaStrategy/ctaBacktesting.py +++ b/vnpy/trader/app/ctaStrategy/ctaBacktesting.py @@ -260,12 +260,13 @@ def loadHistoryData(self, symbolList, startDate, endDate=None, dataMode=None): self.output(f"{symbol}: 从本地缓存文件实取{acq}, 最大应取{need}, 还需从数据库取{need-acq}") # 如果没有完全从本地文件加载完数据, 则尝试从指定的mongodb下载数据, 并缓存到本地 - if self.dbURI: + dbName = None + if dataMode == self.BAR_MODE: + dbName = self.bardbName + else: + dbName = self.tickdbName + if self.dbURI and dbName is not None: # 有设置从指定数据库和表取数据 import pymongo - if dataMode == self.BAR_MODE: - dbName = self.bardbName - else: - dbName = self.tickdbName self.dbClient = pymongo.MongoClient(self.dbURI)[dbName] for symbol, need_datetimes in symbols_no_data.items(): if len(need_datetimes) > 0: # 需要从数据库取数据 @@ -300,7 +301,7 @@ def loadHistoryData(self, symbolList, startDate, endDate=None, dataMode=None): self.output("数据库没有 %s 这个品种" % symbol) self.output("这些品种在我们的数据库里: %s" % self.dbClient.collection_names()) else: - self.output('没有设置回测数据库URI, 无法回补缓存数据。请在回测设置 engine.setDB_URI("mongodb://localhost:27017")') + self.output('没有设置回测数据库相关信息, 无法回补缓存数据。请在回测入口设置 engine.setDB_URI 和 engine.setDatabase') if len(dataList) > 0: dataList.sort(key=lambda x: x.datetime) From 1dd518a42fc7cdc0c4b4af0e42c436acb1de734a Mon Sep 17 00:00:00 2001 From: caimeng <862786917@qq.com> Date: Thu, 11 Apr 2019 18:48:26 +0800 Subject: [PATCH 7/8] fix --- vnpy/trader/utils/templates/orderTemplate.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vnpy/trader/utils/templates/orderTemplate.py b/vnpy/trader/utils/templates/orderTemplate.py index 6903896..43cfd2b 100644 --- a/vnpy/trader/utils/templates/orderTemplate.py +++ b/vnpy/trader/utils/templates/orderTemplate.py @@ -708,9 +708,11 @@ def checkTimeLimitOrders(self): if not tlo.vtOrderIDs: pool.pop(id(tlo)) - def checkComposoryOrders(self): + def checkComposoryOrders(self, vtSymbol): pool = self._infoPool[ComposoryOrderInfo.TYPE] for cpo in list(pool.values()): + if cpo.vtSymbol != vtSymbol: + continue for op in self.iterValidOrderPacks(*cpo.vtOrderIDs): self.onComposoryOrder(op, True) if not cpo.vtOrderIDs: @@ -1155,7 +1157,7 @@ def onJoinOrderChild(self, op): self.onOrder(parent.order) def checkOnPeriodStart(self, bar): - self.checkComposoryOrders() + self.checkComposoryOrders(bar.vtSymbol) self.checkTimeLimitOrders() self.checkAutoExit(bar.vtSymbol) self.checkConditionalClose() From 64e86723bfec00cc34c03a160a2f1c6d13809478 Mon Sep 17 00:00:00 2001 From: caimeng <862786917@qq.com> Date: Fri, 12 Apr 2019 10:21:52 +0800 Subject: [PATCH 8/8] fix orderfilter --- vnpy/trader/utils/templates/orderTemplate.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/vnpy/trader/utils/templates/orderTemplate.py b/vnpy/trader/utils/templates/orderTemplate.py index 43cfd2b..836960b 100644 --- a/vnpy/trader/utils/templates/orderTemplate.py +++ b/vnpy/trader/utils/templates/orderTemplate.py @@ -388,6 +388,8 @@ def onOrder(self, order): else: if op.info.get(self._FINISH_TAG, False): return + if order.status in STATUS_FINISHED: + op.info[self._FINISH_TAG] = True op.order = order for name in op.tracks: @@ -400,10 +402,6 @@ def onOrder(self, order): self.onOrderPack(op) - if op.order.status in STATUS_FINISHED: - op.info[self._FINISH_TAG] = True - - def onOrderPack(self, op): pass