diff --git a/examples/candle_chart/run.py b/examples/candle_chart/run.py index c4114cb9..1059fe6c 100644 --- a/examples/candle_chart/run.py +++ b/examples/candle_chart/run.py @@ -35,7 +35,7 @@ if __name__ == "__main__": timer = QtCore.QTimer() timer.timeout.connect(update_bar) - timer.start(100) + # timer.start(100) widget.show() app.exec_() diff --git a/vnpy/app/cta_backtester/engine.py b/vnpy/app/cta_backtester/engine.py index bfb7b91d..ea9a368b 100644 --- a/vnpy/app/cta_backtester/engine.py +++ b/vnpy/app/cta_backtester/engine.py @@ -402,3 +402,7 @@ class BacktesterEngine(BaseEngine): def get_all_daily_results(self): """""" return self.backtesting_engine.get_all_daily_results() + + def get_history_data(self): + """""" + return self.backtesting_engine.history_data diff --git a/vnpy/app/cta_backtester/ui/widget.py b/vnpy/app/cta_backtester/ui/widget.py index 4efec8ac..ffa43db3 100644 --- a/vnpy/app/cta_backtester/ui/widget.py +++ b/vnpy/app/cta_backtester/ui/widget.py @@ -14,6 +14,7 @@ from vnpy.trader.engine import MainEngine from vnpy.trader.ui import QtCore, QtWidgets, QtGui from vnpy.trader.ui.widget import BaseMonitor, BaseCell, DirectionCell, EnumCell from vnpy.event import Event, EventEngine +from vnpy.chart import ChartWidget, CandleItem, VolumeItem class BacktesterManager(QtWidgets.QWidget): @@ -108,6 +109,10 @@ class BacktesterManager(QtWidgets.QWidget): self.daily_button.clicked.connect(self.show_daily_results) self.daily_button.setEnabled(False) + self.candle_button = QtWidgets.QPushButton("K线图表") + self.candle_button.clicked.connect(self.show_candle_chart) + self.candle_button.setEnabled(False) + for button in [ backtesting_button, optimization_button, @@ -115,7 +120,8 @@ class BacktesterManager(QtWidgets.QWidget): self.result_button, self.order_button, self.trade_button, - self.daily_button + self.daily_button, + self.candle_button ]: button.setFixedHeight(button.sizeHint().height() * 2) @@ -139,6 +145,7 @@ class BacktesterManager(QtWidgets.QWidget): left_vbox.addWidget(self.trade_button) left_vbox.addWidget(self.order_button) left_vbox.addWidget(self.daily_button) + left_vbox.addWidget(self.candle_button) left_vbox.addStretch() left_vbox.addWidget(optimization_button) left_vbox.addWidget(self.result_button) @@ -171,6 +178,9 @@ class BacktesterManager(QtWidgets.QWidget): DailyResultMonitor ) + # Candle Chart + self.candle_dialog = CandleChartDialog() + # Layout vbox = QtWidgets.QVBoxLayout() vbox.addWidget(self.statistics_monitor) @@ -218,6 +228,7 @@ class BacktesterManager(QtWidgets.QWidget): self.trade_button.setEnabled(True) self.order_button.setEnabled(True) self.daily_button.setEnabled(True) + self.candle_button.setEnabled(True) def process_optimization_finished_event(self, event: Event): """""" @@ -267,10 +278,12 @@ class BacktesterManager(QtWidgets.QWidget): self.trade_button.setEnabled(False) self.order_button.setEnabled(False) self.daily_button.setEnabled(False) + self.candle_button.setEnabled(False) self.trade_dialog.clear_data() self.order_dialog.clear_data() self.daily_dialog.clear_data() + self.candle_dialog.clear_data() def start_optimization(self): """""" @@ -362,6 +375,17 @@ class BacktesterManager(QtWidgets.QWidget): self.daily_dialog.exec_() + def show_candle_chart(self): + """""" + if not self.candle_dialog.is_updated(): + history = self.backtester_engine.get_history_data() + self.candle_dialog.update_history(history) + + trades = self.backtester_engine.get_all_trades() + self.candle_dialog.update_trades(trades) + + self.candle_dialog.exec_() + def show(self): """""" self.showMaximized() @@ -941,3 +965,49 @@ class BacktestingResultDialog(QtWidgets.QDialog): def is_updated(self): """""" return self.updated + + +class CandleChartDialog(QtWidgets.QDialog): + """ + """ + + def __init__(self): + """""" + super().__init__() + + self.updated = False + self.init_ui() + + def init_ui(self): + """""" + self.setWindowTitle("回测K线图表") + self.resize(1400, 800) + + self.chart = ChartWidget() + self.chart.add_plot("candle", hide_x_axis=True) + self.chart.add_plot("volume", maximum_height=200) + self.chart.add_item(CandleItem, "candle", "candle") + self.chart.add_item(VolumeItem, "volume", "volume") + self.chart.add_cursor() + + vbox = QtWidgets.QVBoxLayout() + vbox.addWidget(self.chart) + self.setLayout(vbox) + + def update_history(self, history: list): + """""" + self.updated = True + self.chart.update_history(history) + + def update_trades(self, trades: list): + """""" + pass + + def clear_data(self): + """""" + self.updated = False + self.chart.clear_all() + + def is_updated(self): + """""" + return self.updated \ No newline at end of file