Beispiel #1
0
    def __init__(self,
                 account_type,
                 config,
                 sandbox_debug=False,
                 logger_name=None,
                 open_time_adj=0,
                 close_time_adj=0):

        # get logger
        self.logger = Tiger.defualt_logger if (
            logger_name is None) else logging.getLogger(logger_name)

        # read user info, position record from local files
        self.__user_info = io_util.read_config(file_path=config['tiger_path'],
                                               file_name='user_info.json')
        self.__position_record = io_util.read_config(
            file_path=config['config_path'],
            file_name='tiger_position_record.json')
        self.record = self.__position_record[account_type].copy()
        self.eod_api_key = config['api_key']['eod']

        # set account, account type
        self.account = self.__user_info[account_type]
        self.account_type = account_type

        # initialize client_config
        self.client_config = TigerOpenClientConfig(sandbox_debug=sandbox_debug)
        self.client_config.private_key = read_private_key(
            config['tiger_path'] + self.__user_info['private_key_name'])
        self.client_config.tiger_id = str(self.__user_info['tiger_id'])
        self.client_config.language = Language.en_US
        self.client_config.account = self.account

        # get quote/trade clients, assets, positions
        self.quote_client = QuoteClient(self.client_config)
        self.trade_client = TradeClient(self.client_config)
        self.positions = self.trade_client.get_positions(account=self.account)
        self.assets = self.trade_client.get_assets(account=self.account)

        # get market status and trade time
        self.update_trade_time(open_time_adj=open_time_adj,
                               close_time_adj=close_time_adj)

        # update position record
        self.synchronize_position_record(config=config)

        self.logger.info(f'[tiger]: Tiger instance created: {logger_name}')
Beispiel #2
0
    def __init__(self,
                 account_type,
                 config,
                 market='US',
                 is_encrypt=False,
                 logger_name=None):

        # get logger
        self.logger = Futu.defualt_logger if (
            logger_name is None) else logging.getLogger(logger_name)

        # read user info, position record from local files
        self.__user_info = io_util.read_config(file_path=config['futu_path'],
                                               file_name='user_info.json')
        self.__position_record = io_util.read_config(
            file_path=config['config_path'],
            file_name='futu_position_record.json')
        self.record = self.__position_record[account_type].copy()
        self.eod_api_key = config['api_key']['eod']

        # set account type
        self.account_type = account_type

        # get quote and trade context, assets, positions
        self.open_quote_context(host=self.__user_info['host'],
                                port=self.__user_info['port'],
                                is_encrypt=is_encrypt)
        self.open_trade_context(market=market,
                                host=self.__user_info['host'],
                                port=self.__user_info['port'],
                                is_encrypt=is_encrypt)
        if self.trade_context is not None:
            self.trade_context.unlock_trade(self.__user_info['unlock_pwd'])
            ret_positions, self.positions = self.trade_context.position_list_query(
                trd_env=account_type)
            ret_assets, self.assets = self.trade_context.accinfo_query(
                trd_env=account_type)
        else:
            self.positions = None
            self.assets = None
            self.logger.error('trade_context not available')

        # update position record
        self.synchronize_position_record(config=config)

        self.logger.info(f'[futu]: Futu instance created: {logger_name}')
Beispiel #3
0
    def update_portfolio_record(self,
                                config,
                                position_summary=None,
                                is_print=True):

        # get position summary
        if position_summary is None:
            position_summary = self.get_position_summary(get_briefs=False)
        position_summary.set_index('symbol', inplace=True)
        position_summary = position_summary.round(2)

        # get assets summary
        net_value = 0
        market_value = 0
        cash = 0
        asset_summary = self.get_asset_summary()
        if len(asset_summary) > 0:
            net_value = asset_summary.loc[0, 'total_assets']
            market_value = asset_summary.loc[0, 'market_val']
            cash = asset_summary.loc[0, 'cash']

        # post process
        if market_value == float('inf'):
            market_value = position_summary['market_value'].sum().round(2)

        # load portfolio record
        portfolio_record = io_util.read_config(file_path=config['config_path'],
                                               file_name='portfolio.json')
        old_net_value = portfolio_record['futu'][self.account_type].get(
            'net_value')
        support = portfolio_record['futu'][self.account_type].get(
            'portfolio').get('support')
        resistant = portfolio_record['futu'][self.account_type].get(
            'portfolio').get('resistant')

        # update portfolio record for current account
        portfolio_record['futu'][
            self.account_type]['portfolio'] = position_summary.to_dict()
        portfolio_record['futu'][
            self.account_type]['portfolio']['support'] = {}
        portfolio_record['futu'][
            self.account_type]['portfolio']['resistant'] = {}

        quantity = portfolio_record['futu'][
            self.account_type]['portfolio'].get('quantity')
        if quantity is not None:
            if support is not None:
                for symbol in quantity.keys():
                    portfolio_record['futu'][self.account_type]['portfolio'][
                        'support'][symbol] = support.get(symbol)

            if resistant is not None:
                for symbol in quantity.keys():
                    portfolio_record['futu'][self.account_type]['portfolio'][
                        'resistant'][symbol] = resistant.get(symbol)

        portfolio_record['futu'][
            self.account_type]['market_value'] = market_value
        portfolio_record['futu'][self.account_type]['net_value'] = net_value
        portfolio_record['futu'][self.account_type]['cash'] = cash
        portfolio_record['futu'][self.account_type]['updated'] = datetime.now(
        ).strftime(format="%Y-%m-%d %H:%M:%S")
        io_util.create_config_file(config_dict=portfolio_record,
                                   file_path=config['config_path'],
                                   file_name='portfolio.json')

        # print change
        if is_print:
            self.logger.info(
                f'[{self.account_type[:4]}]: net value {old_net_value} --> {net_value}'
            )
Beispiel #4
0
    def update_position_record(self,
                               config,
                               init_cash=None,
                               init_position=None,
                               start_time=None,
                               end_time=None,
                               is_print=True):

        # set default values
        init_cash = config['trade']['init_cash'][self.account_type] if (
            init_cash is None) else init_cash
        init_position = 0 if (init_position is None) else init_position
        start_time = datetime.now().strftime(
            format="%Y-%m-%d") if (start_time is None) else start_time
        end_time = start_time if (end_time is None) else end_time

        try:

            # get today filled orders
            ret_orders, orders = self.trade_context.history_order_list_query(
                trd_env=self.account_type,
                status_filter_list=[
                    OrderStatus.FILLED_PART, OrderStatus.FILLED_ALL
                ],
                start=start_time,
                end=end_time)

            # update position records
            if ret_orders == 0:
                for index, row in orders.iterrows():
                    symbol = row['code'].split('.')[1]  # order.contract.symbol
                    action = row['trd_side']  # order.action
                    quantity = row[
                        'dealt_qty']  # order.quantity - order.remaining
                    commission = 3  # order.commission
                    avg_fill_price = row[
                        'dealt_avg_price']  # order.avg_fill_price

                    # init record if not exist
                    if symbol not in self.record.keys():
                        self.record[symbol] = {
                            'cash': init_cash,
                            'position': init_position
                        }
                    record_cash = self.record[symbol]['cash']
                    record_position = self.record[symbol]['position']

                    # calculate new cash and position
                    if action == 'BUY':
                        cost = avg_fill_price * quantity + commission
                        new_cash = record_cash - cost
                        new_position = record_position + quantity

                    elif action == 'SELL':
                        acquire = avg_fill_price * quantity - commission
                        new_cash = record_cash + acquire
                        new_position = record_position - quantity

                    else:
                        new_cash = self.record[symbol]['cash']
                        new_position = self.record[symbol]['position']

                    # update record
                    if new_cash >= 0 and new_position >= 0:
                        self.record[symbol]['cash'] = new_cash
                        self.record[symbol]['position'] = new_position
                        if is_print:
                            self.logger.info(
                                f'[{self.account_type[:4]}]: updating position record for {symbol} {record_cash, record_position} -> {new_cash, new_position}'
                            )

                # update __position_record
                # self.record['updated'] = datetime.now().strftime(format="%Y-%m-%d %H:%M:%S")
                self.__position_record = io_util.read_config(
                    file_path=config['config_path'],
                    file_name='futu_position_record.json')
                self.__position_record[self.account_type] = self.record.copy()
                self.__position_record['updated'][
                    self.account_type] = datetime.now().strftime(
                        format="%Y-%m-%d %H:%M:%S")
                io_util.create_config_file(
                    config_dict=self.__position_record,
                    file_path=config['config_path'],
                    file_name='futu_position_record.json')

            elif ret_orders == -1:
                self.logger.error(f'[erro]: fail getting orders - {orders}')

        except Exception as e:
            self.logger.exception(
                f'[erro]: fail updating position records for {self.account_type}, {e}'
            )
Beispiel #5
0
    def update_position_record(self,
                               config,
                               init_cash=None,
                               init_position=None,
                               start_time=None,
                               end_time=None,
                               is_print=True):

        # set default values
        init_cash = config['trade']['init_cash'][self.account_type] if (
            init_cash is None) else init_cash
        init_position = 0 if (init_position is None) else init_position
        start_time = self.trade_time['pre_open_time'].strftime(
            format="%Y-%m-%d %H:%M:%S") if (start_time is None) else start_time
        end_time = self.trade_time['post_close_time'].strftime(
            format="%Y-%m-%d %H:%M:%S") if (end_time is None) else end_time

        try:

            # get today filled orders
            orders = self.trade_client.get_filled_orders(start_time=start_time,
                                                         end_time=end_time)

            # update position records
            for order in orders:
                symbol = order.contract.symbol
                action = order.action
                quantity = order.quantity - order.remaining
                commission = order.commission
                avg_fill_price = order.avg_fill_price

                # init record if not exist
                if symbol not in self.record.keys():
                    self.record[symbol] = {
                        'cash': init_cash,
                        'position': init_position
                    }
                record_cash = self.record[symbol]['cash']
                record_position = self.record[symbol]['position']

                # calculate new cash and position
                if action == 'BUY':
                    cost = avg_fill_price * quantity + commission
                    new_cash = record_cash - cost
                    new_position = record_position + quantity

                elif action == 'SELL':
                    acquire = avg_fill_price * quantity - commission
                    new_cash = record_cash + acquire
                    new_position = record_position - quantity

                else:
                    new_cash = record_cash
                    new_position = record_position

                # update record
                if new_cash >= 0 and new_position >= 0:
                    self.record[symbol]['cash'] = new_cash
                    self.record[symbol]['position'] = new_position
                    if is_print:
                        self.logger.info(
                            f'[{self.account_type[:4]}]: updating position record for {symbol} {record_cash, record_position} -> {new_cash, new_position}'
                        )

            # update __position_record
            # self.record['updated'] = datetime.datetime.now().strftime(format="%Y-%m-%d %H:%M:%S")
            self.__position_record = io_util.read_config(
                file_path=config['config_path'],
                file_name='tiger_position_record.json')
            self.__position_record[self.account_type] = self.record.copy()
            self.__position_record['updated'][
                self.account_type] = datetime.datetime.now().strftime(
                    format="%Y-%m-%d %H:%M:%S")
            io_util.create_config_file(config_dict=self.__position_record,
                                       file_path=config['config_path'],
                                       file_name='tiger_position_record.json')

        except Exception as e:
            self.logger.exception(
                f'[erro]: fail updating position records for {self.account_type}, {e}'
            )