def query_poloniex_history(self, history, asset_movements, start_ts, end_ts, end_at_least_ts): log.info( 'Starting poloniex history query', start_ts=start_ts, end_ts=end_ts, end_at_least_ts=end_at_least_ts, ) poloniex_margin_trades = list() polo_loans = list() if self.poloniex is not None: polo_history = self.poloniex.query_trade_history( start_ts=start_ts, end_ts=end_ts, end_at_least_ts=end_at_least_ts, ) for pair, trades in polo_history.items(): for trade in trades: category = trade['category'] if category == 'exchange' or category == 'settlement': history.append(trade_from_poloniex(trade, pair)) elif category == 'marginTrade': if not self.read_manual_margin_positions: poloniex_margin_trades.append(trade_from_poloniex(trade, pair)) else: raise ValueError('Unexpected poloniex trade category: {}'.format(category)) if self.read_manual_margin_positions: # Just read the manual positions log and make virtual trades that # correspond to the profits assert poloniex_margin_trades == list(), ( 'poloniex margin trades list should be empty here' ) poloniex_margin_trades = do_read_manual_margin_positions( self.user_directory, ) else: poloniex_margin_trades.sort(key=lambda trade: trade.timestamp) poloniex_margin_trades = limit_trade_list_to_period( poloniex_margin_trades, start_ts, end_ts, ) polo_loans = self.poloniex.query_loan_history( start_ts=start_ts, end_ts=end_ts, end_at_least_ts=end_at_least_ts, from_csv=True, ) polo_loans = process_polo_loans(polo_loans, start_ts, end_ts) polo_asset_movements = self.poloniex.query_deposits_withdrawals( start_ts=start_ts, end_ts=end_ts, end_at_least_ts=end_at_least_ts, ) asset_movements.extend(polo_asset_movements) return history, asset_movements, poloniex_margin_trades, polo_loans
def test_trade_from_poloniex(): amount = FVal(613.79427133) rate = FVal(0.00022999) perc_fee = FVal(0.0015) cost = amount * rate poloniex_trade = { 'globalTradeID': 192167, 'tradeID': FVal(3727.0), 'date': '2017-07-22 21:18:37', 'rate': rate, 'amount': amount, 'total': FVal(0.14116654), 'fee': perc_fee, 'orderNumber': FVal(2315432.0), 'type': 'sell', 'category': 'exchange', } trade = trade_from_poloniex(poloniex_trade, 'BTC_ETH') assert isinstance(trade, Trade) assert isinstance(trade.timestamp, int) assert trade.timestamp == 1500758317 assert trade.type == 'sell' assert trade.rate == rate assert trade.amount == amount assert trade.cost == cost assert trade.cost_currency == 'BTC' assert trade.fee == cost * perc_fee assert trade.fee_currency == 'BTC' assert trade.location == 'poloniex'
def test_trade_from_poloniex(): amount = FVal(TEST_AMOUNT_STR) rate = FVal(TEST_RATE_STR) perc_fee = FVal(TEST_PERC_FEE_STR) cost = amount * rate trade = trade_from_poloniex(TEST_POLO_TRADE, 'BTC_ETH') assert isinstance(trade, Trade) assert isinstance(trade.timestamp, int) assert trade.timestamp == 1500758317 assert trade.trade_type == TradeType.SELL assert trade.rate == rate assert trade.amount == amount assert trade.pair == 'ETH_BTC' assert trade.fee == cost * perc_fee assert trade.fee_currency == 'BTC' assert trade.location == 'poloniex'
def test_poloniex_trade_with_asset_needing_conversion(): amount = FVal(613.79427133) rate = FVal(0.00022999) perc_fee = FVal(0.0015) poloniex_trade = { 'globalTradeID': 192167, 'tradeID': FVal(3727.0), 'date': '2017-07-22 21:18:37', 'rate': rate, 'amount': amount, 'total': FVal(0.14116654), 'fee': perc_fee, 'orderNumber': FVal(2315432.0), 'type': 'sell', 'category': 'exchange', } trade = trade_from_poloniex(poloniex_trade, 'AIR_BTC') assert trade.pair == 'BTC_AIR-2' assert trade.location == 'poloniex'
def query_poloniex_history( self, history: List[Trade], asset_movements: List[AssetMovement], start_ts: Timestamp, end_ts: Timestamp, end_at_least_ts: Timestamp, ) -> Tuple[List[Trade], List[AssetMovement], Union[ List[MarginPosition], List[Trade]], List[Loan], ]: # The poloniex margin trades list can either be normal trades list or # if we read manual margin positions a List or MarginPosition # TODO: This is pretty ugly. Simply remove the manual MarginPosition trades # possibility from poloniex. Will make it easier to maintain poloniex_margin_trades: List[Trade] = [] poloniex_manual_margin_positions: List[MarginPosition] = [] polo_loans: List[Loan] = list() if not self.poloniex: return history, asset_movements, poloniex_margin_trades, polo_loans log.info( 'Starting poloniex history query', start_ts=start_ts, end_ts=end_ts, end_at_least_ts=end_at_least_ts, ) polo_history = self.poloniex.query_trade_history( start_ts=start_ts, end_ts=end_ts, end_at_least_ts=end_at_least_ts, ) for pair, trades in polo_history.items(): for trade in trades: category = trade['category'] try: if category == 'exchange' or category == 'settlement': history.append(trade_from_poloniex(trade, pair)) elif category == 'marginTrade': if not self.read_manual_margin_positions: poloniex_margin_trades.append( trade_from_poloniex(trade, pair)) else: raise ValueError( f'Unexpected poloniex trade category: {category}', ) except UnsupportedAsset as e: self.msg_aggregator.add_warning( f'Found poloniex trade with unsupported asset' f' {e.asset_name}. Ignoring it.', ) continue except UnknownAsset as e: self.msg_aggregator.add_warning( f'Found poloniex trade with unknown asset' f' {e.asset_name}. Ignoring it.', ) continue except DeserializationError as e: self.msg_aggregator.add_error( 'Error deserializing a poloniex trade. Check the logs ' 'and open a bug report.', ) log.error( 'Error deserializing poloniex trade', trade=trade, error=str(e), ) margin_return_list: Union[List[MarginPosition], List[Trade]] if self.read_manual_margin_positions: # Just read the manual positions log and make virtual trades that # correspond to the profits poloniex_manual_margin_positions = do_read_manual_margin_positions( self.user_directory, ) margin_return_list = poloniex_manual_margin_positions else: poloniex_margin_trades.sort(key=lambda trade: trade.timestamp) poloniex_margin_trades = limit_trade_list_to_period( poloniex_margin_trades, start_ts, end_ts, ) margin_return_list = poloniex_margin_trades polo_loans_data = self.poloniex.query_loan_history( start_ts=start_ts, end_ts=end_ts, end_at_least_ts=end_at_least_ts, from_csv=True, ) polo_loans = process_polo_loans(self.msg_aggregator, polo_loans_data, start_ts, end_ts) polo_asset_movements = self.poloniex.query_deposits_withdrawals( start_ts=start_ts, end_ts=end_ts, end_at_least_ts=end_at_least_ts, ) asset_movements.extend(polo_asset_movements) return history, asset_movements, margin_return_list, polo_loans
def test_poloniex_trade_deserialization_errors(): test_trade = TEST_POLO_TRADE.copy() test_trade['date'] = '2017/07/22 1:18:37' with pytest.raises(DeserializationError): trade_from_poloniex(test_trade, 'BTC_ETH') test_trade = TEST_POLO_TRADE.copy() test_trade['type'] = 'lololol' with pytest.raises(DeserializationError): trade_from_poloniex(test_trade, 'BTC_ETH') test_trade = TEST_POLO_TRADE.copy() test_trade['amount'] = None with pytest.raises(DeserializationError): trade_from_poloniex(test_trade, 'BTC_ETH') test_trade = TEST_POLO_TRADE.copy() test_trade['rate'] = None with pytest.raises(DeserializationError): trade_from_poloniex(test_trade, 'BTC_ETH') test_trade = TEST_POLO_TRADE.copy() test_trade['fee'] = ['a'] with pytest.raises(DeserializationError): trade_from_poloniex(test_trade, 'BTC_ETH') test_trade = TEST_POLO_TRADE.copy() del test_trade['rate'] with pytest.raises(DeserializationError): trade_from_poloniex(test_trade, 'BTC_ETH')
def query_poloniex_history(self, history, asset_movements, start_ts, end_ts, end_at_least_ts): if not self.poloniex: return history, asset_movements, [], [] log.info( 'Starting poloniex history query', start_ts=start_ts, end_ts=end_ts, end_at_least_ts=end_at_least_ts, ) poloniex_margin_trades = list() polo_loans = list() polo_history = self.poloniex.query_trade_history( start_ts=start_ts, end_ts=end_ts, end_at_least_ts=end_at_least_ts, ) for pair, trades in polo_history.items(): for trade in trades: category = trade['category'] try: if category == 'exchange' or category == 'settlement': history.append(trade_from_poloniex(trade, pair)) elif category == 'marginTrade': if not self.read_manual_margin_positions: poloniex_margin_trades.append( trade_from_poloniex(trade, pair)) else: raise ValueError( f'Unexpected poloniex trade category: {category}', ) except UnsupportedAsset as e: self.msg_aggregator.add_warning( f'Found poloniex trade with unsupported asset' f' {e.asset_name}. Ignoring it.', ) continue except UnknownAsset as e: self.msg_aggregator.add_warning( f'Found poloniex trade with unknown asset' f' {e.asset_name}. Ignoring it.', ) continue if self.read_manual_margin_positions: # Just read the manual positions log and make virtual trades that # correspond to the profits assert poloniex_margin_trades == list(), ( 'poloniex margin trades list should be empty here') poloniex_margin_trades = do_read_manual_margin_positions( self.user_directory, ) else: poloniex_margin_trades.sort(key=lambda trade: trade.timestamp) poloniex_margin_trades = limit_trade_list_to_period( poloniex_margin_trades, start_ts, end_ts, ) polo_loans = self.poloniex.query_loan_history( start_ts=start_ts, end_ts=end_ts, end_at_least_ts=end_at_least_ts, from_csv=True, ) polo_loans = self.process_polo_loans(polo_loans, start_ts, end_ts) polo_asset_movements = self.poloniex.query_deposits_withdrawals( start_ts=start_ts, end_ts=end_ts, end_at_least_ts=end_at_least_ts, ) asset_movements.extend(polo_asset_movements) return history, asset_movements, poloniex_margin_trades, polo_loans