Esempio n. 1
0
class Backtest(object):
    """
    Event driven backtest engine
    """
    def __init__(self, config):
        """
        1. read in configs
        2. Set up backtest event engine
        """
        self._current_time = Timestamp('1900-01-01')

        ## 0. read in configs
        self._initial_cash = config['cash']
        self._symbols = config['tickers']
        self._benchmark = config['benchmark']
        #self.start_date = datetime.datetime.strptime(config['start_date'], "%Y-%m-%d")
        #self.end_date = datetime.datetime.strptime(config['end_date'], "%Y-%m-%d")
        start_date = config['start_date']
        send_date = config['end_date']
        strategy_name = config['strategy']
        datasource = str(config['datasource'])
        self._hist_dir = config['hist_dir']
        self._output_dir = config['output_dir']

        ## 1. data_feed
        symbols_all = self._symbols[:]  # copy
        if self._benchmark is not None:
            symbols_all.append(self._benchmark)
        self._symbols = [str(s) for s in self._symbols]
        symbols_all = [str(s) for s in symbols_all]

        if (datasource.upper() == 'LOCAL'):
            self._data_feed = BacktestDataFeedLocal(hist_dir=self._hist_dir,
                                                    start_date=start_date,
                                                    end_date=send_date)
        elif (datasource.upper() == 'TUSHARE'):
            self._data_feed = BacktestDataFeedTushare(start_date=start_date,
                                                      end_date=send_date)
        else:
            self._data_feed = BacktestDataFeedQuandl(start_date=start_date,
                                                     end_date=send_date)

        self._data_feed.subscribe_market_data(symbols_all)

        ## 2. event engine
        self._events_engine = BacktestEventEngine(self._data_feed)

        ## 3. brokerage
        self._data_board = DataBoard()
        self._backtest_brokerage = BacktestBrokerage(self._events_engine,
                                                     self._data_board)

        ## 4. portfolio_manager
        self._portfolio_manager = PortfolioManager(self._initial_cash)

        ## 5. performance_manager
        self._performance_manager = PerformanceManager(symbols_all)

        ## 6. risk_manager
        self._risk_manager = PassThroughRiskManager()

        ## 7. load all strategies
        strategyClass = strategy_list.get(strategy_name, None)
        if not strategyClass:
            print(u'can not find strategy:%s' % strategy_name)
            return
        self._strategy = strategyClass(self._symbols, self._events_engine)
        self._strategy.on_init()
        self._strategy.on_start()

        ## 8. trade recorder
        #self._trade_recorder = ExampleTradeRecorder(output_dir)

        ## 9. wire up event handlers
        self._events_engine.register_handler(EventType.TICK,
                                             self._tick_event_handler)
        self._events_engine.register_handler(EventType.BAR,
                                             self._bar_event_handler)
        self._events_engine.register_handler(EventType.ORDER,
                                             self._order_event_handler)
        self._events_engine.register_handler(EventType.FILL,
                                             self._fill_event_handler)

    # ------------------------------------ private functions -----------------------------#
    def _tick_event_handler(self, tick_event):
        self._current_time = tick_event.timestamp

        # performance update goes before position updates because it updates previous day performance
        self._performance_manager.update_performance(self._current_time,
                                                     self._portfolio_manager,
                                                     self._data_board)
        self._portfolio_manager.mark_to_market(self._current_time,
                                               tick_event.full_symbol,
                                               tick_event.price)
        self._data_board.on_tick(tick_event)
        self._strategy.on_tick(tick_event)

    def _bar_event_handler(self, bar_event):
        self._current_time = bar_event.bar_end_time()

        # performance update goes before position updates because it updates previous day
        self._performance_manager.update_performance(self._current_time,
                                                     self._portfolio_manager,
                                                     self._data_board)
        self._portfolio_manager.mark_to_market(self._current_time,
                                               bar_event.full_symbol,
                                               bar_event.adj_close_price)
        self._data_board.on_bar(bar_event)
        self._strategy.on_bar(bar_event)

    def _order_event_handler(self, order_event):
        self._backtest_brokerage.place_order(order_event)

    def _fill_event_handler(self, fill_event):
        self._portfolio_manager.on_fill(fill_event)
        self._performance_manager.on_fill(fill_event)

    # -------------------------------- end of private functions -----------------------------#

    # -------------------------------------- public functions -------------------------------#
    def run(self):
        """
        Run backtest
        """
        self._events_engine.run()
        self._performance_manager.update_final_performance(
            self._current_time, self._portfolio_manager, self._data_board)
        self._performance_manager.save_results(self._output_dir)
        self._performance_manager.create_tearsheet()
Esempio n. 2
0
    def __init__(self, config):
        """
        1. read in configs
        2. Set up backtest event engine
        """
        self._current_time = Timestamp('1900-01-01')

        ## 0. read in configs
        self._initial_cash = config['cash']
        self._symbols = config['tickers']
        self._benchmark = config['benchmark']
        #self.start_date = datetime.datetime.strptime(config['start_date'], "%Y-%m-%d")
        #self.end_date = datetime.datetime.strptime(config['end_date'], "%Y-%m-%d")
        start_date = config['start_date']
        send_date = config['end_date']
        strategy_name = config['strategy']
        datasource = str(config['datasource'])
        self._hist_dir = config['hist_dir']
        self._output_dir = config['output_dir']

        ## 1. data_feed
        symbols_all = self._symbols[:]  # copy
        if self._benchmark is not None:
            symbols_all.append(self._benchmark)
        self._symbols = [str(s) for s in self._symbols]
        symbols_all = [str(s) for s in symbols_all]

        if (datasource.upper() == 'LOCAL'):
            self._data_feed = BacktestDataFeedLocal(hist_dir=self._hist_dir,
                                                    start_date=start_date,
                                                    end_date=send_date)
        elif (datasource.upper() == 'TUSHARE'):
            self._data_feed = BacktestDataFeedTushare(start_date=start_date,
                                                      end_date=send_date)
        else:
            self._data_feed = BacktestDataFeedQuandl(start_date=start_date,
                                                     end_date=send_date)

        self._data_feed.subscribe_market_data(symbols_all)

        ## 2. event engine
        self._events_engine = BacktestEventEngine(self._data_feed)

        ## 3. brokerage
        self._data_board = DataBoard()
        self._backtest_brokerage = BacktestBrokerage(self._events_engine,
                                                     self._data_board)

        ## 4. portfolio_manager
        self._portfolio_manager = PortfolioManager(self._initial_cash)

        ## 5. performance_manager
        self._performance_manager = PerformanceManager(symbols_all)

        ## 6. risk_manager
        self._risk_manager = PassThroughRiskManager()

        ## 7. load all strategies
        strategyClass = strategy_list.get(strategy_name, None)
        if not strategyClass:
            print(u'can not find strategy:%s' % strategy_name)
            return
        self._strategy = strategyClass(self._symbols, self._events_engine)
        self._strategy.on_init()
        self._strategy.on_start()

        ## 8. trade recorder
        #self._trade_recorder = ExampleTradeRecorder(output_dir)

        ## 9. wire up event handlers
        self._events_engine.register_handler(EventType.TICK,
                                             self._tick_event_handler)
        self._events_engine.register_handler(EventType.BAR,
                                             self._bar_event_handler)
        self._events_engine.register_handler(EventType.ORDER,
                                             self._order_event_handler)
        self._events_engine.register_handler(EventType.FILL,
                                             self._fill_event_handler)
class BacktestEngine(object):
    """
    Event driven backtest engine
    """
    def __init__(self, config):
        """
        1. read in configs
        2. Set up backtest event engine
        """
        self._current_time = None

        ## 0. read in configs
        self._initial_cash = config['cash']
        self._symbols = config['symbols']
        self._benchmark = config['benchmark']
        #self.start_date = datetime.datetime.strptime(config['start_date'], "%Y-%m-%d")
        #self.end_date = datetime.datetime.strptime(config['end_date'], "%Y-%m-%d")
        start_date = config['start_date']
        send_date = config['end_date']
        params = config['params']
        strategy_name = config['strategy']
        datasource = str(config['datasource'])
        batch_tag = config['batch_tag']
        root_multiplier = config['root_multiplier']
        self._hist_dir = config['hist_dir']
        self._fvp_file = config['fvp_file']
        self._output_dir = config['output_dir']

        ## 1. data_feed
        symbols_all = self._symbols[:]   # copy
        if self._benchmark is not None:
            symbols_all.append(self._benchmark)
        self._symbols = [str(s) for s in self._symbols]
        symbols_all = set([str(s) for s in symbols_all])  # remove duplicates

        if (datasource.upper() == 'LOCAL'):
            print('Using local single symbol data feed')
            self._data_feed = BacktestDataFeedLocalSingleSymbol(
                hist_dir=self._hist_dir,
                start_date=start_date, end_date=send_date
            )
        elif (datasource.upper() == 'MULTI_LOCAL'):
            print('Using local multiple symbol data feed')
            self._data_feed = BacktestDataFeedLocalMultipleSymbols(
                hist_dir=self._hist_dir,
                start_date=start_date, end_date=send_date
            )
        else:
            print('Using Quandl data feed')
            self._data_feed = BacktestDataFeedQuandl(
                start_date=start_date, end_date=send_date
            )

        self._data_feed.subscribe_market_data(self._symbols)         # not symbols_all

        ## 2. event engine
        self._events_engine = BacktestEventEngine(self._data_feed)

        ## 3. brokerage
        self._data_board = DataBoard(hist_dir=self._hist_dir, syms=symbols_all)
        self._backtest_brokerage = BacktestBrokerage(
            self._events_engine, self._data_board
        )

        ## 4. portfolio_manager
        self._df_fvp = None
        if self._fvp_file is not None:
            self._df_fvp = pd.read_csv(self._hist_dir+self._fvp_file, index_col=0)

        self._portfolio_manager = PortfolioManager(self._initial_cash, self._df_fvp)

        ## 5. performance_manager
        self._performance_manager = PerformanceManager(self._symbols, self._benchmark, batch_tag, root_multiplier, self._df_fvp)

        ## 6. risk_manager
        self._risk_manager = PassThroughRiskManager()

        ## 7. load all strategies
        strategyClass = strategy_list.get(strategy_name, None)
        if not strategyClass:
            print(u'can not find strategy:%s' % strategy_name)
            return
        else:
            print(u'backtesting strategy:%s' % strategy_name)
        self._strategy = strategyClass(self._events_engine, self._data_board)
        self._strategy.set_symbols(self._symbols)
        self._strategy.set_capital(self._initial_cash)
        self._strategy.on_init(params)
        self._strategy.on_start()

        ## 8. trade recorder
        #self._trade_recorder = ExampleTradeRecorder(output_dir)

        ## 9. wire up event handlers
        self._events_engine.register_handler(EventType.TICK, self._tick_event_handler)
        self._events_engine.register_handler(EventType.BAR, self._bar_event_handler)
        self._events_engine.register_handler(EventType.ORDER, self._order_event_handler)
        self._events_engine.register_handler(EventType.FILL, self._fill_event_handler)

    # ------------------------------------ private functions -----------------------------#
    def _tick_event_handler(self, tick_event):
        self._current_time = tick_event.timestamp

        # performance update goes before position updates because it updates previous day performance
        self._performance_manager.update_performance(self._current_time, self._portfolio_manager, self._data_board)
        self._portfolio_manager.mark_to_market(self._current_time, tick_event.full_symbol, tick_event.price, self._data_board)
        self._data_board.on_tick(tick_event)
        self._strategy.on_tick(tick_event)

    def _bar_event_handler(self, bar_event):
        self._current_time = bar_event.bar_end_time()

        # performance update goes before position updates because it updates previous day
        self._performance_manager.update_performance(self._current_time, self._portfolio_manager, self._data_board)
        self._portfolio_manager.mark_to_market(self._current_time, bar_event.full_symbol, bar_event.adj_close_price, self._data_board)
        self._data_board.on_bar(bar_event)
        self._strategy.on_bar(bar_event)

    def _order_event_handler(self, order_event):
        self._backtest_brokerage.place_order(order_event)

    def _fill_event_handler(self, fill_event):
        self._portfolio_manager.on_fill(fill_event)
        self._performance_manager.on_fill(fill_event)

    # -------------------------------- end of private functions -----------------------------#

    # -------------------------------------- public functions -------------------------------#
    def run(self, tear_sheet=True):
        """
        Run backtest
        """
        self._events_engine.run()
        self._performance_manager.update_final_performance(self._current_time, self._portfolio_manager, self._data_board)
        self._performance_manager.save_results(self._output_dir)

        return self._performance_manager.caculate_performance(tear_sheet)
    def __init__(self, config):
        """
        1. read in configs
        2. Set up backtest event engine
        """
        self._current_time = None

        ## 0. read in configs
        self._initial_cash = config['cash']
        self._symbols = config['symbols']
        self._benchmark = config['benchmark']
        #self.start_date = datetime.datetime.strptime(config['start_date'], "%Y-%m-%d")
        #self.end_date = datetime.datetime.strptime(config['end_date'], "%Y-%m-%d")
        start_date = config['start_date']
        send_date = config['end_date']
        params = config['params']
        strategy_name = config['strategy']
        datasource = str(config['datasource'])
        batch_tag = config['batch_tag']
        root_multiplier = config['root_multiplier']
        self._hist_dir = config['hist_dir']
        self._fvp_file = config['fvp_file']
        self._output_dir = config['output_dir']

        ## 1. data_feed
        symbols_all = self._symbols[:]   # copy
        if self._benchmark is not None:
            symbols_all.append(self._benchmark)
        self._symbols = [str(s) for s in self._symbols]
        symbols_all = set([str(s) for s in symbols_all])  # remove duplicates

        if (datasource.upper() == 'LOCAL'):
            print('Using local single symbol data feed')
            self._data_feed = BacktestDataFeedLocalSingleSymbol(
                hist_dir=self._hist_dir,
                start_date=start_date, end_date=send_date
            )
        elif (datasource.upper() == 'MULTI_LOCAL'):
            print('Using local multiple symbol data feed')
            self._data_feed = BacktestDataFeedLocalMultipleSymbols(
                hist_dir=self._hist_dir,
                start_date=start_date, end_date=send_date
            )
        else:
            print('Using Quandl data feed')
            self._data_feed = BacktestDataFeedQuandl(
                start_date=start_date, end_date=send_date
            )

        self._data_feed.subscribe_market_data(self._symbols)         # not symbols_all

        ## 2. event engine
        self._events_engine = BacktestEventEngine(self._data_feed)

        ## 3. brokerage
        self._data_board = DataBoard(hist_dir=self._hist_dir, syms=symbols_all)
        self._backtest_brokerage = BacktestBrokerage(
            self._events_engine, self._data_board
        )

        ## 4. portfolio_manager
        self._df_fvp = None
        if self._fvp_file is not None:
            self._df_fvp = pd.read_csv(self._hist_dir+self._fvp_file, index_col=0)

        self._portfolio_manager = PortfolioManager(self._initial_cash, self._df_fvp)

        ## 5. performance_manager
        self._performance_manager = PerformanceManager(self._symbols, self._benchmark, batch_tag, root_multiplier, self._df_fvp)

        ## 6. risk_manager
        self._risk_manager = PassThroughRiskManager()

        ## 7. load all strategies
        strategyClass = strategy_list.get(strategy_name, None)
        if not strategyClass:
            print(u'can not find strategy:%s' % strategy_name)
            return
        else:
            print(u'backtesting strategy:%s' % strategy_name)
        self._strategy = strategyClass(self._events_engine, self._data_board)
        self._strategy.set_symbols(self._symbols)
        self._strategy.set_capital(self._initial_cash)
        self._strategy.on_init(params)
        self._strategy.on_start()

        ## 8. trade recorder
        #self._trade_recorder = ExampleTradeRecorder(output_dir)

        ## 9. wire up event handlers
        self._events_engine.register_handler(EventType.TICK, self._tick_event_handler)
        self._events_engine.register_handler(EventType.BAR, self._bar_event_handler)
        self._events_engine.register_handler(EventType.ORDER, self._order_event_handler)
        self._events_engine.register_handler(EventType.FILL, self._fill_event_handler)
class BacktestEngine(object):
    """
    Event driven backtest engine
    """
    def __init__(self, config):
        """
        1. read in configs
        2. Set up backtest event engine
        """
        self._current_time = None

        ## 0. read in configs
        self._initial_cash = config['cash']
        self._symbols = config['symbols']
        self._benchmark = config['benchmark']
        #self.start_date = datetime.datetime.strptime(config['start_date'], "%Y-%m-%d")
        #self.end_date = datetime.datetime.strptime(config['end_date'], "%Y-%m-%d")
        start_date = config['start_date']
        send_date = config['end_date']
        params = config['params']
        strategy_name = config['strategy']
        datasource = str(config['datasource'])
        batch_tag = config['batch_tag']
        root_multiplier = config['root_multiplier']
        self._hist_dir = config['hist_dir']
        self._fvp_file = config['fvp_file']
        self._output_dir = config['output_dir']

        ## 1. data_feed
        symbols_all = self._symbols[:]  # copy
        if self._benchmark is not None:
            symbols_all.append(self._benchmark)
        self._symbols = [str(s) for s in self._symbols]
        symbols_all = set([str(s) for s in symbols_all])  # remove duplicates

        if (datasource.upper() == 'LOCAL'):
            print('Using local single symbol data feed')
            self._data_feed = BacktestDataFeedLocalSingleSymbol(
                hist_dir=self._hist_dir,
                start_date=start_date,
                end_date=send_date)
        elif (datasource.upper() == 'MULTI_LOCAL'):
            print('Using local multiple symbol data feed')
            self._data_feed = BacktestDataFeedLocalMultipleSymbols(
                hist_dir=self._hist_dir,
                start_date=start_date,
                end_date=send_date)
        else:
            print('Using Quandl data feed')
            self._data_feed = BacktestDataFeedQuandl(start_date=start_date,
                                                     end_date=send_date)

        self._data_feed.subscribe_market_data(self._symbols)  # not symbols_all

        ## 2. event engine
        self._events_engine = BacktestEventEngine(self._data_feed)

        ## 3. brokerage
        self._data_board = DataBoard(hist_dir=self._hist_dir, syms=symbols_all)
        self._backtest_brokerage = BacktestBrokerage(self._events_engine,
                                                     self._data_board)

        ## 4. portfolio_manager
        self._df_fvp = None
        if self._fvp_file is not None:
            self._df_fvp = pd.read_csv(self._hist_dir + self._fvp_file,
                                       index_col=0)

        self._portfolio_manager = PortfolioManager(self._initial_cash,
                                                   self._df_fvp)

        ## 5. performance_manager
        self._performance_manager = PerformanceManager(self._symbols,
                                                       self._benchmark,
                                                       batch_tag,
                                                       root_multiplier,
                                                       self._df_fvp)

        ## 6. risk_manager
        self._risk_manager = PassThroughRiskManager()

        ## 7. load all strategies
        strategyClass = strategy_list.get(strategy_name, None)
        if not strategyClass:
            print(u'can not find strategy:%s' % strategy_name)
            return
        else:
            print(u'backtesting strategy:%s' % strategy_name)
        self._strategy = strategyClass(self._events_engine, self._data_board)
        self._strategy.set_symbols(self._symbols)
        self._strategy.set_capital(self._initial_cash)
        self._strategy.on_init(params)
        self._strategy.on_start()

        ## 8. trade recorder
        #self._trade_recorder = ExampleTradeRecorder(output_dir)

        ## 9. wire up event handlers
        self._events_engine.register_handler(EventType.TICK,
                                             self._tick_event_handler)
        self._events_engine.register_handler(EventType.BAR,
                                             self._bar_event_handler)
        self._events_engine.register_handler(EventType.ORDER,
                                             self._order_event_handler)
        self._events_engine.register_handler(EventType.FILL,
                                             self._fill_event_handler)

    # ------------------------------------ private functions -----------------------------#
    def _tick_event_handler(self, tick_event):
        self._current_time = tick_event.timestamp

        # performance update goes before position updates because it updates previous day performance
        self._performance_manager.update_performance(self._current_time,
                                                     self._portfolio_manager,
                                                     self._data_board)
        self._portfolio_manager.mark_to_market(self._current_time,
                                               tick_event.full_symbol,
                                               tick_event.price,
                                               self._data_board)
        self._data_board.on_tick(tick_event)
        self._strategy.on_tick(tick_event)

    def _bar_event_handler(self, bar_event):
        self._current_time = bar_event.bar_end_time()

        # performance update goes before position updates because it updates previous day
        self._performance_manager.update_performance(self._current_time,
                                                     self._portfolio_manager,
                                                     self._data_board)
        self._portfolio_manager.mark_to_market(self._current_time,
                                               bar_event.full_symbol,
                                               bar_event.adj_close_price,
                                               self._data_board)
        self._data_board.on_bar(bar_event)
        self._strategy.on_bar(bar_event)

    def _order_event_handler(self, order_event):
        self._backtest_brokerage.place_order(order_event)

    def _fill_event_handler(self, fill_event):
        self._portfolio_manager.on_fill(fill_event)
        self._performance_manager.on_fill(fill_event)

    # -------------------------------- end of private functions -----------------------------#

    # -------------------------------------- public functions -------------------------------#
    def run(self, tear_sheet=True):
        """
        Run backtest
        """
        self._events_engine.run()
        self._performance_manager.update_final_performance(
            self._current_time, self._portfolio_manager, self._data_board)
        self._performance_manager.save_results(self._output_dir)

        return self._performance_manager.caculate_performance(tear_sheet)
    def __init__(self, config):
        """
        1. read in configs
        2. Set up backtest event engine
        """
        self._current_time = None

        ## 0. read in configs
        self._initial_cash = config['cash']
        self._symbols = config['symbols']
        self._benchmark = config['benchmark']
        #self.start_date = datetime.datetime.strptime(config['start_date'], "%Y-%m-%d")
        #self.end_date = datetime.datetime.strptime(config['end_date'], "%Y-%m-%d")
        start_date = config['start_date']
        send_date = config['end_date']
        params = config['params']
        strategy_name = config['strategy']
        datasource = str(config['datasource'])
        batch_tag = config['batch_tag']
        root_multiplier = config['root_multiplier']
        self._hist_dir = config['hist_dir']
        self._fvp_file = config['fvp_file']
        self._output_dir = config['output_dir']

        ## 1. data_feed
        symbols_all = self._symbols[:]  # copy
        if self._benchmark is not None:
            symbols_all.append(self._benchmark)
        self._symbols = [str(s) for s in self._symbols]
        symbols_all = set([str(s) for s in symbols_all])  # remove duplicates

        if (datasource.upper() == 'LOCAL'):
            print('Using local single symbol data feed')
            self._data_feed = BacktestDataFeedLocalSingleSymbol(
                hist_dir=self._hist_dir,
                start_date=start_date,
                end_date=send_date)
        elif (datasource.upper() == 'MULTI_LOCAL'):
            print('Using local multiple symbol data feed')
            self._data_feed = BacktestDataFeedLocalMultipleSymbols(
                hist_dir=self._hist_dir,
                start_date=start_date,
                end_date=send_date)
        else:
            print('Using Quandl data feed')
            self._data_feed = BacktestDataFeedQuandl(start_date=start_date,
                                                     end_date=send_date)

        self._data_feed.subscribe_market_data(self._symbols)  # not symbols_all

        ## 2. event engine
        self._events_engine = BacktestEventEngine(self._data_feed)

        ## 3. brokerage
        self._data_board = DataBoard(hist_dir=self._hist_dir, syms=symbols_all)
        self._backtest_brokerage = BacktestBrokerage(self._events_engine,
                                                     self._data_board)

        ## 4. portfolio_manager
        self._df_fvp = None
        if self._fvp_file is not None:
            self._df_fvp = pd.read_csv(self._hist_dir + self._fvp_file,
                                       index_col=0)

        self._portfolio_manager = PortfolioManager(self._initial_cash,
                                                   self._df_fvp)

        ## 5. performance_manager
        self._performance_manager = PerformanceManager(self._symbols,
                                                       self._benchmark,
                                                       batch_tag,
                                                       root_multiplier,
                                                       self._df_fvp)

        ## 6. risk_manager
        self._risk_manager = PassThroughRiskManager()

        ## 7. load all strategies
        strategyClass = strategy_list.get(strategy_name, None)
        if not strategyClass:
            print(u'can not find strategy:%s' % strategy_name)
            return
        else:
            print(u'backtesting strategy:%s' % strategy_name)
        self._strategy = strategyClass(self._events_engine, self._data_board)
        self._strategy.set_symbols(self._symbols)
        self._strategy.set_capital(self._initial_cash)
        self._strategy.on_init(params)
        self._strategy.on_start()

        ## 8. trade recorder
        #self._trade_recorder = ExampleTradeRecorder(output_dir)

        ## 9. wire up event handlers
        self._events_engine.register_handler(EventType.TICK,
                                             self._tick_event_handler)
        self._events_engine.register_handler(EventType.BAR,
                                             self._bar_event_handler)
        self._events_engine.register_handler(EventType.ORDER,
                                             self._order_event_handler)
        self._events_engine.register_handler(EventType.FILL,
                                             self._fill_event_handler)
    def __init__(self, config_server, config_client, lang_dict):
        super(MainWindow, self).__init__()

        ## member variables
        self._current_time = None
        self._config_server = config_server
        self._config_client = config_client
        self._symbols =  config_server[config_server['accounts'][0]]['tickers']
        self._lang_dict = lang_dict
        self._font = lang_dict['font']
        self._widget_dict = {}
        self.central_widget = None
        self.market_window = None
        self.message_window = None
        self.order_window = None
        self.fill_window = None
        self.position_window = None
        self.account_window = None
        self.strategy_window = None

        #  0. order_manager; some of ui_windows uses order_manager
        self._order_manager = OrderManager()

        ## 1. event engine
        self._outgoing_queue = Queue()                    # outgoing queue from client side
        self._ui_events_engine = LiveEventEngine()        # update ui
        self._outgoing_request_events_engine = LiveEventEngine()          # events/actions request from client
        self._schedule_timer = QtCore.QTimer()                  # task scheduler; TODO produce result_packet

        # 3. data board
        self._data_board = DataBoard()

        # 5. risk manager and compliance manager
        self.risk_manager = PassThroughRiskManager()

        # 6. account manager
        self.account_manager = AccountManager(self._config_server)

        # 7 portfolio manager and position manager
        self.portfolio_manager = PortfolioManager(self._config_client['initial_cash'])

        ## 4. strategy_manager
        self._strategy_manager = StrategyManager(self._config_client, self._outgoing_request_events_engine,self._order_manager,self.portfolio_manager, self._data_board)
        self._strategy_manager.load_strategy()

        ## 8. client mq
        self._client_mq = ClientMq(self._ui_events_engine, self._outgoing_queue)

        # 1. set up gui windows
        self.setGeometry(50, 50, 600, 400)
        self.setWindowTitle(lang_dict['Prog_Name'])
        self.setWindowIcon(QtGui.QIcon("gui/image/logo.ico"))
        self.init_menu()
        self.init_status_bar()
        self.init_central_area()

        ## 9. wire up event handlers
        self._ui_events_engine.register_handler(EventType.TICK, self._tick_event_handler)
        self._ui_events_engine.register_handler(EventType.ORDERSTATUS, self.order_window.order_status_signal.emit)
        self._ui_events_engine.register_handler(EventType.FILL, self._fill_event_handler)
        self._ui_events_engine.register_handler(EventType.POSITION, self._position_event_handler)
        self._ui_events_engine.register_handler(EventType.ACCOUNT, self.account_window.account_signal.emit)
        self._ui_events_engine.register_handler(EventType.CONTRACT, self._contract_event_handler)
        self._ui_events_engine.register_handler(EventType.HISTORICAL, self._historical_event_handler)
        self._ui_events_engine.register_handler(EventType.GENERAL, self.log_window.msg_signal.emit)

        self._outgoing_request_events_engine.register_handler(EventType.ORDER, self._outgoing_order_request_handler)
        self._outgoing_request_events_engine.register_handler(EventType.ACCOUNT, self._outgoing_account_request_handler)
        self._outgoing_request_events_engine.register_handler(EventType.POSITION, self._outgoing_position_request_handler)
        self._outgoing_request_events_engine.register_handler(EventType.GENERAL, self._outgoing_general_msg_request_handler)

        ## 10. start
        self._ui_events_engine.start()
        self._outgoing_request_events_engine.start()
        self._client_mq.start()
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, config_server, config_client, lang_dict):
        super(MainWindow, self).__init__()

        ## member variables
        self._current_time = None
        self._config_server = config_server
        self._config_client = config_client
        self._symbols =  config_server[config_server['accounts'][0]]['tickers']
        self._lang_dict = lang_dict
        self._font = lang_dict['font']
        self._widget_dict = {}
        self.central_widget = None
        self.market_window = None
        self.message_window = None
        self.order_window = None
        self.fill_window = None
        self.position_window = None
        self.account_window = None
        self.strategy_window = None

        #  0. order_manager; some of ui_windows uses order_manager
        self._order_manager = OrderManager()

        ## 1. event engine
        self._outgoing_queue = Queue()                    # outgoing queue from client side
        self._ui_events_engine = LiveEventEngine()        # update ui
        self._outgoing_request_events_engine = LiveEventEngine()          # events/actions request from client
        self._schedule_timer = QtCore.QTimer()                  # task scheduler; TODO produce result_packet

        # 3. data board
        self._data_board = DataBoard()

        # 5. risk manager and compliance manager
        self.risk_manager = PassThroughRiskManager()

        # 6. account manager
        self.account_manager = AccountManager(self._config_server)

        # 7 portfolio manager and position manager
        self.portfolio_manager = PortfolioManager(self._config_client['initial_cash'])

        ## 4. strategy_manager
        self._strategy_manager = StrategyManager(self._config_client, self._outgoing_request_events_engine,self._order_manager,self.portfolio_manager, self._data_board)
        self._strategy_manager.load_strategy()

        ## 8. client mq
        self._client_mq = ClientMq(self._ui_events_engine, self._outgoing_queue)

        # 1. set up gui windows
        self.setGeometry(50, 50, 600, 400)
        self.setWindowTitle(lang_dict['Prog_Name'])
        self.setWindowIcon(QtGui.QIcon("gui/image/logo.ico"))
        self.init_menu()
        self.init_status_bar()
        self.init_central_area()

        ## 9. wire up event handlers
        self._ui_events_engine.register_handler(EventType.TICK, self._tick_event_handler)
        self._ui_events_engine.register_handler(EventType.ORDERSTATUS, self.order_window.order_status_signal.emit)
        self._ui_events_engine.register_handler(EventType.FILL, self._fill_event_handler)
        self._ui_events_engine.register_handler(EventType.POSITION, self._position_event_handler)
        self._ui_events_engine.register_handler(EventType.ACCOUNT, self.account_window.account_signal.emit)
        self._ui_events_engine.register_handler(EventType.CONTRACT, self._contract_event_handler)
        self._ui_events_engine.register_handler(EventType.HISTORICAL, self._historical_event_handler)
        self._ui_events_engine.register_handler(EventType.GENERAL, self.log_window.msg_signal.emit)

        self._outgoing_request_events_engine.register_handler(EventType.ORDER, self._outgoing_order_request_handler)
        self._outgoing_request_events_engine.register_handler(EventType.ACCOUNT, self._outgoing_account_request_handler)
        self._outgoing_request_events_engine.register_handler(EventType.POSITION, self._outgoing_position_request_handler)
        self._outgoing_request_events_engine.register_handler(EventType.GENERAL, self._outgoing_general_msg_request_handler)

        ## 10. start
        self._ui_events_engine.start()
        self._outgoing_request_events_engine.start()
        self._client_mq.start()

    #################################################################################################
    # -------------------------------- Event Handler   --------------------------------------------#
    #################################################################################################
    def update_status_bar(self, message):
        self.statusBar().showMessage(message)

    def open_proj_folder(self):
        webbrowser.open('d:/workspace/elitequant_python/')

    def place_order(self):
        s = str(self.sym.text())
        n = self.direction.currentIndex()
        f = self.order_flag.currentIndex()
        p = str(self.order_price.text())
        q = str(self.order_quantity.text())
        t = self.order_type.currentIndex()

        # to be checked by risk manger
        try:
            o = OrderEvent()
            o.full_symbol = s
            o.order_size = int(q) if (n == 0) else -1 * int(q)
            o.order_flag = OrderFlag(f)
            o.create_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')

            if (t == 0):
                o.order_type = OrderType.MARKET
                self._outgoing_request_events_engine.put(o)
            elif (t == 1):
                o.order_type = OrderType.LIMIT
                o.limit_price = float(p)
                self._outgoing_request_events_engine.put(o)
            else:
                pass
        except:
            print('place order error')

    def start_strategy(self):
        self.strategy_window.update_status(self.strategy_window.currentRow(), True)

    def pause_strategy(self):
        pass

    def stop_strategy(self):
        self.strategy_window.update_status(self.strategy_window.currentRow(), False)

    def closeEvent(self, a0: QtGui.QCloseEvent):
        print('closing main window')
        self._ui_events_engine.stop()
        self._outgoing_request_events_engine.stop()
        self._client_mq.stop()

    def _tick_event_handler(self, tick_event):
        self._current_time = tick_event.timestamp

        self._data_board.on_tick(tick_event)       # update databoard
        self._order_manager.on_tick(tick_event)     # check standing stop orders
        self._strategy_manager.on_tick(tick_event)  # feed strategies
        self.market_window.tick_signal.emit(tick_event)         # display

    def _order_status_event_handler(self, order_status_event):  # including cancel
        # this is moved to ui_thread for consistency
        pass

    def _fill_event_handler(self, fill_event):
        # update portfolio manager for pnl
        self._order_manager.on_fill(fill_event)  # update order manager with fill
        self._strategy_manager.on_fill(fill_event)  # feed fill to strategy
        self.fill_window.fill_signal.emit(fill_event)     # display
        self.order_window.update_order_status(fill_event.client_order_id,
                                              self._order_manager.retrieve_order(fill_event.client_order_id).order_status)

    def _position_event_handler(self, position_event):
        self.portfolio_manager.on_position(position_event)       # position received
        self.position_window.position_signal.emit(position_event)     # display

    def _account_event_handler(self, account_event):
        pass

    def _contract_event_handler(self, contract_event):
        self.portfolio_manager.on_contract(contract_event)

    def _historical_event_handler(self, historical_event):
        print(historical_event)

    def _general_event_handler(self, general_event):
        pass

    def _outgoing_order_request_handler(self, o):
        """
         process o, check against risk manager and compliance manager
        """
        self.risk_manager.order_in_compliance(o)  # order pointer; modify order directly
        self._order_manager.on_order(o)

        msg = o.serialize()
        print('send msg: ' + msg)
        self._outgoing_queue.put(msg)

    def _outgoing_account_request_handler(self, a):
        msg = a.serialize()
        print('send msg: ' + msg)
        self._outgoing_queue.put(msg)

    def _outgoing_position_request_handler(self, p):
        msg = p.serialize()
        print('send msg: ' + msg)
        self._outgoing_queue.put(msg)

    def _outgoing_general_msg_request_handler(self, g):
        self.log_window.update_table(g)           # append to log window
    #################################################################################################
    # ------------------------------ Event Handler Ends --------------------------------------------#
    #################################################################################################

    #################################################################################################
    # -------------------------------- User Interface  --------------------------------------------#
    #################################################################################################
    def set_font(self, font):
        self._font = font

    def init_menu(self):
        menubar = self.menuBar()

        sysMenu = menubar.addMenu(self._lang_dict['File'])
        # open folder
        sys_folderAction = QtWidgets.QAction(self._lang_dict['Folder'], self)
        sys_folderAction.setStatusTip(self._lang_dict['Open_Folder'])
        sys_folderAction.triggered.connect(self.open_proj_folder)
        sysMenu.addAction(sys_folderAction)

        sysMenu.addSeparator()

        # sys|exit
        sys_exitAction = QtWidgets.QAction(self._lang_dict['Exit'], self)
        sys_exitAction.setShortcut('Ctrl+Q')
        sys_exitAction.setStatusTip(self._lang_dict['Exit_App'])
        sys_exitAction.triggered.connect(self.close)
        sysMenu.addAction(sys_exitAction)

    def init_status_bar(self):
        self.statusthread = StatusThread()
        self.statusthread.status_update.connect(self.update_status_bar)
        self.statusthread.start()

    def init_central_area(self):
        self.central_widget = QtWidgets.QWidget()

        hbox = QtWidgets.QHBoxLayout()

        #-------------------------------- Top Left ------------------------------------------#
        topleft = MarketWindow(self._symbols, self._lang_dict)
        self.market_window = topleft

        # -------------------------------- Top right ------------------------------------------#
        topright = QtWidgets.QFrame()
        topright.setFrameShape(QtWidgets.QFrame.StyledPanel)
        topright.setFont(self._font)
        place_order_layout = QtWidgets.QFormLayout()
        self.sym = QtWidgets.QLineEdit()
        self.sym_name = QtWidgets.QLineEdit()
        self.sec_type = QtWidgets.QComboBox()
        self.sec_type.addItems([self._lang_dict['Stock'], self._lang_dict['Future'], self._lang_dict['Option'], self._lang_dict['Forex']])
        self.direction = QtWidgets.QComboBox()
        self.direction.addItems([self._lang_dict['Long'], self._lang_dict['Short']])
        self.order_flag = QtWidgets.QComboBox()
        self.order_flag.addItems([self._lang_dict['Open'], self._lang_dict['Close'], self._lang_dict['Close_Yesterday'], self._lang_dict['Close_Today']])
        self.order_price = QtWidgets.QLineEdit()
        self.order_quantity = QtWidgets.QLineEdit()
        self.order_type = QtWidgets.QComboBox()
        self.order_type.addItems([self._lang_dict['MKT'], self._lang_dict['LMT'], self._lang_dict['FAK'], self._lang_dict['FOK']])
        self.exchange = QtWidgets.QComboBox()
        self.exchange.addItems(['CFFEX','SHFE', 'DCE', 'HKFE','GLOBEX','SMART'])
        self.account = QtWidgets.QComboBox()
        self.account.addItems(['FROM', 'CONFIG'])
        self.btn_order = QtWidgets.QPushButton(self._lang_dict['Place_Order'])
        self.btn_order.clicked.connect(self.place_order)

        place_order_layout.addRow(QtWidgets.QLabel(self._lang_dict['Discretionary']))
        place_order_layout.addRow(self._lang_dict['Symbol'], self.sym)
        place_order_layout.addRow(self._lang_dict['Name'], self.sym_name)
        place_order_layout.addRow(self._lang_dict['Security_Type'], self.sec_type)
        place_order_layout.addRow(self._lang_dict['Direction'], self.direction)
        place_order_layout.addRow(self._lang_dict['Order_Flag'], self.order_flag)
        place_order_layout.addRow(self._lang_dict['Price'], self.order_price)
        place_order_layout.addRow(self._lang_dict['Quantity'], self.order_quantity)
        place_order_layout.addRow(self._lang_dict['Order_Type'], self.order_type)
        place_order_layout.addRow(self._lang_dict['Exchange'], self.exchange)
        place_order_layout.addRow(self._lang_dict['Account'], self.account)
        place_order_layout.addRow(self.btn_order)
        topright.setLayout(place_order_layout)

        # -------------------------------- bottom Left ------------------------------------------#
        bottomleft = QtWidgets.QTabWidget()
        bottomleft.setFont(self._font)
        tab1 = QtWidgets.QWidget()
        tab2 = QtWidgets.QWidget()
        tab3 = QtWidgets.QWidget()
        tab4 = QtWidgets.QWidget()
        tab5 = QtWidgets.QWidget()
        bottomleft.addTab(tab1, self._lang_dict['Log'])
        bottomleft.addTab(tab2, self._lang_dict['Order'])
        bottomleft.addTab(tab3, self._lang_dict['Fill'])
        bottomleft.addTab(tab4, self._lang_dict['Position'])
        bottomleft.addTab(tab5, self._lang_dict['Account'])

        self.log_window = LogWindow(self._lang_dict)
        tab1_layout = QtWidgets.QVBoxLayout()
        tab1_layout.addWidget(self.log_window)
        tab1.setLayout(tab1_layout)

        self.order_window = OrderWindow(self._order_manager,self._outgoing_queue, self._lang_dict)       # cancel_order outgoing nessage
        tab2_layout = QtWidgets.QVBoxLayout()
        tab2_layout.addWidget(self.order_window)
        tab2.setLayout(tab2_layout)

        self.fill_window =FillWindow(self._order_manager, self._lang_dict)
        tab3_layout = QtWidgets.QVBoxLayout()
        tab3_layout.addWidget(self.fill_window)
        tab3.setLayout(tab3_layout)

        self.position_window = PositionWindow(self._lang_dict)
        tab4_layout = QtWidgets.QVBoxLayout()
        tab4_layout.addWidget(self.position_window)
        tab4.setLayout(tab4_layout)

        self.account_window = AccountWindow(self.account_manager, self._lang_dict)
        tab5_layout = QtWidgets.QVBoxLayout()
        tab5_layout.addWidget(self.account_window)
        tab5.setLayout(tab5_layout)

        # -------------------------------- bottom right ------------------------------------------#
        bottomright = QtWidgets.QFrame()
        bottomright.setFrameShape(QtWidgets.QFrame.StyledPanel)
        bottomright.setFont(self._font)
        strategy_manager_layout = QtWidgets.QFormLayout()
        self.strategy_window = StrategyWindow(self._lang_dict, self._strategy_manager)
        self.btn_strat_start = QtWidgets.QPushButton(self._lang_dict['Start_Strat'])
        self.btn_strat_start.clicked.connect(self.start_strategy)
        self.btn_strat_pause = QtWidgets.QPushButton(self._lang_dict['Pause_Strat'])
        self.btn_strat_pause.clicked.connect(self.pause_strategy)
        self.btn_strat_stop = QtWidgets.QPushButton(self._lang_dict['Stop_Strat'])
        self.btn_strat_stop.clicked.connect(self.stop_strategy)
        self.btn_strat_liquidate = QtWidgets.QPushButton(self._lang_dict['Liquidate_Strat'])
        btn_strat_layout = QtWidgets.QHBoxLayout()
        btn_strat_layout.addWidget(self.btn_strat_start)
        btn_strat_layout.addWidget(self.btn_strat_pause)
        btn_strat_layout.addWidget(self.btn_strat_stop)
        btn_strat_layout.addWidget(self.btn_strat_liquidate)

        strategy_manager_layout.addRow(QtWidgets.QLabel(self._lang_dict['Automatic']))
        strategy_manager_layout.addRow(self.strategy_window)
        strategy_manager_layout.addRow(btn_strat_layout)
        bottomright.setLayout(strategy_manager_layout)

        # --------------------------------------------------------------------------------------#
        splitter1 = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
        splitter1.addWidget(topleft)
        splitter1.addWidget(topright)
        splitter1.setSizes([400,100])

        splitter2 = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
        splitter2.addWidget(bottomleft)
        splitter2.addWidget(bottomright)
        splitter2.setSizes([400, 100])

        splitter3 = QtWidgets.QSplitter(QtCore.Qt.Vertical)
        splitter3.addWidget(splitter1)
        splitter3.addWidget(splitter2)
        splitter3.setSizes([400, 100])

        hbox.addWidget(splitter3)
        self.central_widget.setLayout(hbox)
        self.setCentralWidget(self.central_widget)
    def __init__(self, config_server, config_client, lang_dict):
        super(MainWindow, self).__init__()

        ## member variables
        self._current_time = None
        self._config_server = config_server
        self._config_client = config_client
        self._symbols =  config_server[config_server['accounts'][0]]['tickers']
        self._lang_dict = lang_dict
        self._font = lang_dict['font']
        self._widget_dict = {}
        self.central_widget = None
        self.market_window = None
        self.message_window = None
        self.order_window = None
        self.fill_window = None
        self.position_window = None
        self.account_window = None
        self.strategy_window = None

        #  0. order_manager; some of ui_windows uses order_manager
        self._order_manager = OrderManager()

        ## 1. event engine
        self._outgoing_queue = Queue()                    # outgoing queue from client side
        self._ui_events_engine = LiveEventEngine()        # update ui
        self._outgoing_request_events_engine = LiveEventEngine()          # events/actions request from client
        self._schedule_timer = QtCore.QTimer()                  # task scheduler; TODO produce result_packet

        # 3. data board
        self._data_board = DataBoard()

        # 5. risk manager and compliance manager
        self.risk_manager = PassThroughRiskManager()

        # 6. account manager
        self.account_manager = AccountManager(self._config_server)

        # 7 portfolio manager and position manager
        self.portfolio_manager = PortfolioManager(self._config_client['initial_cash'])

        ## 4. strategy_manager
        self._strategy_manager = StrategyManager(self._config_client, self._outgoing_request_events_engine,self._order_manager,self.portfolio_manager, self._data_board)
        self._strategy_manager.load_strategy()

        ## 8. client mq
        self._client_mq = ClientMq(self._ui_events_engine, self._outgoing_queue)

        # 1. set up gui windows
        self.setGeometry(50, 50, 600, 400)
        self.setWindowTitle(lang_dict['Prog_Name'])
        self.setWindowIcon(QtGui.QIcon("gui/image/logo.ico"))
        self.init_menu()
        self.init_status_bar()
        self.init_central_area()

        ## 9. wire up event handlers
        self._ui_events_engine.register_handler(EventType.TICK, self._tick_event_handler)
        self._ui_events_engine.register_handler(EventType.ORDERSTATUS, self.order_window.order_status_signal.emit)
        self._ui_events_engine.register_handler(EventType.FILL, self._fill_event_handler)
        self._ui_events_engine.register_handler(EventType.POSITION, self._position_event_handler)
        self._ui_events_engine.register_handler(EventType.ACCOUNT, self.account_window.account_signal.emit)
        self._ui_events_engine.register_handler(EventType.CONTRACT, self._contract_event_handler)
        self._ui_events_engine.register_handler(EventType.HISTORICAL, self._historical_event_handler)
        self._ui_events_engine.register_handler(EventType.GENERAL, self.log_window.msg_signal.emit)

        self._outgoing_request_events_engine.register_handler(EventType.ORDER, self._outgoing_order_request_handler)
        self._outgoing_request_events_engine.register_handler(EventType.ACCOUNT, self._outgoing_account_request_handler)
        self._outgoing_request_events_engine.register_handler(EventType.POSITION, self._outgoing_position_request_handler)
        self._outgoing_request_events_engine.register_handler(EventType.GENERAL, self._outgoing_general_msg_request_handler)

        ## 10. start
        self._ui_events_engine.start()
        self._outgoing_request_events_engine.start()
        self._client_mq.start()
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, config_server, config_client, lang_dict):
        super(MainWindow, self).__init__()

        ## member variables
        self._current_time = None
        self._config_server = config_server
        self._config_client = config_client
        self._symbols =  config_server[config_server['accounts'][0]]['tickers']
        self._lang_dict = lang_dict
        self._font = lang_dict['font']
        self._widget_dict = {}
        self.central_widget = None
        self.market_window = None
        self.message_window = None
        self.order_window = None
        self.fill_window = None
        self.position_window = None
        self.account_window = None
        self.strategy_window = None

        #  0. order_manager; some of ui_windows uses order_manager
        self._order_manager = OrderManager()

        ## 1. event engine
        self._outgoing_queue = Queue()                    # outgoing queue from client side
        self._ui_events_engine = LiveEventEngine()        # update ui
        self._outgoing_request_events_engine = LiveEventEngine()          # events/actions request from client
        self._schedule_timer = QtCore.QTimer()                  # task scheduler; TODO produce result_packet

        # 3. data board
        self._data_board = DataBoard()

        # 5. risk manager and compliance manager
        self.risk_manager = PassThroughRiskManager()

        # 6. account manager
        self.account_manager = AccountManager(self._config_server)

        # 7 portfolio manager and position manager
        self.portfolio_manager = PortfolioManager(self._config_client['initial_cash'])

        ## 4. strategy_manager
        self._strategy_manager = StrategyManager(self._config_client, self._outgoing_request_events_engine,self._order_manager,self.portfolio_manager, self._data_board)
        self._strategy_manager.load_strategy()

        ## 8. client mq
        self._client_mq = ClientMq(self._ui_events_engine, self._outgoing_queue)

        # 1. set up gui windows
        self.setGeometry(50, 50, 600, 400)
        self.setWindowTitle(lang_dict['Prog_Name'])
        self.setWindowIcon(QtGui.QIcon("gui/image/logo.ico"))
        self.init_menu()
        self.init_status_bar()
        self.init_central_area()

        ## 9. wire up event handlers
        self._ui_events_engine.register_handler(EventType.TICK, self._tick_event_handler)
        self._ui_events_engine.register_handler(EventType.ORDERSTATUS, self.order_window.order_status_signal.emit)
        self._ui_events_engine.register_handler(EventType.FILL, self._fill_event_handler)
        self._ui_events_engine.register_handler(EventType.POSITION, self._position_event_handler)
        self._ui_events_engine.register_handler(EventType.ACCOUNT, self.account_window.account_signal.emit)
        self._ui_events_engine.register_handler(EventType.CONTRACT, self._contract_event_handler)
        self._ui_events_engine.register_handler(EventType.HISTORICAL, self._historical_event_handler)
        self._ui_events_engine.register_handler(EventType.GENERAL, self.log_window.msg_signal.emit)

        self._outgoing_request_events_engine.register_handler(EventType.ORDER, self._outgoing_order_request_handler)
        self._outgoing_request_events_engine.register_handler(EventType.ACCOUNT, self._outgoing_account_request_handler)
        self._outgoing_request_events_engine.register_handler(EventType.POSITION, self._outgoing_position_request_handler)
        self._outgoing_request_events_engine.register_handler(EventType.GENERAL, self._outgoing_general_msg_request_handler)

        ## 10. start
        self._ui_events_engine.start()
        self._outgoing_request_events_engine.start()
        self._client_mq.start()

    #################################################################################################
    # -------------------------------- Event Handler   --------------------------------------------#
    #################################################################################################
    def update_status_bar(self, message):
        self.statusBar().showMessage(message)

    def open_proj_folder(self):
        webbrowser.open('/home/office/Documents/EliteQuant_Python.git/')

    def place_order(self):
        s = str(self.sym.text())
        n = self.direction.currentIndex()
        f = self.order_flag.currentIndex()
        p = str(self.order_price.text())
        q = str(self.order_quantity.text())
        t = self.order_type.currentIndex()

        # to be checked by risk manger
        try:
            o = OrderEvent()
            o.full_symbol = s
            o.order_size = int(q) if (n == 0) else -1 * int(q)
            o.order_flag = OrderFlag(f)
            o.create_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')

            if (t == 0):
                o.order_type = OrderType.MARKET
                self._outgoing_request_events_engine.put(o)
            elif (t == 1):
                o.order_type = OrderType.LIMIT
                o.limit_price = float(p)
                self._outgoing_request_events_engine.put(o)
            else:
                pass
        except:
            print('place order error')

    def start_strategy(self):
        self.strategy_window.update_status(self.strategy_window.currentRow(), True)

    def pause_strategy(self):
        pass

    def stop_strategy(self):
        self.strategy_window.update_status(self.strategy_window.currentRow(), False)

    def closeEvent(self, a0: QtGui.QCloseEvent):
        print('closing main window')
        self._ui_events_engine.stop()
        self._outgoing_request_events_engine.stop()
        self._client_mq.stop()

    def _tick_event_handler(self, tick_event):
        self._current_time = tick_event.timestamp

        self._data_board.on_tick(tick_event)       # update databoard
        self._order_manager.on_tick(tick_event)     # check standing stop orders
        self._strategy_manager.on_tick(tick_event)  # feed strategies
        self.market_window.tick_signal.emit(tick_event)         # display

    def _order_status_event_handler(self, order_status_event):  # including cancel
        # this is moved to ui_thread for consistency
        pass

    def _fill_event_handler(self, fill_event):
        # update portfolio manager for pnl
        self._order_manager.on_fill(fill_event)  # update order manager with fill
        self._strategy_manager.on_fill(fill_event)  # feed fill to strategy
        self.fill_window.fill_signal.emit(fill_event)     # display
        self.order_window.update_order_status(fill_event.client_order_id,
                                              self._order_manager.retrieve_order(fill_event.client_order_id).order_status)

    def _position_event_handler(self, position_event):
        self.portfolio_manager.on_position(position_event)       # position received
        self.position_window.position_signal.emit(position_event)     # display

    def _account_event_handler(self, account_event):
        pass

    def _contract_event_handler(self, contract_event):
        self.portfolio_manager.on_contract(contract_event)

    def _historical_event_handler(self, historical_event):
        print(historical_event)

    def _general_event_handler(self, general_event):
        pass

    def _outgoing_order_request_handler(self, o):
        """
         process o, check against risk manager and compliance manager
        """
        self.risk_manager.order_in_compliance(o)  # order pointer; modify order directly
        self._order_manager.on_order(o)

        msg = o.serialize()
        print('send msg: ' + msg)
        self._outgoing_queue.put(msg)

    def _outgoing_account_request_handler(self, a):
        msg = a.serialize()
        print('send msg: ' + msg)
        self._outgoing_queue.put(msg)

    def _outgoing_position_request_handler(self, p):
        msg = p.serialize()
        print('send msg: ' + msg)
        self._outgoing_queue.put(msg)

    def _outgoing_general_msg_request_handler(self, g):
        self.log_window.update_table(g)           # append to log window
    #################################################################################################
    # ------------------------------ Event Handler Ends --------------------------------------------#
    #################################################################################################

    #################################################################################################
    # -------------------------------- User Interface  --------------------------------------------#
    #################################################################################################
    def set_font(self, font):
        self._font = font

    def init_menu(self):
        menubar = self.menuBar()

        sysMenu = menubar.addMenu(self._lang_dict['File'])
        # open folder
        sys_folderAction = QtWidgets.QAction(self._lang_dict['Folder'], self)
        sys_folderAction.setStatusTip(self._lang_dict['Open_Folder'])
        sys_folderAction.triggered.connect(self.open_proj_folder)
        sysMenu.addAction(sys_folderAction)

        sysMenu.addSeparator()

        # sys|exit
        sys_exitAction = QtWidgets.QAction(self._lang_dict['Exit'], self)
        sys_exitAction.setShortcut('Ctrl+Q')
        sys_exitAction.setStatusTip(self._lang_dict['Exit_App'])
        sys_exitAction.triggered.connect(self.close)
        sysMenu.addAction(sys_exitAction)

    def init_status_bar(self):
        self.statusthread = StatusThread()
        self.statusthread.status_update.connect(self.update_status_bar)
        self.statusthread.start()

    def init_central_area(self):
        self.central_widget = QtWidgets.QWidget()

        hbox = QtWidgets.QHBoxLayout()

        #-------------------------------- Top Left ------------------------------------------#
        topleft = MarketWindow(self._symbols, self._lang_dict)
        self.market_window = topleft

        # -------------------------------- Top right ------------------------------------------#
        topright = QtWidgets.QFrame()
        topright.setFrameShape(QtWidgets.QFrame.StyledPanel)
        topright.setFont(self._font)
        place_order_layout = QtWidgets.QFormLayout()
        self.sym = QtWidgets.QLineEdit()
        self.sym_name = QtWidgets.QLineEdit()
        self.sec_type = QtWidgets.QComboBox()
        self.sec_type.addItems([self._lang_dict['Stock'], self._lang_dict['Future'], self._lang_dict['Option'], self._lang_dict['Forex']])
        self.direction = QtWidgets.QComboBox()
        self.direction.addItems([self._lang_dict['Long'], self._lang_dict['Short']])
        self.order_flag = QtWidgets.QComboBox()
        self.order_flag.addItems([self._lang_dict['Open'], self._lang_dict['Close'], self._lang_dict['Close_Yesterday'], self._lang_dict['Close_Today']])
        self.order_price = QtWidgets.QLineEdit()
        self.order_quantity = QtWidgets.QLineEdit()
        self.order_type = QtWidgets.QComboBox()
        self.order_type.addItems([self._lang_dict['MKT'], self._lang_dict['LMT'], self._lang_dict['FAK'], self._lang_dict['FOK']])
        self.exchange = QtWidgets.QComboBox()
        self.exchange.addItems(['CFFEX','SHFE', 'DCE', 'HKFE','GLOBEX','SMART'])
        self.account = QtWidgets.QComboBox()
        self.account.addItems(['FROM', 'CONFIG'])
        self.btn_order = QtWidgets.QPushButton(self._lang_dict['Place_Order'])
        self.btn_order.clicked.connect(self.place_order)

        place_order_layout.addRow(QtWidgets.QLabel(self._lang_dict['Discretionary']))
        place_order_layout.addRow(self._lang_dict['Symbol'], self.sym)
        place_order_layout.addRow(self._lang_dict['Name'], self.sym_name)
        place_order_layout.addRow(self._lang_dict['Security_Type'], self.sec_type)
        place_order_layout.addRow(self._lang_dict['Direction'], self.direction)
        place_order_layout.addRow(self._lang_dict['Order_Flag'], self.order_flag)
        place_order_layout.addRow(self._lang_dict['Price'], self.order_price)
        place_order_layout.addRow(self._lang_dict['Quantity'], self.order_quantity)
        place_order_layout.addRow(self._lang_dict['Order_Type'], self.order_type)
        place_order_layout.addRow(self._lang_dict['Exchange'], self.exchange)
        place_order_layout.addRow(self._lang_dict['Account'], self.account)
        place_order_layout.addRow(self.btn_order)
        topright.setLayout(place_order_layout)

        # -------------------------------- bottom Left ------------------------------------------#
        bottomleft = QtWidgets.QTabWidget()
        bottomleft.setFont(self._font)
        tab1 = QtWidgets.QWidget()
        tab2 = QtWidgets.QWidget()
        tab3 = QtWidgets.QWidget()
        tab4 = QtWidgets.QWidget()
        tab5 = QtWidgets.QWidget()
        bottomleft.addTab(tab1, self._lang_dict['Log'])
        bottomleft.addTab(tab2, self._lang_dict['Order'])
        bottomleft.addTab(tab3, self._lang_dict['Fill'])
        bottomleft.addTab(tab4, self._lang_dict['Position'])
        bottomleft.addTab(tab5, self._lang_dict['Account'])

        self.log_window = LogWindow(self._lang_dict)
        tab1_layout = QtWidgets.QVBoxLayout()
        tab1_layout.addWidget(self.log_window)
        tab1.setLayout(tab1_layout)

        self.order_window = OrderWindow(self._order_manager,self._outgoing_queue, self._lang_dict)       # cancel_order outgoing nessage
        tab2_layout = QtWidgets.QVBoxLayout()
        tab2_layout.addWidget(self.order_window)
        tab2.setLayout(tab2_layout)

        self.fill_window =FillWindow(self._order_manager, self._lang_dict)
        tab3_layout = QtWidgets.QVBoxLayout()
        tab3_layout.addWidget(self.fill_window)
        tab3.setLayout(tab3_layout)

        self.position_window = PositionWindow(self._lang_dict)
        tab4_layout = QtWidgets.QVBoxLayout()
        tab4_layout.addWidget(self.position_window)
        tab4.setLayout(tab4_layout)

        self.account_window = AccountWindow(self.account_manager, self._lang_dict)
        tab5_layout = QtWidgets.QVBoxLayout()
        tab5_layout.addWidget(self.account_window)
        tab5.setLayout(tab5_layout)

        # -------------------------------- bottom right ------------------------------------------#
        bottomright = QtWidgets.QFrame()
        bottomright.setFrameShape(QtWidgets.QFrame.StyledPanel)
        bottomright.setFont(self._font)
        strategy_manager_layout = QtWidgets.QFormLayout()
        self.strategy_window = StrategyWindow(self._lang_dict, self._strategy_manager)
        self.btn_strat_start = QtWidgets.QPushButton(self._lang_dict['Start_Strat'])
        self.btn_strat_start.clicked.connect(self.start_strategy)
        self.btn_strat_pause = QtWidgets.QPushButton(self._lang_dict['Pause_Strat'])
        self.btn_strat_pause.clicked.connect(self.pause_strategy)
        self.btn_strat_stop = QtWidgets.QPushButton(self._lang_dict['Stop_Strat'])
        self.btn_strat_stop.clicked.connect(self.stop_strategy)
        self.btn_strat_liquidate = QtWidgets.QPushButton(self._lang_dict['Liquidate_Strat'])
        btn_strat_layout = QtWidgets.QHBoxLayout()
        btn_strat_layout.addWidget(self.btn_strat_start)
        btn_strat_layout.addWidget(self.btn_strat_pause)
        btn_strat_layout.addWidget(self.btn_strat_stop)
        btn_strat_layout.addWidget(self.btn_strat_liquidate)

        strategy_manager_layout.addRow(QtWidgets.QLabel(self._lang_dict['Automatic']))
        strategy_manager_layout.addRow(self.strategy_window)
        strategy_manager_layout.addRow(btn_strat_layout)
        bottomright.setLayout(strategy_manager_layout)

        # --------------------------------------------------------------------------------------#
        splitter1 = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
        splitter1.addWidget(topleft)
        splitter1.addWidget(topright)
        splitter1.setSizes([400,100])

        splitter2 = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
        splitter2.addWidget(bottomleft)
        splitter2.addWidget(bottomright)
        splitter2.setSizes([400, 100])

        splitter3 = QtWidgets.QSplitter(QtCore.Qt.Vertical)
        splitter3.addWidget(splitter1)
        splitter3.addWidget(splitter2)
        splitter3.setSizes([400, 100])

        hbox.addWidget(splitter3)
        self.central_widget.setLayout(hbox)
        self.setCentralWidget(self.central_widget)
Esempio n. 11
0
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, config_server, config_client, lang_dict):
        super(MainWindow, self).__init__()

        ## member variables
        self._current_time = None
        self._config_server = config_server
        self._config_client = config_client
        self._symbols = config_server['tickers']
        self._lang_dict = lang_dict
        self._font = lang_dict['font']
        self._widget_dict = {}
        self.central_widget = None
        # self.central_widget = QtWidgets.QStackedWidget()
        self.market_window = None
        self.message_window = None
        self.order_window = None
        self.fill_window = None
        self.position_window = None
        self.closeposition_window = None
        self.account_window = None
        self.strategy_window = None
        self.manualorderid = 0

        #  0. order_manager; some of ui_windows uses order_manager
        self._order_manager = OrderManager()

        ## 1. event engine
        self._outgoing_queue = Queue()  # outgoing queue from client side
        self._ui_events_engine = LiveEventEngine()  # update ui
        self._outgoing_request_events_engine = LiveEventEngine(
        )  # events/actions request from client
        self._flowrate_timer = QtCore.QTimer(
        )  #  TODO add task scheduler;produce result_packet

        # 3. data board
        self._data_board = DataBoard()

        # 5. risk manager and compliance manager
        self.risk_manager = PassThroughRiskManager()

        # 6. account manager
        self.account_manager = AccountManager(self._config_server)

        # 7 portfolio manager and position manager
        self.portfolio_manager = PortfolioManager(
            self._config_client['initial_cash'], self._symbols[:])

        ## 4. strategy_manager
        self._strategy_manager = StrategyManager(
            self._config_client, self._outgoing_request_events_engine,
            self._order_manager, self.portfolio_manager)
        self._strategy_manager.load_strategy()

        ## 8. client mq
        self._client_mq = ClientMq(self._config_server, self._ui_events_engine,
                                   self._outgoing_queue)

        # 1. set up gui windows
        self.setGeometry(50, 50, 850, 650)
        self.setWindowTitle(lang_dict['Prog_Name'])
        self.setWindowIcon(QtGui.QIcon("source/gui/image/star.png"))
        self.init_menu()
        self.init_status_bar()
        self.init_central_area()

        ## 9. wire up event handlers
        self._ui_events_engine.register_handler(EventType.TICK,
                                                self._tick_event_handler)
        self._ui_events_engine.register_handler(
            EventType.ORDERSTATUS, self.order_window.order_status_signal.emit)
        self._ui_events_engine.register_handler(EventType.FILL,
                                                self._fill_event_handler)
        self._ui_events_engine.register_handler(EventType.POSITION,
                                                self._position_event_handler)
        self._ui_events_engine.register_handler(EventType.ACCOUNT,
                                                self._account_event_handler)
        self._ui_events_engine.register_handler(EventType.CONTRACT,
                                                self._contract_event_handler)
        self._ui_events_engine.register_handler(EventType.HISTORICAL,
                                                self._historical_event_handler)
        self._ui_events_engine.register_handler(EventType.INFO,
                                                self._info_event_handler)
        # TODO:add info and error handler

        self._outgoing_request_events_engine.register_handler(
            EventType.ORDER, self._outgoing_order_request_handler)
        self._outgoing_request_events_engine.register_handler(
            EventType.QRY_ACCOUNT, self._outgoing_account_request_handler)
        self._outgoing_request_events_engine.register_handler(
            EventType.QRY_POS, self._outgoing_position_request_handler)
        self._outgoing_request_events_engine.register_handler(
            EventType.QRY_CONTRACT, self._outgoing_contract_request_handler)
        self._outgoing_request_events_engine.register_handler(
            EventType.SUBSCRIBE, self._outgoing_general_request_handler)
        self._outgoing_request_events_engine.register_handler(
            EventType.GENERAL_REQ, self._outgoing_general_request_handler)
        self._flowrate_timer.timeout.connect(
            self.risk_manager.reset
        )  #timer event to reset riskmanager flow rate count
        ## 10. start
        self._ui_events_engine.start()
        self._outgoing_request_events_engine.start()
        self._client_mq.start()
        self._flowrate_timer.start(5000)

    #################################################################################################
    # -------------------------------- Event Handler   --------------------------------------------#
    #################################################################################################
    def update_status_bar(self, message):
        self.statusBar().showMessage(message)

    def open_proj_folder(self):
        webbrowser.open('.')

    def reload_strategy(self):
        self._strategy_manager.reload_strategy()
        self.strategy_window.reload_table()

    def start_strategy(self):
        self.strategy_window.update_status(self.strategy_window.currentRow(),
                                           True)

    def stop_strategy(self):
        self.strategy_window.update_status(self.strategy_window.currentRow(),
                                           False)

    def closeEvent(self, a0: QtGui.QCloseEvent):
        print('closing main window')
        self._ui_events_engine.stop()
        self._outgoing_request_events_engine.stop()
        self._client_mq.stop()

    def _tick_event_handler(self, tick_event):
        self.dataviewindow.tick_signal.emit(tick_event)
        self._current_time = tick_event.timestamp
        self._data_board.on_tick(tick_event)  # update databoard
        self._order_manager.on_tick(tick_event)  # check standing stop orders
        # print('tick arrive timestamp:',datetime.now())                       # test latency
        self._strategy_manager.on_tick(tick_event)  # feed strategies
        self.market_window.tick_signal.emit(tick_event)  # display

    def _order_status_event_handler(self,
                                    order_status_event):  # including cancel
        # this is moved to ui_thread for consistency
        pass

    def _fill_event_handler(self, fill_event):
        self.portfolio_manager.on_fill_live(fill_event)
        # update portfolio manager for pnl
        self._order_manager.on_fill(
            fill_event)  # update order manager with fill
        #print('fill orderman')
        self._strategy_manager.on_fill(fill_event)  # feed fill to strategy
        #print('fill str')
        self.fill_window.fill_signal.emit(fill_event)  # display
        #print('begin update',fill_event.client_order_id,self._order_manager.retrieve_order(fill_event.client_order_id).order_status)
        #self.order_window.update_order_status(fill_event.client_order_id,OrderStatus.FILLED )
        #print('fill update')
        #利用fill事件重新更新pos开仓来源,因为有时候回调函数先返回的是pos,然后是fill信息
        self._strategy_manager.update_position()
        self.strategy_window.fill_signal.emit(fill_event)

    def _position_event_handler(self, position_event):
        self.portfolio_manager.on_position_live(
            position_event)  # position received
        # print("pm on n")
        self.position_window.position_signal.emit(position_event)  # display
        # print("pw on n")
        self.closeposition_window.position_signal.emit(position_event)
        # print("cpw on n")
        self._strategy_manager.update_position()
        self._strategy_manager.on_position(position_event)
        #print("sm on n")
        self.strategy_window.position_signal.emit(position_event)
        #print("sw on n")

    def _account_event_handler(self, account_event):
        self.portfolio_manager.on_account(account_event)  # fund info add
        self.account_window.account_signal.emit(account_event)
        pass

    def _contract_event_handler(self, contract_event):
        self.portfolio_manager.on_contract(contract_event)
        msg = "Contract {} tickprice = {} multiples = {}".format(
            contract_event.full_symbol, contract_event.mininum_tick,
            contract_event.multiples)
        self.manual_widget.logoutput.append(msg)

    def _historical_event_handler(self, historical_event):
        pass
        # print(historical_event)

    def _info_event_handler(self, info_event):
        if (info_event.msg_type == MSG_TYPE.MSG_TYPE_INFO_ENGINE_STATUS):
            self.manual_widget.updateapistatusdict(info_event)
        else:
            self.log_window.msg_signal.emit(info_event)

    def _general_event_handler(self, general_event):
        pass


#----------------------------------------outgoing event ------------------------------------

    def _outgoing_order_request_handler(self, o):
        """
         process o, check against risk manager and compliance manager
        """
        self.risk_manager.order_in_compliance(
            o)  # order pointer; modify order directly
        if (self.risk_manager.passorder()):
            self._order_manager.on_order(o)
            #self.order_window.
            msg = o.serialize()
            print('client send msg: ' + msg, datetime.now())
            # print('client send msg: ' + msg)
            # text = o.destination + o.source + str(o.clientID)
            # requests.get('https://sc.ftqq.com/SCU49995T54cd0bf4d42dd8448359347830d62bd85cc3f69d085ee.send?text=%s &desp=%s'%(text,msg))
            self._outgoing_queue.put(msg)

    def _outgoing_account_request_handler(self, a):
        if (self.risk_manager.passquery()):
            msg = a.serialize()
            print('client send msg: ' + msg)
            self._outgoing_queue.put(msg)

    def _outgoing_position_request_handler(self, p):
        if (self.risk_manager.passquery()):
            msg = p.serialize()
            print('client send msg: ' + msg)
            self._outgoing_queue.put(msg)

    def _outgoing_contract_request_handler(self, c):
        if (self.risk_manager.passquery()):
            msg = c.serialize()
            print('client send msg: ' + msg)
            self._outgoing_queue.put(msg)

    def _outgoing_general_request_handler(self, gr):
        msg = gr.serialize()
        print('client send msg: ' + msg)
        self._outgoing_queue.put(msg)

    def _outgoing_general_msg_request_handler(self, g):
        self.log_window.update_table(g)  # append to log window

    #################################################################################################
    # ------------------------------ Event Handler Ends --------------------------------------------#
    #################################################################################################

    #################################################################################################
    # -------------------------------- User Interface  --------------------------------------------#
    #################################################################################################
    def set_font(self, font):
        self._font = font

    def displaytrade(self):
        self.central_widget.setCurrentIndex(0)

    def displaybacktest(self):
        self.central_widget.setCurrentIndex(1)

    def init_menu(self):
        menubar = self.menuBar()
        #sys menu --filebrowser
        sysMenu = menubar.addMenu(self._lang_dict['File'])
        sys_folderAction = QtWidgets.QAction(self._lang_dict['Folder'], self)
        sys_folderAction.setStatusTip(self._lang_dict['Open_Folder'])
        sys_folderAction.triggered.connect(self.open_proj_folder)
        sysMenu.addAction(sys_folderAction)
        # --exit
        sysMenu.addSeparator()
        sys_exitAction = QtWidgets.QAction(self._lang_dict['Exit'], self)
        sys_exitAction.setShortcut('Ctrl+Q')
        sys_exitAction.setStatusTip(self._lang_dict['Exit_App'])
        sys_exitAction.triggered.connect(self.close)
        sysMenu.addAction(sys_exitAction)
        #mode menu
        modeMenu = menubar.addMenu('Mode')
        mode_tradeAction = QtWidgets.QAction('Trade', self)
        mode_tradeAction.triggered.connect(self.displaytrade)
        modeMenu.addAction(mode_tradeAction)
        mode_backtestAction = QtWidgets.QAction('Backtest', self)
        mode_backtestAction.triggered.connect(self.displaybacktest)
        modeMenu.addAction(mode_backtestAction)

        #help menu
        helpMenu = menubar.addMenu('Help')
        help_webaction = QtWidgets.QAction('Web/Jupyter Notebook', self)
        help_webaction.triggered.connect(self.openweb)
        helpMenu.addAction(help_webaction)
        help_action = QtWidgets.QAction('About', self)
        help_action.triggered.connect(self.openabout)
        helpMenu.addAction(help_action)

    def openabout(self):
        try:
            self._widget_dict['about'].show()
        except KeyError:
            self._widget_dict['about'] = AboutWidget(self)
            self._widget_dict['about'].show()

    def openweb(self):
        try:
            self._widget_dict['web'].show()
        except KeyError:
            self._widget_dict['web'] = WebWindow()
            self._widget_dict['web'].show()

    def init_status_bar(self):
        self.statusthread = StatusThread()
        self.statusthread.status_update.connect(self.update_status_bar)
        self.statusthread.start()

    def init_central_area(self):
        self.central_widget = QtWidgets.QStackedWidget()

        #-------Trade Widgets----------
        tradewidget = QtWidgets.QWidget()
        hbox = QtWidgets.QHBoxLayout()
        #-------------------------------- Top Left ------------------------------------------#
        topleft = MarketWindow(self._symbols, self._lang_dict)
        self.market_window = topleft

        # -------------------------------- bottom Left ------------------------------------------#
        bottomleft = QtWidgets.QTabWidget()
        bottomleft.setFont(self._font)
        tab1 = QtWidgets.QWidget()
        tab2 = QtWidgets.QWidget()
        tab3 = QtWidgets.QWidget()
        tab4 = QtWidgets.QWidget()
        tab5 = QtWidgets.QWidget()
        tab6 = QtWidgets.QWidget()
        bottomleft.addTab(tab1, self._lang_dict['Log'])
        bottomleft.addTab(tab2, self._lang_dict['Order'])
        bottomleft.addTab(tab3, self._lang_dict['Fill'])
        bottomleft.addTab(tab4, self._lang_dict['Position'])
        bottomleft.addTab(tab5, self._lang_dict['ClosePosition'])
        bottomleft.addTab(tab6, self._lang_dict['Account'])

        self.log_window = LogWindow(self._lang_dict)
        tab1_layout = QtWidgets.QVBoxLayout()
        tab1_layout.addWidget(self.log_window)
        tab1.setLayout(tab1_layout)

        self.order_window = OrderWindow(
            self._order_manager, self._outgoing_queue,
            self._lang_dict)  # cancel_order outgoing nessage
        tab2_layout = QtWidgets.QVBoxLayout()
        tab2_layout.addWidget(self.order_window)
        tab2.setLayout(tab2_layout)

        self.fill_window = FillWindow(self._order_manager, self._lang_dict)
        tab3_layout = QtWidgets.QVBoxLayout()
        tab3_layout.addWidget(self.fill_window)
        tab3.setLayout(tab3_layout)

        self.position_window = PositionWindow(self._lang_dict)
        tab4_layout = QtWidgets.QVBoxLayout()
        tab4_layout.addWidget(self.position_window)
        tab4.setLayout(tab4_layout)

        self.closeposition_window = ClosePositionWindow(self._lang_dict)
        tab5_layout = QtWidgets.QVBoxLayout()
        tab5_layout.addWidget(self.closeposition_window)
        tab5.setLayout(tab5_layout)

        self.account_window = AccountWindow(self.account_manager,
                                            self._lang_dict)
        tab6_layout = QtWidgets.QVBoxLayout()
        tab6_layout.addWidget(self.account_window)
        tab6.setLayout(tab6_layout)

        # -------------------------------- bottom right ------------------------------------------#
        bottomright = QtWidgets.QFrame()
        bottomright.setFrameShape(QtWidgets.QFrame.StyledPanel)
        bottomright.setFont(self._font)
        strategy_manager_layout = QtWidgets.QFormLayout()
        self.strategy_window = StrategyWindow(self._lang_dict,
                                              self._strategy_manager)
        self.btn_strat_reload = QtWidgets.QPushButton(
            self._lang_dict['Load_Strat'])
        self.btn_strat_reload.clicked.connect(self.reload_strategy)
        self.btn_strat_start = QtWidgets.QPushButton(
            self._lang_dict['Start_Strat'])
        self.btn_strat_start.clicked.connect(self.start_strategy)
        self.btn_strat_stop = QtWidgets.QPushButton(
            self._lang_dict['Stop_Strat'])
        self.btn_strat_stop.clicked.connect(self.stop_strategy)
        self.btn_strat_liquidate = QtWidgets.QPushButton(
            self._lang_dict['Liquidate_Strat'])
        btn_strat_layout = QtWidgets.QHBoxLayout()
        btn_strat_layout.addWidget(self.btn_strat_start)
        btn_strat_layout.addWidget(self.btn_strat_stop)
        btn_strat_layout.addWidget(self.btn_strat_liquidate)
        btn_strat_layout.addWidget(self.btn_strat_reload)

        strategy_manager_layout.addRow(
            QtWidgets.QLabel(self._lang_dict['Automatic']))
        strategy_manager_layout.addRow(self.strategy_window)
        strategy_manager_layout.addRow(btn_strat_layout)
        bottomright.setLayout(strategy_manager_layout)

        # --------------------------------------------------------------------------------------#

        self.dataviewindow = MarketDataView()
        self.market_window.symbol_signal.connect(
            self.dataviewindow.symbol_signal.emit)

        splitter1 = QtWidgets.QSplitter(QtCore.Qt.Vertical)
        splitter1.addWidget(topleft)
        splitter1.addWidget(bottomleft)
        splitter1.setSizes([500, 500])

        splitter2 = QtWidgets.QSplitter(QtCore.Qt.Vertical)
        splitter2.addWidget(self.dataviewindow)
        splitter2.addWidget(bottomright)
        splitter2.setSizes([400, 400])

        splitter3 = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
        splitter3.addWidget(splitter1)
        splitter3.addWidget(splitter2)
        splitter3.setSizes([600, 600])

        hbox.addWidget(splitter3)
        tradewidget.setLayout(hbox)

        #---------Backtest ----------------------------------------
        backtestwidget = QtWidgets.QWidget()
        bt_hbox = QtWidgets.QHBoxLayout()
        # bt top middle---result
        bt_topmiddle = QtWidgets.QTabWidget()
        bt_resulttab1 = BtResultViewWidget()
        bt_resulttab2 = BtPosViewWidget()
        bt_resulttab3 = BtTxnViewWidget()
        bt_topmiddle.addTab(bt_resulttab1, 'OverView and Returns')
        bt_topmiddle.addTab(bt_resulttab2, 'Position')
        bt_topmiddle.addTab(bt_resulttab3, 'Transactions')
        #  bottom middle:  data
        bt_bottommiddle = QtWidgets.QTabWidget()
        bt_bottommiddle.setFont(self._font)
        bt_datatab1 = BtDataViewWidget()
        bt_datatab2 = BtDataPGChart()
        bt_bottommiddle.addTab(bt_datatab1, 'Data')
        bt_bottommiddle.addTab(bt_datatab2, 'PGData')

        #   bt  left: setting
        bt_left = BtSettingWindow()

        #--------------------------------

        bt_splitter1 = QtWidgets.QSplitter(QtCore.Qt.Vertical)
        bt_splitter1.addWidget(bt_topmiddle)
        bt_splitter1.addWidget(bt_bottommiddle)
        bt_splitter1.setSizes([400, 400])

        # bt_splitter2 = QtWidgets.QSplitter(QtCore.Qt.Vertical)
        # bt_splitter2.addWidget(bt_left)
        # bt_splitter2.addWidget(bt_right)
        # bt_splitter2.setSizes([1000, 600])

        bt_splitter3 = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
        bt_splitter3.addWidget(bt_left)
        bt_splitter3.addWidget(bt_splitter1)
        # bt_splitter3.addWidget(bt_right)
        bt_splitter3.setSizes([300, 1200])

        bt_hbox.addWidget(bt_splitter3)
        backtestwidget.setLayout(bt_hbox)

        #--------------------mainwindow----------------------
        manualwidget = ManualWindow(self._config_server['apis'],
                                    self._config_server['accounts'])
        manualwidget.order_signal.connect(self._outgoing_order_request_handler)
        manualwidget.qryacc_signal.connect(
            self._outgoing_account_request_handler)
        manualwidget.qrypos_signal.connect(
            self._outgoing_position_request_handler)
        manualwidget.qrycontract_signal.connect(
            self._outgoing_contract_request_handler)
        manualwidget.manual_req.connect(self._outgoing_queue.put)
        manualwidget.subscribe_signal.connect(
            self._outgoing_general_request_handler)
        self.manual_widget = manualwidget
        dockmanual = QtWidgets.QDockWidget('Manual Control Center', self)
        dockmanual.setFeatures(QtWidgets.QDockWidget.DockWidgetFloatable
                               | QtWidgets.QDockWidget.DockWidgetMovable)
        # dockmanual.setFloating(True)
        dockmanual.setAllowedAreas(QtCore.Qt.RightDockWidgetArea
                                   | QtCore.Qt.LeftDockWidgetArea)
        dockmanual.setWidget(manualwidget)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, dockmanual)

        # webwidget = WebWindow()
        # dockweb = QtWidgets.QDockWidget('Web Browser',self)
        # dockweb.setFeatures(QtWidgets.QDockWidget.DockWidgetFloatable|QtWidgets.QDockWidget.DockWidgetMovable)
        # # dockweb.setFloating(True)
        # dockweb.setAllowedAreas(QtCore.Qt.RightDockWidgetArea|QtCore.Qt.LeftDockWidgetArea)
        # dockweb.setWidget(webwidget)
        # self.addDockWidget(QtCore.Qt.RightDockWidgetArea,dockweb)
        # self.tabifyDockWidget(dockmanual,dockweb)
        # dockmanual.raise_()

        self.central_widget.addWidget(tradewidget)
        self.central_widget.addWidget(backtestwidget)
        self.central_widget.setCurrentIndex(0)
        self.setCentralWidget(self.central_widget)