将IbGateway里使用的IbPy替换为vn.ib接口,测试外汇交易无问题
This commit is contained in:
parent
70723dc0cc
commit
8e658868b2
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<SubscriptionDataContainer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:Microsoft.VisualStudio.WindowsAzure.CommonAzureTools.Authentication.CacheManagement">
|
<SubscriptionDataContainer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:Microsoft.VisualStudio.WindowsAzure.CommonAzureTools.Authentication.CacheManagement">
|
||||||
<Items />
|
<Items />
|
||||||
<TokenCache>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAhuIZgFnYcU6wvp5DI4FozAAAAAACAAAAAAAQZgAAAAEAACAAAAAXSj17R5SUHe+A58o1bYLSOOhH9W2Ix9DlZDFBrgVA4gAAAAAOgAAAAAIAACAAAADbVSL+BIaujSBj3UmMHFYW0NN/5M1VZMBFC5NayhA3uBAAAADlsZqLyiwLiExTjbbDU1nZQAAAAA8KhP6XKTAD/Iuw37pqb7rSwSDYQgFsBJvhh4KMkHc9aX3Q+ga9NjStuUrdZVmuMzeMGwsQ+bjLejvA3cCOI9c=</TokenCache>
|
<TokenCache>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAhuIZgFnYcU6wvp5DI4FozAAAAAACAAAAAAAQZgAAAAEAACAAAADnrYSEO5qfCQPpiUFTIS3ZRFiTItrg4/VIVOH2J3epYgAAAAAOgAAAAAIAACAAAACso6CSyxkad28kFe3eIz1YgltVz/YV200C+PLOhtmmPhAAAABBWAXXnj8W8KUy+QlVKF7JQAAAAFuRLjt27YOpR9+kkpnrDzww07fBW08hBX6gGDrJVJp/hGhDL4nX/wEgsPuN/EJB4f48rrPnGlHmfb6B9a0Il60=</TokenCache>
|
||||||
</SubscriptionDataContainer>
|
</SubscriptionDataContainer>
|
@ -1499,15 +1499,15 @@ BOOST_PYTHON_MODULE(vnib)
|
|||||||
.def_readwrite("shares", &Execution::shares)
|
.def_readwrite("shares", &Execution::shares)
|
||||||
.def_readwrite("price", &Execution::price)
|
.def_readwrite("price", &Execution::price)
|
||||||
.def_readwrite("permId", &Execution::permId)
|
.def_readwrite("permId", &Execution::permId)
|
||||||
.def_readwrite("clientId ", &Execution::clientId)
|
.def_readwrite("clientId", &Execution::clientId)
|
||||||
.def_readwrite("orderId ", &Execution::orderId)
|
.def_readwrite("orderId", &Execution::orderId)
|
||||||
.def_readwrite("liquidation ", &Execution::liquidation)
|
.def_readwrite("liquidation", &Execution::liquidation)
|
||||||
.def_readwrite("cumQty ", &Execution::cumQty)
|
.def_readwrite("cumQty", &Execution::cumQty)
|
||||||
.def_readwrite("avgPrice ", &Execution::avgPrice)
|
.def_readwrite("avgPrice", &Execution::avgPrice)
|
||||||
.def_readwrite("orderRef ", &Execution::orderRef)
|
.def_readwrite("orderRef", &Execution::orderRef)
|
||||||
.def_readwrite("evRule ", &Execution::evRule)
|
.def_readwrite("evRule", &Execution::evRule)
|
||||||
.def_readwrite("evMultiplier ", &Execution::evMultiplier)
|
.def_readwrite("evMultiplier", &Execution::evMultiplier)
|
||||||
.def_readwrite("modelCode ", &Execution::modelCode)
|
.def_readwrite("modelCode", &Execution::modelCode)
|
||||||
;
|
;
|
||||||
|
|
||||||
class_<UnderComp>("UnderComp")
|
class_<UnderComp>("UnderComp")
|
||||||
|
@ -166,12 +166,14 @@ class BacktestEngineMultiTF(BacktestingEngine):
|
|||||||
data = self.infobar[info_symbol]
|
data = self.infobar[info_symbol]
|
||||||
|
|
||||||
# Update data only when Time Stamp is matched
|
# Update data only when Time Stamp is matched
|
||||||
if data['datetime'] <= self.dt:
|
if (data is not None) and (data['datetime'] <= self.dt):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
temp[info_symbol] = CtaBarData()
|
temp[info_symbol] = CtaBarData()
|
||||||
temp[info_symbol].__dict__ = data
|
temp[info_symbol].__dict__ = data
|
||||||
self.infobar[info_symbol] = next(self.InfoCursor[info_symbol])
|
self.infobar[info_symbol] = next(self.InfoCursor[info_symbol])
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
|
self.infobar[info_symbol] = None
|
||||||
self.output("No more data in information database.")
|
self.output("No more data in information database.")
|
||||||
else:
|
else:
|
||||||
temp[info_symbol] = None
|
temp[info_symbol] = None
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"port": 7496,
|
"port": 7497,
|
||||||
"clientId": 888
|
"clientId": 888,
|
||||||
|
"accountCode": "DU545254"
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
'''
|
'''
|
||||||
ibpy的gateway接入
|
Interactive Brokers的gateway接入,已经替换为vn.ib封装。
|
||||||
|
|
||||||
注意事项:
|
注意事项:
|
||||||
1. ib api只能获取和操作当前连接后下的单,并且每次重启程序后,之前下的单子收不到
|
1. ib api只能获取和操作当前连接后下的单,并且每次重启程序后,之前下的单子收不到
|
||||||
@ -19,11 +19,7 @@ from copy import copy
|
|||||||
|
|
||||||
from PyQt4 import QtGui, QtCore
|
from PyQt4 import QtGui, QtCore
|
||||||
|
|
||||||
from ib.ext.Contract import Contract
|
from vnib import *
|
||||||
from ib.ext.Order import Order
|
|
||||||
from ib.ext.EWrapper import EWrapper
|
|
||||||
from ib.ext.EClientSocket import EClientSocket
|
|
||||||
|
|
||||||
from vtGateway import *
|
from vtGateway import *
|
||||||
|
|
||||||
|
|
||||||
@ -119,6 +115,7 @@ class IbGateway(VtGateway):
|
|||||||
self.host = EMPTY_STRING # 连接地址
|
self.host = EMPTY_STRING # 连接地址
|
||||||
self.port = EMPTY_INT # 连接端口
|
self.port = EMPTY_INT # 连接端口
|
||||||
self.clientId = EMPTY_INT # 用户编号
|
self.clientId = EMPTY_INT # 用户编号
|
||||||
|
self.accountCode = EMPTY_STRING # 账户编号
|
||||||
|
|
||||||
self.tickerId = 0 # 订阅行情时的代码编号
|
self.tickerId = 0 # 订阅行情时的代码编号
|
||||||
self.tickDict = {} # tick快照字典,key为tickerId,value为VtTickData对象
|
self.tickDict = {} # tick快照字典,key为tickerId,value为VtTickData对象
|
||||||
@ -135,8 +132,7 @@ class IbGateway(VtGateway):
|
|||||||
|
|
||||||
self.connected = False # 连接状态
|
self.connected = False # 连接状态
|
||||||
|
|
||||||
self.wrapper = IbWrapper(self) # 回调接口
|
self.api = IbWrapper(self) # API接口
|
||||||
self.connection = EClientSocket(self.wrapper) # 主动接口
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def connect(self):
|
def connect(self):
|
||||||
@ -161,6 +157,7 @@ class IbGateway(VtGateway):
|
|||||||
self.host = str(setting['host'])
|
self.host = str(setting['host'])
|
||||||
self.port = int(setting['port'])
|
self.port = int(setting['port'])
|
||||||
self.clientId = int(setting['clientId'])
|
self.clientId = int(setting['clientId'])
|
||||||
|
self.accountCode = str(setting['accountCode'])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
log = VtLogData()
|
log = VtLogData()
|
||||||
log.gatewayName = self.gatewayName
|
log.gatewayName = self.gatewayName
|
||||||
@ -169,13 +166,13 @@ class IbGateway(VtGateway):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# 发起连接
|
# 发起连接
|
||||||
self.connection.eConnect(self.host, self.port, self.clientId)
|
self.api.eConnect(self.host, self.port, self.clientId, False)
|
||||||
|
|
||||||
# 查询服务器时间
|
# 查询服务器时间
|
||||||
self.connection.reqCurrentTime()
|
self.api.reqCurrentTime()
|
||||||
|
|
||||||
# 请求账户数据主推更新
|
# 请求账户数据主推更新
|
||||||
self.connection.reqAccountUpdates(True, '')
|
self.api.reqAccountUpdates(True, self.accountCode)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def subscribe(self, subscribeReq):
|
def subscribe(self, subscribeReq):
|
||||||
@ -186,17 +183,17 @@ class IbGateway(VtGateway):
|
|||||||
return
|
return
|
||||||
|
|
||||||
contract = Contract()
|
contract = Contract()
|
||||||
contract.m_localSymbol = str(subscribeReq.symbol)
|
contract.localSymbol = str(subscribeReq.symbol)
|
||||||
contract.m_exchange = exchangeMap.get(subscribeReq.exchange, '')
|
contract.exchange = exchangeMap.get(subscribeReq.exchange, '')
|
||||||
contract.m_secType = productClassMap.get(subscribeReq.productClass, '')
|
contract.secType = productClassMap.get(subscribeReq.productClass, '')
|
||||||
contract.m_currency = currencyMap.get(subscribeReq.currency, '')
|
contract.currency = currencyMap.get(subscribeReq.currency, '')
|
||||||
contract.m_expiry = subscribeReq.expiry
|
contract.expiry = subscribeReq.expiry
|
||||||
contract.m_strike = subscribeReq.strikePrice
|
contract.strike = subscribeReq.strikePrice
|
||||||
contract.m_right = optionTypeMap.get(subscribeReq.optionType, '')
|
contract.right = optionTypeMap.get(subscribeReq.optionType, '')
|
||||||
|
|
||||||
# 获取合约详细信息
|
# 获取合约详细信息
|
||||||
self.tickerId += 1
|
self.tickerId += 1
|
||||||
self.connection.reqContractDetails(self.tickerId, contract)
|
self.api.reqContractDetails(self.tickerId, contract)
|
||||||
|
|
||||||
# 创建合约对象并保存到字典中
|
# 创建合约对象并保存到字典中
|
||||||
ct = VtContractData()
|
ct = VtContractData()
|
||||||
@ -209,7 +206,7 @@ class IbGateway(VtGateway):
|
|||||||
|
|
||||||
# 订阅行情
|
# 订阅行情
|
||||||
self.tickerId += 1
|
self.tickerId += 1
|
||||||
self.connection.reqMktData(self.tickerId, contract, '', False)
|
self.api.reqMktData(self.tickerId, contract, '', False, TagValueList())
|
||||||
|
|
||||||
# 创建Tick对象并保存到字典中
|
# 创建Tick对象并保存到字典中
|
||||||
tick = VtTickData()
|
tick = VtTickData()
|
||||||
@ -229,28 +226,28 @@ class IbGateway(VtGateway):
|
|||||||
|
|
||||||
# 创建合约对象
|
# 创建合约对象
|
||||||
contract = Contract()
|
contract = Contract()
|
||||||
contract.m_localSymbol = str(orderReq.symbol)
|
contract.localSymbol = str(orderReq.symbol)
|
||||||
contract.m_exchange = exchangeMap.get(orderReq.exchange, '')
|
contract.exchange = exchangeMap.get(orderReq.exchange, '')
|
||||||
contract.m_secType = productClassMap.get(orderReq.productClass, '')
|
contract.secType = productClassMap.get(orderReq.productClass, '')
|
||||||
contract.m_currency = currencyMap.get(orderReq.currency, '')
|
contract.currency = currencyMap.get(orderReq.currency, '')
|
||||||
contract.m_expiry = orderReq.expiry
|
contract.expiry = orderReq.expiry
|
||||||
contract.m_strike = orderReq.strikePrice
|
contract.strike = orderReq.strikePrice
|
||||||
contract.m_right = optionTypeMap.get(orderReq.optionType, '')
|
contract.right = optionTypeMap.get(orderReq.optionType, '')
|
||||||
|
|
||||||
# 创建委托对象
|
# 创建委托对象
|
||||||
order = Order()
|
order = Order()
|
||||||
order.m_orderId = self.orderId
|
order.orderId = self.orderId
|
||||||
order.m_clientId = self.clientId
|
order.clientId = self.clientId
|
||||||
order.m_action = directionMap.get(orderReq.direction, '')
|
order.action = directionMap.get(orderReq.direction, '')
|
||||||
order.m_lmtPrice = orderReq.price
|
order.lmtPrice = orderReq.price
|
||||||
order.m_totalQuantity = orderReq.volume
|
order.totalQuantity = orderReq.volume
|
||||||
order.m_orderType = priceTypeMap.get(orderReq.priceType, '')
|
order.orderType = priceTypeMap.get(orderReq.priceType, '')
|
||||||
|
|
||||||
# 发送委托
|
# 发送委托
|
||||||
self.connection.placeOrder(self.orderId, contract, order)
|
self.api.placeOrder(self.orderId, contract, order)
|
||||||
|
|
||||||
# 查询下一个有效编号
|
# 查询下一个有效编号
|
||||||
self.connection.reqIds(1)
|
self.api.reqIds(1)
|
||||||
|
|
||||||
# 返回委托编号
|
# 返回委托编号
|
||||||
vtOrderID = '.'.join([self.gatewayName, str(self.orderId)])
|
vtOrderID = '.'.join([self.gatewayName, str(self.orderId)])
|
||||||
@ -259,7 +256,7 @@ class IbGateway(VtGateway):
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def cancelOrder(self, cancelOrderReq):
|
def cancelOrder(self, cancelOrderReq):
|
||||||
"""撤单"""
|
"""撤单"""
|
||||||
self.connection.cancelOrder(cancelOrderReq.orderID)
|
self.api.cancelOrder(int(cancelOrderReq.orderID))
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def qryAccount(self):
|
def qryAccount(self):
|
||||||
@ -280,11 +277,11 @@ class IbGateway(VtGateway):
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def close(self):
|
def close(self):
|
||||||
"""关闭"""
|
"""关闭"""
|
||||||
self.connection.eDisconnect()
|
self.api.eDisconnect()
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
class IbWrapper(EWrapper):
|
class IbWrapper(IbApi):
|
||||||
"""IB回调接口的实现"""
|
"""IB回调接口的实现"""
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
@ -292,7 +289,7 @@ class IbWrapper(EWrapper):
|
|||||||
"""Constructor"""
|
"""Constructor"""
|
||||||
super(IbWrapper, self).__init__()
|
super(IbWrapper, self).__init__()
|
||||||
|
|
||||||
self.connectionStatus = False # 连接状态
|
self.apiStatus = False # 连接状态
|
||||||
|
|
||||||
self.gateway = gateway # gateway对象
|
self.gateway = gateway # gateway对象
|
||||||
self.gatewayName = gateway.gatewayName # gateway对象名称
|
self.gatewayName = gateway.gatewayName # gateway对象名称
|
||||||
@ -303,10 +300,57 @@ class IbWrapper(EWrapper):
|
|||||||
self.contractDict = gateway.contractDict # contract字典
|
self.contractDict = gateway.contractDict # contract字典
|
||||||
self.tickProductDict = gateway.tickProductDict
|
self.tickProductDict = gateway.tickProductDict
|
||||||
self.subscribeReqDict = gateway.subscribeReqDict
|
self.subscribeReqDict = gateway.subscribeReqDict
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
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 = (u'IB接口连接成功,当前服务器时间 %s' %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
|
||||||
|
self.gateway.onError(err)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def accountSummary(self, reqId, account, tag, value, curency):
|
||||||
|
""""""
|
||||||
|
pass
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def accountSummaryEnd(self, reqId):
|
||||||
|
""""""
|
||||||
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def tickPrice(self, tickerId, field, price, canAutoExecute):
|
def tickPrice(self, tickerId, field, price, canAutoExecute):
|
||||||
"""行情推送(价格相关)"""
|
"""行情价格相关推送"""
|
||||||
if field in tickFieldMap:
|
if field in tickFieldMap:
|
||||||
tick = self.tickDict[tickerId]
|
tick = self.tickDict[tickerId]
|
||||||
key = tickFieldMap[field]
|
key = tickFieldMap[field]
|
||||||
@ -324,10 +368,10 @@ class IbWrapper(EWrapper):
|
|||||||
self.gateway.onTick(newtick)
|
self.gateway.onTick(newtick)
|
||||||
else:
|
else:
|
||||||
print field
|
print field
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def tickSize(self, tickerId, field, size):
|
def tickSize(self, tickerId, field, size):
|
||||||
"""行情推送(量相关)"""
|
"""行情数量相关推送"""
|
||||||
if field in tickFieldMap:
|
if field in tickFieldMap:
|
||||||
tick = self.tickDict[tickerId]
|
tick = self.tickDict[tickerId]
|
||||||
key = tickFieldMap[field]
|
key = tickFieldMap[field]
|
||||||
@ -342,34 +386,30 @@ class IbWrapper(EWrapper):
|
|||||||
self.gateway.onTick(newtick)
|
self.gateway.onTick(newtick)
|
||||||
else:
|
else:
|
||||||
print field
|
print field
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def tickOptionComputation(self, tickerId, field, impliedVol, delta, optPrice, pvDividend, gamma, vega, theta, undPrice):
|
def tickOptionComputation(self, tickerId, tickType, impliedVol, delta, optPrice, pvDividend, gamma, vega, theta, undPrice):
|
||||||
"""行情推送(期权数值)"""
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def tickGeneric(self, tickerId, tickType, value):
|
def tickGeneric(self, tickerId, tickType, value):
|
||||||
"""行情推送(某些通用字段)"""
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
def tickString(self, tickerId, tickType, value):
|
|
||||||
"""行情推送,特殊字段相关"""
|
|
||||||
# 参考了一些其他平台对于IB行情数据的开发建议后,
|
|
||||||
# 发现大部分都选择使用本地电脑时间戳而非IB推送的时间戳,
|
|
||||||
# 猜测原因可能是IB的行情质量一般(本身就是切片了的),
|
|
||||||
# 因此这里也选择使用电脑的本地时间
|
|
||||||
pass
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def tickEFP(self, tickerId, tickType, basisPoints, formattedBasisPoints, impliedFuture, holdDays, futureExpiry, dividendImpact, dividendsToExpiry):
|
def tickString(self, tickerId, tickType, value):
|
||||||
"""行情推送(合约属性相关)"""
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
def tickEFP(self, tickerId, tickType, basisPoints, formattedBasisPoints, totalDividends, holdDays, futureLastTradeDate, dividendImpact, dividendsToLastTradeDate):
|
||||||
|
""""""
|
||||||
|
pass
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
def orderStatus(self, orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld):
|
def orderStatus(self, orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld):
|
||||||
"""报单成交回报"""
|
"""委托状态更新"""
|
||||||
orderId = str(orderId)
|
orderId = str(orderId)
|
||||||
|
|
||||||
if orderId in self.orderDict:
|
if orderId in self.orderDict:
|
||||||
@ -386,10 +426,10 @@ class IbWrapper(EWrapper):
|
|||||||
|
|
||||||
newod = copy(od)
|
newod = copy(od)
|
||||||
self.gateway.onOrder(newod)
|
self.gateway.onOrder(newod)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def openOrder(self, orderId, contract, order, orderState):
|
def openOrder(self, orderId, contract, order, orderState):
|
||||||
"""报单信息推送"""
|
"""下达委托推送"""
|
||||||
orderId = str(orderId) # orderId是整数
|
orderId = str(orderId) # orderId是整数
|
||||||
|
|
||||||
if orderId in self.orderDict:
|
if orderId in self.orderDict:
|
||||||
@ -398,26 +438,42 @@ class IbWrapper(EWrapper):
|
|||||||
od = VtOrderData() # od代表orderData
|
od = VtOrderData() # od代表orderData
|
||||||
od.orderID = orderId
|
od.orderID = orderId
|
||||||
od.vtOrderID = '.'.join([self.gatewayName, orderId])
|
od.vtOrderID = '.'.join([self.gatewayName, orderId])
|
||||||
od.symbol = contract.m_localSymbol
|
od.symbol = contract.localSymbol
|
||||||
od.exchange = exchangeMapReverse.get(contract.m_exchange, '')
|
od.exchange = exchangeMapReverse.get(contract.exchange, '')
|
||||||
od.vtSymbol = '.'.join([od.symbol, od.exchange])
|
od.vtSymbol = '.'.join([od.symbol, od.exchange])
|
||||||
od.gatewayName = self.gatewayName
|
od.gatewayName = self.gatewayName
|
||||||
self.orderDict[orderId] = od
|
self.orderDict[orderId] = od
|
||||||
|
|
||||||
od.direction = directionMapReverse.get(order.m_action, '')
|
od.direction = directionMapReverse.get(order.action, '')
|
||||||
od.price = order.m_lmtPrice
|
od.price = order.lmtPrice
|
||||||
od.totalVolume = order.m_totalQuantity
|
od.totalVolume = order.totalQuantity
|
||||||
|
|
||||||
newod = copy(od)
|
newod = copy(od)
|
||||||
self.gateway.onOrder(newod)
|
self.gateway.onOrder(newod)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def openOrderEnd(self):
|
def openOrderEnd(self):
|
||||||
""" generated source for method openOrderEnd """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def updateAccountValue(self, key, value, currency, accountName):
|
def winError(self, str_, lastError):
|
||||||
|
""""""
|
||||||
|
pass
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def connectionClosed(self):
|
||||||
|
"""断线"""
|
||||||
|
self.apiStatus = False
|
||||||
|
self.gateway.connected = False
|
||||||
|
|
||||||
|
log = VtLogData()
|
||||||
|
log.gatewayName = self.gatewayName
|
||||||
|
log.logContent = (u'IB接口连接断开')
|
||||||
|
self.gateway.onLog(log)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def updateAccountValue(self, key, val, currency, accountName):
|
||||||
"""更新账户数据"""
|
"""更新账户数据"""
|
||||||
# 仅逐个字段更新数据,这里对于没有currency的推送忽略
|
# 仅逐个字段更新数据,这里对于没有currency的推送忽略
|
||||||
if currency:
|
if currency:
|
||||||
@ -434,68 +490,62 @@ class IbWrapper(EWrapper):
|
|||||||
|
|
||||||
if key in accountKeyMap:
|
if key in accountKeyMap:
|
||||||
k = accountKeyMap[key]
|
k = accountKeyMap[key]
|
||||||
account.__setattr__(k, float(value))
|
account.__setattr__(k, float(val))
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def updatePortfolio(self, contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName):
|
def updatePortfolio(self, contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName):
|
||||||
"""持仓更新推送"""
|
"""持仓更新"""
|
||||||
pos = VtPositionData()
|
pos = VtPositionData()
|
||||||
|
|
||||||
pos.symbol = contract.m_localSymbol
|
pos.symbol = contract.localSymbol
|
||||||
pos.exchange = exchangeMapReverse.get(contract.m_exchange, contract.m_exchange)
|
pos.exchange = exchangeMapReverse.get(contract.exchange, contract.exchange)
|
||||||
pos.vtSymbol = '.'.join([pos.symbol, pos.exchange])
|
pos.vtSymbol = '.'.join([pos.symbol, pos.exchange])
|
||||||
pos.direction = DIRECTION_NET
|
pos.direction = DIRECTION_NET
|
||||||
pos.position = position
|
pos.position = position
|
||||||
pos.price = averageCost
|
pos.price = averageCost
|
||||||
pos.vtPositionName = pos.vtSymbol
|
pos.vtPositionName = pos.vtSymbol
|
||||||
pos.gatewayName = self.gatewayName
|
pos.gatewayName = self.gatewayName
|
||||||
|
|
||||||
self.gateway.onPosition(pos)
|
self.gateway.onPosition(pos)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def updateAccountTime(self, timeStamp):
|
def updateAccountTime(self, timeStamp):
|
||||||
"""更新账户数据的时间"""
|
"""更新账户时间"""
|
||||||
# 推送数据
|
# 推送数据
|
||||||
for account in self.accountDict.values():
|
for account in self.accountDict.values():
|
||||||
newaccount = copy(account)
|
newaccount = copy(account)
|
||||||
self.gateway.onAccount(newaccount)
|
self.gateway.onAccount(newaccount)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def accountDownloadEnd(self, accountName):
|
def accountDownloadEnd(self, accountName):
|
||||||
""" generated source for method accountDownloadEnd """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
def nextValidId(self, orderId):
|
|
||||||
"""下一个有效报单编号更新"""
|
|
||||||
self.gateway.orderId = orderId
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def contractDetails(self, reqId, contractDetails):
|
def contractDetails(self, reqId, contractDetails):
|
||||||
"""合约查询回报"""
|
"""合约查询回报"""
|
||||||
symbol = contractDetails.m_summary.m_localSymbol
|
symbol = contractDetails.summary.localSymbol
|
||||||
exchange = exchangeMapReverse.get(contractDetails.m_summary.m_exchange, EXCHANGE_UNKNOWN)
|
exchange = exchangeMapReverse.get(contractDetails.summary.exchange, EXCHANGE_UNKNOWN)
|
||||||
vtSymbol = '.'.join([symbol, exchange])
|
vtSymbol = '.'.join([symbol, exchange])
|
||||||
ct = self.contractDict.get(vtSymbol, None)
|
ct = self.contractDict.get(vtSymbol, None)
|
||||||
|
|
||||||
if not ct:
|
if not ct:
|
||||||
return
|
return
|
||||||
|
|
||||||
ct.name = contractDetails.m_longName.decode('UTF-8')
|
ct.name = contractDetails.longName.decode('UTF-8')
|
||||||
ct.priceTick = contractDetails.m_minTick
|
ct.priceTick = contractDetails.minTick
|
||||||
|
|
||||||
# 推送
|
# 推送
|
||||||
self.gateway.onContract(ct)
|
self.gateway.onContract(ct)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def bondContractDetails(self, reqId, contractDetails):
|
def bondContractDetails(self, reqId, contractDetails):
|
||||||
""" generated source for method bondContractDetails """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def contractDetailsEnd(self, reqId):
|
def contractDetailsEnd(self, reqId):
|
||||||
""" 获取合约结束 """
|
""""""
|
||||||
# 因为IB的合约获取是一个个合约进行的,并不会用于触发其他操作,因此无需发出日志
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
@ -503,172 +553,168 @@ class IbWrapper(EWrapper):
|
|||||||
"""成交推送"""
|
"""成交推送"""
|
||||||
trade = VtTradeData()
|
trade = VtTradeData()
|
||||||
trade.gatewayName = self.gatewayName
|
trade.gatewayName = self.gatewayName
|
||||||
trade.tradeID = execution.m_execId
|
trade.tradeID = execution.execId
|
||||||
trade.vtTradeID = '.'.join([self.gatewayName, trade.tradeID])
|
trade.vtTradeID = '.'.join([self.gatewayName, trade.tradeID])
|
||||||
|
|
||||||
trade.symbol = contract.m_localSymbol
|
trade.symbol = contract.localSymbol
|
||||||
trade.exchange = exchangeMapReverse.get(contract.m_exchange, '')
|
trade.exchange = exchangeMapReverse.get(contract.exchange, '')
|
||||||
trade.vtSymbol = '.'.join([trade.symbol, trade.exchange])
|
trade.vtSymbol = '.'.join([trade.symbol, trade.exchange])
|
||||||
|
|
||||||
trade.orderID = str(execution.m_orderId)
|
trade.orderID = str(execution.orderId)
|
||||||
trade.direction = directionMapReverse.get(execution.m_side, '')
|
trade.direction = directionMapReverse.get(execution.side, '')
|
||||||
trade.price = execution.m_price
|
trade.price = execution.price
|
||||||
trade.volume = execution.m_shares
|
trade.volume = execution.shares
|
||||||
trade.tradeTime = execution.m_time
|
trade.tradeTime = execution.time
|
||||||
|
|
||||||
self.gateway.onTrade(trade)
|
self.gateway.onTrade(trade)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def execDetailsEnd(self, reqId):
|
def execDetailsEnd(self, reqId):
|
||||||
""" generated source for method execDetailsEnd """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def updateMktDepth(self, tickerId, position, operation, side, price, size):
|
def updateMktDepth(self, id_, position, operation, side, price, size):
|
||||||
""" generated source for method updateMktDepth """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def updateMktDepthL2(self, tickerId, position, marketMaker, operation, side, price, size):
|
def updateMktDepthL2(self, id_, position, marketMaker, operation, side, price, size):
|
||||||
""" generated source for method updateMktDepthL2 """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def updateNewsBulletin(self, msgId, msgType, message, origExchange):
|
def updateNewsBulletin(self, msgId, msgType, newsMessage, originExch):
|
||||||
""" generated source for method updateNewsBulletin """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def managedAccounts(self, accountsList):
|
def managedAccounts(self, accountsList):
|
||||||
""" generated source for method managedAccounts """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def receiveFA(self, faDataType, xml):
|
def receiveFA(self, pFaDataType, cxml):
|
||||||
""" generated source for method receiveFA """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def historicalData(self, reqId, date, open, high, low, close, volume, count, WAP, hasGaps):
|
def historicalData(self, reqId, date, open_, high, low, close, volume, barCount, WAP, hasGaps):
|
||||||
""" generated source for method historicalData """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def scannerParameters(self, xml):
|
def scannerParameters(self, xml):
|
||||||
""" generated source for method scannerParameters """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def scannerData(self, reqId, rank, contractDetails, distance, benchmark, projection, legsStr):
|
def scannerData(self, reqId, rank, contractDetails, distance, benchmark, projection, legsStr):
|
||||||
''' generated source for method scannerData '''
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def scannerDataEnd(self, reqId):
|
def scannerDataEnd(self, reqId):
|
||||||
""" generated source for method scannerDataEnd """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def realtimeBar(self, reqId, time, open, high, low, close, volume, wap, count):
|
def realtimeBar(self, reqId, time, open_, high, low, close, volume, wap, count):
|
||||||
""" generated source for method realtimeBar """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
def currentTime(self, time):
|
|
||||||
""" generated source for method currentTime """
|
|
||||||
dt = datetime.fromtimestamp(time)
|
|
||||||
t = dt.strftime("%Y-%m-%d %H:%M:%S.%f")
|
|
||||||
|
|
||||||
self.connectionStatus = True
|
|
||||||
self.gateway.connected = True
|
|
||||||
|
|
||||||
log = VtLogData()
|
|
||||||
log.gatewayName = self.gatewayName
|
|
||||||
log.logContent = (u'IB接口连接成功,当前服务器时间 %s' %t)
|
|
||||||
self.gateway.onLog(log)
|
|
||||||
|
|
||||||
for symbol, req in self.subscribeReqDict.items():
|
|
||||||
del self.subscribeReqDict[symbol]
|
|
||||||
self.gateway.subscribe(req)
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def fundamentalData(self, reqId, data):
|
def fundamentalData(self, reqId, data):
|
||||||
""" generated source for method fundamentalData """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def deltaNeutralValidation(self, reqId, underComp):
|
def deltaNeutralValidation(self, reqId, underComp):
|
||||||
""" generated source for method deltaNeutralValidation """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def tickSnapshotEnd(self, reqId):
|
def tickSnapshotEnd(self, reqId):
|
||||||
""" generated source for method tickSnapshotEnd """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def marketDataType(self, reqId, marketDataType):
|
def marketDataType(self, reqId, marketDataType):
|
||||||
""" generated source for method marketDataType """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def commissionReport(self, commissionReport):
|
def commissionReport(self, commissionReport):
|
||||||
""" generated source for method commissionReport """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def position(self, account, contract, pos, avgCost):
|
def position(self, account, contract, position, avgCost):
|
||||||
""" generated source for method position """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def positionEnd(self):
|
def positionEnd(self):
|
||||||
""" generated source for method positionEnd """
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def accountSummary(self, reqId, account, tag, value, currency):
|
def verifyMessageAPI(self, apiData):
|
||||||
""" generated source for method accountSummary """
|
""""""
|
||||||
pass
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
def accountSummaryEnd(self, reqId):
|
|
||||||
""" generated source for method accountSummaryEnd """
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def error(self, id=None, errorCode=None, errorMsg=None):
|
def verifyCompleted(self, isSuccessful, errorText):
|
||||||
"""错误回报"""
|
""""""
|
||||||
err = VtErrorData()
|
pass
|
||||||
err.gatewayName = self.gatewayName
|
|
||||||
err.errorID = errorCode
|
|
||||||
err.errorMsg = errorMsg
|
|
||||||
self.gateway.onError(err)
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def error_0(self, strval=None):
|
def displayGroupList(self, reqId, groups):
|
||||||
"""错误回报(单一字符串)"""
|
""""""
|
||||||
err = VtErrorData()
|
pass
|
||||||
err.gatewayName = self.gatewayName
|
|
||||||
err.errorMsg = strval
|
#----------------------------------------------------------------------
|
||||||
self.gateway.onError(err)
|
def displayGroupUpdated(self, reqId, contractInfo):
|
||||||
|
""""""
|
||||||
|
pass
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def verifyAndAuthMessageAPI(self, apiData, xyzChallange):
|
||||||
|
""""""
|
||||||
|
pass
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def error_1(self, id=None, errorCode=None, errorMsg=None):
|
def verifyAndAuthCompleted(self, isSuccessful, errorText):
|
||||||
"""错误回报(字符串和代码)"""
|
""""""
|
||||||
err = VtErrorData()
|
pass
|
||||||
err.gatewayName = self.gatewayName
|
|
||||||
err.errorID = errorCode
|
|
||||||
err.errorMsg = errorMsg
|
|
||||||
self.gateway.onError(err)
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def connectionClosed(self):
|
def positionMulti(self, reqId, account, modelCode, contract, pos, avgCost):
|
||||||
"""连接断开"""
|
""""""
|
||||||
self.connectionStatus = False
|
pass
|
||||||
self.gateway.connected = False
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
log = VtLogData()
|
def positionMultiEnd(self, reqId):
|
||||||
log.gatewayName = self.gatewayName
|
""""""
|
||||||
log.logContent = (u'IB接口连接断开')
|
pass
|
||||||
self.gateway.onLog(log)
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def accountUpdateMulti(self, reqId, account, modelCode, key, value, currency):
|
||||||
|
""""""
|
||||||
|
pass
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def accountUpdateMultiEnd(self, reqId):
|
||||||
|
""""""
|
||||||
|
pass
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def securityDefinitionOptionalParameter(self, reqId, exchange, underlyingConId, tradingClass, multiplier, expirations, strikes):
|
||||||
|
""""""
|
||||||
|
pass
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def securityDefinitionOptionalParameterEnd(self, reqId):
|
||||||
|
""""""
|
||||||
|
pass
|
||||||
|
|
BIN
vn.trader/ibGateway/vnib.pyd
Normal file
BIN
vn.trader/ibGateway/vnib.pyd
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user