This commit is contained in:
msincenselee 2018-08-09 23:08:17 +08:00
parent a08f31c59b
commit e61754f1ae
4 changed files with 172 additions and 61 deletions

View File

@ -9,7 +9,7 @@ from OkcoinFutureAPI import OKCoinFuture
#初始化apikeysecretkey,url #初始化apikeysecretkey,url
apikey = 'XXXX' apikey = 'XXXX'
secretkey = 'XXXXX' secretkey = 'XXXXX'
okcoinRESTURL = 'www.okcoin.com' #请求注意:国内账号需要 修改为 www.okcoin.cn okcoinRESTURL = 'www.okex.com' #请求注意:国内账号需要 修改为 www.okcoin.cn
#现货API #现货API
okcoinSpot = OKCoinSpot(okcoinRESTURL,apikey,secretkey) okcoinSpot = OKCoinSpot(okcoinRESTURL,apikey,secretkey)
@ -17,11 +17,15 @@ okcoinSpot = OKCoinSpot(okcoinRESTURL,apikey,secretkey)
#期货API #期货API
okcoinFuture = OKCoinFuture(okcoinRESTURL,apikey,secretkey) okcoinFuture = OKCoinFuture(okcoinRESTURL,apikey,secretkey)
print (u' 现货行情 ') #print (u' 现货行情 ')
print (okcoinSpot.ticker('btc_usd')) #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 (u' 现货历史交易信息 ')
#print (okcoinSpot.trades()) #print (okcoinSpot.trades())

View File

@ -4,7 +4,6 @@
from vnpy.api.okex.HttpMD5Util import buildMySign,httpGet,httpPost from vnpy.api.okex.HttpMD5Util import buildMySign,httpGet,httpPost
class OKCoinSpot: class OKCoinSpot:
def __init__(self,url,apikey,secretkey): def __init__(self,url,apikey,secretkey):
self.__url = url self.__url = url
self.__apikey = apikey self.__apikey = apikey
@ -26,7 +25,27 @@ class OKCoinSpot:
params = 'symbol=%(symbol)s' %{'symbol':symbol} params = 'symbol=%(symbol)s' %{'symbol':symbol}
return httpGet(self.__url,DEPTH_RESOURCE,params) 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 = ''): def trades(self,symbol = ''):
TRADES_RESOURCE = "/api/v1/trades.do" TRADES_RESOURCE = "/api/v1/trades.do"
params='' params=''

View File

@ -29,27 +29,27 @@ SPOT_CURRENCY = ["usdt",
"eos"] "eos"]
SPOT_SYMBOL_PAIRS = set(["ltc_btc", SPOT_SYMBOL_PAIRS = set(["ltc_btc",
"eos_usdt", "eth_btc",
"eth_btc", "etc_btc",
"etc_btc", "bch_btc",
"bch_btc", "btc_usdt",
"btc_usdt", "eth_usdt",
"eth_usdt", "ltc_usdt",
"ltc_usdt", "etc_usdt",
"etc_usdt", "bch_usdt",
"bch_usdt", "etc_eth",
"etc_eth", "bt1_btc",
"bt1_btc", "bt2_btc",
"bt2_btc", "btg_btc",
"btg_btc", "qtum_btc",
"qtum_btc", "hsr_btc",
"hsr_btc", "neo_btc",
"neo_btc", "gas_btc",
"gas_btc", "qtum_usdt",
"qtum_usdt", "hsr_usdt",
"hsr_usdt", "neo_usdt",
"neo_usdt", "gas_usdt",
"gas_usdt"]) "eos_usdt"])
KLINE_PERIOD = ["1min","3min","5min","15min","30min","1hour","2hour","4hour","6hour","12hour","day","3day","week"] 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): def sendRequest(self, channel, params):
"""发送指令请求""" """发送指令请求"""
print(u'vnokex.sendRequest:{}'.format(channel)) #print(u'vnokex.sendRequest:{}'.format(channel))
# 在参数字典中加上api_key和签名字段 # 在参数字典中加上api_key和签名字段
params['api_key'] = self.apiKey params['api_key'] = self.apiKey
params['sign'] = self.generateSign(params) params['sign'] = self.generateSign(params)
@ -214,7 +214,7 @@ class OkexApi(object):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def sendDataRequest(self, channel): def sendDataRequest(self, channel):
"""发送数据请求""" """发送数据请求"""
print(u'vnokex.sendDataRequest:{}'.format(channel)) #print(u'vnokex.sendDataRequest:{}'.format(channel))
d = {} d = {}
d['event'] = 'addChannel' d['event'] = 'addChannel'
d['channel'] = channel d['channel'] = channel
@ -236,7 +236,7 @@ class OkexApi(object):
d = {'event': 'ping'} d = {'event': 'ping'}
# 若触发异常则重连 # 若触发异常则重连
try: try:
print(u'vnokex.sendHeartBeat') #print(u'vnokex.sendHeartBeat')
j = json.dumps(d) j = json.dumps(d)
self.ws.send(j) self.ws.send(j)
except websocket.WebSocketConnectionClosedException as ex: except websocket.WebSocketConnectionClosedException as ex:
@ -281,7 +281,7 @@ class WsSpotApi(OkexApi):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def subscribeSpotTicker(self, symbol): def subscribeSpotTicker(self, symbol):
print(u'vnokex.subscribeSpotTicker:{}'.format(symbol)) #print(u'vnokex.subscribeSpotTicker:{}'.format(symbol))
"""订阅现货的Tick""" """订阅现货的Tick"""
channel = 'ok_sub_spot_%s_ticker' %symbol channel = 'ok_sub_spot_%s_ticker' %symbol
@ -290,7 +290,7 @@ class WsSpotApi(OkexApi):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def subscribeSpotDepth(self, symbol, depth=0): 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 channel = 'ok_sub_spot_%s_depth' %symbol
if depth: if depth:
@ -304,7 +304,7 @@ class WsSpotApi(OkexApi):
:param symbol: :param symbol:
:return: :return:
""" """
print(u'vnokex.subscribeSpotDeals:{}'.format(symbol)) #print(u'vnokex.subscribeSpotDeals:{}'.format(symbol))
channel = 'ok_sub_spot_%s_deals' %symbol channel = 'ok_sub_spot_%s_deals' %symbol
self.sendDataRequest(channel) self.sendDataRequest(channel)
@ -316,14 +316,14 @@ class WsSpotApi(OkexApi):
:param period: :param period:
:return: :return:
""" """
print(u'vnokex.subscribeSpotKlines:{} {}'.format(symbol,period)) #print(u'vnokex.subscribeSpotKlines:{} {}'.format(symbol,period))
channel = 'ok_sub_spot_%s_kline_%s' %(symbol, period) channel = 'ok_sub_spot_%s_kline_%s' %(symbol, period)
self.sendDataRequest(channel) self.sendDataRequest(channel)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def spotTrade(self, symbol, type_, price, amount): 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 = {}
params['symbol'] = str(symbol) params['symbol'] = str(symbol)
@ -349,7 +349,7 @@ class WsSpotApi(OkexApi):
:param orderid: :param orderid:
:return: :return:
""" """
print(u'vnokex.spotCancelOrder:{} orderid:{}'.format(symbol, orderid)) #print(u'vnokex.spotCancelOrder:{} orderid:{}'.format(symbol, orderid))
params = {} params = {}
params['symbol'] = str(symbol) params['symbol'] = str(symbol)
params['order_id'] = str(orderid) params['order_id'] = str(orderid)
@ -364,7 +364,7 @@ class WsSpotApi(OkexApi):
查询现货账户" 查询现货账户"
:return: :return:
""""" """""
print(u'vnokex.spotUserInfo()') #print(u'vnokex.spotUserInfo()')
channel = 'ok_spot_userinfo' channel = 'ok_spot_userinfo'
self.sendRequest(channel, {}) self.sendRequest(channel, {})
@ -376,7 +376,7 @@ class WsSpotApi(OkexApi):
:param orderid: 委托编号 :param orderid: 委托编号
:return: :return:
""" """
print(u'vnokex.spotOrderInfo:{},orderid:{}'.format(symbol,orderid)) #print(u'vnokex.spotOrderInfo:{},orderid:{}'.format(symbol,orderid))
params = {} params = {}
params['symbol'] = str(symbol) params['symbol'] = str(symbol)
@ -679,9 +679,9 @@ class WsFuturesApi(object):
self.sendTradingRequest(channel, {}) self.sendTradingRequest(channel, {})
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
def futureSubUserInfo(self): # def futureSubUserInfo(self):
channel = 'ok_sub_futureusd_userinfo' # channel = 'ok_sub_futureusd_userinfo'
self.sendTradingRequest(channel, {}) # self.sendTradingRequest(channel, {})
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
def futureOrderInfo(self, symbol_pair, order_id, contract_type, status, current_page, page_length=50): def futureOrderInfo(self, symbol_pair, order_id, contract_type, status, current_page, page_length=50):
@ -719,6 +719,15 @@ class WsFuturesApi(object):
# orderid = -1, # orderid = -1,
self.futureOrderInfo(symbol_usd, -1, contract_type, 1, 1, 50) 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): def subscribeFutureUserInfo(self):
"""订阅期货账户信息""" """订阅期货账户信息"""

View File

@ -158,10 +158,39 @@ class OkexGateway(VtGateway):
self.initQuery() self.initQuery()
self.startQuery() 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): 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): def subscribe(self, subscribeReq):
""" """
@ -704,6 +733,20 @@ class OkexSpotApi(WsSpotApi):
vol(double): 成交量(最近的24小时) 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): def onTicker(self, ws_data):
""" """
tick行情数据回报 tick行情数据回报
@ -713,7 +756,7 @@ class OkexSpotApi(WsSpotApi):
channel = ws_data.get('channel') channel = ws_data.get('channel')
data = ws_data.get('data', {}) data = ws_data.get('data', {})
# 检查channel/data # 检查channel/data
if channel is None and len(data) ==0: if channel is None and len(data) == 0:
return return
try: 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): def onTicker(self, ws_data):
""" """
期货行情推送 期货行情推送
@ -2217,7 +2274,8 @@ h_this_week_usd'}
}, },
"channel":"ok_futureusd_cancel_order" "channel":"ok_futureusd_cancel_order"
} }
""" """
def onFutureOrderCancel(self, ws_data): def onFutureOrderCancel(self, ws_data):
""" """
委托撤单的响应" 委托撤单的响应"
@ -2255,7 +2313,6 @@ h_this_week_usd'}
#del self.orderIdDict[orderId] #del self.orderIdDict[orderId]
#del self.localNoDict[localNo] #del self.localNoDict[localNo]
''' '''
逐仓返回 逐仓返回
[{ [{
@ -2401,6 +2458,17 @@ h_this_week_usd'}
account.closeProfit = float(s_inf.get('profit_real',0.0)) account.closeProfit = float(s_inf.get('profit_real',0.0))
account.positionProfit = float(s_inf.get('profit_unreal',0.0)) account.positionProfit = float(s_inf.get('profit_unreal',0.0))
account.margin = float(s_inf.get('keep_deposit',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) self.gateway.onAccount(account)
# 如果该合约账号的净值大于0,则通过rest接口逐一合约类型获取持仓 # 如果该合约账号的净值大于0,则通过rest接口逐一合约类型获取持仓
@ -2415,22 +2483,34 @@ h_this_week_usd'}
#if t_balance > 0 or t_rights > 0: #if t_balance > 0 or t_rights > 0:
account = VtAccountData() account = VtAccountData()
account.gatewayName = self.gatewayName + u'_合约' account.gatewayName = self.gatewayName + u'_Future'
account.accountID = u'[逐仓]{}'.format(symbol) account.accountID = u'[逐仓]{}'.format(symbol)
account.vtAccountID = account.accountID account.vtAccountID = account.accountID
account.balance = t_rights account.balance = t_rights
account.available = t_balance 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: pos = VtPositionData()
self.query_future_position_4fix(symbol=symbol, contractType=contractType) 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) self.gateway.onAccount(account)
@ -2482,7 +2562,7 @@ h_this_week_usd'}
pos.positionProfit = holding.get('buy_profit_real', 0.0) pos.positionProfit = holding.get('buy_profit_real', 0.0)
self.gateway.onPosition(pos) self.gateway.onPosition(pos)
if holding.get('sell_amount', 0) > 0: if holding.get('sell_amount', 0) > 0:
sell_pos = copy.copy(pos) sell_pos = copy(pos)
sell_pos.direction = DIRECTION_SHORT sell_pos.direction = DIRECTION_SHORT
sell_pos.vtPositionName = sell_pos.symbol + sell_pos.direction sell_pos.vtPositionName = sell_pos.symbol + sell_pos.direction
sell_pos.price = holding.get('sell_price_avg', 0.0) 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): def query_future_position_4fix(self,symbol, contractType,leverate=1):
""" """
逐仓模式下查询仓位
:param symbol: :param symbol:
:param contractType: :param contractType:
:param leverate: 默认返回10倍杠杆持仓 type=1 返回全部持仓数据 :param leverate: 默认返回10倍杠杆持仓 type=1 返回全部持仓数据
@ -2547,11 +2627,10 @@ h_this_week_usd'}
pos.frozen = pos.position - (volume_rate * holding.get('buy_available') / price) pos.frozen = pos.position - (volume_rate * holding.get('buy_available') / price)
else: else:
pos.frozen = 0 pos.frozen = 0
pos.positionProfit = holding.get('buy_profit_real', 0.0) pos.positionProfit = holding.get('buy_profit_real', 0.0)
self.gateway.onPosition(pos) self.gateway.onPosition(pos)
if holding.get('sell_amount', 0) > 0: if holding.get('sell_amount', 0) > 0:
sell_pos = copy.copy(pos) sell_pos = copy(pos)
sell_pos.direction = DIRECTION_SHORT sell_pos.direction = DIRECTION_SHORT
sell_pos.vtPositionName = sell_pos.symbol + sell_pos.direction sell_pos.vtPositionName = sell_pos.symbol + sell_pos.direction
sell_pos.price = holding.get('sell_price_avg', 0.0) sell_pos.price = holding.get('sell_price_avg', 0.0)