예제 #1
0
파일: item.py 프로젝트: yutiansut/howtrader
    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
예제 #2
0
    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)
예제 #3
0
파일: item.py 프로젝트: yutiansut/howtrader
    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()
예제 #4
0
파일: item.py 프로젝트: yutiansut/howtrader
    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
예제 #5
0
    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)
예제 #6
0
    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)
예제 #7
0
    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)
예제 #8
0
    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)
예제 #9
0
    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)
예제 #10
0
    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)
예제 #11
0
파일: base.py 프로젝트: yutiansut/howtrader
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))