Esempio n. 1
0
 def initUi(self):
     """初始化界面"""
     self.setWindowTitle(u'K线工具')
     # 主图
     self.pw = pg.PlotWidget()
     # 界面布局
     self.lay_KL = pg.GraphicsLayout(border=(100, 100, 100))
     self.lay_KL.setContentsMargins(10, 10, 10, 10)
     self.lay_KL.setSpacing(0)
     self.lay_KL.setBorder(color=(255, 0, 0, 255), width=0.8)
     self.lay_KL.setZValue(0)
     self.KLtitle = self.lay_KL.addLabel(u'')
     self.pw.setCentralItem(self.lay_KL)
     # 设置横坐标
     xdict = {}
     self.axisTime = MyStringAxis(xdict, orientation='bottom')
     # 初始化子图
     self.initplotKline()
     self.initplotVol()
     self.initplotOI()
     # 注册十字光标
     self.crosshair = Crosshair(self.pw, self)
     # 设置界面
     self.vb = QVBoxLayout()
     self.vb.addWidget(self.pw)
     self.setLayout(self.vb)
     # 初始化完成
     self.initCompleted = True
Esempio n. 2
0
class KLineWidget(KeyWraper):
    """用于显示价格走势图"""

    # 窗口标识
    clsId = 0

    # 保存K线数据的列表和Numpy Array对象
    listBar = []
    listbarshow = False
    listVol = []
    listHigh = []
    listLow = []
    listSig = []
    listOpenInterest = []
    arrows = []
    curves = []
    listSig_deal_DIRECTION = []
    listSig_deal_OFFSET = []
    KLINE_show = True
    MA_SHORT_show = False
    MA_LONG_show = False
    KLINE_CLOSE = []
    start_date = []  #[20090327开始日期,列表的位置]

    # 是否完成了历史数据的读取
    initCompleted = False

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

        # 当前序号
        self.index = None  # 下标
        self.countK = 60  # 显示的K线范围

        KLineWidget.clsId += 1
        self.windowId = str(KLineWidget.clsId)

        # 缓存数据
        self.datas = []
        self.listBar = []
        self.listbarshow = True
        self.listVol = []
        self.listHigh = []
        self.listLow = []
        self.listSig = []
        self.listOpenInterest = []
        self.arrows = []
        self.curves = []
        self.listSig_deal_DIRECTION = []
        self.listSig_deal_OFFSET = []
        self.KLINE_CLOSE = []
        self.MA_SHORT_real = []
        self.MA_LONG_real = []
        self.start_time = []

        # 所有K线上信号图
        self.allColor = deque(['blue', 'green', 'yellow', 'white'])
        self.sigData = {}
        self.sigColor = {}
        self.sigPlots = {}

        # 所副图上信号图
        self.allSubColor = deque(['blue', 'green', 'yellow', 'white'])
        self.subSigData = {}
        self.subSigColor = {}
        self.subSigPlots = {}

        # 初始化完成
        self.initCompleted = False

        # 调用函数
        self.initUi()

        self.menu = CustomMenu(self)

    #----------------------------------------------------------------------
    #  初始化相关
    #----------------------------------------------------------------------
    def initUi(self):
        """初始化界面"""
        self.setWindowTitle(u'K线工具')
        # 主图
        self.pw = pg.PlotWidget()
        # 界面布局
        self.lay_KL = pg.GraphicsLayout(border=(100, 100, 100))
        self.lay_KL.setContentsMargins(10, 10, 10, 10)
        self.lay_KL.setSpacing(0)
        self.lay_KL.setBorder(color=(255, 0, 0, 255), width=0.8)
        self.lay_KL.setZValue(0)
        self.KLtitle = self.lay_KL.addLabel(u'')
        self.pw.setCentralItem(self.lay_KL)
        # 设置横坐标
        xdict = {}
        self.axisTime = MyStringAxis(xdict, orientation='bottom')
        # 初始化子图
        self.initplotKline()
        self.initplotVol()
        self.initplotOI()
        # 注册十字光标
        self.crosshair = Crosshair(self.pw, self)
        # 设置界面
        self.vb = QVBoxLayout()
        self.vb.addWidget(self.pw)
        self.setLayout(self.vb)
        # 初始化完成
        self.initCompleted = True

    #----------------------------------------------------------------------
    def makePI(self, name):
        """生成PlotItem对象"""
        vb = CustomViewBox()
        plotItem = pg.PlotItem(viewBox=vb,
                               name=name,
                               axisItems={'bottom': self.axisTime})
        plotItem.setMenuEnabled(False)
        plotItem.setClipToView(True)
        plotItem.hideAxis('left')
        plotItem.showAxis('right')
        plotItem.setDownsampling(mode='peak')
        plotItem.setRange(xRange=(0, 1), yRange=(0, 1))
        plotItem.getAxis('right').setWidth(30)
        plotItem.getAxis('right').setStyle(
            tickFont=QFont("Roman times", 10, QFont.Bold))
        plotItem.getAxis('right').setPen(color=(255, 0, 0, 255), width=0.8)
        plotItem.showGrid(True, True)
        plotItem.hideButtons()
        return plotItem

    #----------------------------------------------------------------------
    def initplotVol(self):
        """初始化成交量子图"""
        self.pwVol = self.makePI('_'.join([self.windowId, 'PlotVOL']))
        self.volume = CandlestickItem(self.listVol)
        self.pwVol.addItem(self.volume)

        self.pwVol.setMaximumHeight(50)
        self.pwVol.setXLink('_'.join([self.windowId, 'PlotOI']))
        self.pwVol.hideAxis('bottom')

        self.lay_KL.nextRow()
        self.lay_KL.addItem(self.pwVol)

    #----------------------------------------------------------------------
    def initplotKline(self):
        """初始化K线子图以及指标子图"""
        self.pwKL = self.makePI('_'.join([self.windowId, 'PlotKL']))
        self.candle = CandlestickItem(self.listBar)
        self.pwKL.addItem(self.candle)

        self.KLINEOI_CLOSE = pg.PlotCurveItem(pen=({'color': "w", 'width': 1}))
        self.pwKL.addItem(self.KLINEOI_CLOSE)
        self.KLINEOI_CLOSE.hide()

        self.MA_SHORTOI = pg.PlotCurveItem(pen=({'color': "r", 'width': 1}))
        self.pwKL.addItem(self.MA_SHORTOI)
        self.MA_SHORTOI.hide()

        self.MA_LONGOI = pg.PlotCurveItem(pen=({
            'color': "r",
            'width': 1,
            'dash': [3, 3, 3, 3]
        }))
        self.pwKL.addItem(self.MA_LONGOI)
        self.MA_LONGOI.hide()

        self.start_date_Line = pg.InfiniteLine(angle=90,
                                               movable=False,
                                               pen=({
                                                   'color': "w",
                                                   'width': 0.5
                                               }))
        self.pwKL.addItem(self.start_date_Line)

        self.pwKL.setMinimumHeight(350)
        self.pwKL.setXLink('_'.join([self.windowId, 'PlotOI']))
        self.pwKL.hideAxis('bottom')

        self.lay_KL.nextRow()
        self.lay_KL.addItem(self.pwKL)

    #----------------------------------------------------------------------
    def initplotOI(self):
        """初始化持仓量子图"""
        self.pwOI = self.makePI('_'.join([self.windowId, 'PlotOI']))
        self.curveOI = self.pwOI.plot()

        self.pwOI.setMaximumHeight(50)
        self.lay_KL.nextRow()
        self.lay_KL.addItem(self.pwOI)
        pass

    #----------------------------------------------------------------------
    #  画图相关
    #----------------------------------------------------------------------
    def plotVol(self, redraw=False, xmin=0, xmax=-1):
        """重画成交量子图"""
        if self.initCompleted:
            self.volume.generatePicture(self.listVol[xmin:xmax],
                                        redraw)  # 画成交量子图

    #----------------------------------------------------------------------
    def plotKline(self, redraw=False, xmin=0, xmax=-1):
        """重画K线子图"""
        if self.initCompleted:
            self.candle.generatePicture(self.listBar[xmin:xmax], redraw)  # 画K线
            self.KLINEOI_CLOSE.setData(np.array(self.KLINE_CLOSE))  #画收盘价曲线
            self.plotMark()  # 显示开平仓信号位置

    #----------------------------------------------------------------------
    def plotMA_SHORT(self):
        """重画MA_SHORT """
        if self.initCompleted:
            self.MA_SHORTOI.setData(np.array(self.MA_SHORT_real))  #画MA_SHORT

    #----------------------------------------------------------------------
    def plotMA_LONG(self):
        """重画MA_LONG  """
        if self.initCompleted:
            self.MA_LONGOI.setData(np.array(self.MA_LONG_real))  #画MA_LONG

    #----------------------------------------------------------------------
    def plot_startdate(self, pos):
        """重画起始日期  """
        if self.initCompleted:
            self.start_date_Line.setPos(pos)

    #----------------------------------------------------------------------
    def plotOI(self, xmin=0, xmax=-1):
        """重画持仓量子图"""
        if self.initCompleted:
            self.curveOI.setData(np.append(self.listOpenInterest[xmin:xmax],
                                           0),
                                 pen='w',
                                 name="OpenInterest")

    #----------------------------------------------------------------------
    def addSig(self, sig, main=True):
        """新增信号图"""
        if main:
            if sig in self.sigPlots:
                self.pwKL.removeItem(self.sigPlots[sig])
            self.sigPlots[sig] = self.pwKL.plot()
            self.sigColor[sig] = self.allColor[0]
            self.allColor.append(self.allColor.popleft())
        else:
            if sig in self.subSigPlots:
                self.pwOI.removeItem(self.subSigPlots[sig])
            self.subSigPlots[sig] = self.pwOI.plot()
            self.subSigColor[sig] = self.allSubColor[0]
            self.allSubColor.append(self.allSubColor.popleft())

    #----------------------------------------------------------------------
    def showSig(self, datas, main=True, clear=False):
        """刷新信号图"""
        if clear:
            self.clearSig(main)
            if datas and not main:
                sigDatas = np.array(datas.values()[0])
                self.listOpenInterest = sigDatas
                self.datas['openInterest'] = sigDatas
                self.plotOI(0, len(sigDatas))
        if main:
            for sig in datas:
                self.addSig(sig, main)
                self.sigData[sig] = datas[sig]
                self.sigPlots[sig].setData(np.append(datas[sig], 0),
                                           pen=self.sigColor[sig][0],
                                           name=sig)
        else:
            for sig in datas:
                self.addSig(sig, main)
                self.subSigData[sig] = datas[sig]
                self.subSigPlots[sig].setData(np.append(datas[sig], 0),
                                              pen=self.subSigColor[sig][0],
                                              name=sig)

    #----------------------------------------------------------------------
    def plotMark(self):
        """显示开平仓信号"""
        # 检查是否有数据
        if len(self.datas) == 0:
            return
        for arrow in self.arrows:
            self.pwKL.removeItem(arrow)
        for curve in self.curves:
            self.pwKL.removeItem(curve)
        # 画买卖信号
        lastbk_x = -1  #上一个买开的x
        lastbk_y = -1  #上一个买开的y
        lastsk_x = -1  #上一个卖开的x
        lastsk_y = -1  #上一个卖开的y
        for i in range(len(self.listSig_deal_DIRECTION)):
            # 无信号
            if cmp(self.listSig_deal_DIRECTION[i], '-') == 0 or cmp(
                    self.listSig_deal_OFFSET[i], '-') == 0:
                continue
            # 买开信号
            elif cmp(self.listSig_deal_DIRECTION[i], '多') == 0 and cmp(
                    self.listSig_deal_OFFSET[i], '开仓') == 0:
                arrow = pg.ArrowItem(pos=(i, self.datas[i]['low']),
                                     size=7,
                                     tipAngle=55,
                                     tailLen=3,
                                     tailWidth=4,
                                     angle=90,
                                     brush=(255, 0, 0),
                                     pen=({
                                         'color': "r",
                                         'width': 1
                                     }))
                lastbk_x = i
                lastbk_y = self.datas[i]['close']
            # 卖平信号
            elif cmp(self.listSig_deal_DIRECTION[i], '空') == 0 and cmp(
                    self.listSig_deal_OFFSET[i], '平仓') == 0:
                arrow = pg.ArrowItem(pos=(i, self.datas[i]['high']),
                                     size=7,
                                     tipAngle=55,
                                     tailLen=3,
                                     tailWidth=4,
                                     angle=-90,
                                     brush=(0, 0, 0),
                                     pen=({
                                         'color': "g",
                                         'width': 1
                                     }))
                curve = pg.PlotCurveItem(
                    x=np.array([lastbk_x, i]),
                    y=np.array([lastbk_y, self.datas[i]['close']]),
                    name='duo',
                    pen=({
                        'color': "r",
                        'width': 3
                    }))
                self.pwKL.addItem(curve)
                self.curves.append(curve)
            # 卖开信号
            elif cmp(self.listSig_deal_DIRECTION[i], '空') == 0 and cmp(
                    self.listSig_deal_OFFSET[i], '开仓') == 0:
                arrow = pg.ArrowItem(pos=(i, self.datas[i]['high']),
                                     size=7,
                                     tipAngle=55,
                                     tailLen=3,
                                     tailWidth=4,
                                     angle=-90,
                                     brush=(0, 255, 0),
                                     pen=({
                                         'color': "g",
                                         'width': 1
                                     }))
                lastsk_x = i
                lastsk_y = self.datas[i]['close']
            # 买平信号
            elif cmp(self.listSig_deal_DIRECTION[i], '多') == 0 and cmp(
                    self.listSig_deal_OFFSET[i], '平仓') == 0:
                arrow = pg.ArrowItem(pos=(i, self.datas[i]['low']),
                                     size=7,
                                     tipAngle=55,
                                     tailLen=3,
                                     tailWidth=4,
                                     angle=90,
                                     brush=(0, 0, 0),
                                     pen=({
                                         'color': "r",
                                         'width': 1
                                     }))
                curve = pg.PlotCurveItem(
                    x=np.array([lastsk_x, i]),
                    y=np.array([lastsk_y, self.datas[i]['close']]),
                    pen=({
                        'color': "g",
                        'width': 3
                    }))
                self.pwKL.addItem(curve)
                self.curves.append(curve)
            self.pwKL.addItem(arrow)
            self.arrows.append(arrow)

    #----------------------------------------------------------------------
    def updateAll(self):
        """
        手动更新所有K线图形,K线播放模式下需要
        """
        datas = self.datas
        self.volume.pictrue = None
        self.candle.pictrue = None
        self.volume.update()
        self.candle.update()

        def update(view, low, high):
            vRange = view.viewRange()
            xmin = max(0, int(vRange[0][0]))
            xmax = max(0, int(vRange[0][1]))
            try:
                xmax = min(xmax, len(datas) - 1)
            except:
                xmax = xmax
            if len(datas) > 0 and xmax > xmin:
                ymin = min(datas[xmin:xmax][low])
                ymax = max(datas[xmin:xmax][high])
                view.setRange(yRange=(ymin, ymax))
            else:
                view.setRange(yRange=(0, 1))

        update(self.pwKL.getViewBox(), 'low', 'high')
        update(self.pwVol.getViewBox(), 'volume', 'volume')

    #----------------------------------------------------------------------
    def plotAll(self, redraw=True, xMin=0, xMax=-1):
        """
        重画所有界面
        redraw :False=重画最后一根K线; True=重画所有
        xMin,xMax : 数据范围
        """
        xMax = len(self.datas) - 1 if xMax < 0 else xMax
        #self.countK = xMax-xMin
        #self.index = int((xMax+xMin)/2)
        self.pwOI.setLimits(xMin=xMin, xMax=xMax)
        self.pwKL.setLimits(xMin=xMin, xMax=xMax)
        self.pwVol.setLimits(xMin=xMin, xMax=xMax)
        self.plotKline(redraw, xMin, xMax)  # K线图
        self.plot_startdate(self.start_date[1])
        self.plotVol(redraw, xMin, xMax)  # K线副图,成交量
        self.plotOI(0, len(self.datas))  # K线副图,持仓量
        self.refresh()

    #----------------------------------------------------------------------
    def refresh(self):
        """
        刷新三个子图的现实范围
        """
        datas = self.datas
        minutes = int(self.countK / 2)
        xmin = max(0, self.index - minutes)
        try:
            xmax = min(xmin + 2 * minutes,
                       len(self.datas) -
                       1) if self.datas else xmin + 2 * minutes
        except:
            xmax = xmin + 2 * minutes
        self.pwOI.setRange(xRange=(xmin, xmax))
        self.pwKL.setRange(xRange=(xmin, xmax))
        self.pwVol.setRange(xRange=(xmin, xmax))

    #----------------------------------------------------------------------
    #  快捷键与鼠标相关
    #----------------------------------------------------------------------
    def onNxt(self):
        """跳转到下一个开平仓点"""
        if len(self.listSig) > 0 and not self.index is None:
            datalen = len(self.listSig)
            if self.index < datalen - 2: self.index += 1
            while self.index < datalen - 2 and cmp(
                    self.listSig_deal_DIRECTION[self.index], '-') == 0:
                self.index += 1
            self.refresh()
            x = self.index
            y = self.datas[x]['close']
            self.crosshair.signal.emit((x, y))

    #----------------------------------------------------------------------
    def onPre(self):
        """跳转到上一个开平仓点"""
        if len(self.listSig) > 0 and not self.index is None:
            if self.index > 0: self.index -= 1
            while self.index > 0 and cmp(
                    self.listSig_deal_DIRECTION[self.index], '-') == 0:
                self.index -= 1
            self.refresh()
            x = self.index
            y = self.datas[x]['close']
            self.crosshair.signal.emit((x, y))

    #----------------------------------------------------------------------
    def onDown(self):
        """放大显示区间"""
        self.countK = min(len(self.datas), int(self.countK * 1.2) + 1)
        self.refresh()
        if len(self.datas) > 0:
            x = self.index - self.countK / 2 + 2 if int(
                self.crosshair.xAxis
            ) < self.index - self.countK / 2 + 2 else int(self.crosshair.xAxis)
            x = self.index + self.countK / 2 - 2 if x > self.index + self.countK / 2 - 2 else x
            x = len(self.datas) - 1 if x > len(self.datas) - 1 else int(x)
            y = self.datas[x][2]
            self.crosshair.signal.emit((x, y))

    #----------------------------------------------------------------------
    def onUp(self):
        """缩小显示区间"""
        self.countK = max(3, int(self.countK / 1.2) - 1)
        self.refresh()
        if len(self.datas) > 0:
            x = self.index - self.countK / 2 + 2 if int(
                self.crosshair.xAxis
            ) < self.index - self.countK / 2 + 2 else int(self.crosshair.xAxis)
            x = self.index + self.countK / 2 - 2 if x > self.index + self.countK / 2 - 2 else x
            x = len(self.datas) - 1 if x > len(self.datas) - 1 else int(x)
            y = self.datas[x]['close']
            self.crosshair.signal.emit((x, y))

    #----------------------------------------------------------------------
    def onLeft(self):
        """向左移动"""
        if len(self.datas) > 0 and int(self.crosshair.xAxis) > 2:
            x = int(self.crosshair.xAxis) - 1
            x = len(self.datas) - 1 if x > len(self.datas) - 1 else int(x)
            y = self.datas[x]['close']
            if x <= self.index - self.countK / 2 + 2 and self.index > 1:
                self.index -= 1
                self.refresh()
            self.crosshair.signal.emit((x, y))

    #----------------------------------------------------------------------
    def onRight(self):
        """向右移动"""
        if len(self.datas) > 0 and int(
                self.crosshair.xAxis) < len(self.datas) - 1:
            x = int(self.crosshair.xAxis) + 1
            x = len(self.datas) - 1 if x > len(self.datas) - 1 else int(x)
            y = self.datas[x]['close']
            if x >= self.index + int(self.countK / 2) - 2:
                self.index += 1
                self.refresh()
            self.crosshair.signal.emit((x, y))

    #----------------------------------------------------------------------
    def onRClick(self, pos):
        self.menu.showContextMenu(pos)

    #----------------------------------------------------------------------
    #  右键菜单相关
    #----------------------------------------------------------------------
    def initIndicator(self, data):
        if cmp(data, u'信号隐藏') == 0:
            for arrow in self.arrows:
                arrow.hide()
            for curve in self.curves:
                curve.hide()
        elif cmp(data, u'信号显示') == 0:
            for arrow in self.arrows:
                arrow.show()
            for curve in self.curves:
                curve.show()
        elif cmp(data, u'KLINE') == 0:
            if self.KLINE_show == True:
                self.pwKL.removeItem(self.candle)
                self.KLINEOI_CLOSE.show()
                self.KLINE_show = False
            else:
                self.pwKL.addItem(self.candle)
                self.KLINEOI_CLOSE.hide()
                self.KLINE_show = True
        elif cmp(data, u'MA SHORT') == 0:
            if len(self.MA_SHORT_real) == 0:
                self.MA_SHORT_real = ta.MA(np.array(self.KLINE_CLOSE),
                                           timeperiod=22,
                                           matype=0).tolist()
                self.crosshair.ma_s_values = self.MA_SHORT_real
                self.plotMA_SHORT()
            if self.MA_SHORT_show:
                self.MA_SHORTOI.hide()
                self.MA_SHORT_show = False
            else:
                self.MA_SHORTOI.show()
                self.MA_SHORT_show = True
        elif cmp(data, u'MA LONG') == 0:
            if len(self.MA_LONG_real) == 0:
                self.MA_LONG_real = ta.MA(np.array(self.KLINE_CLOSE),
                                          timeperiod=92,
                                          matype=0).tolist()
                self.crosshair.ma_l_values = self.MA_LONG_real
                self.plotMA_LONG()
            if self.MA_LONG_show:
                self.MA_LONGOI.hide()
                self.MA_LONG_show = False
            else:
                self.MA_LONGOI.show()
                self.MA_LONG_show = True
        elif cmp(data, u'设为起始日期') == 0:
            self.plot_startdate(self.crosshair.cur_date()[1])
            self.start_date = self.crosshair.cur_date()
        elif cmp(data, u'MA_螺纹多_PLUS') == 0:
            initday = 100  #MA_螺纹多_PLUS策略需要100天的预处理量
            if self.start_date[1] < 100:
                initday = 0
            rb9999DailyResult(
                dt.datetime.strftime(
                    pd.to_datetime(
                        pd.to_datetime(
                            self.datas[self.start_date[1] -
                                       initday]['datetime'], )), '%Y%m%d'),
                os.path.abspath('.\data\dailyresult\RB9999.csv'))
            self.clearSigData()
            self.loadData_listsig(
                pd.DataFrame.from_csv('data\dailyresult\RB9999.csv'))
            self.plotMark()
            if self.KLINE_show == True:
                self.KLINEOI_CLOSE.hide()
            else:
                self.KLINEOI_CLOSE.show()

    #----------------------------------------------------------------------
    # 界面回调相关
    #----------------------------------------------------------------------
    def onPaint(self):
        """界面刷新回调"""
        view = self.pwKL.getViewBox()
        vRange = view.viewRange()
        xmin = max(0, int(vRange[0][0]))
        xmax = max(0, int(vRange[0][1]))
        self.index = int((xmin + xmax) / 2) + 1

    #----------------------------------------------------------------------
    def resignData(self, datas):
        """更新数据,用于Y坐标自适应"""
        self.crosshair.datas = datas

        def viewXRangeChanged(low, high, self):
            vRange = self.viewRange()
            xmin = max(0, int(vRange[0][0]))
            xmax = max(0, int(vRange[0][1]))
            xmax = min(xmax, len(datas))
            if len(datas) > 0 and xmax > xmin:
                ymin = min(datas[xmin:xmax][low])
                ymax = max(datas[xmin:xmax][high])
                ymin, ymax = (-1, 1) if ymin == ymax else (ymin, ymax)
                self.setRange(yRange=(ymin, ymax))
            else:
                self.setRange(yRange=(0, 1))

        view = self.pwKL.getViewBox()
        view.sigXRangeChanged.connect(partial(viewXRangeChanged, 'low',
                                              'high'))

        view = self.pwVol.getViewBox()
        view.sigXRangeChanged.connect(
            partial(viewXRangeChanged, 'volume', 'volume'))

        view = self.pwOI.getViewBox()
        view.sigXRangeChanged.connect(
            partial(viewXRangeChanged, 'openInterest', 'openInterest'))

    #----------------------------------------------------------------------
    # 数据相关
    #----------------------------------------------------------------------
    def clearData(self):
        """清空数据"""
        # 清空数据,重新画图
        self.time_index = []
        self.listBar = []
        self.listVol = []
        self.listLow = []
        self.listHigh = []
        self.listOpenInterest = []
        self.listSig = []
        self.listSig_deal_DIRECTION = []
        self.listSig_deal_OFFSET = []
        self.sigData = {}
        self.datas = None
        self.MA_SHORT_real = []
        self.MA_LONG_real = []
        self.start_time = []

    #----------------------------------------------------------------------
    def clearSigData(self):
        """清空信号数据"""
        # 清空数据,重新画图
        self.listSig_deal_DIRECTION = []
        self.listSig_deal_OFFSET = []
        for arrow in self.arrows:
            self.pwKL.removeItem(arrow)
        for curve in self.curves:
            self.pwKL.removeItem(curve)
        self.arrows = []
        self.curves = []

    #----------------------------------------------------------------------
    def clearSig(self, main=True):
        """清空信号图形"""
        # 清空信号图
        if main:
            for sig in self.sigPlots:
                self.pwKL.removeItem(self.sigPlots[sig])
            self.sigData = {}
            self.sigPlots = {}
        else:
            for sig in self.subSigPlots:
                self.pwOI.removeItem(self.subSigPlots[sig])
            self.subSigData = {}
            self.subSigPlots = {}

    #----------------------------------------------------------------------
    def updateSig(self, sig):
        """刷新买卖信号"""
        self.listSig = sig
        self.plotMark()

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """
        新增K线数据,K线播放模式
        """
        # 是否需要更新K线
        newBar = False if len(self.datas) > 0 and bar.datetime == self.datas[
            -1].datetime else True
        nrecords = len(self.datas) if newBar else len(self.datas) - 1
        bar.openInterest = np.random.randint(
            0, 3
        ) if bar.openInterest == np.inf or bar.openInterest == -np.inf else bar.openInterest
        recordVol = (nrecords, abs(bar.volume), 0, 0, abs(
            bar.volume)) if bar.close < bar.open else (nrecords, 0,
                                                       abs(bar.volume), 0,
                                                       abs(bar.volume))

        if newBar and any(self.datas):
            self.datas.resize(nrecords + 1, refcheck=0)
            self.listBar.resize(nrecords + 1, refcheck=0)
            self.listVol.resize(nrecords + 1, refcheck=0)
        elif any(self.datas):
            self.listLow.pop()
            self.listHigh.pop()
            self.listOpenInterest.pop()
        if any(self.datas):
            self.datas[-1] = (bar.datetime, bar.open, bar.close, bar.low,
                              bar.high, bar.volume, bar.openInterest)
            self.listBar[-1] = (nrecords, bar.open, bar.close, bar.low,
                                bar.high)
            self.listVol[-1] = recordVol
        else:
            self.datas     = np.rec.array([(bar.datetime, bar.open, bar.close, bar.low, bar.high, bar.volume, bar.openInterest)],\
                                        names=('datetime','open','close','low','high','volume','openInterest'))
            self.listBar   = np.rec.array([(nrecords, bar.open, bar.close, bar.low, bar.high)],\
                                     names=('time_int','open','close','low','high'))
            self.listVol = np.rec.array([recordVol],
                                        names=('time_int', 'open', 'close',
                                               'low', 'high'))
            self.resignData(self.datas)

        self.axisTime.update_xdict({nrecords: bar.datetime})
        self.listLow.append(bar.low)
        self.listHigh.append(bar.high)
        self.listOpenInterest.append(bar.openInterest)
        self.resignData(self.datas)
        return newBar

    #----------------------------------------------------------------------
    def loadData(self, datas, sigs=None):
        """
        载入pandas.DataFrame数据
        datas : 数据格式,cols : datetime, open, close, low, high
        """
        # 设置中心点时间
        # 绑定数据,更新横坐标映射,更新Y轴自适应函数,更新十字光标映射
        datas['time_int'] = np.array(range(len(datas.index)))

        self.datas = datas[[
            'open', 'close', 'low', 'high', 'volume', 'openInterest'
        ]].to_records()
        self.axisTime.xdict = {}
        xdict = dict(enumerate(datas.index.tolist()))
        self.axisTime.update_xdict(xdict)
        self.resignData(self.datas)
        # 更新画图用到的数据
        self.listBar = datas[['time_int', 'open', 'close', 'low',
                              'high']].to_records(False)
        self.listHigh = list(datas['high'])
        self.listLow = list(datas['low'])
        self.listOpenInterest = list(datas['openInterest'])
        self.listSig = [0] * (len(self.datas) - 1) if sigs is None else sigs

        self.KLINE_CLOSE = map(float, list(datas['close']))
        self.start_date = [
            dt.datetime.strftime(
                pd.to_datetime(pd.to_datetime(self.datas[0]['datetime'])),
                '%Y%m%d'), 0
        ]
        # 成交量颜色和涨跌同步,K线方向由涨跌决定
        datas0 = pd.DataFrame()
        datas0['open'] = datas.apply(
            lambda x: 0 if x['close'] >= x['open'] else x['volume'], axis=1)
        datas0['close'] = datas.apply(
            lambda x: 0 if x['close'] < x['open'] else x['volume'], axis=1)
        datas0['low'] = 0
        datas0['high'] = datas['volume']
        datas0['time_int'] = np.array(range(len(datas.index)))
        self.listVol = datas0[['time_int', 'open', 'close', 'low',
                               'high']].to_records(False)

    #----------------------------------------------------------------------
    def loadData_listsig(self, datas):
        datas['deal_DIRECTION'] = datas['deal_DIRECTION'].fillna('-')
        datas['deal_OFFSET'] = datas['deal_OFFSET'].fillna('-')
        self.listSig_deal_DIRECTION = datas['deal_DIRECTION'].tolist()
        if len(self.listSig_deal_DIRECTION) < len(self.KLINE_CLOSE):
            list1 = [
                '-' for i in range(
                    len(self.KLINE_CLOSE) - len(self.listSig_deal_DIRECTION))
            ]
            list1.extend(self.listSig_deal_DIRECTION)
            self.listSig_deal_DIRECTION = list1
        self.listSig_deal_OFFSET = datas['deal_OFFSET'].tolist()
        if len(self.listSig_deal_OFFSET) < len(self.KLINE_CLOSE):
            list1 = [
                '-' for i in range(
                    len(self.KLINE_CLOSE) - len(self.listSig_deal_OFFSET))
            ]
            list1.extend(self.listSig_deal_OFFSET)
            self.listSig_deal_OFFSET = list1

    #----------------------------------------------------------------------
    def refreshAll(self, redraw=True, update=False):
        """
        更新所有界面
        """
        # 调用画图函数
        self.index = len(self.datas)
        self.plotAll(redraw, 0, len(self.datas))
        if not update:
            self.updateAll()
        self.crosshair.signal.emit((None, None))