增加CTA模块和行情记录模块对IB接口的兼容,感谢border的贡献

This commit is contained in:
vnpy 2016-05-13 22:04:29 +08:00
parent c4b7f5b6f2
commit 4560507369
7 changed files with 61 additions and 17 deletions

View File

@ -68,6 +68,9 @@ class CtaEngine(object):
req.price = price
req.volume = volume
req.productClass = strategy.productClass
req.currency = strategy.currency
# 设计为CTA引擎发出的委托只允许使用限价单
req.priceType = PRICETYPE_LIMITPRICE
@ -87,8 +90,9 @@ class CtaEngine(object):
vtOrderID = self.mainEngine.sendOrder(req, contract.gatewayName) # 发单
self.orderStrategyDict[vtOrderID] = strategy # 保存vtOrderID和策略的映射关系
#self.writeCtaLog(u'发送委托:' + str(req.__dict__))
self.writeCtaLog(u'策略%s发送委托,%s%s%s@%s'
%(strategy.name, vtSymbol, req.direction, volume, price))
return vtOrderID
@ -319,6 +323,11 @@ class CtaEngine(object):
req = VtSubscribeReq()
req.symbol = contract.symbol
req.exchange = contract.exchange
# 对于IB接口订阅行情时所需的货币和产品类型从策略属性中获取
req.currency = strategy.currency
req.productClass = strategy.productClass
self.mainEngine.subscribe(req, contract.gatewayName)
else:
self.writeCtaLog(u'%s的交易合约%s无法找到' %(name, strategy.vtSymbol))

View File

@ -23,6 +23,8 @@ class CtaTemplate(object):
# 策略的基本参数
name = EMPTY_UNICODE # 策略实例名称
vtSymbol = EMPTY_STRING # 交易的合约vt系统代码
productClass = EMPTY_STRING # 产品类型只有IB接口需要
currency = EMPTY_STRING # 货币只有IB接口需要
# 策略的基本变量,由引擎管理
inited = False # 是否进行了初始化

View File

@ -8,7 +8,9 @@
["IH1606", "SGIT"],
["IH1606", "SGIT"],
["IC1606", "SGIT"],
["IC1606", "SGIT"]
["IC1606", "SGIT"],
["600036", "LTS", "SZSE"],
["EUR.USD", "IB", "IDEALPRO", "USD", "外汇"]
],
"bar":

View File

@ -60,20 +60,39 @@ class DrEngine(object):
if 'tick' in setting:
l = setting['tick']
for symbol, gatewayName in l:
for setting in l:
symbol = setting[0]
drTick = DrTickData() # 该tick实例可以用于缓存部分数据目前未使用
self.tickDict[symbol] = drTick
req = VtSubscribeReq()
req.symbol = symbol
self.mainEngine.subscribe(req, gatewayName)
req.symbol = setting[0]
# 针对LTS和IB接口订阅行情需要交易所代码
if len(setting)>=3:
req.exchange = setting[2]
# 针对IB接口订阅行情需要货币和产品类型
if len(setting)>=5:
req.currency = setting[3]
req.productClass = setting[4]
self.mainEngine.subscribe(req, setting[1])
if 'bar' in setting:
l = setting['bar']
for symbol, gatewayName in l:
for setting in l:
symbol = setting[0]
bar = DrBarData()
self.barDict[symbol] = bar
if len(setting)>=3:
req.exchange = setting[2]
if len(setting)>=5:
req.currency = setting[3]
req.productClass = setting[4]
req = VtSubscribeReq()
req.symbol = symbol

View File

@ -124,18 +124,18 @@ class DrEngineManager(QtGui.QWidget):
if 'tick' in setting:
l = setting['tick']
for symbol, gatewayName in l:
for setting in l:
self.tickTable.insertRow(0)
self.tickTable.setItem(0, 0, TableCell(symbol))
self.tickTable.setItem(0, 1, TableCell(gatewayName))
self.tickTable.setItem(0, 0, TableCell(setting[0]))
self.tickTable.setItem(0, 1, TableCell(setting[1]))
if 'bar' in setting:
l = setting['bar']
for symbol, gatewayName in l:
for setting in l:
self.barTable.insertRow(0)
self.barTable.setItem(0, 0, TableCell(symbol))
self.barTable.setItem(0, 1, TableCell(gatewayName))
self.barTable.setItem(0, 0, TableCell(setting[0]))
self.barTable.setItem(0, 1, TableCell(setting[1]))
if 'active' in setting:
d = setting['active']

View File

@ -37,8 +37,9 @@ priceTypeMapReverse = {v: k for k, v in priceTypeMap.items()}
# 方向类型映射
directionMap = {}
directionMap[DIRECTION_LONG] = 'BUY'
directionMap[DIRECTION_SHORT] = 'SSHORT'
directionMap[DIRECTION_SELL] = 'SELL'
#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
@ -130,6 +131,8 @@ class IbGateway(VtGateway):
self.contractDict = {} # 合约字典
self.subscribeReqDict = {} # 用来保存订阅请求的字典
self.connected = False # 连接状态
self.wrapper = IbWrapper(self) # 回调接口
@ -176,6 +179,11 @@ class IbGateway(VtGateway):
#----------------------------------------------------------------------
def subscribe(self, subscribeReq):
"""订阅行情"""
# 如果尚未连接行情,则将订阅请求缓存下来后直接返回
if not self.connected:
self.subscribeReqDict[subscribeReq.symbol] = subscribeReq
return
contract = Contract()
contract.m_localSymbol = str(subscribeReq.symbol)
contract.m_exchange = exchangeMap.get(subscribeReq.exchange, '')
@ -289,6 +297,7 @@ class IbWrapper(EWrapper):
self.accountDict = gateway.accountDict # account字典
self.contractDict = gateway.contractDict # contract字典
self.tickProductDict = gateway.tickProductDict
self.subscribeReqDict = gateway.subscribeReqDict
#----------------------------------------------------------------------
def tickPrice(self, tickerId, field, price, canAutoExecute):
@ -572,6 +581,10 @@ class IbWrapper(EWrapper):
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):

View File

@ -619,8 +619,7 @@ class TradingWidget(QtGui.QFrame):
signal = QtCore.pyqtSignal(type(Event()))
directionList = [DIRECTION_LONG,
DIRECTION_SHORT,
DIRECTION_SELL]
DIRECTION_SHORT]
offsetList = [OFFSET_OPEN,
OFFSET_CLOSE,