Esempio n. 1
0
    def synchronize_position_record(self, config):

        account_type = self.account_type

        # initialize position record for symbols that not in position record
        init_cash = config['trade']['init_cash'][account_type]
        pool = config['selected_sec_list'][config['trade']['pool']
                                           [account_type]]
        for symbol in pool:
            if symbol not in self.record.keys():
                self.record[symbol] = {'cash': init_cash, 'position': 0}

        # get real position (dict)
        position_dict = dict([(x.contract.symbol, x.quantity)
                              for x in self.positions])

        # compare position record with real position
        record_conflicted = False
        for symbol in self.record.keys():

            if symbol not in pool:
                continue

            # update position in record
            record_position = self.record[symbol]['position']
            current_position = 0 if (
                symbol not in position_dict.keys()) else position_dict[symbol]
            if current_position != record_position:
                record_conflicted = True
                if current_position > 0:
                    self.record[symbol] = {
                        'cash': 0,
                        'position': current_position
                    }
                else:
                    self.record[symbol] = {'cash': init_cash, 'position': 0}
                self.logger.error(
                    f'[{account_type[:4]}]: {symbol} position({current_position}) rather than ({record_position}), reset record'
                )

        # add record for position that not recorded
        for symbol in [
                x for x in position_dict.keys()
                if (x in pool and x not in self.record.keys())
        ]:
            record_conflicted = True
            self.record[symbol] = {
                'cash': 0,
                'position': position_dict[symbol]
            }
            self.logger.error(
                f'[{account_type[:4]}]: {symbol} position({position_dict[symbol]}) not in record, add record'
            )

        # update __position_record
        if record_conflicted:
            self.__position_record[self.account_type] = self.record.copy()
            io_util.create_config_file(config_dict=self.__position_record,
                                       file_path=config['config_path'],
                                       file_name='tiger_position_record.json')
Esempio n. 2
0
    def synchronize_position_record(self, config):

        account_type = self.account_type

        # initialize position record for symbols that not in position record
        init_cash = config['trade']['init_cash'][account_type]
        pool = config['selected_sec_list'][config['trade']['pool']
                                           [account_type]]
        for symbol in pool:
            if symbol not in self.record.keys():
                self.record[symbol] = {'cash': init_cash, 'position': 0}

        # get record position and real position then compare to each other
        record_conflicted = False
        position_dict = dict([(x[0].split('.')[1], x[1])
                              for x in self.positions[['code', 'qty']].values])
        for symbol in self.record.keys():

            # skip symbols that not in auto-trade pool
            if symbol not in pool:
                continue

            record_position = self.record[symbol]['position']
            current_position = 0 if (
                symbol not in position_dict.keys()) else position_dict[symbol]
            if current_position != record_position:
                record_conflicted = True
                if current_position > 0:
                    self.record[symbol] = {
                        'cash': 0,
                        'position': current_position
                    }
                else:
                    self.record[symbol] = {'cash': init_cash, 'position': 0}
                self.logger.error(
                    f'[{account_type[:4]}]: {symbol} position({current_position}) rather than ({record_position}), reset record'
                )

        # add record for symbol in position but not in record
        for symbol in [
                x for x in position_dict.keys()
                if (x in pool and x not in self.record.keys())
        ]:
            record_conflicted = True
            self.record[symbol] = {
                'cash': 0,
                'position': position_dict[symbol]
            }
            self.logger.error(
                f'[{account_type[:4]}]: {symbol} position({position_dict[symbol]}) not in record, add record'
            )

        # update __position_record
        if record_conflicted:
            self.__position_record[self.account_type] = self.record.copy()
            io_util.create_config_file(config_dict=self.__position_record,
                                       file_path=config['config_path'],
                                       file_name='futu_position_record.json')
Esempio n. 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}'
            )
Esempio n. 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}'
            )
Esempio n. 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}'
            )