Cache analyzed dataframe
This commit is contained in:
parent
79933060e5
commit
fd97ad9b76
@ -5,16 +5,16 @@ including ticker and orderbook data, live and historical candle (OHLCV) data
|
|||||||
Common Interface for bot and strategy to access data.
|
Common Interface for bot and strategy to access data.
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Any, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
|
from arrow import Arrow
|
||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
|
from freqtrade.constants import ListPairsWithTimeframes
|
||||||
from freqtrade.data.history import load_pair_history
|
from freqtrade.data.history import load_pair_history
|
||||||
from freqtrade.exceptions import DependencyException, OperationalException
|
from freqtrade.exceptions import DependencyException, OperationalException
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
from freqtrade.state import RunMode
|
from freqtrade.state import RunMode
|
||||||
from freqtrade.constants import ListPairsWithTimeframes
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -25,6 +25,21 @@ class DataProvider:
|
|||||||
self._config = config
|
self._config = config
|
||||||
self._exchange = exchange
|
self._exchange = exchange
|
||||||
self._pairlists = pairlists
|
self._pairlists = pairlists
|
||||||
|
self.__cached_pairs: Dict[Tuple(str, str), DataFrame] = {}
|
||||||
|
|
||||||
|
def _set_cached_df(self, pair: str, timeframe: str, dataframe: DataFrame) -> None:
|
||||||
|
"""
|
||||||
|
Store cached Dataframe.
|
||||||
|
Using private method as this should never be used by a user
|
||||||
|
(but the class is exposed via `self.dp` to the strategy)
|
||||||
|
:param pair: pair to get the data for
|
||||||
|
:param timeframe: Timeframe to get data for
|
||||||
|
:param dataframe: analyzed dataframe
|
||||||
|
"""
|
||||||
|
self.__cached_pairs[(pair, timeframe)] = {
|
||||||
|
'data': dataframe,
|
||||||
|
'updated': Arrow.utcnow().datetime,
|
||||||
|
}
|
||||||
|
|
||||||
def refresh(self,
|
def refresh(self,
|
||||||
pairlist: ListPairsWithTimeframes,
|
pairlist: ListPairsWithTimeframes,
|
||||||
@ -89,6 +104,19 @@ class DataProvider:
|
|||||||
logger.warning(f"No data found for ({pair}, {timeframe}).")
|
logger.warning(f"No data found for ({pair}, {timeframe}).")
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def get_analyzed_dataframe(self, pair: str, timeframe: str = None) -> DataFrame:
|
||||||
|
"""
|
||||||
|
:param pair: pair to get the data for
|
||||||
|
:param timeframe: timeframe to get data for
|
||||||
|
:return: Analyzed Dataframe for this pair
|
||||||
|
"""
|
||||||
|
# TODO: check updated time and don't return outdated data.
|
||||||
|
if (pair, timeframe) in self._set_cached_df:
|
||||||
|
return self._set_cached_df[(pair, timeframe)]['data']
|
||||||
|
else:
|
||||||
|
# TODO: this is most likely wrong...
|
||||||
|
raise ValueError(f"No analyzed dataframe found for ({pair}, {timeframe})")
|
||||||
|
|
||||||
def market(self, pair: str) -> Optional[Dict[str, Any]]:
|
def market(self, pair: str) -> Optional[Dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
Return market data for the pair
|
Return market data for the pair
|
||||||
|
@ -273,6 +273,7 @@ class IStrategy(ABC):
|
|||||||
# Defs that only make change on new candle data.
|
# Defs that only make change on new candle data.
|
||||||
dataframe = self.analyze_ticker(dataframe, metadata)
|
dataframe = self.analyze_ticker(dataframe, metadata)
|
||||||
self._last_candle_seen_per_pair[pair] = dataframe.iloc[-1]['date']
|
self._last_candle_seen_per_pair[pair] = dataframe.iloc[-1]['date']
|
||||||
|
self.dp._set_cached_df(pair, self.timeframe, dataframe)
|
||||||
else:
|
else:
|
||||||
logger.debug("Skipping TA Analysis for already analyzed candle")
|
logger.debug("Skipping TA Analysis for already analyzed candle")
|
||||||
dataframe['buy'] = 0
|
dataframe['buy'] = 0
|
||||||
@ -348,13 +349,8 @@ class IStrategy(ABC):
|
|||||||
return False, False
|
return False, False
|
||||||
|
|
||||||
(buy, sell) = latest[SignalType.BUY.value] == 1, latest[SignalType.SELL.value] == 1
|
(buy, sell) = latest[SignalType.BUY.value] == 1, latest[SignalType.SELL.value] == 1
|
||||||
logger.debug(
|
logger.debug('trigger: %s (pair=%s) buy=%s sell=%s',
|
||||||
'trigger: %s (pair=%s) buy=%s sell=%s',
|
latest['date'], pair, str(buy), str(sell))
|
||||||
latest['date'],
|
|
||||||
pair,
|
|
||||||
str(buy),
|
|
||||||
str(sell)
|
|
||||||
)
|
|
||||||
return buy, sell
|
return buy, sell
|
||||||
|
|
||||||
def should_sell(self, trade: Trade, rate: float, date: datetime, buy: bool,
|
def should_sell(self, trade: Trade, rate: float, date: datetime, buy: bool,
|
||||||
|
Loading…
Reference in New Issue
Block a user