diff --git a/vn.trader/dataRecorder/DR_setting.json b/vn.trader/dataRecorder/DR_setting.json index cbc5d6b0..f7c297c5 100644 --- a/vn.trader/dataRecorder/DR_setting.json +++ b/vn.trader/dataRecorder/DR_setting.json @@ -1,91 +1,31 @@ { - "working": true, - "tick": [ - [ - "au1706", - "CTP" - ], - [ - "a1705", - "CTP" - ], - [ - "m1705", - "CTP" - ], - [ - "bu1706", - "CTP" - ], - [ - "SR705", - "CTP" - ], - [ - "TA705", - "CTP" - ], - [ - "MA705", - "CTP" - ], - [ - "RM705", - "CTP" - ], - [ - "FG705", - "CTP" - ], - [ - "OI705", - "CTP" - ] + "working": false, + + "tick": + [ + ["m1609", "XSPEED"], + ["IF1606", "SGIT"], + ["IH1606", "SGIT"], + ["IH1606", "SGIT"], + ["IC1606", "SGIT"], + ["IC1606", "SGIT"], + ["600036", "LTS", "SZSE"], + ["EUR.USD", "IB", "IDEALPRO", "USD", "外汇"] ], - "bar": [ - [ - "au1706", - "CTP" - ], - [ - "a1705", - "CTP" - ], - [ - "m1705", - "CTP" - ], - [ - "bu1706", - "CTP" - ], - [ - "SR705", - "CTP" - ], - [ - "TA705", - "CTP" - ], - [ - "MA705", - "CTP" - ], - [ - "RM705", - "CTP" - ], - [ - "FG705", - "CTP" - ], - [ - "OI705", - "CTP" - ] + + "bar": + [ + ["IF1605", "SGIT"], + ["IF1606", "SGIT"], + ["IH1606", "SGIT"], + ["IH1606", "SGIT"], + ["IC1606", "SGIT"], + ["IC1606", "SGIT"] ], - "active": { - "IF0000": "IF1605", + + "active": + { + "IF0000": "IF1605", "IH0000": "IH1605", "IC0000": "IC1605" } diff --git a/vn.trader/dataRecorder/drEngine.py b/vn.trader/dataRecorder/drEngine.py index 8d209504..c4565fc4 100644 --- a/vn.trader/dataRecorder/drEngine.py +++ b/vn.trader/dataRecorder/drEngine.py @@ -6,15 +6,18 @@ 使用DR_setting.json来配置需要收集的合约,以及主力合约代码。 ''' -import copy import json import os -from datetime import datetime +import copy +from collections import OrderedDict +from datetime import datetime, timedelta +from Queue import Queue +from threading import Thread -from drBase import * from eventEngine import * -from vtFunction import todayDate from vtGateway import VtSubscribeReq, VtLogData +from drBase import * +from vtFunction import todayDate ######################################################################## @@ -50,17 +53,6 @@ class DrEngine(object): # 载入设置,订阅行情 self.loadSetting() - - def saveSetting(self, setting): - """保存设置""" - setting['working'] = self.working - with open(self.settingFileName, 'w') as f: - try: - str = json.dumps(setting, indent=2) - f.write(str) - except: - pass - return True #---------------------------------------------------------------------- def loadSetting(self): @@ -69,8 +61,8 @@ class DrEngine(object): drSetting = json.load(f) # 如果working设为False则不启动行情记录功能 - self.working = drSetting['working'] - if not self.working: + working = drSetting['working'] + if not working: return if 'tick' in drSetting: diff --git a/vn.trader/dataRecorder/uiDrEdit.py b/vn.trader/dataRecorder/uiDrEdit.py deleted file mode 100644 index 1242a225..00000000 --- a/vn.trader/dataRecorder/uiDrEdit.py +++ /dev/null @@ -1,400 +0,0 @@ -# encoding: UTF-8 - -''' -行情记录模块相关的GUI控制组件 -''' -import json -import re -import sys - -from PyQt4.QtGui import QTreeView - -from dataRecorder.drEngine import DrEngine -from eventEngine import * -from uiBasicWidget import QtGui, QtCore -from util.UiUtil import CheckBoxDelegate, ComboDelegate - -reload(sys) -sys.setdefaultencoding("utf8") - - -class TreeItem(object): - def __init__(self, data, parent=None): - self.parentItem = parent - self.itemData = data - self.childItems = [] - - def appendChild(self, item): - self.childItems.append(item) - - def extendChild(self, item): - self.childItems.extend(item) - - def child(self, row): - return self.childItems[row] - - def childCount(self): - return len(self.childItems) - - def columnCount(self): - return len(self.itemData) - - def data(self, column): - try: - return self.itemData[column] - except IndexError: - return None - - def parent(self): - return self.parentItem - - def row(self): - if self.parentItem: - return self.parentItem.childItems.index(self) - - return 0 - - def setData(self, column, value): - if column < 0 or column >= len(self.itemData): - return False - - self.itemData[column] = value - - return True - - -class TreeModel(QtCore.QAbstractItemModel): - def __init__(self, parent=None): - super(TreeModel, self).__init__(parent) - self.rootItem = TreeItem([u"合约", u"Tick", u"Bar", u"主力", u"交易所", u"接口"]) - - def rootItem(self): - return self.rootItem - - def setDataSource(self, data): - self.rootItem.extendChild(data) - - def columnCount(self, parent): - if parent.isValid(): - return parent.internalPointer().columnCount() - else: - return self.rootItem.columnCount() - - def setData(self, index, value, role=None): - item = index.internalPointer() - if item is None: - return False - - if index.column() == 5: - result = item.setData(index.column(), value) - if result: - self.dataChanged.emit(index, index) - # 如果第一条 - if item.parentItem == self.rootItem: - for row in range(item.childCount()): - childIndex = self.index(row, index.column(), index) - self.setData(childIndex, value, QtCore.Qt.DisplayRole) - - if index.column() in [1, 2, 3] and role == QtCore.Qt.CheckStateRole: - result = item.setData(index.column(), True if value == QtCore.Qt.Checked else False) - if result: - self.dataChanged.emit(index, index) - - # 如果第一条 - if item.parentItem == self.rootItem and index.column() in [1, 2]: - for row in range(item.childCount()): - childIndex = self.index(row, index.column(), index) - self.setData(childIndex, value, QtCore.Qt.CheckStateRole) - - if value == QtCore.Qt.Checked and index.column() == 3: - for row in range(item.parentItem.childCount()): - if row != index.row(): - siblingIndex = self.index(row, index.column(), index.parent()) - self.setData(siblingIndex, QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) - - return True - - def data(self, index, role): - if not index.isValid(): - return None - - item = index.internalPointer() - - if role == QtCore.Qt.TextAlignmentRole: - return QtCore.Qt.AlignCenter - - if role == QtCore.Qt.CheckStateRole and ( - index.column() in [1, 2] or index.column() == 3 and item.parentItem != self.rootItem): - return QtCore.Qt.Checked if item.data(index.column()) == True else QtCore.Qt.Unchecked - - if role != QtCore.Qt.DisplayRole or index.column() in [3, 4] and item.parentItem == self.rootItem: - return None - - return item.data(index.column()) - - def flags(self, index): - if not index.isValid(): - return QtCore.Qt.NoItemFlags - - if index.column() in [0, 4]: - return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable - - if index.column() in [5]: - return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable - - item = index.internalPointer() - if index.column() == 3 and item.parentItem == self.rootItem: - return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable - - return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEditable - - def headerData(self, section, orientation, role): - if orientation == QtCore.Qt.Horizontal: - if role == QtCore.Qt.DisplayRole: - return self.rootItem.data(section) - elif role == QtCore.Qt.TextAlignmentRole: - return QtCore.Qt.AlignCenter - return None - - def index(self, row, column, parent): - if not self.hasIndex(row, column, parent): - return QtCore.QModelIndex() - - if parent is None or not parent.isValid(): - parentItem = self.rootItem - else: - parentItem = parent.internalPointer() - - childItem = parentItem.child(row) - if childItem: - return self.createIndex(row, column, childItem) - else: - return QtCore.QModelIndex() - - def parent(self, index): - if not index.isValid(): - return QtCore.QModelIndex() - - childItem = index.internalPointer() - parentItem = childItem.parent() - - if parentItem == self.rootItem: - return QtCore.QModelIndex() - - return self.createIndex(parentItem.row(), 0, parentItem) - - def rowCount(self, parent): - if parent.column() > 0: - return 0 - - if not parent.isValid(): - parentItem = self.rootItem - else: - parentItem = parent.internalPointer() - - return parentItem.childCount() - - def hasIndex(self, row, column, parentIndex=None, *args, **kwargs): - if row < 0 or column > self.rootItem.columnCount(): - return False - return True - - -class DrEditWidget(QtGui.QWidget): - """行情数据记录引擎管理组件""" - signal = QtCore.pyqtSignal(type(Event())) - - def __init__(self, drWidget, mainEngine, eventEngine, parent=None): - """Constructor""" - super(DrEditWidget, self).__init__(parent) - self.drWidget = drWidget - self.mainEngine = mainEngine - self.eventEngine = eventEngine - self.hasChanged = False - - # 保存合约详细信息的字典 - self.contractDict = {} - - self.initUi() - self.updateSetting() - self.loadData() - self.registerEvent() - - def closeEvent(self, QCloseEvent): - if self.hasChanged: - self.drWidget.restart() - - def initUi(self): - - vbox = QtGui.QVBoxLayout() - - vline = QtGui.QHBoxLayout() - vline.setSpacing(2) - btnTickAll = QtGui.QPushButton(u"全部记录Tick", self) - btnBarAll = QtGui.QPushButton(u'全部记录Bar', self) - btnSaveAll = QtGui.QPushButton(u'保存设置(重启后生效)', self) - btnTickAll.clicked.connect(self.selectAllTick) - btnBarAll.clicked.connect(self.selectAllBar) - btnSaveAll.clicked.connect(self.saveSetting) - - vline.addWidget(btnTickAll) - vline.addWidget(btnBarAll) - vline.addWidget(btnSaveAll) - - vbox.addLayout(vline) - - self.qTreeView = QTreeView() - self.model = TreeModel() - self.qTreeView.setModel(self.model) - self.qTreeView.setSelectionMode(QtGui.QAbstractItemView.NoSelection) - self.qTreeView.setItemDelegateForColumn(1, CheckBoxDelegate(self)) - self.qTreeView.setItemDelegateForColumn(2, CheckBoxDelegate(self)) - self.qTreeView.setItemDelegateForColumn(3, CheckBoxDelegate(self)) - self.qTreeView.setItemDelegateForColumn(5, ComboDelegate(self, ["CTP", "LTS", "XTP", "FEMAS", "XSPEED", "QDP", - "KSOTP", "KSGOLD", "SGIT"])) - - vbox.addWidget(self.qTreeView) - self.setLayout(vbox) - - def getContractChineseName(self, str): - line = str.strip().decode('utf-8', 'ignore') # 处理前进行相关的处理,包括转换成Unicode等 - p2 = re.compile(ur'[^\u4e00-\u9fa5]') # 中文的编码范围是:\u4e00到\u9fa5 - zh = " ".join(p2.split(line)).strip() - zh = ",".join(zh.split()) - outStr = zh # 经过相关处理后得到中文的文本 - return outStr - - def loadData(self): - child = [] - - tick = {} - bar = {} - active = [] - with open(self.mainEngine.drEngine.settingFileName) as f: - drSetting = json.load(f) - if 'tick' in drSetting: - l = drSetting['tick'] - - for setting in l: - tick[setting[0]] = setting[1] - - if 'bar' in drSetting: - l = drSetting['bar'] - - for setting in l: - bar[setting[0]] = setting[1] - - if 'active' in drSetting: - d = drSetting['active'] - - for activeSymbol, symbol in d.items(): - active.append(symbol) - - contractDict = {} - contracts = self.mainEngine.getAllContracts() - for contract in contracts: - contractName = self.getContractChineseName(contract.name) - gateWayName = u"CTP" - hasTick = tick.has_key(contract.symbol) - hasBar = bar.has_key(contract.symbol) - hasActive = contract.symbol in active - if hasTick: - gateWayName = tick[contract.symbol] - elif hasBar: - gateWayName = bar[contract.symbol] - if contractDict.has_key(contractName): - parentItem = contractDict[contractName] - item = TreeItem([contract.symbol, hasTick, hasBar, hasActive, contract.exchange, gateWayName], - parentItem) - parentItem.appendChild(item) - else: - item = TreeItem([contractName, False, False, False, contract.exchange, gateWayName], - self.model.rootItem) - contractDict[contractName] = item - child.append(item) - subItem = TreeItem([contract.symbol, hasTick, hasBar, hasActive, contract.exchange, gateWayName], item) - item.appendChild(subItem) - - # yumi = TreeItem([u"玉米", False, False, False, "SH", "CTP"], self.model.rootItem) - # yumi.appendChild(TreeItem([u"c1705", False, False, False, "SH", "CTP"], yumi)) - # yumi.appendChild(TreeItem([u"c1703", False, False, False, "SH", "CTP"], yumi)) - # yumi.appendChild(TreeItem([u"c1707", False, False, False, "SH", "CTP"], yumi)) - # yumi.appendChild(TreeItem([u"c1709", False, False, False, "SH", "CTP"], yumi)) - # dianfen = TreeItem([u"淀粉", False, False, False, "SH", "CTP"], self.model.rootItem) - # dianfen.appendChild(TreeItem([u"d1705", False, False, False, "SH", "CTP"], dianfen)) - # dianfen.appendChild(TreeItem([u"d1703", False, False, False, "SH", "CTP"], dianfen)) - # dianfen.appendChild(TreeItem([u"d1707", False, False, False, "SH", "CTP"], dianfen)) - # dianfen.appendChild(TreeItem([u"d1709", False, False, False, "SH", "CTP"], dianfen)) - # - # child.append(yumi) - # child.append(dianfen) - self.model.setDataSource(child) - self.qTreeView.expandAll() - - def saveSetting(self): - setting = {} - setting["tick"] = [] - setting["bar"] = [] - setting["active"] = {} - queue = Queue() - queue.put(self.model.rootItem) - while queue.qsize() > 0: - item = queue.get() - for child in item.childItems: - queue.put(child) - if item.parentItem is not None and item.parentItem != self.model.rootItem: - name = item.data(0) - interface = item.data(5) - if item.data(1): - setting["tick"].append([name, interface]) - if item.data(2): - setting["bar"].append([name, interface]) - if item.data(3): - setting["active"][item.parentItem.data(0)] = name - if self.mainEngine.drEngine.saveSetting(setting): - self.hasChanged = True - self.close() - - def selectAllTick(self): - self.selectAll(True, False, True) - - def selectAllBar(self): - self.selectAll(False, True, True) - - def selectAll(self, tick=False, bar=False, select=False): - column = None - if tick: - column = 1 - if bar: - column = 2 - - for row in range(self.model.rootItem.childCount()): - childIndex = self.model.index(row, column, None) - self.model.setData(childIndex, QtCore.Qt.Unchecked if select == False else QtCore.Qt.Checked, - QtCore.Qt.CheckStateRole) - - def updateSetting(self): - pass - - def updateContract(self, event): - """更新合约数据""" - contract = event.dict_['data'] - self.contractDict[contract.vtSymbol] = contract - self.contractDict[contract.symbol] = contract # 使用常规代码(不包括交易所)可能导致重复 - - # ---------------------------------------------------------------------- - def registerEvent(self): - """注册事件监听""" - self.signal.connect(self.updateContract) - self.eventEngine.register(EVENT_CONTRACT, self.signal.emit) - - -if __name__ == '__main__': - import sys - - app = QtGui.QApplication(sys.argv) - - view = DrEditWidget(None, DrEngine, EventEngine) - view.setFixedSize(650, 500) - view.show() - sys.exit(app.exec_()) diff --git a/vn.trader/dataRecorder/uiDrWidget.py b/vn.trader/dataRecorder/uiDrWidget.py index 869f7e1a..b9a21190 100644 --- a/vn.trader/dataRecorder/uiDrWidget.py +++ b/vn.trader/dataRecorder/uiDrWidget.py @@ -6,9 +6,8 @@ import json -from dataRecorder.uiDrEdit import DrEditWidget -from eventEngine import * from uiBasicWidget import QtGui, QtCore +from eventEngine import * ######################################################################## @@ -39,23 +38,22 @@ class DrEngineManager(QtGui.QWidget): signal = QtCore.pyqtSignal(type(Event())) #---------------------------------------------------------------------- - def __init__(self, mainEngine, eventEngine, parent=None): + def __init__(self, drEngine, eventEngine, parent=None): """Constructor""" super(DrEngineManager, self).__init__(parent) - - self.mainEngine = mainEngine - self.drEngine = mainEngine.drEngine + + self.drEngine = drEngine self.eventEngine = eventEngine - + self.initUi() self.updateSetting() - self.registerEvent() - + self.registerEvent() + #---------------------------------------------------------------------- def initUi(self): """初始化界面""" self.setWindowTitle(u'行情数据记录工具') - + # 记录合约配置监控 tickLabel = QtGui.QLabel(u'Tick记录') self.tickTable = QtGui.QTableWidget() @@ -65,14 +63,14 @@ class DrEngineManager(QtGui.QWidget): self.tickTable.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch) self.tickTable.setAlternatingRowColors(True) self.tickTable.setHorizontalHeaderLabels([u'合约代码', u'接口']) - + barLabel = QtGui.QLabel(u'Bar记录') self.barTable = QtGui.QTableWidget() self.barTable.setColumnCount(2) self.barTable.verticalHeader().setVisible(False) self.barTable.setEditTriggers(QtGui.QTableWidget.NoEditTriggers) self.barTable.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch) - self.barTable.setAlternatingRowColors(True) + self.barTable.setAlternatingRowColors(True) self.barTable.setHorizontalHeaderLabels([u'合约代码', u'接口']) activeLabel = QtGui.QLabel(u'主力合约') @@ -81,99 +79,77 @@ class DrEngineManager(QtGui.QWidget): self.activeTable.verticalHeader().setVisible(False) self.activeTable.setEditTriggers(QtGui.QTableWidget.NoEditTriggers) self.activeTable.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch) - self.activeTable.setAlternatingRowColors(True) + self.activeTable.setAlternatingRowColors(True) self.activeTable.setHorizontalHeaderLabels([u'主力代码', u'合约代码']) # 日志监控 self.logMonitor = QtGui.QTextEdit() self.logMonitor.setReadOnly(True) self.logMonitor.setMinimumHeight(600) - + # 设置布局 grid = QtGui.QGridLayout() - + grid.addWidget(tickLabel, 0, 0) grid.addWidget(barLabel, 0, 1) grid.addWidget(activeLabel, 0, 2) grid.addWidget(self.tickTable, 1, 0) grid.addWidget(self.barTable, 1, 1) - grid.addWidget(self.activeTable, 1, 2) - - btnEdit = QtGui.QPushButton(u'编辑', self) - + grid.addWidget(self.activeTable, 1, 2) + vbox = QtGui.QVBoxLayout() vbox.addLayout(grid) - - vline = QtGui.QHBoxLayout() - vline.addWidget(btnEdit) - - vbox.addLayout(vline) vbox.addWidget(self.logMonitor) self.setLayout(vbox) - btnEdit.clicked.connect(self.openDr) - #---------------------------------------------------------------------- def updateLog(self, event): """更新日志""" log = event.dict_['data'] content = '\t'.join([log.logTime, log.logContent]) self.logMonitor.append(content) - + #---------------------------------------------------------------------- def registerEvent(self): """注册事件监听""" self.signal.connect(self.updateLog) self.eventEngine.register(EVENT_DATARECORDER_LOG, self.signal.emit) - + #---------------------------------------------------------------------- def updateSetting(self): """显示引擎行情记录配置""" - - self.tickTable.clearContents() - self.tickTable.setRowCount(0) - self.barTable.clearContents() - self.barTable.setRowCount(0) - self.activeTable.clearContents() - self.activeTable.setRowCount(0) - with open(self.drEngine.settingFileName) as f: drSetting = json.load(f) - + if 'tick' in drSetting: l = drSetting['tick'] - + for setting in l: self.tickTable.insertRow(0) self.tickTable.setItem(0, 0, TableCell(setting[0])) self.tickTable.setItem(0, 1, TableCell(setting[1])) - + if 'bar' in drSetting: l = drSetting['bar'] - + for setting in l: self.barTable.insertRow(0) self.barTable.setItem(0, 0, TableCell(setting[0])) - self.barTable.setItem(0, 1, TableCell(setting[1])) - + self.barTable.setItem(0, 1, TableCell(setting[1])) + if 'active' in drSetting: d = drSetting['active'] - + for activeSymbol, symbol in d.items(): self.activeTable.insertRow(0) self.activeTable.setItem(0, 0, TableCell(activeSymbol)) self.activeTable.setItem(0, 1, TableCell(symbol)) + + + + - # ---------------------------------------------------------------------- - def openDr(self): - """打开行情数据记录组件""" - self.mDrEditWidget = DrEditWidget(self,self.mainEngine, self.eventEngine) - self.mDrEditWidget.setWindowTitle(u"编辑订阅") - self.mDrEditWidget.setFixedSize(800,800) - self.mDrEditWidget.show() - def restart(self): - pass - # self.drEngine.stop() - # self.updateSetting() - # self.mainEngine.drEngine = DrEngine(self.mainEngine, self.mainEngine.eventEngine) + + + \ No newline at end of file diff --git a/vn.trader/uiBasicWidget.py b/vn.trader/uiBasicWidget.py index 8a842810..f7f4eb63 100644 --- a/vn.trader/uiBasicWidget.py +++ b/vn.trader/uiBasicWidget.py @@ -1,11 +1,13 @@ # encoding: UTF-8 +import json import csv +import os from collections import OrderedDict from PyQt4 import QtGui, QtCore -from PyQt4.QtCore import Qt +from eventEngine import * from vtFunction import * from vtGateway import * @@ -14,9 +16,9 @@ from vtGateway import * def loadFont(): """载入字体设置""" fileName = 'VT_setting.json' - path = os.path.abspath(os.path.dirname(__file__)) - fileName = os.path.join(path, fileName) - + path = os.path.abspath(os.path.dirname(__file__)) + fileName = os.path.join(path, fileName) + try: f = file(fileName) setting = json.load(f) @@ -41,7 +43,7 @@ class BasicCell(QtGui.QTableWidgetItem): self.data = None if text: self.setContent(text) - + #---------------------------------------------------------------------- def setContent(self, text): """设置内容""" @@ -51,22 +53,6 @@ class BasicCell(QtGui.QTableWidgetItem): self.setText(text) -######################################################################## -class CheckBoxCell(QtGui.QTableWidgetItem): - """用来显示复选框的单元格""" - - def __init__(self, isChecked=False, mainEngine=None): - """Constructor""" - super(CheckBoxCell, self).__init__() - self.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) - self.setStauts(isChecked) - - def setStauts(self, isChecked=False): - if not isChecked: - self.setCheckState(Qt.Unchecked) - else: - self.setCheckState(Qt.Checked) - ######################################################################## class NumCell(QtGui.QTableWidgetItem): """用来显示数字的单元格""" @@ -78,7 +64,7 @@ class NumCell(QtGui.QTableWidgetItem): self.data = None if text: self.setContent(text) - + #---------------------------------------------------------------------- def setContent(self, text): """设置内容""" @@ -90,7 +76,7 @@ class NumCell(QtGui.QTableWidgetItem): self.setData(QtCore.Qt.DisplayRole, num) except ValueError: self.setText(text) - + ######################################################################## class DirectionCell(QtGui.QTableWidgetItem): @@ -103,7 +89,7 @@ class DirectionCell(QtGui.QTableWidgetItem): self.data = None if text: self.setContent(text) - + #---------------------------------------------------------------------- def setContent(self, text): """设置内容""" @@ -122,20 +108,20 @@ class NameCell(QtGui.QTableWidgetItem): def __init__(self, text=None, mainEngine=None): """Constructor""" super(NameCell, self).__init__() - + self.mainEngine = mainEngine self.data = None - + if text: self.setContent(text) - + #---------------------------------------------------------------------- def setContent(self, text): """设置内容""" if self.mainEngine: # 首先尝试正常获取合约对象 contract = self.mainEngine.getContract(text) - + # 如果能读取合约信息 if contract: self.setText(contract.name) @@ -153,10 +139,10 @@ class BidCell(QtGui.QTableWidgetItem): self.setForeground(QtGui.QColor('black')) self.setBackground(QtGui.QColor(255,174,201)) - + if text: self.setContent(text) - + #---------------------------------------------------------------------- def setContent(self, text): """设置内容""" @@ -175,10 +161,10 @@ class AskCell(QtGui.QTableWidgetItem): self.setForeground(QtGui.QColor('black')) self.setBackground(QtGui.QColor(160,255,160)) - + if text: self.setContent(text) - + #---------------------------------------------------------------------- def setContent(self, text): """设置内容""" @@ -189,10 +175,10 @@ class AskCell(QtGui.QTableWidgetItem): class BasicMonitor(QtGui.QTableWidget): """ 基础监控 - + headerDict中的值对应的字典格式如下 {'chinese': u'中文名', 'cellType': BasicCell} - + """ signal = QtCore.pyqtSignal(type(Event())) @@ -200,79 +186,79 @@ class BasicMonitor(QtGui.QTableWidget): def __init__(self, mainEngine=None, eventEngine=None, parent=None): """Constructor""" super(BasicMonitor, self).__init__(parent) - + self.mainEngine = mainEngine self.eventEngine = eventEngine - + # 保存表头标签用 self.headerDict = OrderedDict() # 有序字典,key是英文名,value是对应的配置字典 self.headerList = [] # 对应self.headerDict.keys() - + # 保存相关数据用 self.dataDict = {} # 字典,key是字段对应的数据,value是保存相关单元格的字典 self.dataKey = '' # 字典键对应的数据字段 - + # 监控的事件类型 self.eventType = '' - + # 字体 self.font = None - + # 保存数据对象到单元格 self.saveData = False - + # 默认不允许根据表头进行排序,需要的组件可以开启 self.sorting = False - + # 初始化右键菜单 self.initMenu() - + #---------------------------------------------------------------------- def setHeaderDict(self, headerDict): """设置表头有序字典""" self.headerDict = headerDict self.headerList = headerDict.keys() - + #---------------------------------------------------------------------- def setDataKey(self, dataKey): """设置数据字典的键""" self.dataKey = dataKey - + #---------------------------------------------------------------------- def setEventType(self, eventType): """设置监控的事件类型""" self.eventType = eventType - + #---------------------------------------------------------------------- def setFont(self, font): """设置字体""" self.font = font - + #---------------------------------------------------------------------- def setSaveData(self, saveData): """设置是否要保存数据到单元格""" self.saveData = saveData - + #---------------------------------------------------------------------- def initTable(self): """初始化表格""" # 设置表格的列数 col = len(self.headerDict) self.setColumnCount(col) - + # 设置列表头 labels = [d['chinese'] for d in self.headerDict.values()] self.setHorizontalHeaderLabels(labels) - + # 关闭左边的垂直表头 self.verticalHeader().setVisible(False) - + # 设为不可编辑 self.setEditTriggers(self.NoEditTriggers) - + # 设为行交替颜色 self.setAlternatingRowColors(True) - + # 设置允许排序 self.setSortingEnabled(self.sorting) @@ -281,38 +267,38 @@ class BasicMonitor(QtGui.QTableWidget): """注册GUI更新相关的事件监听""" self.signal.connect(self.updateEvent) self.eventEngine.register(self.eventType, self.signal.emit) - + #---------------------------------------------------------------------- def updateEvent(self, event): """收到事件更新""" data = event.dict_['data'] self.updateData(data) - + #---------------------------------------------------------------------- def updateData(self, data): """将数据更新到表格中""" # 如果允许了排序功能,则插入数据前必须关闭,否则插入新的数据会变乱 if self.sorting: self.setSortingEnabled(False) - + # 如果设置了dataKey,则采用存量更新模式 if self.dataKey: key = data.__getattribute__(self.dataKey) # 如果键在数据字典中不存在,则先插入新的一行,并创建对应单元格 if key not in self.dataDict: - self.insertRow(0) + self.insertRow(0) d = {} - for n, header in enumerate(self.headerList): + for n, header in enumerate(self.headerList): content = safeUnicode(data.__getattribute__(header)) cellType = self.headerDict[header]['cellType'] cell = cellType(content, self.mainEngine) - + if self.font: cell.setFont(self.font) # 如果设置了特殊字体,则进行单元格设置 - + if self.saveData: # 如果设置了保存数据对象,则进行对象保存 cell.data = data - + self.setItem(0, n, cell) d[header] = cell self.dataDict[key] = d @@ -323,48 +309,48 @@ class BasicMonitor(QtGui.QTableWidget): content = safeUnicode(data.__getattribute__(header)) cell = d[header] cell.setContent(content) - + if self.saveData: # 如果设置了保存数据对象,则进行对象保存 - cell.data = data + cell.data = data # 否则采用增量更新模式 else: - self.insertRow(0) + self.insertRow(0) for n, header in enumerate(self.headerList): content = safeUnicode(data.__getattribute__(header)) cellType = self.headerDict[header]['cellType'] cell = cellType(content, self.mainEngine) - + if self.font: cell.setFont(self.font) if self.saveData: - cell.data = data - - self.setItem(0, n, cell) + cell.data = data + self.setItem(0, n, cell) + # 调整列宽 self.resizeColumns() - + # 重新打开排序 if self.sorting: self.setSortingEnabled(True) - + #---------------------------------------------------------------------- def resizeColumns(self): """调整各列的大小""" - self.horizontalHeader().resizeSections(QtGui.QHeaderView.ResizeToContents) - + self.horizontalHeader().resizeSections(QtGui.QHeaderView.ResizeToContents) + #---------------------------------------------------------------------- def setSorting(self, sorting): """设置是否允许根据表头排序""" self.sorting = sorting - + #---------------------------------------------------------------------- def saveToCsv(self): """保存表格内容到CSV文件""" # 先隐藏右键菜单 self.menu.close() - + # 获取想要保存的文件名 path = QtGui.QFileDialog.getSaveFileName(self, '保存数据', '', 'CSV(*.csv)') @@ -372,11 +358,11 @@ class BasicMonitor(QtGui.QTableWidget): if not path.isEmpty(): with open(unicode(path), 'wb') as f: writer = csv.writer(f) - + # 保存标签 headers = [header.encode('gbk') for header in self.headerList] writer.writerow(headers) - + # 保存每行内容 for row in range(self.rowCount()): rowdata = [] @@ -387,24 +373,24 @@ class BasicMonitor(QtGui.QTableWidget): unicode(item.text()).encode('gbk')) else: rowdata.append('') - writer.writerow(rowdata) + writer.writerow(rowdata) except IOError: pass #---------------------------------------------------------------------- def initMenu(self): """初始化右键菜单""" - self.menu = QtGui.QMenu(self) - + self.menu = QtGui.QMenu(self) + saveAction = QtGui.QAction(u'保存内容', self) saveAction.triggered.connect(self.saveToCsv) - + self.menu.addAction(saveAction) - + #---------------------------------------------------------------------- def contextMenuEvent(self, event): """右键点击事件""" - self.menu.popup(QtGui.QCursor.pos()) + self.menu.popup(QtGui.QCursor.pos()) ######################################################################## @@ -415,7 +401,7 @@ class MarketMonitor(BasicMonitor): def __init__(self, mainEngine, eventEngine, parent=None): """Constructor""" super(MarketMonitor, self).__init__(mainEngine, eventEngine, parent) - + # 设置表头有序字典 d = OrderedDict() d['symbol'] = {'chinese':u'合约代码', 'cellType':BasicCell} @@ -434,22 +420,22 @@ class MarketMonitor(BasicMonitor): d['time'] = {'chinese':u'时间', 'cellType':BasicCell} d['gatewayName'] = {'chinese':u'接口', 'cellType':BasicCell} self.setHeaderDict(d) - + # 设置数据键 self.setDataKey('vtSymbol') - + # 设置监控事件类型 self.setEventType(EVENT_TICK) - + # 设置字体 self.setFont(BASIC_FONT) - + # 设置允许排序 - self.setSorting(False) - + self.setSorting(True) + # 初始化表格 self.initTable() - + # 注册事件监听 self.registerEvent() @@ -462,15 +448,15 @@ class LogMonitor(BasicMonitor): def __init__(self, mainEngine, eventEngine, parent=None): """Constructor""" super(LogMonitor, self).__init__(mainEngine, eventEngine, parent) - - d = OrderedDict() + + d = OrderedDict() d['logTime'] = {'chinese':u'时间', 'cellType':BasicCell} d['logContent'] = {'chinese':u'内容', 'cellType':BasicCell} d['gatewayName'] = {'chinese':u'接口', 'cellType':BasicCell} self.setHeaderDict(d) - + self.setEventType(EVENT_LOG) - self.setFont(BASIC_FONT) + self.setFont(BASIC_FONT) self.initTable() self.registerEvent() @@ -483,14 +469,14 @@ class ErrorMonitor(BasicMonitor): def __init__(self, mainEngine, eventEngine, parent=None): """Constructor""" super(ErrorMonitor, self).__init__(mainEngine, eventEngine, parent) - - d = OrderedDict() + + d = OrderedDict() d['errorTime'] = {'chinese':u'错误时间', 'cellType':BasicCell} d['errorID'] = {'chinese':u'错误代码', 'cellType':BasicCell} d['errorMsg'] = {'chinese':u'错误信息', 'cellType':BasicCell} d['gatewayName'] = {'chinese':u'接口', 'cellType':BasicCell} self.setHeaderDict(d) - + self.setEventType(EVENT_ERROR) self.setFont(BASIC_FONT) self.initTable() @@ -505,7 +491,7 @@ class TradeMonitor(BasicMonitor): def __init__(self, mainEngine, eventEngine, parent=None): """Constructor""" super(TradeMonitor, self).__init__(mainEngine, eventEngine, parent) - + d = OrderedDict() d['tradeID'] = {'chinese':u'成交编号', 'cellType':NumCell} d['orderID'] = {'chinese':u'委托编号', 'cellType':NumCell} @@ -518,11 +504,11 @@ class TradeMonitor(BasicMonitor): d['tradeTime'] = {'chinese':u'成交时间', 'cellType':BasicCell} d['gatewayName'] = {'chinese':u'接口', 'cellType':BasicCell} self.setHeaderDict(d) - + self.setEventType(EVENT_TRADE) self.setFont(BASIC_FONT) self.setSorting(True) - + self.initTable() self.registerEvent() @@ -537,7 +523,7 @@ class OrderMonitor(BasicMonitor): super(OrderMonitor, self).__init__(mainEngine, eventEngine, parent) self.mainEngine = mainEngine - + d = OrderedDict() d['orderID'] = {'chinese':u'委托编号', 'cellType':NumCell} d['symbol'] = {'chinese':u'合约代码', 'cellType':BasicCell} @@ -554,28 +540,28 @@ class OrderMonitor(BasicMonitor): d['sessionID'] = {'chinese':u'会话编号', 'cellType':BasicCell} d['gatewayName'] = {'chinese':u'接口', 'cellType':BasicCell} self.setHeaderDict(d) - + self.setDataKey('vtOrderID') self.setEventType(EVENT_ORDER) self.setFont(BASIC_FONT) self.setSaveData(True) self.setSorting(True) - + self.initTable() self.registerEvent() self.connectSignal() - + #---------------------------------------------------------------------- def connectSignal(self): """连接信号""" # 双击单元格撤单 - self.itemDoubleClicked.connect(self.cancelOrder) - + self.itemDoubleClicked.connect(self.cancelOrder) + #---------------------------------------------------------------------- def cancelOrder(self, cell): """根据单元格的数据撤单""" order = cell.data - + req = VtCancelOrderReq() req.symbol = order.symbol req.exchange = order.exchange @@ -592,7 +578,7 @@ class PositionMonitor(BasicMonitor): def __init__(self, mainEngine, eventEngine, parent=None): """Constructor""" super(PositionMonitor, self).__init__(mainEngine, eventEngine, parent) - + d = OrderedDict() d['symbol'] = {'chinese':u'合约代码', 'cellType':BasicCell} d['vtSymbol'] = {'chinese':u'名称', 'cellType':NameCell} @@ -604,16 +590,16 @@ class PositionMonitor(BasicMonitor): d['positionProfit'] = {'chinese':u'持仓盈亏', 'cellType':BasicCell} d['gatewayName'] = {'chinese':u'接口', 'cellType':BasicCell} self.setHeaderDict(d) - + self.setDataKey('vtPositionName') self.setEventType(EVENT_POSITION) self.setFont(BASIC_FONT) self.setSaveData(True) - + self.initTable() self.registerEvent() - - + + ######################################################################## class AccountMonitor(BasicMonitor): """账户监控""" @@ -622,7 +608,7 @@ class AccountMonitor(BasicMonitor): def __init__(self, mainEngine, eventEngine, parent=None): """Constructor""" super(AccountMonitor, self).__init__(mainEngine, eventEngine, parent) - + d = OrderedDict() d['accountID'] = {'chinese':u'账户', 'cellType':BasicCell} d['preBalance'] = {'chinese':u'昨结', 'cellType':BasicCell} @@ -634,7 +620,7 @@ class AccountMonitor(BasicMonitor): d['positionProfit'] = {'chinese':u'持仓盈亏', 'cellType':BasicCell} d['gatewayName'] = {'chinese':u'接口', 'cellType':BasicCell} self.setHeaderDict(d) - + self.setDataKey('vtAccountID') self.setEventType(EVENT_ACCOUNT) self.setFont(BASIC_FONT) @@ -646,7 +632,7 @@ class AccountMonitor(BasicMonitor): class TradingWidget(QtGui.QFrame): """简单交易组件""" signal = QtCore.pyqtSignal(type(Event())) - + directionList = [DIRECTION_LONG, DIRECTION_SHORT] @@ -654,12 +640,12 @@ class TradingWidget(QtGui.QFrame): OFFSET_CLOSE, OFFSET_CLOSEYESTERDAY, OFFSET_CLOSETODAY] - + priceTypeList = [PRICETYPE_LIMITPRICE, PRICETYPE_MARKETPRICE, PRICETYPE_FAK, PRICETYPE_FOK] - + exchangeList = [EXCHANGE_NONE, EXCHANGE_CFFEX, EXCHANGE_SHFE, @@ -676,18 +662,18 @@ class TradingWidget(QtGui.QFrame): EXCHANGE_NYMEX, EXCHANGE_GLOBEX, EXCHANGE_IDEALPRO] - + currencyList = [CURRENCY_NONE, CURRENCY_CNY, CURRENCY_HKD, CURRENCY_USD] - + productClassList = [PRODUCT_NONE, PRODUCT_EQUITY, PRODUCT_FUTURES, PRODUCT_OPTION, PRODUCT_FOREX] - + gatewayList = [''] #---------------------------------------------------------------------- @@ -696,9 +682,9 @@ class TradingWidget(QtGui.QFrame): super(TradingWidget, self).__init__(parent) self.mainEngine = mainEngine self.eventEngine = eventEngine - + self.symbol = '' - + # 添加交易接口 self.gatewayList.extend(mainEngine.getAllGatewayNames()) @@ -711,7 +697,7 @@ class TradingWidget(QtGui.QFrame): self.setWindowTitle(u'交易') self.setMaximumWidth(400) self.setFrameShape(self.Box) # 设置边框 - self.setLineWidth(1) + self.setLineWidth(1) # 左边部分 labelSymbol = QtGui.QLabel(u'代码') @@ -722,7 +708,7 @@ class TradingWidget(QtGui.QFrame): self.checkFixed = QtGui.QCheckBox(u'') # 价格固定选择框 labelVolume = QtGui.QLabel(u'数量') labelPriceType = QtGui.QLabel(u'价格类型') - labelExchange = QtGui.QLabel(u'交易所') + labelExchange = QtGui.QLabel(u'交易所') labelCurrency = QtGui.QLabel(u'货币') labelProductClass = QtGui.QLabel(u'产品类型') labelGateway = QtGui.QLabel(u'交易接口') @@ -747,18 +733,18 @@ class TradingWidget(QtGui.QFrame): self.comboPriceType = QtGui.QComboBox() self.comboPriceType.addItems(self.priceTypeList) - + self.comboExchange = QtGui.QComboBox() - self.comboExchange.addItems(self.exchangeList) - + self.comboExchange.addItems(self.exchangeList) + self.comboCurrency = QtGui.QComboBox() self.comboCurrency.addItems(self.currencyList) - + self.comboProductClass = QtGui.QComboBox() - self.comboProductClass.addItems(self.productClassList) - + self.comboProductClass.addItems(self.productClassList) + self.comboGateway = QtGui.QComboBox() - self.comboGateway.addItems(self.gatewayList) + self.comboGateway.addItems(self.gatewayList) gridleft = QtGui.QGridLayout() gridleft.addWidget(labelSymbol, 0, 0) @@ -770,9 +756,9 @@ class TradingWidget(QtGui.QFrame): gridleft.addWidget(labelPriceType, 6, 0) gridleft.addWidget(labelExchange, 7, 0) gridleft.addWidget(labelCurrency, 8, 0) - gridleft.addWidget(labelProductClass, 9, 0) + gridleft.addWidget(labelProductClass, 9, 0) gridleft.addWidget(labelGateway, 10, 0) - + gridleft.addWidget(self.lineSymbol, 0, 1, 1, -1) gridleft.addWidget(self.lineName, 1, 1, 1, -1) gridleft.addWidget(self.comboDirection, 2, 1, 1, -1) @@ -808,7 +794,7 @@ class TradingWidget(QtGui.QFrame): self.labelBidVolume2 = QtGui.QLabel() self.labelBidVolume3 = QtGui.QLabel() self.labelBidVolume4 = QtGui.QLabel() - self.labelBidVolume5 = QtGui.QLabel() + self.labelBidVolume5 = QtGui.QLabel() self.labelAskPrice1 = QtGui.QLabel() self.labelAskPrice2 = QtGui.QLabel() @@ -819,7 +805,7 @@ class TradingWidget(QtGui.QFrame): self.labelAskVolume2 = QtGui.QLabel() self.labelAskVolume3 = QtGui.QLabel() self.labelAskVolume4 = QtGui.QLabel() - self.labelAskVolume5 = QtGui.QLabel() + self.labelAskVolume5 = QtGui.QLabel() labelLast = QtGui.QLabel(u'最新') self.labelLastPrice = QtGui.QLabel() @@ -851,7 +837,7 @@ class TradingWidget(QtGui.QFrame): gridRight.addWidget(self.labelBidPrice2, 7, 1) gridRight.addWidget(self.labelBidPrice3, 8, 1) gridRight.addWidget(self.labelBidPrice4, 9, 1) - gridRight.addWidget(self.labelBidPrice5, 10, 1) + gridRight.addWidget(self.labelBidPrice5, 10, 1) gridRight.addWidget(self.labelAskVolume5, 0, 2) gridRight.addWidget(self.labelAskVolume4, 1, 2) @@ -868,7 +854,7 @@ class TradingWidget(QtGui.QFrame): # 发单按钮 buttonSendOrder = QtGui.QPushButton(u'发单') buttonCancelAll = QtGui.QPushButton(u'全撤') - + size = buttonSendOrder.sizeHint() buttonSendOrder.setMinimumHeight(size.height()*2) # 把按钮高度设为默认两倍 buttonCancelAll.setMinimumHeight(size.height()*2) @@ -898,23 +884,23 @@ class TradingWidget(QtGui.QFrame): symbol = str(self.lineSymbol.text()) exchange = unicode(self.comboExchange.currentText()) currency = unicode(self.comboCurrency.currentText()) - productClass = unicode(self.comboProductClass.currentText()) + productClass = unicode(self.comboProductClass.currentText()) gatewayName = unicode(self.comboGateway.currentText()) - + # 查询合约 if exchange: vtSymbol = '.'.join([symbol, exchange]) contract = self.mainEngine.getContract(vtSymbol) else: vtSymbol = symbol - contract = self.mainEngine.getContract(symbol) - + contract = self.mainEngine.getContract(symbol) + if contract: vtSymbol = contract.vtSymbol gatewayName = contract.gatewayName self.lineName.setText(contract.name) exchange = contract.exchange # 保证有交易所代码 - + # 清空价格数量 self.spinPrice.setValue(0) self.spinVolume.setValue(0) @@ -929,7 +915,7 @@ class TradingWidget(QtGui.QFrame): self.labelBidVolume2.setText('') self.labelBidVolume3.setText('') self.labelBidVolume4.setText('') - self.labelBidVolume5.setText('') + self.labelBidVolume5.setText('') self.labelAskPrice1.setText('') self.labelAskPrice2.setText('') self.labelAskPrice3.setText('') @@ -974,30 +960,30 @@ class TradingWidget(QtGui.QFrame): self.labelAskPrice1.setText(str(tick.askPrice1)) self.labelBidVolume1.setText(str(tick.bidVolume1)) self.labelAskVolume1.setText(str(tick.askVolume1)) - + if tick.bidPrice2: self.labelBidPrice2.setText(str(tick.bidPrice2)) self.labelBidPrice3.setText(str(tick.bidPrice3)) self.labelBidPrice4.setText(str(tick.bidPrice4)) self.labelBidPrice5.setText(str(tick.bidPrice5)) - + self.labelAskPrice2.setText(str(tick.askPrice2)) self.labelAskPrice3.setText(str(tick.askPrice3)) self.labelAskPrice4.setText(str(tick.askPrice4)) self.labelAskPrice5.setText(str(tick.askPrice5)) - + self.labelBidVolume2.setText(str(tick.bidVolume2)) self.labelBidVolume3.setText(str(tick.bidVolume3)) self.labelBidVolume4.setText(str(tick.bidVolume4)) self.labelBidVolume5.setText(str(tick.bidVolume5)) - + self.labelAskVolume2.setText(str(tick.askVolume2)) self.labelAskVolume3.setText(str(tick.askVolume3)) self.labelAskVolume4.setText(str(tick.askVolume4)) - self.labelAskVolume5.setText(str(tick.askVolume5)) + self.labelAskVolume5.setText(str(tick.askVolume5)) self.labelLastPrice.setText(str(tick.lastPrice)) - + if tick.preClosePrice: rt = (tick.lastPrice/tick.preClosePrice)-1 self.labelReturn.setText(('%.2f' %(rt*100))+'%') @@ -1015,8 +1001,8 @@ class TradingWidget(QtGui.QFrame): symbol = str(self.lineSymbol.text()) exchange = unicode(self.comboExchange.currentText()) currency = unicode(self.comboCurrency.currentText()) - productClass = unicode(self.comboProductClass.currentText()) - gatewayName = unicode(self.comboGateway.currentText()) + productClass = unicode(self.comboProductClass.currentText()) + gatewayName = unicode(self.comboGateway.currentText()) # 查询合约 if exchange: @@ -1025,11 +1011,11 @@ class TradingWidget(QtGui.QFrame): else: vtSymbol = symbol contract = self.mainEngine.getContract(symbol) - + if contract: gatewayName = contract.gatewayName exchange = contract.exchange # 保证有交易所代码 - + req = VtOrderReq() req.symbol = symbol req.exchange = exchange @@ -1040,9 +1026,9 @@ class TradingWidget(QtGui.QFrame): req.offset = unicode(self.comboOffset.currentText()) req.currency = currency req.productClass = productClass - + self.mainEngine.sendOrder(req, gatewayName) - + #---------------------------------------------------------------------- def cancelAll(self): """一键撤销所有委托""" @@ -1055,18 +1041,18 @@ class TradingWidget(QtGui.QFrame): req.sessionID = order.sessionID req.orderID = order.orderID self.mainEngine.cancelOrder(req, order.gatewayName) - + #---------------------------------------------------------------------- def closePosition(self, cell): """根据持仓信息自动填写交易组件""" # 读取持仓数据,cell是一个表格中的单元格对象 pos = cell.data symbol = pos.symbol - + # 更新交易组件的显示合约 self.lineSymbol.setText(symbol) self.updateSymbol() - + # 自动填写信息 self.comboPriceType.setCurrentIndex(self.priceTypeList.index(PRICETYPE_LIMITPRICE)) self.comboOffset.setCurrentIndex(self.offsetList.index(OFFSET_CLOSE)) @@ -1088,9 +1074,9 @@ class ContractMonitor(BasicMonitor): def __init__(self, mainEngine, parent=None): """Constructor""" super(ContractMonitor, self).__init__(parent=parent) - + self.mainEngine = mainEngine - + d = OrderedDict() d['symbol'] = {'chinese':u'合约代码', 'cellType':BasicCell} d['exchange'] = {'chinese':u'交易所', 'cellType':BasicCell} @@ -1101,11 +1087,11 @@ class ContractMonitor(BasicMonitor): d['priceTick'] = {'chinese':u'最小价格变动', 'cellType':BasicCell} #d['strikePrice'] = {'chinese':u'期权行权价', 'cellType':BasicCell} #d['underlyingSymbol'] = {'chinese':u'期权标的物', 'cellType':BasicCell} - #d['optionType'] = {'chinese':u'期权类型', 'cellType':BasicCell} + #d['optionType'] = {'chinese':u'期权类型', 'cellType':BasicCell} self.setHeaderDict(d) - + self.initUi() - + #---------------------------------------------------------------------- def initUi(self): """初始化界面""" @@ -1114,7 +1100,7 @@ class ContractMonitor(BasicMonitor): self.setFont(BASIC_FONT) self.initTable() self.addMenuAction() - + #---------------------------------------------------------------------- def showAllContracts(self): """显示所有合约数据""" @@ -1125,24 +1111,22 @@ class ContractMonitor(BasicMonitor): self.setRowCount(len(l2)) row = 0 - + for key in l2: contract = d[key] - + for n, header in enumerate(self.headerList): + content = safeUnicode(contract.__getattribute__(header)) cellType = self.headerDict[header]['cellType'] - content = None - if (hasattr(contract, header)): - content = safeUnicode(contract.__getattribute__(header)) cell = cellType(content) - + if self.font: cell.setFont(self.font) # 如果设置了特殊字体,则进行单元格设置 - + self.setItem(row, n, cell) - + row = row + 1 - + #---------------------------------------------------------------------- def refresh(self): """刷新""" @@ -1150,19 +1134,19 @@ class ContractMonitor(BasicMonitor): self.clearContents() self.setRowCount(0) self.showAllContracts() - + #---------------------------------------------------------------------- def addMenuAction(self): """增加右键菜单内容""" refreshAction = QtGui.QAction(u'刷新', self) refreshAction.triggered.connect(self.refresh) - + self.menu.addAction(refreshAction) - + #---------------------------------------------------------------------- def show(self): """显示""" super(ContractMonitor, self).show() self.refresh() - - + + diff --git a/vn.trader/uiMainWindow.py b/vn.trader/uiMainWindow.py index 8115f61f..007fd8b1 100644 --- a/vn.trader/uiMainWindow.py +++ b/vn.trader/uiMainWindow.py @@ -2,10 +2,10 @@ import psutil +from uiBasicWidget import * from ctaAlgo.uiCtaWidget import CtaEngineManager from dataRecorder.uiDrWidget import DrEngineManager from riskManager.uiRmWidget import RmEngineManager -from uiBasicWidget import * ######################################################################## class MainWindow(QtGui.QMainWindow): @@ -197,7 +197,7 @@ class MainWindow(QtGui.QMainWindow): try: self.widgetDict['drM'].showMaximized() except KeyError: - self.widgetDict['drM'] = DrEngineManager(self.mainEngine, self.eventEngine) + self.widgetDict['drM'] = DrEngineManager(self.mainEngine.drEngine, self.eventEngine) self.widgetDict['drM'].showMaximized() #---------------------------------------------------------------------- diff --git a/vn.trader/util/UiUtil.py b/vn.trader/util/UiUtil.py deleted file mode 100644 index 33eab6ac..00000000 --- a/vn.trader/util/UiUtil.py +++ /dev/null @@ -1,144 +0,0 @@ -from PyQt4 import QtCore -from PyQt4.QtGui import QStyle, QStyledItemDelegate, QStyleOptionButton, QApplication, QItemDelegate, QComboBox, \ - QItemEditorCreatorBase - - -class CheckBoxDelegate(QStyledItemDelegate): - """ - A delegate that places a fully functioning QCheckBox in every - cell of the column to which it's applied - """ - - def __init__(self, parent): - QItemDelegate.__init__(self, parent) - - def createEditor(self, parent, option, index): - ''' - Important, otherwise an editor is created if the user clicks in this cell. - ** Need to hook up a signal to the model - ''' - return None - - def paint(self, painter, option, index): - ''' - Paint a checkbox without the label. - ''' - data = index.model().data(index, QtCore.Qt.CheckStateRole) - if not data in [QtCore.Qt.Unchecked, QtCore.Qt.Checked]: - return - checked = data == QtCore.Qt.Checked - check_box_style_option = QStyleOptionButton() - - if index.flags() & QtCore.Qt.ItemIsEditable == QtCore.Qt.ItemIsEditable: - check_box_style_option.state |= QStyle.State_Enabled - else: - check_box_style_option.state |= QStyle.State_ReadOnly - - if checked: - check_box_style_option.state |= QStyle.State_On - else: - check_box_style_option.state |= QStyle.State_Off - - check_box_style_option.rect = self.getCheckBoxRect(option) - - # this will not run - hasFlag does not exist - # if not index.model().hasFlag(index, QtCore.Qt.ItemIsEditable): - # check_box_style_option.state |= QStyle.State_ReadOnly - - # check_box_style_option.state |= QStyle.State_Enabled - - QApplication.style().drawControl(QStyle.CE_CheckBox, check_box_style_option, painter) - - def editorEvent(self, event, model, option, index): - ''' - Change the data in the model and the state of the checkbox - if the user presses the left mousebutton or presses - Key_Space or Key_Select and this cell is editable. Otherwise do nothing. - ''' - # print 'Check Box editor Event detected : ' - if index.flags() & QtCore.Qt.ItemIsEditable != QtCore.Qt.ItemIsEditable: - return False - - # print 'Check Box edior Event detected : passed first check' - # Do not change the checkbox-state - if event.type() == QtCore.QEvent.MouseButtonRelease or event.type() == QtCore.QEvent.MouseButtonDblClick: - if event.button() != QtCore.Qt.LeftButton or not self.getCheckBoxRect(option).contains(event.pos()): - return False - if event.type() == QtCore.QEvent.MouseButtonDblClick: - return True - elif event.type() == QtCore.QEvent.KeyPress: - if event.key() != QtCore.Qt.Key_Space and event.key() != QtCore.Qt.Key_Select: - return False - else: - return False - - # Change the checkbox-state - self.setModelData(None, model, index) - return True - - def setModelData(self, editor, model, index): - ''' - The user wanted to change the old state in the opposite. - ''' - # print 'SetModelData' - newValue = not index.data().toBool() - # print 'New Value : {0}'.format(newValue) - model.setData(index, QtCore.Qt.Checked if newValue else QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) - - def getCheckBoxRect(self, option): - check_box_style_option = QStyleOptionButton() - check_box_rect = QApplication.style().subElementRect(QStyle.SE_CheckBoxIndicator, check_box_style_option, None) - check_box_point = QtCore.QPoint(option.rect.x() + - option.rect.width() / 2 - - check_box_rect.width() / 2, - option.rect.y() + - option.rect.height() / 2 - - check_box_rect.height() / 2) - return QtCore.QRect(check_box_point, check_box_rect.size()) - - -class ComboDelegate(QItemDelegate): - def __init__(self, parent, dataList=[]): - QItemDelegate.__init__(self, parent) - self.dataList = dataList - - def createEditor(self, parent, option, index): - combo = QComboBox(parent) - combo.addItems(self.dataList) - return combo - - def setEditorData(self, editor, index): - text = index.data().toString() - index = editor.findText(text) - editor.setCurrentIndex(index) - - def setModelData(self, editor, model, index): - model.setData(index, str(editor.itemText(editor.currentIndex()))) - - def updateEditorGeometry(self, editor, option, index): - print option, option.rect - editor.setGeometry(option.rect) - - -class GateWayListEditor(QComboBox): - def __init__(self, widget=None, dataList=[]): - super(GateWayListEditor, self).__init__(widget) - self.dataList = dataList - self.populateList() - - def getGateWay(self): - gateWay = self.itemData(self.currentIndex(), QtCore.Qt.DisplayRole) - return gateWay - - def setGateWay(self, gateWay): - self.setCurrentIndex(self.findData(gateWay, QtCore.Qt.DisplayRole)) - - def populateList(self): - for i, gateWayName in enumerate(self.dataList): - self.insertItem(i, gateWayName) - self.setItemData(i, gateWayName, QtCore.Qt.DisplayRole) - - -class GateWayListItemEditorCreator(QItemEditorCreatorBase): - def createWidget(self, parent): - return GateWayListEditor(parent, ["CTP", "LTS", "XTP", "FEMAS", "XSPEED", "QDP", "KSOTP", "KSGOLD", "SGIT"]) diff --git a/vn.trader/util/__init__.py b/vn.trader/util/__init__.py deleted file mode 100644 index e69de29b..00000000