예제 #1
0
    def _get_open_orders(self, asset=None, attempt_index=0):
        try:
            if asset:
                exchange = self.exchanges[asset.exchange]
                return exchange.get_open_orders(asset)

            else:
                open_orders = []
                for exchange_name in self.exchanges:
                    exchange = self.exchanges[exchange_name]
                    exchange_orders = exchange.get_open_orders()
                    open_orders.append(exchange_orders)

                return open_orders
        except ExchangeRequestError as e:
            log.warn(
                'open orders attempt {}: {}'.format(attempt_index, e)
            )
            if attempt_index < self.retry_get_open_orders:
                sleep(self.retry_delay)
                return self._get_open_orders(asset, attempt_index + 1)
            else:
                raise ExchangePortfolioDataError(
                    data_type='open-orders',
                    attempts=attempt_index,
                    error=e
                )
예제 #2
0
    def _synchronize_portfolio(self, attempt_index=0):
        try:
            self.exchange.synchronize_portfolio()

            # Applying the updated last_sales_price to the positions
            # in the performance tracker. This seems a bit redundant
            # but it will make sense when we have multiple exchange portfolios
            # feeding into the same performance tracker.
            tracker = self.perf_tracker.todays_performance.position_tracker
            for asset in self.exchange.portfolio.positions:
                position = self.exchange.portfolio.positions[asset]
                tracker.update_position(
                    asset=asset,
                    last_sale_date=position.last_sale_date,
                    last_sale_price=position.last_sale_price)
        except ExchangeRequestError as e:
            log.warn('update portfolio attempt {}: {}'.format(
                attempt_index, e))
            if attempt_index < self.retry_synchronize_portfolio:
                sleep(self.retry_delay)
                self._synchronize_portfolio(attempt_index + 1)
            else:
                raise ExchangePortfolioDataError(data_type='update-portfolio',
                                                 attempts=attempt_index,
                                                 error=e)
예제 #3
0
    def get_exchange_transactions(self, attempt_index=0):
        closed_orders = []
        transactions = []
        commissions = []

        try:
            for order, txn in self.check_open_orders():
                order.dt = txn.dt

                transactions.append(txn)

                if not order.open:
                    closed_orders.append(order)

            return transactions, commissions, closed_orders

        except ExchangeRequestError as e:
            log.warn('check open orders attempt {}: {}'.format(
                attempt_index, e))
            if attempt_index < self.retry_check_open_orders:
                sleep(self.retry_delay)
                return self.get_exchange_transactions(attempt_index + 1)

            else:
                raise ExchangePortfolioDataError(data_type='order-status',
                                                 attempts=attempt_index,
                                                 error=e)
예제 #4
0
 def _get_open_orders(self, asset=None, attempt_index=0):
     try:
         return self.exchange.get_open_orders(asset)
     except ExchangeRequestError as e:
         log.warn('open orders attempt {}: {}'.format(attempt_index, e))
         if attempt_index < self.retry_get_open_orders:
             sleep(self.retry_delay)
             return self._get_open_orders(asset, attempt_index + 1)
         else:
             raise ExchangePortfolioDataError(data_type='open-orders',
                                              attempts=attempt_index,
                                              error=e)
예제 #5
0
 def _check_open_orders(self, attempt_index=0):
     try:
         return self.exchange.check_open_orders()
     except ExchangeRequestError as e:
         log.warn('check open orders attempt {}: {}'.format(
             attempt_index, e))
         if attempt_index < self.retry_check_open_orders:
             sleep(self.retry_delay)
             return self._check_open_orders(attempt_index + 1)
         else:
             raise ExchangePortfolioDataError(data_type='order-status',
                                              attempts=attempt_index,
                                              error=e)
예제 #6
0
    def synchronize_portfolio(self, attempt_index=0):
        """
        Synchronizes the portfolio tracked by the algorithm to refresh
        its current value.

        This includes updating the last_sale_price of all tracked
        positions, returning the available cash, and raising error
        if the data goes out of sync.

        Parameters
        ----------
        attempt_index: int

        Returns
        -------
        float
            The amount of base currency available for trading.

        float
            The total value of all tracked positions.

        """
        tracker = self.perf_tracker.position_tracker
        total_cash = 0.0
        total_positions_value = 0.0

        try:
            # Position keys correspond to assets
            positions = self.portfolio.positions
            assets = list(positions)
            exchange_assets = group_assets_by_exchange(assets)
            for exchange_name in self.exchanges:
                assets = exchange_assets[exchange_name] \
                    if exchange_name in exchange_assets else []

                exchange_positions = \
                    [positions[asset] for asset in assets]

                check_cash = (not self.simulate_orders)

                exchange = self.exchanges[exchange_name]  # Type: Exchange
                cash, positions_value = exchange.calculate_totals(
                    positions=exchange_positions,
                    check_cash=check_cash,
                )
                total_positions_value += positions_value

                if cash is not None:
                    total_cash += cash

                for position in exchange_positions:
                    tracker.update_position(
                        asset=position.asset,
                        last_sale_date=position.last_sale_date,
                        last_sale_price=position.last_sale_price
                    )

            if cash is None:
                total_cash = self.portfolio.cash

            elif total_cash < self.portfolio.cash:
                raise ValueError('Cash on exchanges is lower than the algo.')

            return total_cash, total_positions_value

        except ExchangeRequestError as e:
            log.warn(
                'update portfolio attempt {}: {}'.format(attempt_index, e)
            )
            if attempt_index < self.retry_synchronize_portfolio:
                sleep(self.retry_delay)
                return self.synchronize_portfolio(attempt_index + 1)
            else:
                raise ExchangePortfolioDataError(
                    data_type='update-portfolio',
                    attempts=attempt_index,
                    error=e
                )