This commit is contained in:
msincenselee 2017-10-17 19:56:32 +08:00
parent e992787d29
commit 027750362a
7 changed files with 340 additions and 159 deletions

View File

@ -3,22 +3,23 @@
import json
import csv
import os
import platform
from collections import OrderedDict
#from PyQt4 import QtGui, QtCore
from vnpy.trader.vtEvent import *
from vnpy.trader.vtFunction import *
from vnpy.trader.vtGateway import *
import vtText
from vnpy.trader.uiQt import QtGui, QtCore, BASIC_FONT
from vnpy.trader.uiQt import QtWidgets, QtGui, QtCore, BASIC_FONT
if str(platform.system()) == 'Windows':
import winsound
QCOLOR_RED = QtGui.QColor('red')
QCOLOR_GREEN = QtGui.QColor('green')
########################################################################
class BasicCell(QtGui.QTableWidgetItem):
class BasicCell(QtWidgets.QTableWidgetItem):
"""基础的单元格"""
#----------------------------------------------------------------------
@ -39,7 +40,7 @@ class BasicCell(QtGui.QTableWidgetItem):
########################################################################
class NumCell(QtGui.QTableWidgetItem):
class NumCell(QtWidgets.QTableWidgetItem):
"""用来显示数字的单元格"""
# ----------------------------------------------------------------------
@ -64,7 +65,7 @@ class NumCell(QtGui.QTableWidgetItem):
########################################################################
class DirectionCell(QtGui.QTableWidgetItem):
class DirectionCell(QtWidgets.QTableWidgetItem):
"""用来显示买卖方向的单元格"""
#----------------------------------------------------------------------
@ -84,10 +85,8 @@ class DirectionCell(QtGui.QTableWidgetItem):
self.setForeground(QtGui.QColor('green'))
self.setText(text)
########################################################################
class NameCell(QtGui.QTableWidgetItem):
class NameCell(QtWidgets.QTableWidgetItem):
"""用来显示合约中文的单元格"""
#----------------------------------------------------------------------
@ -114,7 +113,7 @@ class NameCell(QtGui.QTableWidgetItem):
########################################################################
class BidCell(QtGui.QTableWidgetItem):
class BidCell(QtWidgets.QTableWidgetItem):
"""买价单元格"""
#----------------------------------------------------------------------
@ -136,7 +135,7 @@ class BidCell(QtGui.QTableWidgetItem):
########################################################################
class AskCell(QtGui.QTableWidgetItem):
class AskCell(QtWidgets.QTableWidgetItem):
"""买价单元格"""
#----------------------------------------------------------------------
@ -157,7 +156,7 @@ class AskCell(QtGui.QTableWidgetItem):
self.setText(text)
########################################################################
class PnlCell(QtGui.QTableWidgetItem):
class PnlCell(QtWidgets.QTableWidgetItem):
"""显示盈亏的单元格"""
# ----------------------------------------------------------------------
@ -185,7 +184,7 @@ class PnlCell(QtGui.QTableWidgetItem):
except ValueError:
pass
########################################################################
class BasicMonitor(QtGui.QTableWidget):
class BasicMonitor(QtWidgets.QTableWidget):
"""
基础监控
@ -193,7 +192,7 @@ class BasicMonitor(QtGui.QTableWidget):
{'chinese': u'中文名', 'cellType': BasicCell}
"""
signal = QtCore.pyqtSignal(type(Event()))
signal = QtCore.Signal(type(Event()))
#----------------------------------------------------------------------
def __init__(self, mainEngine=None, eventEngine=None, parent=None):
@ -351,7 +350,7 @@ class BasicMonitor(QtGui.QTableWidget):
#----------------------------------------------------------------------
def resizeColumns(self):
"""调整各列的大小"""
self.horizontalHeader().resizeSections(QtGui.QHeaderView.ResizeToContents)
self.horizontalHeader().resizeSections(QtWidgets.QHeaderView.ResizeToContents)
#----------------------------------------------------------------------
def setSorting(self, sorting):
@ -368,7 +367,7 @@ class BasicMonitor(QtGui.QTableWidget):
self.menu.close()
# 获取想要保存的文件名
path = QtGui.QFileDialog.getSaveFileName(self, vtText.SAVE_DATA, '', 'CSV(*.csv)')
path = QtWidgets.QFileDialog.getSaveFileName(self, vtText.SAVE_DATA, '', 'CSV(*.csv)')
log = VtLogData()
log.gatewayName = u'-'
@ -406,9 +405,9 @@ class BasicMonitor(QtGui.QTableWidget):
#----------------------------------------------------------------------
def initMenu(self):
"""初始化右键菜单"""
self.menu = QtGui.QMenu(self)
self.menu = QtWidgets.QMenu(self)
saveAction = QtGui.QAction(vtText.SAVE_DATA, self)
saveAction = QtWidgets.QAction(vtText.SAVE_DATA, self)
saveAction.triggered.connect(self.saveToCsv)
self.menu.addAction(saveAction)
@ -514,6 +513,14 @@ class ErrorMonitor(BasicMonitor):
self.initTable()
self.registerEvent()
self.eventEngine.register(EVENT_TRADE, self.play_trade)
def play_trade(self, event):
"""播放交易声音"""
# 1.获取事件的Trade数据
trade = event.dict_['data']
winsound.PlaySound('warn.wav', winsound.SND_ASYNC)
########################################################################
class TradeMonitor(BasicMonitor):
@ -536,7 +543,8 @@ class TradeMonitor(BasicMonitor):
d['tradeTime'] = {'chinese':vtText.TRADE_TIME, 'cellType':BasicCell}
d['gatewayName'] = {'chinese':vtText.GATEWAY, 'cellType':BasicCell}
self.setHeaderDict(d)
self.setDataKey('vtTradeID')
self.setEventType(EVENT_TRADE)
self.setFont(BASIC_FONT)
self.setSorting(True)
@ -544,6 +552,16 @@ class TradeMonitor(BasicMonitor):
self.initTable()
self.registerEvent()
self.eventEngine.register( EVENT_TRADE, self.play_trade)
def play_trade(self, event):
"""播放交易声音"""
# 1.获取事件的Trade数据
trade = event.dict_['data']
winsound.PlaySound('match.wav', winsound.SND_ASYNC)
########################################################################
class OrderMonitor(BasicMonitor):
@ -666,9 +684,9 @@ class AccountMonitor(BasicMonitor):
self.registerEvent()
########################################################################
class TradingWidget(QtGui.QFrame):
class TradingWidget(QtWidgets.QFrame):
"""简单交易组件"""
signal = QtCore.pyqtSignal(type(Event()))
signal = QtCore.Signal(type(Event()))
directionList = [DIRECTION_LONG,
DIRECTION_SHORT]
@ -737,55 +755,53 @@ class TradingWidget(QtGui.QFrame):
self.setLineWidth(1)
# 左边部分
labelSymbol = QtGui.QLabel(vtText.CONTRACT_SYMBOL)
labelName = QtGui.QLabel(vtText.CONTRACT_NAME)
labelDirection = QtGui.QLabel(vtText.DIRECTION)
labelOffset = QtGui.QLabel(vtText.OFFSET)
labelPrice = QtGui.QLabel(vtText.PRICE)
self.checkFixed = QtGui.QCheckBox(u'') # 价格固定选择框
labelVolume = QtGui.QLabel(vtText.VOLUME)
labelPriceType = QtGui.QLabel(vtText.PRICE_TYPE)
labelExchange = QtGui.QLabel(vtText.EXCHANGE)
labelCurrency = QtGui.QLabel(vtText.CURRENCY)
labelProductClass = QtGui.QLabel(vtText.PRODUCT_CLASS)
labelGateway = QtGui.QLabel(vtText.GATEWAY)
labelSymbol = QtWidgets.QLabel(vtText.CONTRACT_SYMBOL)
labelName = QtWidgets.QLabel(vtText.CONTRACT_NAME)
labelDirection = QtWidgets.QLabel(vtText.DIRECTION)
labelOffset = QtWidgets.QLabel(vtText.OFFSET)
labelPrice = QtWidgets.QLabel(vtText.PRICE)
self.checkFixed = QtWidgets.QCheckBox(u'') # 价格固定选择框
labelVolume = QtWidgets.QLabel(vtText.VOLUME)
labelPriceType = QtWidgets.QLabel(vtText.PRICE_TYPE)
labelExchange = QtWidgets.QLabel(vtText.EXCHANGE)
labelCurrency = QtWidgets.QLabel(vtText.CURRENCY)
labelProductClass = QtWidgets.QLabel(vtText.PRODUCT_CLASS)
labelGateway = QtWidgets.QLabel(vtText.GATEWAY)
self.lineSymbol = QtGui.QLineEdit()
self.lineName = QtGui.QLineEdit()
self.lineSymbol = QtWidgets.QLineEdit()
self.lineName = QtWidgets.QLineEdit()
self.comboDirection = QtGui.QComboBox()
self.comboDirection = QtWidgets.QComboBox()
self.comboDirection.addItems(self.directionList)
self.comboOffset = QtGui.QComboBox()
self.comboOffset = QtWidgets.QComboBox()
self.comboOffset.addItems(self.offsetList)
self.spinPrice = QtGui.QDoubleSpinBox()
self.spinPrice = QtWidgets.QDoubleSpinBox()
self.spinPrice.setDecimals(4)
self.spinPrice.setMinimum(-10000) # 原来是0为支持套利改为-10000
self.spinPrice.setMaximum(100000)
self.spinVolume = QtGui.QSpinBox()
self.spinVolume = QtWidgets.QSpinBox()
self.spinVolume.setMinimum(0)
self.spinVolume.setMaximum(1000000)
self.comboPriceType = QtGui.QComboBox()
self.comboPriceType = QtWidgets.QComboBox()
self.comboPriceType.addItems(self.priceTypeList)
self.comboExchange = QtGui.QComboBox()
self.comboExchange = QtWidgets.QComboBox()
self.comboExchange.addItems(self.exchangeList)
self.comboCurrency = QtGui.QComboBox()
self.comboCurrency = QtWidgets.QComboBox()
self.comboCurrency.addItems(self.currencyList)
self.comboProductClass = QtGui.QComboBox()
self.comboProductClass = QtWidgets.QComboBox()
self.comboProductClass.addItems(self.productClassList)
self.comboGateway = QtGui.QComboBox()
self.comboGateway = QtWidgets.QComboBox()
self.comboGateway.addItems(self.gatewayList)
#self.lineOrder = QtGui.QLineEdit()
gridleft = QtGui.QGridLayout()
gridleft = QtWidgets.QGridLayout()
gridleft.addWidget(labelSymbol, 0, 0)
gridleft.addWidget(labelName, 1, 0)
gridleft.addWidget(labelDirection, 2, 0)
@ -813,48 +829,48 @@ class TradingWidget(QtGui.QFrame):
gridleft.addWidget(self.comboGateway, 10, 1, 1, -1)
# 右边部分
labelBid1 = QtGui.QLabel(vtText.BID_1)
labelBid2 = QtGui.QLabel(vtText.BID_2)
labelBid3 = QtGui.QLabel(vtText.BID_3)
labelBid4 = QtGui.QLabel(vtText.BID_4)
labelBid5 = QtGui.QLabel(vtText.BID_5)
labelBid1 = QtWidgets.QLabel(vtText.BID_1)
labelBid2 = QtWidgets.QLabel(vtText.BID_2)
labelBid3 = QtWidgets.QLabel(vtText.BID_3)
labelBid4 = QtWidgets.QLabel(vtText.BID_4)
labelBid5 = QtWidgets.QLabel(vtText.BID_5)
labelAsk1 = QtGui.QLabel(vtText.ASK_1)
labelAsk2 = QtGui.QLabel(vtText.ASK_2)
labelAsk3 = QtGui.QLabel(vtText.ASK_3)
labelAsk4 = QtGui.QLabel(vtText.ASK_4)
labelAsk5 = QtGui.QLabel(vtText.ASK_5)
labelAsk1 = QtWidgets.QLabel(vtText.ASK_1)
labelAsk2 = QtWidgets.QLabel(vtText.ASK_2)
labelAsk3 = QtWidgets.QLabel(vtText.ASK_3)
labelAsk4 = QtWidgets.QLabel(vtText.ASK_4)
labelAsk5 = QtWidgets.QLabel(vtText.ASK_5)
self.labelBidPrice1 = QtGui.QLabel()
self.labelBidPrice2 = QtGui.QLabel()
self.labelBidPrice3 = QtGui.QLabel()
self.labelBidPrice4 = QtGui.QLabel()
self.labelBidPrice5 = QtGui.QLabel()
self.labelBidVolume1 = QtGui.QLabel()
self.labelBidVolume2 = QtGui.QLabel()
self.labelBidVolume3 = QtGui.QLabel()
self.labelBidVolume4 = QtGui.QLabel()
self.labelBidVolume5 = QtGui.QLabel()
self.labelBidPrice1 = QtWidgets.QLabel()
self.labelBidPrice2 = QtWidgets.QLabel()
self.labelBidPrice3 = QtWidgets.QLabel()
self.labelBidPrice4 = QtWidgets.QLabel()
self.labelBidPrice5 = QtWidgets.QLabel()
self.labelBidVolume1 = QtWidgets.QLabel()
self.labelBidVolume2 = QtWidgets.QLabel()
self.labelBidVolume3 = QtWidgets.QLabel()
self.labelBidVolume4 = QtWidgets.QLabel()
self.labelBidVolume5 = QtWidgets.QLabel()
self.labelAskPrice1 = QtGui.QLabel()
self.labelAskPrice2 = QtGui.QLabel()
self.labelAskPrice3 = QtGui.QLabel()
self.labelAskPrice4 = QtGui.QLabel()
self.labelAskPrice5 = QtGui.QLabel()
self.labelAskVolume1 = QtGui.QLabel()
self.labelAskVolume2 = QtGui.QLabel()
self.labelAskVolume3 = QtGui.QLabel()
self.labelAskVolume4 = QtGui.QLabel()
self.labelAskVolume5 = QtGui.QLabel()
self.labelAskPrice1 = QtWidgets.QLabel()
self.labelAskPrice2 = QtWidgets.QLabel()
self.labelAskPrice3 = QtWidgets.QLabel()
self.labelAskPrice4 = QtWidgets.QLabel()
self.labelAskPrice5 = QtWidgets.QLabel()
self.labelAskVolume1 = QtWidgets.QLabel()
self.labelAskVolume2 = QtWidgets.QLabel()
self.labelAskVolume3 = QtWidgets.QLabel()
self.labelAskVolume4 = QtWidgets.QLabel()
self.labelAskVolume5 = QtWidgets.QLabel()
labelLast = QtGui.QLabel(vtText.LAST)
self.labelLastPrice = QtGui.QLabel()
self.labelReturn = QtGui.QLabel()
labelLast = QtWidgets.QLabel(vtText.LAST)
self.labelLastPrice = QtWidgets.QLabel()
self.labelReturn = QtWidgets.QLabel()
self.labelLastPrice.setMinimumWidth(60)
self.labelReturn.setMinimumWidth(60)
gridRight = QtGui.QGridLayout()
gridRight = QtWidgets.QGridLayout()
gridRight.addWidget(labelAsk5, 0, 0)
gridRight.addWidget(labelAsk4, 1, 0)
gridRight.addWidget(labelAsk3, 2, 0)
@ -892,19 +908,19 @@ class TradingWidget(QtGui.QFrame):
gridRight.addWidget(self.labelBidVolume5, 10, 2)
# 发单按钮
buttonSendOrder = QtGui.QPushButton(vtText.SEND_ORDER)
buttonCancelAll = QtGui.QPushButton(vtText.CANCEL_ALL)
buttonSendOrder = QtWidgets.QPushButton(vtText.SEND_ORDER)
buttonCancelAll = QtWidgets.QPushButton(vtText.CANCEL_ALL)
size = buttonSendOrder.sizeHint()
buttonSendOrder.setMinimumHeight(size.height()*2) # 把按钮高度设为默认两倍
buttonCancelAll.setMinimumHeight(size.height()*2)
# 整合布局
hbox = QtGui.QHBoxLayout()
hbox = QtWidgets.QHBoxLayout()
hbox.addLayout(gridleft)
hbox.addLayout(gridRight)
vbox = QtGui.QVBoxLayout()
vbox = QtWidgets.QVBoxLayout()
vbox.addLayout(hbox)
vbox.addWidget(buttonSendOrder)
vbox.addWidget(buttonCancelAll)
@ -1202,7 +1218,7 @@ class ContractMonitor(BasicMonitor):
#----------------------------------------------------------------------
def addMenuAction(self):
"""增加右键菜单内容"""
refreshAction = QtGui.QAction(vtText.REFRESH, self)
refreshAction = QtWidgets.QAction(vtText.REFRESH, self)
refreshAction.triggered.connect(self.refresh)
self.menu.addAction(refreshAction)
@ -1220,7 +1236,7 @@ class ContractMonitor(BasicMonitor):
########################################################################
class ContractManager(QtGui.QWidget):
class ContractManager(QtWidgets.QWidget):
"""合约管理组件"""
#----------------------------------------------------------------------
@ -1237,18 +1253,18 @@ class ContractManager(QtGui.QWidget):
"""初始化界面"""
self.setWindowTitle(vtText.CONTRACT_SEARCH)
self.lineFilter = QtGui.QLineEdit()
self.buttonFilter = QtGui.QPushButton(vtText.SEARCH)
self.lineFilter = QtWidgets.QLineEdit()
self.buttonFilter = QtWidgets.QPushButton(vtText.SEARCH)
self.buttonFilter.clicked.connect(self.filterContract)
self.monitor = ContractMonitor(self.mainEngine)
self.monitor.refresh()
hbox = QtGui.QHBoxLayout()
hbox = QtWidgets.QHBoxLayout()
hbox.addWidget(self.lineFilter)
hbox.addWidget(self.buttonFilter)
hbox.addStretch()
vbox = QtGui.QVBoxLayout()
vbox = QtWidgets.QVBoxLayout()
vbox.addLayout(hbox)
vbox.addWidget(self.monitor)
@ -1261,4 +1277,110 @@ class ContractManager(QtGui.QWidget):
self.monitor.setFilterContent(content)
self.monitor.refresh()
########################################################################
class WorkingOrderMonitor(OrderMonitor):
"""活动委托监控"""
STATUS_COMPLETED = [STATUS_ALLTRADED, STATUS_CANCELLED, STATUS_REJECTED]
# ----------------------------------------------------------------------
def __init__(self, mainEngine, eventEngine, parent=None):
"""Constructor"""
super(WorkingOrderMonitor, self).__init__(mainEngine, eventEngine, parent)
# ----------------------------------------------------------------------
def updateData(self, data):
"""更新数据"""
super(WorkingOrderMonitor, self).updateData(data)
# 如果该委托已完成,则隐藏该行
if data.status in self.STATUS_COMPLETED:
vtOrderID = data.vtOrderID
cellDict = self.dataDict[vtOrderID]
cell = cellDict['status']
row = self.row(cell)
self.hideRow(row)
########################################################################
class SettingEditor(QtWidgets.QWidget):
"""配置编辑器"""
# ----------------------------------------------------------------------
def __init__(self, mainEngine, parent=None):
"""Constructor"""
super(SettingEditor, self).__init__(parent)
self.mainEngine = mainEngine
self.currentFileName = ''
self.initUi()
# ----------------------------------------------------------------------
def initUi(self):
"""初始化界面"""
self.setWindowTitle(vtText.EDIT_SETTING)
self.comboFileName = QtWidgets.QComboBox()
self.comboFileName.addItems(jsonPathDict.keys())
buttonLoad = QtWidgets.QPushButton(vtText.LOAD)
buttonSave = QtWidgets.QPushButton(vtText.SAVE)
buttonLoad.clicked.connect(self.loadSetting)
buttonSave.clicked.connect(self.saveSetting)
self.editSetting = QtWidgets.QTextEdit()
self.labelPath = QtWidgets.QLabel()
hbox = QtWidgets.QHBoxLayout()
hbox.addWidget(self.comboFileName)
hbox.addWidget(buttonLoad)
hbox.addWidget(buttonSave)
hbox.addStretch()
vbox = QtWidgets.QVBoxLayout()
vbox.addLayout(hbox)
vbox.addWidget(self.editSetting)
vbox.addWidget(self.labelPath)
self.setLayout(vbox)
# ----------------------------------------------------------------------
def loadSetting(self):
"""加载配置"""
self.currentFileName = str(self.comboFileName.currentText())
filePath = jsonPathDict[self.currentFileName]
self.labelPath.setText(filePath)
with open(filePath) as f:
self.editSetting.clear()
for line in f:
line = line.replace('\n', '') # 移除换行符号
line = line.decode('UTF-8')
self.editSetting.append(line)
# ----------------------------------------------------------------------
def saveSetting(self):
"""保存配置"""
if not self.currentFileName:
return
filePath = jsonPathDict[self.currentFileName]
with open(filePath, 'w') as f:
content = self.editSetting.toPlainText()
content = content.encode('UTF-8')
f.write(content)
# ----------------------------------------------------------------------
def show(self):
"""显示"""
# 更新配置文件下拉框
self.comboFileName.clear()
self.comboFileName.addItems(jsonPathDict.keys())
# 显示界面
super(SettingEditor, self).show()

View File

@ -2,35 +2,43 @@
import platform
from PyQt4 import QtGui, QtCore
from qtpy import QtWidgets, QtGui, QtCore
from vnpy.trader.vtGlobal import globalSetting
from vnpy.trader.vtFunction import loadIconPath
# 创建Qt应用对象
qApp = QtGui.QApplication([])
# 设置Qt的皮肤
if globalSetting['darkStyle']:
try:
import qdarkstyle
qApp.setStyleSheet(qdarkstyle.load_stylesheet(pyside=False))
except ImportError:
pass
# 设置Windows底部任务栏图标
if 'Windows' in platform.uname():
import ctypes
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('vn.trader')
# 设置Qt字体
BASIC_FONT = None
try:
family = globalSetting['fontFamily']
size = globalSetting['fontSize']
BASIC_FONT = QtGui.QFont(family, size)
except:
BASIC_FONT = QtGui.QFont(u'微软雅黑', 12)
qApp.setFont(BASIC_FONT)
# 设置Qt图标
qApp.setWindowIcon(QtGui.QIcon(loadIconPath('vnpy.ico')))
#----------------------------------------------------------------------
def createQApp():
"""创建PyQt应用对象"""
# 创建Qt应用对象
qApp = QtWidgets.QApplication([])
# 设置Qt的皮肤
if globalSetting['darkStyle']:
try:
import qdarkstyle
qApp.setStyleSheet(qdarkstyle.load_stylesheet(pyside=False))
except ImportError:
pass
# 设置Windows底部任务栏图标
if 'Windows' in platform.uname():
import ctypes
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('vn.trader')
# 设置Qt字体
qApp.setFont(BASIC_FONT)
# 设置Qt图标
qApp.setWindowIcon(QtGui.QIcon(loadIconPath('vnpy.ico')))
# 返回创建好的QApp对象
return qApp

View File

@ -372,13 +372,13 @@ if __name__ == '__main__':
sina = UtilSinaClient(t)
#rt=sina.getDayBars(symbol='RB1705', callback=t.addBar)
rt=sina.getDayBars(symbol='RB1710', callback=t.addBar)
#rt = sina.getMinBars(symbol='RB1705',minute = 5, callback=t.addBar)
rt = sina.getMinBars(symbol='RB1710',minute = 60, callback=t.addBar)
#rt = sina.getTicks(symbol='RB1705', callback=t.addTick)
#rt = sina.getTicks2(symbol='TF1706', callback=t.addTick)
#rt = sina.getTicks3(symbol='TF1709', callback=t.addTick)
rt = sina.getMinBars2(symbol='TF1709',minute=60, callback=t.addBar)
#rt = sina.getMinBars2(symbol='TF1709',minute=60, callback=t.addBar)

View File

@ -11,9 +11,9 @@ from pymongo.errors import ConnectionFailure
from vnpy.trader.vtEvent import Event as vn_event
from vnpy.trader.language import text
from vnpy.trader.app.ctaStrategy.ctaEngine import CtaEngine
from vnpy.trader.app.dataRecorder.drEngine import DrEngine
from vnpy.trader.app.riskManager.rmEngine import RmEngine
#from vnpy.trader.app.ctaStrategy.ctaEngine import CtaEngine
#from vnpy.trader.app.dataRecorder.drEngine import DrEngine
#from vnpy.trader.app.riskManager.rmEngine import RmEngine
from vnpy.trader.vtFunction import loadMongoSetting
from vnpy.trader.vtGateway import *
@ -27,13 +27,13 @@ class MainEngine(object):
"""主引擎"""
#----------------------------------------------------------------------
def __init__(self):
def __init__(self, eventEngine):
"""Constructor"""
# 记录今日日期
self.todayDate = datetime.now().strftime('%Y%m%d')
# 创建事件引擎
self.eventEngine = EventEngine2()
self.eventEngine = eventEngine
self.eventEngine.start()
# 创建数据引擎
@ -51,9 +51,9 @@ class MainEngine(object):
self.appDetailList = []
# 扩展模块
self.ctaEngine = CtaEngine(self, self.eventEngine) # cta策略运行模块
self.drEngine = DrEngine(self, self.eventEngine) # 数据记录模块
self.rmEngine = RmEngine(self, self.eventEngine) # 风险管理模块
self.ctaEngine = None # CtaEngine(self, self.eventEngine) # cta策略运行模块
self.drEngine = None # DrEngine(self, self.eventEngine) # 数据记录模块
self.rmEngine = None # RmEngine(self, self.eventEngine) # 风险管理模块
self.connected_gw_name = u''
# ----------------------------------------------------------------------
@ -75,8 +75,8 @@ class MainEngine(object):
# 保存接口详细信息
d = {
'gatewayName': gatewayModule.gatewayName,
'gatewayDisplayName': gatewayModule.gatewayDisplayName,
'gatewayName': gatewayName, #gatewayModule.gatewayName,
'gatewayDisplayName': gatewayName, #gatewayModule.gatewayDisplayName,
'gatewayType': gatewayModule.gatewayType
}
self.gatewayDetailList.append(d)
@ -84,6 +84,26 @@ class MainEngine(object):
if gateway_name != self.connected_gw_name:
self.connected_gw_name = gateway_name
# ----------------------------------------------------------------------
def addApp(self, appModule):
"""添加上层应用"""
appName = appModule.appName
# 创建应用实例
self.appDict[appName] = appModule.appEngine(self, self.eventEngine)
# 将应用引擎实例添加到主引擎的属性中
self.__dict__[appName] = self.appDict[appName]
# 保存应用信息
d = {
'appName': appModule.appName,
'appDisplayName': appModule.appDisplayName,
'appWidget': appModule.appWidget,
'appIco': appModule.appIco
}
self.appDetailList.append(d)
# ----------------------------------------------------------------------
def connect(self, gatewayName):
"""连接特定名称的接口"""
@ -96,11 +116,9 @@ class MainEngine(object):
# 接口连接后自动执行数据库连接的任务
self.dbConnect()
return True
else:
self.writeLog(text.GATEWAY_NOT_EXIST.format(gateway=gatewayName))
return False
def checkGatewayStatus(self,gatewayName):
@ -150,7 +168,7 @@ class MainEngine(object):
def sendOrder(self, orderReq, gatewayName):
"""对特定接口发单"""
# 如果风控检查失败则不发单
if not self.rmEngine.checkRisk(orderReq):
if self.rmEngine and not self.rmEngine.checkRisk(orderReq):
self.writeCritical(u'风控检查不通过')
return ''
@ -183,8 +201,12 @@ class MainEngine(object):
# Added by IncenseLee
仅支持一个账号不支持多账号
以后支持跨市场套利才更新吧
return 当前账号的权益可用资金当前仓位比例, 投资仓位比例上限
"""
return self.rmEngine.getAccountInfo()
if self.rmEngine:
return self.rmEngine.getAccountInfo()
else:
return 0, 0, 0, 0
# ----------------------------------------------------------------------
def qryPosition(self, gatewayName):
@ -206,7 +228,8 @@ class MainEngine(object):
self.eventEngine.stop()
# 停止数据记录引擎
self.drEngine.stop()
if self.drEngine:
self.drEngine.stop()
# 保存数据引擎里的合约数据到硬盘
self.dataEngine.saveContracts()
@ -400,6 +423,22 @@ class MainEngine(object):
def getAllGatewayNames(self):
"""查询引擎中所有可用接口的名称"""
return self.gatewayDict.keys()
# ----------------------------------------------------------------------
def getAllGatewayDetails(self):
"""查询引擎中所有底层接口的信息"""
return self.gatewayDetailList
# ----------------------------------------------------------------------
def getAllAppDetails(self):
"""查询引擎中所有上层应用的信息"""
return self.appDetailList
# ----------------------------------------------------------------------
def getApp(self, appName):
"""获取APP引擎对象"""
return self.appDict[appName]
def clearData(self):
"""清空数据引擎的数据"""

View File

@ -35,6 +35,8 @@ EVENT_ON_BAR = 'eOnBar' # OnBar事件
EVENT_WARNING = 'eWarning' # 全局告警信息
EVENT_CRITICAL = 'eCritical' # 全局严重信息
EVENT_NOTIFICATION = 'eNotification' # 全局通知
EVENT_SIGNAL = 'eSignal' # 信号通知
EVENT_STATUS = 'eStatus' # 服务状态
# CTA模块相关
EVENT_CTA_LOG = 'eCtaLog' # CTA相关的日志事件

View File

@ -1,22 +1,31 @@
# encoding: UTF-8
# 重载sys模块设置默认字符串编码方式为utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import sys
import os
import ctypes
import platform
system = platform.system()
# 将repostory的目录作为根目录添加到系统环境中。
ROOT_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..' , '..'))
sys.path.append(ROOT_PATH)
from vnpy.trader.vtEngine import MainEngine
from vnpy.trader.uiQt import qApp
from vnpy.trader.uiQt import createQApp
from vnpy.trader.uiMainWindow import *
# 加载底层接口
from vnpy.trader.gateway import ctpGateway
# 初始化的接口模块,以及其指定的名称,CTP是模块value是该模块下的多个连接配置文件,如 CTP_JR_connect.json
init_gateway_names = {'CTP': ['CTP', 'CTP_Prod', 'CTP_Post', 'CTP_EBF', 'CTP_JR', 'CTP_JR2']}
# 初始化的接口模块,以及其指定的名称,CTP是模块value是该模块下的多个连接配置文件,如 CTP_JR_connect.json 'CTP_Prod', 'CTP_JR', , 'CTP_JK', 'CTP_02'
init_gateway_names = {'CTP': ['CTP','CTP_YH01', 'CTP_YH02', 'CTP_YHHZQQ','CTP_JR2']}
from vnpy.trader.app import (ctaStrategy, riskManager, spreadTrading)
# 文件路径名
path = os.path.abspath(os.path.dirname(__file__))
@ -24,43 +33,31 @@ ICON_FILENAME = 'vnpy.ico'
ICON_FILENAME = os.path.join(path, ICON_FILENAME)
from vnpy.trader.setup_logger import setup_logger
setup_logger(filename='logs/vnpy_{0}.log'.format(datetime.now().strftime('%m%d_%H%M')), debug=False)
setup_logger(filename='logs/vnpy.log', debug=False)
# ----------------------------------------------------------------------
def main():
"""主程序入口"""
# 重载sys模块设置默认字符串编码方式为utf8
reload(sys)
sys.setdefaultencoding('utf8')
# 创建Qt应用对象
qApp = createQApp()
"""
# 设置Windows底部任务栏图标
if 'Windows' in platform.uname():
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('vn.trader')
# 创建事件引擎
ee = EventEngine2()
# 初始化Qt应用对象
app = QtGui.QApplication(sys.argv)
app.setWindowIcon(QtGui.QIcon(ICON_FILENAME))
app.setFont(BASIC_FONT)
# 设置Qt的皮肤
try:
from vnpy.trader.vtGlobal import globalSetting
if globalSetting['darkStyle']:
import qdarkstyle
app.setStyleSheet(qdarkstyle.load_stylesheet(pyside=False))
except:
pass
"""
# 初始化主引擎和主窗口对象
mainEngine = MainEngine()
mainEngine = MainEngine(ee)
# 添加Gatway
for gw_name in init_gateway_names['CTP']:
print 'add {0}'.format(gw_name)
mainEngine.addGateway(ctpGateway, gw_name)
mainWindow = MainWindow(mainEngine, mainEngine.eventEngine)
# 添加应用
mainEngine.addApp(ctaStrategy)
mainEngine.addApp(riskManager)
mainEngine.addApp(spreadTrading)
mainWindow = MainWindow(mainEngine, ee)
mainWindow.showMaximized()
# 在主线程中启动Qt事件循环

View File

@ -241,6 +241,19 @@ class VtLogData(VtBaseData):
self.logTime = datetime.now().strftime('%X:%f')
self.logContent = EMPTY_UNICODE # 日志信息
class VtSignalData(VtBaseData):
"""信号数据类"""
# ----------------------------------------------------------------------
def __init__(self):
super(VtSignalData, self).__init__()
self.time = datetime.now().strftime('%X:%f')
self.source = EMPTY_STRING # 来源
self.symbol = EMPTY_STRING # 合约信息
self.direction = EMPTY_STRING #信号方向
self.price = EMPTY_FLOAT # 信号价格
self.level = EMPTY_INT # 0 普通信号1强信号
########################################################################
class VtContractData(VtBaseData):