-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuiMainWindow.py
More file actions
376 lines (302 loc) · 14.7 KB
/
uiMainWindow.py
File metadata and controls
376 lines (302 loc) · 14.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
# encoding: UTF-8
import psutil
from ctpquant.uiBasicWidget import *
from ctpquant.ctaAlgo.uiCtaWidget import CtaEngineManager
from ctpquant.dataRecorder.uiDrWidget import DrEngineManager
from ctpquant.riskManager.uiRmWidget import RmEngineManager
from ctpquant.engine import MainEngine, QuoteEngine
########################################################################
class MainWindow(QtWidgets.QMainWindow):
"""主窗口"""
signalStatusBar = QtCore.pyqtSignal(type(Event()))
def __init__(self):
"""Constructor"""
super(MainWindow, self).__init__()
self.quoteEngine = QuoteEngine()
self.quoteEventEngine = self.quoteEngine.eventEngine
time.sleep(1)
self.mainEngine = MainEngine(self.quoteEngine)
self.eventEngine = self.mainEngine.eventEngine
time.sleep(1)
#
# self.mainEngine = mainEngine
# self.eventEngine = mainEngine.eventEngine
# self.quoteEngine = quoteEngine
# self.quoteEventEngine = quoteEngine.eventEngine
# self.connectCtpQuote()
self.widgetDict = {} # 用来保存子窗口的字典
self.initUi()
self.loadWindowSettings()
def initUi(self):
"""初始化界面"""
self.setWindowTitle('CTPQuant')
self.initCentral()
self.initMenu()
#self.initStatusBar()
def initCentral(self):
"""初始化中心区域"""
widgetMarketM, dockMarketM = self.createMarketMonitor(MarketMonitor, '行情', QtCore.Qt.RightDockWidgetArea)
widgetContractM, dockContractM = self.createDock(ContractMonitor, '合约列表', QtCore.Qt.RightDockWidgetArea)
widgetLogM, dockLogM = self.createDock(LogMonitor, '日志', QtCore.Qt.BottomDockWidgetArea)
widgetErrorM, dockErrorM = self.createDock(ErrorMonitor, '错误', QtCore.Qt.BottomDockWidgetArea)
widgetTradeM, dockTradeM = self.createDock(TradeMonitor, '成交', QtCore.Qt.RightDockWidgetArea)
widgetOrderM, dockOrderM = self.createDock(OrderMonitor, '委托', QtCore.Qt.RightDockWidgetArea)
widgetUTOrderM, dockUTOrderM = self.createDock(UTOrderMonitor, '未成交委托', QtCore.Qt.RightDockWidgetArea)
widgetPositionM, dockPositionM = self.createDock(PositionMonitor, '持仓', QtCore.Qt.BottomDockWidgetArea)
widgetAccountM, dockAccountM = self.createDock(AccountMonitor, '账户', QtCore.Qt.BottomDockWidgetArea)
widgetTradingW, dockTradingW = self.createDock(TradingWidget, '交易', QtCore.Qt.LeftDockWidgetArea)
self.tabifyDockWidget(dockMarketM, dockContractM)
self.tabifyDockWidget(dockLogM, dockErrorM)
self.tabifyDockWidget(dockTradeM, dockUTOrderM)
self.tabifyDockWidget(dockUTOrderM, dockOrderM)
self.tabifyDockWidget(dockPositionM, dockAccountM)
dockLogM.raise_()
dockPositionM.raise_()
dockUTOrderM.raise_()
# 连接组件之间的信号
widgetPositionM.itemDoubleClicked.connect(widgetTradingW.closePosition)
def initMenu(self):
"""初始化菜单"""
# 创建操作
connectCtpQuoteAction = QtWidgets.QAction(u'连接CTP行情', self)
connectCtpQuoteAction.triggered.connect(self.connectCtpQuote)
connectCtpAction = QtWidgets.QAction(u'连接账户', self)
connectCtpAction.triggered.connect(self.connectCtp)
'''
connectLtsAction = QtWidgets.QAction(u'连接LTS', self)
connectLtsAction.triggered.connect(self.connectLts)
connectKsotpAction = QtWidgets.QAction(u'连接金仕达期权', self)
connectKsotpAction.triggered.connect(self.connectKsotp)
connectFemasAction = QtWidgets.QAction(u'连接飞马', self)
connectFemasAction.triggered.connect(self.connectFemas)
connectXspeedAction = QtWidgets.QAction(u'连接飞创', self)
connectXspeedAction.triggered.connect(self.connectXspeed)
connectKsgoldAction = QtWidgets.QAction(u'连接金仕达黄金', self)
connectKsgoldAction.triggered.connect(self.connectKsgold)
connectSgitAction = QtWidgets.QAction(u'连接飞鼠', self)
connectSgitAction.triggered.connect(self.connectSgit)
connectWindAction = QtWidgets.QAction(u'连接Wind', self)
connectWindAction.triggered.connect(self.connectWind)
connectIbAction = QtWidgets.QAction(u'连接IB', self)
connectIbAction.triggered.connect(self.connectIb)
connectOandaAction = QtWidgets.QAction(u'连接OANDA', self)
connectOandaAction.triggered.connect(self.connectOanda)
connectOkcoinAction = QtWidgets.QAction(u'连接OKCOIN', self)
connectOkcoinAction.triggered.connect(self.connectOkcoin)
'''
connectDbAction = QtWidgets.QAction(u'连接数据库', self)
connectDbAction.triggered.connect(self.mainEngine.dbConnect)
testAction = QtWidgets.QAction(u'测试', self)
testAction.triggered.connect(self.test)
exitAction = QtWidgets.QAction(u'退出', self)
exitAction.triggered.connect(self.close)
aboutAction = QtWidgets.QAction(u'关于', self)
aboutAction.triggered.connect(self.openAbout)
contractAction = QtWidgets.QAction(u'查询合约', self)
contractAction.triggered.connect(self.openContract)
drAction = QtWidgets.QAction(u'行情数据记录', self)
drAction.triggered.connect(self.openDr)
ctaAction = QtWidgets.QAction(u'CTA策略', self)
ctaAction.triggered.connect(self.openCta)
rmAction = QtWidgets.QAction(u'风险管理', self)
rmAction.triggered.connect(self.openRm)
qryAccountAction = QtWidgets.QAction('账户查询', self)
qryAccountAction.triggered.connect(self.qryAccount)
qryInvestorPositionAction = QtWidgets.QAction('持仓查询', self)
qryInvestorPositionAction.triggered.connect(self.qryInvestorPosition)
# 创建菜单
menubar = self.menuBar()
# 设计为只显示存在的接口
sysMenu = menubar.addMenu(u'系统')
if 'CTPTrade' in self.mainEngine.gatewayDict:
sysMenu.addAction(connectCtpAction)
if 'CTPQuote' in self.quoteEngine.gatewayDict:
sysMenu.addAction(connectCtpQuoteAction)
# if 'LTS' in self.mainEngine.gatewayDict:
# sysMenu.addAction(connectLtsAction)
# if 'FEMAS' in self.mainEngine.gatewayDict:
# sysMenu.addAction(connectFemasAction)
# if 'XSPEED' in self.mainEngine.gatewayDict:
# sysMenu.addAction(connectXspeedAction)
# if 'KSOTP' in self.mainEngine.gatewayDict:
# sysMenu.addAction(connectKsotpAction)
# if 'KSGOLD' in self.mainEngine.gatewayDict:
# sysMenu.addAction(connectKsgoldAction)
# if 'SGIT' in self.mainEngine.gatewayDict:
# sysMenu.addAction(connectSgitAction)
# sysMenu.addSeparator()
# if 'IB' in self.mainEngine.gatewayDict:
# sysMenu.addAction(connectIbAction)
# if 'OANDA' in self.mainEngine.gatewayDict:
# sysMenu.addAction(connectOandaAction)
# if 'OKCOIN' in self.mainEngine.gatewayDict:
# sysMenu.addAction(connectOkcoinAction)
# sysMenu.addSeparator()
# if 'Wind' in self.mainEngine.gatewayDict:
# sysMenu.addAction(connectWindAction)
sysMenu.addSeparator()
sysMenu.addAction(connectDbAction)
sysMenu.addSeparator()
sysMenu.addAction(exitAction)
functionMenu = menubar.addMenu('功能')
functionMenu.addAction(contractAction)
functionMenu.addAction(drAction)
functionMenu.addAction(rmAction)
functionMenu.addSeparator()
functionMenu.addAction(qryAccountAction)
functionMenu.addAction(qryInvestorPositionAction)
# 算法相关
algoMenu = menubar.addMenu('策略')
algoMenu.addAction(ctaAction)
# 帮助
helpMenu = menubar.addMenu('帮助')
helpMenu.addAction(aboutAction)
helpMenu.addAction(testAction)
def initStatusBar(self):
"""初始化状态栏"""
self.statusLabel = QtWidgets.QLabel()
self.statusLabel.setAlignment(QtCore.Qt.AlignLeft)
self.statusBar().addPermanentWidget(self.statusLabel)
self.statusLabel.setText(self.getCpuMemory())
self.sbCount = 0
self.sbTrigger = 10 # 10秒刷新一次
self.signalStatusBar.connect(self.updateStatusBar)
self.eventEngine.register(EVENT_TIMER, self.signalStatusBar.emit)
def updateStatusBar(self, event):
"""在状态栏更新CPU和内存信息"""
self.sbCount += 1
if self.sbCount == self.sbTrigger:
self.sbCount = 0
self.statusLabel.setText(self.getCpuMemory())
def getCpuMemory(self):
"""获取CPU和内存状态信息"""
cpuPercent = psutil.cpu_percent()
memoryPercent = psutil.virtual_memory().percent
return u'CPU使用率:%d%% 内存使用率:%d%%' % (cpuPercent, memoryPercent)
def connectCtp(self):
"""连接CTP接口"""
self.mainEngine.connect('CTPTrade')
def connectCtpQuote(self):
"""连接CTP行情接口"""
self.quoteEngine.connect('CTPQuote')
def test(self):
"""测试按钮用的函数"""
# 有需要使用手动触发的测试函数可以写在这里
pass
#--------------------------------------------------------------------
def qryAccount(self):
self.mainEngine.gatewayDict['CTPTrade'].qryAccount()
#--------------------------------------------------------------------
def qryInvestorPosition(self):
self.mainEngine.gatewayDict['CTPTrade'].qryPosition()
#--------------------------------------------------------------------
def openAbout(self):
"""打开关于"""
try:
self.widgetDict['aboutW'].show()
except KeyError:
self.widgetDict['aboutW'] = AboutWidget(self)
self.widgetDict['aboutW'].show()
def openContract(self):
"""打开合约查询"""
self.mainEngine.gatewayDict['CTPTrade'].qryInstrument()
time.sleep(5)
try:
self.widgetDict['contractM'].show()
except KeyError:
self.widgetDict['contractM'] = ContractMonitor(self.mainEngine,self.eventEngine)
self.widgetDict['contractM'].show()
def openCta(self):
"""打开CTA组件"""
try:
self.widgetDict['ctaM'].showMaximized()
except KeyError:
self.widgetDict['ctaM'] = CtaEngineManager(self.mainEngine.ctaEngine, self.eventEngine)
self.widgetDict['ctaM'].showMaximized()
def openDr(self):
"""打开行情数据记录组件"""
try:
self.widgetDict['drM'].showMaximized()
except KeyError:
self.widgetDict['drM'] = DrEngineManager(self.quoteEngine.drEngine, self.quoteEventEngine)
self.widgetDict['drM'].showMaximized()
def openRm(self):
"""打开组件"""
try:
self.widgetDict['rmM'].show()
except KeyError:
self.widgetDict['rmM'] = RmEngineManager(self.mainEngine.rmEngine, self.eventEngine)
self.widgetDict['rmM'].show()
def closeEvent(self, event):
"""关闭事件"""
reply = QtWidgets.QMessageBox.question(self, '退出',
'确认退出?', QtWidgets.QMessageBox.Yes |
QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
for widget in self.widgetDict.values():
widget.close()
self.saveWindowSettings()
self.mainEngine.exit()
self.quoteEngine.exit()
event.accept()
else:
event.ignore()
def createDock(self, widgetClass, widgetName, widgetArea):
"""创建停靠组件"""
widget = widgetClass(self.mainEngine, self.eventEngine)
dock = QtWidgets.QDockWidget(widgetName)
dock.setWidget(widget)
dock.setObjectName(widgetName)
dock.setFeatures(dock.DockWidgetFloatable|dock.DockWidgetMovable)
self.addDockWidget(widgetArea, dock)
return widget, dock
def createMarketMonitor(self, widgetClass, widgetName, widgetArea):
"""创建停靠组件"""
widget = widgetClass(self.quoteEngine, self.quoteEventEngine)
# widget = widgetClass(self.quoteEngine, self.quoteEventEngine)
dock = QtWidgets.QDockWidget(widgetName)
dock.setWidget(widget)
dock.setObjectName(widgetName)
dock.setFeatures(dock.DockWidgetFloatable|dock.DockWidgetMovable)
self.addDockWidget(widgetArea, dock)
return widget, dock
def saveWindowSettings(self):
"""保存窗口设置"""
settings = QtCore.QSettings('vn.py', 'vn.trader')
settings.setValue('state', self.saveState())
settings.setValue('geometry', self.saveGeometry())
def loadWindowSettings(self):
"""载入窗口设置"""
settings = QtCore.QSettings('vn.py', 'vn.trader')
# 这里由于PyQt4的版本不同,settings.value('state')调用返回的结果可能是:
# 1. None(初次调用,注册表里无相应记录,因此为空)
# 2. QByteArray(比较新的PyQt4)
# 3. QVariant(以下代码正确执行所需的返回结果)
# 所以为了兼容考虑,这里加了一个try...except,如果是1、2的情况就pass
# 可能导致主界面的设置无法载入(每次退出时的保存其实是成功了)
try:
self.restoreState(settings.value('state').toByteArray())
self.restoreGeometry(settings.value('geometry').toByteArray())
except AttributeError:
pass
class AboutWidget(QtWidgets.QDialog):
"""显示关于信息"""
def __init__(self, parent=None):
"""Constructor"""
super(AboutWidget, self).__init__(parent)
self.initUi()
def initUi(self):
""""""
self.setWindowTitle(u'关于VnTrader')
text = u"""
Developed by traders, for traders.
License:MIT
Website:www.vnpy.org
Github:www.github.com/vnpy/vnpy
"""
label = QtWidgets.QLabel()
label.setText(text)
label.setMinimumWidth(500)
vbox = QtWidgets.QVBoxLayout()
vbox.addWidget(label)
self.setLayout(vbox)