Exemplo 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()
        maminstrategy = MAMINStrategy()
        # maminstrategy.reset_assets(1000)
        # self.portfolio, self.account = self.user.register_account(mastrategy)
        self.user = QA_User(user_cookie='user_admin')
        self.portfolio = self.user.new_portfolio('folio_admin')
        self.portfolio, self.account = self.user.register_account(mastrategy)

    def after_success(self):
        QA_util_log_info(self.account.history_table)
        risk = QA_Risk(self.account, benchmark_code='000300',
                       benchmark_type=MARKET_TYPE.INDEX_CN)

        print(risk().T)
        risk.plot_assets_curve()
        risk.plot_dailyhold()
        risk.plot_signal()
        self.account.save()
        risk.save()
Exemplo n.º 2
0
 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()
     bool_strategy = BollingerBandsStrategy(
         code=code_list, start=start, end=end)
     self.portfolio, self.account = self.user.register_account(
         bool_strategy)
Exemplo n.º 3
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)

        cpsstrategy = CaoPanShouStrategy()
        self.user = QA_User(user_cookie='user_admin')
        self.portfolio = self.user.new_portfolio('folio_admin_caopanshou')
        # self.account = self.portfolio.new_account()
        # self.portfolio, self.account = self.user.register_account(cpsstrategy, portfolio_cookie='folio_admin')
        self.portfolio, self.account = self.user.register_account(cpsstrategy)
        # account = QA_Account(user_cookie='user_admin',
        #                      portfolio_cookie='portfolio_admin',
        #                      account_cookie='account_admin')
        # self.user = QA_User.register_account(account)
        # self.portfolio, self.account = self.user.register_account(cpsstrategy)


    def after_success(self):
        QA_util_log_info(self.account.history_table)
        risk = QA_Risk(self.account, benchmark_code='000300',
                       benchmark_type=MARKET_TYPE.INDEX_CN)

        print(risk().T)

        self.account.save()
        risk.save()
Exemplo n.º 4
0
 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)
Exemplo n.º 5
0
    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
Exemplo n.º 6
0
 def __init__(self, username, password):
     super().__init__(name='QAREALTIME_COLLECTOR_STOCK')
     self.user = QA_User(username=username, password=password)
     self.sub = subscriber_routing(exchange='QARealtime_Market',
                                   routing_key='stock')
     self.sub.callback = self.callback
     threading.Thread(target=self.sub.start, daemon=True).start()
Exemplo n.º 7
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()
        # maminstrategy = MAMINStrategy()
        # maminstrategy.reset_assets(1000)
        # self.portfolio, self.account = self.user.register_account(mastrategy)
        self.user = QA_User(user_cookie='user_admin')
        self.portfolio = self.user.new_portfolio('folio_admin')
        self.portfolio, self.account = self.user.register_account(mastrategy)

    def after_success(self):
        QA_util_log_info(self.account.history_table)
        risk = QA_Risk(self.account,
                       benchmark_code='000300',
                       benchmark_type=MARKET_TYPE.INDEX_CN)

        print(risk().T)

        self.account.save()
        risk.save()
Exemplo n.º 8
0
    def __init__(
            self,
            market_type,
            frequence,
            start,
            end,
            code_list,
            commission_fee,
            username='******',
            password='******',
            portfolio_cookie='qatestportfolio'
    ):
        """
        :param market_type: 回测的市场 MARKET_TYPE.STOCK_CN ,
        :param frequence: 'day' '1min' '5min' '15min' '30min' '60min'
        :param start:     开始日期
        :param end:       结束日期
        :param code_list: 股票代码池
        :param commission_fee: 交易佣金
        """
        self.user = QA_User(username=username, password=password)
        self.if_settled = False
        self.account = None
        self.portfolio = self.user.new_portfolio(portfolio_cookie)
        # 🛠todo market_type 应该放在 QA_Market对象里的一个属性
        self.market = QA_Market(if_start_orderthreading=True)
        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

        # 🛠todo 检查start日期和结束end日期是否正确
        # 🛠todo 检查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

        else:
            QA_util_log_info("{} 的市场类型没有实现!".format(market_type))
Exemplo n.º 9
0
    def __init__(self, market_type, frequence, start, end, code_list, commission_fee):
        super().__init__(market_type,  frequence, start, end, code_list, commission_fee)

        cpsstrategy = CaoPanShouStrategy()
        self.user = QA_User(user_cookie='user_admin')
        self.portfolio = self.user.new_portfolio('folio_admin_caopanshou')
        # self.account = self.portfolio.new_account()
        # self.portfolio, self.account = self.user.register_account(cpsstrategy, portfolio_cookie='folio_admin')
        self.portfolio, self.account = self.user.register_account(cpsstrategy)
Exemplo n.º 10
0
 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()
     t0strategy=MAMINT0Strategy()
     # maminstrategy.reset_assets(1000)
     # self.portfolio, self.account = self.user.register_account(mastrategy)
     self.user = QA_User(user_cookie='user_admin')
     self.portfolio = self.user.new_portfolio('folio_admin')
     self.portfolio, self.account = self.user.register_account(t0strategy)
Exemplo n.º 11
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)
Exemplo n.º 12
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)

    def after_success(self):
        QA_util_log_info(self.account.history_table)
        # check if the history_table is empty list
        if len(self.account.history_table) == 0:
            # 没有交易历史记录,直接返回
            return

        risk = QA_Risk(self.account, benchmark_code='000300',
                       benchmark_type=MARKET_TYPE.INDEX_CN)
        print(risk().T)
        risk.plot_assets_curve()
        risk.plot_dailyhold()
        risk.plot_signal()
        performance = QA_Performance(self.account)
        performance.plot_pnlmoney(performance.pnl_fifo)
        performance.plot_pnlratio(performance.pnl_fifo)
        self.account.save()
        risk.save()
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)

    def after_success(self):
        QA_util_log_info(self.account.history_table)
        # check if the history_table is empty list
        if len(self.account.history_table) == 0:
            # 没有交易历史记录,直接返回
            return

        risk = QA_Risk(self.account, benchmark_code='000300',
                       benchmark_type=MARKET_TYPE.INDEX_CN)
        print(risk().T)
        risk.plot_assets_curve()
        risk.plot_dailyhold()
        risk.plot_signal()
        performance = QA_Performance(self.account)
        performance.plot_pnlmoney(performance.pnl_fifo)
        performance.plot_pnlratio(performance.pnl_fifo)
        self.account.save()
        risk.save()
Exemplo n.º 14
0
    def __init__(self,
                 user: QA_User,
                 wsuri: str,
                 broker_name='simnow',
                 sig=True):

        super().__init__(name='QAModel_{}'.format(account_cookie))

        self.account_cookie = user.generate_simpleaccount()
        self.password = password
        self.broker_name = broker_name
        self.account_client = DATABASE.model
        self.connection = True
        self.message = {
            'password': password,
            'wsuri': wsuri,
            'broker_name': broker_name,
            'updatetime': str(datetime.datetime.now()),
            'accounts': {},
            'orders': {},
            'positions': {},
            'trades': {}
        }
        self.last_update_time = datetime.datetime.now()
        self.sig = sig
        self.if_restart = False
        self.orders_client = DATABASE.orders
Exemplo n.º 15
0
    def __init__(
            self,
            market_type,
            frequence,
            start,
            end,
            code_list,
            commission_fee,
            username='******',
            password='******',
            portfolio_cookie='qatestportfolio'
    ):
        """
        :param market_type: 回测的市场 MARKET_TYPE.STOCK_CN ,
        :param frequence: 'day' '1min' '5min' '15min' '30min' '60min'
        :param start:     开始日期
        :param end:       结束日期
        :param code_list: 股票代码池
        :param commission_fee: 交易佣金
        """
        self.user = QA_User(username=username, password=password)
        self.if_settled = False
        self.account = None
        self.portfolio = self.user.new_portfolio(portfolio_cookie)
        # 🛠todo market_type 应该放在 QA_Market对象里的一个属性
        self.market = QA_Market(if_start_orderthreading=True)
        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

        # 🛠todo 检查start日期和结束end日期是否正确
        # 🛠todo 检查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

        else:
            QA_util_log_info("{} 的市场类型没有实现!".format(market_type))
Exemplo n.º 16
0
    def __init__(
        self,
        market_type,
        frequence,
        start,
        end,
        code_list,
        commission_fee,
    ):
        """

        :param market_type: 回测的市场 MARKET_TYPE.STOCK_CN ,
        :param frequence: 'day' '1min' '5min' '15min' '30min' '60min'
        :param start:     开始日期
        :param end:       结束日期
        :param code_list: 股票代码池
        :param 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
        else:
            QA_util_log_info("{} 的市场类型没有实现!".format(market_type))
Exemplo n.º 17
0
    def __init__(self, market_type, frequence,):
        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_SPEBroker()
        self.broker_name = 'shipane_broker'

        self.ingest_data = None
Exemplo n.º 18
0
    def __init__(self, code, market_type, frequence, broker_name=BROKER_TYPE.SHIPANE, broker=None,):
        self.user = QA_User()
        self.if_settled = False
        self.account = None
        self.portfolio = None

        self.market = QA_Market(if_start_orderthreading=True)
        self.market_type = market_type

        self.frequence = frequence

        #self.broker = QA_SPEBroker()
        self.broker_name = broker_name

        self.ingest_data = None
Exemplo n.º 19
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()
        maminstrategy = MAMINStrategy()
        self.portfolio, self.account = self.user.register_account(mastrategy)

    def after_success(self):
        QA_util_log_info(self.account.history_table)
        risk = QA_Risk(self.account)

        print(risk.assets)
        print('annualize_return : {} %'.format(risk.annualize_return))
        print('max_dropback : {} %'.format(risk.max_dropback))
        print('profit : {} %'.format(risk.profit))
        print('volatility : {}'.format(risk.volatility))

        self.account.save()
Exemplo n.º 20
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()
        maminstrategy = MAMINStrategy()

        self.portfolio, self.account = self.user.register_account(mastrategy)

        self.portfolio.add_account(MAStrategy())

    def after_success(self):
        QA_util_log_info(self.account.history_table)
        risk = QA_Risk(self.account,
                       benchmark_code='000300',
                       benchmark_type=MARKET_TYPE.INDEX_CN)

        print(risk().T)

        self.account.save()
        risk.save()
Exemplo n.º 21
0
class QARTC_Stock(QA_Tdx_Executor):
    def __init__(self, username, password):
        super().__init__(name='QAREALTIME_COLLECTOR_STOCK')
        self.user = QA_User(username=username, password=password)
        self.sub = subscriber_routing(exchange='QARealtime_Market',
                                      routing_key='stock')
        self.sub.callback = self.callback
        threading.Thread(target=self.sub.start, daemon=True).start()

    def subscribe(self, code):
        """继续订阅

        Arguments:
            code {[type]} -- [description]
        """
        self.user.sub_code(code)

    def unsubscribe(self, code):
        self.user.unsub_code(code)

    def callback(self, a, b, c, data):
        data = json.loads(data)
        if data['topic'] == 'subscribe':
            print('receive new subscribe: {}'.format(data['code']))
            new_ins = data['code'].replace('_', '.').split(',')

            import copy
            if isinstance(new_ins, list):
                for item in new_ins:
                    self.user.sub_code(item)
            else:
                self.user.sub_code(new_ins)
        if data['topic'] == 'unsubscribe':
            print('receive new unsubscribe: {}'.format(data['code']))
            new_ins = data['code'].replace('_', '.').split(',')

            import copy
            if isinstance(new_ins, list):
                for item in new_ins:
                    self.user.unsub_code(item)
            else:
                self.user.unsub_code(new_ins)

    def get_data(self):
        data = self.get_realtime_concurrent(self.user.subscribed_code)
        print(data)

    def run(self):
        while 1:
            self.get_data()
            import time
            time.sleep(1)
Exemplo n.º 22
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()
Exemplo n.º 23
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,):
        """
        :param market_type: 回测的市场 MARKET_TYPE.STOCK_CN ,
        :param frequence: 'day' '1min' '5min' '15min' '30min' '60min'
        :param start:     开始日期
        :param end:       结束日期
        :param code_list: 股票代码池
        :param commission_fee: 交易佣金
        """
        self.user = QA_User()
        self.if_settled = False
        self.account = None
        self.portfolio = None

        #🛠todo market_type 应该放在 QA_Market对象里的一个属性
        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

        #🛠todo 检查start日期和结束end日期是否正确
        #🛠todo 检查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

        else:
            QA_util_log_info("{} 的市场类型没有实现!".format(market_type))

    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
        QAMarket 继承QATrader, QATrader 中有 trade_engine属性 , trade_engine类型是QA_Engine从 QA_Thread继承
        """
        # 启动 trade_engine 线程
        self.market.start()

        # 注册 backtest_broker ,并且启动和它关联线程QAThread 存放在 kernels 词典中, { 'broker_name': QAThread }
        self.market.register(self.broker_name, self.broker)

        # 通过 broke名字 新建立一个 QAAccount 放在的中 session字典中 session 是 { 'cookie' , QAAccount }
        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:  # 对于在ingest_data中的数据
            #<class 'QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_day'>
            date = data.date[0]
            if self.market_type is MARKET_TYPE.STOCK_CN:  # 如果是股票市场
                if _date != date:  # 如果新的date

                    # 前一天的交易日已经过去
                    # 往 broker 和 account 发送 settle 事件
                    try:
                        self.market.trade_engine.join()
                        #time.sleep(2)
                        self.market._settle(self.broker_name)

                    except Exception as e:
                        raise e
            # 基金 指数 期货
            elif self.market_type in [MARKET_TYPE.FUND_CN, MARKET_TYPE.INDEX_CN, MARKET_TYPE.FUTURE_CN]:
                self.market._settle(self.broker_name)
            # print(data)
            self.broker.run(
                QA_Event(event_type=ENGINE_EVENT.UPCOMING_DATA, market_data=data))
            # 生成 UPCOMING_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_by_cookie(po).accounts.keys():
                accounts = self.user.get_portfolio_by_cookie(
                    po).get_account_by_cookie(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()
Exemplo n.º 24
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,
    ):
        """
        :param market_type: 回测的市场 MARKET_TYPE.STOCK_CN ,
        :param frequence: 'day' '1min' '5min' '15min' '30min' '60min'
        :param start:     开始日期
        :param end:       结束日期
        :param code_list: 股票代码池
        :param commission_fee: 交易佣金
        """
        self.user = QA_User()
        self.if_settled = False
        self.account = None
        self.portfolio = None

        #🛠todo market_type 应该放在 QA_Market对象里的一个属性
        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

        #🛠todo 检查start日期和结束end日期是否正确
        #🛠todo 检查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

        else:
            QA_util_log_info("{} 的市场类型没有实现!".format(market_type))

    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
        QAMarket 继承QATrader, QATrader 中有 trade_engine属性 , trade_engine类型是QA_Engine从 QA_Thread继承
        """
        # 启动 trade_engine 线程
        self.market.start()

        # 注册 backtest_broker ,并且启动和它关联线程QAThread 存放在 kernels 词典中, { 'broker_name': QAThread }
        self.market.register(self.broker_name, self.broker)

        # 通过 broke名字 新建立一个 QAAccount 放在的中 session字典中 session 是 { 'cookie' , QAAccount }
        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:  # 对于在ingest_data中的数据
            #<class 'QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_day'>
            date = data.date[0]
            if self.market_type is MARKET_TYPE.STOCK_CN:  # 如果是股票市场
                if _date != date:  # 如果新的date

                    # 前一天的交易日已经过去
                    # 往 broker 和 account 发送 settle 事件
                    try:
                        self.market.trade_engine.join()
                        #time.sleep(2)
                        self.market._settle(self.broker_name)

                    except Exception as e:
                        raise e
            # 基金 指数 期货
            elif self.market_type in [
                    MARKET_TYPE.FUND_CN, MARKET_TYPE.INDEX_CN,
                    MARKET_TYPE.FUTURE_CN
            ]:
                self.market._settle(self.broker_name)
            # print(data)
            self.broker.run(
                QA_Event(event_type=ENGINE_EVENT.UPCOMING_DATA,
                         market_data=data))
            # 生成 UPCOMING_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_by_cookie(po).accounts.keys():
                accounts = self.user.get_portfolio_by_cookie(
                    po).get_account_by_cookie(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()
 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)