VeighNa量化社区
你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 5
声望: 0

已正确配置MongoDB,在MongoDBCompass内可正常查看数据库内容。
根据社区精选18 19 修改了对应文件,地址分别是https://zhuanlan.zhihu.com/p/135939575https://zhuanlan.zhihu.com/p/135940704
但是在数据管理中,刷新数据后没有任何返回
由于采用集中在db_bar_data中时能正常识别,推测数据管理模块没有识别到其他表格中的内容,需要对对应文件做相应修改。同时可以推测,行情录制模块需要做类似修改以加入已有表格中。
想请教社区里面的各位大神,这里应该对哪些文件做什么修改呢?还请不吝赐教,感谢~

Member
avatar
加入于:
帖子: 5
声望: 0

10小时了,一个回复都没有,甚至只有寥寥无几的浏览,在求助板块发的帖子还被删除了。过于失望
下面是解决方案。果然还是只能自己动手丰衣足食。
为了简化工作量分表的名字都是合约的代号 如'SR2011',同时只考虑了BarData,即除了'db_tick_data'都视为BarData
默认安装位置,修改了自行推导
C:\vnstudio\Lib\site-packages\vnpy\trader\database\database.py

    @abstractmethod
    def get_newest_bar_data(
        self,
        symbol: str,
        exchange: "Exchange",
        interval: "Interval",
        collection_name: str = None
    ) -> Optional["BarData"]:
        """
        If there is data in database, return the one with greatest datetime(newest one)
        otherwise, return None
        """
        pass

    @abstractmethod
    def get_oldest_bar_data(
        self,
        symbol: str,
        exchange: "Exchange",
        interval: "Interval",
        collection_name: str = None
    ) -> Optional["BarData"]:
        """
        If there is data in database, return the one with smallest datetime(oldest one)
        otherwise, return None
        """
        pass

    @abstractmethod
    def get_newest_tick_data(
        self,
        symbol: str,
        exchange: "Exchange",
        collection_name: str = None
    ) -> Optional["TickData"]:
        """
        If there is data in database, return the one with greatest datetime(newest one)
        otherwise, return None
        """
        pass

    @abstractmethod
    def get_bar_data_statistics(
        self,
        symbol: str,
        exchange: "Exchange",
        collection_name: str = None
    ) -> List[Dict]:
        """
        Return data avaible in database with a list of symbol/exchange/interval/count.
        """
        pass

    @abstractmethod
    def delete_bar_data(
        self,
        symbol: str,
        exchange: "Exchange",
        interval: "Interval",
        collection_name: str = None
    ) -> int:
        """
        Delete all bar data with given symbol + exchange + interval.
        """
        pass

C:\vnstudio\Lib\site-packages\vnpy\trader\database\database_mongo.py


    def get_newest_bar_data(
        self, symbol: str, exchange: "Exchange", interval: "Interval",collection_name:str=None
    ) -> Optional["BarData"]:
            if collection_name is None:
                    s=(
                        DbBarData.objects(
                            symbol=symbol,
                            exchange=exchange.value,
                            interval=interval.value
                        )
                        .order_by("-datetime")
                        .first()
                    )
            else:
                with switch_collection(DbBarData, collection_name):
                    s = (
                            DbBarData.objects(
                                symbol=symbol,
                                exchange=exchange.value,
                                interval=interval.value
                            )
                            .order_by("-datetime")
                            .first()
                        )
            if s:
                return s.to_bar()
            return None

    def get_oldest_bar_data(
        self, symbol: str, exchange: "Exchange", interval: "Interval",collection_name:str=None
    ) -> Optional["BarData"]:
            if collection_name is None:
                s = (
                    DbBarData.objects(
                        symbol=symbol,
                        exchange=exchange.value,
                        interval=interval.value
                    )
                    .order_by("+datetime")
                    .first()
                )
            else:
                with switch_collection(DbBarData, collection_name):
                    s = (
                            DbBarData.objects(
                                symbol=symbol,
                                exchange=exchange.value,
                                interval=interval.value
                            )
                            .order_by("+datetime")
                            .first()
                        )
            if s:
                return s.to_bar()
            return None

    def get_newest_tick_data(
        self, symbol: str, exchange: "Exchange",collection_name:str=None
    ) -> Optional["TickData"]:
            if collection_name is None:
                s = (
                    DbTickData.objects(symbol=symbol, exchange=exchange.value)
                    .order_by("-datetime")
                    .first()
                )
            else:
                with switch_collection(DbTickData, collection_name):
                    s = (
                            DbTickData.objects(symbol=symbol, exchange=exchange.value)
                            .order_by("-datetime")
                            .first()
                        )
            if s:
                return s.to_tick()
            return None

    def get_bar_data_statistics(self) -> List:
        """"""
        if 'db_tick_data' in AllCollectionNames:
            AllCollectionNames.remove('db_tick_data')
##        print(AllCollectionNames)
        s=list()
        for i in AllCollectionNames:
            with switch_collection(DbBarData,i):
                s.extend(
                DbBarData.objects.aggregate({
                    "$group": {
                        "_id": {
                            "symbol": "$symbol",
                            "exchange": "$exchange",
                            "interval": "$interval",
                            "collection_name":i,
                        },
                        "count": {"$sum": 1}
                    }
                }))

        result = []

        for d in s:
            data = d["_id"]
            data["count"] = d["count"]
            result.append(data)

        return result

    def delete_bar_data(
        self,
        symbol: str,
        exchange: "Exchange",
        interval: "Interval",
        collection_name:str=None
    ) -> int:
        """
        Delete all bar data with given symbol + exchange + interval.
        """
        if collection_name is None:
            count = DbBarData.objects(
                symbol=symbol,
                exchange=exchange.value,
                interval=interval.value
            ).delete()
        else:
                with switch_collection(DbBarData, collection_name):
                        count = DbBarData.objects(
                            symbol=symbol,
                            exchange=exchange.value,
                            interval=interval.value
                        ).delete()
        return count

C:\vnstudio\Lib\site-packages\vnpy\app\data_manager\engine.py

    def import_data_from_csv(
        self,
        file_path: str,
        symbol: str,
        exchange: Exchange,
        interval: Interval,
        datetime_head: str,
        open_head: str,
        high_head: str,
        low_head: str,
        close_head: str,
        volume_head: str,
        open_interest_head: str,
        datetime_format: str,
        OrderBookId:str
    ) -> Tuple:
        """"""
        with open(file_path, "rt") as f:
            buf = [line.replace("\0", "") for line in f]

        reader = csv.DictReader(buf, delimiter=",")

        bars = []
        start = None
        count = 0

        for item in reader:
            if datetime_format:
                dt = datetime.strptime(item[datetime_head], datetime_format)
            else:
                dt = datetime.fromisoformat(item[datetime_head])

            open_interest = item.get(open_interest_head, 0)

            bar = BarData(
                symbol=symbol,
                exchange=exchange,
                datetime=dt,
                interval=interval,
                volume=float(item[volume_head]),
                open_price=float(item[open_head]),
                high_price=float(item[high_head]),
                low_price=float(item[low_head]),
                close_price=float(item[close_head]),
                open_interest=float(open_interest),
                gateway_name="DB",
            )

            bars.append(bar)

            # do some statistics
            count += 1
            if not start:
                start = bar.datetime

        # insert into database
        database_manager.save_bar_data(bars,OrderBookId)

        end = bar.datetime
        return start, end, count

    def get_bar_data_available(self) -> List[Dict]:
        """"""
        data = database_manager.get_bar_data_statistics()

        for d in data:
            oldest_bar = database_manager.get_oldest_bar_data(
                d["symbol"], Exchange(d["exchange"]), Interval(d["interval"]),
                d['collection_name']
            )
            d["start"] = oldest_bar.datetime

            newest_bar = database_manager.get_newest_bar_data(
                d["symbol"], Exchange(d["exchange"]), Interval(d["interval"]),
                d['collection_name']
            )
            d["end"] = newest_bar.datetime

        return data

    def load_bar_data(
        self,
        symbol: str,
        exchange: Exchange,
        interval: Interval,
        start: datetime,
        end: datetime,
        collection_name: str = None,
    ) -> List[BarData]:
        """"""
        bars = database_manager.load_bar_data(
            symbol,
            exchange,
            interval,
            start,
            end,
            symbol,
        )

        return bars
    def delete_bar_data(
        self,
        symbol: str,
        exchange: Exchange,
        interval: Interval,
        collection_name: str = None,
    ) -> int:
        """"""
        count = database_manager.delete_bar_data(
            symbol,
            exchange,
            interval,
            symbol,
        )

        return count

C:\vnstudio\Lib\site-packages\vnpy\app\data_manager\ui\widget.py

    def import_data(self) -> None:
        """"""
        dialog = ImportDialog()
        n = dialog.exec_()
        if n != dialog.Accepted:
            return

        file_path = dialog.file_edit.text()
        symbol = dialog.symbol_edit.text()
        OrderBookId= dialog.OrderBookId_edit.text()
        exchange = dialog.exchange_combo.currentData()
        interval = dialog.interval_combo.currentData()
        datetime_head = dialog.datetime_edit.text()
        open_head = dialog.open_edit.text()
        low_head = dialog.low_edit.text()
        high_head = dialog.high_edit.text()
        close_head = dialog.close_edit.text()
        volume_head = dialog.volume_edit.text()
        open_interest_head = dialog.open_interest_edit.text()
        datetime_format = dialog.format_edit.text()

        start, end, count = self.engine.import_data_from_csv(
            file_path,
            symbol,
            exchange,
            interval,
            datetime_head,
            open_head,
            high_head,
            low_head,
            close_head,
            volume_head,
            open_interest_head,
            datetime_format,
            OrderBookId
        )

        msg = f"\
        CSV载入成功\n\
        代码:{symbol}\n\
        OrderBookId:{OrderBookId}\n\
        交易所:{exchange.value}\n\
        周期:{interval.value}\n\
        起始:{start}\n\
        结束:{end}\n\
        总数量:{count}\n\
        "
        QtWidgets.QMessageBox.information(self, "载入成功!", msg)
    def __init__(self, parent=None):
        """"""
        super().__init__()

        self.setWindowTitle("从CSV文件导入数据")
        self.setFixedWidth(300)

        self.setWindowFlags(
            (self.windowFlags() | QtCore.Qt.CustomizeWindowHint)
            & ~QtCore.Qt.WindowMaximizeButtonHint)

        file_button = QtWidgets.QPushButton("选择文件")
        file_button.clicked.connect(self.select_file)

        load_button = QtWidgets.QPushButton("确定")
        load_button.clicked.connect(self.accept)

        self.file_edit = QtWidgets.QLineEdit()
        self.symbol_edit = QtWidgets.QLineEdit()
        self.OrderBookId_edit = QtWidgets.QLineEdit()

        self.exchange_combo = QtWidgets.QComboBox()
        for i in Exchange:
            self.exchange_combo.addItem(str(i.name), i)

        self.interval_combo = QtWidgets.QComboBox()
        for i in Interval:
            if i != Interval.TICK:
                self.interval_combo.addItem(str(i.name), i)

        self.datetime_edit = QtWidgets.QLineEdit("datetime")
        self.open_edit = QtWidgets.QLineEdit("open")
        self.high_edit = QtWidgets.QLineEdit("high")
        self.low_edit = QtWidgets.QLineEdit("low")
        self.close_edit = QtWidgets.QLineEdit("close")
        self.volume_edit = QtWidgets.QLineEdit("volume")
        self.open_interest_edit = QtWidgets.QLineEdit("open_interest")

        self.format_edit = QtWidgets.QLineEdit("%Y-%m-%d %H:%M:%S")

        info_label = QtWidgets.QLabel("合约信息")
        info_label.setAlignment(QtCore.Qt.AlignCenter)

        head_label = QtWidgets.QLabel("表头信息")
        head_label.setAlignment(QtCore.Qt.AlignCenter)

        format_label = QtWidgets.QLabel("格式信息")
        format_label.setAlignment(QtCore.Qt.AlignCenter)

        form = QtWidgets.QFormLayout()
        form.addRow(file_button, self.file_edit)
        form.addRow(QtWidgets.QLabel())
        form.addRow(info_label)
        form.addRow("代码", self.symbol_edit)
        form.addRow("OrderBookId", self.OrderBookId_edit)
        form.addRow("交易所", self.exchange_combo)
        form.addRow("周期", self.interval_combo)
        form.addRow(QtWidgets.QLabel())
        form.addRow(head_label)
        form.addRow("时间戳", self.datetime_edit)
        form.addRow("开盘价", self.open_edit)
        form.addRow("最高价", self.high_edit)
        form.addRow("最低价", self.low_edit)
        form.addRow("收盘价", self.close_edit)
        form.addRow("成交量", self.volume_edit)
        form.addRow("持仓量", self.open_interest_edit)
        form.addRow(QtWidgets.QLabel())
        form.addRow(format_label)
        form.addRow("时间格式", self.format_edit)
        form.addRow(QtWidgets.QLabel())
        form.addRow(load_button)

        self.setLayout(form)

非常感谢社区精选18 19的作者,我这个操作完全是在他(们)的思路上继续做的,不然我也想不到
另外vnpy写的很赞,虽然没有多少注释,但是变量名把所有的逻辑解释的明明白白,很强
还是希望社区内能互帮互助吧,相逢即是缘,交易已经这么不容易了。

Member
avatar
加入于:
帖子: 5
声望: 0

CTP回测GUI修改
注意原本使用Backtest已经可以正常使用回测
这里就是吃饱了撑着的把图形化也改了出来
注意事项同上
另外因为我没用米筐的数据,全是本地的,所以他的下载接口还没改也不会去改
C:\vnstudio\Lib\site-packages\vnpy\app\cta_backtester\ui

    def init_ui(self):
        """"""
        self.setWindowTitle("CTA回测")

        # Setting Part
        self.class_combo = QtWidgets.QComboBox()

        self.symbol_line = QtWidgets.QLineEdit("IF88.CFFEX")
        self.collection_name_line = QtWidgets.QLineEdit("IF88")
        self.interval_combo = QtWidgets.QComboBox()
        for interval in Interval:
            if interval != Interval.TICK:
                self.interval_combo.addItem(interval.value)

        end_dt = datetime.now()
        start_dt = end_dt - timedelta(days=3 * 365)

        self.start_date_edit = QtWidgets.QDateEdit(
            QtCore.QDate(
                start_dt.year,
                start_dt.month,
                start_dt.day
            )
        )
        self.end_date_edit = QtWidgets.QDateEdit(
            QtCore.QDate.currentDate()
        )

        self.rate_line = QtWidgets.QLineEdit("0.000025")
        self.slippage_line = QtWidgets.QLineEdit("0.2")
        self.size_line = QtWidgets.QLineEdit("300")
        self.pricetick_line = QtWidgets.QLineEdit("0.2")
        self.capital_line = QtWidgets.QLineEdit("1000000")

        self.inverse_combo = QtWidgets.QComboBox()
        self.inverse_combo.addItems(["正向", "反向"])

        backtesting_button = QtWidgets.QPushButton("开始回测")
        backtesting_button.clicked.connect(self.start_backtesting)

        optimization_button = QtWidgets.QPushButton("参数优化")
        optimization_button.clicked.connect(self.start_optimization)

        self.result_button = QtWidgets.QPushButton("优化结果")
        self.result_button.clicked.connect(self.show_optimization_result)
        self.result_button.setEnabled(False)

        downloading_button = QtWidgets.QPushButton("下载数据")
        downloading_button.clicked.connect(self.start_downloading)

        self.order_button = QtWidgets.QPushButton("委托记录")
        self.order_button.clicked.connect(self.show_backtesting_orders)
        self.order_button.setEnabled(False)

        self.trade_button = QtWidgets.QPushButton("成交记录")
        self.trade_button.clicked.connect(self.show_backtesting_trades)
        self.trade_button.setEnabled(False)

        self.daily_button = QtWidgets.QPushButton("每日盈亏")
        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)

        edit_button = QtWidgets.QPushButton("代码编辑")
        edit_button.clicked.connect(self.edit_strategy_code)

        reload_button = QtWidgets.QPushButton("策略重载")
        reload_button.clicked.connect(self.reload_strategy_class)

        for button in [
            backtesting_button,
            optimization_button,
            downloading_button,
            self.result_button,
            self.order_button,
            self.trade_button,
            self.daily_button,
            self.candle_button,
            edit_button,
            reload_button
        ]:
            button.setFixedHeight(button.sizeHint().height() * 2)

        form = QtWidgets.QFormLayout()
        form.addRow("交易策略", self.class_combo)
        form.addRow("本地代码", self.symbol_line)
        form.addRow("OrderBookId", self.collection_name_line)
        form.addRow("K线周期", self.interval_combo)
        form.addRow("开始日期", self.start_date_edit)
        form.addRow("结束日期", self.end_date_edit)
        form.addRow("手续费率", self.rate_line)
        form.addRow("交易滑点", self.slippage_line)
        form.addRow("合约乘数", self.size_line)
        form.addRow("价格跳动", self.pricetick_line)
        form.addRow("回测资金", self.capital_line)
        form.addRow("合约模式", self.inverse_combo)

        result_grid = QtWidgets.QGridLayout()
        result_grid.addWidget(self.trade_button, 0, 0)
        result_grid.addWidget(self.order_button, 0, 1)
        result_grid.addWidget(self.daily_button, 1, 0)
        result_grid.addWidget(self.candle_button, 1, 1)

        left_vbox = QtWidgets.QVBoxLayout()
        left_vbox.addLayout(form)
        left_vbox.addWidget(backtesting_button)
        left_vbox.addWidget(downloading_button)
        left_vbox.addStretch()
        left_vbox.addLayout(result_grid)
        left_vbox.addStretch()
        left_vbox.addWidget(optimization_button)
        left_vbox.addWidget(self.result_button)
        left_vbox.addStretch()
        left_vbox.addWidget(edit_button)
        left_vbox.addWidget(reload_button)

        # Result part
        self.statistics_monitor = StatisticsMonitor()

        self.log_monitor = QtWidgets.QTextEdit()
        self.log_monitor.setMaximumHeight(400)

        self.chart = BacktesterChart()
        self.chart.setMinimumWidth(1000)

        self.trade_dialog = BacktestingResultDialog(
            self.main_engine,
            self.event_engine,
            "回测成交记录",
            BacktestingTradeMonitor
        )
        self.order_dialog = BacktestingResultDialog(
            self.main_engine,
            self.event_engine,
            "回测委托记录",
            BacktestingOrderMonitor
        )
        self.daily_dialog = BacktestingResultDialog(
            self.main_engine,
            self.event_engine,
            "回测每日盈亏",
            DailyResultMonitor
        )

        # Candle Chart
        self.candle_dialog = CandleChartDialog()

        # Layout
        vbox = QtWidgets.QVBoxLayout()
        vbox.addWidget(self.statistics_monitor)
        vbox.addWidget(self.log_monitor)

        hbox = QtWidgets.QHBoxLayout()
        hbox.addLayout(left_vbox)
        hbox.addLayout(vbox)
        hbox.addWidget(self.chart)
        self.setLayout(hbox)

        # Code Editor
        self.editor = CodeEditor(self.main_engine, self.event_engine)


    def load_backtesting_setting(self):
        """"""
        setting = load_json(self.setting_filename)
        if not setting:
            return

        self.class_combo.setCurrentIndex(
            self.class_combo.findText(setting["class_name"])
        )

        self.symbol_line.setText(setting["vt_symbol"])
        self.collection_name_line.setText(setting["collection_name"])

        self.interval_combo.setCurrentIndex(
            self.interval_combo.findText(setting["interval"])
        )

        self.rate_line.setText(str(setting["rate"]))
        self.slippage_line.setText(str(setting["slippage"]))
        self.size_line.setText(str(setting["size"]))
        self.pricetick_line.setText(str(setting["pricetick"]))
        self.capital_line.setText(str(setting["capital"]))

        if not setting["inverse"]:
            self.inverse_combo.setCurrentIndex(0)
        else:
            self.inverse_combo.setCurrentIndex(1)
    def start_backtesting(self):
        """"""
        class_name = self.class_combo.currentText()
        vt_symbol = self.symbol_line.text()
        collection_name = self.collection_name_line.text()
        interval = self.interval_combo.currentText()
        start = self.start_date_edit.date().toPyDate()
        end = self.end_date_edit.date().toPyDate()
        rate = float(self.rate_line.text())
        slippage = float(self.slippage_line.text())
        size = float(self.size_line.text())
        pricetick = float(self.pricetick_line.text())
        capital = float(self.capital_line.text())

        if self.inverse_combo.currentText() == "正向":
            inverse = False
        else:
            inverse = True

        # Save backtesting parameters
        backtesting_setting = {
            "class_name": class_name,
            "vt_symbol": vt_symbol,
            "collection_name":collection_name,
            "interval": interval,
            "rate": rate,
            "slippage": slippage,
            "size": size,
            "pricetick": pricetick,
            "capital": capital,
            "inverse": inverse,
        }
        save_json(self.setting_filename, backtesting_setting)

        # Get strategy setting
        old_setting = self.settings[class_name]
        dialog = BacktestingSettingEditor(class_name, old_setting)
        i = dialog.exec()
        if i != dialog.Accepted:
            return

        new_setting = dialog.get_setting()
        self.settings[class_name] = new_setting

        result = self.backtester_engine.start_backtesting(
            class_name,
            vt_symbol,
            collection_name,
            interval,
            start,
            end,
            rate,
            slippage,
            size,
            pricetick,
            capital,
            inverse,
            new_setting
        )

        if result:
            self.statistics_monitor.clear_data()
            self.chart.clear_data()

            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):
        """"""
        class_name = self.class_combo.currentText()
        vt_symbol = self.symbol_line.text()
        collection_name=self.collection_name_line.text()
        interval = self.interval_combo.currentText()
        start = self.start_date_edit.date().toPyDate()
        end = self.end_date_edit.date().toPyDate()
        rate = float(self.rate_line.text())
        slippage = float(self.slippage_line.text())
        size = float(self.size_line.text())
        pricetick = float(self.pricetick_line.text())
        capital = float(self.capital_line.text())

        if self.inverse_combo.currentText() == "正向":
            inverse = False
        else:
            inverse = True

        parameters = self.settings[class_name]
        dialog = OptimizationSettingEditor(class_name, parameters)
        i = dialog.exec()
        if i != dialog.Accepted:
            return

        optimization_setting, use_ga = dialog.get_setting()
        self.target_display = dialog.target_display

        self.backtester_engine.start_optimization(
            class_name,
            vt_symbol,
            collection_name,
            interval,
            start,
            end,
            rate,
            slippage,
            size,
            pricetick,
            capital,
            inverse,
            optimization_setting,
            use_ga
        )

        self.result_button.setEnabled(False)

    def start_downloading(self):
        """"""
        vt_symbol = self.symbol_line.text()
        collection_name=self.collection_name_line.text()
        interval = self.interval_combo.currentText()
        start_date = self.start_date_edit.date()
        end_date = self.end_date_edit.date()

        start = datetime(
            start_date.year(),
            start_date.month(),
            start_date.day(),
            tzinfo=get_localzone()
        )

        end = datetime(
            end_date.year(),
            end_date.month(),
            end_date.day(),
            23,
            59,
            59,
            tzinfo=get_localzone()
        )

        self.backtester_engine.start_downloading(
            vt_symbol,
            interval,
            start,
            end
        )

C:\vnstudio\Lib\site-packages\vnpy\app\cta_backtester


    def run_backtesting(
        self,
        class_name: str,
        vt_symbol: str,
        collection_name:str,
        interval: str,
        start: datetime,
        end: datetime,
        rate: float,
        slippage: float,
        size: int,
        pricetick: float,
        capital: int,
        inverse: bool,
        setting: dict,
    ):
        """"""
        self.result_df = None
        self.result_statistics = None

        engine = self.backtesting_engine
        engine.clear_data()

        engine.set_parameters(
            vt_symbol=vt_symbol,
            interval=interval,
            start=start,
            end=end,
            rate=rate,
            slippage=slippage,
            size=size,
            pricetick=pricetick,
            capital=capital,
            inverse=inverse,
            collection_name=collection_name
        )

        strategy_class = self.classes[class_name]
        engine.add_strategy(
            strategy_class,
            setting
        )

        engine.load_data()

        try:
            engine.run_backtesting()
        except Exception:
            msg = f"策略回测失败,触发异常:\n{traceback.format_exc()}"
            self.write_log(msg)

            self.thread = None
            return

        self.result_df = engine.calculate_result()
        self.result_statistics = engine.calculate_statistics(output=False)

        # Clear thread object handler.
        self.thread = None

        # Put backtesting done event
        event = Event(EVENT_BACKTESTER_BACKTESTING_FINISHED)
        self.event_engine.put(event)

    def start_backtesting(
        self,
        class_name: str,
        vt_symbol: str,
        collection_name:str,
        interval: str,
        start: datetime,
        end: datetime,
        rate: float,
        slippage: float,
        size: int,
        pricetick: float,
        capital: int,
        inverse: bool,
        setting: dict
    ):
        if self.thread:
            self.write_log("已有任务在运行中,请等待完成")
            return False

        self.write_log("-" * 40)
        self.thread = Thread(
            target=self.run_backtesting,
            args=(
                class_name,
                vt_symbol,
                collection_name,
                interval,
                start,
                end,
                rate,
                slippage,
                size,
                pricetick,
                capital,
                inverse,
                setting
            )
        )
        self.thread.start()

        return True

改完就又能在GUI用分表的MongoDB了
挺好

Member
avatar
加入于:
帖子: 4622
声望: 284

可以去原帖看一下,楼下好像有补充的

Member
avatar
加入于:
帖子: 5
声望: 0

xiaohe wrote:

可以去原帖看一下,楼下好像有补充的

非常感谢您的提醒,检查了下下面确实是有关键补充

© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】