Ejemplo n.º 1
0
class Backtest(QA_Backtest):

    def __init__(self, market_type, frequence, start, end, code_list, commission_fee):
        super().__init__(market_type,  frequence, start, end, code_list, commission_fee)
        self.user = QA_User()
        mastrategy = MAStrategy()
        self.portfolio, self.account = self.user.register_account(mastrategy)
        QA_util_log_info(self.user.get_portfolio(self.portfolio).accounts)
        QA_util_log_info(self.user.get_portfolio(
            self.portfolio).get_account(self.account).cash)

    def after_success(self):
        QA_util_log_info(self.user.get_portfolio(self.portfolio).get_account(
            self.account).history_table)
Ejemplo n.º 2
0
class QA_Backtest():
    """BACKTEST

    BACKTEST的主要目的:

    - 引入时间轴环境,获取全部的数据,然后按生成器将数据迭代插入回测的BROKER
        (这一个过程是模拟在真实情况中市场的时间变化和价格变化)

    - BROKER有了新数据以后 会通知MARKET交易前置,MARKET告知已经注册的所有的ACCOUNT 有新的市场数据

    - ACCOUNT 获取了新的市场函数,并将其插入他已有的数据中(update)

    - ACCOUNT 底下注册的策略STRATEGY根据新的市场函数,产生新的买卖判断,综合生成信号

    - 买卖判断通过交易前置发送给对应的BROKER,进行交易

    - BROKER发送SETTLE指令 结束这一个bar的所有交易,进行清算

    - 账户也进行清算,更新持仓,可卖,可用现金等

    - 迭代循环直至结束回测

    - 回测去计算这段时间的各个账户收益,并给出综合的最终结果

    """
    def __init__(
        self,
        market_type,
        frequence,
        start,
        end,
        code_list,
        commission_fee,
    ):
        self.user = QA_User()
        self.if_settled = False
        self.account = None
        self.portfolio = None

        self.market = QA_Market()
        self.market_type = market_type
        self.frequence = frequence
        self.broker = QA_BacktestBroker(commission_fee)
        self.broker_name = 'backtest_broker'

        self.start = start
        self.end = end
        self.code_list = code_list

        if self.market_type is MARKET_TYPE.STOCK_CN and self.frequence is FREQUENCE.DAY:
            self.ingest_data = QA_fetch_stock_day_adv(
                self.code_list, self.start, self.end).to_qfq().panel_gen
        elif self.market_type is MARKET_TYPE.STOCK_CN and self.frequence[
                -3:] == 'min':
            self.ingest_data = QA_fetch_stock_min_adv(
                self.code_list, self.start, self.end,
                self.frequence).to_qfq().panel_gen

    def _generate_account(self):
        """generate a simple account
        """

        self.account, self.portfolio = self.user.generate_simpleaccount()

    def start_market(self):
        """start the market thread and register backtest broker thread
        """

        self.market.start()
        self.market.register(self.broker_name, self.broker)
        self.market.login(self.broker_name, self.account.account_cookie,
                          self.account)

    def run(self):
        """generator driven data flow
        """
        # 如果出现了日期的改变 才会进行结算的事件

        _date = None
        for data in self.ingest_data:
            date = data.date[0]
            if self.market_type is MARKET_TYPE.STOCK_CN:
                if _date != date:
                    self.market._settle(self.broker_name)
            elif self.market_type in [
                    MARKET_TYPE.FUND_CN, MARKET_TYPE.INDEX_CN,
                    MARKET_TYPE.FUTURE_CN
            ]:
                self.market._settle(self.broker_name)
            self.broker.run(
                QA_Event(event_type=ENGINE_EVENT.UPCOMING_DATA,
                         market_data=data))
            self.market.upcoming_data(self.broker_name, data)
            self.market.trade_engine.join()

            _date = date

        self.after_success()

    def after_success(self):
        """called when all trading fininshed, for performance analysis
        """

        for po in self.user.portfolio_list.keys():
            for ac in self.user.get_portfolio(po).accounts.keys():
                accounts = self.user.get_portfolio(po).get_account(ac)
                print(accounts.hold)

                print(accounts.history_table)

        self.stop()

    def stop(self):
        """stop all the market trade enging threads and all subthreads
        """

        self.market.trade_engine.stop_all()
        self.market.trade_engine.stop()