From b6040e270fa253fc089230decf37d7cce98d61a8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 Mar 2024 13:08:58 +0100 Subject: [PATCH] Update data handlers to accept trading_mode for trade data related functions --- freqtrade/data/history/featherdatahandler.py | 14 ++++++---- freqtrade/data/history/hdf5datahandler.py | 14 ++++++---- freqtrade/data/history/idatahandler.py | 29 ++++++++++++++------ freqtrade/data/history/jsondatahandler.py | 14 ++++++---- freqtrade/data/history/parquetdatahandler.py | 16 +++++++---- 5 files changed, 57 insertions(+), 30 deletions(-) diff --git a/freqtrade/data/history/featherdatahandler.py b/freqtrade/data/history/featherdatahandler.py index 44d337836..6d57dbed7 100644 --- a/freqtrade/data/history/featherdatahandler.py +++ b/freqtrade/data/history/featherdatahandler.py @@ -5,7 +5,7 @@ from pandas import DataFrame, read_feather, to_datetime from freqtrade.configuration import TimeRange from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS -from freqtrade.enums import CandleType +from freqtrade.enums import CandleType, TradingMode from .idatahandler import IDataHandler @@ -82,14 +82,15 @@ class FeatherDataHandler(IDataHandler): """ raise NotImplementedError() - def _trades_store(self, pair: str, data: DataFrame) -> None: + def _trades_store(self, pair: str, data: DataFrame, trading_mode: TradingMode) -> None: """ Store trades data (list of Dicts) to file :param pair: Pair - used for filename :param data: Dataframe containing trades column sequence as in DEFAULT_TRADES_COLUMNS + :param trading_mode: Trading mode to use (used to determine the filename) """ - filename = self._pair_trades_filename(self._datadir, pair) + filename = self._pair_trades_filename(self._datadir, pair, trading_mode) self.create_dir_if_needed(filename) data.reset_index(drop=True).to_feather(filename, compression_level=9, compression='lz4') @@ -102,15 +103,18 @@ class FeatherDataHandler(IDataHandler): """ raise NotImplementedError() - def _trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> DataFrame: + def _trades_load( + self, pair: str, trading_mode: TradingMode, timerange: Optional[TimeRange] = None + ) -> DataFrame: """ Load a pair from file, either .json.gz or .json # TODO: respect timerange ... :param pair: Load trades for this pair + :param trading_mode: Trading mode to use (used to determine the filename) :param timerange: Timerange to load trades for - currently not implemented :return: Dataframe containing trades """ - filename = self._pair_trades_filename(self._datadir, pair) + filename = self._pair_trades_filename(self._datadir, pair, trading_mode) if not filename.exists(): return DataFrame(columns=DEFAULT_TRADES_COLUMNS) diff --git a/freqtrade/data/history/hdf5datahandler.py b/freqtrade/data/history/hdf5datahandler.py index b118bd7e0..cb2cdd884 100644 --- a/freqtrade/data/history/hdf5datahandler.py +++ b/freqtrade/data/history/hdf5datahandler.py @@ -6,7 +6,7 @@ import pandas as pd from freqtrade.configuration import TimeRange from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS -from freqtrade.enums import CandleType +from freqtrade.enums import CandleType, TradingMode from .idatahandler import IDataHandler @@ -100,17 +100,18 @@ class HDF5DataHandler(IDataHandler): """ raise NotImplementedError() - def _trades_store(self, pair: str, data: pd.DataFrame) -> None: + def _trades_store(self, pair: str, data: pd.DataFrame, trading_mode: TradingMode) -> None: """ Store trades data (list of Dicts) to file :param pair: Pair - used for filename :param data: Dataframe containing trades column sequence as in DEFAULT_TRADES_COLUMNS + :param trading_mode: Trading mode to use (used to determine the filename) """ key = self._pair_trades_key(pair) data.to_hdf( - self._pair_trades_filename(self._datadir, pair), key=key, + self._pair_trades_filename(self._datadir, pair, trading_mode), key=key, mode='a', complevel=9, complib='blosc', format='table', data_columns=['timestamp'] ) @@ -124,15 +125,18 @@ class HDF5DataHandler(IDataHandler): """ raise NotImplementedError() - def _trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> pd.DataFrame: + def _trades_load( + self, pair: str, trading_mode: TradingMode, timerange: Optional[TimeRange] = None + ) -> pd.DataFrame: """ Load a pair from h5 file. :param pair: Load trades for this pair + :param trading_mode: Trading mode to use (used to determine the filename) :param timerange: Timerange to load trades for - currently not implemented :return: Dataframe containing trades """ key = self._pair_trades_key(pair) - filename = self._pair_trades_filename(self._datadir, pair) + filename = self._pair_trades_filename(self._datadir, pair, trading_mode) if not filename.exists(): return pd.DataFrame(columns=DEFAULT_TRADES_COLUMNS) diff --git a/freqtrade/data/history/idatahandler.py b/freqtrade/data/history/idatahandler.py index 01c244f38..bcb31a7c8 100644 --- a/freqtrade/data/history/idatahandler.py +++ b/freqtrade/data/history/idatahandler.py @@ -172,12 +172,13 @@ class IDataHandler(ABC): return [cls.rebuild_pair_from_filename(match[0]) for match in _tmp if match] @abstractmethod - def _trades_store(self, pair: str, data: DataFrame) -> None: + def _trades_store(self, pair: str, data: DataFrame, trading_mode: TradingMode) -> None: """ Store trades data (list of Dicts) to file :param pair: Pair - used for filename :param data: Dataframe containing trades column sequence as in DEFAULT_TRADES_COLUMNS + :param trading_mode: Trading mode to use (used to determine the filename) """ @abstractmethod @@ -190,45 +191,55 @@ class IDataHandler(ABC): """ @abstractmethod - def _trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> DataFrame: + def _trades_load( + self, pair: str, trading_mode: TradingMode, timerange: Optional[TimeRange] = None + ) -> DataFrame: """ Load a pair from file, either .json.gz or .json :param pair: Load trades for this pair + :param trading_mode: Trading mode to use (used to determine the filename) :param timerange: Timerange to load trades for - currently not implemented :return: Dataframe containing trades """ - def trades_store(self, pair: str, data: DataFrame) -> None: + def trades_store(self, pair: str, data: DataFrame, trading_mode: TradingMode) -> None: """ Store trades data (list of Dicts) to file :param pair: Pair - used for filename :param data: Dataframe containing trades column sequence as in DEFAULT_TRADES_COLUMNS + :param trading_mode: Trading mode to use (used to determine the filename) """ # Filter on expected columns (will remove the actual date column). - self._trades_store(pair, data[DEFAULT_TRADES_COLUMNS]) + self._trades_store(pair, data[DEFAULT_TRADES_COLUMNS], trading_mode) - def trades_purge(self, pair: str) -> bool: + def trades_purge(self, pair: str, trading_mode: TradingMode) -> bool: """ Remove data for this pair :param pair: Delete data for this pair. + :param trading_mode: Trading mode to use (used to determine the filename) :return: True when deleted, false if file did not exist. """ - filename = self._pair_trades_filename(self._datadir, pair) + filename = self._pair_trades_filename(self._datadir, pair, trading_mode) if filename.exists(): filename.unlink() return True return False - def trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> DataFrame: + def trades_load( + self, pair: str, trading_mode: TradingMode, timerange: Optional[TimeRange] = None + ) -> DataFrame: """ Load a pair from file, either .json.gz or .json Removes duplicates in the process. :param pair: Load trades for this pair + :param trading_mode: Trading mode to use (used to determine the filename) :param timerange: Timerange to load trades for - currently not implemented :return: List of trades """ - trades = trades_df_remove_duplicates(self._trades_load(pair, timerange=timerange)) + trades = trades_df_remove_duplicates( + self._trades_load(pair, trading_mode, timerange=timerange) + ) trades = trades_convert_types(trades) return trades @@ -264,7 +275,7 @@ class IDataHandler(ABC): return filename @classmethod - def _pair_trades_filename(cls, datadir: Path, pair: str) -> Path: + def _pair_trades_filename(cls, datadir: Path, pair: str, trading_mode: TradingMode) -> Path: pair_s = misc.pair_to_filename(pair) if ':' in pair: # Futures pair ... diff --git a/freqtrade/data/history/jsondatahandler.py b/freqtrade/data/history/jsondatahandler.py index baa0c10a5..2d0333fed 100644 --- a/freqtrade/data/history/jsondatahandler.py +++ b/freqtrade/data/history/jsondatahandler.py @@ -8,7 +8,7 @@ from freqtrade import misc from freqtrade.configuration import TimeRange from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS from freqtrade.data.converter import trades_dict_to_list, trades_list_to_df -from freqtrade.enums import CandleType +from freqtrade.enums import CandleType, TradingMode from .idatahandler import IDataHandler @@ -94,14 +94,15 @@ class JsonDataHandler(IDataHandler): """ raise NotImplementedError() - def _trades_store(self, pair: str, data: DataFrame) -> None: + def _trades_store(self, pair: str, data: DataFrame, trading_mode: TradingMode) -> None: """ Store trades data (list of Dicts) to file :param pair: Pair - used for filename :param data: Dataframe containing trades column sequence as in DEFAULT_TRADES_COLUMNS + :param trading_mode: Trading mode to use (used to determine the filename) """ - filename = self._pair_trades_filename(self._datadir, pair) + filename = self._pair_trades_filename(self._datadir, pair, trading_mode) trades = data.values.tolist() misc.file_dump_json(filename, trades, is_zip=self._use_zip) @@ -114,15 +115,18 @@ class JsonDataHandler(IDataHandler): """ raise NotImplementedError() - def _trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> DataFrame: + def _trades_load( + self, pair: str, trading_mode: TradingMode, timerange: Optional[TimeRange] = None + ) -> DataFrame: """ Load a pair from file, either .json.gz or .json # TODO: respect timerange ... :param pair: Load trades for this pair + :param trading_mode: Trading mode to use (used to determine the filename) :param timerange: Timerange to load trades for - currently not implemented :return: Dataframe containing trades """ - filename = self._pair_trades_filename(self._datadir, pair) + filename = self._pair_trades_filename(self._datadir, pair, trading_mode) tradesdata = misc.file_load_json(filename) if not tradesdata: diff --git a/freqtrade/data/history/parquetdatahandler.py b/freqtrade/data/history/parquetdatahandler.py index c0b0cad63..01becdc84 100644 --- a/freqtrade/data/history/parquetdatahandler.py +++ b/freqtrade/data/history/parquetdatahandler.py @@ -4,8 +4,8 @@ from typing import Optional from pandas import DataFrame, read_parquet, to_datetime from freqtrade.configuration import TimeRange -from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS, TradeList -from freqtrade.enums import CandleType +from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS +from freqtrade.enums import CandleType, TradingMode from .idatahandler import IDataHandler @@ -81,14 +81,15 @@ class ParquetDataHandler(IDataHandler): """ raise NotImplementedError() - def _trades_store(self, pair: str, data: DataFrame) -> None: + def _trades_store(self, pair: str, data: DataFrame, trading_mode: TradingMode) -> None: """ Store trades data (list of Dicts) to file :param pair: Pair - used for filename :param data: Dataframe containing trades column sequence as in DEFAULT_TRADES_COLUMNS + :param trading_mode: Trading mode to use (used to determine the filename) """ - filename = self._pair_trades_filename(self._datadir, pair) + filename = self._pair_trades_filename(self._datadir, pair, trading_mode) self.create_dir_if_needed(filename) data.reset_index(drop=True).to_parquet(filename) @@ -101,15 +102,18 @@ class ParquetDataHandler(IDataHandler): """ raise NotImplementedError() - def _trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> TradeList: + def _trades_load( + self, pair: str, trading_mode: TradingMode, timerange: Optional[TimeRange] = None + ) -> DataFrame: """ Load a pair from file, either .json.gz or .json # TODO: respect timerange ... :param pair: Load trades for this pair + :param trading_mode: Trading mode to use (used to determine the filename) :param timerange: Timerange to load trades for - currently not implemented :return: List of trades """ - filename = self._pair_trades_filename(self._datadir, pair) + filename = self._pair_trades_filename(self._datadir, pair, trading_mode) if not filename.exists(): return DataFrame(columns=DEFAULT_TRADES_COLUMNS)