def sendOrder(self, vtSymbol, orderType, price, volume, priceType, levelRate, strategy): """发单""" contract = self.mainEngine.getContract(vtSymbol) req = VtOrderReq() req.symbol = contract.symbol req.exchange = contract.exchange req.vtSymbol = contract.vtSymbol req.price = self.roundToPriceTick(contract.priceTick, price) req.volume = volume req.productClass = strategy.productClass req.currency = strategy.currency req.byStrategy = strategy.name # 设计为CTA引擎发出的委托只允许使用限价单 # req.priceType = PRICETYPE_LIMITPRICE req.priceType = priceType req.levelRate = str(levelRate) # CTA委托类型映射 if orderType == CTAORDER_BUY: req.direction = DIRECTION_LONG req.offset = OFFSET_OPEN elif orderType == CTAORDER_SELL: req.direction = DIRECTION_SHORT req.offset = OFFSET_CLOSE elif orderType == CTAORDER_SHORT: req.direction = DIRECTION_SHORT req.offset = OFFSET_OPEN elif orderType == CTAORDER_COVER: req.direction = DIRECTION_LONG req.offset = OFFSET_CLOSE # 委托转换 reqList = self.mainEngine.convertOrderReq(req) vtOrderIDList = [] if not reqList: return vtOrderIDList for convertedReq in reqList: vtOrderID = self.mainEngine.sendOrder(convertedReq, contract.gatewayName) # 发单 self.orderStrategyDict[vtOrderID] = strategy # 保存vtOrderID和策略的映射关系 self.strategyOrderDict[strategy.name].add(vtOrderID) # 添加到策略委托号集合中 vtOrderIDList.append(vtOrderID) self.writeCtaLog('策略%s: 发送%s委托%s, 交易:%s,%s,数量:%s @ %s' % (strategy.name, priceType, vtOrderID, vtSymbol, orderType, volume, price)) return vtOrderIDList
def sendOrder(self, vtSymbol, orderType, price, volume, priceType, strategy): """发单""" contract = self.mainEngine.getContract(vtSymbol) req = VtOrderReq() reqList = [] req.symbol = contract.symbol req.exchange = contract.exchange req.vtSymbol = contract.vtSymbol req.price = self.roundToPriceTick(contract.priceTick, price) req.volume = volume req.productClass = strategy.productClass req.currency = strategy.currency req.byStrategy = strategy.name req.priceType = priceType # CTA委托类型映射 if orderType == CTAORDER_BUY: req.direction = constant.DIRECTION_LONG req.offset = constant.OFFSET_OPEN elif orderType == CTAORDER_SELL: req.direction = constant.DIRECTION_SHORT # 只有上期所才要考虑平今平昨 if contract.exchange != constant.EXCHANGE_SHFE: req.offset = constant.OFFSET_CLOSE else: # 获取持仓缓存数据 posBuffer = self.ydPositionDict.get(vtSymbol + '_LONG', None) # 如果获取持仓缓存失败,则默认平昨 if not posBuffer: self.writeCtaLog(u'获取昨持多仓为0, 发出平今指令') req.offset = constant.OFFSET_CLOSETODAY elif posBuffer: if volume <= posBuffer: req.offset = constant.OFFSET_CLOSE self.writeCtaLog( f'{vtSymbol}优先平昨, 昨多仓:{posBuffer}, 平仓数:{volume}') req.offset = constant.OFFSET_CLOSE if (posBuffer - volume) > 0: self.writeCtaLog( f'{vtSymbol}剩余昨多仓{(posBuffer - volume)}') else: req.offset = constant.OFFSET_CLOSE req.volume = posBuffer self.writeCtaLog( f'{vtSymbol}平仓量{volume}, 大于昨多仓, 拆分优先平昨仓数:{posBuffer}' ) req2 = copy(req) req2.offset = constant.OFFSET_CLOSETODAY req2.volume = volume - posBuffer self.writeCtaLog( f'{vtSymbol}平仓量大于昨多仓, 拆分到平今仓数:{req2.volume}') reqList.append(req2) elif orderType == CTAORDER_SHORT: req.direction = constant.DIRECTION_SHORT req.offset = constant.OFFSET_OPEN elif orderType == CTAORDER_COVER: req.direction = constant.DIRECTION_LONG # # 只有上期所才要考虑平今平昨 if contract.exchange != constant.EXCHANGE_SHFE: req.offset = constant.OFFSET_CLOSE else: # 获取持仓缓存数据 posBuffer = self.ydPositionDict.get(vtSymbol + '_SHORT', None) # 如果获取持仓缓存失败,则默认平昨 if not posBuffer: self.writeCtaLog(u'获取昨持空仓为0, 发出平今指令') req.offset = constant.OFFSET_CLOSETODAY elif posBuffer: if volume <= posBuffer: req.offset = constant.OFFSET_CLOSE self.writeCtaLog( f'{vtSymbol}优先平昨,昨空仓:{posBuffer}, 平仓数:{volume}') req.offset = constant.OFFSET_CLOSE if (posBuffer - volume) > 0: self.writeCtaLog( f'{vtSymbol}剩余昨空仓{(posBuffer - volume)}') else: req.offset = constant.OFFSET_CLOSE req.volume = posBuffer self.writeCtaLog( f'{vtSymbol}平仓量{volume}, 大于昨空仓, 拆分优先平昨仓数:{posBuffer}' ) req2 = copy(req) req2.offset = constant.OFFSET_CLOSETODAY req2.volume = volume - posBuffer self.writeCtaLog( f'{vtSymbol}平仓量大于昨空仓, 拆分到平今仓数:{req2.volume}') reqList.append(req2) # 委托转换 # reqList = self.mainEngine.convertOrderReq(req) # 不转了 reqList.append(req) vtOrderIDList = [] # if not reqList: # return vtOrderIDList for convertedReq in reqList: vtOrderID = self.mainEngine.sendOrder(convertedReq, contract.gatewayName) # 发单 self.orderStrategyDict[vtOrderID] = strategy # 保存vtOrderID和策略的映射关系 self.strategyOrderDict[strategy.name].add(vtOrderID) # 添加到策略委托号集合中 vtOrderIDList.append(vtOrderID) self.writeCtaLog('策略%s: 发送%s委托%s, 交易:%s,%s,数量:%s @ %s' % (strategy.name, priceType, vtOrderID, vtSymbol, orderType, volume, price)) return vtOrderIDList
def sendOrder(self, vtSymbol, orderType, price, volume, priceType, strategy): """发单""" contract = self.mainEngine.getContract(vtSymbol) req = VtOrderReq() reqcount = 1 req.symbol = contract.symbol req.exchange = contract.exchange req.vtSymbol = contract.vtSymbol req.price = self.roundToPriceTick(contract.priceTick, price) req.volume = volume req.productClass = strategy.productClass req.currency = strategy.currency req.byStrategy = strategy.name # 设计为CTA引擎发出的委托只允许使用限价单 # req.priceType = PRICETYPE_LIMITPRICE req.priceType = priceType # CTA委托类型映射 if orderType == CTAORDER_BUY: req.direction = DIRECTION_LONG req.offset = OFFSET_OPEN elif orderType == CTAORDER_SELL: req.direction = DIRECTION_SHORT # 只有上期所才要考虑平今平昨 if contract.exchange != EXCHANGE_SHFE: req.offset = OFFSET_CLOSE else: # 获取持仓缓存数据 posBuffer = self.ydPositionDict.get(vtSymbol+'_LONG', None) # 如果获取持仓缓存失败,则默认平昨 if not posBuffer: self.writeCtaLog(u'获取昨持多仓为0,发出平今指令') req.offset = OFFSET_CLOSETODAY elif posBuffer: if volume <= posBuffer: req.offset = OFFSET_CLOSE self.writeCtaLog(u'{}优先平昨,昨多仓:{},平仓数:{}'.format(vtSymbol, posBuffer, volume)) req.offset = OFFSET_CLOSE if (posBuffer - volume)>0: self.writeCtaLog(u'{}剩余昨多仓{}'.format(vtSymbol,(posBuffer - volume))) else: req.offset = OFFSET_CLOSE req.volume = posBuffer self.writeCtaLog(u'{}平仓量{},大于昨多仓,拆分优先平昨仓数:{}'.format(vtSymbol, volume, posBuffer)) req2 = copy(req) req2.offset = OFFSET_CLOSETODAY req2.volume = volume - posBuffer self.writeCtaLog(u'{}平仓量大于昨多仓,拆分到平今仓数:{}'.format(vtSymbol, req2.volume)) reqcount = 2 elif orderType == CTAORDER_SHORT: req.direction = DIRECTION_SHORT req.offset = OFFSET_OPEN elif orderType == CTAORDER_COVER: req.direction = DIRECTION_LONG # # 只有上期所才要考虑平今平昨 if contract.exchange != EXCHANGE_SHFE: req.offset = OFFSET_CLOSE else: # 获取持仓缓存数据 posBuffer = self.ydPositionDict.get(vtSymbol+'_SHORT', None) # 如果获取持仓缓存失败,则默认平昨 if not posBuffer: self.writeCtaLog(u'获取昨持空仓为0,发出平今指令') req.offset = OFFSET_CLOSETODAY elif posBuffer: if volume <= posBuffer: req.offset = OFFSET_CLOSE self.writeCtaLog(u'{}优先平昨,昨空仓:{},平仓数:{}'.format(vtSymbol, posBuffer, volume)) req.offset = OFFSET_CLOSE if (posBuffer - volume)>0: self.writeCtaLog(u'{}剩余昨空仓{}'.format(vtSymbol,(posBuffer - volume))) else: req.offset = OFFSET_CLOSE req.volume = posBuffer self.writeCtaLog(u'{}平仓量{},大于昨空仓,拆分优先平昨仓数:{}'.format(vtSymbol, volume, posBuffer)) req2 = copy(req) req2.offset = OFFSET_CLOSETODAY req2.volume = volume - posBuffer self.writeCtaLog(u'{}平仓量大于昨空仓,拆分到平今仓数:{}'.format(vtSymbol, req2.volume)) reqcount = 2 # 委托转换 # reqList = self.mainEngine.convertOrderReq(req) # 不转了 if reqcount == 1: reqList = [req] else: reqList = [req,req2] vtOrderIDList = [] # if not reqList: # return vtOrderIDList for convertedReq in reqList: vtOrderID = self.mainEngine.sendOrder(convertedReq, contract.gatewayName) # 发单 self.orderStrategyDict[vtOrderID] = strategy # 保存vtOrderID和策略的映射关系 self.strategyOrderDict[strategy.name].add(vtOrderID) # 添加到策略委托号集合中 vtOrderIDList.append(vtOrderID) self.writeCtaLog('策略%s: 发送%s委托%s, 交易:%s,%s,数量:%s @ %s' %(strategy.name, priceType, vtOrderID, vtSymbol, orderType, volume, price )) return vtOrderIDList
def sendOrder(self, vtSymbol, orderType, price, volume, priceType, strategy): """发单 cta引擎之中所有的操作都是基于引擎的,具体数据流为 strategy --->ctatemple----->ctaenging 在ctaenging 之中进行四个交易方向的order 分别为"买开" "卖开" "买平" "卖平" 这块是非常重要的,首先在存储的reqorder list 列表之中进行循环,调用底层接口进行发单,返回vtOrder;维护两个列表 orderStrategyDict[vtOrderID] 保存vtOrderID和strategy对象映射的字典(用于推送order和trade数据) key为vtOrderID,value为strategy对象; 保存策略名称和委托号列表的字典 key为name,value为保存orderID(限价+本地停止)的集合 """ contract = self.mainEngine.getContract(vtSymbol) req = VtOrderReq() reqcount = 1 req.symbol = contract.symbol req.exchange = contract.exchange req.vtSymbol = contract.vtSymbol req.price = self.roundToPriceTick(contract.priceTick, price) req.volume = volume req.productClass = strategy.productClass req.currency = strategy.currency req.byStrategy = strategy.name # 设计为CTA引擎发出的委托只允许使用限价单 # req.priceType = PRICETYPE_LIMITPRICE req.priceType = priceType # CTA委托类型映射 """ cta策略底层委托映射 可以根据传入的ordertype求出来相应的direction 和 offset,进而判断开平仓方向 注意这里使用的bitfinex 由于bitfinex gateway api 没有开平,所以需要在gateway 之中进行定义转换 """ if orderType == CTAORDER_BUY: req.direction = constant.DIRECTION_LONG req.offset = constant.OFFSET_OPEN elif orderType == CTAORDER_SELL: req.direction = constant.DIRECTION_SHORT # 只有上期所才要考虑平今平昨,上期所映射 if contract.exchange != constant.EXCHANGE_SHFE: req.offset = constant.OFFSET_CLOSE else: # 获取持仓缓存数据 posBuffer = self.ydPositionDict.get(vtSymbol + '_LONG', None) # 如果获取持仓缓存失败,则默认平昨 if not posBuffer: self.writeCtaLog(u'获取昨持多仓为0,发出平今指令') req.offset = constant.OFFSET_CLOSETODAY elif posBuffer: if volume <= posBuffer: req.offset = constant.OFFSET_CLOSE self.writeCtaLog(u'{}优先平昨,昨多仓:{},平仓数:{}'.format( vtSymbol, posBuffer, volume)) req.offset = constant.OFFSET_CLOSE if (posBuffer - volume) > 0: self.writeCtaLog(u'{}剩余昨多仓{}'.format( vtSymbol, (posBuffer - volume))) else: req.offset = constant.OFFSET_CLOSE req.volume = posBuffer self.writeCtaLog(u'{}平仓量{},大于昨多仓,拆分优先平昨仓数:{}'.format( vtSymbol, volume, posBuffer)) req2 = copy(req) req2.offset = constant.OFFSET_CLOSETODAY req2.volume = volume - posBuffer self.writeCtaLog(u'{}平仓量大于昨多仓,拆分到平今仓数:{}'.format( vtSymbol, req2.volume)) reqcount = 2 elif orderType == CTAORDER_SHORT: req.direction = constant.DIRECTION_SHORT req.offset = constant.OFFSET_OPEN elif orderType == CTAORDER_COVER: req.direction = constant.DIRECTION_LONG # # 只有上期所才要考虑平今平昨 if contract.exchange != constant.EXCHANGE_SHFE: req.offset = constant.OFFSET_CLOSE else: # 获取持仓缓存数据 posBuffer = self.ydPositionDict.get(vtSymbol + '_SHORT', None) # 如果获取持仓缓存失败,则默认平昨 if not posBuffer: self.writeCtaLog(u'获取昨持空仓为0,发出平今指令') req.offset = constant.OFFSET_CLOSETODAY elif posBuffer: if volume <= posBuffer: req.offset = constant.OFFSET_CLOSE self.writeCtaLog(u'{}优先平昨,昨空仓:{},平仓数:{}'.format( vtSymbol, posBuffer, volume)) req.offset = constant.OFFSET_CLOSE if (posBuffer - volume) > 0: self.writeCtaLog(u'{}剩余昨空仓{}'.format( vtSymbol, (posBuffer - volume))) else: req.offset = constant.OFFSET_CLOSE req.volume = posBuffer self.writeCtaLog(u'{}平仓量{},大于昨空仓,拆分优先平昨仓数:{}'.format( vtSymbol, volume, posBuffer)) req2 = copy(req) req2.offset = constant.OFFSET_CLOSETODAY req2.volume = volume - posBuffer self.writeCtaLog(u'{}平仓量大于昨空仓,拆分到平今仓数:{}'.format( vtSymbol, req2.volume)) reqcount = 2 # 委托转换 # reqList = self.mainEngine.convertOrderReq(req) # 不转了 if reqcount == 1: reqList = [req] else: reqList = [req, req2] vtOrderIDList = [] # 维系一个列表 vtOrderIDList # if not reqList: # return vtOrderIDList for convertedReq in reqList: vtOrderID = self.mainEngine.sendOrder(convertedReq, contract.gatewayName) # 发单 self.orderStrategyDict[vtOrderID] = strategy # 保存vtOrderID和策略的映射关系 self.strategyOrderDict[strategy.name].add(vtOrderID) # 添加到策略委托号集合中 vtOrderIDList.append(vtOrderID) self.writeCtaLog('策略%s: 发送%s委托%s, 交易:%s,%s,数量:%s @ %s' % (strategy.name, priceType, vtOrderID, vtSymbol, orderType, volume, price)) return vtOrderIDList