Exemple #1
0
class AlgoLogMonitor(QtWidgets.QTextEdit):
    """"""
    signal = QtCore.Signal(type(Event()))

    #----------------------------------------------------------------------
    def __init__(self, algoEngine):
        """Constructor"""
        super(AlgoLogMonitor, self).__init__()
        
        self.eventEngine = algoEngine.eventEngine
        
        self.registerEvent()
        
    #----------------------------------------------------------------------
    def registerEvent(self):
        """"""
        self.signal.connect(self.processEvent)
        
        self.eventEngine.register(EVENT_ALGO_LOG, self.signal.emit)
        
    #----------------------------------------------------------------------
    def processEvent(self, event):
        """"""
        log = event.dict_['data']
        if not log.gatewayName:
            log.gatewayName = u'算法引擎'
        msg = u'%s\t%s:%s' %(log.logTime, log.gatewayName, log.logContent)
        self.append(msg)
class StLogMonitor(QtWidgets.QTextEdit):
    """价差日志监控"""
    signal = QtCore.Signal(type(Event()))

    #----------------------------------------------------------------------
    def __init__(self, mainEngine, eventEngine, parent=None):
        """Constructor"""
        super(StLogMonitor, self).__init__(parent)

        self.eventEngine = eventEngine

        self.registerEvent()

    #----------------------------------------------------------------------
    def processLogEvent(self, event):
        """处理日志事件"""
        log = event.dict_['data']
        content = '%s:%s' % (log.logTime, log.logContent)
        self.append(content)

    #----------------------------------------------------------------------
    def registerEvent(self):
        """注册事件监听"""
        self.signal.connect(self.processLogEvent)

        self.eventEngine.register(EVENT_SPREADTRADING_LOG, self.signal.emit)
class StActiveButton(QtWidgets.QPushButton):
    """"""
    signalActive = QtCore.Signal(bool)

    #----------------------------------------------------------------------
    def __init__(self, algoEngine, spreadName, parent=None):
        """Constructor"""
        super(StActiveButton, self).__init__(parent)

        self.algoEngine = algoEngine
        self.spreadName = spreadName

        self.active = False
        self.setStopped()

        self.clicked.connect(self.buttonClicked)

    #----------------------------------------------------------------------
    def buttonClicked(self):
        """改变运行模式"""
        if self.active:
            self.stop()
        else:
            self.start()

    #----------------------------------------------------------------------
    def stop(self):
        """停止"""
        algoActive = self.algoEngine.stopAlgo(self.spreadName)
        if not algoActive:
            self.setStopped()

    #----------------------------------------------------------------------
    def start(self):
        """启动"""
        algoActive = self.algoEngine.startAlgo(self.spreadName)
        if algoActive:
            self.setStarted()

    #----------------------------------------------------------------------
    def setStarted(self):
        """算法启动"""
        self.setText(u'运行中')
        self.setStyleSheet(STYLESHEET_START)

        self.active = True
        self.signalActive.emit(self.active)

    #----------------------------------------------------------------------
    def setStopped(self):
        """算法停止"""
        self.setText(u'已停止')
        self.setStyleSheet(STYLESHEET_STOP)

        self.active = False
        self.signalActive.emit(self.active)
Exemple #4
0
class LogMonitor(BasicMonitor):
    """日志监控"""
    signalError = QtCore.Signal(type(Event()))

    #----------------------------------------------------------------------
    def __init__(self, mainEngine, eventEngine, parent=None):
        """Constructor"""
        super(LogMonitor, self).__init__(mainEngine, eventEngine, parent)

        d = OrderedDict()
        d['gatewayName'] = {'chinese': vtText.GATEWAY, 'cellType': BasicCell}
        d['logTime'] = {'chinese': vtText.TIME, 'cellType': BasicCell}
        d['logContent'] = {'chinese': vtText.CONTENT, 'cellType': BasicCell}
        self.setHeaderDict(d)

        self.setEventType(EVENT_LOG)
        self.setFont(BASIC_FONT)
        self.initTable()
        self.registerEvent()

        self.signalError.connect(self.processErrorEvent)
        self.eventEngine.register(EVENT_ERROR, self.signalError.emit)

        # self.horizontalHeader().setResizeMode(2, QtWidgets.QHeaderView.Stretch)
        self.horizontalHeader().setSectionResizeMode(
            2, QtWidgets.QHeaderView.Stretch)
        self.setFixedHeight(200)

    #----------------------------------------------------------------------
    def processErrorEvent(self, event):
        """"""
        error = event.dict_['data']
        logContent = u'发生错误,错误代码:%s,错误信息:%s' % (error.errorID, error.errorMsg)

        self.insertRow(0)
        cellLogTime = BasicCell(error.errorTime)
        cellLogContent = BasicCell(logContent)
        cellGatewayName = BasicCell(error.gatewayName)

        self.setItem(0, 0, cellGatewayName)
        self.setItem(0, 1, cellLogTime)
        self.setItem(0, 2, cellLogContent)
Exemple #5
0
class RtdManager(QtWidgets.QWidget):
    """RTD管理工具"""

    signal = QtCore.Signal(type(Event()))

    #----------------------------------------------------------------------
    def __init__(self, rsEngine, eventEngine, parent=None):
        """Constructor"""
        super(RtdManager, self).__init__(parent)

        self.rsEngine = rsEngine
        self.eventEngine = eventEngine

        self.initUi()
        self.registerEvent()

    #----------------------------------------------------------------------
    def registerEvent(self):
        """注册事件监听"""
        self.signal.connect(self.updateLog)

        self.eventEngine.register(EVENT_RTDSERVICE_LOG, self.signal.emit)

    #----------------------------------------------------------------------
    def initUi(self):
        """初始化界面"""
        self.setWindowTitle(u'RTD服务')

        self.logMonitor = QtWidgets.QTextBrowser()

        vbox = QtWidgets.QVBoxLayout()
        vbox.addWidget(self.logMonitor)

        self.setLayout(vbox)

    #----------------------------------------------------------------------
    def updateLog(self, event):
        """输出日志"""
        log = event.dict_['data']
        content = log.logTime + "\t" + log.logContent + '\n'
        self.logMonitor.append(content)
Exemple #6
0
class JsEngineManager(QtWidgets.QWidget):
    """Jaqs服务管理组件"""
    signal = QtCore.Signal(type(Event()))

    #----------------------------------------------------------------------
    def __init__(self, jsEngine, eventEngine, parent=None):
        """Constructor"""
        super(JsEngineManager, self).__init__(parent)

        self.jsEngine = jsEngine
        self.eventEngine = eventEngine

        self.initUi()
        self.registerEvent()

    #----------------------------------------------------------------------
    def initUi(self):
        """初始化界面"""
        self.setWindowTitle('Jaqs服务')
        # 日志监控
        self.logMonitor = QtWidgets.QTextEdit()
        self.logMonitor.setReadOnly(True)
        self.logMonitor.setMinimumHeight(600)

        # 设置布局
        vbox = QtWidgets.QVBoxLayout()
        vbox.addWidget(self.logMonitor)
        self.setLayout(vbox)

    #----------------------------------------------------------------------
    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_JS_LOG, self.signal.emit)
Exemple #7
0
class RqDataManager(QtWidgets.QWidget):
    """"""
    signal = QtCore.Signal(str)

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        super(RqDataManager, self).__init__()

        self.client = None
        self.rq = None
        self.thread = Thread(target=self.run)

        self.productList = []
        self.symbolExchangeDict = OrderedDict()

        self.initUi()

        n1 = self.connectMongo()
        if not n1:
            return

        n2 = self.initRqData()
        if not n2:
            return

        self.count = 0
        self.active = True
        self.thread.start()

    #----------------------------------------------------------------------
    def connectMongo(self):
        """连接数据库"""
        try:
            self.client = MongoClient(serverSelectionTimeoutMS=10)
            self.client.server_info()
            self.writeLog(u'MongoDB连接成功')
            return True
        except ConnectionFailure:
            self.client = None
            self.writeLog(u'MongoDB连接失败')
            return False

    #----------------------------------------------------------------------
    def initUi(self):
        """初始化界面"""
        self.setWindowTitle(u'RQData数据服务')
        self.setWindowIcon(QtGui.QIcon('vnpy.ico'))

        self.setFixedHeight(500)
        self.setFixedWidth(900)

        self.logMonitor = QtWidgets.QTextEdit()
        self.logMonitor.setReadOnly(True)

        vbox = QtWidgets.QVBoxLayout()
        vbox.addWidget(self.logMonitor)
        self.setLayout(vbox)

        self.signal.connect(self.updateLog)

        # 托盘配置
        self.tray = QtWidgets.QSystemTrayIcon()
        self.tray.setIcon(QtGui.QIcon('vnpy.ico'))
        self.tray.activated.connect(self.showManager)

        restoreAction = QtWidgets.QAction(u'还原', self, triggered=self.show)
        quitAction = QtWidgets.QAction(u'退出', self, triggered=self.exit)

        menu = QtWidgets.QMenu(QtWidgets.QApplication.desktop())
        menu.addAction(restoreAction)
        menu.addAction(quitAction)
        self.tray.setContextMenu(menu)

        self.tray.show()

    #----------------------------------------------------------------------
    def initRqData(self):
        """"""
        with open('config.json') as config:
            setting = json.load(config)

            for product in setting['product']:
                self.productList.append(product.upper())

        # 检查是否填写了RQData配置
        username = setting.get('rqUsername', None)
        password = setting.get('rqPassword', None)
        if not username or not password:
            self.writeLog(u'RQData的用户名和密码配置错误,请在config.json中修改')
            return False

        # 加载RQData
        try:
            import rqdatac as rq
        except ImportError:
            self.writeLog(u'没有安装RQData客户端,请先安装rqdatac')
            return False

        # 登录RQData
        self.rq = rq
        self.rq.init(username, password)

        # 获取本日可交易合约代码
        try:
            df = self.rq.all_instruments(type='Future', date=datetime.now())
            for ix, row in df.iterrows():
                self.symbolExchangeDict[row['order_book_id']] = row['exchange']
        except RuntimeError:
            self.writeLog(u'RQData的用户名和密码无效,请联系米筐申请试用或者购买')
            return False

        self.writeLog(u'RQData客户端登录成功')
        return True

    #----------------------------------------------------------------------
    def downloadBar(self, symbol, frequency):
        """下载合约数据"""
        if 'frequency' == '1m':
            db = self.client[MINUTE_DB_NAME]
        else:
            db = self.client[DAILY_DB_NAME]

        # 上期所和大商所代码改为小写
        exchange = self.symbolExchangeDict[symbol]
        if exchange in ['SHFE', 'DCE']:
            localSymbol = symbol.lower()
        else:
            localSymbol = symbol
        collection = db[localSymbol]

        # 获取本地数据库中最后一条记录的时间,并下载新数据
        result = collection.find_one(sort=[("datetime", DESCENDING)])
        if result:
            startDate = result['datetime']
        else:
            startDate = '20180101'

        if startDate:
            self.writeLog(u'%s下载更新数据,开始时间:%s' % (localSymbol, startDate))
        else:
            self.writeLog(u'%s初次下载数据,耗时可能较长,请耐心等待' % (localSymbol))

        df = self.rq.get_price(
            symbol,
            frequency=frequency,
            fields=['open', 'high', 'low', 'close', 'volume'],
            start_date=startDate,
            end_date=datetime.now())

        # 插入到数据库
        for ix, row in df.iterrows():
            bar = self.generateBar(row, localSymbol)
            d = bar.__dict__
            flt = {'datetime': bar.datetime}
            collection.replace_one(flt, d, True)

        self.writeLog(u'%s数据更新完成:%s - %s' %
                      (localSymbol, df.index[0], df.index[-1]))

    #----------------------------------------------------------------------
    def generateBar(self, row, symbol):
        """生成K线对象"""
        bar = VtBarData()

        bar.symbol = symbol
        bar.vtSymbol = symbol
        bar.open = row['open']
        bar.high = row['high']
        bar.low = row['low']
        bar.close = row['close']
        bar.volume = row['volume']
        bar.datetime = row.name
        bar.date = bar.datetime.strftime("%Y%m%d")
        bar.time = bar.datetime.strftime("%H:%M:%S")

        return bar

    #----------------------------------------------------------------------
    def writeLog(self, msg):
        """记录日志"""
        self.signal.emit(msg)

    #----------------------------------------------------------------------
    def updateLog(self, msg):
        """更新日志"""
        dt = datetime.now()
        msg = '%s:    %s' % (dt, msg)
        self.logMonitor.append(msg)

    #----------------------------------------------------------------------
    def run(self):
        """运行"""
        while self.active:
            sleep(1)

            self.count += 1
            if self.count < 10:
                continue
            self.count = 0

            now = datetime.now().time()
            if ((DAY_START <= now <= DAY_END) or (now >= NIGHT_START)
                    or (now <= NIGHT_END)):
                for symbol in self.symbolExchangeDict.keys():
                    download = False
                    for product in self.productList:
                        if product in symbol:
                            download = True

                    if download:
                        self.downloadBar(symbol, '1m')
            else:
                self.writeLog(u'非交易时间段,不执行更新')

    #----------------------------------------------------------------------
    def showManager(self, reason):
        """"""
        self.show()

    #----------------------------------------------------------------------
    def closeEvent(self, event):
        """"""
        self.hide()
        event.ignore()

    #----------------------------------------------------------------------
    def exit(self):
        """"""
        self.active = False
        self.thread.join()

        QtWidgets.qApp.quit()
Exemple #8
0
class AlgoStatusMonitor(QtWidgets.QTableWidget):
    """算法状态监控"""
    signalParam = QtCore.Signal(type(Event()))
    signalVar = QtCore.Signal(type(Event()))
    
    MODE_WORKING = 'working'
    MODE_HISTORY = 'history'

    #----------------------------------------------------------------------
    def __init__(self, algoEngine, mode):
        """Constructor"""
        super(AlgoStatusMonitor, self).__init__()
        
        self.algoEngine = algoEngine
        self.eventEngine = algoEngine.eventEngine
        self.mode = mode
        
        self.cellDict = {}
        
        self.initUi()
        self.registerEvent()
    
    #----------------------------------------------------------------------
    def initUi(self):
        """初始化界面"""
        labels = [u'',
                  u'名称',
                  u'参数',
                  u'变量']
        
        self.setColumnCount(len(labels))
        self.setHorizontalHeaderLabels(labels)
        self.setRowCount(0)
        self.verticalHeader().setVisible(False)
        self.setEditTriggers(self.NoEditTriggers)
        self.setAlternatingRowColors(True)
        
        if self.mode == self.MODE_HISTORY:
            self.hideColumn(0)

    #----------------------------------------------------------------------
    def registerEvent(self):
        """注册事件监听"""
        self.signalParam.connect(self.processParamEvent)
        self.signalVar.connect(self.processVarEvent)
        
        self.eventEngine.register(EVENT_ALGO_PARAM, self.signalParam.emit)
        self.eventEngine.register(EVENT_ALGO_VAR, self.signalVar.emit)
    
    #----------------------------------------------------------------------
    def addAlgo(self, algoName):
        """新增算法"""
        self.insertRow(0)
        
        buttonStop = StopButton(self.algoEngine, algoName)
        cellName = AlgoCell(algoName)
        cellParam = AlgoCell()
        cellVar = AlgoCell()
        
        self.setCellWidget(0, 0, buttonStop)
        self.setItem(0, 1, cellName)
        self.setItem(0, 2, cellParam)
        self.setItem(0, 3, cellVar)
        
        self.cellDict[algoName] = {
            'param': cellParam,
            'var': cellVar,
            'button': buttonStop
        }
        
        if self.mode == self.MODE_HISTORY:
            self.hideRow(0)
        
    #----------------------------------------------------------------------
    def processParamEvent(self, event):
        """处理参数事件"""
        d = event.dict_['data']
        
        algoName = d['algoName']
        if algoName not in self.cellDict:
            self.addAlgo(algoName)
        
        text = self.generateText(d)
        cell = self.cellDict[algoName]['param']
        cell.setText(text)

        self.resizeColumnsToContents()
        
    #----------------------------------------------------------------------
    def processVarEvent(self, event):
        """处理变量事件"""
        d = event.dict_['data']
        
        algoName = d['algoName']
        if algoName not in self.cellDict:
            self.addAlgo(algoName)
            
        if 'active' in d:
            active = d['active']
            
            # 若算法已经结束
            if not active:
                # 禁用按钮
                cells = self.cellDict[algoName]
                button = cells['button']
                button.disable()
                
                # 根据模式决定显示或者隐藏该行
                cell = cells['var']
                row = self.row(cell)
                if self.mode == self.MODE_WORKING:
                    self.hideRow(row)
                else:
                    self.showRow(row)
        
        text = self.generateText(d)
        cell = self.cellDict[algoName]['var']
        cell.setText(text)
        
        self.resizeColumnsToContents()
    
    #----------------------------------------------------------------------
    def generateText(self, d):
        """从字典生成字符串"""
        l = []
        for k, v in d.items():
            if k not in ['algoName']:
                msg = u'%s:%s' %(k, v)
                l.append(msg)
        text = ','.join(l)        
        return text
Exemple #9
0
class AlgoSettingMonitor(QtWidgets.QTableWidget):
    """"""
    signal = QtCore.Signal(type(Event()))

    #----------------------------------------------------------------------
    def __init__(self, algoEngine):
        """Constructor"""
        super(AlgoSettingMonitor, self).__init__()
        
        self.algoEngine = algoEngine
        self.eventEngine = algoEngine.eventEngine
        
        self.cellDict = {}
        
        self.initUi()
        self.registerEvent()
    
    #----------------------------------------------------------------------
    def initUi(self):
        """初始化界面"""
        labels = ['',
                  '',
                  u'名称',
                  u'算法',
                  u'参数']
        
        self.setColumnCount(len(labels))
        self.setHorizontalHeaderLabels(labels)
        self.setRowCount(0)
        self.verticalHeader().setVisible(False)
        self.setEditTriggers(self.NoEditTriggers)   

    #----------------------------------------------------------------------
    def registerEvent(self):
        """注册事件监听"""
        self.signal.connect(self.processEvent)
        
        self.eventEngine.register(EVENT_ALGO_SETTING, self.signal.emit)
    
    #----------------------------------------------------------------------
    def processEvent(self, event):
        """处理事件"""
        setting = event.dict_['data']
        settingName = setting['settingName']
        
        # 删除配置行
        if len(setting) == 1:
            d = self.cellDict.pop(settingName)
            cell = d['text']
            row = self.row(cell)
            self.removeRow(row)
        # 新增配置行
        elif settingName not in self.cellDict:
            self.insertRow(0)
        
            buttonStart = StartButton(self.algoEngine, setting)
            buttonDelete = DeleteButton(self.algoEngine, setting)
            cellSettingName = AlgoCell(settingName)
            cellTemplateName = AlgoCell(setting['templateName'])
            cellSettingText = AlgoCell(self.generateText(setting))
            
            self.setCellWidget(0, 0, buttonStart)
            self.setCellWidget(0, 1, buttonDelete)
            self.setItem(0, 2, cellSettingName)
            self.setItem(0, 3, cellTemplateName)
            self.setItem(0, 4, cellSettingText)
            
            self.cellDict[settingName] = {
                'start': buttonStart,
                'template': cellTemplateName,
                'text': cellSettingText,
                'delete': buttonDelete
            }
        # 更新已有配置行
        else:
            d = self.cellDict[settingName]
            d['start'].updateSetting(setting)
            d['template'].setText(setting['templateName'])
            d['text'].setText(self.generateText(setting))
            d['delete'].updateSetting(setting)
        
        self.resizeColumnsToContents()
    
    #----------------------------------------------------------------------
    def generateText(self, d):
        """从字典生成字符串"""
        l = []
        for k, v in d.items():
            if k not in ['settingName', 'templateName', '_id']:
                msg = u'%s:%s' %(k, v)
                l.append(msg)
        text = ','.join(l)
        return text
Exemple #10
0
class CustomMenu(QtWidgets.QPushButton):
    """合约管理组件"""
    signal = QtCore.Signal(type(Event()))

    # ----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        super(CustomMenu, self).__init__()
        self.parent = parent

        # self.initUi()
        self.initMenu()

    #-----------------------------------------------------------------------
    def initMenu(self):
        self.setStyleSheet(
            "QMenu{background:purple;}"
            "QMenu{border:1px solid lightgray;}"
            "QMenu{border-color:green;}"
            "QMenu::item{padding:0px 20px 0px 15px;}"
            "QMenu::item{height:30px;}"
            "QMenu::item{color:blue;}"
            "QMenu::item{background:white;}"
            "QMenu::item{margin:1px 0px 0px 0px;}"
            "QMenu::item:selected:enabled{background:lightgray;}"
            "QMenu::item:selected:enabled{color:blue;}"
            "QMenu::item:selected:!enabled{background:transparent;}"
            "QMenu::separator{height:50px;}"
            "QMenu::separator{width:1px;}"
            "QMenu::separator{background:white;}"
            "QMenu::separator{margin:1px 1px 1px 1px;}"
            "QMenu#menu{background:white;}"
            "QMenu#menu{border:1px solid lightgray;}"
            "QMenu#menu::item{padding:0px 20px 0px 15px;}"
            "QMenu#menu::item{height:15px;}"
            "QMenu#menu::item:selected:enabled{background:lightgray;}"
            "QMenu#menu::item:selected:enabled{color:white;}"
            "QMenu#menu::item:selected:!enabled{background:transparent;}"
            "QMenu#menu::separator{height:1px;}"
            "QMenu#menu::separator{background:lightgray;}"
            "QMenu#menu::separator{margin:2px 0px 2px 0px;}"
            "QMenu#menu::indicator {padding:5px;}")
        self.color = QColor(Qt.gray)
        self.opacity = 1.0
        '''''' ' 创建右键菜单 ' ''
        # 必须将ContextMenuPolicy设置为Qt.CustomContextMenu
        # 否则无法使用customContextMenuRequested信号
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.showContextMenu)

        # 创建QMenu
        self.contextMenu = QMenu(self)
        self.trendMenu = self.contextMenu.addMenu(u"k线形态")
        self.swingMenu = self.contextMenu.addMenu(u"技术指标")
        self.amountMenu = self.contextMenu.addMenu(u"策略研究")
        self.pzxzMenu = self.contextMenu.addMenu(u"品种选择")
        # 添加二级菜单

        #趋势分析指标
        self.actionSAR = self.trendMenu.addAction(u'k线')
        self.actionSAR.triggered.connect(
            lambda: self.parent.initIndicator(u"KLINE"))

        self.actionMA = self.trendMenu.addAction(u'信号隐藏')
        self.actionMA.triggered.connect(
            lambda: self.parent.initIndicator(u"信号隐藏"))

        self.actionMA = self.trendMenu.addAction(u'信号显示')
        self.actionMA.triggered.connect(
            lambda: self.parent.initIndicator(u"信号显示"))

        #摆动分析
        self.actionCCI = self.swingMenu.addAction(u'MA SHORT')
        self.actionCCI.triggered.connect(
            lambda: self.parent.initIndicator(u"MA SHORT"))
        self.actionROC = self.swingMenu.addAction(u'MA LONG')
        self.actionROC.triggered.connect(
            lambda: self.parent.initIndicator(u"MA LONG"))
        self.actionSHORTTERM = self.swingMenu.addAction(u'SHORT TERM(Limit)')
        self.actionSHORTTERM.triggered.connect(
            lambda: self.parent.initIndicator(u"SHORT TERM(Limit)"))
        self.actionSHORTTERMF = self.swingMenu.addAction(u'SHORT TERM(First)')
        self.actionSHORTTERMF.triggered.connect(
            lambda: self.parent.initIndicator(u"SHORT TERM(First)"))
        self.actionSHORTTERMALL = self.swingMenu.addAction(u'SHORT TERM(All)')
        self.actionSHORTTERMALL.triggered.connect(
            lambda: self.parent.initIndicator(u"SHORT TERM(All)"))
        self.actionWAIBAORI = self.swingMenu.addAction(u'外包日')
        self.actionWAIBAORI.triggered.connect(
            lambda: self.parent.initIndicator(u"外包日"))
        self.actionGJR_BUY = self.swingMenu.addAction(u'攻击日(买入)')
        self.actionGJR_BUY.triggered.connect(
            lambda: self.parent.initIndicator(u"攻击日(买入)"))
        self.actionGJR_SELL = self.swingMenu.addAction(u'攻击日(卖出)')
        self.actionGJR_SELL.triggered.connect(
            lambda: self.parent.initIndicator(u"攻击日(卖出)"))

        ##设为起始日期
        self.actionOPI = self.amountMenu.addAction(u'设为起始日期')
        self.actionOPI.triggered.connect(
            lambda: self.parent.initIndicator(u"设为起始日期"))

        self.actionOPI1 = self.amountMenu.addAction(u'设为结束日期')
        self.actionOPI1.triggered.connect(
            lambda: self.parent.initIndicator(u"设为结束日期"))

        ##量仓分析
        self.actionOPI2 = self.amountMenu.addAction(u'MA_螺纹空_PLUS')
        self.actionOPI2.triggered.connect(
            lambda: self.parent.initIndicator(u"MA_螺纹空_PLUS"))

        ##成交量分析
        self.actionVOL = self.amountMenu.addAction(u'SHORTTERM_螺纹_多')
        self.actionVOL.triggered.connect(
            lambda: self.parent.initIndicator(u"SHORTTERM_螺纹_多"))

        self.action1 = self.amountMenu.addAction(u'SHORTTERM_螺纹_空')
        self.action1.triggered.connect(
            lambda: self.parent.initIndicator(u"SHORTTERM_螺纹_空"))

        self.action2 = self.amountMenu.addAction(u'SHORTTERM_螺纹_多_加仓')
        self.action2.triggered.connect(
            lambda: self.parent.initIndicator(u"SHORTTERM_螺纹_多_加仓"))

        self.action5 = self.amountMenu.addAction(u'VOLATILITY_螺纹_多')
        self.action5.triggered.connect(
            lambda: self.parent.initIndicator(u"VOLATILITY_螺纹_多"))

        self.action6 = self.amountMenu.addAction(u'VOLATILITY_螺纹_空')
        self.action6.triggered.connect(
            lambda: self.parent.initIndicator(u"VOLATILITY_螺纹_空"))

        self.action9 = self.amountMenu.addAction(u'VOLATILITY_螺纹_V1')
        self.action9.triggered.connect(
            lambda: self.parent.initIndicator(u"VOLATILITY_螺纹_V1"))

        self.action7 = self.amountMenu.addAction(u'外包日_螺纹_多')
        self.action7.triggered.connect(
            lambda: self.parent.initIndicator(u"外包日_螺纹_多"))

        self.action3 = self.pzxzMenu.addAction(u'RB9999')
        self.action3.triggered.connect(
            lambda: self.parent.initIndicator(u"RB9999"))

        self.action4 = self.pzxzMenu.addAction(u'BU9999')
        self.action4.triggered.connect(
            lambda: self.parent.initIndicator(u"BU9999"))

        #self.contextMenu.exec_(QCursor.pos())  # 在鼠标位置显示
        #添加二级菜单

    def showContextMenu(self, pos):
        '''''
        右键点击时调用的函数
        '''
        # 菜单显示前,将它移动到鼠标点击的位置
        # self.contextMenu.move(self.pos() + pos)
        self.contextMenu.show()
        self.contextMenu.exec_(QCursor.pos())
Exemple #11
0
class TcManager(QtWidgets.QWidget):
    """"""
    REQ_ADDRESS = 'tcp://localhost:2015'
    SUB_ADDRESS = 'tcp://localhost:2018'   
    REP_ADDRESS = 'tcp://*:2015'
    PUB_ADDRESS = 'tcp://*:2018'
    COPY_RATIO = '1'
    INTERVAL = '1'
    
    settingFileName = 'TradeCopy.vt'
    settingFilePath = getTempPath(settingFileName)
    
    signal = QtCore.Signal(type(Event()))

    #----------------------------------------------------------------------
    def __init__(self, tcEngine, eventEngine, parent=None):
        """Constructor"""
        super(TcManager, self).__init__(parent)
        
        self.tcEngine = tcEngine
        self.eventEngine = eventEngine
        
        self.initUi()
        self.loadSetting()
        self.registerEvent()
        
        self.tcEngine.writeLog(u'欢迎使用TradeCopy交易复制模块')
    
    #----------------------------------------------------------------------
    def initUi(self):
        """"""
        self.setWindowTitle(u'交易复制')
        self.setMinimumWidth(700)
        self.setMinimumHeight(700)
        
        # 创建组件
        self.lineReqAddress = QtWidgets.QLineEdit(self.REQ_ADDRESS)
        self.lineSubAddress= QtWidgets.QLineEdit(self.SUB_ADDRESS)
        self.lineRepAddress = QtWidgets.QLineEdit(self.REP_ADDRESS)
        self.linePubAddress = QtWidgets.QLineEdit(self.PUB_ADDRESS)
        
        validator = QtGui.QDoubleValidator()
        validator.setBottom(0)
        self.lineCopyRatio = QtWidgets.QLineEdit()
        self.lineCopyRatio.setValidator(validator)
        self.lineCopyRatio.setText(self.COPY_RATIO)
        
        validator2 = QtGui.QIntValidator()
        validator2.setBottom(1)
        self.lineInterval = QtWidgets.QLineEdit()
        self.lineInterval.setValidator(validator2)
        self.lineInterval.setText(self.INTERVAL)
        
        self.buttonProvider = QtWidgets.QPushButton(u'启动发布者')
        self.buttonProvider.clicked.connect(self.startProvider)
        
        self.buttonSubscriber = QtWidgets.QPushButton(u'启动订阅者')
        self.buttonSubscriber.clicked.connect(self.startSubscriber)
        
        self.buttonStopEngine = QtWidgets.QPushButton(u'停止')
        self.buttonStopEngine.clicked.connect(self.stopEngine)
        self.buttonStopEngine.setEnabled(False)
        
        self.buttonResetAddress = QtWidgets.QPushButton(u'重置地址')
        self.buttonResetAddress.clicked.connect(self.resetAddress)
        
        self.logMonitor = QtWidgets.QTextEdit()
        self.logMonitor.setReadOnly(True)
        
        self.widgetList = [
            self.lineCopyRatio,
            self.lineInterval,
            self.linePubAddress,
            self.lineSubAddress,
            self.lineRepAddress,
            self.lineReqAddress,
            self.buttonProvider,
            self.buttonSubscriber,
            self.buttonResetAddress
        ]
        
        # 布局
        QLabel = QtWidgets.QLabel
        grid = QtWidgets.QGridLayout()
        
        grid.addWidget(QLabel(u'响应地址'), 0, 0)
        grid.addWidget(self.lineRepAddress, 0, 1)
        grid.addWidget(QLabel(u'请求地址'), 0, 2)
        grid.addWidget(self.lineReqAddress, 0, 3)
        
        grid.addWidget(QLabel(u'发布地址'), 1, 0)
        grid.addWidget(self.linePubAddress, 1, 1)
        grid.addWidget(QLabel(u'订阅地址'), 1, 2)
        grid.addWidget(self.lineSubAddress, 1, 3)
        
        grid.addWidget(QLabel(u'发布间隔(秒)'), 2, 0)
        grid.addWidget(self.lineInterval, 2, 1)
        grid.addWidget(QLabel(u'复制比例(倍)'), 2, 2)
        grid.addWidget(self.lineCopyRatio, 2, 3)
        
        grid.addWidget(self.buttonProvider, 3, 0, 1, 2)
        grid.addWidget(self.buttonSubscriber, 3, 2, 1, 2)
        grid.addWidget(self.buttonStopEngine, 4, 0, 1, 2)
        grid.addWidget(self.buttonResetAddress, 4, 2, 1, 2)
        
        grid.addWidget(self.logMonitor, 5, 0, 1, 4)
        
        self.setLayout(grid)
    
    #----------------------------------------------------------------------
    def saveSetting(self):
        """"""
        f = shelve.open(self.settingFilePath)
        f['repAddress'] = self.lineRepAddress.text()
        f['reqAddress'] = self.lineReqAddress.text()
        f['pubAddress'] = self.linePubAddress.text()
        f['subAddress'] = self.lineSubAddress.text()
        f['copyRatio'] = self.lineCopyRatio.text()
        f['interval'] = self.lineInterval.text()
        f.close()
    
    #----------------------------------------------------------------------
    def loadSetting(self):
        """"""
        f = shelve.open(self.settingFilePath)
        if f:
            self.lineRepAddress.setText(f['repAddress'])
            self.lineReqAddress.setText(f['reqAddress'])
            self.linePubAddress.setText(f['pubAddress'])
            self.lineSubAddress.setText(f['subAddress'])
            self.lineCopyRatio.setText(f['copyRatio'])
            self.lineInterval.setText(f['interval'])
        f.close()        
    
    #----------------------------------------------------------------------
    def resetAddress(self):
        """"""
        self.lineReqAddress.setText(self.REQ_ADDRESS)
        self.lineRepAddress.setText(self.REP_ADDRESS)
        self.linePubAddress.setText(self.PUB_ADDRESS)
        self.lineSubAddress.setText(self.SUB_ADDRESS)
    
    #----------------------------------------------------------------------
    def stopEngine(self):
        """"""
        self.tcEngine.stop()
        
        for widget in self.widgetList:
            widget.setEnabled(True)
        self.buttonStopEngine.setEnabled(False)

    #----------------------------------------------------------------------
    def registerEvent(self):
        """"""
        self.signal.connect(self.processLogEvent)
        self.eventEngine.register(EVENT_TC_LOG, self.signal.emit)
    
    #----------------------------------------------------------------------
    def processLogEvent(self, event):
        """"""
        log = event.dict_['data']
        txt = '%s:  %s' %(log.logTime, log.logContent)
        self.logMonitor.append(txt)
    
    #----------------------------------------------------------------------
    def startProvider(self):
        """"""
        repAddress = str(self.lineRepAddress.text())
        pubAddress = str(self.linePubAddress.text())
        interval = int(self.lineInterval.text())
        self.tcEngine.startProvider(repAddress, pubAddress, interval)
        
        for widget in self.widgetList:
            widget.setEnabled(False)
        self.buttonStopEngine.setEnabled(True)
        
    #----------------------------------------------------------------------
    def startSubscriber(self):
        """"""
        reqAddress = str(self.lineReqAddress.text())
        subAddress = str(self.lineSubAddress.text())
        copyRatio = float(self.lineCopyRatio.text())
        self.tcEngine.startSubscriber(reqAddress, subAddress, copyRatio)
    
        for widget in self.widgetList:
            widget.setEnabled(False)
        self.buttonStopEngine.setEnabled(True)
Exemple #12
0
class TradingWidget(QtWidgets.QFrame):
    """简单交易组件"""
    signal = QtCore.Signal(type(Event()))
    
    directionList = [DIRECTION_LONG,
                     DIRECTION_SHORT]

    offsetList = [OFFSET_OPEN,
                  OFFSET_CLOSE,
                  OFFSET_NONE]

    priceTypeList = [PRICETYPE_LIMITPRICE,
                     PRICETYPE_MARKETPRICE]
    
    gatewayList = ['']

    #----------------------------------------------------------------------
    def __init__(self, mainEngine, eventEngine, parent=None):
        """Constructor"""
        super(TradingWidget, self).__init__(parent)
        self.mainEngine = mainEngine
        self.eventEngine = eventEngine
        
        self.vtSymbol = ''
        
        # 添加交易接口
        l = mainEngine.getAllGatewayDetails()
        gatewayNameList = [d['gatewayName'] for d in l]
        self.gatewayList.extend(gatewayNameList)

        self.initUi()
        self.registerEvent()

    #----------------------------------------------------------------------
    def initUi(self):
        """初始化界面"""
        self.setWindowTitle(vtText.TRADING)
        self.setFixedHeight(400)
        self.setFixedWidth(600)
        self.setFrameShape(self.Box)    # 设置边框
        self.setLineWidth(1)           

        # 左边部分
        labelPriceType = QtWidgets.QLabel(vtText.PRICE_TYPE)
        labelSymbol = QtWidgets.QLabel(u'VT代码')
        labelPrice = QtWidgets.QLabel(vtText.PRICE)
        labelVolume = QtWidgets.QLabel(u'数量')
        labelOffset = QtWidgets.QLabel(vtText.OFFSET)
        
        self.comboPriceType = QtWidgets.QComboBox()
        self.comboPriceType.addItems(self.priceTypeList)
        
        self.lineSymbol = QtWidgets.QLineEdit()
        
        validator = QtGui.QDoubleValidator()
        validator.setBottom(0)        

        self.linePrice = QtWidgets.QLineEdit()
        self.linePrice.setValidator(validator)
        
        self.lineVolume = QtWidgets.QLineEdit()
        self.lineVolume.setValidator(validator)

        self.comboOffset = QtWidgets.QComboBox()
        self.comboOffset.addItems(self.offsetList)
        
        gridLeft = QtWidgets.QGridLayout()
        gridLeft.addWidget(labelPriceType, 0, 0)
        gridLeft.addWidget(labelSymbol, 1, 0)
        gridLeft.addWidget(labelPrice, 2, 0)
        gridLeft.addWidget(labelVolume, 3, 0)
        gridLeft.addWidget(labelOffset, 4, 0)
        
        gridLeft.addWidget(self.comboPriceType, 0, 1)
        gridLeft.addWidget(self.lineSymbol, 1, 1)
        gridLeft.addWidget(self.linePrice, 2, 1)
        gridLeft.addWidget(self.lineVolume, 3, 1)
        gridLeft.addWidget(self.comboOffset, 4, 1)
        
        # 右边部分
        self.depthMonitor = DepthMonitor(self.mainEngine, self.eventEngine)

        # 发单按钮
        buttonBuy = QtWidgets.QPushButton(u'买/多')
        buttonSell = QtWidgets.QPushButton(u'卖/空')
        buttonCancelAll = QtWidgets.QPushButton(vtText.CANCEL_ALL)
        
        size = buttonBuy.sizeHint()
        buttonBuy.setMinimumHeight(size.height()*2)
        buttonSell.setMinimumHeight(size.height()*2)
        buttonCancelAll.setMinimumHeight(size.height()*2)
        
        buttonBuy.clicked.connect(self.sendBuyOrder)
        buttonSell.clicked.connect(self.sendSellOrder)
        buttonCancelAll.clicked.connect(self.cancelAll)
        
        buttonBuy.setStyleSheet('color:white;background-color:red')
        buttonSell.setStyleSheet('color:white;background-color:green')
        buttonCancelAll.setStyleSheet('color:black;background-color:yellow')
        
        gridButton = QtWidgets.QGridLayout()
        gridButton.addWidget(buttonBuy, 0, 0)
        gridButton.addWidget(buttonSell, 0, 1)
        gridButton.addWidget(buttonCancelAll, 1, 0, 1, 2)
        
        # 整合布局
        vbox = QtWidgets.QVBoxLayout()
        vbox.addLayout(gridLeft)
        vbox.addLayout(gridButton)
        
        hbox = QtWidgets.QHBoxLayout()
        hbox.addLayout(vbox)
        hbox.addWidget(self.depthMonitor)
        
        self.setLayout(hbox)

        # 关联更新
        self.lineSymbol.returnPressed.connect(self.updateSymbol)
        self.depthMonitor.itemDoubleClicked.connect(self.updatePrice)

    #----------------------------------------------------------------------
    def updateSymbol(self):
        """合约变化"""
        self.vtSymbol = str(self.lineSymbol.text())
        contract = self.mainEngine.getContract(self.vtSymbol)
        
        if not contract:
            return
        
        # 清空价格数量
        self.linePrice.clear()
        self.lineVolume.clear()

        self.depthMonitor.updateVtSymbol(self.vtSymbol)
        
        # 订阅合约
        req = VtSubscribeReq()
        req.symbol = contract.symbol
        self.mainEngine.subscribe(req, contract.gatewayName)

    #----------------------------------------------------------------------
    def updateTick(self, event):
        """更新行情"""
        tick = event.dict_['data']
        if tick.vtSymbol != self.vtSymbol:
            return
        self.depthMonitor.updateTick(tick)

    #----------------------------------------------------------------------
    def registerEvent(self):
        """注册事件监听"""
        self.signal.connect(self.updateTick)
        self.eventEngine.register(EVENT_TICK, self.signal.emit)        
    
    #----------------------------------------------------------------------
    def updatePrice(self, cell):
        """"""
        try:
            price = cell.price
        except AttributeError:
            return
        self.linePrice.setText(str(price))

    #----------------------------------------------------------------------
    def sendOrder(self, direction):
        """发单"""
        vtSymbol = str(self.lineSymbol.text())
        contract = self.mainEngine.getContract(vtSymbol)
        if not contract:
            return

        # 获取价格
        priceText = self.linePrice.text()
        if not priceText:
            return
        price = float(priceText)
        
        # 获取数量
        volumeText = self.lineVolume.text()
        if not volumeText:
            return
        
        if '.' in volumeText:
            volume = float(volumeText)
        else:
            volume = int(volumeText)
        
        # 委托
        req = VtOrderReq()
        req.symbol = contract.symbol
        req.vtSymbol = ':'.join([contract.symbol,contract.gatewayName])
        req.price = price
        req.volume = volume
        req.direction = direction
        req.priceType = text_type(self.comboPriceType.currentText())
        req.offset = text_type(self.comboOffset.currentText())
        req.byStrategy = 'Manual'
        
        self.mainEngine.sendOrder(req, contract.gatewayName)
    
    #----------------------------------------------------------------------
    def sendBuyOrder(self):
        """"""
        self.sendOrder(DIRECTION_LONG)
        
    #----------------------------------------------------------------------
    def sendSellOrder(self):
        """"""
        self.sendOrder(DIRECTION_SHORT)
        
    #----------------------------------------------------------------------
    def cancelAll(self):
        """一键撤销所有委托"""
        l = self.mainEngine.getAllWorkingOrders()
        for order in l:
            req = VtCancelOrderReq()
            req.symbol = order.symbol
            req.exchange = order.exchange
            req.frontID = order.frontID
            req.sessionID = order.sessionID
            req.orderID = order.orderID
            self.mainEngine.cancelOrder(req, order.gatewayName)
Exemple #13
0
class WeixinEngineManager(QtWidgets.QWidget):
    """行情数据记录引擎管理组件"""
    signal = QtCore.Signal(type(Event()))

    #----------------------------------------------------------------------
    def __init__(self, drEngine, eventEngine, parent=None):
        """Constructor"""
        super(DrEngineManager, self).__init__(parent)

        self.drEngine = drEngine
        self.eventEngine = eventEngine

        self.initUi()
        self.updateSetting()
        self.registerEvent()

    #----------------------------------------------------------------------
    def initUi(self):
        """初始化界面"""
        self.setWindowTitle(text.DATA_RECORDER)

        # 记录合约配置监控
        tickLabel = QtWidgets.QLabel(text.TICK_RECORD)
        self.tickTable = QtWidgets.QTableWidget()
        self.tickTable.setColumnCount(2)
        self.tickTable.verticalHeader().setVisible(False)
        self.tickTable.setEditTriggers(QtWidgets.QTableWidget.NoEditTriggers)
        self.tickTable.setAlternatingRowColors(True)
        self.tickTable.setHorizontalHeaderLabels(
            [text.CONTRACT_SYMBOL, text.GATEWAY])

        barLabel = QtWidgets.QLabel(text.BAR_RECORD)
        self.barTable = QtWidgets.QTableWidget()
        self.barTable.setColumnCount(2)
        self.barTable.verticalHeader().setVisible(False)
        self.barTable.setEditTriggers(QtWidgets.QTableWidget.NoEditTriggers)
        self.barTable.setAlternatingRowColors(True)
        self.barTable.setHorizontalHeaderLabels(
            [text.CONTRACT_SYMBOL, text.GATEWAY])

        activeLabel = QtWidgets.QLabel(text.DOMINANT_CONTRACT)
        self.activeTable = QtWidgets.QTableWidget()
        self.activeTable.setColumnCount(2)
        self.activeTable.verticalHeader().setVisible(False)
        self.activeTable.setEditTriggers(QtWidgets.QTableWidget.NoEditTriggers)
        self.activeTable.setAlternatingRowColors(True)
        self.activeTable.setHorizontalHeaderLabels(
            [text.DOMINANT_SYMBOL, text.CONTRACT_SYMBOL])

        # 日志监控
        self.logMonitor = QtWidgets.QTextEdit()
        self.logMonitor.setReadOnly(True)
        self.logMonitor.setMinimumHeight(600)

        # 设置布局
        grid = QtWidgets.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)

        vbox = QtWidgets.QVBoxLayout()
        vbox.addLayout(grid)
        vbox.addWidget(self.logMonitor)
        self.setLayout(vbox)

    #----------------------------------------------------------------------
    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_ORDER, self.signal.emit)

    #----------------------------------------------------------------------
    def updateSetting(self):
        """显示引擎行情记录配置"""
        setting, activeSetting = self.drEngine.getSetting()

        for d in setting.values():
            if 'tick' in d and d['tick']:
                self.tickTable.insertRow(0)
                self.tickTable.setItem(0, 0, TableCell(d['symbol']))
                self.tickTable.setItem(0, 1, TableCell(d['gateway']))

            if 'bar' in d and d['bar']:
                self.barTable.insertRow(0)
                self.barTable.setItem(0, 0, TableCell(d['symbol']))
                self.barTable.setItem(0, 1, TableCell(d['gateway']))

        for vtSymbol, activeSymbol in activeSetting.items():
            self.activeTable.insertRow(0)
            self.activeTable.setItem(0, 0, TableCell(activeSymbol))
            self.activeTable.setItem(0, 1, TableCell(vtSymbol))

        self.tickTable.resizeColumnsToContents()
        self.barTable.resizeColumnsToContents()
        self.activeTable.resizeColumnsToContents()
Exemple #14
0
class CustomMenu(QtWidgets.QPushButton):
    """合约管理组件"""
    signal = QtCore.Signal(type(Event()))

    # ----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        super(CustomMenu, self).__init__()
        self.parent = parent

        # self.initUi()
        self.initMenu()

    #-----------------------------------------------------------------------
    def initMenu(self):
        self.setStyleSheet(
            "QMenu{background:purple;}"
            "QMenu{border:1px solid lightgray;}"
            "QMenu{border-color:green;}"
            "QMenu::item{padding:0px 20px 0px 15px;}"
            "QMenu::item{height:30px;}"
            "QMenu::item{color:blue;}"
            "QMenu::item{background:white;}"
            "QMenu::item{margin:1px 0px 0px 0px;}"
            "QMenu::item:selected:enabled{background:lightgray;}"
            "QMenu::item:selected:enabled{color:blue;}"
            "QMenu::item:selected:!enabled{background:transparent;}"
            "QMenu::separator{height:50px;}"
            "QMenu::separator{width:1px;}"
            "QMenu::separator{background:white;}"
            "QMenu::separator{margin:1px 1px 1px 1px;}"
            "QMenu#menu{background:white;}"
            "QMenu#menu{border:1px solid lightgray;}"
            "QMenu#menu::item{padding:0px 20px 0px 15px;}"
            "QMenu#menu::item{height:15px;}"
            "QMenu#menu::item:selected:enabled{background:lightgray;}"
            "QMenu#menu::item:selected:enabled{color:white;}"
            "QMenu#menu::item:selected:!enabled{background:transparent;}"
            "QMenu#menu::separator{height:1px;}"
            "QMenu#menu::separator{background:lightgray;}"
            "QMenu#menu::separator{margin:2px 0px 2px 0px;}"
            "QMenu#menu::indicator {padding:5px;}")
        self.color = QColor(Qt.gray)
        self.opacity = 1.0
        '''''' ' 创建右键菜单 ' ''
        # 必须将ContextMenuPolicy设置为Qt.CustomContextMenu
        # 否则无法使用customContextMenuRequested信号
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.showContextMenu)

        # 创建QMenu
        self.contextMenu = QMenu(self)
        self.trendMenu = self.contextMenu.addMenu(u"k线形态")
        self.swingMenu = self.contextMenu.addMenu(u"技术指标")
        self.amountMenu = self.contextMenu.addMenu(u"策略研究")
        # 添加二级菜单

        #趋势分析指标
        self.actionSAR = self.trendMenu.addAction(u'k线')
        self.actionSAR.triggered.connect(
            lambda: self.parent.initIndicator(u"KLINE"))

        self.actionMA = self.trendMenu.addAction(u'信号隐藏')
        self.actionMA.triggered.connect(
            lambda: self.parent.initIndicator(u"信号隐藏"))

        self.actionMA = self.trendMenu.addAction(u'信号显示')
        self.actionMA.triggered.connect(
            lambda: self.parent.initIndicator(u"信号显示"))

        #摆动分析
        self.actionCCI = self.swingMenu.addAction(u'MA SHORT')
        self.actionCCI.triggered.connect(
            lambda: self.parent.initIndicator(u"MA SHORT"))
        self.actionROC = self.swingMenu.addAction(u'MA LONG')
        self.actionROC.triggered.connect(
            lambda: self.parent.initIndicator(u"MA LONG"))

        ##设为起始日期
        self.actionOPI = self.amountMenu.addAction(u'设为起始日期')
        self.actionOPI.triggered.connect(
            lambda: self.parent.initIndicator(u"设为起始日期"))

        ##量仓分析
        self.actionOPI = self.amountMenu.addAction(u'MA_螺纹多_PLUS')
        self.actionOPI.triggered.connect(
            lambda: self.parent.initIndicator(u"MA_螺纹多_PLUS"))

        ##成交量分析
        self.actionVOL = self.amountMenu.addAction(u'CJL')
        self.actionVOL.triggered.connect(
            lambda: self.parent.initIndicator(u"CJL"))

        #self.contextMenu.exec_(QCursor.pos())  # 在鼠标位置显示
        #添加二级菜单

    def showContextMenu(self, pos):
        '''''
        右键点击时调用的函数
        '''
        # 菜单显示前,将它移动到鼠标点击的位置
        # self.contextMenu.move(self.pos() + pos)
        self.contextMenu.show()
        self.contextMenu.exec_(QCursor.pos())
Exemple #15
0
class BasicMonitor(QtWidgets.QTableWidget):
    """
    基础监控
    
    headerDict中的值对应的字典格式如下
    {'chinese': u'中文名', 'cellType': BasicCell}
    
    """
    signal = QtCore.Signal(type(Event()))

    #----------------------------------------------------------------------
    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.columnResized = False

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

    #----------------------------------------------------------------------
    def registerEvent(self):
        """注册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)
                d = {}
                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
            # 否则如果已经存在,则直接更新相关单元格
            else:
                d = self.dataDict[key]
                for header in self.headerList:
                    content = safeUnicode(data.__getattribute__(header))
                    cell = d[header]
                    cell.setContent(content)

                    if self.saveData:  # 如果设置了保存数据对象,则进行对象保存
                        cell.data = data
        # 否则采用增量更新模式
        else:
            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)

        # 调整列宽
        if not self.columnResized:
            self.resizeColumns()
            self.columnResized = True

        # 重新打开排序
        if self.sorting:
            self.setSortingEnabled(True)

    #----------------------------------------------------------------------
    def resizeColumns(self):
        """调整各列的大小"""
        self.horizontalHeader().resizeSections(
            QtWidgets.QHeaderView.ResizeToContents)

    #----------------------------------------------------------------------
    def setSorting(self, sorting):
        """设置是否允许根据表头排序"""
        self.sorting = sorting

    #----------------------------------------------------------------------
    def saveToCsv(self):
        """保存表格内容到CSV文件"""
        # 先隐藏右键菜单
        self.menu.close()

        # 获取想要保存的文件名
        path = QtWidgets.QFileDialog.getSaveFileName(self, vtText.SAVE_DATA,
                                                     '', 'CSV(*.csv)')

        try:
            #if not path.isEmpty():
            if path:
                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 = []
                        for column in range(self.columnCount()):
                            item = self.item(row, column)
                            if item is not None:
                                rowdata.append(
                                    unicode(item.text()).encode('gbk'))
                            else:
                                rowdata.append('')
                        writer.writerow(rowdata)
        except IOError:
            pass

    #----------------------------------------------------------------------
    def initMenu(self):
        """初始化右键菜单"""
        self.menu = QtWidgets.QMenu(self)

        saveAction = QtWidgets.QAction(vtText.SAVE_DATA, self)
        saveAction.triggered.connect(self.saveToCsv)

        self.menu.addAction(saveAction)

    #----------------------------------------------------------------------
    def contextMenuEvent(self, event):
        """右键点击事件"""
        self.menu.popup(QtGui.QCursor.pos())
Exemple #16
0
class TradingWidget(QtWidgets.QFrame):
    """简单交易组件"""
    signal = QtCore.Signal(type(Event()))

    directionList = [DIRECTION_LONG, DIRECTION_SHORT]

    offsetList = [
        OFFSET_OPEN, OFFSET_CLOSE, OFFSET_CLOSEYESTERDAY, OFFSET_CLOSETODAY
    ]

    priceTypeList = [
        PRICETYPE_LIMITPRICE, PRICETYPE_MARKETPRICE, PRICETYPE_FAK,
        PRICETYPE_FOK
    ]

    exchangeList = [
        EXCHANGE_NONE, EXCHANGE_CFFEX, EXCHANGE_SHFE, EXCHANGE_DCE,
        EXCHANGE_CZCE, EXCHANGE_SSE, EXCHANGE_SZSE, EXCHANGE_SGE,
        EXCHANGE_HKEX, EXCHANGE_HKFE, EXCHANGE_SMART, EXCHANGE_ICE,
        EXCHANGE_CME, EXCHANGE_NYMEX, EXCHANGE_LME, 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 = ['']

    #----------------------------------------------------------------------
    def __init__(self, mainEngine, eventEngine, parent=None):
        """Constructor"""
        super(TradingWidget, self).__init__(parent)
        self.mainEngine = mainEngine
        self.eventEngine = eventEngine

        self.symbol = ''

        # 添加交易接口
        l = mainEngine.getAllGatewayDetails()
        gatewayNameList = [d['gatewayName'] for d in l]
        self.gatewayList.extend(gatewayNameList)

        self.initUi()
        self.connectSignal()

    #----------------------------------------------------------------------
    def initUi(self):
        """初始化界面"""
        self.setWindowTitle(vtText.TRADING)
        self.setMaximumWidth(400)
        self.setFrameShape(self.Box)  # 设置边框
        self.setLineWidth(1)

        # 左边部分
        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 = QtWidgets.QLineEdit()
        self.lineName = QtWidgets.QLineEdit()

        self.comboDirection = QtWidgets.QComboBox()
        self.comboDirection.addItems(self.directionList)

        self.comboOffset = QtWidgets.QComboBox()
        self.comboOffset.addItems(self.offsetList)

        self.spinPrice = QtWidgets.QDoubleSpinBox()
        self.spinPrice.setDecimals(4)
        self.spinPrice.setMinimum(0)
        self.spinPrice.setMaximum(100000)

        self.spinVolume = QtWidgets.QSpinBox()
        self.spinVolume.setMinimum(0)
        self.spinVolume.setMaximum(1000000)

        self.comboPriceType = QtWidgets.QComboBox()
        self.comboPriceType.addItems(self.priceTypeList)

        self.comboExchange = QtWidgets.QComboBox()
        self.comboExchange.addItems(self.exchangeList)

        self.comboCurrency = QtWidgets.QComboBox()
        self.comboCurrency.addItems(self.currencyList)

        self.comboProductClass = QtWidgets.QComboBox()
        self.comboProductClass.addItems(self.productClassList)

        self.comboGateway = QtWidgets.QComboBox()
        self.comboGateway.addItems(self.gatewayList)

        gridleft = QtWidgets.QGridLayout()
        gridleft.addWidget(labelSymbol, 0, 0)
        gridleft.addWidget(labelName, 1, 0)
        gridleft.addWidget(labelDirection, 2, 0)
        gridleft.addWidget(labelOffset, 3, 0)
        gridleft.addWidget(labelPrice, 4, 0)
        gridleft.addWidget(labelVolume, 5, 0)
        gridleft.addWidget(labelPriceType, 6, 0)
        gridleft.addWidget(labelExchange, 7, 0)
        gridleft.addWidget(labelCurrency, 8, 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)
        gridleft.addWidget(self.comboOffset, 3, 1, 1, -1)
        gridleft.addWidget(self.checkFixed, 4, 1)
        gridleft.addWidget(self.spinPrice, 4, 2)
        gridleft.addWidget(self.spinVolume, 5, 1, 1, -1)
        gridleft.addWidget(self.comboPriceType, 6, 1, 1, -1)
        gridleft.addWidget(self.comboExchange, 7, 1, 1, -1)
        gridleft.addWidget(self.comboCurrency, 8, 1, 1, -1)
        gridleft.addWidget(self.comboProductClass, 9, 1, 1, -1)
        gridleft.addWidget(self.comboGateway, 10, 1, 1, -1)

        # 右边部分
        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 = 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 = 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 = 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 = QtWidgets.QLabel(vtText.LAST)
        self.labelLastPrice = QtWidgets.QLabel()
        self.labelReturn = QtWidgets.QLabel()

        self.labelLastPrice.setMinimumWidth(60)
        self.labelReturn.setMinimumWidth(60)

        gridRight = QtWidgets.QGridLayout()
        gridRight.addWidget(labelAsk5, 0, 0)
        gridRight.addWidget(labelAsk4, 1, 0)
        gridRight.addWidget(labelAsk3, 2, 0)
        gridRight.addWidget(labelAsk2, 3, 0)
        gridRight.addWidget(labelAsk1, 4, 0)
        gridRight.addWidget(labelLast, 5, 0)
        gridRight.addWidget(labelBid1, 6, 0)
        gridRight.addWidget(labelBid2, 7, 0)
        gridRight.addWidget(labelBid3, 8, 0)
        gridRight.addWidget(labelBid4, 9, 0)
        gridRight.addWidget(labelBid5, 10, 0)

        gridRight.addWidget(self.labelAskPrice5, 0, 1)
        gridRight.addWidget(self.labelAskPrice4, 1, 1)
        gridRight.addWidget(self.labelAskPrice3, 2, 1)
        gridRight.addWidget(self.labelAskPrice2, 3, 1)
        gridRight.addWidget(self.labelAskPrice1, 4, 1)
        gridRight.addWidget(self.labelLastPrice, 5, 1)
        gridRight.addWidget(self.labelBidPrice1, 6, 1)
        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.labelAskVolume5, 0, 2)
        gridRight.addWidget(self.labelAskVolume4, 1, 2)
        gridRight.addWidget(self.labelAskVolume3, 2, 2)
        gridRight.addWidget(self.labelAskVolume2, 3, 2)
        gridRight.addWidget(self.labelAskVolume1, 4, 2)
        gridRight.addWidget(self.labelReturn, 5, 2)
        gridRight.addWidget(self.labelBidVolume1, 6, 2)
        gridRight.addWidget(self.labelBidVolume2, 7, 2)
        gridRight.addWidget(self.labelBidVolume3, 8, 2)
        gridRight.addWidget(self.labelBidVolume4, 9, 2)
        gridRight.addWidget(self.labelBidVolume5, 10, 2)

        # 发单按钮
        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 = QtWidgets.QHBoxLayout()
        hbox.addLayout(gridleft)
        hbox.addLayout(gridRight)

        vbox = QtWidgets.QVBoxLayout()
        vbox.addLayout(hbox)
        vbox.addWidget(buttonSendOrder)
        vbox.addWidget(buttonCancelAll)
        vbox.addStretch()

        self.setLayout(vbox)

        # 关联更新
        buttonSendOrder.clicked.connect(self.sendOrder)
        buttonCancelAll.clicked.connect(self.cancelAll)
        self.lineSymbol.returnPressed.connect(self.updateSymbol)

    #----------------------------------------------------------------------
    def updateSymbol(self):
        """合约变化"""
        # 读取组件数据
        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())

        # 查询合约
        if exchange:
            vtSymbol = '.'.join([symbol, exchange])
            contract = self.mainEngine.getContract(vtSymbol)
        else:
            vtSymbol = 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)

        # 清空行情显示
        self.labelBidPrice1.setText('')
        self.labelBidPrice2.setText('')
        self.labelBidPrice3.setText('')
        self.labelBidPrice4.setText('')
        self.labelBidPrice5.setText('')
        self.labelBidVolume1.setText('')
        self.labelBidVolume2.setText('')
        self.labelBidVolume3.setText('')
        self.labelBidVolume4.setText('')
        self.labelBidVolume5.setText('')
        self.labelAskPrice1.setText('')
        self.labelAskPrice2.setText('')
        self.labelAskPrice3.setText('')
        self.labelAskPrice4.setText('')
        self.labelAskPrice5.setText('')
        self.labelAskVolume1.setText('')
        self.labelAskVolume2.setText('')
        self.labelAskVolume3.setText('')
        self.labelAskVolume4.setText('')
        self.labelAskVolume5.setText('')
        self.labelLastPrice.setText('')
        self.labelReturn.setText('')

        # 重新注册事件监听
        self.eventEngine.unregister(EVENT_TICK + self.symbol, self.signal.emit)
        self.eventEngine.register(EVENT_TICK + vtSymbol, self.signal.emit)

        # 订阅合约
        req = VtSubscribeReq()
        req.symbol = symbol
        req.exchange = exchange
        req.currency = currency
        req.productClass = productClass

        # 默认跟随价
        self.checkFixed.setChecked(False)

        self.mainEngine.subscribe(req, gatewayName)

        # 更新组件当前交易的合约
        self.symbol = vtSymbol

    #----------------------------------------------------------------------
    def updateTick(self, event):
        """更新行情"""
        tick = event.dict_['data']

        if tick.vtSymbol == self.symbol:
            if not self.checkFixed.isChecked():
                self.spinPrice.setValue(tick.lastPrice)
            self.labelBidPrice1.setText(str(tick.bidPrice1))
            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.labelLastPrice.setText(str(tick.lastPrice))

            if tick.preClosePrice:
                rt = (tick.lastPrice / tick.preClosePrice) - 1
                self.labelReturn.setText(('%.2f' % (rt * 100)) + '%')
            else:
                self.labelReturn.setText('')

    #----------------------------------------------------------------------
    def connectSignal(self):
        """连接Signal"""
        self.signal.connect(self.updateTick)

    #----------------------------------------------------------------------
    def sendOrder(self):
        """发单"""
        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())

        # 查询合约
        if exchange:
            vtSymbol = '.'.join([symbol, exchange])
            contract = self.mainEngine.getContract(vtSymbol)
        else:
            vtSymbol = symbol
            contract = self.mainEngine.getContract(vtSymbol)

        if contract:
            gatewayName = contract.gatewayName
            exchange = contract.exchange  # 保证有交易所代码

        req = VtOrderReq()
        req.symbol = symbol
        req.exchange = exchange
        req.price = self.spinPrice.value()
        req.volume = self.spinVolume.value()
        req.direction = unicode(self.comboDirection.currentText())
        req.priceType = unicode(self.comboPriceType.currentText())
        req.offset = unicode(self.comboOffset.currentText())
        req.currency = currency
        req.productClass = productClass

        self.mainEngine.sendOrder(req, gatewayName)

    #----------------------------------------------------------------------
    def cancelAll(self):
        """一键撤销所有委托"""
        l = self.mainEngine.getAllWorkingOrders()
        for order in l:
            req = VtCancelOrderReq()
            req.symbol = order.symbol
            req.exchange = order.exchange
            req.frontID = order.frontID
            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))
        self.spinVolume.setValue(pos.position)

        if pos.direction == DIRECTION_LONG or pos.direction == DIRECTION_NET:
            self.comboDirection.setCurrentIndex(
                self.directionList.index(DIRECTION_SHORT))
        else:
            self.comboDirection.setCurrentIndex(
                self.directionList.index(DIRECTION_LONG))
Exemple #17
0
class AlgoStatusMonitor(QtWidgets.QTableWidget):
    """"""
    signalParam = QtCore.Signal(type(Event()))
    signalVar = QtCore.Signal(type(Event()))

    #----------------------------------------------------------------------
    def __init__(self, algoEngine):
        """Constructor"""
        super(AlgoStatusMonitor, self).__init__()

        self.algoEngine = algoEngine
        self.eventEngine = algoEngine.eventEngine

        self.cellDict = {}

        self.initUi()
        self.registerEvent()

    #----------------------------------------------------------------------
    def initUi(self):
        """初始化界面"""
        labels = [u'', u'名称', u'参数', u'变量']

        self.setColumnCount(len(labels))
        self.setHorizontalHeaderLabels(labels)
        self.setRowCount(0)
        self.verticalHeader().setVisible(False)
        self.setEditTriggers(self.NoEditTriggers)

    #----------------------------------------------------------------------
    def registerEvent(self):
        """注册事件监听"""
        self.signalParam.connect(self.processParamEvent)
        self.signalVar.connect(self.processVarEvent)

        self.eventEngine.register(EVENT_ALGO_PARAM, self.signalParam.emit)
        self.eventEngine.register(EVENT_ALGO_VAR, self.signalVar.emit)

    #----------------------------------------------------------------------
    def addAlgo(self, algoName):
        """新增算法"""
        self.insertRow(0)

        buttonStop = StopButton(self.algoEngine, algoName)
        cellName = AlgoCell(algoName)
        cellParam = AlgoCell()
        cellVar = AlgoCell()

        self.setCellWidget(0, 0, buttonStop)
        self.setItem(0, 1, cellName)
        self.setItem(0, 2, cellParam)
        self.setItem(0, 3, cellVar)

        self.cellDict[algoName] = {
            'param': cellParam,
            'var': cellVar,
            'button': buttonStop
        }

    #----------------------------------------------------------------------
    def processParamEvent(self, event):
        """"""
        d = event.dict_['data']

        algoName = d.pop('algoName')
        if algoName not in self.cellDict:
            self.addAlgo(algoName)

        l = []
        for k, v in d.items():
            msg = u'%s:%s' % (k, v)
            l.append(msg)
        text = ','.join(l)

        cell = self.cellDict[algoName]['param']
        cell.setText(text)

        self.resizeColumnsToContents()

    #----------------------------------------------------------------------
    def processVarEvent(self, event):
        """"""
        d = event.dict_['data']

        algoName = d.pop('algoName')
        if algoName not in self.cellDict:
            self.addAlgo(algoName)

        if 'active' in d:
            active = d.pop('active')
            if not active:
                button = self.cellDict[algoName]['button']
                button.disable()

        l = []
        for k, v in d.items():
            msg = u'%s:%s' % (k, v)
            l.append(msg)
        text = ','.join(l)

        cell = self.cellDict[algoName]['var']
        cell.setText(text)

        self.resizeColumnsToContents()