change how missing candles will be handled
This commit is contained in:
parent
9660e445b8
commit
4cbb3341d7
@ -7,9 +7,9 @@ Common Interface for bot and strategy to access data.
|
||||
import logging
|
||||
from collections import deque
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
from typing import Any, Dict, List, Optional, Tuple, Union
|
||||
|
||||
from pandas import DataFrame, concat, date_range
|
||||
from pandas import DataFrame, concat
|
||||
|
||||
from freqtrade.configuration import TimeRange
|
||||
from freqtrade.constants import Config, ListPairsWithTimeframes, PairWithTimeframe
|
||||
@ -165,40 +165,36 @@ class DataProvider:
|
||||
timeframe: str,
|
||||
candle_type: CandleType,
|
||||
producer_name: str = "default"
|
||||
) -> Tuple[bool, Optional[List[str]]]:
|
||||
) -> Union[bool, int]:
|
||||
"""
|
||||
Append a candle to the existing external dataframe
|
||||
|
||||
:param pair: pair to get the data for
|
||||
:param timeframe: Timeframe to get data for
|
||||
:param candle_type: Any of the enum CandleType (must match trading mode!)
|
||||
:returns: A tuple with a boolean value signifying if the candle was correctly appended,
|
||||
and a list of datetimes missing from the candle if it finds some.
|
||||
Will return false if has no data for `producer_name`.
|
||||
Will return false if no existing data for (pair, timeframe, candle_type).
|
||||
Will return false if there's missing candles, and a list of datetimes of
|
||||
the missing candles.
|
||||
:returns: False if the candle could not be appended, or the int number of missing candles.
|
||||
"""
|
||||
pair_key = (pair, timeframe, candle_type)
|
||||
|
||||
if producer_name not in self.__producer_pairs_df:
|
||||
# We don't have data from this producer yet,
|
||||
# so we can't append a candle
|
||||
return (False, None)
|
||||
return False
|
||||
|
||||
if pair_key not in self.__producer_pairs_df[producer_name]:
|
||||
# We don't have data for this pair_key,
|
||||
# so we can't append a candle
|
||||
return (False, None)
|
||||
return False
|
||||
|
||||
# CHECK FOR MISSING CANDLES
|
||||
# return int
|
||||
|
||||
existing_df, _ = self.__producer_pairs_df[producer_name][pair_key]
|
||||
appended_df = self._append_candle_to_dataframe(existing_df, dataframe)
|
||||
|
||||
# Everything is good, we appended
|
||||
self.__producer_pairs_df[producer_name][pair_key] = appended_df, last_analyzed
|
||||
return (True, None)
|
||||
return True
|
||||
|
||||
def _append_candle_to_dataframe(self, existing: DataFrame, new: DataFrame) -> DataFrame:
|
||||
"""
|
||||
@ -212,25 +208,10 @@ class DataProvider:
|
||||
existing = concat([existing, new])
|
||||
|
||||
# Only keep the last 1000 candles in memory
|
||||
# TODO: Do this better
|
||||
existing = existing[-1000:] if len(existing) > 1000 else existing
|
||||
|
||||
return existing
|
||||
|
||||
def _is_missing_candles(self, dataframe: DataFrame) -> bool:
|
||||
"""
|
||||
Check if the dataframe is missing any candles
|
||||
|
||||
:param dataframe: The DataFrame to check
|
||||
"""
|
||||
logger.info(dataframe.index)
|
||||
return len(
|
||||
date_range(
|
||||
dataframe.index.min(),
|
||||
dataframe.index.max()
|
||||
).difference(dataframe.index)
|
||||
) > 0
|
||||
|
||||
def get_producer_df(
|
||||
self,
|
||||
pair: str,
|
||||
|
@ -388,8 +388,8 @@ class ExternalMessageConsumer:
|
||||
producer_name=producer_name
|
||||
)
|
||||
|
||||
elif len(df) == 1:
|
||||
# This is just a single candle
|
||||
elif len(df) < 999:
|
||||
# This is n single candles
|
||||
# Have dataprovider append it to
|
||||
# the full datafame. If it can't,
|
||||
# request the missing candles
|
||||
|
@ -1062,31 +1062,28 @@ class RPC:
|
||||
self,
|
||||
pair: str,
|
||||
timeframe: str,
|
||||
limit: Optional[Union[int, List[str]]] = None
|
||||
limit: Optional[int] = None
|
||||
) -> Tuple[DataFrame, datetime]:
|
||||
"""
|
||||
Get the dataframe and last analyze from the dataprovider
|
||||
|
||||
:param pair: The pair to get
|
||||
:param timeframe: The timeframe of data to get
|
||||
:param limit: If an integer, limits the size of dataframe
|
||||
If a list of string date times, only returns those candles
|
||||
:param limit: The amount of candles in the dataframe
|
||||
"""
|
||||
_data, last_analyzed = self._freqtrade.dataprovider.get_analyzed_dataframe(
|
||||
pair, timeframe)
|
||||
_data = _data.copy()
|
||||
|
||||
if limit and isinstance(limit, int):
|
||||
if limit:
|
||||
_data = _data.iloc[-limit:]
|
||||
elif limit and isinstance(limit, str):
|
||||
_data = _data.iloc[_data['date'].isin(limit)]
|
||||
|
||||
return _data, last_analyzed
|
||||
|
||||
def _ws_all_analysed_dataframes(
|
||||
self,
|
||||
pairlist: List[str],
|
||||
limit: Optional[Union[int, List[str]]] = None
|
||||
limit: Optional[int] = None
|
||||
) -> Generator[Dict[str, Any], None, None]:
|
||||
"""
|
||||
Get the analysed dataframes of each pair in the pairlist.
|
||||
@ -1113,7 +1110,7 @@ class RPC:
|
||||
def _ws_request_analyzed_df(
|
||||
self,
|
||||
pair: Optional[str],
|
||||
limit: Optional[Union[int, List[str]]] = None,
|
||||
limit: Optional[int] = None,
|
||||
):
|
||||
""" Historical Analyzed Dataframes for WebSocket """
|
||||
pairlist = [pair] if pair else self._freqtrade.active_pair_whitelist
|
||||
|
Loading…
Reference in New Issue
Block a user