diff --git a/freqtrade/data/converter.py b/freqtrade/data/converter.py index 77a3447da..dc566070d 100644 --- a/freqtrade/data/converter.py +++ b/freqtrade/data/converter.py @@ -10,14 +10,16 @@ from pandas import DataFrame, to_datetime logger = logging.getLogger(__name__) -def parse_ticker_dataframe(ticker: list, ticker_interval: str, - fill_missing: bool = True) -> DataFrame: +def parse_ticker_dataframe(ticker: list, ticker_interval: str, *, + fill_missing: bool = True, + drop_incomplete: bool = True) -> DataFrame: """ Converts a ticker-list (format ccxt.fetch_ohlcv) to a Dataframe :param ticker: ticker list, as returned by exchange.async_get_candle_history :param ticker_interval: ticker_interval (e.g. 5m). Used to fill up eventual missing data :param fill_missing: fill up missing candles with 0 candles (see ohlcv_fill_up_missing_data for details) + :param drop_incomplete: Drop the last candle of the dataframe, assuming it's incomplete :return: DataFrame """ logger.debug("Parsing tickerlist to dataframe") @@ -43,8 +45,10 @@ def parse_ticker_dataframe(ticker: list, ticker_interval: str, 'close': 'last', 'volume': 'max', }) - frame.drop(frame.tail(1).index, inplace=True) # eliminate partial candle - logger.debug('Dropping last candle') + # eliminate partial candle + if drop_incomplete: + frame.drop(frame.tail(1).index, inplace=True) + logger.debug('Dropping last candle') if fill_missing: return ohlcv_fill_up_missing_data(frame, ticker_interval) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 07a5e9037..401a3571f 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -74,6 +74,7 @@ class Exchange(object): _ft_has_default: Dict = { "stoploss_on_exchange": False, "order_time_in_force": ["gtc"], + "ohlcv_partial_candle": True, } _ft_has: Dict = {} @@ -108,7 +109,12 @@ class Exchange(object): if exchange_config.get("_ft_has_params"): self._ft_has = deep_merge_dicts(exchange_config.get("_ft_has_params"), self._ft_has) + logger.info("Overriding exchange._ft_has with config params, result: %s", self._ft_has) + # Assign this directly for easy access + self._drop_incomplete = self._ft_has['ohlcv_partial_candle'] + + # Initialize ccxt objects self._api: ccxt.Exchange = self._init_ccxt( exchange_config, ccxt_kwargs=exchange_config.get('ccxt_config')) self._api_async: ccxt_async.Exchange = self._init_ccxt( @@ -575,7 +581,7 @@ class Exchange(object): self._pairs_last_refresh_time[(pair, ticker_interval)] = ticks[-1][0] // 1000 # keeping parsed dataframe in cache self._klines[(pair, ticker_interval)] = parse_ticker_dataframe( - ticks, ticker_interval, fill_missing=True) + ticks, ticker_interval, fill_missing=True, drop_incomplete=self._drop_incomplete) return tickers def _now_is_time_to_refresh(self, pair: str, ticker_interval: str) -> bool: