stable/freqtrade/data/dataprovider.py

114 lines
4.1 KiB
Python
Raw Normal View History

2018-11-30 19:42:16 +00:00
"""
Dataprovider
Responsible to provide data to the bot
including Klines, tickers, historic data
Common Interface for bot and strategy to access data.
"""
import logging
2018-12-17 05:52:13 +00:00
from pathlib import Path
from typing import List, Tuple
2018-11-30 19:42:16 +00:00
2018-12-02 08:16:35 +00:00
from pandas import DataFrame
2018-12-17 05:52:13 +00:00
from freqtrade.data.history import load_pair_history
from freqtrade.exchange import Exchange
from freqtrade.state import RunMode
2018-11-30 19:42:16 +00:00
logger = logging.getLogger(__name__)
class DataProvider():
2018-11-30 19:42:16 +00:00
2018-12-02 08:16:35 +00:00
def __init__(self, config: dict, exchange: Exchange) -> None:
self._config = config
self._exchange = exchange
2018-11-30 19:42:16 +00:00
2019-01-22 05:55:40 +00:00
def refresh(self,
pairlist: List[Tuple[str, str]],
helping_pairs: List[Tuple[str, str]] = None) -> None:
2018-11-30 19:42:16 +00:00
"""
Refresh data, called with each cycle
"""
2019-01-22 05:55:40 +00:00
if helping_pairs:
self._exchange.refresh_latest_ohlcv(pairlist + helping_pairs)
else:
self._exchange.refresh_latest_ohlcv(pairlist)
2018-11-30 19:42:16 +00:00
2018-12-26 13:23:21 +00:00
@property
def available_pairs(self) -> List[Tuple[str, str]]:
2018-12-26 13:23:21 +00:00
"""
Return a list of tuples containing pair, ticker_interval for which data is currently cached.
2018-12-26 13:23:21 +00:00
Should be whitelist + open trades.
"""
return list(self._exchange._klines.keys())
def ohlcv(self, pair: str, ticker_interval: str = None, copy: bool = True) -> DataFrame:
2018-11-30 19:42:16 +00:00
"""
2019-08-17 08:43:36 +00:00
Get ohlcv data for the given pair as DataFrame
Please check `self.available_pairs` to verify which pairs are currently cached.
2018-12-25 12:37:15 +00:00
:param pair: pair to get the data for
2019-08-17 08:43:36 +00:00
:param ticker_interval: ticker interval to get data for
:param copy: copy dataframe before returning if True.
Use False only for read-only operations (where the dataframe is not modified)
2018-11-30 19:42:16 +00:00
"""
if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE):
2019-08-17 08:43:36 +00:00
pairtick = (pair, ticker_interval or self._config['ticker_interval'])
if pairtick in self.available_pairs:
return self._exchange.klines(pairtick, copy=copy)
2019-08-17 08:43:36 +00:00
return DataFrame()
2018-11-30 19:42:16 +00:00
2019-08-17 08:43:36 +00:00
def historic_ohlcv(self, pair: str, ticker_interval: str = None) -> DataFrame:
2018-11-30 19:42:16 +00:00
"""
2019-08-17 08:43:36 +00:00
Get stored historic ohlcv data
:param pair: pair to get the data for
2019-08-17 08:43:36 +00:00
:param ticker_interval: ticker interval to get data for
2018-11-30 19:42:16 +00:00
"""
2018-12-17 05:52:13 +00:00
return load_pair_history(pair=pair,
2019-08-17 08:43:36 +00:00
ticker_interval=ticker_interval or self._config['ticker_interval'],
2018-12-17 05:52:13 +00:00
refresh_pairs=False,
2018-12-25 12:20:25 +00:00
datadir=Path(self._config['datadir']) if self._config.get(
2018-12-17 05:52:13 +00:00
'datadir') else None
)
2018-11-30 19:42:16 +00:00
2019-08-17 08:43:36 +00:00
def get_pair_dataframe(self, pair: str, ticker_interval: str = None) -> DataFrame:
"""
Return pair ohlcv data, either live or cached historical -- depending
on the runmode.
:param pair: pair to get the data for
:param ticker_interval: ticker interval to get data for
"""
if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE):
# Get live ohlcv data.
data = self.ohlcv(pair=pair, ticker_interval=ticker_interval)
else:
# Get historic ohlcv data (cached on disk).
data = self.historic_ohlcv(pair=pair, ticker_interval=ticker_interval)
if len(data) == 0:
logger.warning(f"No data found for pair {pair}")
return data
2018-12-02 08:16:35 +00:00
def ticker(self, pair: str):
"""
Return last ticker data
"""
2018-12-26 13:58:16 +00:00
# TODO: Implement me
2018-11-30 19:42:16 +00:00
pass
def orderbook(self, pair: str, maximum: int):
2018-12-02 08:16:35 +00:00
"""
return latest orderbook data
:param pair: pair to get the data for
:param maximum: Maximum number of orderbook entries to query
:return: dict including bids/asks with a total of `maximum` entries.
2018-12-02 08:16:35 +00:00
"""
return self._exchange.get_order_book(pair, maximum)
2018-12-02 20:57:30 +00:00
@property
def runmode(self) -> RunMode:
2018-12-02 20:57:30 +00:00
"""
Get runmode of the bot
can be "live", "dry-run", "backtest", "edgecli", "hyperopt" or "other".
2018-12-02 20:57:30 +00:00
"""
2018-12-25 13:35:48 +00:00
return RunMode(self._config.get('runmode', RunMode.OTHER))