Source code for dccd.histo_dl.kraken

#!/usr/bin/env python3
# coding: utf-8
# @Author: ArthurBernard
# @Email: arthur.bernard.92@gmail.com
# @Date: 2019-02-13 18:25:01
# @Last modified by: ArthurBernard
# @Last modified time: 2019-09-03 22:05:04

""" Objects to download historical data from Kraken exchange.

.. currentmodule:: dccd.histo_dl.kraken

.. autoclass:: FromKraken
   :members: import_data, save, get_data, import_trades, save_trades, import_orderbook, save_orderbook
   :show-inheritance:

"""

from __future__ import annotations

# Import built-in packages
import time
import warnings
from typing import Any

# Import third party packages
# Import local packages
from dccd.histo_dl.exchange import ImportDataCryptoCurrencies

__all__ = ['FromKraken']


[docs] class FromKraken(ImportDataCryptoCurrencies): """ Class to import crypto-currencies data from the Kraken exchange. Parameters ---------- path : str Root directory for data files. crypto : str Crypto-currency symbol, e.g. ``'BTC'``. span : int or str Candle interval in seconds (minimum 60) or a label such as ``'hourly'`` or ``'1h'``. fiat : str, optional Quote currency. Default is ``'USD'``. The resulting Kraken pair uses the X/Z prefix scheme (e.g. ``'USD'`` → ``'XXBTZUSD'``); use :meth:`format_pair` to inspect the resolved symbol. form : str, optional Legacy parameter — ignored. Storage is always Parquet via :class:`~dccd.storage.DataStore`. tz : str, optional Timezone for date parsing: ``'local'`` (default), ``'UTC'``, or any IANA timezone name. See Also -------- FromBinance, FromCoinbase, FromBybit, FromOKX Notes ----- See Kraken API documentation [1]_ for more details on parameters. References ---------- .. [1] https://www.kraken.com/features/api Attributes ---------- pair : str Pair symbol, `crypto + fiat`. start, end : int Timestamp to starting and ending download data. span : int Number of seconds between observations. full_path : str Directory managed by :class:`~dccd.storage.DataStore` — ``{path}/kraken/ohlc/{pair}/{span}/``. Methods ------- import_data save get_data import_trades save_trades import_orderbook save_orderbook """
[docs] @staticmethod def format_pair(crypto: str, fiat: str) -> str: """ Return the Kraken pair symbol for *crypto* and *fiat*. Parameters ---------- crypto, fiat : str Asset symbols using common names (e.g. ``'BTC'``, ``'USD'``). Returns ------- str Kraken pair string, e.g. ``'XXBTZUSD'``, ``'BCHUSD'``, or ``'XXMRXXBT'`` for cross-crypto pairs. Notes ----- Rules applied in order: 1. ``'BTC'`` is renamed to ``'XBT'`` (Kraken convention). 2. ``'BCH'`` and ``'DASH'`` are exempt from the X/Z prefix scheme. 3. Major fiats (EUR, USD, CAD, JPY, GBP) use ``X<crypto>Z<fiat>``. 4. All other fiats (incl. crypto quoted in crypto) use ``X<crypto>X<fiat>``. """ if crypto == 'BTC': crypto = 'XBT' if crypto in ('BCH', 'DASH'): return crypto + fiat if fiat not in ('EUR', 'USD', 'CAD', 'JPY', 'GBP'): return 'X' + crypto + 'X' + fiat return 'X' + crypto + 'Z' + fiat
def __init__(self, path, crypto, span, fiat='USD', form='xlsx', tz='local'): ImportDataCryptoCurrencies.__init__( self, path, crypto, span, 'Kraken', fiat=fiat, form=form, tz=tz ) self.pair = self.format_pair(crypto, fiat) def _import_data( self, start: int | str = 'last', end: int | str | None = None ) -> list[dict[str, Any]]: if end is not None: warnings.warn( "The Kraken OHLC API does not support an end date — the 'end' " "parameter is ignored and data is always fetched up to now.", UserWarning, stacklevel=2, ) self.start, self.end = self._set_time(start, int(time.time())) param = { 'pair': self.pair, 'interval': int(self.span / 60), 'since': self.start - self.span } r = self._fetch('https://api.kraken.com/0/public/OHLC', param) text = r.json()['result'][self.pair] data = [{ 'date': float(e[0]), 'open': float(e[1]), 'high': float(e[2]), 'low': float(e[3]), 'close': float(e[4]), 'weightedAverage': float(e[5]), 'volume': float(e[6]), 'quoteVolume': float(e[6]) * float(e[5]) } for e in text] return data def _import_trades(self, start: int, end: int) -> list[dict[str, Any]]: r = self._fetch( 'https://api.kraken.com/0/public/Trades', {'pair': self.pair, 'since': start}, ) trades = r.json()['result'][self.pair] return [{ 'tid': None, 'timestamp': float(e[2]), 'price': float(e[0]), 'amount': float(e[1]), 'type': 'buy' if e[3] == 'b' else 'sell', } for e in trades if float(e[2]) <= end] def _import_orderbook(self, depth: int = 50) -> list[dict[str, Any]]: r = self._fetch( 'https://api.kraken.com/0/public/Depth', {'pair': self.pair, 'count': depth}, ) book = r.json()['result'][self.pair] result = [] for bid in book['bids']: result.append({'side': 'bid', 'price': str(bid[0]), 'amount': float(bid[1]), 'count': None}) for ask in book['asks']: result.append({'side': 'ask', 'price': str(ask[0]), 'amount': float(ask[1]), 'count': None}) return result
[docs] def import_data( self, start: int | str = 'last', end: int | str | None = None ) -> ImportDataCryptoCurrencies: """ Download data from Kraken since a specific time until now. Parameters ---------- start : int or str Timestamp of the first observation as a Unix timestamp (int) or a date string ``'yyyy-mm-dd hh:mm:ss'``. end : int, str or None Ignored. The Kraken OHLC API does not support a custom end date and always returns data up to the current time. Passing a non-None value raises a :class:`UserWarning`. Returns ------- self : FromKraken Data sorted and cleaned in a data frame, accessible via :meth:`get_data`. """ data = self._import_data(start=start, end=end) return self._sort_data(data)