增加CTA模块和行情记录模块对IB接口的兼容,感谢border的贡献
This commit is contained in:
parent
c4b7f5b6f2
commit
4560507369
@ -68,6 +68,9 @@ class CtaEngine(object):
|
|||||||
req.price = price
|
req.price = price
|
||||||
req.volume = volume
|
req.volume = volume
|
||||||
|
|
||||||
|
req.productClass = strategy.productClass
|
||||||
|
req.currency = strategy.currency
|
||||||
|
|
||||||
# 设计为CTA引擎发出的委托只允许使用限价单
|
# 设计为CTA引擎发出的委托只允许使用限价单
|
||||||
req.priceType = PRICETYPE_LIMITPRICE
|
req.priceType = PRICETYPE_LIMITPRICE
|
||||||
|
|
||||||
@ -88,7 +91,8 @@ class CtaEngine(object):
|
|||||||
vtOrderID = self.mainEngine.sendOrder(req, contract.gatewayName) # 发单
|
vtOrderID = self.mainEngine.sendOrder(req, contract.gatewayName) # 发单
|
||||||
self.orderStrategyDict[vtOrderID] = strategy # 保存vtOrderID和策略的映射关系
|
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
|
return vtOrderID
|
||||||
|
|
||||||
@ -319,6 +323,11 @@ class CtaEngine(object):
|
|||||||
req = VtSubscribeReq()
|
req = VtSubscribeReq()
|
||||||
req.symbol = contract.symbol
|
req.symbol = contract.symbol
|
||||||
req.exchange = contract.exchange
|
req.exchange = contract.exchange
|
||||||
|
|
||||||
|
# 对于IB接口订阅行情时所需的货币和产品类型,从策略属性中获取
|
||||||
|
req.currency = strategy.currency
|
||||||
|
req.productClass = strategy.productClass
|
||||||
|
|
||||||
self.mainEngine.subscribe(req, contract.gatewayName)
|
self.mainEngine.subscribe(req, contract.gatewayName)
|
||||||
else:
|
else:
|
||||||
self.writeCtaLog(u'%s的交易合约%s无法找到' %(name, strategy.vtSymbol))
|
self.writeCtaLog(u'%s的交易合约%s无法找到' %(name, strategy.vtSymbol))
|
||||||
|
@ -23,6 +23,8 @@ class CtaTemplate(object):
|
|||||||
# 策略的基本参数
|
# 策略的基本参数
|
||||||
name = EMPTY_UNICODE # 策略实例名称
|
name = EMPTY_UNICODE # 策略实例名称
|
||||||
vtSymbol = EMPTY_STRING # 交易的合约vt系统代码
|
vtSymbol = EMPTY_STRING # 交易的合约vt系统代码
|
||||||
|
productClass = EMPTY_STRING # 产品类型(只有IB接口需要)
|
||||||
|
currency = EMPTY_STRING # 货币(只有IB接口需要)
|
||||||
|
|
||||||
# 策略的基本变量,由引擎管理
|
# 策略的基本变量,由引擎管理
|
||||||
inited = False # 是否进行了初始化
|
inited = False # 是否进行了初始化
|
||||||
|
@ -8,7 +8,9 @@
|
|||||||
["IH1606", "SGIT"],
|
["IH1606", "SGIT"],
|
||||||
["IH1606", "SGIT"],
|
["IH1606", "SGIT"],
|
||||||
["IC1606", "SGIT"],
|
["IC1606", "SGIT"],
|
||||||
["IC1606", "SGIT"]
|
["IC1606", "SGIT"],
|
||||||
|
["600036", "LTS", "SZSE"],
|
||||||
|
["EUR.USD", "IB", "IDEALPRO", "USD", "外汇"]
|
||||||
],
|
],
|
||||||
|
|
||||||
"bar":
|
"bar":
|
||||||
|
@ -60,21 +60,40 @@ class DrEngine(object):
|
|||||||
if 'tick' in setting:
|
if 'tick' in setting:
|
||||||
l = setting['tick']
|
l = setting['tick']
|
||||||
|
|
||||||
for symbol, gatewayName in l:
|
for setting in l:
|
||||||
|
symbol = setting[0]
|
||||||
drTick = DrTickData() # 该tick实例可以用于缓存部分数据(目前未使用)
|
drTick = DrTickData() # 该tick实例可以用于缓存部分数据(目前未使用)
|
||||||
self.tickDict[symbol] = drTick
|
self.tickDict[symbol] = drTick
|
||||||
|
|
||||||
req = VtSubscribeReq()
|
req = VtSubscribeReq()
|
||||||
req.symbol = symbol
|
req.symbol = setting[0]
|
||||||
self.mainEngine.subscribe(req, gatewayName)
|
|
||||||
|
# 针对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:
|
if 'bar' in setting:
|
||||||
l = setting['bar']
|
l = setting['bar']
|
||||||
|
|
||||||
for symbol, gatewayName in l:
|
for setting in l:
|
||||||
|
symbol = setting[0]
|
||||||
bar = DrBarData()
|
bar = DrBarData()
|
||||||
self.barDict[symbol] = bar
|
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 = VtSubscribeReq()
|
||||||
req.symbol = symbol
|
req.symbol = symbol
|
||||||
self.mainEngine.subscribe(req, gatewayName)
|
self.mainEngine.subscribe(req, gatewayName)
|
||||||
|
@ -124,18 +124,18 @@ class DrEngineManager(QtGui.QWidget):
|
|||||||
if 'tick' in setting:
|
if 'tick' in setting:
|
||||||
l = setting['tick']
|
l = setting['tick']
|
||||||
|
|
||||||
for symbol, gatewayName in l:
|
for setting in l:
|
||||||
self.tickTable.insertRow(0)
|
self.tickTable.insertRow(0)
|
||||||
self.tickTable.setItem(0, 0, TableCell(symbol))
|
self.tickTable.setItem(0, 0, TableCell(setting[0]))
|
||||||
self.tickTable.setItem(0, 1, TableCell(gatewayName))
|
self.tickTable.setItem(0, 1, TableCell(setting[1]))
|
||||||
|
|
||||||
if 'bar' in setting:
|
if 'bar' in setting:
|
||||||
l = setting['bar']
|
l = setting['bar']
|
||||||
|
|
||||||
for symbol, gatewayName in l:
|
for setting in l:
|
||||||
self.barTable.insertRow(0)
|
self.barTable.insertRow(0)
|
||||||
self.barTable.setItem(0, 0, TableCell(symbol))
|
self.barTable.setItem(0, 0, TableCell(setting[0]))
|
||||||
self.barTable.setItem(0, 1, TableCell(gatewayName))
|
self.barTable.setItem(0, 1, TableCell(setting[1]))
|
||||||
|
|
||||||
if 'active' in setting:
|
if 'active' in setting:
|
||||||
d = setting['active']
|
d = setting['active']
|
||||||
|
@ -37,8 +37,9 @@ priceTypeMapReverse = {v: k for k, v in priceTypeMap.items()}
|
|||||||
# 方向类型映射
|
# 方向类型映射
|
||||||
directionMap = {}
|
directionMap = {}
|
||||||
directionMap[DIRECTION_LONG] = 'BUY'
|
directionMap[DIRECTION_LONG] = 'BUY'
|
||||||
directionMap[DIRECTION_SHORT] = 'SSHORT'
|
#directionMap[DIRECTION_SHORT] = 'SSHORT' # SSHORT在IB系统中代表对股票的融券做空(而不是国内常见的卖出)
|
||||||
directionMap[DIRECTION_SELL] = 'SELL'
|
directionMap[DIRECTION_SHORT] = 'SELL' # 出于和国内的统一性考虑,这里选择把IB里的SELL印射为vt的SHORT
|
||||||
|
|
||||||
directionMapReverse = {v: k for k, v in directionMap.items()}
|
directionMapReverse = {v: k for k, v in directionMap.items()}
|
||||||
directionMapReverse['BOT'] = DIRECTION_LONG
|
directionMapReverse['BOT'] = DIRECTION_LONG
|
||||||
directionMapReverse['SLD'] = DIRECTION_SHORT
|
directionMapReverse['SLD'] = DIRECTION_SHORT
|
||||||
@ -130,6 +131,8 @@ class IbGateway(VtGateway):
|
|||||||
|
|
||||||
self.contractDict = {} # 合约字典
|
self.contractDict = {} # 合约字典
|
||||||
|
|
||||||
|
self.subscribeReqDict = {} # 用来保存订阅请求的字典
|
||||||
|
|
||||||
self.connected = False # 连接状态
|
self.connected = False # 连接状态
|
||||||
|
|
||||||
self.wrapper = IbWrapper(self) # 回调接口
|
self.wrapper = IbWrapper(self) # 回调接口
|
||||||
@ -176,6 +179,11 @@ class IbGateway(VtGateway):
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def subscribe(self, subscribeReq):
|
def subscribe(self, subscribeReq):
|
||||||
"""订阅行情"""
|
"""订阅行情"""
|
||||||
|
# 如果尚未连接行情,则将订阅请求缓存下来后直接返回
|
||||||
|
if not self.connected:
|
||||||
|
self.subscribeReqDict[subscribeReq.symbol] = subscribeReq
|
||||||
|
return
|
||||||
|
|
||||||
contract = Contract()
|
contract = Contract()
|
||||||
contract.m_localSymbol = str(subscribeReq.symbol)
|
contract.m_localSymbol = str(subscribeReq.symbol)
|
||||||
contract.m_exchange = exchangeMap.get(subscribeReq.exchange, '')
|
contract.m_exchange = exchangeMap.get(subscribeReq.exchange, '')
|
||||||
@ -289,6 +297,7 @@ class IbWrapper(EWrapper):
|
|||||||
self.accountDict = gateway.accountDict # account字典
|
self.accountDict = gateway.accountDict # account字典
|
||||||
self.contractDict = gateway.contractDict # contract字典
|
self.contractDict = gateway.contractDict # contract字典
|
||||||
self.tickProductDict = gateway.tickProductDict
|
self.tickProductDict = gateway.tickProductDict
|
||||||
|
self.subscribeReqDict = gateway.subscribeReqDict
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def tickPrice(self, tickerId, field, price, canAutoExecute):
|
def tickPrice(self, tickerId, field, price, canAutoExecute):
|
||||||
@ -573,6 +582,10 @@ class IbWrapper(EWrapper):
|
|||||||
log.logContent = (u'IB接口连接成功,当前服务器时间 %s' %t)
|
log.logContent = (u'IB接口连接成功,当前服务器时间 %s' %t)
|
||||||
self.gateway.onLog(log)
|
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 """
|
""" generated source for method fundamentalData """
|
||||||
|
@ -619,8 +619,7 @@ class TradingWidget(QtGui.QFrame):
|
|||||||
signal = QtCore.pyqtSignal(type(Event()))
|
signal = QtCore.pyqtSignal(type(Event()))
|
||||||
|
|
||||||
directionList = [DIRECTION_LONG,
|
directionList = [DIRECTION_LONG,
|
||||||
DIRECTION_SHORT,
|
DIRECTION_SHORT]
|
||||||
DIRECTION_SELL]
|
|
||||||
|
|
||||||
offsetList = [OFFSET_OPEN,
|
offsetList = [OFFSET_OPEN,
|
||||||
OFFSET_CLOSE,
|
OFFSET_CLOSE,
|
||||||
|
Loading…
Reference in New Issue
Block a user