def initChart(self): self._chart = QChart(title='蜡烛图悬浮提示') self._chart.setAnimationOptions(QChart.SeriesAnimations) series = QCandlestickSeries() series.setIncreasingColor(QColor(Qt.red)) series.setDecreasingColor(QColor(Qt.green)) series.setName(self.stocks['name'].iloc[0]) for _, stock in self.stocks.iterrows(): time_p = datetime.datetime.strptime(stock['trade_date'], '%Y%m%d') time_p = float(time.mktime(time_p.timetuple())) _set = QCandlestickSet(float(stock['open']), float(stock['high']), float(stock['low']), float(stock['close']), time_p, series) _set.hovered.connect(self.handleBarHoverd) # 鼠标悬停 series.append(_set) self._chart.addSeries(series) self._chart.createDefaultAxes() self._chart.setLocalizeNumbers(True) axis_x = self._chart.axisX() axis_y = self._chart.axisY() axis_x.setGridLineVisible(False) axis_y.setGridLineVisible(False) # axis_y.setLabelFormat("%.2f") axis_x.setCategories(self.category) max_p = self.stocks[['high', 'low']].stack().max() + 10 min_p = self.stocks[['high', 'low']].stack().min() - 10 axis_y.setRange(min_p, max_p) # chart的图例 legend = self._chart.legend() # 设置图例由Series来决定样式 legend.setMarkerShape(QLegend.MarkerShapeFromSeries) self.setChart(self._chart)
def appendCandlestickSeries(self, name): ls = QCandlestickSeries() ls.setName(name) ls.setIncreasingColor(QColor(Qt.green)) ls.setDecreasingColor(QColor(Qt.red)) self.series.append(ls) return ls
def addSeries( self, _x2idx: typing.Dict, _idx2x: list, _chart: QChart, _axis_x: QValueAxis, _axis_y: QValueAxis, ): series = QCandlestickSeries() series.setName(self.name) for x, y in zip(self.x_list, self.y_list): series.append(QCandlestickSet(*y, _x2idx[x])) if self.inc_color is not None: series.setIncreasingColor(self.inc_color) else: series.setIncreasingColor(QColor("#c41919")) if self.dec_color is not None: series.setDecreasingColor(self.dec_color) else: series.setDecreasingColor(QColor("#009f9f")) _chart.addSeries(series) _chart.setAxisX(_axis_x, series) _chart.setAxisY(_axis_y, series) if self.show_value: self.createShow()
def plot_candlechart(ohlc_data): app = ParaMakerApplication([]) #app.setStyleSheet("background-color:black;") series = QCandlestickSeries() series.setBodyOutlineVisible(False) series.setDecreasingColor(Qt.red) series.setIncreasingColor(Qt.green) rsi = qc.QLineSeries() # 5-days average data line rsi.append(QPointF(ohlc_data[300].timestamp, ohlc_data[300].closed)) rsi.append(QPointF(ohlc_data[700].timestamp, ohlc_data[700].closed)) #rsi.append(QPointF(ohlc_data[150].timestamp, ohlc_data[100].closed)) tm = [] # stores str type data # in a loop, series and rsi append corresponding data for candle in ohlc_data: series.append( QCandlestickSet(candle.opened, candle.high, candle.low, candle.closed)) #rsi.append(QPointF(num, m)) tm.append(str(candle.timestamp)) #rsi.append(str(candle.timestamp)) #rsi_values = calculate_rsi(14, ohlc_data) chart = QChart() chart.setBackgroundVisible(False) chart.setPlotAreaBackgroundVisible(False) chart.addSeries(series) # candle chart.addSeries(rsi) # rsi line #chart.axisX(rsi).setRange(ohlc_data[0].timestamp, ohlc_data[-1].timestamp) chart.createDefaultAxes() axisXRSI = QValueAxis() axisYRSI = QValueAxis() axisXRSI.setRange(ohlc_data[0].timestamp, ohlc_data[-1].timestamp) axisYRSI.setRange(ohlc_data[0].closed, ohlc_data[-1].closed) axisXRSI.setGridLineVisible(False) axisYRSI.setGridLineVisible(False) chart.setAxisX(axisXRSI, rsi) chart.setAxisY(axisYRSI, rsi) chart.legend().hide() chart.axisX(series).setCategories(tm) #chart.axisX(series).setGridLineVisible(False) #chart.axisY(series).setGridLineVisible(False) ###chart.axisX(rsi).setVisible(False) chartview = QChartView(chart) chartview.setRenderHint(QPainter.Antialiasing) ui = ParaMakerWindow() ui.setCentralWidget(chartview) sys.exit(app.exec_())
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)
def main (): if len (sys.argv) < 3: print ("файл не задан") sys.exit () with open (sys.argv[1], 'rt') as file: TicksFile = file.read() TicksTuple = tuple(TicksFile.split('\n')[:-1]) Bars = (FormBarFrame(TicksTuple, 60)) with open(sys.argv[1][:-4] + '_' + sys.argv[2] + '.bars', 'wt') as file: for i in reversed(Bars): file.write("{0} {1} {2} {3} {4} {5} {6}\n".format(str(i[0]), i[1], i[2], i[3], i[4], i[5], i[6])) # Вывод графика app = QApplication(sys.argv) series = QCandlestickSeries() series.setDecreasingColor(Qt.red) series.setIncreasingColor(Qt.green) #ma5 = qc.QLineSeries() # 5-days average data line tm = [] # stores str type data # in a loop, series and ma5 append corresponding data #for num, o, h, l, c in Bars: for i in range(len(Bars)): series.append(QCandlestickSet(Bars[i][1], Bars[i][4], Bars[i][3], Bars[i][2])) #ma5.append(QPointF(num, m)) tm.append(str(Bars[i][0])) chart = QChart() chart.addSeries(series) # candle #chart.addSeries(ma5) # ma5 line chart.setAnimationOptions(QChart.SeriesAnimations) chart.createDefaultAxes() chart.legend().hide() chart.axisX(series).setCategories(tm) #chart.axisX(ma5).setVisible(False) chartview = QChartView(chart) ui = QMainWindow() ui.setGeometry(50, 50, 500, 300) ui.setCentralWidget(chartview) ui.show() sys.exit(app.exec_())
def main(): import sys a = QApplication(sys.argv) acmeSeries = QCandlestickSeries() acmeSeries.setName("Acme Ltd") acmeSeries.setIncreasingColor(QColor(Qt.green)) acmeSeries.setDecreasingColor(QColor(Qt.red)) acmeData = QFile(":acme") if not acmeData.open(QIODevice.ReadOnly | QIODevice.Text): sys.exit(1) categories = [] dataReader = CandlestickDataReader(acmeData) while not dataReader.atEnd(): _set = dataReader.readCandlestickSet() if _set is not None: acmeSeries.append(_set) categories.append( QDateTime.fromMSecsSinceEpoch(int( _set.timestamp())).toString("dd")) chart = QChart() chart.addSeries(acmeSeries) chart.setTitle("Acme Ltd Historical Data (July 2015)") chart.setAnimationOptions(QChart.SeriesAnimations) chart.createDefaultAxes() axisX = chart.axes(Qt.Horizontal)[0] axisX.setCategories(categories) axisY = chart.axes(Qt.Vertical)[0] axisY.setMax(axisY.max() * 1.01) axisY.setMin(axisY.min() * 0.99) chart.legend().setVisible(True) chart.legend().setAlignment(Qt.AlignBottom) chartView = QChartView(chart) chartView.setRenderHint(QPainter.Antialiasing) window = QMainWindow() window.setCentralWidget(chartView) window.resize(800, 600) window.show() sys.exit(a.exec_())
class ChartTab(QChartView): def __init__(self): QChartView.__init__(self) self.chart = QChart() self.candleSeries = QCandlestickSeries(self) self.candleSeries.setIncreasingColor(Qt.blue) self.candleSeries.setBodyOutlineVisible(False) self.candleSeries.setDecreasingColor(Qt.red) self.candleSeries.setMaximumColumnWidth(20) self.candleSeries.clicked.connect(lambda set: print(set.high())) self.xAxis = QDateTimeAxis() self.xAxis.setTickCount(10) self.xAxis.setFormat("h:mm") self.yAxis = QValueAxis() for candle in data: self.addCandle( self.get_integer_price(candle[0]), self.get_integer_price(candle[1]), self.get_integer_price(candle[2]), self.get_integer_price(candle[3]), datetime.strptime(candle[4], '%Y%m%d%H%M%S').timestamp() * 1000) self.chart.addSeries(self.candleSeries) self.setChart(self.chart) self.chart.setAxisX(self.xAxis, self.candleSeries) self.chart.setAxisY(self.yAxis, self.candleSeries) self.chart.legend().setVisible(False) def mouseMoveEvent(self, QMouseEvent): chartValues = self.chart.mapToValue(QMouseEvent.pos()) price = chartValues.y() print(price) def addCandle(self, open, close, high, low, timestamp): candlestickSet = QCandlestickSet() candlestickSet.setOpen(open) candlestickSet.setClose(close) candlestickSet.setHigh(high) candlestickSet.setLow(low) candlestickSet.setTimestamp(timestamp) pen = QPen() candlestickSet.setPen(pen) self.candleSeries.append(candlestickSet) def get_integer_price(self, str_price): return int(str_price.strip()[1:])
class Display: def __init__(self): self.data = [] self.app = QApplication(sys.argv) self.series = QCandlestickSeries() self.series.setDecreasingColor(Qt.red) self.series.setIncreasingColor(Qt.green) self.win = QMainWindow() self.tm = [] # stores str type data def load_data(self, _data): self.data = _data # data format [[Open] [High] [Low] [Close] ] for i in range(len(self.data[0])): self.series.append( QCandlestickSet(float(self.data[0][i]), float(self.data[1][i]), float(self.data[2][i]), float(self.data[3][i]))) self.tm.append(str(i)) i = i + 1 def set_window_size(self, width, high, grid_x=20, grid_y=20): self.win.setGeometry(grid_x, grid_y, width, high) def run_app(self): chart = QChart() chart.addSeries(self.series) # candle chart.createDefaultAxes() chart.legend().hide() chart.axisX(self.series).setCategories(self.tm) chart_view = QChartView(chart) self.win.setGeometry(50, 50, 800, 500) self.win.setCentralWidget(chart_view) self.win.show() sys.exit(self.app.exec_())
def addSeries( self, _x2idx: typing.Dict, _idx2x: list, _chart: QChart, _axis_x: QValueAxis, _axis_y: QValueAxis ): series = QCandlestickSeries() series.setName(self.name) for x, y in zip(self.x_list, self.y_list): series.append(QCandlestickSet(*y, _x2idx[x])) if self.inc_color is not None: series.setIncreasingColor(self.inc_color) else: series.setIncreasingColor(QColor('#c41919')) if self.dec_color is not None: series.setDecreasingColor(self.dec_color) else: series.setDecreasingColor(QColor('#009f9f')) _chart.addSeries(series) _chart.setAxisX(_axis_x, series) _chart.setAxisY(_axis_y, series) if self.show_value: self.createShow()
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)
from PyQt5.QtCore import Qt from PyQt5.Qt import QMainWindow, QApplication, QColor, QDateTime, QIODevice, QFile, QPainter from PyQt5.QtChart import QChart, QChartView, QLineSeries, QCandlestickSeries, QCandlestickSet from candlestickdatareader import CandlestickDataReader # example qtcharts/examples/candlestickchart tranlated in python if __name__ == '__main__': import sys app = QApplication(sys.argv) # [1] acmeSeries = QCandlestickSeries() acmeSeries.setName("Acme Ltd") acmeSeries.setIncreasingColor(QColor("light green")) acmeSeries.setDecreasingColor(QColor("red")) # [1] # [2] load the data acmeData = QFile("acme_data.txt") if not acmeData.open(QIODevice.ReadOnly | QIODevice.Text): sys.exit(1) categories = [] dataReader = CandlestickDataReader(acmeData) while not dataReader.atEnd(): line = dataReader.read_candlestick_set() if line is not None: acmeSeries.append(line) categories.append( QDateTime.fromMSecsSinceEpoch(line.timestamp()).toString("dd"))
class CTViewPair(QWidget): def __init__(self, CTMain=None, exchange=None, base_curr=None, curr_curr=None, chart_lookback=None, chart_interval=None, order_book_depth=None): super().__init__() self._CTMain = CTMain self._exchange = exchange self._base_curr = base_curr self._curr_curr = curr_curr self._chart_lookback = chart_lookback self._chart_interval = chart_interval self._order_book_depth = order_book_depth if self._exchange is None: self._exchange = CTMain._settings['Initial Market View Exchange'] if self._base_curr is None: self._base_curr = CTMain._settings[ 'Initial Market View Base Currency'] if self._curr_curr is None: self._curr_curr = CTMain._settings[ 'Initial Market View Quote Currency'] if self._chart_lookback is None: self._chart_lookback = CTMain._settings[ 'Initial Market View Chart Lookback'] if self._chart_interval is None: self._chart_interval = CTMain._settings[ 'Initial Market View Chart Interval'] if self._order_book_depth is None: self._order_book_depth = CTMain._settings[ 'Default Order Book Depth'] if 'Fusion' in QStyleFactory.keys(): self.change_style('Fusion') self._layout = QGridLayout() self._order_book_widget = CTOrderBook(self._CTMain, None, None, None, None, self._order_book_depth) self.CandlestickSeries = QCandlestickSeries() self.CandlestickSeries.setIncreasingColor(Qt.green) self.CandlestickSeries.setDecreasingColor(Qt.red) self.VolumeBarSeries = QCandlestickSeries() self.VolumeBarSeries.setBodyWidth(1.0) self.VolumeBarSeries.setIncreasingColor(Qt.green) self.VolumeBarSeries.setDecreasingColor(Qt.red) # self._chart_view = CTChartView(self) # self._chart_view_volume = QChartView(self) # self._chart_view_volume.chart().legend().setVisible(False) exchanges = self._CTMain._Crypto_Trader.trader.keys() self._dropdown_exchange = Dropdown(exchanges, self._exchange) self._dropdown_exchange.activated[str].connect( self.refresh_dropdown_exchange_change) base_codes = sorted(self._CTMain._Crypto_Trader.trader[ self._exchange]._active_markets.keys()) self._dropdown_base_curr = Dropdown(base_codes, self._base_curr) self._dropdown_base_curr.activated[str].connect( self.refresh_dropdown_base_change) curr_codes = sorted(self._CTMain._Crypto_Trader.trader[ self._exchange]._active_markets[self._base_curr].keys()) self._dropdown_curr_curr = Dropdown(curr_codes, self._curr_curr) self._dropdown_curr_curr.activated[str].connect( self.refresh_dropdown_curr_change) # label_lookback = QLabel("Lookback:") # self._chart_dropdown_lookback = Dropdown( # list(self._CTMain._settings['Chart Lookback Window']), # self._chart_lookback # ) # self._chart_dropdown_lookback.currentTextChanged.connect(self.draw_chart) # label_interval = QLabel("Interval:") # self._chart_dropdown_interval = Dropdown( # list(self._CTMain._settings['Chart Interval']), # self._chart_interval # ) # self._chart_dropdown_interval.currentTextChanged.connect(self.draw_chart) self._market_symbol = self._CTMain._Crypto_Trader.get_market_symbol( self._exchange, self._base_curr, self._curr_curr) self._trade_widget = CTTradeWidget(self._CTMain, self._exchange, self._base_curr, self._curr_curr, self._market_symbol) self._open_orders_widget = CTOpenOrdersWidget(self._CTMain, self._exchange, self._market_symbol) self._recent_trades_widget = CTRecentTradesWidget( self._CTMain, self._exchange, self._base_curr, self._curr_curr, self._market_symbol) self.refresh_dropdown_exchange_change(self._exchange, self._base_curr, self._curr_curr) label_exchange = QLabel("&Exchange:") label_exchange.setBuddy(self._dropdown_exchange) label_base_curr = QLabel("&Base:") label_base_curr.setBuddy(self._dropdown_base_curr) label_curr_curr = QLabel("&Currency:") label_curr_curr.setBuddy(self._dropdown_curr_curr) self._debug_button = QPushButton() self._debug_button.setText("Debug") self._debug_button.clicked.connect(self.debug) top_layout = QHBoxLayout() top_layout.addWidget(label_exchange) top_layout.addWidget(self._dropdown_exchange) top_layout.addWidget(label_base_curr) top_layout.addWidget(self._dropdown_base_curr) top_layout.addWidget(label_curr_curr) top_layout.addWidget(self._dropdown_curr_curr) # top_layout.addWidget(label_lookback) # top_layout.addWidget(self._chart_dropdown_lookback) # top_layout.addWidget(label_interval) # top_layout.addWidget(self._chart_dropdown_interval) top_layout.addWidget(self._debug_button) top_layout.addStretch(1) self._layout.addLayout(top_layout, 0, 0, 1, 10) self._splitter_top = QSplitter(Qt.Horizontal) self._splitter_left = QSplitter(Qt.Vertical) self._splitter_left.addWidget(self._order_book_widget) self._splitter_left.addWidget(self._recent_trades_widget) self._splitter_left.addWidget(self._trade_widget) self._splitter_left.setSizes([500, 100, 100]) self._splitter_right = QSplitter(Qt.Vertical) # self._splitter_right.addWidget(self._chart_view) # self._splitter_right.addWidget(self._chart_view_volume) self._splitter_right.addWidget(self._open_orders_widget) self._splitter_right.setSizes([500, 100, 100]) self._splitter_top.addWidget(self._splitter_left) self._splitter_top.addWidget(self._splitter_right) window_width = self._CTMain.frameGeometry().width() self._splitter_top.setSizes( [round(0.3 * window_width), round(0.7 * window_width)]) self._layout.addWidget(self._splitter_top, 1, 0, 9, 10) self.setLayout(self._layout) self.show() def refresh_dropdown_exchange_change(self, exchange, default_base=None, default_curr=None): self._exchange = exchange if default_base is None: default_base = self._dropdown_base_curr.currentText if default_curr is None: default_curr = self._dropdown_curr_curr.currentText base_codes = sorted( list(self._CTMain._Crypto_Trader.trader[exchange]._active_markets)) self._dropdown_base_curr.clear() self._dropdown_base_curr.addItems(base_codes) if default_base not in base_codes: default_base = base_codes[0] self._dropdown_base_curr.setCurrentText(default_base) self.refresh_dropdown_base_change(default_base, default_curr) def refresh_dropdown_base_change(self, base_curr, default_curr=None): self._base_curr = base_curr if default_curr is None: default_curr = self._dropdown_curr_curr.currentText curr_codes = sorted( list(self._CTMain._Crypto_Trader.trader[ self._exchange]._active_markets[base_curr])) self._dropdown_curr_curr.clear() self._dropdown_curr_curr.addItems(curr_codes) if default_curr not in curr_codes: default_curr = curr_codes[0] self._dropdown_curr_curr.setCurrentText(default_curr) self.refresh_dropdown_curr_change(default_curr) def refresh_dropdown_curr_change(self, curr_curr): self._curr_curr = curr_curr self._market_symbol = self._CTMain._Crypto_Trader.get_market_symbol( self._exchange, self._base_curr, curr_curr) self.initiate_widgets() @staticmethod def change_style(style_name): QApplication.setStyle(QStyleFactory.create(style_name)) @staticmethod def debug(): import ipdb ipdb.set_trace() # def refresh(self): # t = threading.Thread(target = self.refresh_widgets) # t.start() # t.join(1) def initiate_widgets(self): self._order_book_widget.refresh_order_book(self._exchange, self._market_symbol, self._base_curr, self._curr_curr) self._trade_widget.update_currencies(self._exchange, self._base_curr, self._curr_curr, self._market_symbol) self._open_orders_widget.update_market(self._exchange, self._market_symbol) self._recent_trades_widget.update_market(self._exchange, self._base_curr, self._curr_curr, self._market_symbol) # self.draw_chart() def draw_chart(self): exchange = self._exchange market_symbol = self._market_symbol interval_name = self._chart_dropdown_interval.currentText() lookback_name = self._chart_dropdown_lookback.currentText() interval = self._CTMain._settings['Chart Interval'][interval_name] lookback = self._CTMain._settings['Chart Lookback Window'][ lookback_name] load_chart = self._CTMain._Crypto_Trader.trader[ exchange].load_chart_data(market_symbol, interval, lookback) self.CandlestickSeries.clear() self.VolumeBarSeries.clear() ch_min = load_chart[0][3] ch_max = load_chart[0][2] t_min = load_chart[0][0] t_max = load_chart[0][0] v_max = load_chart[0][6] for point in load_chart: candle = CTCandlestickSet(timestamp=point[0] * 1000, c_open=point[1], c_high=point[2], c_low=point[3], c_close=point[4], volume=point[5], base_volume=point[6], base_curr=self._base_curr, curr_curr=self._curr_curr, parent=self) self.CandlestickSeries.append(candle) ch_min = min(ch_min, point[3]) ch_max = max(ch_max, point[2]) t_min = min(t_min, point[0]) t_max = max(t_max, point[0]) v_max = max(v_max, point[6]) min_y = max(0, ch_min - 0.15 * (ch_max - ch_min)) max_y = ch_max + 0.1 * (ch_max - ch_min) max_volume = 0 for point in load_chart: # high = min_y + 0.1 * (max_y - min_y) * point[6] / v_max # low = min_y v_low = 0 v_high = point[6] max_volume = max(max_volume, point[6]) if point[4] >= point[1]: v_open = v_low v_close = v_high else: v_open = v_high v_close = v_low volume_candle = QCandlestickSet(v_open, v_high, v_low, v_close, point[0] * 1000, self) self.VolumeBarSeries.append(volume_candle) if not self._chart_view._chart_loaded: self._chart_view.chart.addSeries(self.CandlestickSeries) self._chart_view_volume.chart().addSeries(self.VolumeBarSeries) self._chart_view._chart_loaded = True axis_x = QDateTimeAxis() axis_x.setFormat("dd-MM-yyyy h:mm") axis_x.setRange(datetime.fromtimestamp(int(t_min) - 30 * interval), datetime.fromtimestamp(int(t_max) + 30 * interval)) self._chart_view.chart.setAxisX(axis_x, self.CandlestickSeries) axis_y = QValueAxis() axis_y.setRange(min_y, max_y) self._chart_view.chart.setAxisY(axis_y, self.CandlestickSeries) axis_x2 = QDateTimeAxis() axis_x2.setFormat("dd-MM-yyyy h:mm") axis_x2.setRange(datetime.fromtimestamp(int(t_min) - 30 * interval), datetime.fromtimestamp(int(t_max) + 30 * interval)) self._chart_view_volume.chart().setAxisX(axis_x2, self.VolumeBarSeries) axis_y2 = QValueAxis() axis_y2.setRange(0, max_volume) self._chart_view_volume.chart().setAxisY(axis_y2, self.VolumeBarSeries)
class KLineChartView(QChartView): # QCandlestickSeries的hovered的信号响应后传递日期出去 candles_hovered = pyqtSignal(bool, str) def __init__(self, data: pd.DataFrame): super(KLineChartView, self).__init__() self.setRenderHint(QPainter.Antialiasing) # 抗锯齿 self._chart = QChart() self._series = QCandlestickSeries() self._stocks = data self._category = list() self._count = None self.init_chart() self._zero_value = (0, self._chart.axisY().min()) self._max_value = (len(self._chart.axisX().categories()), self._chart.axisY().max()) self._zero_point = self._chart.mapToPosition( QPointF(self._zero_value[0], self._zero_value[1])) self._max_point = self._chart.mapToPosition( QPointF(self._max_value[0], self._max_value[1])) # 计算x轴单个cate的宽度,用来处理横线不能画到边界 self._cate_width = (self._max_point.x() - self._zero_point.x()) / len( self._category) self._series.hovered.connect(self.on_series_hovered) def on_series_hovered(self, status, candles_set): trade_date = time.strftime('%Y%m%d', time.localtime(candles_set.timestamp())) self.candles_hovered.emit(status, trade_date) def set_name(self, name): self._series.setName(name) def clear_series_values(self): self._series.clear() self._chart.axisY().setRange(0, 10) self._chart.axisX().setCategories(list()) self._stocks = None def add_series_values(self, data: pd.DataFrame, is_init=False): self._stocks = data self._category = self._stocks['trade_date'] self._count = len(self._category) for _, stock in self._stocks.iterrows(): time_p = datetime.datetime.strptime(stock['trade_date'], '%Y%m%d') time_p = float(time.mktime(time_p.timetuple())) _set = QCandlestickSet(float(stock['open']), float(stock['high']), float(stock['low']), float(stock['close']), time_p, self._series) self._series.append(_set) if not is_init: self._stocks = data self._category = self._stocks['trade_date'] axis_x = self._chart.axisX() axis_y = self._chart.axisY() axis_x.setCategories(self._category) max_p = self._stocks[['high', 'low']].stack().max() min_p = self._stocks[['high', 'low']].stack().min() axis_y.setRange(min_p * 0.99, max_p * 1.01) self._zero_value = (0, self._chart.axisY().min()) self._max_value = (len(self._chart.axisX().categories()), self._chart.axisY().max()) # 计算x轴单个cate的宽度,用来处理横线不能画到边界 self._cate_width = (self._max_point.x() - self._zero_point.x()) / len(self._category) def resizeEvent(self, event): super(KLineChartView, self).resizeEvent(event) self._zero_point = self._chart.mapToPosition( QPointF(self._zero_value[0], self._zero_value[1])) self._max_point = self._chart.mapToPosition( QPointF(self._max_value[0], self._max_value[1])) self._cate_width = (self._max_point.x() - self._zero_point.x()) / len( self._category) def max_point(self): return QPointF(self._max_point.x() + self._cate_width / 2, self._max_point.y()) def min_point(self): return QPointF(self._zero_point.x() - self._cate_width / 2, self._zero_point.y()) def init_chart(self): self._chart.setAnimationOptions(QChart.SeriesAnimations) self._series.setIncreasingColor(QColor(Qt.red)) self._series.setDecreasingColor(QColor(Qt.green)) self._series.setName(self._stocks['name'].iloc[0]) self.add_series_values(self._stocks, True) self._chart.addSeries(self._series) self._chart.createDefaultAxes() self._chart.setLocalizeNumbers(True) axis_x = self._chart.axisX() axis_y = self._chart.axisY() axis_x.setGridLineVisible(False) axis_y.setGridLineVisible(False) axis_x.setCategories(self._category) axis_x.setLabelsVisible(False) axis_x.setVisible(False) max_p = self._stocks[['high', 'low']].stack().max() min_p = self._stocks[['high', 'low']].stack().min() axis_y.setRange(min_p * 0.99, max_p * 1.01) # chart的图例 legend = self._chart.legend() # 设置图例由Series来决定样式 legend.setMarkerShape(QLegend.MarkerShapeFromSeries) self.setChart(self._chart) # 设置外边界全部为0 self._chart.layout().setContentsMargins(0, 0, 0, 0) # 设置内边界的bottom为0 margins = self._chart.margins() self._chart.setMargins(QMargins(margins.left(), 0, margins.right(), 0)) # 设置背景区域无圆角 self._chart.setBackgroundRoundness(0)
class MainWindow(QMainWindow): def __init__(self, data, parent=None): super().__init__(parent) self.data = data self.centralwidget = QWidget(self) self.centralwidget.setObjectName("centralwidget") self.label = QLabel(self.centralwidget) self.label.setGeometry(QRect(0, 0, 261, 31)) font = QtGui.QFont() font.setFamily("Consolas") font.setPointSize(18) self.label.setFont(font) self.label.setTextFormat(Qt.AutoText) self.label.setObjectName("label") self.series = QCandlestickSeries() self.series.setDecreasingColor(Qt.red) self.series.setIncreasingColor(Qt.green) self.ma5 = qc.QLineSeries() self.tm = [] self.chart = QChart() self.chart.addSeries(self.series) # candle self.chart.addSeries(self.ma5) # ma5 line self.chart.createDefaultAxes() self.chart.legend().hide() self.chart.axisX(self.series).setCategories(self.tm) self.chart.axisX(self.ma5).setVisible(False) self.chartview = QChartView(self.chart) self.setGeometry(50, 50, 500, 300) self.setCentralWidget(self.chartview) def append_data_and_plot(self, d): """Append and update the plot""" num, o, h, l, c, m = d ax1 = self.chart.axisX(self.ma5) ay1 = self.chart.axisY(self.ma5) xmin = xmax = num ymin = ymax = m step = 10 offset = 100 for p in self.ma5.pointsVector()[-step:]: xmin = min(p.x(), xmin) xmax = max(p.x(), xmax) ymin = min(p.y(), ymin) - offset ymax = max(p.y(), ymax) + offset xmin = max(0, xmax - step) ax1.setMin(xmin) ax1.setMax(xmax) ay1.setMin(ymin) ay1.setMax(ymax) self.ma5.append(QPointF(num, m)) self.tm.append(str(num)) self.series.append(QCandlestickSet(o, h, l, c)) ax2 = self.chart.axisX(self.series) ax2.setCategories(self.tm) ax2.setMin(str(xmin)) ax2.setMax(str(xmax)) ay2 = self.chart.axisY(self.series) ay2.setMin(ymin) ay2.setMax(ymax)
class Ui_MainWindow(object): start = ('2021-01-01') end = datetime.datetime.now() df = web.DataReader('AAPL', 'yahoo', start=start, end=end) def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(1025, 770) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.splitter = QtWidgets.QSplitter(self.centralwidget) self.splitter.setGeometry(QtCore.QRect(10, 595, 500, 41)) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setObjectName("splitter") self.qLineEdit = QtWidgets.QLineEdit(self.splitter) MainWindow.setCentralWidget(self.centralwidget) self.qLineEdit.setObjectName("lineEdit") self.graphicsView = PlotWidget(self.centralwidget) self.graphicsView.setGeometry(QtCore.QRect(10, 20, 1000, 550)) self.graphicsView.setObjectName("graphicsView") self.graphicsView.setBackground('w') self.graphicsView.setLabel( 'left', "<span style=\"color:black;font-size:30px\">Dollars</span>") self.graphicsView.setLabel( 'bottom', "<span style=\"color:black;font-size:30px\">Date</span>") self.split = QtWidgets.QSplitter(self.centralwidget) self.split.setGeometry(QtCore.QRect(10, 695, 800, 41)) self.split.setOrientation(QtCore.Qt.Horizontal) self.split.setObjectName("splitter2") self.split2 = QtWidgets.QSplitter(self.centralwidget) self.split2.setGeometry(QtCore.QRect(10, 645, 800, 41)) self.split2.setOrientation(QtCore.Qt.Horizontal) self.split2.setObjectName("splitter3") self.series = QCandlestickSeries() self.series.setDecreasingColor(Qt.red) self.series.setIncreasingColor(Qt.green) self.searchButton = QtWidgets.QPushButton(self.splitter) font = QtGui.QFont() font.setPointSize(8) font.setBold(True) font.setWeight(75) self.searchButton.setFont(font) self.searchButton.setObjectName("searchButton") self.fiveDayMA = QtWidgets.QCheckBox(self.split) self.fiveDayMA.setFont(font) self.fiveDayMA.setObjectName("fiveDayMA") self.tenDayMA = QtWidgets.QCheckBox(self.split) self.tenDayMA.setFont(font) self.tenDayMA.setObjectName("oneMonthMA") self.twentyDayMA = QtWidgets.QCheckBox(self.split) self.twentyDayMA.setFont(font) self.twentyDayMA.setObjectName("twoMonthMA") self.oneMonthMA = QtWidgets.QCheckBox(self.split) self.oneMonthMA.setFont(font) self.oneMonthMA.setObjectName("threeMonthMA") self.oneDayButton = QtWidgets.QPushButton(self.split2) self.oneDayButton.setFont(font) self.oneDayButton.setObjectName("oneDayButton") self.oneMonthButton = QtWidgets.QPushButton(self.split2) self.oneMonthButton.setFont(font) self.oneMonthButton.setObjectName("oneMonthButton") MainWindow.setCentralWidget(self.centralwidget) self.threeMonthButton = QtWidgets.QPushButton(self.split2) self.threeMonthButton.setFont(font) self.threeMonthButton.setObjectName("threeMonthButton") MainWindow.setCentralWidget(self.centralwidget) self.oneYearButton = QtWidgets.QPushButton(self.split2) self.oneYearButton.setFont(font) self.oneYearButton.setObjectName("oneYearButton") MainWindow.setCentralWidget(self.centralwidget) self.fiveYearButton = QtWidgets.QPushButton(self.split2) self.fiveYearButton.setFont(font) self.fiveYearButton.setObjectName("fiveYearButton") MainWindow.setCentralWidget(self.centralwidget) self.maxButton = QtWidgets.QPushButton(self.split2) self.maxButton.setFont(font) self.maxButton.setObjectName("maxButton") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 497, 21)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) self.oneDayButton.clicked.connect(lambda: self.one_day_clicked()) self.oneMonthButton.clicked.connect(lambda: self.one_month_clicked()) self.threeMonthButton.clicked.connect( lambda: self.three_months_clicked()) self.oneYearButton.clicked.connect(lambda: self.one_year_clicked()) self.fiveYearButton.clicked.connect(lambda: self.five_years_clicked()) self.searchButton.clicked.connect(lambda: self.search_button_clicked()) self.maxButton.clicked.connect(lambda: self.max_clicked()) self.fiveDayMA.clicked.connect( lambda: self.five_day_ma_clicked(self.fiveDayMA.isChecked())) self.tenDayMA.clicked.connect( lambda: self.ten_day_ma_clicked(self.tenDayMA.isChecked())) self.twentyDayMA.clicked.connect( lambda: self.twenty_day_ma_clicked(self.twentyDayMA.isChecked())) self.oneMonthMA.clicked.connect( lambda: self.one_month_ma_clicked(self.oneMonthMA.isChecked())) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.searchButton.setText(_translate("MainWindow", "Search")) self.oneDayButton.setText(_translate("MainWindow", "1 day")) self.oneMonthButton.setText(_translate("MainWindow", "1 Month")) self.threeMonthButton.setText(_translate("MainWindow", "3 Months")) self.oneYearButton.setText(_translate("MainWindow", "1 Year")) self.fiveYearButton.setText(_translate("MainWindow", "5 Years")) self.maxButton.setText(_translate("MainWindow", "Max")) self.fiveDayMA.setText(_translate("MainWindow", "5 Days MA")) self.tenDayMA.setText(_translate("MainWindow", "10 Days MA")) self.twentyDayMA.setText(_translate("MainWindow", "20 days MA")) self.oneMonthMA.setText(_translate("MainWindow", "1 Month MA")) def search_button_clicked(self): self.graphicsView.clear() self.start = datetime.datetime(2020, 5, 11) self.end = datetime.datetime.now() self.df = web.DataReader(self.qLineEdit.text(), 'yahoo', self.start, self.end) stock = self.qLineEdit.text() stock = stock.upper() + " Stock" self.graphicsView.plot(self.df['Adj Close'], label='AAPL', pen=pen) self.graphicsView.setTitle(stock) def one_day_clicked(self): self.graphicsView.clear() global start, end, df start = datetime.datetime(2020, 5, 11) end = datetime.datetime.now() df = web.DataReader(self.qLineEdit.text(), 'yahoo', start, end) stock = self.qLineEdit.text() stock = stock.upper() + " Stock" self.graphicsView.plot(df['Adj Close'], pen=pen) def one_month_clicked(self): self.graphicsView.clear() global start, end, df start = datetime.datetime(2020, 4, 1) end = datetime.datetime.now() df = web.DataReader(self.qLineEdit.text(), 'yahoo', start, end) self.graphicsView.plot(df['Adj Close'], pen=pen) def three_months_clicked(self): self.graphicsView.clear() global start, end, df start = datetime.datetime(2020, 2, 1) end = datetime.datetime.now() df = web.DataReader(self.qLineEdit.text(), 'yahoo', start, end) self.graphicsView.plot(df['Adj Close'], pen=pen) def one_year_clicked(self): self.graphicsView.clear() global start, end, df start = datetime.datetime(2019, 1, 1) end = datetime.datetime.now() df = web.DataReader(self.qLineEdit.text(), 'yahoo', start, end) self.graphicsView.plot(df['Adj Close'], pen=pen) def five_years_clicked(self): self.graphicsView.clear() global start, end, df start = datetime.datetime(2015, 1, 1) end = datetime.datetime.now() df = web.DataReader(self.qLineEdit.text(), 'yahoo', start, end) self.graphicsView.plot(df['Adj Close'], pen=pen) def max_clicked(self): self.graphicsView.clear() global start, end, df start = datetime.datetime(1990, 1, 1) end = datetime.datetime.now() df = web.DataReader(self.qLineEdit.text(), 'yahoo', start, end) self.graphicsView.plot(df['Adj Close'], pen=pen) def five_day_ma_clicked(self, chx): pen2 = pg.mkPen(color=(255, 0, 0)) if chx: #self.graphicsView.clear() df['SMA_5'] = df.iloc[:, 1].rolling(window=5).mean() df.fillna(0, inplace=True) self.graphicsView.plot(df['Adj Close'], pen=pen) self.graphicsView.plot(df['SMA_5'], label="5 Day MA", pen=pen2) else: self.graphicsView.clear() #if self.tenDayMA.isChecked(): # self.graphicsView.plot(df['SMA_10']) #elif self.twentyDayMA.isChecked(): # self.graphicsView.plot(df['SMA_20']) #elif self.oneMonthMA.isChecked(): # self.graphicsView.plot(df['SMA_30']) self.graphicsView.plot(df['Adj Close'], pen=pen) def check(self): if self.tenDayMA.isChecked() and self.twentyDayMA.isChecked( ) and self.fiveDayMA.ischecked() and self.oneMonthMA.isChecked(): self.graphicsView.plot(df['SMA_5']) self.graphicsView.plot(df['SMA_10']) self.graphicsView.plot(df['SMA_20']) self.graphicsView.plot(df['SMA_30']) if self.tenDayMA.isChecked() and self.twentyDayMA.isChecked( ) and self.oneMonthMA.isChecked(): self.graphicsView.plot(df['SMA_10']) self.graphicsView.plot(df['SMA_20']) self.graphicsView.plot(df['SMA_30']) def ten_day_ma_clicked(self, chx): pen3 = pg.mkPen(color=(0, 0, 255)) if chx: #self.graphicsView.clear() df['SMA_10'] = df.iloc[:, 1].rolling(window=10).mean() df.fillna(0, inplace=True) self.graphicsView.plot(df['Adj Close'], pen=pen) self.graphicsView.plot(df['SMA_10'], label="10 Day MA", pen=pen3) else: self.graphicsView.clear() self.graphicsView.plot(df['Adj Close'], pen=pen) def twenty_day_ma_clicked(self, chx): pen4 = pg.mkPen(color=(0, 128, 0)) if chx: #self.graphicsView.clear() df['SMA_15'] = df.iloc[:, 1].rolling(window=15).mean() df.fillna(0, inplace=True) self.graphicsView.plot(df['Adj Close'], pen=pen) self.graphicsView.plot(df['SMA_15'], pen=pen4) else: self.graphicsView.clear() self.graphicsView.plot(df['Adj Close'], pen=pen) def one_month_ma_clicked(self, chx): pen5 = pg.mkPen(color=(255, 165, 0)) if chx: #self.graphicsView.clear() df['SMA_20'] = df.iloc[:, 1].rolling(window=20).mean() df.fillna(0, inplace=True) print(df.head(40)) self.graphicsView.plot(df['Adj Close'], pen=pen) self.graphicsView.plot(df['SMA_20'], label="3 Month MA", pen=pen5) else: self.graphicsView.clear() self.graphicsView.plot(df['Adj Close'], pen=pen) def clear(self): self.graphicsView.clear()
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)
data = ( (1, 7380, 7520, 7380, 7510, 7324), (2, 7520, 7580, 7410, 7440, 7372), (3, 7440, 7650, 7310, 7520, 7434), (4, 7450, 7640, 7450, 7550, 7480), (5, 7510, 7590, 7460, 7490, 7502), (6, 7500, 7590, 7480, 7560, 7512), (7, 7560, 7830, 7540, 7800, 7584), ) app = QApplication(sys.argv) # series = QCandlestickSeries() series.setDecreasingColor(Qt.red) series.setIncreasingColor(Qt.green) ma5 = qc.QLineSeries() # 5-days average data line tm = [] # stores str type data # in a loop, series and ma5 append corresponding data for num, o, h, l, c, m in data: series.append(QCandlestickSet(o, h, l, c)) ma5.append(QPointF(num, m)) tm.append(str(num)) chart = QChart() chart.addSeries(series) # candle chart.addSeries(ma5) # ma5 line