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 )
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)
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)
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)
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)
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 )