vnpy/vn.trader/gateway/windGateway/windGateway.py
2017-04-28 21:32:19 +08:00

185 lines
6.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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)