[Add] 将OkexFutureRestClient做成独立的API分离出来
This commit is contained in:
parent
b34dcf6a73
commit
f5755b222a
337
vnpy/api/okexfuture/OkexFutureApi.py
Normal file
337
vnpy/api/okexfuture/OkexFutureApi.py
Normal file
@ -0,0 +1,337 @@
|
||||
# encoding: UTF-8
|
||||
from enum import Enum
|
||||
from typing import Any, Callable, List, Union
|
||||
|
||||
from vnpy.api.okexfuture.vnokexFuture import OkexFutureRestBase
|
||||
from vnpy.network.RestClient import Request
|
||||
|
||||
|
||||
class _OkexFutureCustomExtra(object):
|
||||
|
||||
def __init__(self, onSuccess, onFailed, extra):
|
||||
self.onFailed = onFailed
|
||||
self.onSuccess = onSuccess
|
||||
self.extra = extra
|
||||
|
||||
|
||||
class OkexFuturePriceType(Enum):
|
||||
Buy = 'buy'
|
||||
Sell = 'sell'
|
||||
|
||||
|
||||
class OkexFutureContractType(Enum):
|
||||
ThisWeek = 'this_week'
|
||||
NextWeek = 'next_week'
|
||||
Quarter = 'quarter'
|
||||
|
||||
|
||||
class OkexFutureStatus(Enum):
|
||||
NoTraded = '0'
|
||||
PartialTraded = '1'
|
||||
AllTraded = '2'
|
||||
Canceled = '-1'
|
||||
CancelProcessing = '4'
|
||||
Canceling = '5'
|
||||
|
||||
|
||||
class OkexFutureOrderType(Enum):
|
||||
OpenLong = '1'
|
||||
OpenShort = '2'
|
||||
CloseLong = '3'
|
||||
CloseShort = '4'
|
||||
|
||||
|
||||
class OkexFutureOrder(object):
|
||||
|
||||
def __init__(self):
|
||||
self.symbol = None
|
||||
self.volume = None
|
||||
self.price = None
|
||||
self.priceAvg = None
|
||||
self.status = None
|
||||
self.orderType = None
|
||||
self.unitAmount = None
|
||||
self.leverRate = None
|
||||
self.remoteId = None
|
||||
self.fee = None
|
||||
self.tradedVolume = None
|
||||
self.createDate = None
|
||||
|
||||
|
||||
class OkexFutureUserInfo(object):
|
||||
|
||||
def __init__(self):
|
||||
self.accountRights = None
|
||||
self.keepDeposit = None
|
||||
self.profitReal = None
|
||||
self.profitUnreal = None
|
||||
self.riskRate = None
|
||||
|
||||
|
||||
class OkexFuturePosition(object):
|
||||
|
||||
def __init__(self, ):
|
||||
self.forceLiquidatePrice = None
|
||||
self.holding = [] # type: List[OkexFuturePositionDetail]
|
||||
|
||||
|
||||
class OkexFuturePositionDetail(object):
|
||||
|
||||
def __init__(self, ):
|
||||
self.buyAmount = None
|
||||
self.buyAvailable = None
|
||||
self.buyPriceAvg = None
|
||||
self.buyPriceCost = None
|
||||
self.buyProfitReal = None
|
||||
self.contractId = None
|
||||
self.createDate = None
|
||||
self.leverRate = None
|
||||
self.sellAmount = None
|
||||
self.sellAvailable = None
|
||||
self.sellPriceAvg = None
|
||||
self.sellPriceCost = None
|
||||
self.sellProfitReal = None
|
||||
self.symbol = None
|
||||
self.contractType = None
|
||||
|
||||
|
||||
########################################################################
|
||||
class OkexFutureRestClient(OkexFutureRestBase):
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self):
|
||||
"""Constructor"""
|
||||
super(OkexFutureRestClient, self).__init__()
|
||||
|
||||
self.client = ()
|
||||
|
||||
self._redirectedOnError = None # type: Callable[[object, object, object, Request], Any]
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def setOnError(self, callback): # type: (Callable[[object, object, object, Request], Any])->None
|
||||
self._redirectedOnError = callback
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def onError(self, exceptionType, exceptionValue, tb, req):
|
||||
if self._redirectedOnError:
|
||||
self._redirectedOnError(exceptionType, exceptionValue, tb, req)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def onFailed(self, httpStatusCode, req):
|
||||
super(OkexFutureRestClient, self).onFailed(httpStatusCode, req)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def sendOrder(self, symbol, contractType, orderType, volume,
|
||||
onSuccess, onFailed=None,
|
||||
price=None, useMarketPrice=False, leverRate=None,
|
||||
extra=None): # type:(str, OkexFutureContractType, OkexFutureOrderType, float, Callable[[int, Any], Any], Callable[[object], Any], float, bool, Union[int, None], Any)->Request
|
||||
"""
|
||||
:param symbol: str
|
||||
:param contractType: OkexFutureContractType
|
||||
:param orderType: OkexFutureOrderType
|
||||
:param volume: float
|
||||
:param onSuccess: (orderId: int)->Any
|
||||
:param onFailed: ()->Any
|
||||
:param price: float
|
||||
:param useMarketPrice: bool
|
||||
:param leverRate: int | None
|
||||
:param extra: Any
|
||||
:return:
|
||||
"""
|
||||
|
||||
data = {}
|
||||
if useMarketPrice:
|
||||
data['match_price'] = 1
|
||||
else:
|
||||
data['price'] = price
|
||||
data.update({
|
||||
'symbol': symbol,
|
||||
'contract_typ': contractType, # 合约类型:当周/下周/季度
|
||||
'amount': volume,
|
||||
'type': orderType,
|
||||
'lever_rate': leverRate # 杠杆倍数
|
||||
})
|
||||
|
||||
request = self.addReq('POST',
|
||||
'/future_trade.do',
|
||||
callback=self.onOrderSent,
|
||||
data=data,
|
||||
extra=_OkexFutureCustomExtra(onSuccess, onFailed, extra))
|
||||
return request
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def cancelOrder(self, symbol, contractType, orderId, onSuccess, onFailed=None,
|
||||
extra=None): # type: (str, OkexFutureContractType, str, Callable[[object], Any], Callable[[object], Any], Any)->Request
|
||||
"""
|
||||
:param symbol: str
|
||||
:param contractType: OkexFutureContractType
|
||||
:param orderId: str
|
||||
:param onSuccess: ()->Any
|
||||
:param onFailed: ()->Any
|
||||
:param extra: Any
|
||||
:return: Request
|
||||
"""
|
||||
data = {
|
||||
'symbol': symbol,
|
||||
'contractType': contractType,
|
||||
'order_id': orderId
|
||||
}
|
||||
return self.addReq('POST',
|
||||
'/future_cancel.do',
|
||||
callback=self.onOrderCanceled,
|
||||
data=data,
|
||||
extra=_OkexFutureCustomExtra(onSuccess, onFailed, extra))
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def queryOrder(self, symbol, contractType, orderId, onSuccess, onFailed=None,
|
||||
extra=None): # type: (str, OkexFutureContractType, str, Callable[[OkexFutureOrder, Any], Any], Callable[[Any], Any], Any)->Request
|
||||
"""
|
||||
:param symbol: str
|
||||
:param contractType: OkexFutureContractType
|
||||
:param orderId: str
|
||||
:param onSuccess: (OkexFutureOrder, extra:Any)->Any
|
||||
:param onFailed: (extra: Any)->Any
|
||||
:param extra: Any
|
||||
:return: Request
|
||||
"""
|
||||
data = {
|
||||
'symbol': symbol,
|
||||
'contractType': contractType,
|
||||
'order_id': orderId
|
||||
}
|
||||
return self.addReq('POST',
|
||||
'/future_order_info.do',
|
||||
callback=self.onOrder,
|
||||
data=data,
|
||||
extra=_OkexFutureCustomExtra(onSuccess, onFailed, extra))
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def queryUserInfo(self, onSuccess, onFailed=None,
|
||||
extra=None): # type: (Callable[[List[OkexFutureUserInfo], Any], Any], Callable[[Any], Any], Any)->Request
|
||||
"""
|
||||
查询用户信息
|
||||
:param onSuccess: (userInfos: List[OkexFutureUserInfo], extra: Any)->Any
|
||||
:param onFailed: (extra: Any)->Any
|
||||
:param extra: Any
|
||||
:return: Request
|
||||
"""
|
||||
return self.addReq('POST',
|
||||
'/future_userinfo.do',
|
||||
callback=self.onOrder,
|
||||
extra=_OkexFutureCustomExtra(onSuccess, onFailed, extra))
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def queryPosition(self, symbol, contractType,
|
||||
onSuccess, onFailed=None,
|
||||
extra=None): # type: (str, OkexFutureContractType, Callable[[OkexFuturePosition, Any], Any], Callable[[Any], Any], Any)->Request
|
||||
data = {
|
||||
'symbol': symbol,
|
||||
'contractType': contractType
|
||||
}
|
||||
return self.addReq('POST',
|
||||
'/future_position.do',
|
||||
data=data,
|
||||
callback=self.onPosition,
|
||||
extra=_OkexFutureCustomExtra(onSuccess, onFailed, extra))
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@staticmethod
|
||||
def onOrderSent(data, req): # type: (dict, Request)->None
|
||||
"""
|
||||
下单回执,一般用来保存sysId
|
||||
"""
|
||||
extra = req.extra # type: _OkexFutureCustomExtra
|
||||
if data['result'] is True:
|
||||
remoteId = data['order_id']
|
||||
extra.onSuccess(remoteId, extra.extra)
|
||||
else:
|
||||
extra.onFailed(extra.extra)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@staticmethod
|
||||
def onOrderCanceled(data, req): # type: (dict, Request)->None
|
||||
"""
|
||||
取消订单回执
|
||||
"""
|
||||
success = data['result']
|
||||
extra = req.extra # type: _OkexFutureCustomExtra
|
||||
if success:
|
||||
extra.onSuccess(extra.extra)
|
||||
else:
|
||||
extra.onFailed(extra.extra)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@staticmethod
|
||||
def onOrder(data, req): # type: (dict, Request)->None
|
||||
success = data['result']
|
||||
extra = req.extra # type: _OkexFutureCustomExtra
|
||||
if success:
|
||||
order = data['orders'][0]
|
||||
okexOrder = OkexFutureOrder()
|
||||
|
||||
okexOrder.symbol = order['symbol']
|
||||
okexOrder.volume = order['amount']
|
||||
okexOrder.price = order['price']
|
||||
okexOrder.priceAvg = order['price_avg']
|
||||
okexOrder.status = order['status']
|
||||
okexOrder.orderType = order['type']
|
||||
okexOrder.unitAmount = order['unit_amount']
|
||||
okexOrder.leverRate = order['lever_rate']
|
||||
okexOrder.remoteId = order['order_id']
|
||||
okexOrder.fee = order['fee']
|
||||
okexOrder.tradedVolume = order['deal_amount']
|
||||
okexOrder.createDate = order['create_date']
|
||||
|
||||
extra.onSuccess(okexOrder, extra.extra)
|
||||
else:
|
||||
extra.onFailed(extra.extra)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@staticmethod
|
||||
def onUserInfo(data, req): # type: (dict, Request)->None
|
||||
success = data['result']
|
||||
extra = req.extra # type: _OkexFutureCustomExtra
|
||||
if success:
|
||||
infos = data['info']
|
||||
uis = []
|
||||
for symbol, info in infos.items(): # type: str, dict
|
||||
ui = OkexFutureUserInfo()
|
||||
ui.accountRights = info['account_rights']
|
||||
ui.keepDeposit = info['keep_deposit']
|
||||
ui.profitReal = info['profit_real']
|
||||
ui.profitUnreal = info['profit_unreal']
|
||||
ui.riskRate = info['risk_rate']
|
||||
uis.append(ui)
|
||||
extra.onSuccess(uis, extra.extra)
|
||||
else:
|
||||
extra.onFailed(extra.extra)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@staticmethod
|
||||
def onPosition(data, req): # type: (dict, Request)->None
|
||||
success = data['result']
|
||||
extra = req.extra # type: _OkexFutureCustomExtra
|
||||
if success:
|
||||
pos = OkexFuturePosition()
|
||||
pos.forceLiquidatePrice = data['force_liqu_price']
|
||||
for item in data['holding']:
|
||||
posDetail = OkexFuturePositionDetail()
|
||||
posDetail.buyAmount = item['buy_amount']
|
||||
posDetail.buyAvailable = item['buy_available']
|
||||
posDetail.buyPriceAvg = item['buy_price_avg']
|
||||
posDetail.buyPriceCost = item['buy_price_cost']
|
||||
posDetail.buyProfitReal = item['buy_profit_real']
|
||||
posDetail.contractId = item['contract_id']
|
||||
posDetail.contractType = item['contract_type']
|
||||
posDetail.createDate = item['create_date']
|
||||
posDetail.leverRate = item['lever_rate']
|
||||
posDetail.sellAmount = item['sell_amount']
|
||||
posDetail.sellAvailable = item['sell_available']
|
||||
posDetail.sellPriceAvg = item['sell_price_avg']
|
||||
posDetail.sellPriceCost = item['sell_price_cost']
|
||||
posDetail.sellProfitReal = item['sell_profit_real']
|
||||
posDetail.symbol = item['symbol']
|
||||
pos.holding.append(posDetail)
|
||||
extra.onSuccess(pos, extra.extra)
|
||||
else:
|
||||
extra.onFailed(extra.extra)
|
@ -8,11 +8,11 @@ from vnpy.network.RestClient import RestClient, Request
|
||||
|
||||
|
||||
########################################################################
|
||||
class OkexFutureRestClient(RestClient):
|
||||
class OkexFutureRestBase(RestClient):
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self):
|
||||
super(OkexFutureRestClient, self).__init__()
|
||||
super(OkexFutureRestBase, self).__init__()
|
||||
self.apiKey = None
|
||||
self.apiSecret = None
|
||||
|
||||
@ -20,7 +20,7 @@ class OkexFutureRestClient(RestClient):
|
||||
# noinspection PyMethodOverriding
|
||||
def init(self, apiKey, apiSecret):
|
||||
# type: (str, str) -> any
|
||||
super(OkexFutureRestClient, self).init('https://www.okex.com/api/v1')
|
||||
super(OkexFutureRestBase, self).init('https://www.okex.com/api/v1')
|
||||
self.apiKey = apiKey
|
||||
self.apiSecret = apiSecret
|
||||
|
||||
|
@ -5,16 +5,15 @@ from __future__ import print_function
|
||||
import json
|
||||
from abc import abstractmethod, abstractproperty
|
||||
|
||||
from vnpy.api.okexfuture.vnokexFuture import OkexFutureRestClient
|
||||
from vnpy.network.RestClient import Request
|
||||
from vnpy.api.okexfuture.OkexFutureApi import *
|
||||
from vnpy.trader.vtFunction import getJsonPath
|
||||
from vnpy.trader.vtGateway import *
|
||||
|
||||
orderTypeMap = {
|
||||
(constant.DIRECTION_LONG, constant.OFFSET_OPEN): 1,
|
||||
(constant.DIRECTION_SHORT, constant.OFFSET_OPEN): 2,
|
||||
(constant.DIRECTION_LONG, constant.OFFSET_CLOSE): 3,
|
||||
(constant.DIRECTION_SHORT, constant.OFFSET_CLOSE): 4,
|
||||
(constant.DIRECTION_LONG, constant.OFFSET_OPEN): OkexFutureOrderType.OpenLong,
|
||||
(constant.DIRECTION_SHORT, constant.OFFSET_OPEN): OkexFutureOrderType.OpenShort,
|
||||
(constant.DIRECTION_LONG, constant.OFFSET_CLOSE): OkexFutureOrderType.CloseLong,
|
||||
(constant.DIRECTION_SHORT, constant.OFFSET_CLOSE): OkexFutureOrderType.CloseShort,
|
||||
}
|
||||
orderTypeMapReverse = {v: k for k, v in orderTypeMap.items()}
|
||||
|
||||
@ -23,9 +22,9 @@ contracts = (
|
||||
)
|
||||
|
||||
contractTypeMap = {
|
||||
'THISWEEK': 'this_week',
|
||||
'NEXTWEEK': 'next_week',
|
||||
'QUARTER': 'quarter',
|
||||
'THISWEEK': OkexFutureContractType.ThisWeek,
|
||||
'NEXTWEEK': OkexFutureContractType.NextWeek,
|
||||
'QUARTER': OkexFutureContractType.Quarter,
|
||||
}
|
||||
|
||||
# symbols for ui,
|
||||
@ -98,7 +97,7 @@ class OkexFutureGateway(VnpyGateway):
|
||||
super(OkexFutureGateway, self).__init__(eventEngine)
|
||||
self.apiKey = None # type: str
|
||||
self.apiSecret = None # type: str
|
||||
self.api = OkexFutureApi(self)
|
||||
self.api = OkexFutureRestClient()
|
||||
self.leverRate = 1.0
|
||||
self.symbols = []
|
||||
|
||||
@ -166,249 +165,3 @@ class OkexFutureGateway(VnpyGateway):
|
||||
def close(self):
|
||||
"""关闭"""
|
||||
self.api.close()
|
||||
|
||||
|
||||
########################################################################
|
||||
class VnpyOrder():
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
这个东西将VtOrderReq和VtOrderData还有Request三者绑定起来,以便查询
|
||||
|
||||
"""
|
||||
self.vtRequest = None # type: VtOrderReq # 如果这个order是通过sendOrder产生的,则会有对应的vtRequest
|
||||
self.request = None # type: Request # 如果这个order是通过sendOrder产生的,request就是对应的网络请求
|
||||
self.order = None # type: VtOrderData # 对应的VtOrderData
|
||||
|
||||
self.remoteId = None # type: str # 当确定了这个order在交易所内部的id的时候,这个值才会有效
|
||||
|
||||
|
||||
########################################################################
|
||||
class ApiBase(object):
|
||||
"""
|
||||
写在前面:现在不打算重构MainEngine才会有这个类的存在
|
||||
所以这个类注定活不久。
|
||||
|
||||
每个Api实现发单等等操作的时候,有太多重复代码。
|
||||
于是我写了这个类,以期简化Api的实现。
|
||||
|
||||
发单实现:
|
||||
重写_sendOrder函数。
|
||||
在_sendOrder的下单请求回执中获取API使用的orderId,并调用_processOrderSent函数即可
|
||||
|
||||
例如:
|
||||
def _sendOrder(self, vtRequest):
|
||||
return self.httpClient.addReq(..., callback=self._onOrderSent)
|
||||
|
||||
def _onOrderSent(self, data, req):
|
||||
remoteId = None
|
||||
if data['success'] is True:
|
||||
remoteId = data['order_id']
|
||||
self._processOrderSent(req, remoteId)
|
||||
|
||||
撤单实现:
|
||||
重写_cancelOrder函数。
|
||||
"""
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self, gateway):
|
||||
self.gateway = gateway # type: VnpyGateway
|
||||
|
||||
self._lastOrderId = 0
|
||||
|
||||
self._orders = {} # type: dict[str, VnpyOrder]
|
||||
self._cancelDict = {} # type: dict[str, VtCancelOrderReq]
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# todo: push this / make this standalone
|
||||
def generateVnpyOrder(self):
|
||||
localId = str(self._lastOrderId)
|
||||
self._lastOrderId += 1
|
||||
|
||||
order = VnpyOrder()
|
||||
|
||||
order.order = VtOrderData()
|
||||
order.order.orderID = localId
|
||||
order.order.vtOrderID = ".".join(self.gateway.gatewayName, localId)
|
||||
order.order.exchange = self.gateway.exchange
|
||||
|
||||
self._orders[localId] = order
|
||||
return order
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@staticmethod
|
||||
def fillVnpyOrder(order, symbol, price, totalVolume,
|
||||
direction): # type: (VnpyOrder, str, float, float, str)->None
|
||||
order.order.symbol = symbol
|
||||
order.order.vtSymbol = '.'.join([order.order.symbol, order.order.exchange])
|
||||
order.order.price = price
|
||||
order.order.totalVolume = totalVolume
|
||||
order.order.direction = direction
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def local2remote(self, localId):
|
||||
"""将localId(orderId)转化为remoteId"""
|
||||
return self._orders[localId]
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def getOrder(self, localId=None, remoteId=None):
|
||||
"""通过localId或者remoteId获取order"""
|
||||
if remoteId:
|
||||
raise NotImplementedError()
|
||||
return self._orders[localId]
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def sendOrder(self, vtRequest): # type: (VtOrderReq)->str
|
||||
"""发单"""
|
||||
|
||||
# 内部状态相关
|
||||
order = self.generateVnpyOrder()
|
||||
self.fillVnpyOrder(order,
|
||||
vtRequest.symbol,
|
||||
vtRequest.price,
|
||||
vtRequest.volume,
|
||||
vtRequest.direction)
|
||||
order.vtRequest = vtRequest
|
||||
|
||||
# 发送发单请求
|
||||
order.request = self._sendOrder(vtRequest)
|
||||
|
||||
# 增加反向引用
|
||||
# 这个写法在逻辑上有漏洞:当请求返回特别快(理论上可能)的时候,返回回调中的extra仍为空
|
||||
# 但是这种情况几乎不可能出现,在Python中就更不可能会出现。所以就这样写把,美观一些
|
||||
order.request.extra = order
|
||||
|
||||
return order.order.vtOrderID
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def cancelOrder(self, vtCancelRequest): # type: (VtCancelOrderReq)->Request
|
||||
localId = vtCancelRequest.orderID
|
||||
|
||||
order = self.getOrder(localId)
|
||||
if order.remoteId:
|
||||
return self._cancelOrder(vtCancelRequest)
|
||||
else:
|
||||
self._cancelDict[localId] = vtCancelRequest
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def _processOrderSent(self, request, remoteId):
|
||||
"""
|
||||
如果在_sendOrder中发送了HTTP请求,则应该在收到响应的时候调用该函数,
|
||||
并且将remoteId设置为交易所API使用的ID
|
||||
|
||||
如果该下单请求失败,将remoteId设为None即可
|
||||
"""
|
||||
order = request.extra # type: VnpyOrder
|
||||
localId = order.order.orderID
|
||||
if remoteId:
|
||||
order.remoteId = remoteId # None就是失败或者未返回
|
||||
self.gateway.onOrder(order.order)
|
||||
order.order.status = constant.STATUS_NOTTRADED
|
||||
|
||||
# todo: 撤单委托相关
|
||||
if localId in self._cancelDict:
|
||||
req = self._cancelDict[localId]
|
||||
self.cancelOrder(req)
|
||||
del self._cancelDict[localId]
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def _processOrderCancel(self, req, success):
|
||||
"""
|
||||
如果在_cancelOrder中发送了HTTP请求,则应该在收到响应的时候调用该函数,
|
||||
如果取消订单成功,应该将success设置为True。如果取消订单失败,则应该讲success设置为False
|
||||
"""
|
||||
order = req.extra # type: VnpyOrder
|
||||
order.order.status = constant.STATUS_CANCELLED
|
||||
pass
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@abstractmethod
|
||||
def _sendOrder(self, vtRequest): # type: (VtOrderReq)->Request
|
||||
"""
|
||||
这个函数实现下单请求。
|
||||
:return: 如果发送了HTTP请求,就应该返回addReq的值。
|
||||
"""
|
||||
pass
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@abstractmethod
|
||||
def _cancelOrder(self, vtCancelRequest): # type: (VtCancelOrderReq)->Request
|
||||
"""
|
||||
这个函数实现下单请求。
|
||||
:return: 如果发送了HTTP请求,就应该返回addReq的值。
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
########################################################################
|
||||
class OkexFutureApi(ApiBase):
|
||||
"""OKEX的API实现"""
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self, gateway):
|
||||
"""Constructor"""
|
||||
super(OkexFutureApi, self).__init__()
|
||||
self.gateway = gateway # type: OkexFutureGateway
|
||||
|
||||
self.localID = 0
|
||||
self.client = OkexFutureRestClient()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def onOrderSent(self, data, req): # type: (dict, Request)->None
|
||||
"""
|
||||
下单回执,一般用来保存sysId
|
||||
"""
|
||||
remoteId = None
|
||||
if data['result'] is True:
|
||||
remoteId = data['order_id']
|
||||
super(OkexFutureApi, self)._processOrderSent(req, remoteId)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def onOrderCanceled(self, data, req): # type: (dict, Request)->None
|
||||
"""
|
||||
取消订单回执
|
||||
:param data:
|
||||
:param req:
|
||||
:return:
|
||||
"""
|
||||
success = data['result']
|
||||
super(OkexFutureApi, self)._processOrderCancel(req, success)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def _cancelOrder(self, vtCancelRequest): # type: (VtCancelOrderReq)->Request
|
||||
localId = vtCancelRequest.orderID
|
||||
order = self.getOrder(localId)
|
||||
|
||||
data = {'symbol': order.order.symbol}
|
||||
return self.client.addReq('POST',
|
||||
'/future_cancel.do',
|
||||
callback=self.onOrderCanceled,
|
||||
data=data
|
||||
)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def _sendOrder(self, vtRequest): # type: (VtOrderReq)->Request
|
||||
"""
|
||||
单纯的发单
|
||||
"""
|
||||
symbol, contractType = symbolsForUi[vtRequest.symbol]
|
||||
orderType = orderTypeMap[(vtRequest.priceType, vtRequest.offset)] # 开多、开空、平多、平空
|
||||
|
||||
data = {}
|
||||
if vtRequest.priceType == constant.PRICETYPE_MARKETPRICE:
|
||||
data['match_price'] = 1
|
||||
else:
|
||||
data['price'] = vtRequest.price
|
||||
data.update({
|
||||
'symbol': symbol,
|
||||
'contract_typ': contractType, # 合约类型:当周/下周/季度
|
||||
'amount': vtRequest.volume,
|
||||
'type': orderType,
|
||||
'lever_rate': self.gateway.leverRate # 杠杆倍数
|
||||
})
|
||||
|
||||
request = self.client.addReq('POST',
|
||||
'/future_trade.do',
|
||||
callback=self.onOrderSent,
|
||||
data=data)
|
||||
return request
|
||||
|
Loading…
Reference in New Issue
Block a user