Merge remote-tracking branch 'refs/remotes/vnpy/master'

Conflicts:
	vn.trader/ContractData.vt
	vn.trader/ctaEngine.py
	vn.trader/ctaStrategies.py
	vn.trader/ltsGateway.py
	vn.trader/uiBasicWidget.py
	vn.trader/uiMainWindow.py
	vn.trader/vtConstant.py
	vn.trader/vtEngine.py
This commit is contained in:
msincenselee 2015-11-20 15:50:57 +08:00
commit 64f772e650
15 changed files with 379 additions and 188 deletions

View File

@ -1,14 +1,10 @@
{
"Test1": {
"strategyClassName": "TestStrategy",
"vtSymbol": "IF1511"
},
"Test3": {
"strategyClassName": "TestStrategy",
"DR_IF1512": {
"strategyClassName": "DataRecorder",
"vtSymbol": "IF1512"
},
"Test2": {
"strategyClassName": "TestStrategy",
"vtSymbol": "IH1511"
"DR_IH1512": {
"strategyClassName": "DataRecorder",
"vtSymbol": "IH1512"
}
}

View File

@ -0,0 +1,106 @@
# encoding: UTF-8
from ctaStrategyTemplate import *
from ctaObject import CtaBarData
########################################################################
class DataRecorder(CtaStrategyTemplate):
"""
纯粹用来记录历史数据的工具基于CTA策略
建议运行在实际交易程序外的一个vn.trader实例中
本工具会记录Tick和1分钟K线数据
"""
#----------------------------------------------------------------------
def __init__(self, ctaEngine, name, setting=None):
"""Constructor"""
super(DataRecorder, self).__init__(ctaEngine, name, setting)
self.strategyClassName = 'DataRecorder'
self.author = u'用Python的交易员'
self.tickDbName = 'VtTrader_Tick_Db'
self.barDbName = 'VtTrader_1Min_Db'
self.paramList.append('author')
# 数据记录相关
self.bar = None # K线数据对象
self.barMinute = -1 # 当前的分钟,初始化设为-1
#----------------------------------------------------------------------
def init(self):
"""初始化"""
self.writeCtaLog(u'数据记录工具%s初始化' %self.name)
#----------------------------------------------------------------------
def start(self):
"""启动策略(必须由用户继承实现)"""
self.writeCtaLog(u'数据记录工具%s启动' %self.name)
#----------------------------------------------------------------------
def stop(self):
"""停止策略(必须由用户继承实现)"""
self.writeCtaLog(u'数据记录工具%s停止' %self.name)
#----------------------------------------------------------------------
def onTick(self, tick):
"""收到行情TICK推送"""
# 收到Tick后首先插入到数据库里
self.insertTick(tick)
# 计算K线
tickMinute = tick.datetime.minute
if tickMinute != self.barMinute: # 如果分钟变了则把旧的K线插入数据库并生成新的K线
if self.bar:
self.onBar(self.bar)
bar = CtaBarData() # 创建新的K线目的在于防止之前K线对象在插入Mongo中被再次修改导致出错
bar.vtSymbol = tick.vtSymbol
bar.symbol = tick.symbol
bar.exchange = tick.exchange
bar.open = tick.lastPrice
bar.high = tick.lastPrice
bar.low = tick.lastPrice
bar.close = tick.lastPrice
bar.date = tick.date
bar.time = tick.time
bar.datetime = tick.datetime # K线的时间设为第一个Tick的时间
bar.volume = tick.volume
bar.openInterest = tick.openInterest
self.bar = bar # 这种写法为了减少一层访问,加快速度
self.barMinute = tickMinute # 更新当前的分钟
else: # 否则继续累加新的K线
bar = self.bar # 写法同样为了加快速度
bar.high = max(bar.high, tick.lastPrice)
bar.low = min(bar.low, tick.lastPrice)
bar.close = tick.lastPrice
bar.volume = bar.volume + tick.volume # 成交量是累加的
bar.openInterest = tick.openInterest # 持仓量直接更新
#----------------------------------------------------------------------
def onOrder(self, order):
"""收到委托变化推送"""
pass
#----------------------------------------------------------------------
def onTrade(self, trade):
"""收到成交推送"""
pass
#----------------------------------------------------------------------
def onBar(self, bar):
"""收到Bar推送"""
self.insertBar(bar)

View File

@ -10,100 +10,10 @@ from vtConstant import *
from vtGateway import VtSubscribeReq, VtOrderReq, VtCancelOrderReq, VtLogData
from ctaConstant import *
from ctaObject import *
from ctaStrategies import strategyClassDict
########################################################################
class StopOrder(object):
"""本地停止单"""
# ----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
self.vtSymbol = EMPTY_STRING
self.orderType = EMPTY_UNICODE
self.price = EMPTY_FLOAT
self.volume = EMPTY_INT
self.strategy = None # 下停止单的策略对象
self.stopOrderID = EMPTY_STRING # 停止单的本地编号
self.status = EMPTY_STRING # 停止单状态
########################################################################
class CtaBarData(object):
"""K线数据"""
# ----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
self.vtSymbol = EMPTY_STRING # vt系统代码
self.symbol = EMPTY_STRING # 代码
self.exchange = EMPTY_STRING # 交易所
self.open = EMPTY_FLOAT # OHLC
self.high = EMPTY_FLOAT
self.low = EMPTY_FLOAT
self.close = EMPTY_FLOAT
self.date = EMPTY_STRING # bar开始的时间日期
self.time = EMPTY_STRING # 时间
self.datetime = None # python的datetime时间对象
self.volume = EMPTY_INT # 成交量
self.openInterest = EMPTY_INT # 持仓量
########################################################################
class CtaTickData(object):
"""Tick数据"""
# ----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
self.vtSymbol = EMPTY_STRING # vt系统代码
self.symbol = EMPTY_STRING # 合约代码
self.exchange = EMPTY_STRING # 交易所代码
# 成交数据
self.lastPrice = EMPTY_FLOAT # 最新成交价
self.volume = EMPTY_INT # 最新成交量
self.openInterest = EMPTY_INT # 持仓量
self.upperLimit = EMPTY_FLOAT # 涨停价
self.lowerLimit = EMPTY_FLOAT # 跌停价
# tick的时间
self.date = EMPTY_STRING # 日期
self.time = EMPTY_STRING # 时间
self.datetime = None # python的datetime时间对象
# 五档行情
self.bidPrice1 = EMPTY_FLOAT
self.bidPrice2 = EMPTY_FLOAT
self.bidPrice3 = EMPTY_FLOAT
self.bidPrice4 = EMPTY_FLOAT
self.bidPrice5 = EMPTY_FLOAT
self.askPrice1 = EMPTY_FLOAT
self.askPrice2 = EMPTY_FLOAT
self.askPrice3 = EMPTY_FLOAT
self.askPrice4 = EMPTY_FLOAT
self.askPrice5 = EMPTY_FLOAT
self.bidVolume1 = EMPTY_INT
self.bidVolume2 = EMPTY_INT
self.bidVolume3 = EMPTY_INT
self.bidVolume4 = EMPTY_INT
self.bidVolume5 = EMPTY_INT
self.askVolume1 = EMPTY_INT
self.askVolume2 = EMPTY_INT
self.askVolume3 = EMPTY_INT
self.askVolume4 = EMPTY_INT
self.askVolume5 = EMPTY_INT
########################################################################
class CtaEngine(object):
"""CTA策略引擎"""
@ -174,8 +84,10 @@ class CtaEngine(object):
req.direction = DIRECTION_LONG
req.offset = OFFSET_CLOSE
# 3.调用主引擎的发单接口进行发单保存OrderID与策略映射关系
vtOrderID = self.mainEngine.sendOrder(req) # 发单
vtOrderID = self.mainEngine.sendOrder(req, contract.gatewayName) # 发单
self.orderDict[vtOrderID] = strategy # 保存vtOrderID和策略的映射关系
return vtOrderID
@ -308,7 +220,7 @@ class CtaEngine(object):
l = self.tickStrategyDict[tick.vtSymbol]
for strategy in l:
strategy.onTick(tick)
strategy.onTick(ctaTick)
# ----------------------------------------------------------------------
@ -434,7 +346,8 @@ class CtaEngine(object):
# 5.调用主引擎的订阅接口
self.mainEngine.subscribe(req, contract.gatewayName)
else:
self.writeCtaLog(u'%s的交易合约%s无法找到' %(name, strategy.vtSymbol))
else:
self.writeCtaLog(u'存在策略对象重名:' + name)

95
vn.trader/ctaObject.py Normal file
View File

@ -0,0 +1,95 @@
# encoding: UTF-8
from vtConstant import EMPTY_UNICODE, EMPTY_STRING, EMPTY_FLOAT, EMPTY_INT
########################################################################
class StopOrder(object):
"""本地停止单"""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
self.vtSymbol = EMPTY_STRING
self.orderType = EMPTY_UNICODE
self.price = EMPTY_FLOAT
self.volume = EMPTY_INT
self.strategy = None # 下停止单的策略对象
self.stopOrderID = EMPTY_STRING # 停止单的本地编号
self.status = EMPTY_STRING # 停止单状态
########################################################################
class CtaBarData(object):
"""K线数据"""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
self.vtSymbol = EMPTY_STRING # vt系统代码
self.symbol = EMPTY_STRING # 代码
self.exchange = EMPTY_STRING # 交易所
self.open = EMPTY_FLOAT # OHLC
self.high = EMPTY_FLOAT
self.low = EMPTY_FLOAT
self.close = EMPTY_FLOAT
self.date = EMPTY_STRING # bar开始的时间日期
self.time = EMPTY_STRING # 时间
self.datetime = None # python的datetime时间对象
self.volume = EMPTY_INT # 成交量
self.openInterest = EMPTY_INT # 持仓量
########################################################################
class CtaTickData(object):
"""Tick数据"""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
self.vtSymbol = EMPTY_STRING # vt系统代码
self.symbol = EMPTY_STRING # 合约代码
self.exchange = EMPTY_STRING # 交易所代码
# 成交数据
self.lastPrice = EMPTY_FLOAT # 最新成交价
self.volume = EMPTY_INT # 最新成交量
self.openInterest = EMPTY_INT # 持仓量
self.upperLimit = EMPTY_FLOAT # 涨停价
self.lowerLimit = EMPTY_FLOAT # 跌停价
# tick的时间
self.date = EMPTY_STRING # 日期
self.time = EMPTY_STRING # 时间
self.datetime = None # python的datetime时间对象
# 五档行情
self.bidPrice1 = EMPTY_FLOAT
self.bidPrice2 = EMPTY_FLOAT
self.bidPrice3 = EMPTY_FLOAT
self.bidPrice4 = EMPTY_FLOAT
self.bidPrice5 = EMPTY_FLOAT
self.askPrice1 = EMPTY_FLOAT
self.askPrice2 = EMPTY_FLOAT
self.askPrice3 = EMPTY_FLOAT
self.askPrice4 = EMPTY_FLOAT
self.askPrice5 = EMPTY_FLOAT
self.bidVolume1 = EMPTY_INT
self.bidVolume2 = EMPTY_INT
self.bidVolume3 = EMPTY_INT
self.bidVolume4 = EMPTY_INT
self.bidVolume5 = EMPTY_INT
self.askVolume1 = EMPTY_INT
self.askVolume2 = EMPTY_INT
self.askVolume3 = EMPTY_INT
self.askVolume4 = EMPTY_INT
self.askVolume5 = EMPTY_INT

View File

@ -2,10 +2,18 @@
'''
在本文件中引入所有希望在系统中使用的策略类
当作配置文件每次增加删除策略时需要维护此字典
这个字典中保存了需要运行的策略的名称和策略类的映射关系
用户的策略类写好后先在该文件中引入并设置好名称然后
在CTA_setting.json中写入具体每个策略对象的类和合约设置
'''
from ctaStrategyTemplate import TestStrategy
from ctaDataRecorder import DataRecorder
strategyClassDict = {}
strategyClassDict[u'TestStrategy'] = TestStrategy
strategyClassDict['TestStrategy'] = TestStrategy
strategyClassDict['DataRecorder'] = DataRecorder

View File

@ -190,7 +190,7 @@ class TestStrategy(CtaStrategyTemplate):
self.lastPrice = EMPTY_FLOAT # 最新价
# 参数和变量列表设置
self.paramList.append(u'author')
self.paramList.append('author')
self.varList.append('pos')
self.varList.append('lastPrice')

View File

@ -640,6 +640,7 @@ class CtpTdApi(TdApi):
# 持仓量
pos.position = data['Position']
pos.ydPosition = data['YdPosition']
# 持仓均价
if pos.position:

View File

@ -30,6 +30,13 @@ EVENT_CTA_LOG = 'eCtaLog' # CTA相关的日志事件
# Wind接口相关
EVENT_WIND_CONNECTREQ = 'eWindConnectReq' # Wind接口请求连接事件
# 20151020后更新
# LTS Gateway相关
EVENT_LTS_SF = 'eLtsSf.' # SF基金查询推送事件
# 分级A算法相关
EVENT_FUNDA_DATA = 'eFaData.' # 分级A基金更新事件
EVENT_FUNDA_LOG = 'eFaLog' # 分级A算法日志事件
# ----------------------------------------------------------------------
def test():

View File

@ -321,7 +321,7 @@ class LtsMdApi(MdApi):
tick.lastPrice = data['LastPrice']
tick.volume = data['Volume']
tick.openInterest = data['OpenInterest']
tick.tickTime = '.'.join([data['UpdateTime'], str(data['UpdateMillisec']/100)])
tick.time = '.'.join([data['UpdateTime'], str(data['UpdateMillisec']/100)])
tick.date = data['TradingDay']
tick.openPrice = data['OpenPrice']
@ -392,9 +392,9 @@ class LtsMdApi(MdApi):
"""订阅合约"""
req = {}
req['InstrumentID'] = str(subscribeReq.symbol)
req['ExchangeID'] = str(subscribeReq.exchange)
req['ExchangeID'] = exchangeMap.get(str(subscribeReq.exchange), '')
# 这里的设计是,如果尚未登录就调用了订阅方法
# 则先保存订阅请求,登录完成后会自动订阅
if self.loginStatus:
@ -582,7 +582,7 @@ class LtsTdApi(TdApi):
# 保存代码和报单号
order.symbol = data['InstrumentID']
order.exchange = exchangeMapReverse[data['ExchangeID']]
order.exchange = exchangeMapReverse.get(data['ExchangeID'], '')
order.vtSymbol = '.'.join([order.symbol, order.exchange])
order.orderID = data['OrderRef']
@ -616,7 +616,7 @@ class LtsTdApi(TdApi):
order.status = STATUS_UNKNOWN
# 价格、报单量等数值
order.price = data['LimitPrice']
order.price = float(data['LimitPrice'])
order.totalVolume = data['VolumeTotalOriginal']
order.tradedVolume = data['VolumeTraded']
order.orderTime = data['InsertTime']
@ -639,7 +639,7 @@ class LtsTdApi(TdApi):
# 保存代码和报单号
trade.symbol = data['InstrumentID']
trade.exchange = exchangeMapReverse[data['ExchangeID']]
trade.exchange = exchangeMapReverse.get(data['ExchangeID'], '')
trade.vtSymbol = '.'.join([trade.symbol, trade.exchange])
trade.tradeID = data['TradeID']
@ -655,7 +655,7 @@ class LtsTdApi(TdApi):
trade.offset = offsetMapReverse.get(data['OffsetFlag'], '')
# 价格、报单量等数值
trade.price = data['Price']
trade.price = float(data['Price'])
trade.volume = data['Volume']
trade.tradeTime = data['TradeTime']
@ -772,10 +772,10 @@ class LtsTdApi(TdApi):
req = {}
req['InstrumentID'] = orderReq.symbol
req['InstrumentID'] = str(orderReq.symbol)
req['LimitPrice'] = str(orderReq.price) # LTS里的价格是字符串
req['VolumeTotalOriginal'] = orderReq.volume
req['ExchangeID'] = orderReq.exchange
req['VolumeTotalOriginal'] = int(orderReq.volume)
req['ExchangeID'] = exchangeMap.get(orderReq.exchange, '')
# 下面如果由于传入的类型本接口不支持,则会返回空字符串
try:
@ -1067,11 +1067,21 @@ class LtsQryApi(QryApi):
def onRspQryOFInstrument(self, data, error, n, last):
"""OF合约查询回报"""
pass
# ----------------------------------------------------------------------
def onRspQrySFInstrument(self, data, error, n, last):
"""SF合约查询回报"""
pass
event1 = Event(type_=EVENT_LTS_SF)
event1.dict_['data'] = data
self.gateway.eventEngine.put(event1)
symbol = data['InstrumentID']
exchange = exchangeMapReverse[data['ExchangeID']]
vtSymbol = '.'.join([symbol, exchange])
event2 = Event(type_=EVENT_LTS_SF + vtSymbol)
event2.dict_['data'] = data
self.gateway.eventEngine.put(event2)
# ----------------------------------------------------------------------
def onRspQryInstrumentUnitMargin(self, data, error, n, last):
@ -1141,11 +1151,12 @@ class LtsQryApi(QryApi):
# 保存代码
pos.symbol = data['InstrumentID']
pos.exchange = data['ExchangeID']
pos.exchange = exchangeMapReverse.get(data['ExchangeID'], '')
pos.vtSymbol = '.'.join([pos.symbol, pos.exchange])
# 方向和持仓冻结数量
pos.direction = posiDirectionMapReverse.get(data['PosiDirection'], '')
if pos.direction == DIRECTION_NET or pos.direction == DIRECTION_LONG:
pos.frozen = data['LongFrozen']
elif pos.direction == DIRECTION_SHORT:
@ -1153,6 +1164,7 @@ class LtsQryApi(QryApi):
# 持仓量
pos.position = data['Position']
pos.ydPosition = data['YdPosition']
# 持仓均价
if pos.position:

View File

@ -473,6 +473,7 @@ class PositionMonitor(BasicMonitor):
d['vtSymbol'] = {'chinese':u'名称', 'cellType':NameCell}
d['direction'] = {'chinese':u'方向', 'cellType':DirectionCell}
d['position'] = {'chinese':u'持仓量', 'cellType':BasicCell}
d['ydPosition'] = {'chinese':u'昨持仓', 'cellType':BasicCell}
d['frozen'] = {'chinese':u'冻结量', 'cellType':BasicCell}
d['price'] = {'chinese':u'价格', 'cellType':BasicCell}
d['gatewayName'] = {'chinese':u'接口', 'cellType':BasicCell}
@ -761,7 +762,7 @@ class TradingWidget(QtGui.QFrame):
"""合约变化"""
# 读取组件数据
symbol = unicode(self.lineSymbol.text())
symbol = str(self.lineSymbol.text())
exchange = unicode(self.comboExchange.currentText())
currency = unicode(self.comboCurrency.currentText())
productClass = unicode(self.comboProductClass.currentText())
@ -923,7 +924,8 @@ class TradingWidget(QtGui.QFrame):
def sendOrder(self):
"""发单"""
symbol = unicode(self.lineSymbol.text())
symbol = str(self.lineSymbol.text())
exchange = unicode(self.comboExchange.currentText())
currency = unicode(self.comboCurrency.currentText())
productClass = unicode(self.comboProductClass.currentText())

View File

@ -6,6 +6,7 @@ from uiBasicWidget import *
from uiCtaWidget import CtaEngineManager
########################################################################
class MainWindow(QtGui.QMainWindow):
"""主窗口"""
@ -19,6 +20,8 @@ class MainWindow(QtGui.QMainWindow):
self.eventEngine = eventEngine
self.dataEngine = dataEngine
self.widgetDict = {} # 用来保存子窗口的字典
self.initUi()
# ----------------------------------------------------------------------
@ -90,7 +93,10 @@ class MainWindow(QtGui.QMainWindow):
connectIbAction = QtGui.QAction(u'连接IB', self)
connectIbAction.triggered.connect(self.connectIb)
connectIbAction.triggered.connect(self.connectIb)
connectDbAction = QtGui.QAction(u'连接数据库', self)
connectDbAction.triggered.connect(self.mainEngine.dbConnect)
testAction = QtGui.QAction(u'测试', self)
@ -124,16 +130,25 @@ class MainWindow(QtGui.QMainWindow):
sysMenu.addAction(connectIbAction)
sysMenu.addSeparator()
sysMenu.addAction(connectDbAction)
sysMenu.addSeparator()
sysMenu.addAction(testAction)
sysMenu.addAction(exitAction)
functionMenu = menubar.addMenu(u'功能')
functionMenu.addAction(contractAction)
functionMenu.addAction(ctaAction)
# 算法相关
algoMenu = menubar.addMenu(u'算法')
algoMenu.addAction(ctaAction)
# 帮助
helpMenu = menubar.addMenu(u'帮助')
helpMenu.addAction(aboutAction)
helpMenu.addAction(aboutAction)
# ----------------------------------------------------------------------
def initStatusBar(self):
@ -201,54 +216,58 @@ class MainWindow(QtGui.QMainWindow):
# ----------------------------------------------------------------------
def testSubscribe(self):
"""测试订阅"""
req = VtSubscribeReq()
req.symbol = 'GOOG'
req.productClass = PRODUCT_EQUITY
req.exchange = EXCHANGE_SMART
req.currency = CURRENCY_USD
self.mainEngine.subscribe(req, 'IB')
api = self.mainEngine.gatewayDict['LTS'].qryApi
api.reqID += 1
api.reqQryOFInstrument({}, api.reqID)
req.symbol = 'AAPL'
self.mainEngine.subscribe(req, 'IB')
#req = VtSubscribeReq()
#req.symbol = 'GOOG'
#req.productClass = PRODUCT_EQUITY
#req.exchange = EXCHANGE_SMART
#req.currency = CURRENCY_USD
#self.mainEngine.subscribe(req, 'IB')
req.symbol = 'YHOO'
self.mainEngine.subscribe(req, 'IB')
#req.symbol = 'AAPL'
#self.mainEngine.subscribe(req, 'IB')
req.symbol = 'MSFT'
self.mainEngine.subscribe(req, 'IB')
#req.symbol = 'YHOO'
#self.mainEngine.subscribe(req, 'IB')
#req.symbol = 'MSFT'
#self.mainEngine.subscribe(req, 'IB')
req.symbol = 'GE'
self.mainEngine.subscribe(req, 'IB')
#req.symbol = 'GE'
#self.mainEngine.subscribe(req, 'IB')
# ----------------------------------------------------------------------
def openAbout(self):
"""打开关于"""
try:
self.aboutW.show()
except AttributeError:
self.aboutW = AboutWidget(self)
self.aboutW.show()
self.widgetDict['aboutW'].show()
except KeyError:
self.widgetDict['aboutW'] = AboutWidget(self)
self.widgetDict['aboutW'].show()
# ----------------------------------------------------------------------
def openContract(self):
"""打开合约查询"""
try:
self.contractM.show()
except AttributeError:
self.contractM = ContractMonitor(self.mainEngine.dataEngine)
self.contractM.show()
self.widgetDict['contractM'].show()
except KeyError:
self.widgetDict['contractM'] = ContractMonitor(self.mainEngine.dataEngine)
self.widgetDict['contractM'].show()
# ----------------------------------------------------------------------
def openCta(self):
"""打开CTA组件"""
try:
self.ctaM.show()
except AttributeError:
self.ctaM = CtaEngineManager(self.mainEngine.ctaEngine, self.eventEngine)
self.ctaM.show()
self.widgetDict['ctaM'].show()
except KeyError:
self.widgetDict['ctaM'] = CtaEngineManager(self.mainEngine.ctaEngine, self.eventEngine)
self.widgetDict['ctaM'].show()
# ----------------------------------------------------------------------
def closeEvent(self, event):
"""关闭事件"""
@ -256,7 +275,9 @@ class MainWindow(QtGui.QMainWindow):
u'确认退出?', QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No, QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
if reply == QtGui.QMessageBox.Yes:
for widget in self.widgetDict.values():
widget.close()
self.mainEngine.exit()
event.accept()
else:

View File

@ -49,18 +49,20 @@ OPTION_CALL = u'看涨期权'
OPTION_PUT = u'看跌期权'
# 交易所类型
EXCHANGE_SSE = u'SSE' # 上交所
EXCHANGE_SZSE = u'SZSE' # 深交所
EXCHANGE_CFFEX = u'CFFEX' # 中金所
EXCHANGE_SHFE = u'SHFE' # 上期所
EXCHANGE_CZCE = u'CZCE' # 郑商所
EXCHANGE_DCE = u'DCE' # 大商所
EXCHANGE_SSE = 'SSE' # 上交所
EXCHANGE_SZSE = 'SZSE' # 深交所
EXCHANGE_CFFEX = 'CFFEX' # 中金所
EXCHANGE_SHFE = 'SHFE' # 上期所
EXCHANGE_CZCE = 'CZCE' # 郑商所
EXCHANGE_DCE = 'DCE' # 大商所
EXCHANGE_UNKNOWN = 'UNKNOWN'# 未知交易所
EXCHANGE_NONE = '' # 空交易所
EXCHANGE_SMART = u'SMART' # IB智能路由股票、期权
EXCHANGE_GLOBEX = u'GLOBEX' # CME电子交易平台
EXCHANGE_IDEALPRO = u'IDEALPRO' # IB外汇ECN
EXCHANGE_SMART = 'SMART' # IB智能路由股票、期权
EXCHANGE_GLOBEX = 'GLOBEX' # CME电子交易平台
EXCHANGE_IDEALPRO = 'IDEALPRO' # IB外汇ECN
# 货币类型
CURRENCY_USD = 'USD' # 美元

View File

@ -7,10 +7,6 @@ from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
from eventEngine import *
from ctpGateway import CtpGateway
from ltsGateway import LtsGateway
#from windGateway import WindGateway
from ibGateway import IbGateway
from vtGateway import *
import uiBasicWidget
from ctaEngine import CtaEngine
@ -35,22 +31,44 @@ class MainEngine(object):
self.gatewayDict = OrderedDict()
# 创建我们想要接入的接口对象
self.addGateway(CtpGateway, 'CTP')
self.gatewayDict['CTP'].setQryEnabled(True)
self.addGateway(CtpGateway, 'CTP_Prod')
self.gatewayDict['CTP_Prod'].setQryEnabled(True)
try:
from ctpGateway import CtpGateway
self.addGateway(CtpGateway, 'CTP_Post')
self.gatewayDict['CTP_Post'].setQryEnabled(True)
self.addGateway(CtpGateway, 'CTP')
self.gatewayDict['CTP'].setQryEnabled(True)
self.addGateway(CtpGateway, 'CTP_Test')
self.gatewayDict['CTP_Test'].setQryEnabled(True)
self.addGateway(CtpGateway, 'CTP_Prod')
self.gatewayDict['CTP_Prod'].setQryEnabled(True)
self.addGateway(CtpGateway, 'CTP_Post')
self.gatewayDict['CTP_Post'].setQryEnabled(True)
self.addGateway(CtpGateway, 'CTP_Test')
self.gatewayDict['CTP_Test'].setQryEnabled(True)
except Exception, e:
print e
try:
from ltsGateway import LtsGateway
self.addGateway(LtsGateway, 'LTS')
self.gatewayDict['LTS'].setQryEnabled(True)
except Exception, e:
print e
self.addGateway(LtsGateway, 'LTS')
self.gatewayDict['LTS'].setQryEnabled(True)
try:
from windGateway import WindGateway
self.addGateway(WindGateway, 'Wind')
except Exception, e:
print e
try:
from ibGateway import IbGateway
self.addGateway(IbGateway, 'IB')
except Exception, e:
print e
#self.addGateway(WindGateway, 'Wind') # 没有Wind的请注释掉这一行
# MongoDB数据库相关
self.dbClient = None # MongoDB客户端对象

View File

@ -33,10 +33,15 @@ class VtGateway(object):
# ----------------------------------------------------------------------
def onTrade(self, trade):
"""成交信息推送"""
# 因为成交通常都是事后才会知道成交编号,因此只需要推送通用事件
# 通用事件
event1 = Event(type_=EVENT_TRADE)
event1.dict_['data'] = trade
self.eventEngine.put(event1)
# 特定合约的成交事件
event2 = Event(type_=EVENT_TRADE+trade.vtSymbol)
event2.dict_['data'] = trade
self.eventEngine.put(event2)
# ----------------------------------------------------------------------
def onOrder(self, order):
@ -60,7 +65,7 @@ class VtGateway(object):
self.eventEngine.put(event1)
# 特定合约代码的事件
event2 = Event(type_=EVENT_POSITION+position.vtPositionName)
event2 = Event(type_=EVENT_POSITION+position.vtSymbol)
event2.dict_['data'] = position
self.eventEngine.put(event2)
@ -286,6 +291,9 @@ class VtPositionData(VtBaseData):
self.frozen = EMPTY_INT # 冻结数量
self.price = EMPTY_FLOAT # 持仓均价
self.vtPositionName = EMPTY_STRING # 持仓在vt系统中的唯一代码通常是vtSymbol.方向
# 20151020添加
self.ydPosition = EMPTY_INT # 昨持仓
########################################################################
@ -363,7 +371,7 @@ class VtContractData(VtBaseData):
########################################################################
class VtSubscribeReq:
class VtSubscribeReq(object):
"""订阅行情时传入的对象类"""
# ----------------------------------------------------------------------
@ -381,7 +389,7 @@ class VtSubscribeReq:
########################################################################
class VtOrderReq:
class VtOrderReq(object):
"""发单时传入的对象类"""
# ----------------------------------------------------------------------
@ -405,7 +413,7 @@ class VtOrderReq:
########################################################################
class VtCancelOrderReq:
class VtCancelOrderReq(object):
"""撤单时传入的对象类"""
# ----------------------------------------------------------------------
@ -418,9 +426,9 @@ class VtCancelOrderReq:
self.orderID = EMPTY_STRING # 报单号
self.frontID = EMPTY_STRING # 前置机号
self.sessionID = EMPTY_STRING # 会话号

View File

@ -3,7 +3,8 @@
'''
Wind Python API的gateway接入
'''
from threading import Thread
from copy import copy
try:
from WindPy import w
@ -166,7 +167,8 @@ class WindGateway(VtGateway):
value = values[n][0]
d[key] = value
self.onTick(tick)
newtick = copy(tick)
self.onTick(newtick)
# ----------------------------------------------------------------------
def wConnect(self, event):