Пример #1
0
class ChartWidget(QWidget):
    def __init__(self, parent=None, ticker="BTCUSDT"):
        super().__init__(parent)
        uic.loadUi("resource/chart.ui", self)
        self.ticker = ticker
        self.viewLimit = 10

        self.tm = []

        self.priceData = QCandlestickSeries()
        self.priceData.setDecreasingColor(Qt.red)
        self.priceData.setIncreasingColor(Qt.green)
        self.priceChart = QChart()
        self.priceChart.addSeries(self.priceData)
        self.priceChart.legend().hide()

        axisX = QDateTimeAxis()
        axisX.setFormat("hh:mm:ss")
        axisX.setTickCount(4)
        dt = QDateTime.currentDateTime()
        axisX.setRange(dt, dt.addSecs(self.viewLimit))
        axisY = QValueAxis()
        axisY.setVisible(False)

        self.priceChart.addAxis(axisX, Qt.AlignBottom)
        self.priceChart.addAxis(axisY, Qt.AlignRight)
        self.priceData.attachAxis(axisX)
        self.priceData.attachAxis(axisY)
        self.priceChart.layout().setContentsMargins(0, 0, 0, 0)

        self.priceView.setChart(self.priceChart)
        self.priceView.setRenderHints(QPainter.Antialiasing)

        self.pw = PriceWorker(ticker)
        self.pw.dataSent.connect(self.appendData)
        self.pw.start()

    def appendData(self, o, h, l, c):
        if len(self.tm) == self.viewLimit:
            self.priceData.remove(0)
            self.tm.remove(0)
        dt = QDateTime.currentDateTime()
        self.priceData.append(QCandlestickSet(o, h, l, c))
        print(dt.toMSecsSinceEpoch())
        print(type(dt.toMSecsSinceEpoch()))
        self.tm.append(dt.toMSecsSinceEpoch())
        self.__updateAxis()

    def __updateAxis(self):
        pvs = self.tm
        dtStart = QDateTime.fromMSecsSinceEpoch(int(pvs[0]))
        if len(self.priceData) == self.viewLimit:
            dtLast = QDateTime.fromMSecsSinceEpoch(int(pvs[-1]))
        else:
            dtLast = dtStart.addSecs(self.viewLimit)
        ax = self.priceChart.axisX()
        ax.setRange(dtStart, dtLast)
Пример #2
0
class PriceFigure:
    def __init__(self, name):
        self.name = name
        self.chart_view = QChartView()

        self.price_time_axis = QDateTimeAxis()
        self.price_time_axis.setFormat('h:mm')

        self.price_axis = QValueAxis()
        self.candle_stick_series = QCandlestickSeries()
        self.candle_stick_series.setIncreasingColor(Qt.red)
        self.candle_stick_series.setDecreasingColor(Qt.blue)

        self.moving_average_series = QLineSeries()

        self.top_edge_series = QScatterSeries()
        self.bottom_edge_series = QScatterSeries()

        self.trend_lines = []
        self.short_top_trend_series = QLineSeries()
        self.short_bottom_trend_series = QLineSeries()
        self.long_top_trend_series = QLineSeries()
        self.long_bottom_trend_series = QLineSeries()
        self.trend_lines.append(self.short_top_trend_series)
        self.trend_lines.append(self.short_bottom_trend_series)
        self.trend_lines.append(self.long_top_trend_series)
        self.trend_lines.append(self.long_bottom_trend_series)

        self.chart_view.chart().addSeries(self.candle_stick_series)
        self.chart_view.chart().addSeries(self.moving_average_series)
        self.chart_view.chart().addSeries(self.top_edge_series)
        self.chart_view.chart().addSeries(self.bottom_edge_series)
        self.chart_view.chart().addSeries(self.short_top_trend_series)
        self.chart_view.chart().addSeries(self.long_top_trend_series)
        self.chart_view.chart().addSeries(self.short_bottom_trend_series)
        self.chart_view.chart().addSeries(self.long_bottom_trend_series)

        self.chart_view.chart().addAxis(self.price_time_axis, Qt.AlignBottom)
        self.chart_view.chart().addAxis(self.price_axis, Qt.AlignLeft)
        self.chart_view.chart().legend().hide()
        self.chart_view.setRenderHint(QPainter.Antialiasing)
        self.set_marker_color()
        self.set_trend_line_pen()

    def set_trend_line_pen(self):
        brushes = [
            QBrush(QColor(255, 0, 0, 90)),
            QBrush(QColor(0, 0, 255, 90)),
            QBrush(QColor(205, 56, 47, 255)),
            QBrush(QColor(0, 153, 213, 255))
        ]
        for i, tl in enumerate(self.trend_lines):
            tl.setPen(QPen(brushes[i], 4, Qt.DotLine))

    def set_marker_color(self):
        self.top_edge_series.setPen(Qt.black)
        self.top_edge_series.setBrush(QBrush(QColor(255, 0, 255, 90)))
        self.bottom_edge_series.setPen(Qt.black)
        self.bottom_edge_series.setBrush(QBrush(QColor(0, 255, 255, 90)))

    def set_datetime(self, d):
        self.chart_datetime = d
        self.datetime_range = (d.timestamp() * 1000,
                               d.replace(hour=23, minute=59).timestamp() *
                               1000)
        start_time = QDateTime()
        until_time = QDateTime()
        start_time.setDate(QDate(d.year, d.month, d.day))
        until_time.setDate(QDate(d.year, d.month, d.day))
        start_time.setTime(QTime(9, 0))
        until_time.setTime(QTime(16, 0))
        self.price_time_axis.setRange(start_time, until_time)

    def attach(self):
        self.price_time_axis.setTickCount(7)
        self.candle_stick_series.attachAxis(self.price_time_axis)
        self.candle_stick_series.attachAxis(self.price_axis)
        self.moving_average_series.attachAxis(self.price_time_axis)
        self.moving_average_series.attachAxis(self.price_axis)
        self.top_edge_series.attachAxis(self.price_time_axis)
        self.top_edge_series.attachAxis(self.price_axis)
        self.bottom_edge_series.attachAxis(self.price_time_axis)
        self.bottom_edge_series.attachAxis(self.price_axis)
        self.short_top_trend_series.attachAxis(self.price_time_axis)
        self.short_top_trend_series.attachAxis(self.price_axis)
        self.long_top_trend_series.attachAxis(self.price_time_axis)
        self.long_top_trend_series.attachAxis(self.price_axis)
        self.short_bottom_trend_series.attachAxis(self.price_time_axis)
        self.short_bottom_trend_series.attachAxis(self.price_axis)
        self.long_bottom_trend_series.attachAxis(self.price_time_axis)
        self.long_bottom_trend_series.attachAxis(self.price_axis)

    def in_datetime_range(self, q):
        return self.datetime_range[0] < q < self.datetime_range[1]

    def clear_series_data(self):
        self.candle_stick_series.clear()
        self.moving_average_series.clear()
        self.top_edge_series.clear()
        self.bottom_edge_series.clear()
        self.short_top_trend_series.clear()
        self.long_top_trend_series.clear()
        self.short_bottom_trend_series.clear()
        self.long_bottom_trend_series.clear()

    def get_chart_view(self):
        return self.chart_view

    def add_moving_average(self, q, price):
        if self.in_datetime_range(q):
            self.moving_average_series.append(q, price)

    def add_candle_stick(self, q, o, h, l, c):
        if self.in_datetime_range(q):
            self.candle_stick_series.append(QCandlestickSet(o, h, l, c, q))

    def set_price_range(self, price_min, price_max):
        self.price_axis.setRange(price_min, price_max)
        tick_count = int(
            math.ceil((price_max - price_min) / price_min * 100. / 2.0))
        self.price_axis.setTickCount(tick_count if tick_count + 1 > 2 else 2)

    def add_top_edge(self, q, price):
        if self.in_datetime_range(q):
            self.top_edge_series.append(q, price)

    def add_bottom_edge(self, q, price):
        if self.in_datetime_range(q):
            self.bottom_edge_series.append(q, price)

    def add_short_top_trend(self, q, price, draw_horizontal=False):
        if self.in_datetime_range(q):
            if draw_horizontal:
                self.short_top_trend_series.append(q, price)
                if self.name == 'yesterday':
                    self.short_top_trend_series.append(self.datetime_range[1],
                                                       price)
                else:
                    self.short_top_trend_series.append(self.datetime_range[0],
                                                       price)
            else:
                self.short_top_trend_series.append(q, price)

    def add_long_top_trend(self, q, price, draw_horizontal=False):
        if self.in_datetime_range(q):
            if draw_horizontal:
                self.long_top_trend_series.append(q, price)
                if self.name == 'yesterday':
                    self.long_top_trend_series.append(self.datetime_range[1],
                                                      price)
                else:
                    self.long_top_trend_series.append(self.datetime_range[0],
                                                      price)
            else:
                self.long_top_trend_series.append(q, price)

    def add_short_bottom_trend(self, q, price, draw_horizontal=False):
        if self.in_datetime_range(q):
            if draw_horizontal:
                self.short_bottom_trend_series.append(q, price)
                if self.name == 'yesterday':
                    self.short_bottom_trend_series.append(
                        self.datetime_range[1], price)
                else:
                    self.short_bottom_trend_series.append(
                        self.datetime_range[0], price)
            else:
                self.short_bottom_trend_series.append(q, price)

    def add_long_bottom_trend(self, q, price, draw_horizontal=False):
        if self.in_datetime_range(q):
            if draw_horizontal:
                self.long_bottom_trend_series.append(q, price)
                if self.name == 'yesterday':
                    self.long_bottom_trend_series.append(
                        self.datetime_range[1], price)
                else:
                    self.long_bottom_trend_series.append(
                        self.datetime_range[0], price)
            else:
                self.long_bottom_trend_series.append(q, price)
Пример #3
0
class VolumeFigure:
    def __init__(self, name):
        self.chart_volume_view = QChartView()
        self.chart_volume_view.chart().setLocalizeNumbers(True)
        self.volume_series = QCandlestickSeries()

        self.volume_time_axis = QDateTimeAxis()
        self.volume_time_axis.setFormat('h:mm')
        self.volume_axis = QValueAxis()

        self.volume_average_series = QLineSeries()

        self.chart_volume_view.chart().addSeries(self.volume_series)
        self.chart_volume_view.chart().addSeries(self.volume_average_series)

        self.chart_volume_view.chart().addAxis(self.volume_time_axis,
                                               Qt.AlignBottom)
        self.chart_volume_view.chart().addAxis(self.volume_axis, Qt.AlignLeft)
        self.chart_volume_view.chart().legend().hide()
        self.chart_volume_view.setRenderHint(QPainter.Antialiasing)

    def in_datetime_range(self, q):
        return self.datetime_range[0] < q < self.datetime_range[1]

    def get_chart_view(self):
        return self.chart_volume_view

    def clear_series_data(self):
        self.volume_series.clear()
        self.volume_average_series.clear()

    def set_volume_average(self, vol):
        self.volume_average_series.append(self.datetime_range[0], vol)
        self.volume_average_series.append(self.datetime_range[1], vol)

    def set_datetime(self, d):
        self.chart_datetime = d
        self.datetime_range = (d.timestamp() * 1000,
                               d.replace(hour=23, minute=59).timestamp() *
                               1000)
        start_time = QDateTime()
        until_time = QDateTime()
        start_time.setDate(QDate(d.year, d.month, d.day))
        until_time.setDate(QDate(d.year, d.month, d.day))
        start_time.setTime(QTime(9, 0))
        until_time.setTime(QTime(16, 0))
        self.volume_time_axis.setRange(start_time, until_time)

    def add_volume_data(self, q, volume):
        if self.in_datetime_range(q):
            self.volume_series.append(QCandlestickSet(0, volume, 0, volume, q))

    def attach(self):
        self.volume_time_axis.setTickCount(7)
        self.volume_average_series.attachAxis(self.volume_axis)
        self.volume_average_series.attachAxis(self.volume_time_axis)
        self.volume_series.attachAxis(self.volume_axis)
        self.volume_series.attachAxis(self.volume_time_axis)

    def set_max(self, vol):
        self.volume_axis.setRange(0, vol)
Пример #4
0
    def __drawChart(self):  ##绘制图表
        self.chart.removeAllSeries()  #删除所有序列
        self.chart.setTitle("股票日线图--" + self.ui.tabWidget.tabText(0))

        ## 1. 创建蜡烛图
        seriesCandle = QCandlestickSeries()
        seriesCandle.setName("蜡烛图")
        seriesCandle.setIncreasingColor(Qt.red)  #暴涨
        seriesCandle.setDecreasingColor(Qt.darkGreen)  #暴跌

        visible = self.ui.chkBox_Outline.isChecked()
        seriesCandle.setBodyOutlineVisible(visible)
        seriesCandle.setCapsVisible(self.ui.chkBox_Caps.isChecked())

        self.chart.addSeries(seriesCandle)
        seriesCandle.attachAxis(self.__axisX)
        seriesCandle.attachAxis(self.__axisY)

        seriesCandle.clicked.connect(self.do_candleClicked)
        seriesCandle.hovered.connect(self.do_candleHovered)

        ## 2. 创建MA曲线
        pen = QPen()
        pen.setWidth(2)

        seriesMA1 = QLineSeries()  #不能使用QSplineSeries
        seriesMA1.setName("MA5")
        pen.setColor(Qt.magenta)
        seriesMA1.setPen(pen)
        self.chart.addSeries(seriesMA1)
        seriesMA1.attachAxis(self.__axisX)
        seriesMA1.attachAxis(self.__axisY)

        seriesMA2 = QLineSeries()
        seriesMA2.setName("MA10")
        pen.setColor(Qt.yellow)
        seriesMA2.setPen(pen)
        self.chart.addSeries(seriesMA2)
        seriesMA2.attachAxis(self.__axisX)
        seriesMA2.attachAxis(self.__axisY)

        seriesMA3 = QLineSeries()
        seriesMA3.setName("MA20")
        pen.setColor(Qt.cyan)
        seriesMA3.setPen(pen)
        self.chart.addSeries(seriesMA3)
        seriesMA3.attachAxis(self.__axisX)
        seriesMA3.attachAxis(self.__axisY)

        seriesMA4 = QLineSeries()
        seriesMA4.setName("MA60")
        pen.setColor(Qt.green)  #green
        seriesMA4.setPen(pen)
        self.chart.addSeries(seriesMA4)
        seriesMA4.attachAxis(self.__axisX)
        seriesMA4.attachAxis(self.__axisY)

        ## 3. 填充数据到序列
        dataRowCount = self.itemModel.rowCount()  #数据点个数
        for i in range(dataRowCount):
            dateStr = self.itemModel.item(i, 0).text()  #日期字符串,如"2017/02/03"
            dateValue = QDate.fromString(dateStr, "yyyy/MM/dd")  #QDate
            dtValue = QDateTime(dateValue)  #日期时间 QDateTime
            timeStamp = dtValue.toMSecsSinceEpoch()  #毫秒数

            oneCandle = QCandlestickSet()  #QCandlestickSet
            oneCandle.setOpen(float(self.itemModel.item(i, 1).text()))  #开盘
            oneCandle.setHigh(float(self.itemModel.item(i, 2).text()))  #最高
            oneCandle.setLow(float(self.itemModel.item(i, 3).text()))  #最低
            oneCandle.setClose(float(self.itemModel.item(i, 4).text()))  #收盘
            oneCandle.setTimestamp(timeStamp)  #时间戳
            seriesCandle.append(oneCandle)  #添加到序列

            M1 = float(self.itemModel.item(i, 5).text())
            M2 = float(self.itemModel.item(i, 6).text())
            M3 = float(self.itemModel.item(i, 7).text())
            M4 = float(self.itemModel.item(i, 8).text())

            seriesMA1.append(timeStamp, M1)
            seriesMA2.append(timeStamp, M2)
            seriesMA3.append(timeStamp, M3)
            seriesMA4.append(timeStamp, M4)

    ## 4. 设置坐标轴范围
        minDateStr = self.itemModel.item(0, 0).text()  #日期字符串,如"2017/02/03"
        minDate = QDate.fromString(minDateStr, "yyyy/MM/dd")  #QDate
        minDateTime = QDateTime(minDate)  #最小日期时间,QDateTime

        maxDateStr = self.itemModel.item(dataRowCount - 1,
                                         0).text()  #日期字符串,如"2017/05/03"
        maxDate = QDate.fromString(maxDateStr, "yyyy/MM/dd")
        maxDateTime = QDateTime(maxDate)  #最大日期时间

        self.__axisX.setRange(minDateTime, maxDateTime)  #日期时间范围
        dateFormat = self.ui.comboDateFormat.currentText()  #格式,如"MM-dd"
        self.__axisX.setFormat(dateFormat)  #标签格式

        self.__axisY.applyNiceNumbers()  #自动

        for marker in self.chart.legend().markers():  #QLegendMarker类型列表
            marker.clicked.connect(self.do_LegendMarkerClicked)