From e204af935d51de232d0d560aaa1ad4dd5cf07b29 Mon Sep 17 00:00:00 2001 From: Bian Jiang Date: Wed, 4 May 2016 22:00:57 +0800 Subject: [PATCH 1/6] =?UTF-8?q?IB=E5=A2=9E=E5=8A=A0=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=90=88=E7=BA=A6=E8=AF=A6=E6=83=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vn.trader/ibGateway/ibGateway.py | 34 ++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/vn.trader/ibGateway/ibGateway.py b/vn.trader/ibGateway/ibGateway.py index 6e243b74..f0711c78 100644 --- a/vn.trader/ibGateway/ibGateway.py +++ b/vn.trader/ibGateway/ibGateway.py @@ -184,6 +184,9 @@ class IbGateway(VtGateway): self.connection.reqMktData(self.tickerId, contract, '', False) + # 获取合约详细信息 + self.connection.reqContractDetails(self.tickerId, contract) + # 创建Tick对象并保存到字典中 tick = VtTickData() tick.symbol = subscribeReq.symbol @@ -429,17 +432,40 @@ class IbWrapper(EWrapper): #---------------------------------------------------------------------- def contractDetails(self, reqId, contractDetails): - """ generated source for method contractDetails """ - pass + """合约查询回报""" + contract = VtContractData() + contract.gatewayName = self.gatewayName + contract.symbol = contractDetails.m_summary.m_symbol + contract.exchange = contractDetails.m_summary.m_exchange + contract.vtSymbol = '.'.join([contract.symbol, contract.exchange]) + contract.name = contractDetails.m_marketName.decode('UTF-8') + + # 合约类型 + if contractDetails.m_summary.m_secType == 'STK': + contract.productClass = PRODUCT_EQUITY + elif contractDetails.m_summary.m_secType == 'CASH': + contract.productClass = PRODUCT_FOREX + elif contractDetails.m_summary.m_secType == 'FUT': + contract.productClass = PRODUCT_FUTURES + elif contractDetails.m_summary.m_secType == 'OPT': + contract.productClass = PRODUCT_OPTION + else: + contract.productClass = PRODUCT_UNKNOWN + # 推送 + self.gateway.onContract(contract) + #---------------------------------------------------------------------- def bondContractDetails(self, reqId, contractDetails): """ generated source for method bondContractDetails """ #---------------------------------------------------------------------- def contractDetailsEnd(self, reqId): - """ generated source for method contractDetailsEnd """ - pass + """ 获取合约结束 """ + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'交易合约信息获取完成' + self.gateway.onLog(log) #---------------------------------------------------------------------- def execDetails(self, reqId, contract, execution): From 163fc39f157868700d3ba3b2a67899908775d9ef Mon Sep 17 00:00:00 2001 From: Bian Jiang Date: Wed, 4 May 2016 22:06:20 +0800 Subject: [PATCH 2/6] .gitignore add .pyd --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c0b231cf..045a4b99 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ Release/ # Python编译文件 *.pyc +*.pyd # WingIDE文件 *.wpr From 8d73c809196041c2fe78178d6197dee50e1ca1ba Mon Sep 17 00:00:00 2001 From: Bian Jiang Date: Thu, 5 May 2016 10:13:59 +0800 Subject: [PATCH 3/6] =?UTF-8?q?IB=201.=20=E4=BF=AE=E5=A4=8D=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E6=A0=BC=E5=BC=8F,=20=E5=A2=9E=E5=8A=A0=E6=AF=AB?= =?UTF-8?q?=E7=A7=92=202.=20IB=E5=A4=96=E6=B1=87=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vn.trader/ibGateway/ibGateway.py | 41 +++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/vn.trader/ibGateway/ibGateway.py b/vn.trader/ibGateway/ibGateway.py index f0711c78..c7cba073 100644 --- a/vn.trader/ibGateway/ibGateway.py +++ b/vn.trader/ibGateway/ibGateway.py @@ -13,7 +13,7 @@ ibpy的gateway接入 import os import json -from time import sleep, strftime, localtime +from datetime import datetime from copy import copy from PyQt4 import QtGui, QtCore @@ -193,6 +193,7 @@ class IbGateway(VtGateway): tick.exchange = subscribeReq.exchange tick.vtSymbol = '.'.join([tick.symbol, tick.exchange]) tick.gatewayName = self.gatewayName + tick.__setattr__('m_secType', productClassMap.get(subscribeReq.productClass, '')) self.tickDict[self.tickerId] = tick #---------------------------------------------------------------------- @@ -281,6 +282,13 @@ class IbWrapper(EWrapper): tick = self.tickDict[tickerId] key = tickFieldMap[field] tick.__setattr__(key, price) + + # 外汇单独设置时间, tickString 没有返回外汇时间 + if tick.m_secType == 'CASH': + dt_obj = datetime.now() + tick.time = dt_obj.strftime('%H:%M:%S.%f') + tick.date = dt_obj.strftime('%Y%m%d') + # 行情数据更新 newtick = copy(tick) self.gateway.onTick(newtick) @@ -293,7 +301,17 @@ class IbWrapper(EWrapper): if field in tickFieldMap: tick = self.tickDict[tickerId] key = tickFieldMap[field] - tick.__setattr__(key, size) + tick.__setattr__(key, size) + + # 外汇单独设置时间, tickString 没有返回外汇时间 + if tick.m_secType == 'CASH': + dt_obj = datetime.now() + tick.time = dt_obj.strftime('%H:%M:%S.%f') + tick.date = dt_obj.strftime('%Y%m%d') + + # 行情数据更新 + newtick = copy(tick) + self.gateway.onTick(newtick) else: print field @@ -310,12 +328,12 @@ class IbWrapper(EWrapper): #---------------------------------------------------------------------- def tickString(self, tickerId, tickType, value): """行情推送,特殊字段相关""" - if tickType == 45: - lt = localtime(int(value)) + if tickType == 45: + dt_obj = datetime.utcfromtimestamp(int(value)) tick = self.tickDict[tickerId] - tick.time = strftime('%H:%M:%S', lt) - tick.date = strftime('%Y%m%d') + tick.time = dt_obj.strftime('%H:%M:%S.%f') + tick.date = dt_obj.strftime('%Y%m%d') # 这里使用copy的目的是为了保证推送到事件系统中的对象 # 不会被当前的API线程修改,否则可能出现多线程数据同步错误 @@ -439,8 +457,8 @@ class IbWrapper(EWrapper): contract.exchange = contractDetails.m_summary.m_exchange contract.vtSymbol = '.'.join([contract.symbol, contract.exchange]) - contract.name = contractDetails.m_marketName.decode('UTF-8') - + contract.name = contractDetails.m_summary.m_localSymbol.decode('UTF-8') + # 合约类型 if contractDetails.m_summary.m_secType == 'STK': contract.productClass = PRODUCT_EQUITY @@ -545,14 +563,15 @@ class IbWrapper(EWrapper): #---------------------------------------------------------------------- def currentTime(self, time): """ generated source for method currentTime """ - t = strftime('%H:%M:%S', localtime(time)) - + dt_obj = datetime.utcfromtimestamp(time) + t = dt_obj.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) + log.logContent = (u'IB接口连接成功,当前服务器时间 %s' %t) self.gateway.onLog(log) #---------------------------------------------------------------------- From adaf10c96eae7279db75eab5857f6d7809a0fea4 Mon Sep 17 00:00:00 2001 From: Bian Jiang Date: Thu, 5 May 2016 13:47:49 +0800 Subject: [PATCH 4/6] =?UTF-8?q?IB=20=E5=A2=9E=E5=8A=A0=E6=9C=9F=E8=B4=A7?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vn.trader/ibGateway/ibGateway.py | 13 +++++++++++-- vn.trader/uiBasicWidget.py | 1 + vn.trader/vtConstant.py | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/vn.trader/ibGateway/ibGateway.py b/vn.trader/ibGateway/ibGateway.py index c7cba073..e9a17ec2 100644 --- a/vn.trader/ibGateway/ibGateway.py +++ b/vn.trader/ibGateway/ibGateway.py @@ -13,7 +13,8 @@ ibpy的gateway接入 import os import json -from datetime import datetime +import calendar +from datetime import datetime, timedelta from copy import copy from PyQt4 import QtGui, QtCore @@ -45,6 +46,7 @@ directionMapReverse['SLD'] = DIRECTION_SHORT # 交易所类型映射 exchangeMap = {} exchangeMap[EXCHANGE_SMART] = 'SMART' +exchangeMap[EXCHANGE_NYMEX] = 'NYMEX' exchangeMap[EXCHANGE_GLOBEX] = 'GLOBEX' exchangeMap[EXCHANGE_IDEALPRO] = 'IDEALPRO' exchangeMapReverse = {v:k for k,v in exchangeMap.items()} @@ -181,7 +183,14 @@ class IbGateway(VtGateway): contract.m_expiry = subscribeReq.expiry contract.m_strike = subscribeReq.strikePrice contract.m_right = optionTypeMap.get(subscribeReq.optionType, '') - + + if contract.m_secType == 'FUT' and not subscribeReq.expiry: + # 期货 如果没有设置过期时间, 默认设置为下个月 + dt_obj = datetime.now() + days = calendar.monthrange(dt_obj.year, dt_obj.month)[1] + nextMonth = dt_obj + timedelta(days=days) + contract.m_expiry = nextMonth.strftime('%Y%m') + self.connection.reqMktData(self.tickerId, contract, '', False) # 获取合约详细信息 diff --git a/vn.trader/uiBasicWidget.py b/vn.trader/uiBasicWidget.py index d1fc75b6..7fe68f35 100644 --- a/vn.trader/uiBasicWidget.py +++ b/vn.trader/uiBasicWidget.py @@ -641,6 +641,7 @@ class TradingWidget(QtGui.QFrame): EXCHANGE_SGE, EXCHANGE_HKEX, EXCHANGE_SMART, + EXCHANGE_NYMEX, EXCHANGE_GLOBEX, EXCHANGE_IDEALPRO] diff --git a/vn.trader/vtConstant.py b/vn.trader/vtConstant.py index 0492cc4b..d8ed868a 100644 --- a/vn.trader/vtConstant.py +++ b/vn.trader/vtConstant.py @@ -64,6 +64,7 @@ EXCHANGE_NONE = '' # 空交易所 EXCHANGE_HKEX = 'HKEX' # 港交所 EXCHANGE_SMART = 'SMART' # IB智能路由(股票、期权) +EXCHANGE_NYMEX = 'NYMEX' # IB 期货 EXCHANGE_GLOBEX = 'GLOBEX' # CME电子交易平台 EXCHANGE_IDEALPRO = 'IDEALPRO' # IB外汇ECN From e42c8136d95056708cd8ec4dbb1aa517f4902cb3 Mon Sep 17 00:00:00 2001 From: Bian Jiang Date: Thu, 5 May 2016 14:23:55 +0800 Subject: [PATCH 5/6] FIX IB Next Month Bug --- vn.trader/ibGateway/ibGateway.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vn.trader/ibGateway/ibGateway.py b/vn.trader/ibGateway/ibGateway.py index e9a17ec2..12e9ae6a 100644 --- a/vn.trader/ibGateway/ibGateway.py +++ b/vn.trader/ibGateway/ibGateway.py @@ -188,7 +188,7 @@ class IbGateway(VtGateway): # 期货 如果没有设置过期时间, 默认设置为下个月 dt_obj = datetime.now() days = calendar.monthrange(dt_obj.year, dt_obj.month)[1] - nextMonth = dt_obj + timedelta(days=days) + nextMonth = dt_obj + timedelta(days=(days - dt_obj.day + 1)) contract.m_expiry = nextMonth.strftime('%Y%m') self.connection.reqMktData(self.tickerId, contract, '', False) From 2b686053206094bddca69368b4bf7581128ec18a Mon Sep 17 00:00:00 2001 From: Bian Jiang Date: Thu, 5 May 2016 21:11:08 +0800 Subject: [PATCH 6/6] FIX from UTC time to local time --- vn.trader/ibGateway/ibGateway.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vn.trader/ibGateway/ibGateway.py b/vn.trader/ibGateway/ibGateway.py index 12e9ae6a..5658ff88 100644 --- a/vn.trader/ibGateway/ibGateway.py +++ b/vn.trader/ibGateway/ibGateway.py @@ -338,7 +338,7 @@ class IbWrapper(EWrapper): def tickString(self, tickerId, tickType, value): """行情推送,特殊字段相关""" if tickType == 45: - dt_obj = datetime.utcfromtimestamp(int(value)) + dt_obj = datetime.fromtimestamp(int(value)) tick = self.tickDict[tickerId] tick.time = dt_obj.strftime('%H:%M:%S.%f') @@ -572,7 +572,7 @@ class IbWrapper(EWrapper): #---------------------------------------------------------------------- def currentTime(self, time): """ generated source for method currentTime """ - dt_obj = datetime.utcfromtimestamp(time) + dt_obj = datetime.fromtimestamp(time) t = dt_obj.strftime("%Y-%m-%d %H:%M:%S.%f") self.connectionStatus = True