From e61754f1ae54ae17a9fc32b7241b0aa5dd2b06fb Mon Sep 17 00:00:00 2001 From: msincenselee Date: Thu, 9 Aug 2018 23:08:17 +0800 Subject: [PATCH] update --- vnpy/api/okex/Client.py | 14 ++- vnpy/api/okex/OkcoinSpotAPI.py | 23 +++- vnpy/api/okex/vnokex.py | 79 ++++++------ .../trader/gateway/okexGateway/okexGateway.py | 117 +++++++++++++++--- 4 files changed, 172 insertions(+), 61 deletions(-) diff --git a/vnpy/api/okex/Client.py b/vnpy/api/okex/Client.py index 31503158..c5a10e21 100644 --- a/vnpy/api/okex/Client.py +++ b/vnpy/api/okex/Client.py @@ -9,7 +9,7 @@ from OkcoinFutureAPI import OKCoinFuture #初始化apikey,secretkey,url apikey = 'XXXX' secretkey = 'XXXXX' -okcoinRESTURL = 'www.okcoin.com' #请求注意:国内账号需要 修改为 www.okcoin.cn +okcoinRESTURL = 'www.okex.com' #请求注意:国内账号需要 修改为 www.okcoin.cn #现货API okcoinSpot = OKCoinSpot(okcoinRESTURL,apikey,secretkey) @@ -17,11 +17,15 @@ okcoinSpot = OKCoinSpot(okcoinRESTURL,apikey,secretkey) #期货API okcoinFuture = OKCoinFuture(okcoinRESTURL,apikey,secretkey) -print (u' 现货行情 ') -print (okcoinSpot.ticker('btc_usd')) +#print (u' 现货行情 ') +#print (okcoinSpot.ticker('btc_usdt')) + +#print (u' 现货深度 ') +#print (okcoinSpot.depth('btc_usdt')) + +print (u' K线数据 ') +print (okcoinSpot.kline(symbol='btc_usdt',type_='1day')) -print (u' 现货深度 ') -print (okcoinSpot.depth('btc_usd')) #print (u' 现货历史交易信息 ') #print (okcoinSpot.trades()) diff --git a/vnpy/api/okex/OkcoinSpotAPI.py b/vnpy/api/okex/OkcoinSpotAPI.py index e4284832..5a3f7146 100644 --- a/vnpy/api/okex/OkcoinSpotAPI.py +++ b/vnpy/api/okex/OkcoinSpotAPI.py @@ -4,7 +4,6 @@ from vnpy.api.okex.HttpMD5Util import buildMySign,httpGet,httpPost class OKCoinSpot: - def __init__(self,url,apikey,secretkey): self.__url = url self.__apikey = apikey @@ -26,7 +25,27 @@ class OKCoinSpot: params = 'symbol=%(symbol)s' %{'symbol':symbol} return httpGet(self.__url,DEPTH_RESOURCE,params) - #获取OKCOIN现货历史交易信息 + def kline(self,symbol,type_,size_=None, since=None): + """ + 获取OKEx币币K线数据(每个周期数据条数2000左右) + :param symbol:币对如ltc_btc + :param type_: 1min/3min/5min/15min/30min/1day/3day/1week/1hour/2hour/4hour/6hour/12hour + :param size_: 默认全部 + :param since: 时间戳,返回该时间戳以后的数据(例如1417536000000) + :return: + """ + KLINE_RESOURCE = "/api/v1/kline.do" + + params = 'symbol={}&type={}'.format(symbol,type_) + + if size_ is not None and isinstance(size_,int): + params = params + '&size={}'.format(size_) + + if since is not None and isinstance(since,int): + params = params + '&since={}'.format(since) + return httpGet(self.__url, KLINE_RESOURCE, params) + + #获取OKCOIN现货历史交易信息 def trades(self,symbol = ''): TRADES_RESOURCE = "/api/v1/trades.do" params='' diff --git a/vnpy/api/okex/vnokex.py b/vnpy/api/okex/vnokex.py index bed328fb..ed97910c 100644 --- a/vnpy/api/okex/vnokex.py +++ b/vnpy/api/okex/vnokex.py @@ -29,27 +29,27 @@ SPOT_CURRENCY = ["usdt", "eos"] SPOT_SYMBOL_PAIRS = set(["ltc_btc", - "eos_usdt", - "eth_btc", - "etc_btc", - "bch_btc", - "btc_usdt", - "eth_usdt", - "ltc_usdt", - "etc_usdt", - "bch_usdt", - "etc_eth", - "bt1_btc", - "bt2_btc", - "btg_btc", - "qtum_btc", - "hsr_btc", - "neo_btc", - "gas_btc", - "qtum_usdt", - "hsr_usdt", - "neo_usdt", - "gas_usdt"]) + "eth_btc", + "etc_btc", + "bch_btc", + "btc_usdt", + "eth_usdt", + "ltc_usdt", + "etc_usdt", + "bch_usdt", + "etc_eth", + "bt1_btc", + "bt2_btc", + "btg_btc", + "qtum_btc", + "hsr_btc", + "neo_btc", + "gas_btc", + "qtum_usdt", + "hsr_usdt", + "neo_usdt", + "gas_usdt", + "eos_usdt"]) KLINE_PERIOD = ["1min","3min","5min","15min","30min","1hour","2hour","4hour","6hour","12hour","day","3day","week"] @@ -191,7 +191,7 @@ class OkexApi(object): #---------------------------------------------------------------------- def sendRequest(self, channel, params): """发送指令请求""" - print(u'vnokex.sendRequest:{}'.format(channel)) + #print(u'vnokex.sendRequest:{}'.format(channel)) # 在参数字典中加上api_key和签名字段 params['api_key'] = self.apiKey params['sign'] = self.generateSign(params) @@ -214,7 +214,7 @@ class OkexApi(object): #---------------------------------------------------------------------- def sendDataRequest(self, channel): """发送数据请求""" - print(u'vnokex.sendDataRequest:{}'.format(channel)) + #print(u'vnokex.sendDataRequest:{}'.format(channel)) d = {} d['event'] = 'addChannel' d['channel'] = channel @@ -236,7 +236,7 @@ class OkexApi(object): d = {'event': 'ping'} # 若触发异常则重连 try: - print(u'vnokex.sendHeartBeat') + #print(u'vnokex.sendHeartBeat') j = json.dumps(d) self.ws.send(j) except websocket.WebSocketConnectionClosedException as ex: @@ -281,7 +281,7 @@ class WsSpotApi(OkexApi): #---------------------------------------------------------------------- def subscribeSpotTicker(self, symbol): - print(u'vnokex.subscribeSpotTicker:{}'.format(symbol)) + #print(u'vnokex.subscribeSpotTicker:{}'.format(symbol)) """订阅现货的Tick""" channel = 'ok_sub_spot_%s_ticker' %symbol @@ -290,7 +290,7 @@ class WsSpotApi(OkexApi): #---------------------------------------------------------------------- def subscribeSpotDepth(self, symbol, depth=0): """订阅现货的深度""" - print(u'vnokex.subscribeSpotDepth:{}'.format(symbol)) + #print(u'vnokex.subscribeSpotDepth:{}'.format(symbol)) channel = 'ok_sub_spot_%s_depth' %symbol if depth: @@ -304,7 +304,7 @@ class WsSpotApi(OkexApi): :param symbol: :return: """ - print(u'vnokex.subscribeSpotDeals:{}'.format(symbol)) + #print(u'vnokex.subscribeSpotDeals:{}'.format(symbol)) channel = 'ok_sub_spot_%s_deals' %symbol self.sendDataRequest(channel) @@ -316,14 +316,14 @@ class WsSpotApi(OkexApi): :param period: :return: """ - print(u'vnokex.subscribeSpotKlines:{} {}'.format(symbol,period)) + #print(u'vnokex.subscribeSpotKlines:{} {}'.format(symbol,period)) channel = 'ok_sub_spot_%s_kline_%s' %(symbol, period) self.sendDataRequest(channel) #---------------------------------------------------------------------- def spotTrade(self, symbol, type_, price, amount): """现货委托""" - print(u'vnokex.stopTrade:symbol:{} type:{} price:{} amount:{}'.format(symbol, type_, price,amount)) + #print(u'vnokex.stopTrade:symbol:{} type:{} price:{} amount:{}'.format(symbol, type_, price,amount)) params = {} params['symbol'] = str(symbol) @@ -349,7 +349,7 @@ class WsSpotApi(OkexApi): :param orderid: :return: """ - print(u'vnokex.spotCancelOrder:{} orderid:{}'.format(symbol, orderid)) + #print(u'vnokex.spotCancelOrder:{} orderid:{}'.format(symbol, orderid)) params = {} params['symbol'] = str(symbol) params['order_id'] = str(orderid) @@ -364,7 +364,7 @@ class WsSpotApi(OkexApi): 查询现货账户" :return: """"" - print(u'vnokex.spotUserInfo()') + #print(u'vnokex.spotUserInfo()') channel = 'ok_spot_userinfo' self.sendRequest(channel, {}) @@ -376,7 +376,7 @@ class WsSpotApi(OkexApi): :param orderid: 委托编号 :return: """ - print(u'vnokex.spotOrderInfo:{},orderid:{}'.format(symbol,orderid)) + #print(u'vnokex.spotOrderInfo:{},orderid:{}'.format(symbol,orderid)) params = {} params['symbol'] = str(symbol) @@ -679,9 +679,9 @@ class WsFuturesApi(object): self.sendTradingRequest(channel, {}) # ---------------------------------------------------------------------- - def futureSubUserInfo(self): - channel = 'ok_sub_futureusd_userinfo' - self.sendTradingRequest(channel, {}) + # def futureSubUserInfo(self): + # channel = 'ok_sub_futureusd_userinfo' + # self.sendTradingRequest(channel, {}) # ---------------------------------------------------------------------- def futureOrderInfo(self, symbol_pair, order_id, contract_type, status, current_page, page_length=50): @@ -719,6 +719,15 @@ class WsFuturesApi(object): # orderid = -1, self.futureOrderInfo(symbol_usd, -1, contract_type, 1, 1, 50) + # ---------------------------------------------------------------------- + def subscribeFutureTrades(self): + """ + 订阅期货成交回报 + :return: + """ + channel = 'ok_sub_futureusd_trades' + self.sendTradingRequest(channel, {}) + # ---------------------------------------------------------------------- def subscribeFutureUserInfo(self): """订阅期货账户信息""" diff --git a/vnpy/trader/gateway/okexGateway/okexGateway.py b/vnpy/trader/gateway/okexGateway/okexGateway.py index 4dce6f96..120e1faf 100644 --- a/vnpy/trader/gateway/okexGateway/okexGateway.py +++ b/vnpy/trader/gateway/okexGateway/okexGateway.py @@ -158,10 +158,39 @@ class OkexGateway(VtGateway): self.initQuery() self.startQuery() + def writeLog(self, content): + """ + 记录日志文件 + :param content: + :return: + """ + if self.logger: + self.logger.info(content) + + def writeError(self, content, error_id = 0): + """ + 发送错误通知/记录日志文件 + :param content: + :return: + """ + error = VtErrorData() + error.gatewayName = self.gatewayName + error.errorID = error_id + error.errorMsg = content + self.onError(error) + + if self.logger: + self.logger.error(content) def checkStatus(self): - return self.spot_connected or self.futures_connected + if not self.spot_connected and not self.futures_connected: + return False + if self.spot_connected: + return self.api_spot.checkStatus() + + if self.futures_connected: + return self.api_futures.checkStatus() # ---------------------------------------------------------------------- def subscribe(self, subscribeReq): """ @@ -704,6 +733,20 @@ class OkexSpotApi(WsSpotApi): vol(double): 成交量(最近的24小时) """ + def checkStatus(self): + """ + 检查状态 + :return: + """ + if len(self.tickDict)>0: + symbol,last_tick = list(self.tickDict.items())[0] + if (datetime.now()-last_tick.datetime).seconds > 60: + return False + + return True + else: + return False + def onTicker(self, ws_data): """ tick行情数据回报 @@ -713,7 +756,7 @@ class OkexSpotApi(WsSpotApi): channel = ws_data.get('channel') data = ws_data.get('data', {}) # 检查channel/data - if channel is None and len(data) ==0: + if channel is None and len(data) == 0: return try: @@ -1907,6 +1950,20 @@ class OkexFuturesApi(WsFuturesApi): } """ + def checkStatus(self): + """ + 检查状态 + :return: + """ + if len(self.tickDict) > 0: + symbol,last_tick = list(self.tickDict.items())[0] + if (datetime.now() - last_tick.datetime).seconds > 60: + return False + + return True + else: + return False + def onTicker(self, ws_data): """ 期货行情推送 @@ -2217,7 +2274,8 @@ h_this_week_usd'} }, "channel":"ok_futureusd_cancel_order" } - """ + """ + def onFutureOrderCancel(self, ws_data): """ 委托撤单的响应" @@ -2255,7 +2313,6 @@ h_this_week_usd'} #del self.orderIdDict[orderId] #del self.localNoDict[localNo] - ''' 逐仓返回: [{ @@ -2401,6 +2458,17 @@ h_this_week_usd'} account.closeProfit = float(s_inf.get('profit_real',0.0)) account.positionProfit = float(s_inf.get('profit_unreal',0.0)) account.margin = float(s_inf.get('keep_deposit',0.0)) + + # 更新持仓信息 + pos = VtPositionData() + pos.gatewayName = self.gatewayName + u'_Future' + pos.symbol = u'{}.{}_Future'.format(symbol, EXCHANGE_OKEX) + pos.vtSymbol = u'{}.{}_Future'.format(symbol, EXCHANGE_OKEX) + pos.position = account.balance + pos.frozen = float(s_inf.get('keep_deposit',0.0)) + pos.direction = DIRECTION_NET + self.gateway.onPosition(pos) + self.gateway.onAccount(account) # 如果该合约账号的净值大于0,则通过rest接口,逐一合约类型获取持仓 @@ -2415,22 +2483,34 @@ h_this_week_usd'} #if t_balance > 0 or t_rights > 0: account = VtAccountData() - account.gatewayName = self.gatewayName + u'_合约' + account.gatewayName = self.gatewayName + u'_Future' account.accountID = u'[逐仓]{}'.format(symbol) account.vtAccountID = account.accountID account.balance = t_rights account.available = t_balance - for contract in t_contracts: - # 保证金 - account.margin += contract.get('bond',0.0) - # 平仓盈亏 - account.closeProfit += contract.get('profit',0.0) - # 持仓盈亏 - account.positionProfit += contract.get('unprofit',0.0) - if account.balance > 0 or account.available > 0: - for contractType in CONTRACT_TYPE: - self.query_future_position_4fix(symbol=symbol, contractType=contractType) + # 更新持仓信息 + pos = VtPositionData() + pos.gatewayName = self.gatewayName + u'_Future' + pos.symbol = u'{}.{}_Future'.format(symbol,EXCHANGE_OKEX) + pos.vtSymbol = u'{}.{}_Future'.format(symbol,EXCHANGE_OKEX) + pos.position = t_rights + pos.frozen = t_rights - t_balance + pos.direction = DIRECTION_NET + self.gateway.onPosition(pos) + + for contract in t_contracts: + # 保证金 + account.margin += contract.get('bond',0.0) + # 平仓盈亏 + account.closeProfit += contract.get('profit',0.0) + # 持仓盈亏 + account.positionProfit += contract.get('unprofit',0.0) + + + if account.balance > 0 or account.available > 0: + for contractType in CONTRACT_TYPE: + self.query_future_position_4fix(symbol=symbol, contractType=contractType) self.gateway.onAccount(account) @@ -2482,7 +2562,7 @@ h_this_week_usd'} pos.positionProfit = holding.get('buy_profit_real', 0.0) self.gateway.onPosition(pos) if holding.get('sell_amount', 0) > 0: - sell_pos = copy.copy(pos) + sell_pos = copy(pos) sell_pos.direction = DIRECTION_SHORT sell_pos.vtPositionName = sell_pos.symbol + sell_pos.direction sell_pos.price = holding.get('sell_price_avg', 0.0) @@ -2499,7 +2579,7 @@ h_this_week_usd'} def query_future_position_4fix(self,symbol, contractType,leverate=1): """ - + 逐仓模式下,查询仓位 :param symbol: :param contractType: :param leverate: 默认返回10倍杠杆持仓 type=1 返回全部持仓数据 @@ -2547,11 +2627,10 @@ h_this_week_usd'} pos.frozen = pos.position - (volume_rate * holding.get('buy_available') / price) else: pos.frozen = 0 - pos.positionProfit = holding.get('buy_profit_real', 0.0) self.gateway.onPosition(pos) if holding.get('sell_amount', 0) > 0: - sell_pos = copy.copy(pos) + sell_pos = copy(pos) sell_pos.direction = DIRECTION_SHORT sell_pos.vtPositionName = sell_pos.symbol + sell_pos.direction sell_pos.price = holding.get('sell_price_avg', 0.0)