def _draw_bar_picture(self, ix: int, bar: BarData) -> QtGui.QPicture: """""" # Create objects volume_picture = QtGui.QPicture() painter = QtGui.QPainter(volume_picture) # Set painter color if bar.close_price >= bar.open_price: painter.setPen(self._up_pen) painter.setBrush(self._up_brush) else: painter.setPen(self._down_pen) painter.setBrush(self._down_brush) # Draw volume body rect = QtCore.QRectF( ix - BAR_WIDTH, 0, BAR_WIDTH * 2, bar.volume ) painter.drawRect(rect) # Finish painter.end() return volume_picture
def init_ui(self): """""" form = QtWidgets.QFormLayout() # Add spread_name and name edit if add new strategy if self.class_name: self.setWindowTitle(f"添加策略:{self.class_name}") button_text = "添加" parameters = {"strategy_name": "", "spread_name": ""} parameters.update(self.parameters) else: self.setWindowTitle(f"参数编辑:{self.strategy_name}") button_text = "确定" parameters = self.parameters for name, value in parameters.items(): type_ = type(value) edit = QtWidgets.QLineEdit(str(value)) if type_ is int: validator = QtGui.QIntValidator() edit.setValidator(validator) elif type_ is float: validator = QtGui.QDoubleValidator() edit.setValidator(validator) form.addRow(f"{name} {type_}", edit) self.edits[name] = (edit, type_) button = QtWidgets.QPushButton(button_text) button.clicked.connect(self.accept) form.addRow(button) self.setLayout(form)
def _draw_item_picture(self, min_ix: int, max_ix: int) -> None: """ Draw the picture of item in specific range. """ self._item_picuture = QtGui.QPicture() painter = QtGui.QPainter(self._item_picuture) for n in range(min_ix, max_ix): bar_picture = self._bar_picutures[n] bar_picture.play(painter) painter.end()
def _draw_bar_picture(self, ix: int, bar: BarData) -> QtGui.QPicture: """""" # Create objects candle_picture = QtGui.QPicture() painter = QtGui.QPainter(candle_picture) # Set painter color if bar.close_price >= bar.open_price: painter.setPen(self._up_pen) painter.setBrush(self._black_brush) else: painter.setPen(self._down_pen) painter.setBrush(self._down_brush) # Draw candle shadow if bar.high_price > bar.low_price: painter.drawLine( QtCore.QPointF(ix, bar.high_price), QtCore.QPointF(ix, bar.low_price) ) # Draw candle body if bar.open_price == bar.close_price: painter.drawLine( QtCore.QPointF(ix - BAR_WIDTH, bar.open_price), QtCore.QPointF(ix + BAR_WIDTH, bar.open_price), ) else: rect = QtCore.QRectF( ix - BAR_WIDTH, bar.open_price, BAR_WIDTH * 2, bar.close_price - bar.open_price ) painter.drawRect(rect) # Finish painter.end() return candle_picture
def init_ui(self): """""" form = QtWidgets.QFormLayout() # Add vt_symbol and name edit if add new strategy self.setWindowTitle(f"策略参数配置:{self.class_name}") button_text = "确定" parameters = self.parameters for name, value in parameters.items(): type_ = type(value) edit = QtWidgets.QLineEdit(str(value)) if type_ is int: validator = QtGui.QIntValidator() edit.setValidator(validator) elif type_ is float: validator = QtGui.QDoubleValidator() edit.setValidator(validator) form.addRow(f"{name} {type_}", edit) self.edits[name] = (edit, type_) button = QtWidgets.QPushButton(button_text) button.clicked.connect(self.accept) form.addRow(button) widget = QtWidgets.QWidget() widget.setLayout(form) scroll = QtWidgets.QScrollArea() scroll.setWidgetResizable(True) scroll.setWidget(widget) vbox = QtWidgets.QVBoxLayout() vbox.addWidget(scroll) self.setLayout(vbox)
def init_ui(self): """""" self.name_combo = QtWidgets.QComboBox() self.direction_combo = QtWidgets.QComboBox() self.direction_combo.addItems( [Direction.LONG.value, Direction.SHORT.value]) self.offset_combo = QtWidgets.QComboBox() self.offset_combo.addItems([offset.value for offset in Offset]) double_validator = QtGui.QDoubleValidator() double_validator.setBottom(0) self.price_line = QtWidgets.QLineEdit() self.price_line.setValidator(double_validator) self.volume_line = QtWidgets.QLineEdit() self.volume_line.setValidator(double_validator) for w in [ self.name_combo, self.price_line, self.volume_line, self.direction_combo, self.offset_combo ]: w.setFixedWidth(150) send_button = QtWidgets.QPushButton("委托") send_button.clicked.connect(self.send_order) send_button.setFixedWidth(70) cancel_button = QtWidgets.QPushButton("全撤") cancel_button.clicked.connect(self.cancel_all) cancel_button.setFixedWidth(70) hbox = QtWidgets.QHBoxLayout() hbox.addWidget(QtWidgets.QLabel("策略名称")) hbox.addWidget(self.name_combo) hbox.addWidget(QtWidgets.QLabel("方向")) hbox.addWidget(self.direction_combo) hbox.addWidget(QtWidgets.QLabel("开平")) hbox.addWidget(self.offset_combo) hbox.addWidget(QtWidgets.QLabel("价格")) hbox.addWidget(self.price_line) hbox.addWidget(QtWidgets.QLabel("数量")) hbox.addWidget(self.volume_line) hbox.addWidget(send_button) hbox.addWidget(cancel_button) hbox.addStretch() self.setLayout(hbox)
def init_ui(self): """""" QLabel = QtWidgets.QLabel self.target_combo = QtWidgets.QComboBox() self.target_combo.addItems(list(self.DISPLAY_NAME_MAP.keys())) grid = QtWidgets.QGridLayout() grid.addWidget(QLabel("目标"), 0, 0) grid.addWidget(self.target_combo, 0, 1, 1, 3) grid.addWidget(QLabel("参数"), 1, 0) grid.addWidget(QLabel("开始"), 1, 1) grid.addWidget(QLabel("步进"), 1, 2) grid.addWidget(QLabel("结束"), 1, 3) # Add vt_symbol and name edit if add new strategy self.setWindowTitle(f"优化参数配置:{self.class_name}") validator = QtGui.QDoubleValidator() row = 2 for name, value in self.parameters.items(): type_ = type(value) if type_ not in [int, float]: continue start_edit = QtWidgets.QLineEdit(str(value)) step_edit = QtWidgets.QLineEdit(str(1)) end_edit = QtWidgets.QLineEdit(str(value)) for edit in [start_edit, step_edit, end_edit]: edit.setValidator(validator) grid.addWidget(QLabel(name), row, 0) grid.addWidget(start_edit, row, 1) grid.addWidget(step_edit, row, 2) grid.addWidget(end_edit, row, 3) self.edits[name] = { "type": type_, "start": start_edit, "step": step_edit, "end": end_edit } row += 1 parallel_button = QtWidgets.QPushButton("多进程优化") parallel_button.clicked.connect(self.generate_parallel_setting) grid.addWidget(parallel_button, row, 0, 1, 4) row += 1 ga_button = QtWidgets.QPushButton("遗传算法优化") ga_button.clicked.connect(self.generate_ga_setting) grid.addWidget(ga_button, row, 0, 1, 4) widget = QtWidgets.QWidget() widget.setLayout(grid) scroll = QtWidgets.QScrollArea() scroll.setWidgetResizable(True) scroll.setWidget(widget) vbox = QtWidgets.QVBoxLayout() vbox.addWidget(scroll) self.setLayout(vbox)
def update_trades(self, trades: list): """""" trade_pairs = generate_trade_pairs(trades) candle_plot = self.chart.get_plot("candle") scatter_data = [] y_adjustment = self.price_range * 0.001 for d in trade_pairs: open_ix = self.dt_ix_map[d["open_dt"]] close_ix = self.dt_ix_map[d["close_dt"]] open_price = d["open_price"] close_price = d["close_price"] # Trade Line x = [open_ix, close_ix] y = [open_price, close_price] if d["direction"] == Direction.LONG and close_price >= open_price: color = "r" elif d["direction"] == Direction.SHORT and close_price <= open_price: color = "r" else: color = "g" pen = pg.mkPen(color, width=1.5, style=QtCore.Qt.DashLine) item = pg.PlotCurveItem(x, y, pen=pen) self.items.append(item) candle_plot.addItem(item) # Trade Scatter open_bar = self.ix_bar_map[open_ix] close_bar = self.ix_bar_map[close_ix] if d["direction"] == Direction.LONG: scatter_color = "yellow" open_symbol = "t1" close_symbol = "t" open_side = 1 close_side = -1 open_y = open_bar.low_price close_y = close_bar.high_price else: scatter_color = "magenta" open_symbol = "t" close_symbol = "t1" open_side = -1 close_side = 1 open_y = open_bar.high_price close_y = close_bar.low_price pen = pg.mkPen(QtGui.QColor(scatter_color)) brush = pg.mkBrush(QtGui.QColor(scatter_color)) size = 10 open_scatter = { "pos": (open_ix, open_y - open_side * y_adjustment), "size": size, "pen": pen, "brush": brush, "symbol": open_symbol } close_scatter = { "pos": (close_ix, close_y - close_side * y_adjustment), "size": size, "pen": pen, "brush": brush, "symbol": close_symbol } scatter_data.append(open_scatter) scatter_data.append(close_scatter) # Trade text volume = d["volume"] text_color = QtGui.QColor(scatter_color) open_text = pg.TextItem(f"[{volume}]", color=text_color, anchor=(0.5, 0.5)) close_text = pg.TextItem(f"[{volume}]", color=text_color, anchor=(0.5, 0.5)) open_text.setPos(open_ix, open_y - open_side * y_adjustment * 3) close_text.setPos(close_ix, close_y - close_side * y_adjustment * 3) self.items.append(open_text) self.items.append(close_text) candle_plot.addItem(open_text) candle_plot.addItem(close_text) trade_scatter = pg.ScatterPlotItem(scatter_data) self.items.append(trade_scatter) candle_plot.addItem(trade_scatter)
def init_ui(self): """""" self.setWindowTitle("创建价差") self.name_line = QtWidgets.QLineEdit() self.active_line = QtWidgets.QLineEdit() self.min_volume_combo = QtWidgets.QComboBox() self.min_volume_combo.addItems([ "1", "0.1", "0.01", "0.001", "0.0001", "0.00001", "0.000001", ]) self.grid = QtWidgets.QGridLayout() button_add = QtWidgets.QPushButton("创建价差") button_add.clicked.connect(self.add_spread) Label = QtWidgets.QLabel grid = QtWidgets.QGridLayout() grid.addWidget(Label("价差名称"), 0, 0) grid.addWidget(self.name_line, 0, 1, 1, 4) grid.addWidget(Label("主动腿代码"), 1, 0) grid.addWidget(self.active_line, 1, 1, 1, 4) grid.addWidget(Label("最小交易量"), 2, 0) grid.addWidget(self.min_volume_combo, 2, 1, 1, 4) grid.addWidget(Label(""), 3, 0) grid.addWidget(Label("本地代码"), 4, 1) grid.addWidget(Label("价格乘数"), 4, 2) grid.addWidget(Label("交易乘数"), 4, 3) grid.addWidget(Label("合约模式"), 4, 4) int_validator = QtGui.QIntValidator() leg_count = 5 for i in range(leg_count): symbol_line = QtWidgets.QLineEdit() price_line = QtWidgets.QLineEdit() price_line.setValidator(int_validator) trading_line = QtWidgets.QLineEdit() trading_line.setValidator(int_validator) inverse_combo = QtWidgets.QComboBox() inverse_combo.addItems(["正向", "反向"]) grid.addWidget(Label("腿{}".format(i + 1)), 5 + i, 0) grid.addWidget(symbol_line, 5 + i, 1) grid.addWidget(price_line, 5 + i, 2) grid.addWidget(trading_line, 5 + i, 3) grid.addWidget(inverse_combo, 5 + i, 4) d = { "symbol": symbol_line, "price": price_line, "trading": trading_line, "inverse": inverse_combo } self.leg_widgets.append(d) grid.addWidget(Label(""), 5 + leg_count, 0,) grid.addWidget(button_add, 6 + leg_count, 0, 1, 5) self.setLayout(grid)
def init_ui(self): """""" self.setWindowTitle("启动算法") self.setFrameShape(self.Box) self.setLineWidth(1) self.name_line = QtWidgets.QLineEdit() self.direction_combo = QtWidgets.QComboBox() self.direction_combo.addItems( [Direction.LONG.value, Direction.SHORT.value] ) self.offset_combo = QtWidgets.QComboBox() self.offset_combo.addItems( [Offset.NONE.value, Offset.OPEN.value, Offset.CLOSE.value] ) float_validator = QtGui.QDoubleValidator() self.price_line = QtWidgets.QLineEdit() self.price_line.setValidator(float_validator) self.volume_line = QtWidgets.QLineEdit() self.volume_line.setValidator(float_validator) int_validator = QtGui.QIntValidator() self.payup_line = QtWidgets.QLineEdit() self.payup_line.setValidator(int_validator) self.interval_line = QtWidgets.QLineEdit() self.interval_line.setValidator(int_validator) button_start = QtWidgets.QPushButton("启动") button_start.clicked.connect(self.start_algo) self.lock_combo = QtWidgets.QComboBox() self.lock_combo.addItems( ["否", "是"] ) self.class_combo = QtWidgets.QComboBox() add_button = QtWidgets.QPushButton("添加策略") add_button.clicked.connect(self.add_strategy) init_button = QtWidgets.QPushButton("全部初始化") init_button.clicked.connect(self.strategy_engine.init_all_strategies) start_button = QtWidgets.QPushButton("全部启动") start_button.clicked.connect(self.strategy_engine.start_all_strategies) stop_button = QtWidgets.QPushButton("全部停止") stop_button.clicked.connect(self.strategy_engine.stop_all_strategies) add_spread_button = QtWidgets.QPushButton("创建价差") add_spread_button.clicked.connect(self.add_spread) remove_spread_button = QtWidgets.QPushButton("移除价差") remove_spread_button.clicked.connect(self.remove_spread) form = QtWidgets.QFormLayout() form.addRow("价差", self.name_line) form.addRow("方向", self.direction_combo) form.addRow("开平", self.offset_combo) form.addRow("价格", self.price_line) form.addRow("数量", self.volume_line) form.addRow("超价", self.payup_line) form.addRow("间隔", self.interval_line) form.addRow("锁仓", self.lock_combo) form.addRow(button_start) vbox = QtWidgets.QVBoxLayout() vbox.addLayout(form) vbox.addStretch() vbox.addWidget(self.class_combo) vbox.addWidget(add_button) vbox.addWidget(init_button) vbox.addWidget(start_button) vbox.addWidget(stop_button) vbox.addStretch() vbox.addWidget(add_spread_button) vbox.addWidget(remove_spread_button) self.setLayout(vbox)
from howtrader.trader.ui import QtGui WHITE_COLOR = (255, 255, 255) BLACK_COLOR = (0, 0, 0) GREY_COLOR = (100, 100, 100) UP_COLOR = (255, 75, 75) DOWN_COLOR = (0, 255, 255) CURSOR_COLOR = (255, 245, 162) PEN_WIDTH = 1 BAR_WIDTH = 0.3 AXIS_WIDTH = 0.8 NORMAL_FONT = QtGui.QFont("Arial", 9) def to_int(value: float) -> int: """""" return int(round(value, 0))