From 97fcd7f19a0051aec1955f73fa2093cee4f599ca Mon Sep 17 00:00:00 2001 From: "vn.py" Date: Thu, 20 Dec 2018 09:55:48 +0800 Subject: [PATCH] =?UTF-8?q?[Mod]=E6=9B=B4=E6=96=B0=E5=AF=8C=E9=80=94?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E4=B8=BAfutu-api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 3 +- vnpy/trader/gateway/bithumb/bithumbGateway.py | 742 ------------------ .../trader/gateway/futuGateway/futuGateway.py | 10 +- vnpy/trader/uiMainWindow.py | 2 +- 4 files changed, 7 insertions(+), 750 deletions(-) delete mode 100644 vnpy/trader/gateway/bithumb/bithumbGateway.py diff --git a/requirements.txt b/requirements.txt index 6751b70d..54f8b972 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,6 @@ websocket-client msgpack-python qdarkstyle SortedContainers -futuquant wmi future flask-socketio @@ -16,4 +15,4 @@ pyqtgraph qtpy psutil ta-lib - +futu-api diff --git a/vnpy/trader/gateway/bithumb/bithumbGateway.py b/vnpy/trader/gateway/bithumb/bithumbGateway.py deleted file mode 100644 index 42c3e8e5..00000000 --- a/vnpy/trader/gateway/bithumb/bithumbGateway.py +++ /dev/null @@ -1,742 +0,0 @@ -# encoding: UTF-8 - -''' -vnpy.api.bithumb的gateway接入 -''' -import json -from collections import defaultdict -from datetime import datetime - -from vnpy.api.bithumb import BithumbRestApi -from vnpy.trader.vtFunction import getJsonPath -from vnpy.trader.vtGateway import * - -# 方向映射 -directionMap = { - constant.DIRECTION_LONG: 'bid', - constant.DIRECTION_SHORT: 'ask' -} -directionMapReverse = {v: k for k, v in directionMap.items()} - -# 从https://www.bithumb.com/u1/US127中https://api.bithumb.com/trade/place的API说明中得到 -minimum_ticks = { - 'BTC': 0.001, - 'ETH': 0.01, - 'DASH': 0.01, - 'LTC': 0.01, - 'ETC': 0.1, - 'XRP': 10, - 'BCH': 0.001, - 'XMR': 0.01, - 'ZEC': 0.01, - 'QTUM': 0.1, - 'BTG': 0.1, - 'EOS': 0.1, - 'ICX': 1, - 'VEN': 1, - 'TRX': 100, - 'ELF': 10, - 'MITH': 10, - 'MCO': 10, - 'OMG': 0.1, - 'KNC': 1, - 'GNT': 10, - 'HSR': 1, - 'ZIL': 100, - 'ETHOS': 1, - 'PAY': 1, - 'WAX': 10, - 'POWR': 10, - 'LRC': 10, - 'GTO': 10, - 'STEEM': 10, - 'STRAT': 1, - 'ZRX': 1, - 'REP': 0.1, - 'AE': 1, - 'XEM': 10, - 'SNT': 10, - 'ADA': 10 -} - - -######################################################################## -class BithumbGateway(VtGateway): - - #---------------------------------------------------------------------- - def __init__(self, eventEngine, gatewayName='BithumbGateway'): - super(BithumbGateway, self).__init__(eventEngine, gatewayName) - - self.restApi = RestApi(self) # type: RestApi - - self.qryEnabled = False - - self.fileName = self.gatewayName + '_connect.json' - self.filePath = getJsonPath(self.fileName, __file__) - - #---------------------------------------------------------------------- - def connect(self): - """连接""" - try: - f = open(self.filePath) - except IOError: - log = VtLogData() - log.gatewayName = self.gatewayName - log.logContent = u'读取连接配置出错,请检查' - self.onLog(log) - return - - # 解析json文件 - setting = json.load(f) - f.close() - try: - apiKey = str(setting['apiKey']) - apiSecret = str(setting['apiSecret']) - # symbols = setting['symbols'] - except KeyError: - log = VtLogData() - log.gatewayName = self.gatewayName - log.logContent = u'连接配置缺少字段,请检查' - self.onLog(log) - return - - # 创建行情和交易接口对象 - self.restApi.connect(apiKey, apiSecret) - - # 初始化并启动查询 - self.initQuery() - - #---------------------------------------------------------------------- - def subscribe(self, subscribeReq): - """订阅行情""" - pass - - #---------------------------------------------------------------------- - def sendOrder(self, orderReq): - """发单""" - return self.restApi.sendOrder(orderReq) - - #---------------------------------------------------------------------- - def cancelOrder(self, cancelOrderReq): - """撤单""" - self.restApi.cancelOrder(cancelOrderReq) - - #---------------------------------------------------------------------- - def close(self): - """关闭""" - self.restApi.close() - - #---------------------------------------------------------------------- - def initQuery(self): - """初始化连续查询""" - # if self.qryEnabled: - # 需要循环的查询函数列表 - # self.qryFunctionList = [self.restApi.qryTickers, - # self.restApi.qryDepth, - # self.restApi.qryPosition, - # self.restApi.qryOrder] - # - # self.qryCount = 0 # 查询触发倒计时 - # self.qryTrigger = 1 # 查询触发点 - # self.qryNextFunction = 0 # 上次运行的查询函数索引 - # - # self.startQuery() - pass - - #---------------------------------------------------------------------- - def query(self, event): - """注册到事件处理引擎上的查询函数""" - # self.qryCount += 1 - # - # if self.qryCount > self.qryTrigger: - # # 清空倒计时 - # self.qryCount = 0 - # - # # 执行查询函数 - # function = self.qryFunctionList[self.qryNextFunction] - # function() - # - # # 计算下次查询函数的索引,如果超过了列表长度,则重新设为0 - # self.qryNextFunction += 1 - # if self.qryNextFunction == len(self.qryFunctionList): - # self.qryNextFunction = 0 - pass - - #---------------------------------------------------------------------- - def startQuery(self): - """启动连续查询""" - self.eventEngine.register(EVENT_TIMER, self.query) - - #---------------------------------------------------------------------- - def setQryEnabled(self, qryEnabled): - """设置是否要启动循环查询""" - self.qryEnabled = qryEnabled - - -######################################################################## -# noinspection PyUnusedLocal -class RestApi(BithumbRestApi): - """REST API实现""" - - #---------------------------------------------------------------------- - def __init__(self, gateway): - """Constructor""" - super(RestApi, self).__init__() - - self.gateway = gateway # type: BithumbGateway # gateway对象 - self.gatewayName = gateway.gatewayName # gateway对象名称 - - self.localID = 0 - self.tradeID = 0 - - self.orders = {} # type: dict[str, VtOrderData] # localID:order - self.sysLocalDict = {} # type: dict[str, str] # sysID: localID - self.localSysDict = {} # type: dict[str, str] # localID: sysID - self.reqOrderDict = {} # type: dict[int, VtOrderData] # reqID:order - self.cancelDict = {} # type: dict[str, VtCancelOrderReq] # localID:req - - self.tickDict = {} - - #---------------------------------------------------------------------- - def connect(self, apiKey, apiSecret): - """连接服务器""" - self.init(apiKey, apiSecret) - self.start() - - # self.symbols = symbols - self.writeLog(u'REST API启动成功') - - self.qryContract() - - #---------------------------------------------------------------------- - def writeLog(self, content): - """发出日志""" - log = VtLogData() - log.gatewayName = self.gatewayName - log.logContent = content - self.gateway.onLog(log) - - #---------------------------------------------------------------------- - def generateLocalOrder(self, ): - self.localID += 1 - localID = str(self.localID) - order = VtOrderData() - order.gatewayName = self.gatewayName - order.status = constant.STATUS_UNKNOWN - order.exchange = constant.EXCHANGE_BITHUMB - order.orderID = localID - order.vtOrderID = '.'.join([self.gatewayName, localID]) - self.orders[localID] = order - return order - - #---------------------------------------------------------------------- - def sendOrder(self, orderReq): - """下单""" - req = { - 'order_currency': orderReq.symbol, - 'Payment_currency': orderReq.currency, # todo: 无论如何服务器都会以KRW作为单位 - 'type': directionMap[orderReq.direction], - 'price': int(orderReq.price), - 'units': orderReq.volume - } - - reqid = self.addReq('POST', '/trade/place', self.onSendOrder, postdict=req) - - # 缓存委托数据对象 - order = self.generateLocalOrder() - self.fillLocalOrder(order, - orderReq.symbol, - orderReq.price, - orderReq.volume, - orderReq.direction) - - self.reqOrderDict[reqid] = order - return order.vtOrderID - - #---------------------------------------------------------------------- - def onSendOrder(self, data, reqid): # type: (dict, int)->None - """下单回执""" - if self.checkError(u'委托', data): - return - - order = self.reqOrderDict[reqid] - localID = order.orderID - sysID = data['order_id'] - - self.saveSysIDForOrder(order, sysID) - - self.gateway.onOrder(order) - - # 发出等待的撤单委托 - if localID in self.cancelDict: - req = self.cancelDict[localID] - self.cancelOrder(req) - del self.cancelDict[localID] - - #---------------------------------------------------------------------- - @staticmethod - def fillLocalOrder(order, symbol, price, totalVolume, direction): - order.symbol = symbol - order.vtSymbol = '.'.join([order.symbol, order.exchange]) - order.price = price - order.totalVolume = totalVolume - order.direction = direction - - #---------------------------------------------------------------------- - def saveSysIDForOrder(self, order, sysID): # type: (VtOrderData, str)->None - self.sysLocalDict[sysID] = order.orderID - self.localSysDict[order.orderID] = sysID - - #---------------------------------------------------------------------- - def qryOrder(self, order): # type: (VtOrderData)->None - sysID = self.getSysIDForOrder(order) - req = { - 'currency': order.symbol, - 'order_id': sysID - } - self.addReq('POST', '/info/orders', self.onQryOrders, postdict=req) - - #---------------------------------------------------------------------- - def qryOrders(self, currency='XML'): # type: (VtOrderData)->None - sysID = self.getSysIDForOrder(order) - req = { - 'currency': order.symbol, - } - self.addReq('POST', '/info/orders', self.onQryOrders, postdict=req) - - #---------------------------------------------------------------------- - def onQryOrders(self, data, reqid): - if self.checkError(u'订单查询', data): - return - orders = data['data'] - for detail in orders: - sysID = detail['order_id'] - order = self.getOrderBySysID(sysID) - if not order: - # 查询到了新的order(以前的order) - order = self.generateLocalOrder() - self.fillLocalOrder(order, - detail['order_currency'], - detail['price'], - detail['units'], - directionMapReverse[detail['type']]) - order.tradedVolume = order.totalVolume - detail['units_remaining'] - # todo: payment_currency - # payment_currency = detail['payment_currency'] - self.saveSysIDForOrder(order, sysID) - - # 推送 - self.gateway.onOrder(order) - continue - - originalTradeVolume = order.tradedVolume - order.tradedVolume = newTradeVolume = order.totalVolume - detail['units_remaining'] - - if newTradeVolume != originalTradeVolume: - # 推送更新 - self.gateway.onOrder(order) - - # 尝试更新状态 - # todo: 这一句还未测试,不知道成交之后date_completed是不是就会有值 - order.status = constant.STATUS_ALLTRADED if detail['date_completed'] else order.status - if order.status == constant.STATUS_ALLTRADED: - # 推送成交 - self.pushOrderAsTraded(order) - - #---------------------------------------------------------------------- - def pushOrderAsTraded(self, order): - trade = VtTradeData() - trade.gatewayName = order.gatewayName - trade.symbol = order.symbol - trade.vtSymbol = order.vtSymbol - trade.orderID = order.orderID - trade.vtOrderID = order.vtOrderID - self.tradeID += 1 - trade.tradeID = str(self.tradeID) - trade.vtTradeID = '.'.join([self.gatewayName, trade.tradeID]) - trade.direction = order.direction - trade.price = order.price - trade.volume = order.tradedVolume - trade.tradeTime = datetime.now().strftime('%H:%M:%S') - self.gateway.onTrade(trade) - - #---------------------------------------------------------------------- - def cancelOrder(self, cancelOrderReq): # type: (self, VtCancelOrderReq)->None - """""" - localID = cancelOrderReq.orderID - order = self.getOrderByLocalID(localID) - - if self.isOrderPosted(order): - sysID = self.getSysIDForOrder(order) - req = { - 'type': directionMap[order.direction], - 'order_id': sysID, - 'currency': cancelOrderReq.symbol - } - self.addReq('POST', - '/trade/cancel', - callback=lambda data, reqid: self.onCancelOrder(localID, data, reqid), - postdict=req) - else: - self.cancelDict[localID] = cancelOrderReq - - #---------------------------------------------------------------------- - def onCancelOrder(self, localID, data, reqid): - if self.checkError(u'撤单', data): - return - order = self.getOrderByLocalID(localID) - order.status = constant.STATUS_CANCELLED - - #---------------------------------------------------------------------- - def qryContract(self): - """""" - contract = VtContractData() - contract.gatewayName = self.gatewayName - - for symbol, tick in minimum_ticks.items(): - contract.symbol = symbol - contract.exchange = constant.EXCHANGE_BITHUMB - contract.vtSymbol = '.'.join([contract.symbol, contract.exchange]) - contract.name = contract.vtSymbol - contract.productClass = constant.PRODUCT_SPOT - contract.priceTick = tick - contract.size = 1 - self.gateway.onContract(contract) - - #---------------------------------------------------------------------- - def qryPublicTick(self, symbol='ALL'): - """ symbol 可以是'BTC', 'ETC'等等电子货币符号;也可以使用'ALL',表示要获取所有货币的行情""" - url = '/public/ticker/' + symbol - if symbol.upper() == 'ALL': - self.addReq('GET', url, self.onQryMultiPublicTicker) - else: - self.addReq('GET', url, - callback=lambda data, reqid: self.onQrySinglePublicTicker(symbol, data, id)) - - #---------------------------------------------------------------------- - def qryPublicOrderBook(self, symbol='ALL'): - """ symbol 可以是'BTC', 'ETC'等等电子货币符号;也可以使用'ALL',表示要获取所有货币的行情""" - url = '/public/orderbook/' + symbol - if symbol.upper() == 'ALL': - self.addReq('GET', url, self.onQryMultiPublicOrderBook) - else: - self.addReq('GET', url, - callback=lambda data, reqid: self.onQrySinglePublicOrderBook(symbol, data, id)) - - #---------------------------------------------------------------------- - def qryPrivateTick(self, symbol, currency='CNY'): - """""" - req = { - 'order_currency': symbol, - 'payment_currency': currency, - } - self.addReq('POST', '/info/ticker', self.onQryPrivateTicker, postdict=req) - - #---------------------------------------------------------------------- - def qryPosition(self, symbol='ALL'): - """""" - req = { - 'currency': symbol, - } - self.addReq('POST', '/info/balance', self.onQryPosition, postdict=req) - - pass - - #---------------------------------------------------------------------- - def onQryPosition(self, data, reqid): # type: (self, dict, int)->None - """""" - if self.checkError(u'查询持仓', data): - return - - datas = data['data'] # type: dict - - # 先分类一下 - infos = defaultdict(dict) # type: dict[str, dict[str, str]] - for key, val in datas.items(): # type: str, str - split_position = key.rfind('_') - infoType, symbol = key[:split_position], key[split_position+1:] - infos[symbol.upper()][infoType] = val - - for symbol in infos.keys(): - info = infos[symbol] - if symbol == u'LAST': # 过滤掉xcoin_last,这个值表示的是最后一次交易量 - continue - if symbol == u'KRW': - accountData = VtAccountData() - # todo: accountID必须从另一个API获取 - # accountData.accountID = - accountData.balance = info['total'] - accountData.available = info['available'] - self.gateway.onAccount(accountData) - pass - else: - pos = VtPositionData() - pos.gatewayName = self.gatewayName - - pos.symbol = symbol - pos.exchange = constant.EXCHANGE_BITHUMB - pos.vtSymbol = '.'.join([pos.symbol, pos.exchange]) - pos.direction = constant.DIRECTION_NET - pos.vtPositionName = '.'.join([pos.vtSymbol, pos.direction]) - pos.position = float(info['total']) - pos.frozen = float(info['in_use']) - - self.gateway.onPosition(pos) - - #---------------------------------------------------------------------- - def parsePublicTickerData(self, symbol, info): - dt = datetime.now() - date = dt.strftime('%Y%m%d') - time = dt.strftime('%H:%M:%S') - - tick = self.getTick(symbol) - - tick.openPrice = float(info['opening_price']) - tick.highPrice = float(info['max_price']) - tick.lowPrice = float(info['min_price']) - tick.lastPrice = float(info['closing_price']) # todo: 也许应该是'buy_price'? - tick.volume = float(info['volume_1day']) - tick.datetime = datetime - tick.date = date - tick.time = time - - # 只有订阅了深度行情才推送 - if tick.bidPrice1: - self.gateway.onTick(tick) - - #---------------------------------------------------------------------- - def onQrySinglePublicTicker(self, symbol, data, reqid): - if self.checkError(u'查询行情', data): - return - - info = data['data'] - self.parsePublicTickerData(symbol=symbol, info=info) - - #---------------------------------------------------------------------- - def onQryMultiPublicTicker(self, data, reqid): - if self.checkError(u'查询行情', data): - return - - for symbol, info in data['data'].items(): - # 里面可能会出现一对:date: int这样的值,所以要过滤掉 - if isinstance(info, dict): - self.parsePublicTickerData(symbol=symbol, info=info) - pass - - #---------------------------------------------------------------------- - def parsePublicOrderBookData(self, symbol, info): - dt = datetime.now() - date = dt.strftime('%Y%m%d') - time = dt.strftime('%H:%M:%S') - - tick = self.getTick(symbol) - - for i in range(5): - tick.__setattr__('askPrice' + str(i + 1), float(info['asks'][i]['price'])) - tick.__setattr__('askVolume' + str(i + 1), float(info['asks'][i]['quantity'])) - - for i in range(5): - tick.__setattr__('bidPrice' + str(i + 1), float(info['bids'][i]['price'])) - tick.__setattr__('bidVolume' + str(i + 1), float(info['bids'][i]['quantity'])) - - tick.datetime = datetime - tick.date = date - tick.time = time - - # 只有订阅了深度行情才推送 - if tick.bidPrice1: - self.gateway.onTick(tick) - - #---------------------------------------------------------------------- - def onQrySinglePublicOrderBook(self, symbol, data, reqid): - if self.checkError(u'五档行情', data): - return - - info = data['data'] - self.parsePublicTickerData(symbol=symbol, info=info) - pass - - #---------------------------------------------------------------------- - def onQryMultiPublicOrderBook(self, data, reqid): - if self.checkError(u'五档行情', data): - return - - for symbol, info in data['data'].items(): - self.parsePublicTickerData(symbol=symbol, info=info) - pass - - #---------------------------------------------------------------------- - def onQryPrivateTicker(self, data, reqid): - pass - - #---------------------------------------------------------------------- - def getTick(self, symbol): - """""" - tick = self.tickDict.get(symbol, None) # type: VtTickData - - if not tick: - tick = VtTickData() - tick.gatewayName = self.gatewayName - tick.symbol = symbol - tick.exchange = constant.EXCHANGE_BITHUMB - tick.vtSymbol = '.'.join([tick.symbol, tick.exchange]) - self.tickDict[symbol] = tick - - return tick - - #---------------------------------------------------------------------- - def checkError(self, name, data): - """""" - status = data.get('status', None) - if status == u'0000': - return False - elif not status: - self.writeLog(u'%s触发错误:%s' % (name, u"未知的响应报文 : %s".format(data))) - return True - - msg = data.get('message', u'unknown') - self.writeLog(u'%s触发错误:%s' % (name, msg)) - return True - - #---------------------------------------------------------------------- - def getOrderByLocalID(self, localID): # type: (str)->VtOrderData - """如果没有该订单,这个函数会出错""" - return self.orders[localID] - - #---------------------------------------------------------------------- - def getOrderByVtOrderID(self, vtOrderId): # type: (str)->VtOrderData - """如果没有该订单,这个函数会出错""" - localID = vtOrderId[vtOrderId.rfind('.') + 1:] - return self.getOrderByLocalID(localID) - - #---------------------------------------------------------------------- - def getOrderBySysID(self, sysID): # type: (str)->VtOrderData - return self.getOrderByLocalID(self.getLocalIDBySysID(sysID)) - - #---------------------------------------------------------------------- - def getLocalIDBySysID(self, sysID): # type: (str)->str - return self.sysLocalDict[sysID] - - #---------------------------------------------------------------------- - def isOrderPosted(self, order): # type: (VtOrderData)->bool - """检查服务器是否响应了一个下单请求,如果已经响应了返回True,否则False""" - return order.orderID in self.localSysDict - - #---------------------------------------------------------------------- - def getSysIDForOrder(self, order): # type: (VtOrderData)->str - return self.localSysDict[order.orderID] - - #---------------------------------------------------------------------- - def hasSysID(self, sysID): - return sysID in self.sysLocalDict - - - -if __name__ == '__main__': - # default test secret: - API_KEY = '0c2f5621ac18d26d51ce640b25eb44f9' - API_SECRET = '62bb8b4e263476f443f8d3dbf0aad6bc' - - api = BithumbRestApi() - api.init(apiKey=API_KEY, apiSecret=API_SECRET) - api.start(1) - - eventEngine = EventEngine2() - rest = RestApi(BithumbGateway(eventEngine=eventEngine)) - rest.connect(API_KEY, API_SECRET) - - translateDict = { - u'\uac70\ub798 \uccb4\uacb0\ub0b4\uc5ed\uc774 ' - u'\uc874\uc7ac\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.': "交易记录不存在", - - u'\uac70\ub798 \uc9c4\ud589\uc911\uc778 \ub0b4\uc5ed\uc774 ' - u'\uc874\uc7ac\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.': "没有正在进行的交易", - - u'\ub9e4\uc218\uae08\uc561\uc774 \uc0ac\uc6a9\uac00\ub2a5 KRW' - u' \ub97c \ucd08\uacfc\ud558\uc600\uc2b5\ub2c8\ub2e4.': "购买金额超过可用KRW", - - u'\ub9e4\uc218\uac74\uc758 \uc0c1\ud0dc\uac00 \uc9c4\ud589\uc911\uc774 \uc544\ub2d9\ub2c8\ub2e4. ' - u'\ucde8\uc18c\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.': "购买查询的状态未在进行中。 它无法取消。", - - u'\uc9c0\uc6d0\ud558\uc9c0 \uc54a\ub294 \ud654\ud3d0\uc785\ub2c8\ub2e4. [347]': "不支持该货币单位。[347]", - } - - def printError(jsonObj): - if rest.checkError('', data=jsonObj): - print('error : ') - msg = jsonObj['message'] - print(translateDict.get(msg, msg)) - - def manualCancelOrder(sysID): - def onTradeCancel(jsonObj, reqid): - print('onTradeCancel : \n{}'.format(jsonObj)) - printError(jsonObj) - - rest.addReq('POST', '/trade/cancel', onTradeCancel, - postdict={'type': 'bid', 'order_id': sysID, 'currency': 'XMR'}) - - def apiCancelOrder(localId): - cancelReq = VtCancelOrderReq() - cancelReq.symbol = order.symbol - cancelReq.orderID = localId - rest.cancelOrder(cancelReq) - - # query tick - rest.qryPublicTick('BTC') - rest.qryPublicTick('ALL') - rest.qryPosition('BTC') - rest.qryPosition('ALL') - - # send order - sendOrderReq = VtOrderReq() - sendOrderReq.symbol = 'XMR' - sendOrderReq.direction = constant.DIRECTION_LONG - sendOrderReq.volume = minimum_ticks['XMR'] - # sendOrderReq.price = 700 - # sendOrderReq.currency = 'CNY' # 不可用 - # sendOrderReq.price = 16.6461 - # sendOrderReq.currency = 'USD' # 不可用 - sendOrderReq.price = 17500 - sendOrderReq.currency = 'KRW' - - vtOrderId = rest.sendOrder(sendOrderReq) - order = rest.getOrderByVtOrderID(vtOrderId) - - # todo: order的状态表示不够清晰 - while not rest.isOrderPosted(order): - time.sleep(0.1) - - sysID = rest.getSysIDForOrder(order) - print("sysID : ") - print(sysID) - - def onOrders(jsonObj, reqid): - print('on_orders : \n{}'.format(jsonObj)) - printError(jsonObj) - - for detail in jsonObj['data']: - sysID = detail['order_id'] - if rest.hasSysID(sysID): - apiCancelOrder(rest.getLocalIDBySysID(sysID)) - else: - manualCancelOrder(sysID) - - after = '1531926544794' # 2018-07-18T15:09:04.794Z - # rest.addReq('POST', '/info/orders', on_orders, - # postdict={'order_id': sysID, 'type': 'bid', 'after': after, 'currency': 'XMR'}) # got - # - # rest.addReq('POST', '/info/orders', on_orders, - # postdict={'order_id': sysID, 'type': 'bid', 'currency': 'XMR'}) # got - # - # rest.addReq('POST', '/info/orders', on_orders, - # postdict={'after': after, 'currency': 'XMR'}) # got - rest.addReq('POST', '/info/orders', onOrders, postdict={'currency': 'XMR'}) # got - - # rest.addReq('POST', '/info/orders', on_orders, - # postdict={'order_id': sysID, 'type': 'bid', 'after': after}) # 没有正在进行的交易 - # - # rest.addReq('POST', '/info/orders', on_orders, postdict={'after': after}) # 没有正在进行的交易 - # rest.addReq('POST', '/info/orders', on_orders, postdict={}) # 没有正在进行的交易 - # rest.addReq('POST', '/info/orders', on_orders, postdict={'currency': 'ALL'}) # 不支持该货币单位 - - raw_input() diff --git a/vnpy/trader/gateway/futuGateway/futuGateway.py b/vnpy/trader/gateway/futuGateway/futuGateway.py index 1fbabb13..861f93a2 100644 --- a/vnpy/trader/gateway/futuGateway/futuGateway.py +++ b/vnpy/trader/gateway/futuGateway/futuGateway.py @@ -11,11 +11,11 @@ from time import sleep from datetime import datetime from copy import copy -from futuquant import (OpenQuoteContext, OpenHKTradeContext, OpenUSTradeContext, - RET_ERROR, RET_OK, - TrdEnv, TrdSide, OrderType, OrderStatus, ModifyOrderOp, - StockQuoteHandlerBase, OrderBookHandlerBase, - TradeOrderHandlerBase, TradeDealHandlerBase) +from futu import (OpenQuoteContext, OpenHKTradeContext, OpenUSTradeContext, + RET_ERROR, RET_OK, + TrdEnv, TrdSide, OrderType, OrderStatus, ModifyOrderOp, + StockQuoteHandlerBase, OrderBookHandlerBase, + TradeOrderHandlerBase, TradeDealHandlerBase) from vnpy.trader.vtGateway import * from vnpy.trader.vtConstant import GATEWAYTYPE_INTERNATIONAL diff --git a/vnpy/trader/uiMainWindow.py b/vnpy/trader/uiMainWindow.py index 8e0f555a..058d3bfb 100644 --- a/vnpy/trader/uiMainWindow.py +++ b/vnpy/trader/uiMainWindow.py @@ -36,7 +36,7 @@ class MainWindow(QtWidgets.QMainWindow): #---------------------------------------------------------------------- def initUi(self): """初始化界面""" - self.setWindowTitle('VnTrader') + self.setWindowTitle('VN Trader') self.initCentral() self.initMenu() self.initStatusBar()