vnpy/vn.trader/gateway/ibGateway/ibGateway.py

736 lines
27 KiB
Python
Raw Normal View History

2016-07-02 03:12:44 +00:00
# encoding: UTF-8
'''
2017-04-28 13:32:17 +00:00
Interactive Brokers的gateway接入已经替换为vn.ib封装
2016-07-02 03:12:44 +00:00
注意事项
1. ib api只能获取和操作当前连接后下的单并且每次重启程序后之前下的单子收不到
2. ib api的成交也只会推送当前连接后的成交
3. ib api的持仓和账户更新可以订阅成主推模式因此qryAccount和qryPosition就用不到了
4. 目前只支持股票和期货交易ib api里期权合约的确定是基于Contract对象的多个字段比较复杂暂时没做
5. 海外市场的交易规则和国内有很多细节上的不同所以一些字段类型的映射可能不合理如果发现问题欢迎指出
'''
import os
import json
import calendar
from datetime import datetime, timedelta
from copy import copy
2017-04-28 13:32:17 +00:00
from vnib import *
2016-07-02 03:12:44 +00:00
from vtGateway import *
2017-04-28 13:32:17 +00:00
from language import text
2016-07-02 03:12:44 +00:00
# 以下为一些VT类型和CTP类型的映射字典
# 价格类型映射
priceTypeMap = {}
priceTypeMap[PRICETYPE_LIMITPRICE] = 'LMT'
priceTypeMap[PRICETYPE_MARKETPRICE] = 'MKT'
priceTypeMapReverse = {v: k for k, v in priceTypeMap.items()}
# 方向类型映射
directionMap = {}
directionMap[DIRECTION_LONG] = 'BUY'
#directionMap[DIRECTION_SHORT] = 'SSHORT' # SSHORT在IB系统中代表对股票的融券做空而不是国内常见的卖出
directionMap[DIRECTION_SHORT] = 'SELL' # 出于和国内的统一性考虑这里选择把IB里的SELL印射为vt的SHORT
directionMapReverse = {v: k for k, v in directionMap.items()}
directionMapReverse['BOT'] = DIRECTION_LONG
directionMapReverse['SLD'] = DIRECTION_SHORT
# 交易所类型映射
exchangeMap = {}
exchangeMap[EXCHANGE_SMART] = 'SMART'
exchangeMap[EXCHANGE_NYMEX] = 'NYMEX'
exchangeMap[EXCHANGE_GLOBEX] = 'GLOBEX'
exchangeMap[EXCHANGE_IDEALPRO] = 'IDEALPRO'
2017-04-28 13:32:17 +00:00
exchangeMap[EXCHANGE_HKEX] = 'HKEX'
exchangeMap[EXCHANGE_HKFE] = 'HKFE'
2016-07-02 03:12:44 +00:00
exchangeMapReverse = {v:k for k,v in exchangeMap.items()}
# 报单状态映射
orderStatusMap = {}
orderStatusMap[STATUS_NOTTRADED] = 'Submitted'
orderStatusMap[STATUS_ALLTRADED] = 'Filled'
orderStatusMap[STATUS_CANCELLED] = 'Cancelled'
orderStatusMapReverse = {v:k for k,v in orderStatusMap.items()}
orderStatusMapReverse['PendingSubmit'] = STATUS_UNKNOWN # 这里未来视乎需求可以拓展vt订单的状态类型
orderStatusMapReverse['PendingCancel'] = STATUS_UNKNOWN
orderStatusMapReverse['PreSubmitted'] = STATUS_UNKNOWN
orderStatusMapReverse['Inactive'] = STATUS_UNKNOWN
# 合约类型映射
productClassMap = {}
productClassMap[PRODUCT_EQUITY] = 'STK'
productClassMap[PRODUCT_FUTURES] = 'FUT'
productClassMap[PRODUCT_OPTION] = 'OPT'
productClassMap[PRODUCT_FOREX] = 'CASH'
2017-04-28 13:32:17 +00:00
productClassMap[PRODUCT_INDEX] = 'IND'
2016-07-02 03:12:44 +00:00
productClassMapReverse = {v:k for k,v in productClassMap.items()}
# 期权类型映射
optionTypeMap = {}
optionTypeMap[OPTION_CALL] = 'CALL'
optionTypeMap[OPTION_PUT] = 'PUT'
optionTypeMap = {v:k for k,v in optionTypeMap.items()}
# 货币类型映射
currencyMap = {}
currencyMap[CURRENCY_USD] = 'USD'
currencyMap[CURRENCY_CNY] = 'CNY'
2017-04-28 13:32:17 +00:00
currencyMap[CURRENCY_HKD] = 'HKD'
2016-07-02 03:12:44 +00:00
currencyMap = {v:k for k,v in currencyMap.items()}
# Tick数据的Field和名称映射
tickFieldMap = {}
tickFieldMap[0] = 'bidVolume1'
tickFieldMap[1] = 'bidPrice1'
tickFieldMap[2] = 'askPrice1'
tickFieldMap[3] = 'askVolume1'
tickFieldMap[4] = 'lastPrice'
tickFieldMap[5] = 'lastVolume'
tickFieldMap[6] = 'highPrice'
tickFieldMap[7] = 'lowPrice'
tickFieldMap[8] = 'volume'
tickFieldMap[9] = 'preClosePrice'
tickFieldMap[14] = 'openPrice'
tickFieldMap[22] = 'openInterest'
# Account数据Key和名称的映射
accountKeyMap = {}
accountKeyMap['NetLiquidationByCurrency'] = 'balance'
accountKeyMap['NetLiquidation'] = 'balance'
accountKeyMap['UnrealizedPnL'] = 'positionProfit'
accountKeyMap['AvailableFunds'] = 'available'
accountKeyMap['MaintMarginReq'] = 'margin'
########################################################################
class IbGateway(VtGateway):
"""IB接口"""
#----------------------------------------------------------------------
def __init__(self, eventEngine, gatewayName='IB'):
"""Constructor"""
super(IbGateway, self).__init__(eventEngine, gatewayName)
self.host = EMPTY_STRING # 连接地址
self.port = EMPTY_INT # 连接端口
self.clientId = EMPTY_INT # 用户编号
2017-04-28 13:32:17 +00:00
self.accountCode = EMPTY_STRING # 账户编号
2016-07-02 03:12:44 +00:00
self.tickerId = 0 # 订阅行情时的代码编号
self.tickDict = {} # tick快照字典key为tickerIdvalue为VtTickData对象
self.tickProductDict = {} # tick对应的产品类型字典key为tickerIdvalue为产品类型
self.orderId = 0 # 订单编号
self.orderDict = {} # 报单字典key为orderIdvalue为VtOrderData对象
self.accountDict = {} # 账户字典
self.contractDict = {} # 合约字典
self.subscribeReqDict = {} # 用来保存订阅请求的字典
self.connected = False # 连接状态
2017-04-28 13:32:17 +00:00
self.api = IbWrapper(self) # API接口
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def connect(self):
"""连接"""
# 载入json文件
fileName = self.gatewayName + '_connect.json'
2017-04-28 13:32:17 +00:00
path = os.path.abspath(os.path.dirname(__file__))
fileName = os.path.join(path, fileName)
2016-07-02 03:12:44 +00:00
try:
f = file(fileName)
except IOError:
log = VtLogData()
log.gatewayName = self.gatewayName
2017-04-28 13:32:17 +00:00
log.logContent = text.LOADING_ERROR
2016-07-02 03:12:44 +00:00
self.onLog(log)
return
# 解析json文件
setting = json.load(f)
try:
self.host = str(setting['host'])
self.port = int(setting['port'])
self.clientId = int(setting['clientId'])
2017-04-28 13:32:17 +00:00
self.accountCode = str(setting['accountCode'])
2016-07-02 03:12:44 +00:00
except KeyError:
log = VtLogData()
log.gatewayName = self.gatewayName
2017-04-28 13:32:17 +00:00
log.logContent = text.CONFIG_KEY_MISSING
2016-07-02 03:12:44 +00:00
self.onLog(log)
return
# 发起连接
2017-04-28 13:32:17 +00:00
self.api.eConnect(self.host, self.port, self.clientId, False)
2016-07-02 03:12:44 +00:00
# 查询服务器时间
2017-04-28 13:32:17 +00:00
self.api.reqCurrentTime()
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def subscribe(self, subscribeReq):
"""订阅行情"""
# 如果尚未连接行情,则将订阅请求缓存下来后直接返回
if not self.connected:
self.subscribeReqDict[subscribeReq.symbol] = subscribeReq
return
contract = Contract()
2017-04-28 13:32:17 +00:00
contract.localSymbol = str(subscribeReq.symbol)
contract.exchange = exchangeMap.get(subscribeReq.exchange, '')
contract.secType = productClassMap.get(subscribeReq.productClass, '')
contract.currency = currencyMap.get(subscribeReq.currency, '')
contract.expiry = subscribeReq.expiry
contract.strike = subscribeReq.strikePrice
contract.right = optionTypeMap.get(subscribeReq.optionType, '')
2016-07-02 03:12:44 +00:00
# 获取合约详细信息
self.tickerId += 1
2017-04-28 13:32:17 +00:00
self.api.reqContractDetails(self.tickerId, contract)
2016-07-02 03:12:44 +00:00
# 创建合约对象并保存到字典中
ct = VtContractData()
ct.gatewayName = self.gatewayName
ct.symbol = str(subscribeReq.symbol)
ct.exchange = subscribeReq.exchange
ct.vtSymbol = '.'.join([ct.symbol, ct.exchange])
ct.productClass = subscribeReq.productClass
self.contractDict[ct.vtSymbol] = ct
# 订阅行情
self.tickerId += 1
2017-04-28 13:32:17 +00:00
self.api.reqMktData(self.tickerId, contract, '', False, TagValueList())
2016-07-02 03:12:44 +00:00
# 创建Tick对象并保存到字典中
tick = VtTickData()
tick.symbol = subscribeReq.symbol
tick.exchange = subscribeReq.exchange
tick.vtSymbol = '.'.join([tick.symbol, tick.exchange])
tick.gatewayName = self.gatewayName
self.tickDict[self.tickerId] = tick
self.tickProductDict[self.tickerId] = subscribeReq.productClass
#----------------------------------------------------------------------
def sendOrder(self, orderReq):
"""发单"""
# 增加报单号1最后再次进行查询
# 这里双重设计的目的是为了防止某些情况下连续发单时nextOrderId的回调推送速度慢导致没有更新
self.orderId += 1
# 创建合约对象
contract = Contract()
2017-04-28 13:32:17 +00:00
contract.localSymbol = str(orderReq.symbol)
contract.exchange = exchangeMap.get(orderReq.exchange, '')
contract.secType = productClassMap.get(orderReq.productClass, '')
contract.currency = currencyMap.get(orderReq.currency, '')
contract.expiry = orderReq.expiry
contract.strike = orderReq.strikePrice
contract.right = optionTypeMap.get(orderReq.optionType, '')
contract.lastTradeDateOrContractMonth = str(orderReq.lastTradeDateOrContractMonth)
contract.multiplier = str(orderReq.multiplier)
2016-07-02 03:12:44 +00:00
# 创建委托对象
order = Order()
2017-04-28 13:32:17 +00:00
order.orderId = self.orderId
order.clientId = self.clientId
order.action = directionMap.get(orderReq.direction, '')
order.lmtPrice = orderReq.price
order.totalQuantity = orderReq.volume
order.orderType = priceTypeMap.get(orderReq.priceType, '')
2016-07-02 03:12:44 +00:00
# 发送委托
2017-04-28 13:32:17 +00:00
self.api.placeOrder(self.orderId, contract, order)
2016-07-02 03:12:44 +00:00
# 查询下一个有效编号
2017-04-28 13:32:17 +00:00
self.api.reqIds(1)
2016-07-02 03:12:44 +00:00
# 返回委托编号
vtOrderID = '.'.join([self.gatewayName, str(self.orderId)])
return vtOrderID
#----------------------------------------------------------------------
def cancelOrder(self, cancelOrderReq):
"""撤单"""
2017-04-28 13:32:17 +00:00
self.api.cancelOrder(int(cancelOrderReq.orderID))
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def qryAccount(self):
"""查询账户资金"""
log = VtLogData()
log.gatewayName = self.gatewayName
2017-04-28 13:32:17 +00:00
log.logContent = text.NONEED_TO_QRYACCOUNT
2016-07-02 03:12:44 +00:00
self.onLog(log)
#----------------------------------------------------------------------
def qryPosition(self):
"""查询持仓"""
log = VtLogData()
log.gatewayName = self.gatewayName
2017-04-28 13:32:17 +00:00
log.logContent = text.NONEED_TO_QRYPOSITION
2016-07-02 03:12:44 +00:00
self.onLog(log)
#----------------------------------------------------------------------
def close(self):
"""关闭"""
2017-04-28 13:32:17 +00:00
self.api.eDisconnect()
2016-07-02 03:12:44 +00:00
########################################################################
2017-04-28 13:32:17 +00:00
class IbWrapper(IbApi):
2016-07-02 03:12:44 +00:00
"""IB回调接口的实现"""
#----------------------------------------------------------------------
def __init__(self, gateway):
"""Constructor"""
super(IbWrapper, self).__init__()
2017-04-28 13:32:17 +00:00
self.apiStatus = False # 连接状态
2016-07-02 03:12:44 +00:00
self.gateway = gateway # gateway对象
self.gatewayName = gateway.gatewayName # gateway对象名称
self.tickDict = gateway.tickDict # tick快照字典key为tickerIdvalue为VtTickData对象
self.orderDict = gateway.orderDict # order字典
self.accountDict = gateway.accountDict # account字典
self.contractDict = gateway.contractDict # contract字典
self.tickProductDict = gateway.tickProductDict
self.subscribeReqDict = gateway.subscribeReqDict
2017-04-28 13:32:17 +00:00
#----------------------------------------------------------------------
def nextValidId(self, orderId):
""""""
self.gateway.orderId = orderId
#----------------------------------------------------------------------
def currentTime(self, time):
"""连接成功后推送当前时间"""
dt = datetime.fromtimestamp(time)
t = dt.strftime("%Y-%m-%d %H:%M:%S.%f")
self.apiStatus = True
self.gateway.connected = True
log = VtLogData()
log.gatewayName = self.gatewayName
log.logContent = text.API_CONNECTED.format(time=t)
self.gateway.onLog(log)
for symbol, req in self.subscribeReqDict.items():
del self.subscribeReqDict[symbol]
self.gateway.subscribe(req)
#----------------------------------------------------------------------
def connectAck(self):
""""""
pass
#----------------------------------------------------------------------
def error(self, id_, errorCode, errorString):
"""错误推送"""
err = VtErrorData()
err.gatewayName = self.gatewayName
err.errorID = errorCode
err.errorMsg = errorString.decode('GBK')
self.gateway.onError(err)
#----------------------------------------------------------------------
def accountSummary(self, reqId, account, tag, value, curency):
""""""
pass
#----------------------------------------------------------------------
def accountSummaryEnd(self, reqId):
""""""
pass
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def tickPrice(self, tickerId, field, price, canAutoExecute):
2017-04-28 13:32:17 +00:00
"""行情价格相关推送"""
2016-07-02 03:12:44 +00:00
if field in tickFieldMap:
2017-04-28 13:32:17 +00:00
# 对于股票、期货等行情有新价格推送时仅更新tick缓存
# 只有当发生成交后tickString更新最新成交价时才推送新的tick
# 即bid/ask的价格变动并不会触发新的tick推送
2016-07-02 03:12:44 +00:00
tick = self.tickDict[tickerId]
key = tickFieldMap[field]
tick.__setattr__(key, price)
2017-04-28 13:32:17 +00:00
# IB的外汇行情没有成交价和时间通过本地计算生成同时立即推送
2016-07-02 03:12:44 +00:00
if self.tickProductDict[tickerId] == PRODUCT_FOREX:
tick.lastPrice = (tick.bidPrice1 + tick.askPrice1) / 2
2017-04-28 13:32:17 +00:00
dt = datetime.now()
tick.time = dt.strftime('%H:%M:%S.%f')
tick.date = dt.strftime('%Y%m%d')
2016-07-02 03:12:44 +00:00
2017-04-28 13:32:17 +00:00
# 行情数据更新
newtick = copy(tick)
self.gateway.onTick(newtick)
2016-07-02 03:12:44 +00:00
else:
print field
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def tickSize(self, tickerId, field, size):
2017-04-28 13:32:17 +00:00
"""行情数量相关推送"""
2016-07-02 03:12:44 +00:00
if field in tickFieldMap:
tick = self.tickDict[tickerId]
key = tickFieldMap[field]
2017-04-28 13:32:17 +00:00
tick.__setattr__(key, size)
2016-07-02 03:12:44 +00:00
else:
print field
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def tickOptionComputation(self, tickerId, tickType, impliedVol, delta, optPrice, pvDividend, gamma, vega, theta, undPrice):
""""""
2016-07-02 03:12:44 +00:00
pass
#----------------------------------------------------------------------
def tickGeneric(self, tickerId, tickType, value):
2017-04-28 13:32:17 +00:00
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
#----------------------------------------------------------------------
2016-07-02 03:12:44 +00:00
def tickString(self, tickerId, tickType, value):
2017-04-28 13:32:17 +00:00
"""行情补充信息相关推送"""
# 如果是最新成交时间戳更新
if tickType == '45':
tick = self.tickDict[tickerId]
2016-07-02 03:12:44 +00:00
2017-04-28 13:32:17 +00:00
dt = datetime.fromtimestamp(value)
tick.time = dt.strftime('%H:%M:%S.%f')
tick.date = dt.strftime('%Y%m%d')
newtick = copy(tick)
self.gateway.onTick(newtick)
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def tickEFP(self, tickerId, tickType, basisPoints, formattedBasisPoints, totalDividends, holdDays, futureLastTradeDate, dividendImpact, dividendsToLastTradeDate):
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
#----------------------------------------------------------------------
2016-07-02 03:12:44 +00:00
def orderStatus(self, orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld):
2017-04-28 13:32:17 +00:00
"""委托状态更新"""
2016-07-02 03:12:44 +00:00
orderId = str(orderId)
if orderId in self.orderDict:
od = self.orderDict[orderId]
else:
od = VtOrderData() # od代表orderData
od.orderID = orderId
od.vtOrderID = '.'.join([self.gatewayName, orderId])
od.gatewayName = self.gatewayName
self.orderDict[orderId] = od
od.status = orderStatusMapReverse.get(status, STATUS_UNKNOWN)
od.tradedVolume = filled
newod = copy(od)
self.gateway.onOrder(newod)
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def openOrder(self, orderId, contract, order, orderState):
2017-04-28 13:32:17 +00:00
"""下达委托推送"""
2016-07-02 03:12:44 +00:00
orderId = str(orderId) # orderId是整数
if orderId in self.orderDict:
od = self.orderDict[orderId]
else:
od = VtOrderData() # od代表orderData
od.orderID = orderId
od.vtOrderID = '.'.join([self.gatewayName, orderId])
2017-04-28 13:32:17 +00:00
od.symbol = contract.localSymbol
od.exchange = exchangeMapReverse.get(contract.exchange, '')
2016-07-02 03:12:44 +00:00
od.vtSymbol = '.'.join([od.symbol, od.exchange])
od.gatewayName = self.gatewayName
self.orderDict[orderId] = od
2017-04-28 13:32:17 +00:00
od.direction = directionMapReverse.get(order.action, '')
od.price = order.lmtPrice
od.totalVolume = order.totalQuantity
2016-07-02 03:12:44 +00:00
newod = copy(od)
self.gateway.onOrder(newod)
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def openOrderEnd(self):
2017-04-28 13:32:17 +00:00
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
#----------------------------------------------------------------------
def winError(self, str_, lastError):
""""""
pass
#----------------------------------------------------------------------
def connectionClosed(self):
"""断线"""
self.apiStatus = False
self.gateway.connected = False
log = VtLogData()
log.gatewayName = self.gatewayName
log.logContent = text.API_DISCONNECTED
self.gateway.onLog(log)
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def updateAccountValue(self, key, val, currency, accountName):
2016-07-02 03:12:44 +00:00
"""更新账户数据"""
# 仅逐个字段更新数据这里对于没有currency的推送忽略
if currency:
name = '.'.join([accountName, currency])
if name in self.accountDict:
account = self.accountDict[name]
else:
account = VtAccountData()
account.accountID = name
account.vtAccountID = name
account.gatewayName = self.gatewayName
self.accountDict[name] = account
if key in accountKeyMap:
k = accountKeyMap[key]
2017-04-28 13:32:17 +00:00
account.__setattr__(k, float(val))
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def updatePortfolio(self, contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName):
2017-04-28 13:32:17 +00:00
"""持仓更新"""
2016-07-02 03:12:44 +00:00
pos = VtPositionData()
2017-04-28 13:32:17 +00:00
pos.symbol = contract.localSymbol
pos.exchange = exchangeMapReverse.get(contract.exchange, contract.exchange)
2016-07-02 03:12:44 +00:00
pos.vtSymbol = '.'.join([pos.symbol, pos.exchange])
pos.direction = DIRECTION_NET
pos.position = position
pos.price = averageCost
pos.vtPositionName = pos.vtSymbol
pos.gatewayName = self.gatewayName
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
self.gateway.onPosition(pos)
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def updateAccountTime(self, timeStamp):
2017-04-28 13:32:17 +00:00
"""更新账户时间"""
2016-07-02 03:12:44 +00:00
# 推送数据
for account in self.accountDict.values():
newaccount = copy(account)
self.gateway.onAccount(newaccount)
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def accountDownloadEnd(self, accountName):
2017-04-28 13:32:17 +00:00
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def contractDetails(self, reqId, contractDetails):
"""合约查询回报"""
2017-04-28 13:32:17 +00:00
symbol = contractDetails.summary.localSymbol
exchange = exchangeMapReverse.get(contractDetails.summary.exchange, EXCHANGE_UNKNOWN)
2016-07-02 03:12:44 +00:00
vtSymbol = '.'.join([symbol, exchange])
ct = self.contractDict.get(vtSymbol, None)
if not ct:
return
2017-04-28 13:32:17 +00:00
ct.name = contractDetails.longName.decode('UTF-8')
ct.priceTick = contractDetails.minTick
2016-07-02 03:12:44 +00:00
# 推送
self.gateway.onContract(ct)
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def bondContractDetails(self, reqId, contractDetails):
2017-04-28 13:32:17 +00:00
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def contractDetailsEnd(self, reqId):
2017-04-28 13:32:17 +00:00
""""""
2016-07-02 03:12:44 +00:00
pass
#----------------------------------------------------------------------
def execDetails(self, reqId, contract, execution):
"""成交推送"""
trade = VtTradeData()
trade.gatewayName = self.gatewayName
2017-04-28 13:32:17 +00:00
trade.tradeID = execution.execId
2016-07-02 03:12:44 +00:00
trade.vtTradeID = '.'.join([self.gatewayName, trade.tradeID])
2017-04-28 13:32:17 +00:00
trade.symbol = contract.localSymbol
trade.exchange = exchangeMapReverse.get(contract.exchange, '')
2016-07-02 03:12:44 +00:00
trade.vtSymbol = '.'.join([trade.symbol, trade.exchange])
2017-04-28 13:32:17 +00:00
trade.orderID = str(execution.orderId)
trade.vtOrderID = '.'.join([self.gatewayName, trade.orderID])
trade.direction = directionMapReverse.get(execution.side, '')
trade.price = execution.price
trade.volume = execution.shares
trade.tradeTime = execution.time
2016-07-02 03:12:44 +00:00
self.gateway.onTrade(trade)
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def execDetailsEnd(self, reqId):
2017-04-28 13:32:17 +00:00
""""""
2016-07-02 03:12:44 +00:00
pass
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def updateMktDepth(self, id_, position, operation, side, price, size):
""""""
2016-07-02 03:12:44 +00:00
pass
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def updateMktDepthL2(self, id_, position, marketMaker, operation, side, price, size):
""""""
2016-07-02 03:12:44 +00:00
pass
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def updateNewsBulletin(self, msgId, msgType, newsMessage, originExch):
""""""
2016-07-02 03:12:44 +00:00
pass
#----------------------------------------------------------------------
def managedAccounts(self, accountsList):
2017-04-28 13:32:17 +00:00
"""推送管理账户的信息"""
l = accountsList.split(',')
# 请求账户数据主推更新
for account in l:
self.reqAccountUpdates(True, account)
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def receiveFA(self, pFaDataType, cxml):
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def historicalData(self, reqId, date, open_, high, low, close, volume, barCount, WAP, hasGaps):
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def scannerParameters(self, xml):
2017-04-28 13:32:17 +00:00
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def scannerData(self, reqId, rank, contractDetails, distance, benchmark, projection, legsStr):
2017-04-28 13:32:17 +00:00
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def scannerDataEnd(self, reqId):
2017-04-28 13:32:17 +00:00
""""""
2016-07-02 03:12:44 +00:00
pass
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def realtimeBar(self, reqId, time, open_, high, low, close, volume, wap, count):
""""""
2016-07-02 03:12:44 +00:00
pass
#----------------------------------------------------------------------
def fundamentalData(self, reqId, data):
2017-04-28 13:32:17 +00:00
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def deltaNeutralValidation(self, reqId, underComp):
2017-04-28 13:32:17 +00:00
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def tickSnapshotEnd(self, reqId):
2017-04-28 13:32:17 +00:00
""""""
2016-07-02 03:12:44 +00:00
pass
#----------------------------------------------------------------------
def marketDataType(self, reqId, marketDataType):
2017-04-28 13:32:17 +00:00
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def commissionReport(self, commissionReport):
2017-04-28 13:32:17 +00:00
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def position(self, account, contract, position, avgCost):
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
def positionEnd(self):
2017-04-28 13:32:17 +00:00
""""""
pass
#----------------------------------------------------------------------
def verifyMessageAPI(self, apiData):
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def verifyCompleted(self, isSuccessful, errorText):
""""""
2016-07-02 03:12:44 +00:00
pass
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def displayGroupList(self, reqId, groups):
""""""
2016-07-02 03:12:44 +00:00
pass
2017-04-28 13:32:17 +00:00
#----------------------------------------------------------------------
def displayGroupUpdated(self, reqId, contractInfo):
""""""
pass
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def verifyAndAuthMessageAPI(self, apiData, xyzChallange):
""""""
pass
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def verifyAndAuthCompleted(self, isSuccessful, errorText):
""""""
pass
#----------------------------------------------------------------------
def positionMulti(self, reqId, account, modelCode, contract, pos, avgCost):
""""""
pass
#----------------------------------------------------------------------
def positionMultiEnd(self, reqId):
""""""
pass
#----------------------------------------------------------------------
def accountUpdateMulti(self, reqId, account, modelCode, key, value, currency):
""""""
pass
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def accountUpdateMultiEnd(self, reqId):
""""""
pass
2016-07-02 03:12:44 +00:00
#----------------------------------------------------------------------
2017-04-28 13:32:17 +00:00
def securityDefinitionOptionalParameter(self, reqId, exchange, underlyingConId, tradingClass, multiplier, expirations, strikes):
""""""
pass
#----------------------------------------------------------------------
def securityDefinitionOptionalParameterEnd(self, reqId):
""""""
pass
#----------------------------------------------------------------------
def softDollarTiers(self, reqId, tiers):
""""""
pass