2019-02-17 03:01:17 +00:00
|
|
|
""" Kraken exchange subclass """
|
|
|
|
import logging
|
|
|
|
from typing import Dict
|
|
|
|
|
2019-09-11 04:58:10 +00:00
|
|
|
import ccxt
|
|
|
|
|
|
|
|
from freqtrade import OperationalException, TemporaryError
|
2019-02-17 03:01:17 +00:00
|
|
|
from freqtrade.exchange import Exchange
|
2019-09-11 04:58:10 +00:00
|
|
|
from freqtrade.exchange.exchange import retrier
|
2019-02-17 03:01:17 +00:00
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class Kraken(Exchange):
|
|
|
|
|
2019-02-17 14:54:22 +00:00
|
|
|
_params: Dict = {"trading_agreement": "agree"}
|
2019-08-14 17:22:52 +00:00
|
|
|
_ft_has: Dict = {
|
|
|
|
"trades_pagination": "id",
|
|
|
|
"trades_pagination_arg": "since",
|
|
|
|
}
|
2019-09-11 04:58:10 +00:00
|
|
|
|
|
|
|
@retrier
|
|
|
|
def get_balances(self) -> dict:
|
|
|
|
if self._config['dry_run']:
|
|
|
|
return {}
|
|
|
|
|
|
|
|
try:
|
|
|
|
balances = self._api.fetch_balance()
|
|
|
|
# Remove additional info from ccxt results
|
|
|
|
balances.pop("info", None)
|
|
|
|
balances.pop("free", None)
|
|
|
|
balances.pop("total", None)
|
|
|
|
balances.pop("used", None)
|
|
|
|
|
|
|
|
orders = self._api.fetch_open_orders()
|
2019-09-12 05:03:52 +00:00
|
|
|
order_list = [(x["symbol"].split("/")[0 if x["side"] == "sell" else 1],
|
|
|
|
x["remaining"],
|
|
|
|
# Don't remove the below comment, this can be important for debuggung
|
|
|
|
# x["side"], x["amount"],
|
|
|
|
) for x in orders]
|
2019-09-11 04:58:10 +00:00
|
|
|
for bal in balances:
|
|
|
|
balances[bal]['used'] = sum(order[1] for order in order_list if order[0] == bal)
|
|
|
|
balances[bal]['free'] = balances[bal]['total'] - balances[bal]['used']
|
|
|
|
|
|
|
|
return balances
|
|
|
|
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
|
|
|
raise TemporaryError(
|
|
|
|
f'Could not get balance due to {e.__class__.__name__}. Message: {e}') from e
|
|
|
|
except ccxt.BaseError as e:
|
|
|
|
raise OperationalException(e) from e
|