freqtrade_origin/freqtrade/data/dataprovider.py

119 lines
4.2 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
from typing import Any, Dict, List, Optional, 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__)
2019-09-12 09:13:20 +00:00
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, timeframe) 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, timeframe: 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
2019-08-18 09:47:19 +00:00
Please use the `available_pairs` method to verify which pairs are currently cached.
2018-12-25 12:37:15 +00:00
:param pair: pair to get the data for
:param timeframe: Ticker timeframe to get data for
2019-08-17 08:43:36 +00:00
: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):
return self._exchange.klines((pair, timeframe or self._config['ticker_interval']),
2019-08-18 10:00:37 +00:00
copy=copy)
else:
return DataFrame()
2018-11-30 19:42:16 +00:00
def historic_ohlcv(self, pair: str, timeframe: 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-11-13 10:28:26 +00:00
:param timeframe: timeframe 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,
timeframe=timeframe or self._config['ticker_interval'],
datadir=self._config['datadir']
2018-12-17 05:52:13 +00:00
)
2018-11-30 19:42:16 +00:00
def get_pair_dataframe(self, pair: str, timeframe: str = None) -> DataFrame:
2019-08-17 08:43:36 +00:00
"""
Return pair ohlcv data, either live or cached historical -- depending
on the runmode.
:param pair: pair to get the data for
2019-11-13 10:28:26 +00:00
:param timeframe: timeframe to get data for
:return: Dataframe for this pair
2019-08-17 08:43:36 +00:00
"""
if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE):
# Get live ohlcv data.
data = self.ohlcv(pair=pair, timeframe=timeframe)
2019-08-17 08:43:36 +00:00
else:
# Get historic ohlcv data (cached on disk).
data = self.historic_ohlcv(pair=pair, timeframe=timeframe)
2019-08-17 08:43:36 +00:00
if len(data) == 0:
logger.warning(f"No data found for ({pair}, {timeframe}).")
2019-08-17 08:43:36 +00:00
return data
def market(self, pair: str) -> Optional[Dict[str, Any]]:
2019-10-02 23:58:45 +00:00
"""
Return market data for the pair
:param pair: Pair to get the data for
:return: Market data dict from ccxt or None if market info is not available for the pair
"""
return self._exchange.markets.get(pair)
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) -> Dict[str, List]:
2018-12-02 08:16:35 +00:00
"""
fetch 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))