vnpy/vn.trader/gateway/windGateway/windGateway.py

185 lines
6.5 KiB
Python
Raw Normal View History

# encoding: UTF-8
'''
Wind Python API的gateway接入
'''
from copy import copy
try:
from WindPy import w
except ImportError:
print u'请先安装WindPy接口'
from vtGateway import *
# 交易所类型映射
exchangeMap = {}
exchangeMap[EXCHANGE_SSE] = 'SH'
exchangeMap[EXCHANGE_SZSE] = 'SZ'
exchangeMap[EXCHANGE_CFFEX] = 'CFE'
exchangeMap[EXCHANGE_SHFE] = 'SHF'
exchangeMap[EXCHANGE_DCE] = 'DCE'
exchangeMap[EXCHANGE_CZCE] = 'CZC'
exchangeMap[EXCHANGE_UNKNOWN] = ''
exchangeMapReverse = {v:k for k,v in exchangeMap.items()}
########################################################################
class WindGateway(VtGateway):
"""Wind接口"""
# 订阅wsq时传入的字段列表
wsqParamMap = {}
wsqParamMap['rt_last'] = 'lastPrice'
wsqParamMap['rt_last_vol'] = 'volume'
wsqParamMap['rt_oi'] = 'openInterest'
wsqParamMap['rt_open'] = 'openPrice'
wsqParamMap['rt_high'] = 'highPrice'
wsqParamMap['rt_low'] = 'lowPrice'
wsqParamMap['rt_pre_close'] = 'preClosePrice'
wsqParamMap['rt_high_limit'] = 'upperLimit'
wsqParamMap['rt_low_limit'] = 'lowerLimit'
wsqParamMap['rt_bid1'] = 'bidPrice1'
wsqParamMap['rt_bid2'] = 'bidPrice2'
wsqParamMap['rt_bid3'] = 'bidPrice3'
wsqParamMap['rt_bid4'] = 'bidPrice4'
wsqParamMap['rt_bid5'] = 'bidPrice5'
wsqParamMap['rt_ask1'] = 'askPrice1'
wsqParamMap['rt_ask2'] = 'askPrice2'
wsqParamMap['rt_ask3'] = 'askPrice3'
wsqParamMap['rt_ask4'] = 'askPrice4'
wsqParamMap['rt_ask5'] = 'askPrice5'
wsqParamMap['rt_bsize1'] = 'bidVolume1'
wsqParamMap['rt_bsize2'] = 'bidVolume2'
wsqParamMap['rt_bsize3'] = 'bidVolume3'
wsqParamMap['rt_bsize4'] = 'bidVolume4'
wsqParamMap['rt_bsize5'] = 'bidVolume5'
wsqParamMap['rt_asize1'] = 'askVolume1'
wsqParamMap['rt_asize2'] = 'askVolume2'
wsqParamMap['rt_asize3'] = 'askVolume3'
wsqParamMap['rt_asize4'] = 'askVolume4'
wsqParamMap['rt_asize5'] = 'askVolume5'
wsqParam = ','.join(wsqParamMap.keys())
#----------------------------------------------------------------------
def __init__(self, eventEngine, gatewayName='Wind'):
"""Constructor"""
super(WindGateway, self).__init__(eventEngine, gatewayName)
self.w = w # Wind API对象
self.connected = False # 连接状态
# Wind的wsq更新采用的是增量更新模式每次推送只会更新发生变化的字段
# 而vt中的tick是完整更新因此需要本地维护一个所有字段的快照
self.tickDict = {}
self.registerEvent()
#----------------------------------------------------------------------
def connect(self):
"""连接"""
# 由于w.start方法会阻塞较长时间
# 因此设计为异步模式,交给事件处理线程去处理
# 另外w.start和WingIDE的debug模块有冲突会导致异常退出
event = Event(type_=EVENT_WIND_CONNECTREQ)
self.eventEngine.put(event)
#----------------------------------------------------------------------
def subscribe(self, subscribeReq):
"""订阅行情"""
windSymbol = '.'.join([subscribeReq.symbol, exchangeMap[subscribeReq.exchange]])
data = self.w.wsq(windSymbol, self.wsqParam, func=self.wsqCallBack)
#----------------------------------------------------------------------
def sendOrder(self, orderReq):
"""发单"""
log = VtLogData()
log.gatewayName = self.gatewayName
log.logContent = u'Wind接口未实现发单功能'
self.onLog(log)
#----------------------------------------------------------------------
def cancelOrder(self, cancelOrderReq):
"""撤单"""
log = VtLogData()
log.gatewayName = self.gatewayName
log.logContent = u'Wind接口未实现撤单功能'
self.onLog(log)
#----------------------------------------------------------------------
def getAccount(self):
"""查询账户资金"""
log = VtLogData()
log.gatewayName = self.gatewayName
log.logContent = u'Wind接口未实现查询账户功能'
self.onLog(log)
#----------------------------------------------------------------------
def getPosition(self):
"""查询持仓"""
log = VtLogData()
log.gatewayName = self.gatewayName
log.logContent = u'Wind接口未实现查询持仓功能'
self.onLog(log)
#----------------------------------------------------------------------
def close(self):
self.w.stop()
#----------------------------------------------------------------------
def registerEvent(self):
"""注册事件监听"""
self.eventEngine.register(EVENT_WIND_CONNECTREQ, self.wConnect)
#----------------------------------------------------------------------
def wsqCallBack(self, data):
"""收到wsq推送"""
windSymbol = data.Codes[0]
if windSymbol in self.tickDict:
tick = self.tickDict[windSymbol]
else:
tick = VtTickData()
tick.gatewayName = self.gatewayName
symbolSplit = windSymbol.split('.')
tick.symbol = symbolSplit[0]
tick.exchange = exchangeMapReverse[symbolSplit[1]]
tick.vtSymbol = '.'.join([tick.symbol, tick.exchange])
self.tickDict[windSymbol] = tick
dt = data.Times[0]
tick.time = dt.strftime('%H:%M:%S')
tick.date = dt.strftime('%Y%m%d')
# 采用遍历的形式读取数值
fields = data.Fields
values = data.Data
d = tick.__dict__
for n, field in enumerate(fields):
field = field.lower()
key = self.wsqParamMap[field]
value = values[n][0]
d[key] = value
newtick = copy(tick)
self.onTick(newtick)
#----------------------------------------------------------------------
def wConnect(self, event):
"""利用事件处理线程去异步连接Wind接口"""
result = self.w.start()
log = VtLogData()
log.gatewayName = self.gatewayName
if not result.ErrorCode:
log.logContent = u'Wind接口连接成功'
else:
log.logContent = u'Wind接口连接失败错误代码%d' %result.ErrorCode
self.onLog(log)