From 6e3c9a117b894c2c4ae61f9265d025135deb787d Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Sun, 22 Dec 2024 05:44:51 +0100 Subject: [PATCH] Rework kraken to use ledger --- fin_depo/defi_kraken.py | 74 ++++++++++++++++++++++++++++++++++++----- test/test_kucoin.py | 22 +++--------- 2 files changed, 69 insertions(+), 27 deletions(-) diff --git a/fin_depo/defi_kraken.py b/fin_depo/defi_kraken.py index c430c7e..ef36b96 100644 --- a/fin_depo/defi_kraken.py +++ b/fin_depo/defi_kraken.py @@ -66,7 +66,9 @@ class KrakenDepoFetcher(DepoFetcher): def _get_withdrawals(self) -> list[WithdrawalDetails]: - json = self.client.query_private('WithdrawStatus') + raise NotImplementedError("work in progress") + """ + json = self.client.query_private('WithdrawStatus',data={'start':1}) results = [] for v in json['result']: asset = parse_asset_from_ticker(v['asset']) @@ -77,9 +79,13 @@ class KrakenDepoFetcher(DepoFetcher): raw_details = v, )) return results + """ def _get_deposits(self) -> list[DepositDetails]: - json = self.client.query_private('DepositStatus') + raise NotImplementedError("work in progress") + """ + json = self.client.query_private('DepositStatus',data={'start':1}) + print(json) results = [] for v in json['result']: asset = parse_asset_from_ticker(v['asset']) @@ -90,9 +96,12 @@ class KrakenDepoFetcher(DepoFetcher): raw_details = v, )) return results + """ def _get_historic_spot_orders(self) -> Iterator[TradeOrderDetails]: - json = self.client.query_private('ClosedOrders') + raise NotImplementedError("work in progress") + """ + json = self.client.query_private('ClosedOrders',data={'start':1}) for order_id, v in json['result']['closed'].items(): assert v['descr']['pair'] == 'USDTEUR', 'Only sell USDT for EUR is supported' assert v['descr']['type'] == 'sell', 'Only sell USDT for EUR is supported' @@ -107,17 +116,64 @@ class KrakenDepoFetcher(DepoFetcher): raw_order_details= v, ) del order_id, v + """ def _get_double_registers(self) -> list[DoubleRegister]: - double_registers: list[DoubleRegister] = [] - double_registers += self._get_deposits() - double_registers += self._get_withdrawals() - double_registers += self._get_historic_spot_orders() - double_registers.sort(key=lambda x: x.executed_time) - return double_registers + json = self.client.query_private('Ledgers',data={'start':1}) + return list(parse_from_ledger(json['result']['ledger'].values())) def parse_asset_from_ticker(ticker: str) -> fin_defs.Asset: account = ticker.removesuffix('.HOLD') if account == 'ZEUR': return fin_defs.EUR return fin_defs.WELL_KNOWN_SYMBOLS[account] + +def parse_from_ledger(ledger_items: list[dict[str,str]]) -> Iterator: + collected_items = {} + for item in ledger_items: + collected_items.setdefault(item['refid'], []).append(item) + + for refid, items in collected_items.items(): + print(refid, items) + assert len(items) <= 2 + + if items[0]['type'] == 'deposit': + assert len(items) == 1 + asset = parse_asset_from_ticker(items[0]['asset']) + yield DepositDetails( + deposit = fin_defs.AssetAmount(asset, Decimal(items[0]['amount'])), + fee = fin_defs.AssetAmount(asset, Decimal(items[0]['fee'])), + executed_time = datetime.datetime.fromtimestamp(items[0]['time'],tz=datetime.UTC), + raw_details = items[0], + ) + elif items[0]['type'] == 'withdrawal': + assert len(items) == 1 + asset = parse_asset_from_ticker(items[0]['asset']) + yield WithdrawalDetails( + withdrawn = -fin_defs.AssetAmount(asset, Decimal(items[0]['amount'])), + fee = fin_defs.AssetAmount(asset, Decimal(items[0]['fee'])), + executed_time = datetime.datetime.fromtimestamp(items[0]['time'],tz=datetime.UTC), + raw_details = items[0], + ) + else: + assert len(items) == 2, items + assert items[0]['type'] in {'receive', 'trade'} + assert items[1]['type'] in {'spend', 'trade'} + assert float(items[0]['amount']) > 0 + assert float(items[1]['amount']) < 0 + asset_input = parse_asset_from_ticker(items[1]['asset']) + asset_output = parse_asset_from_ticker(items[0]['asset']) + + input = -fin_defs.AssetAmount(asset_input, Decimal(items[1]['amount'])) + output = fin_defs.AssetAmount(asset_output, Decimal(items[0]['amount'])) + fee_of_input = fin_defs.AssetAmount(asset_input, Decimal(items[1]['fee'])) + fee_of_output = fin_defs.AssetAmount(asset_output, Decimal(items[0]['fee'])) + details = TradeOrderDetails( + input = input, + output = output, + fee = fee_of_input if fee_of_input.amount != 0 else fee_of_output, + executed_time = datetime.datetime.fromtimestamp(items[1]['time'],tz=datetime.UTC), + order_id = refid, + raw_order_details = items[0], + ) + yield details diff --git a/test/test_kucoin.py b/test/test_kucoin.py index 046de14..9b7fba9 100644 --- a/test/test_kucoin.py +++ b/test/test_kucoin.py @@ -36,25 +36,11 @@ def test_get_depo(): assert isinstance(nested_depo, fin_depo.data.DepoSingle) -@needs_secrets -def test_get_withdrawals(): - withdrawals = get_fetcher()._get_withdrawals() - assert len(withdrawals) > 0 - - -@needs_secrets -def test_get_deposits(): - deposits = get_fetcher()._get_deposits() - assert len(deposits) > 0 - - -@needs_secrets -def test_get_historic_spot_orders(): - orders = get_fetcher()._get_historic_spot_orders() - assert next(orders) - - @needs_secrets def test_get_double_registers(): double_registers = get_fetcher()._get_double_registers() assert len(double_registers) > 0 + for item in double_registers: + print(item) + assert item.input.amount > 0 if item.input else None + assert item.output.amount > 0 if item.output else None