From 0c34104e45f4fbeae66036452ade47fff13ff058 Mon Sep 17 00:00:00 2001 From: robcaulk Date: Wed, 17 Aug 2022 15:18:44 +0200 Subject: [PATCH 01/65] extract download-data from freqai to prepare for future async changes --- freqtrade/freqai/data_kitchen.py | 102 ++++++++++++++++++++------- freqtrade/freqai/freqai_interface.py | 12 ++-- freqtrade/strategy/interface.py | 13 +++- 3 files changed, 94 insertions(+), 33 deletions(-) diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index 35f51baed..4554a5c1a 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -816,7 +816,7 @@ class FreqaiDataKitchen: return False def check_if_new_training_required( - self, trained_timestamp: int + self, trained_timestamp: int = 0 ) -> Tuple[bool, TimeRange, TimeRange]: time = datetime.datetime.now(tz=datetime.timezone.utc).timestamp() @@ -889,31 +889,6 @@ class FreqaiDataKitchen: self.model_filename = f"cb_{coin.lower()}_{int(trained_timerange.stopts)}" - def download_all_data_for_training(self, timerange: TimeRange, dp: DataProvider) -> None: - """ - Called only once upon start of bot to download the necessary data for - populating indicators and training the model. - :param timerange: TimeRange = The full data timerange for populating the indicators - and training the model. - :param dp: DataProvider instance attached to the strategy - """ - new_pairs_days = int((timerange.stopts - timerange.startts) / SECONDS_IN_DAY) - if not dp._exchange: - # Not realistic - this is only called in live mode. - raise OperationalException("Dataprovider did not have an exchange attached.") - refresh_backtest_ohlcv_data( - dp._exchange, - pairs=self.all_pairs, - timeframes=self.freqai_config["feature_parameters"].get("include_timeframes"), - datadir=self.config["datadir"], - timerange=timerange, - new_pairs_days=new_pairs_days, - erase=False, - data_format=self.config.get("dataformat_ohlcv", "json"), - trading_mode=self.config.get("trading_mode", "spot"), - prepend=self.config.get("prepend_data", False), - ) - def set_all_pairs(self) -> None: self.all_pairs = copy.deepcopy( @@ -1027,3 +1002,78 @@ class FreqaiDataKitchen: if self.unique_classes: for label in self.unique_classes: self.unique_class_list += list(self.unique_classes[label]) + +# Methods called by interface.py (load_freqai_model()) + + +def download_all_data_for_training(timerange: TimeRange, + dp: DataProvider, config: dict) -> None: + """ + Called only once upon start of bot to download the necessary data for + populating indicators and training the model. + :param timerange: TimeRange = The full data timerange for populating the indicators + and training the model. + :param dp: DataProvider instance attached to the strategy + """ + all_pairs = copy.deepcopy( + config["freqai"]["feature_parameters"].get("include_corr_pairlist", []) + ) + for pair in config.get("exchange", "").get("pair_whitelist"): + if pair not in all_pairs: + all_pairs.append(pair) + + new_pairs_days = int((timerange.stopts - timerange.startts) / SECONDS_IN_DAY) + if not dp._exchange: + # Not realistic - this is only called in live mode. + raise OperationalException("Dataprovider did not have an exchange attached.") + refresh_backtest_ohlcv_data( + dp._exchange, + pairs=all_pairs, + timeframes=config["freqai"]["feature_parameters"].get("include_timeframes"), + datadir=config["datadir"], + timerange=timerange, + new_pairs_days=new_pairs_days, + erase=False, + data_format=config.get("dataformat_ohlcv", "json"), + trading_mode=config.get("trading_mode", "spot"), + prepend=config.get("prepend_data", False), + ) + + +def get_required_data_timerange( + config: dict +) -> TimeRange: + """ + Used by interface.py to pre-download necessary data for FreqAI + user. + """ + time = datetime.datetime.now(tz=datetime.timezone.utc).timestamp() + trained_timerange = TimeRange() + data_load_timerange = TimeRange() + + timeframes = config["freqai"]["feature_parameters"].get("include_timeframes") + + max_tf_seconds = 0 + for tf in timeframes: + secs = timeframe_to_seconds(tf) + if secs > max_tf_seconds: + max_tf_seconds = secs + + max_period = config["freqai"]["feature_parameters"].get( + "indicator_max_period_candles", 20 + ) * 2 + additional_seconds = max_period * max_tf_seconds + + trained_timerange.startts = int( + time - config["freqai"].get("train_period_days", 0) * SECONDS_IN_DAY + ) + trained_timerange.stopts = int(time) + + data_load_timerange.startts = int( + time + - config["freqai"].get("train_period_days", 0) * SECONDS_IN_DAY + - additional_seconds + ) + data_load_timerange.stopts = int(time) + + return data_load_timerange diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index 49e4ce5c3..5d85cc225 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -278,12 +278,12 @@ class IFreqaiModel(ABC): # download candle history if it is not already in memory if not self.dd.historic_data: - logger.info( - "Downloading all training data for all pairs in whitelist and " - "corr_pairlist, this may take a while if you do not have the " - "data saved" - ) - dk.download_all_data_for_training(data_load_timerange, strategy.dp) + # logger.info( + # "Downloading all training data for all pairs in whitelist and " + # "corr_pairlist, this may take a while if you do not have the " + # "data saved" + # ) + # dk.download_all_data_for_training(data_load_timerange, strategy.dp) self.dd.load_all_pair_histories(data_load_timerange, dk) if not self.scanning: diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 79dbd4c69..20a35ac3e 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -149,9 +149,20 @@ class IStrategy(ABC, HyperStrategyMixin): if self.config.get('freqai', {}).get('enabled', False): # Import here to avoid importing this if freqAI is disabled from freqtrade.resolvers.freqaimodel_resolver import FreqaiModelResolver - + from freqtrade.freqai.data_kitchen import (get_required_data_timerange, + download_all_data_for_training) self.freqai = FreqaiModelResolver.load_freqaimodel(self.config) self.freqai_info = self.config["freqai"] + + # download the desired data in dry/live + if self.config.get('runmode') in (RunMode.DRY_RUN, RunMode.LIVE): + logger.info( + "Downloading all training data for all pairs in whitelist and " + "corr_pairlist, this may take a while if you do not have the " + "data saved" + ) + data_load_timerange = get_required_data_timerange(self.config) + download_all_data_for_training(data_load_timerange, self.dp, self.config) else: # Gracious failures if freqAI is disabled but "start" is called. class DummyClass(): From 5155afb4e7adb62b219fab65df86ac29524e405a Mon Sep 17 00:00:00 2001 From: robcaulk Date: Wed, 17 Aug 2022 15:22:48 +0200 Subject: [PATCH 02/65] clean up code remnants --- freqtrade/freqai/data_kitchen.py | 2 +- freqtrade/freqai/freqai_interface.py | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index 4554a5c1a..6541261eb 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -816,7 +816,7 @@ class FreqaiDataKitchen: return False def check_if_new_training_required( - self, trained_timestamp: int = 0 + self, trained_timestamp: int ) -> Tuple[bool, TimeRange, TimeRange]: time = datetime.datetime.now(tz=datetime.timezone.utc).timestamp() diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index 5d85cc225..1a9e549f6 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -276,14 +276,8 @@ class IFreqaiModel(ABC): ) dk.set_paths(metadata["pair"], new_trained_timerange.stopts) - # download candle history if it is not already in memory + # load candle history into memory if it is not yet. if not self.dd.historic_data: - # logger.info( - # "Downloading all training data for all pairs in whitelist and " - # "corr_pairlist, this may take a while if you do not have the " - # "data saved" - # ) - # dk.download_all_data_for_training(data_load_timerange, strategy.dp) self.dd.load_all_pair_histories(data_load_timerange, dk) if not self.scanning: From 88dd9920ea9dd66c17a55fad4d6fb69cacefb8c2 Mon Sep 17 00:00:00 2001 From: robcaulk Date: Wed, 17 Aug 2022 16:38:09 +0200 Subject: [PATCH 03/65] sort imports for isort --- freqtrade/strategy/interface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 20a35ac3e..1e51701f7 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -148,9 +148,9 @@ class IStrategy(ABC, HyperStrategyMixin): def load_freqAI_model(self) -> None: if self.config.get('freqai', {}).get('enabled', False): # Import here to avoid importing this if freqAI is disabled + from freqtrade.freqai.data_kitchen import (download_all_data_for_training, + get_required_data_timerange) from freqtrade.resolvers.freqaimodel_resolver import FreqaiModelResolver - from freqtrade.freqai.data_kitchen import (get_required_data_timerange, - download_all_data_for_training) self.freqai = FreqaiModelResolver.load_freqaimodel(self.config) self.freqai_info = self.config["freqai"] From ac42c0153da716e0a70abd7a8024d8d3162e4ba6 Mon Sep 17 00:00:00 2001 From: robcaulk Date: Mon, 22 Aug 2022 18:19:07 +0200 Subject: [PATCH 04/65] deprecate indicator_max_period_candles, automatically compute startup candles for FreqAI backtesting. --- config_examples/config_freqai.example.json | 2 +- docs/freqai.md | 2 +- docs/strategy-customization.md | 2 +- freqtrade/data/dataprovider.py | 13 +++++++- freqtrade/freqai/data_kitchen.py | 32 +++++++++---------- freqtrade/optimize/backtesting.py | 33 ++++++++++++++------ freqtrade/strategy/interface.py | 1 + freqtrade/templates/FreqaiExampleStrategy.py | 3 +- tests/freqai/conftest.py | 1 - tests/freqai/test_freqai_backtesting.py | 10 +++--- 10 files changed, 61 insertions(+), 38 deletions(-) diff --git a/config_examples/config_freqai.example.json b/config_examples/config_freqai.example.json index aeb1cb13d..093e11b2a 100644 --- a/config_examples/config_freqai.example.json +++ b/config_examples/config_freqai.example.json @@ -9,6 +9,7 @@ "dry_run": true, "timeframe": "3m", "dry_run_wallet": 1000, + "startup_candle_count": 20, "cancel_open_orders_on_exit": true, "unfilledtimeout": { "entry": 10, @@ -53,7 +54,6 @@ ], "freqai": { "enabled": true, - "startup_candles": 10000, "purge_old_models": true, "train_period_days": 15, "backtest_period_days": 7, diff --git a/docs/freqai.md b/docs/freqai.md index b22e1cd31..f3c9021ed 100644 --- a/docs/freqai.md +++ b/docs/freqai.md @@ -113,7 +113,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `use_SVM_to_remove_outliers` | Ask FreqAI to train a support vector machine to detect and remove outliers from the training data set as well as from incoming data points.
**Datatype:** boolean. | `svm_params` | All parameters available in Sklearn's `SGDOneClassSVM()`. E.g. `nu` *Very* broadly, is the percentage of data points that should be considered outliers. `shuffle` is by default false to maintain reproducibility. But these and all others can be added/changed in this dictionary.
**Datatype:** dictionary. | `stratify_training_data` | This value is used to indicate the stratification of the data. e.g. 2 would set every 2nd data point into a separate dataset to be pulled from during training/testing.
**Datatype:** positive integer. -| `indicator_max_period_candles` | The maximum *period* used in `populate_any_indicators()` for indicator creation. FreqAI uses this information in combination with the maximum timeframe to calculate how many data points it should download so that the first data point does not have a NaN
**Datatype:** positive integer. +| `indicator_max_period_candles` | **Deprecated in favor of** strategy set `startup_candle_count`, however, both configuration parameters provide the same functionality; the maximum *period* used in `populate_any_indicators()` for indicator creation (timeframe independent). FreqAI uses this information in combination with the maximum timeframe to calculate how many data points it should download so that the first data point does not have a NaN
**Datatype:** positive integer. | `indicator_periods_candles` | A list of integers used to duplicate all indicators according to a set of periods and add them to the feature set.
**Datatype:** list of positive integers. | `use_DBSCAN_to_remove_outliers` | Inactive by default. If true, FreqAI clusters data using DBSCAN to identify and remove outliers from training and prediction data.
**Datatype:** float (fraction of 1). | | **Data split parameters** diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 260e253c4..a452b8f05 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -166,7 +166,7 @@ Additional technical libraries can be installed as necessary, or custom indicato Most indicators have an instable startup period, in which they are either not available (NaN), or the calculation is incorrect. This can lead to inconsistencies, since Freqtrade does not know how long this instable period should be. To account for this, the strategy can be assigned the `startup_candle_count` attribute. -This should be set to the maximum number of candles that the strategy requires to calculate stable indicators. +This should be set to the maximum number of candles that the strategy requires to calculate stable indicators. In the case where a user includes higher timeframes with informative pairs, the `startup_candle_count` does not necessarily change. The value is the maximum period (in candles) that any of the informatives timeframes need to compute stable indicators. In this example strategy, this should be set to 100 (`startup_candle_count = 100`), since the longest needed history is 100 candles. diff --git a/freqtrade/data/dataprovider.py b/freqtrade/data/dataprovider.py index 21cead77f..529a12690 100644 --- a/freqtrade/data/dataprovider.py +++ b/freqtrade/data/dataprovider.py @@ -92,7 +92,7 @@ class DataProvider: 'timerange') is None else str(self._config.get('timerange'))) # Move informative start time respecting startup_candle_count timerange.subtract_start( - timeframe_to_seconds(str(timeframe)) * self._config.get('startup_candle_count', 0) + self.get_required_startup_seconds(str(timeframe)) ) self.__cached_pairs_backtesting[saved_pair] = load_pair_history( pair=pair, @@ -105,6 +105,17 @@ class DataProvider: ) return self.__cached_pairs_backtesting[saved_pair].copy() + def get_required_startup_seconds(self, timeframe: str) -> int: + tf_seconds = timeframe_to_seconds(timeframe) + base_seconds = tf_seconds * self._config.get('startup_candle_count', 0) + if not self._config['freqai']['enabled']: + return base_seconds + else: + train_seconds = self._config['freqai']['train_period_days'] * 86400 + # multiplied by safety factor of 2 because FreqAI users + # typically do not know the correct window. + return base_seconds * 2 + int(train_seconds) + def get_pair_dataframe( self, pair: str, diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index 6541261eb..c768fc30e 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -20,6 +20,8 @@ from freqtrade.data.dataprovider import DataProvider from freqtrade.data.history.history_utils import refresh_backtest_ohlcv_data from freqtrade.exceptions import OperationalException from freqtrade.exchange import timeframe_to_seconds +from freqtrade.exchange.exchange import market_is_active +from freqtrade.plugins.pairlist.pairlist_helpers import dynamic_expand_pairlist from freqtrade.strategy.interface import IStrategy @@ -834,9 +836,7 @@ class FreqaiDataKitchen: # We notice that users like to use exotic indicators where # they do not know the required timeperiod. Here we include a factor # of safety by multiplying the user considered "max" by 2. - max_period = self.freqai_config["feature_parameters"].get( - "indicator_max_period_candles", 20 - ) * 2 + max_period = self.config.get('startup_candle_count', 20) * 2 additional_seconds = max_period * max_tf_seconds if trained_timestamp != 0: @@ -1015,12 +1015,15 @@ def download_all_data_for_training(timerange: TimeRange, and training the model. :param dp: DataProvider instance attached to the strategy """ - all_pairs = copy.deepcopy( - config["freqai"]["feature_parameters"].get("include_corr_pairlist", []) - ) - for pair in config.get("exchange", "").get("pair_whitelist"): - if pair not in all_pairs: - all_pairs.append(pair) + + if dp._exchange is not None: + markets = [p for p, m in dp._exchange.markets.items() if market_is_active(m) + or config.get('include_inactive')] + else: + # This should not occur: + raise OperationalException('No exchange object found.') + + all_pairs = dynamic_expand_pairlist(config, markets) new_pairs_days = int((timerange.stopts - timerange.startts) / SECONDS_IN_DAY) if not dp._exchange: @@ -1048,7 +1051,6 @@ def get_required_data_timerange( user. """ time = datetime.datetime.now(tz=datetime.timezone.utc).timestamp() - trained_timerange = TimeRange() data_load_timerange = TimeRange() timeframes = config["freqai"]["feature_parameters"].get("include_timeframes") @@ -1059,15 +1061,9 @@ def get_required_data_timerange( if secs > max_tf_seconds: max_tf_seconds = secs - max_period = config["freqai"]["feature_parameters"].get( - "indicator_max_period_candles", 20 - ) * 2 - additional_seconds = max_period * max_tf_seconds + max_period = config.get('startup_candle_count', 20) * 2 - trained_timerange.startts = int( - time - config["freqai"].get("train_period_days", 0) * SECONDS_IN_DAY - ) - trained_timerange.stopts = int(time) + additional_seconds = max_period * max_tf_seconds data_load_timerange.startts = int( time diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 6528481d5..8f0302ada 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -211,21 +211,21 @@ class Backtesting: """ self.progress.init_step(BacktestState.DATALOAD, 1) - if self.config.get('freqai', {}).get('enabled', False): - startup_candles = int(self.config.get('freqai', {}).get('startup_candles', 0)) - if not startup_candles: - raise OperationalException('FreqAI backtesting module requires user set ' - 'startup_candles in config.') - self.required_startup += int(self.config.get('freqai', {}).get('startup_candles', 0)) - logger.info(f'Increasing startup_candle_count for freqai to {self.required_startup}') - self.config['startup_candle_count'] = self.required_startup + # if self.config.get('freqai', {}).get('enabled', False): + # startup_candles = int(self.config.get('freqai', {}).get('startup_candles', 0)) + # if not startup_candles: + # raise OperationalException('FreqAI backtesting module requires user set ' + # 'startup_candles in config.') + # self.required_startup += int(self.config.get('freqai', {}).get('startup_candles', 0)) + # logger.info(f'Increasing startup_candle_count for freqai to {self.required_startup}') + # self.config['startup_candle_count'] = self.required_startup data = history.load_data( datadir=self.config['datadir'], pairs=self.pairlists.whitelist, timeframe=self.timeframe, timerange=self.timerange, - startup_candles=self.required_startup, + startup_candles=self.get_required_startup(self.timeframe), fail_without_data=True, data_format=self.config.get('dataformat_ohlcv', 'json'), candle_type=self.config.get('candle_type_def', CandleType.SPOT) @@ -244,6 +244,21 @@ class Backtesting: self.progress.set_new_value(1) return data, self.timerange + def get_required_startup(self, timeframe: str) -> int: + if not self.config['freqai']['enabled']: + return self.required_startup + else: + if not self.config['startup_candle_count']: + raise OperationalException('FreqAI backtesting module requires strategy ' + 'set startup_candle_count.') + tf_seconds = timeframe_to_seconds(timeframe) + train_candles = self.config['freqai']['train_period_days'] * 86400 / tf_seconds + # multiplied by safety factor of 2 because FreqAI users + # typically do not know the correct window. + total_candles = self.required_startup * 2 + train_candles + logger.info(f'Increasing startup_candle_count for freqai to {total_candles}') + return total_candles + def load_bt_data_detail(self) -> None: """ Loads backtest detail data (smaller timeframe) if necessary. diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 1e51701f7..284727d2b 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -163,6 +163,7 @@ class IStrategy(ABC, HyperStrategyMixin): ) data_load_timerange = get_required_data_timerange(self.config) download_all_data_for_training(data_load_timerange, self.dp, self.config) + else: # Gracious failures if freqAI is disabled but "start" is called. class DummyClass(): diff --git a/freqtrade/templates/FreqaiExampleStrategy.py b/freqtrade/templates/FreqaiExampleStrategy.py index 5810e7881..aa584bfbc 100644 --- a/freqtrade/templates/FreqaiExampleStrategy.py +++ b/freqtrade/templates/FreqaiExampleStrategy.py @@ -43,7 +43,8 @@ class FreqaiExampleStrategy(IStrategy): process_only_new_candles = True stoploss = -0.05 use_exit_signal = True - startup_candle_count: int = 300 + # this is the maximum period fed to talib (timeframe independent) + startup_candle_count: int = 20 can_short = False linear_roi_offset = DecimalParameter( diff --git a/tests/freqai/conftest.py b/tests/freqai/conftest.py index 6ace13677..113cb3a79 100644 --- a/tests/freqai/conftest.py +++ b/tests/freqai/conftest.py @@ -44,7 +44,6 @@ def freqai_conf(default_conf, tmpdir): "principal_component_analysis": False, "use_SVM_to_remove_outliers": True, "stratify_training_data": 0, - "indicator_max_period_candles": 10, "indicator_periods_candles": [10], }, "data_split_parameters": {"test_size": 0.33, "random_state": 1}, diff --git a/tests/freqai/test_freqai_backtesting.py b/tests/freqai/test_freqai_backtesting.py index 273791609..c8a51edb0 100644 --- a/tests/freqai/test_freqai_backtesting.py +++ b/tests/freqai/test_freqai_backtesting.py @@ -48,10 +48,10 @@ def test_freqai_backtest_load_data(freqai_conf, mocker, caplog): assert log_has_re('Increasing startup_candle_count for freqai to.*', caplog) - del freqai_conf['freqai']['startup_candles'] - backtesting = Backtesting(freqai_conf) - with pytest.raises(OperationalException, - match=r'FreqAI backtesting module.*startup_candles in config.'): - backtesting.load_bt_data() + # del freqai_conf['freqai']['startup_candles'] + # backtesting = Backtesting(freqai_conf) + # with pytest.raises(OperationalException, + # match=r'FreqAI backtesting module.*startup_candles in config.'): + # backtesting.load_bt_data() Backtesting.cleanup() From 4b7e640f31f2a35ba3b73a3bfbbfb2882ecb7a81 Mon Sep 17 00:00:00 2001 From: robcaulk Date: Fri, 26 Aug 2022 13:56:44 +0200 Subject: [PATCH 05/65] reduce code duplication, optimize auto data download per tf --- freqtrade/data/dataprovider.py | 26 ++++++------ freqtrade/freqai/data_kitchen.py | 69 +++++++++++-------------------- freqtrade/optimize/backtesting.py | 26 +----------- freqtrade/strategy/interface.py | 7 ++-- 4 files changed, 42 insertions(+), 86 deletions(-) diff --git a/freqtrade/data/dataprovider.py b/freqtrade/data/dataprovider.py index 529a12690..a21114901 100644 --- a/freqtrade/data/dataprovider.py +++ b/freqtrade/data/dataprovider.py @@ -91,9 +91,9 @@ class DataProvider: timerange = TimeRange.parse_timerange(None if self._config.get( 'timerange') is None else str(self._config.get('timerange'))) # Move informative start time respecting startup_candle_count - timerange.subtract_start( - self.get_required_startup_seconds(str(timeframe)) - ) + startup_candles = self.get_required_startup(str(timeframe)) + tf_seconds = timeframe_to_seconds(str(timeframe)) + timerange.subtract_start(tf_seconds * startup_candles) self.__cached_pairs_backtesting[saved_pair] = load_pair_history( pair=pair, timeframe=timeframe or self._config['timeframe'], @@ -105,16 +105,18 @@ class DataProvider: ) return self.__cached_pairs_backtesting[saved_pair].copy() - def get_required_startup_seconds(self, timeframe: str) -> int: - tf_seconds = timeframe_to_seconds(timeframe) - base_seconds = tf_seconds * self._config.get('startup_candle_count', 0) - if not self._config['freqai']['enabled']: - return base_seconds + def get_required_startup(self, timeframe: str) -> int: + if not self._config.get('freqai', {}).get('enabled', False): + return self._config.get('startup_candle_count', 0) else: - train_seconds = self._config['freqai']['train_period_days'] * 86400 - # multiplied by safety factor of 2 because FreqAI users - # typically do not know the correct window. - return base_seconds * 2 + int(train_seconds) + if not self._config['startup_candle_count']: + raise OperationalException('FreqAI backtesting module requires strategy ' + 'set startup_candle_count.') + tf_seconds = timeframe_to_seconds(timeframe) + train_candles = self._config['freqai']['train_period_days'] * 86400 / tf_seconds + total_candles = int(self._config.get('startup_candle_count', 0) + train_candles) + logger.info(f'Increasing startup_candle_count for freqai to {total_candles}') + return total_candles def get_pair_dataframe( self, diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index c768fc30e..1a8063add 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -1006,8 +1006,7 @@ class FreqaiDataKitchen: # Methods called by interface.py (load_freqai_model()) -def download_all_data_for_training(timerange: TimeRange, - dp: DataProvider, config: dict) -> None: +def download_all_data_for_training(dp: DataProvider, config: dict) -> None: """ Called only once upon start of bot to download the necessary data for populating indicators and training the model. @@ -1025,51 +1024,31 @@ def download_all_data_for_training(timerange: TimeRange, all_pairs = dynamic_expand_pairlist(config, markets) - new_pairs_days = int((timerange.stopts - timerange.startts) / SECONDS_IN_DAY) if not dp._exchange: # Not realistic - this is only called in live mode. raise OperationalException("Dataprovider did not have an exchange attached.") - refresh_backtest_ohlcv_data( - dp._exchange, - pairs=all_pairs, - timeframes=config["freqai"]["feature_parameters"].get("include_timeframes"), - datadir=config["datadir"], - timerange=timerange, - new_pairs_days=new_pairs_days, - erase=False, - data_format=config.get("dataformat_ohlcv", "json"), - trading_mode=config.get("trading_mode", "spot"), - prepend=config.get("prepend_data", False), - ) - - -def get_required_data_timerange( - config: dict -) -> TimeRange: - """ - Used by interface.py to pre-download necessary data for FreqAI - user. - """ - time = datetime.datetime.now(tz=datetime.timezone.utc).timestamp() - data_load_timerange = TimeRange() - - timeframes = config["freqai"]["feature_parameters"].get("include_timeframes") - - max_tf_seconds = 0 - for tf in timeframes: - secs = timeframe_to_seconds(tf) - if secs > max_tf_seconds: - max_tf_seconds = secs - max_period = config.get('startup_candle_count', 20) * 2 - - additional_seconds = max_period * max_tf_seconds - - data_load_timerange.startts = int( - time - - config["freqai"].get("train_period_days", 0) * SECONDS_IN_DAY - - additional_seconds - ) - data_load_timerange.stopts = int(time) + time = datetime.datetime.now(tz=datetime.timezone.utc).timestamp() - return data_load_timerange + for tf in config["freqai"]["feature_parameters"].get("include_timeframes"): + timerange = TimeRange() + timerange.startts = int(time) + timerange.stopts = int(time) + startup_candles = dp.get_required_startup(str(tf)) + tf_seconds = timeframe_to_seconds(str(tf)) + timerange.subtract_start(tf_seconds * startup_candles) + new_pairs_days = int((timerange.stopts - timerange.startts) / SECONDS_IN_DAY) + # FIXME: now that we are looping on `refresh_backtest_ohlcv_data`, the function + # redownloads the funding rate for each pair. + refresh_backtest_ohlcv_data( + dp._exchange, + pairs=all_pairs, + timeframes=[tf], + datadir=config["datadir"], + timerange=timerange, + new_pairs_days=new_pairs_days, + erase=False, + data_format=config.get("dataformat_ohlcv", "json"), + trading_mode=config.get("trading_mode", "spot"), + prepend=config.get("prepend_data", False), + ) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 8f0302ada..3d715c82d 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -211,21 +211,12 @@ class Backtesting: """ self.progress.init_step(BacktestState.DATALOAD, 1) - # if self.config.get('freqai', {}).get('enabled', False): - # startup_candles = int(self.config.get('freqai', {}).get('startup_candles', 0)) - # if not startup_candles: - # raise OperationalException('FreqAI backtesting module requires user set ' - # 'startup_candles in config.') - # self.required_startup += int(self.config.get('freqai', {}).get('startup_candles', 0)) - # logger.info(f'Increasing startup_candle_count for freqai to {self.required_startup}') - # self.config['startup_candle_count'] = self.required_startup - data = history.load_data( datadir=self.config['datadir'], pairs=self.pairlists.whitelist, timeframe=self.timeframe, timerange=self.timerange, - startup_candles=self.get_required_startup(self.timeframe), + startup_candles=self.dataprovider.get_required_startup(self.timeframe), fail_without_data=True, data_format=self.config.get('dataformat_ohlcv', 'json'), candle_type=self.config.get('candle_type_def', CandleType.SPOT) @@ -244,21 +235,6 @@ class Backtesting: self.progress.set_new_value(1) return data, self.timerange - def get_required_startup(self, timeframe: str) -> int: - if not self.config['freqai']['enabled']: - return self.required_startup - else: - if not self.config['startup_candle_count']: - raise OperationalException('FreqAI backtesting module requires strategy ' - 'set startup_candle_count.') - tf_seconds = timeframe_to_seconds(timeframe) - train_candles = self.config['freqai']['train_period_days'] * 86400 / tf_seconds - # multiplied by safety factor of 2 because FreqAI users - # typically do not know the correct window. - total_candles = self.required_startup * 2 + train_candles - logger.info(f'Increasing startup_candle_count for freqai to {total_candles}') - return total_candles - def load_bt_data_detail(self) -> None: """ Loads backtest detail data (smaller timeframe) if necessary. diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 284727d2b..9124a0427 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -148,8 +148,7 @@ class IStrategy(ABC, HyperStrategyMixin): def load_freqAI_model(self) -> None: if self.config.get('freqai', {}).get('enabled', False): # Import here to avoid importing this if freqAI is disabled - from freqtrade.freqai.data_kitchen import (download_all_data_for_training, - get_required_data_timerange) + from freqtrade.freqai.data_kitchen import (download_all_data_for_training) from freqtrade.resolvers.freqaimodel_resolver import FreqaiModelResolver self.freqai = FreqaiModelResolver.load_freqaimodel(self.config) self.freqai_info = self.config["freqai"] @@ -161,8 +160,8 @@ class IStrategy(ABC, HyperStrategyMixin): "corr_pairlist, this may take a while if you do not have the " "data saved" ) - data_load_timerange = get_required_data_timerange(self.config) - download_all_data_for_training(data_load_timerange, self.dp, self.config) + # data_load_timerange = get_required_data_timerange(self.config) + download_all_data_for_training(self.dp, self.config) else: # Gracious failures if freqAI is disabled but "start" is called. From 65b552e310fe751989e43848498e03157cc50232 Mon Sep 17 00:00:00 2001 From: robcaulk Date: Fri, 26 Aug 2022 15:30:01 +0200 Subject: [PATCH 06/65] make docs reflect reality, move download_all_data to new utils.py file, automatic startup_candle detection --- docs/freqai.md | 7 +++-- freqtrade/data/dataprovider.py | 14 +++++---- freqtrade/freqai/data_kitchen.py | 54 -------------------------------- freqtrade/strategy/interface.py | 2 +- 4 files changed, 14 insertions(+), 63 deletions(-) diff --git a/docs/freqai.md b/docs/freqai.md index f3c9021ed..bd746c984 100644 --- a/docs/freqai.md +++ b/docs/freqai.md @@ -113,7 +113,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `use_SVM_to_remove_outliers` | Ask FreqAI to train a support vector machine to detect and remove outliers from the training data set as well as from incoming data points.
**Datatype:** boolean. | `svm_params` | All parameters available in Sklearn's `SGDOneClassSVM()`. E.g. `nu` *Very* broadly, is the percentage of data points that should be considered outliers. `shuffle` is by default false to maintain reproducibility. But these and all others can be added/changed in this dictionary.
**Datatype:** dictionary. | `stratify_training_data` | This value is used to indicate the stratification of the data. e.g. 2 would set every 2nd data point into a separate dataset to be pulled from during training/testing.
**Datatype:** positive integer. -| `indicator_max_period_candles` | **Deprecated in favor of** strategy set `startup_candle_count`, however, both configuration parameters provide the same functionality; the maximum *period* used in `populate_any_indicators()` for indicator creation (timeframe independent). FreqAI uses this information in combination with the maximum timeframe to calculate how many data points it should download so that the first data point does not have a NaN
**Datatype:** positive integer. +| `indicator_max_period_candles` | **No longer used**. User must use the strategy set `startup_candle_count` which defines the maximum *period* used in `populate_any_indicators()` for indicator creation (timeframe independent). FreqAI uses this information in combination with the maximum timeframe to calculate how many data points it should download so that the first data point does not have a NaN
**Datatype:** positive integer. | `indicator_periods_candles` | A list of integers used to duplicate all indicators according to a set of periods and add them to the feature set.
**Datatype:** list of positive integers. | `use_DBSCAN_to_remove_outliers` | Inactive by default. If true, FreqAI clusters data using DBSCAN to identify and remove outliers from training and prediction data.
**Datatype:** float (fraction of 1). | | **Data split parameters** @@ -162,7 +162,6 @@ The user interface is isolated to the typical config file. A typical FreqAI conf "label_period_candles": 24, "include_shifted_candles": 2, "weight_factor": 0, - "indicator_max_period_candles": 20, "indicator_periods_candles": [10, 20] }, "data_split_parameters" : { @@ -387,6 +386,10 @@ The FreqAI strategy requires the user to include the following lines of code in ```python + # user should define the maximum startup candle count (the largest number of candles + # passed to any single indicator) + startup_candle_count: int = 20 + def informative_pairs(self): whitelist_pairs = self.dp.current_whitelist() corr_pairs = self.config["freqai"]["feature_parameters"]["include_corr_pairlist"] diff --git a/freqtrade/data/dataprovider.py b/freqtrade/data/dataprovider.py index a21114901..4151b7419 100644 --- a/freqtrade/data/dataprovider.py +++ b/freqtrade/data/dataprovider.py @@ -106,15 +106,17 @@ class DataProvider: return self.__cached_pairs_backtesting[saved_pair].copy() def get_required_startup(self, timeframe: str) -> int: - if not self._config.get('freqai', {}).get('enabled', False): + freqai_config = self._config.get('freqai', {}) + if not freqai_config.get('enabled', False): return self._config.get('startup_candle_count', 0) else: - if not self._config['startup_candle_count']: - raise OperationalException('FreqAI backtesting module requires strategy ' - 'set startup_candle_count.') + startup_candles = self._config.get('startup_candle_count', 0) + indicator_periods = freqai_config['feature_parameters']['indicator_periods_candles'] + # make sure the startupcandles is at least the set maximum indicator periods + self._config['startup_candle_count'] = max(startup_candles, max(indicator_periods)) tf_seconds = timeframe_to_seconds(timeframe) - train_candles = self._config['freqai']['train_period_days'] * 86400 / tf_seconds - total_candles = int(self._config.get('startup_candle_count', 0) + train_candles) + train_candles = freqai_config['train_period_days'] * 86400 / tf_seconds + total_candles = int(self._config['startup_candle_count'] + train_candles) logger.info(f'Increasing startup_candle_count for freqai to {total_candles}') return total_candles diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index 1a8063add..1b88405c1 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -16,12 +16,8 @@ from sklearn.model_selection import train_test_split from sklearn.neighbors import NearestNeighbors from freqtrade.configuration import TimeRange -from freqtrade.data.dataprovider import DataProvider -from freqtrade.data.history.history_utils import refresh_backtest_ohlcv_data from freqtrade.exceptions import OperationalException from freqtrade.exchange import timeframe_to_seconds -from freqtrade.exchange.exchange import market_is_active -from freqtrade.plugins.pairlist.pairlist_helpers import dynamic_expand_pairlist from freqtrade.strategy.interface import IStrategy @@ -1002,53 +998,3 @@ class FreqaiDataKitchen: if self.unique_classes: for label in self.unique_classes: self.unique_class_list += list(self.unique_classes[label]) - -# Methods called by interface.py (load_freqai_model()) - - -def download_all_data_for_training(dp: DataProvider, config: dict) -> None: - """ - Called only once upon start of bot to download the necessary data for - populating indicators and training the model. - :param timerange: TimeRange = The full data timerange for populating the indicators - and training the model. - :param dp: DataProvider instance attached to the strategy - """ - - if dp._exchange is not None: - markets = [p for p, m in dp._exchange.markets.items() if market_is_active(m) - or config.get('include_inactive')] - else: - # This should not occur: - raise OperationalException('No exchange object found.') - - all_pairs = dynamic_expand_pairlist(config, markets) - - if not dp._exchange: - # Not realistic - this is only called in live mode. - raise OperationalException("Dataprovider did not have an exchange attached.") - - time = datetime.datetime.now(tz=datetime.timezone.utc).timestamp() - - for tf in config["freqai"]["feature_parameters"].get("include_timeframes"): - timerange = TimeRange() - timerange.startts = int(time) - timerange.stopts = int(time) - startup_candles = dp.get_required_startup(str(tf)) - tf_seconds = timeframe_to_seconds(str(tf)) - timerange.subtract_start(tf_seconds * startup_candles) - new_pairs_days = int((timerange.stopts - timerange.startts) / SECONDS_IN_DAY) - # FIXME: now that we are looping on `refresh_backtest_ohlcv_data`, the function - # redownloads the funding rate for each pair. - refresh_backtest_ohlcv_data( - dp._exchange, - pairs=all_pairs, - timeframes=[tf], - datadir=config["datadir"], - timerange=timerange, - new_pairs_days=new_pairs_days, - erase=False, - data_format=config.get("dataformat_ohlcv", "json"), - trading_mode=config.get("trading_mode", "spot"), - prepend=config.get("prepend_data", False), - ) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 9124a0427..c9ec466de 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -148,7 +148,7 @@ class IStrategy(ABC, HyperStrategyMixin): def load_freqAI_model(self) -> None: if self.config.get('freqai', {}).get('enabled', False): # Import here to avoid importing this if freqAI is disabled - from freqtrade.freqai.data_kitchen import (download_all_data_for_training) + from freqtrade.freqai.utils import download_all_data_for_training from freqtrade.resolvers.freqaimodel_resolver import FreqaiModelResolver self.freqai = FreqaiModelResolver.load_freqaimodel(self.config) self.freqai_info = self.config["freqai"] From e7261cf51577dc30b530370f81df620c898f6a11 Mon Sep 17 00:00:00 2001 From: robcaulk Date: Fri, 26 Aug 2022 15:30:28 +0200 Subject: [PATCH 07/65] add freqai utils.py file --- freqtrade/freqai/utils.py | 56 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 freqtrade/freqai/utils.py diff --git a/freqtrade/freqai/utils.py b/freqtrade/freqai/utils.py new file mode 100644 index 000000000..056458115 --- /dev/null +++ b/freqtrade/freqai/utils.py @@ -0,0 +1,56 @@ +from freqtrade.data.dataprovider import DataProvider +from freqtrade.plugins.pairlist.pairlist_helpers import dynamic_expand_pairlist +from freqtrade.exchange.exchange import market_is_active +from freqtrade.exchange import timeframe_to_seconds +from freqtrade.data.history.history_utils import refresh_backtest_ohlcv_data +from datetime import datetime, timezone +from freqtrade.exceptions import OperationalException +from freqtrade.configuration import TimeRange + + +def download_all_data_for_training(dp: DataProvider, config: dict) -> None: + """ + Called only once upon start of bot to download the necessary data for + populating indicators and training a FreqAI model. + :param timerange: TimeRange = The full data timerange for populating the indicators + and training the model. + :param dp: DataProvider instance attached to the strategy + """ + + if dp._exchange is not None: + markets = [p for p, m in dp._exchange.markets.items() if market_is_active(m) + or config.get('include_inactive')] + else: + # This should not occur: + raise OperationalException('No exchange object found.') + + all_pairs = dynamic_expand_pairlist(config, markets) + + if not dp._exchange: + # Not realistic - this is only called in live mode. + raise OperationalException("Dataprovider did not have an exchange attached.") + + time = datetime.now(tz=timezone.utc).timestamp() + + for tf in config["freqai"]["feature_parameters"].get("include_timeframes"): + timerange = TimeRange() + timerange.startts = int(time) + timerange.stopts = int(time) + startup_candles = dp.get_required_startup(str(tf)) + tf_seconds = timeframe_to_seconds(str(tf)) + timerange.subtract_start(tf_seconds * startup_candles) + new_pairs_days = int((timerange.stopts - timerange.startts) / 86400) + # FIXME: now that we are looping on `refresh_backtest_ohlcv_data`, the function + # redownloads the funding rate for each pair. + refresh_backtest_ohlcv_data( + dp._exchange, + pairs=all_pairs, + timeframes=[tf], + datadir=config["datadir"], + timerange=timerange, + new_pairs_days=new_pairs_days, + erase=False, + data_format=config.get("dataformat_ohlcv", "json"), + trading_mode=config.get("trading_mode", "spot"), + prepend=config.get("prepend_data", False), + ) From bb3523f3838686f92420b27e58cc1b5a37df6b9e Mon Sep 17 00:00:00 2001 From: robcaulk Date: Fri, 26 Aug 2022 18:51:42 +0200 Subject: [PATCH 08/65] download data homogeneously across timeframes --- freqtrade/freqai/utils.py | 138 +++++++++++++++++++++++++------- freqtrade/strategy/interface.py | 6 +- 2 files changed, 112 insertions(+), 32 deletions(-) diff --git a/freqtrade/freqai/utils.py b/freqtrade/freqai/utils.py index 056458115..d56702049 100644 --- a/freqtrade/freqai/utils.py +++ b/freqtrade/freqai/utils.py @@ -1,17 +1,22 @@ +import logging +from datetime import datetime, timezone + +from freqtrade.configuration import TimeRange from freqtrade.data.dataprovider import DataProvider -from freqtrade.plugins.pairlist.pairlist_helpers import dynamic_expand_pairlist -from freqtrade.exchange.exchange import market_is_active -from freqtrade.exchange import timeframe_to_seconds from freqtrade.data.history.history_utils import refresh_backtest_ohlcv_data -from datetime import datetime, timezone from freqtrade.exceptions import OperationalException -from freqtrade.configuration import TimeRange +from freqtrade.exchange import timeframe_to_seconds +from freqtrade.exchange.exchange import market_is_active +from freqtrade.plugins.pairlist.pairlist_helpers import dynamic_expand_pairlist + + +logger = logging.getLogger(__name__) def download_all_data_for_training(dp: DataProvider, config: dict) -> None: """ Called only once upon start of bot to download the necessary data for - populating indicators and training a FreqAI model. + populating indicators and training the model. :param timerange: TimeRange = The full data timerange for populating the indicators and training the model. :param dp: DataProvider instance attached to the strategy @@ -26,31 +31,108 @@ def download_all_data_for_training(dp: DataProvider, config: dict) -> None: all_pairs = dynamic_expand_pairlist(config, markets) + timerange = get_required_data_timerange(config) + + new_pairs_days = int((timerange.stopts - timerange.startts) / 86400) if not dp._exchange: # Not realistic - this is only called in live mode. raise OperationalException("Dataprovider did not have an exchange attached.") + refresh_backtest_ohlcv_data( + dp._exchange, + pairs=all_pairs, + timeframes=config["freqai"]["feature_parameters"].get("include_timeframes"), + datadir=config["datadir"], + timerange=timerange, + new_pairs_days=new_pairs_days, + erase=False, + data_format=config.get("dataformat_ohlcv", "json"), + trading_mode=config.get("trading_mode", "spot"), + prepend=config.get("prepend_data", False), + ) + +def get_required_data_timerange( + config: dict +) -> TimeRange: + """ + Used to compute the required data download time range + for auto data-download in FreqAI + """ time = datetime.now(tz=timezone.utc).timestamp() + data_load_timerange = TimeRange() + + timeframes = config["freqai"]["feature_parameters"].get("include_timeframes") + + max_tf_seconds = 0 + for tf in timeframes: + secs = timeframe_to_seconds(tf) + if secs > max_tf_seconds: + max_tf_seconds = secs + + startup_candles = config.get('startup_candle_count', 0) + indicator_periods = config["freqai"]["feature_parameters"]["indicator_periods_candles"] + + # factor the max_period as a factor of safety. + max_period = int(max(startup_candles, max(indicator_periods)) * 1.5) + config['startup_candle_count'] = max_period + logger.info(f'FreqAI auto-downloader using {max_period} startup candles.') + + additional_seconds = max_period * max_tf_seconds + + data_load_timerange.startts = int( + time + - config["freqai"].get("train_period_days", 0) * 86400 + - additional_seconds + ) + data_load_timerange.stopts = int(time) + + return data_load_timerange + + +# Keep below for when we wish to download heterogeneously lengthed data for FreqAI. +# def download_all_data_for_training(dp: DataProvider, config: dict) -> None: +# """ +# Called only once upon start of bot to download the necessary data for +# populating indicators and training a FreqAI model. +# :param timerange: TimeRange = The full data timerange for populating the indicators +# and training the model. +# :param dp: DataProvider instance attached to the strategy +# """ + +# if dp._exchange is not None: +# markets = [p for p, m in dp._exchange.markets.items() if market_is_active(m) +# or config.get('include_inactive')] +# else: +# # This should not occur: +# raise OperationalException('No exchange object found.') + +# all_pairs = dynamic_expand_pairlist(config, markets) + +# if not dp._exchange: +# # Not realistic - this is only called in live mode. +# raise OperationalException("Dataprovider did not have an exchange attached.") + +# time = datetime.now(tz=timezone.utc).timestamp() - for tf in config["freqai"]["feature_parameters"].get("include_timeframes"): - timerange = TimeRange() - timerange.startts = int(time) - timerange.stopts = int(time) - startup_candles = dp.get_required_startup(str(tf)) - tf_seconds = timeframe_to_seconds(str(tf)) - timerange.subtract_start(tf_seconds * startup_candles) - new_pairs_days = int((timerange.stopts - timerange.startts) / 86400) - # FIXME: now that we are looping on `refresh_backtest_ohlcv_data`, the function - # redownloads the funding rate for each pair. - refresh_backtest_ohlcv_data( - dp._exchange, - pairs=all_pairs, - timeframes=[tf], - datadir=config["datadir"], - timerange=timerange, - new_pairs_days=new_pairs_days, - erase=False, - data_format=config.get("dataformat_ohlcv", "json"), - trading_mode=config.get("trading_mode", "spot"), - prepend=config.get("prepend_data", False), - ) +# for tf in config["freqai"]["feature_parameters"].get("include_timeframes"): +# timerange = TimeRange() +# timerange.startts = int(time) +# timerange.stopts = int(time) +# startup_candles = dp.get_required_startup(str(tf)) +# tf_seconds = timeframe_to_seconds(str(tf)) +# timerange.subtract_start(tf_seconds * startup_candles) +# new_pairs_days = int((timerange.stopts - timerange.startts) / 86400) +# # FIXME: now that we are looping on `refresh_backtest_ohlcv_data`, the function +# # redownloads the funding rate for each pair. +# refresh_backtest_ohlcv_data( +# dp._exchange, +# pairs=all_pairs, +# timeframes=[tf], +# datadir=config["datadir"], +# timerange=timerange, +# new_pairs_days=new_pairs_days, +# erase=False, +# data_format=config.get("dataformat_ohlcv", "json"), +# trading_mode=config.get("trading_mode", "spot"), +# prepend=config.get("prepend_data", False), +# ) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index c9ec466de..3ea1a3fae 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -157,12 +157,10 @@ class IStrategy(ABC, HyperStrategyMixin): if self.config.get('runmode') in (RunMode.DRY_RUN, RunMode.LIVE): logger.info( "Downloading all training data for all pairs in whitelist and " - "corr_pairlist, this may take a while if you do not have the " - "data saved" + "corr_pairlist, this may take a while if the data is not " + "already on disk." ) - # data_load_timerange = get_required_data_timerange(self.config) download_all_data_for_training(self.dp, self.config) - else: # Gracious failures if freqAI is disabled but "start" is called. class DummyClass(): From c9aa09ec89d37d6f8fcea4c9f15c092021a82a93 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 30 Aug 2022 20:46:06 +0200 Subject: [PATCH 09/65] Simplify base fee handling --- freqtrade/freqtradebot.py | 32 ++++++++++------------ tests/test_freqtradebot.py | 56 ++++++++++++++++++++------------------ 2 files changed, 43 insertions(+), 45 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index ea9221213..5393e3d39 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1778,7 +1778,7 @@ class FreqtradeBot(LoggingMixin): self.rpc.send_msg(msg) def apply_fee_conditional(self, trade: Trade, trade_base_currency: str, - amount: float, fee_abs: float) -> float: + amount: float, fee_abs: float) -> Optional[float]: """ Applies the fee to amount (either from Order or from Trades). Can eat into dust if more than the required asset is available. @@ -1791,35 +1791,32 @@ class FreqtradeBot(LoggingMixin): logger.info(f"Fee amount for {trade} was in base currency - " f"Eating Fee {fee_abs} into dust.") elif fee_abs != 0: - real_amount = self.exchange.amount_to_precision(trade.pair, amount - fee_abs) - logger.info(f"Applying fee on amount for {trade} " - f"(from {amount} to {real_amount}).") - return real_amount - return amount + logger.info(f"Applying fee on amount for {trade}, fee={fee_abs}.") + return fee_abs + return None def handle_order_fee(self, trade: Trade, order_obj: Order, order: Dict[str, Any]) -> None: # Try update amount (binance-fix) try: - new_amount = self.get_real_amount(trade, order, order_obj) - if not isclose(safe_value_fallback(order, 'filled', 'amount'), new_amount, - abs_tol=constants.MATH_CLOSE_PREC): - order_obj.ft_fee_base = trade.amount - new_amount + fee_abs = self.get_real_amount(trade, order, order_obj) + if fee_abs is not None: + order_obj.ft_fee_base = fee_abs except DependencyException as exception: logger.warning("Could not update trade amount: %s", exception) - def get_real_amount(self, trade: Trade, order: Dict, order_obj: Order) -> float: + def get_real_amount(self, trade: Trade, order: Dict, order_obj: Order) -> Optional[float]: """ Detect and update trade fee. Calls trade.update_fee() upon correct detection. Returns modified amount if the fee was taken from the destination currency. Necessary for exchanges which charge fees in base currency (e.g. binance) - :return: identical (or new) amount for the trade + :return: Absolute fee to apply for this order or None """ # Init variables order_amount = safe_value_fallback(order, 'filled', 'amount') # Only run for closed orders if trade.fee_updated(order.get('side', '')) or order['status'] == 'open': - return order_amount + return None trade_base_currency = self.exchange.get_pair_base_currency(trade.pair) # use fee from order-dict if possible @@ -1837,12 +1834,12 @@ class FreqtradeBot(LoggingMixin): # Apply fee to amount return self.apply_fee_conditional(trade, trade_base_currency, amount=order_amount, fee_abs=fee_cost) - return order_amount + return None return self.fee_detection_from_trades( trade, order, order_obj, order_amount, order.get('trades', [])) def fee_detection_from_trades(self, trade: Trade, order: Dict, order_obj: Order, - order_amount: float, trades: List) -> float: + order_amount: float, trades: List) -> Optional[float]: """ fee-detection fallback to Trades. Either uses provided trades list or the result of fetch_my_trades to get correct fee. @@ -1853,7 +1850,7 @@ class FreqtradeBot(LoggingMixin): if len(trades) == 0: logger.info("Applying fee on amount for %s failed: myTrade-Dict empty found", trade) - return order_amount + return None fee_currency = None amount = 0 fee_abs = 0.0 @@ -1897,8 +1894,7 @@ class FreqtradeBot(LoggingMixin): if fee_abs != 0: return self.apply_fee_conditional(trade, trade_base_currency, amount=amount, fee_abs=fee_abs) - else: - return amount + return None def get_valid_price(self, custom_price: float, proposed_price: float) -> float: """ diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 138527053..902343c1e 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1927,8 +1927,7 @@ def test_update_trade_state(mocker, default_conf_usdt, limit_order, is_short, ca mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_trade', MagicMock(return_value=True)) mocker.patch('freqtrade.exchange.Exchange.fetch_order', return_value=order) mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[]) - mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount', - return_value=order['amount']) + mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount', return_value=0.0) order_id = order['id'] trade = Trade( @@ -1960,11 +1959,11 @@ def test_update_trade_state(mocker, default_conf_usdt, limit_order, is_short, ca assert trade.amount == order['amount'] trade.open_order_id = order_id - mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount', return_value=90.81) - assert trade.amount != 90.81 + mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount', return_value=0.01) + assert trade.amount == 30.0 # test amount modified by fee-logic freqtrade.update_trade_state(trade, order_id) - assert trade.amount == 90.81 + assert trade.amount == 29.99 assert trade.open_order_id is None trade.is_open = True @@ -4268,10 +4267,10 @@ def test_get_real_amount_quote(default_conf_usdt, trades_for_order, buy_order_fe caplog.clear() order_obj = Order.parse_from_ccxt_object(buy_order_fee, 'LTC/ETH', 'buy') # Amount is reduced by "fee" - assert freqtrade.get_real_amount(trade, buy_order_fee, order_obj) == amount - (amount * 0.001) + assert freqtrade.get_real_amount(trade, buy_order_fee, order_obj) == (amount * 0.001) assert log_has( 'Applying fee on amount for Trade(id=None, pair=LTC/ETH, amount=8.00000000, is_short=False,' - ' leverage=1.0, open_rate=0.24544100, open_since=closed) (from 8.0 to 7.992).', + ' leverage=1.0, open_rate=0.24544100, open_since=closed), fee=0.008.', caplog ) @@ -4296,7 +4295,7 @@ def test_get_real_amount_quote_dust(default_conf_usdt, trades_for_order, buy_ord walletmock.reset_mock() order_obj = Order.parse_from_ccxt_object(buy_order_fee, 'LTC/ETH', 'buy') # Amount is kept as is - assert freqtrade.get_real_amount(trade, buy_order_fee, order_obj) == amount + assert freqtrade.get_real_amount(trade, buy_order_fee, order_obj) is None assert walletmock.call_count == 1 assert log_has_re(r'Fee amount for Trade.* was in base currency ' '- Eating Fee 0.008 into dust', caplog) @@ -4319,7 +4318,7 @@ def test_get_real_amount_no_trade(default_conf_usdt, buy_order_fee, caplog, mock order_obj = Order.parse_from_ccxt_object(buy_order_fee, 'LTC/ETH', 'buy') # Amount is reduced by "fee" - assert freqtrade.get_real_amount(trade, buy_order_fee, order_obj) == amount + assert freqtrade.get_real_amount(trade, buy_order_fee, order_obj) is None assert log_has( 'Applying fee on amount for Trade(id=None, pair=LTC/ETH, amount=8.00000000, ' 'is_short=False, leverage=1.0, open_rate=0.24544100, open_since=closed) failed: ' @@ -4343,8 +4342,7 @@ def test_get_real_amount_no_trade(default_conf_usdt, buy_order_fee, caplog, mock # from order ({'cost': 0.004, 'currency': 'LTC'}, 0.004, False, ( 'Applying fee on amount for Trade(id=None, pair=LTC/ETH, amount=8.00000000, ' - 'is_short=False, leverage=1.0, open_rate=0.24544100, open_since=closed) (from' - ' 8.0 to 7.996).' + 'is_short=False, leverage=1.0, open_rate=0.24544100, open_since=closed), fee=0.004.' )), # invalid, no currency in from fee dict ({'cost': 0.008, 'currency': None}, 0, True, None), @@ -4376,7 +4374,11 @@ def test_get_real_amount( caplog.clear() order_obj = Order.parse_from_ccxt_object(buy_order_fee, 'LTC/ETH', 'buy') - assert freqtrade.get_real_amount(trade, buy_order, order_obj) == amount - fee_reduction_amount + res = freqtrade.get_real_amount(trade, buy_order, order_obj) + if fee_reduction_amount == 0: + assert res is None + else: + assert res == fee_reduction_amount if expected_log: assert log_has(expected_log, caplog) @@ -4422,14 +4424,14 @@ def test_get_real_amount_multi( return_value={'ask': 0.19, 'last': 0.2}) # Amount is reduced by "fee" - expected_amount = amount - (amount * fee_reduction_amount) + expected_amount = amount * fee_reduction_amount order_obj = Order.parse_from_ccxt_object(buy_order_fee, 'LTC/ETH', 'buy') assert freqtrade.get_real_amount(trade, buy_order_fee, order_obj) == expected_amount assert log_has( ( 'Applying fee on amount for Trade(id=None, pair=LTC/ETH, amount=8.00000000, ' - 'is_short=False, leverage=1.0, open_rate=0.24544100, open_since=closed) ' - f'(from 8.0 to {expected_log_amount}).' + 'is_short=False, leverage=1.0, open_rate=0.24544100, open_since=closed), ' + f'fee={expected_amount}.' ), caplog ) @@ -4462,7 +4464,7 @@ def test_get_real_amount_invalid_order(default_conf_usdt, trades_for_order, buy_ order_obj = Order.parse_from_ccxt_object(buy_order_fee, 'LTC/ETH', 'buy') # Amount does not change - assert freqtrade.get_real_amount(trade, limit_buy_order_usdt, order_obj) == amount + assert freqtrade.get_real_amount(trade, limit_buy_order_usdt, order_obj) is None def test_get_real_amount_fees_order(default_conf_usdt, market_buy_order_usdt_doublefee, @@ -4485,7 +4487,7 @@ def test_get_real_amount_fees_order(default_conf_usdt, market_buy_order_usdt_dou # Amount does not change assert trade.fee_open == 0.0025 order_obj = Order.parse_from_ccxt_object(market_buy_order_usdt_doublefee, 'LTC/ETH', 'buy') - assert freqtrade.get_real_amount(trade, market_buy_order_usdt_doublefee, order_obj) == 30.0 + assert freqtrade.get_real_amount(trade, market_buy_order_usdt_doublefee, order_obj) is None assert tfo_mock.call_count == 0 # Fetch fees from trades dict if available to get "proper" values assert round(trade.fee_open, 4) == 0.001 @@ -4537,7 +4539,7 @@ def test_get_real_amount_wrong_amount_rounding(default_conf_usdt, trades_for_ord order_obj = Order.parse_from_ccxt_object(buy_order_fee, 'LTC/ETH', 'buy') # Amount changes by fee amount. assert pytest.approx(freqtrade.get_real_amount( - trade, limit_buy_order_usdt, order_obj)) == amount - (amount * 0.001) + trade, limit_buy_order_usdt, order_obj)) == (amount * 0.001) def test_get_real_amount_open_trade_usdt(default_conf_usdt, fee, mocker): @@ -4559,7 +4561,7 @@ def test_get_real_amount_open_trade_usdt(default_conf_usdt, fee, mocker): } freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt) order_obj = Order.parse_from_ccxt_object(order, 'LTC/ETH', 'buy') - assert freqtrade.get_real_amount(trade, order, order_obj) == amount + assert freqtrade.get_real_amount(trade, order, order_obj) is None def test_get_real_amount_in_point(default_conf_usdt, buy_order_fee, fee, mocker, caplog): @@ -4616,7 +4618,7 @@ def test_get_real_amount_in_point(default_conf_usdt, buy_order_fee, fee, mocker, order_obj = Order.parse_from_ccxt_object(buy_order_fee, 'LTC/ETH', 'buy') res = freqtrade.get_real_amount(trade, limit_buy_order_usdt, order_obj) - assert res == amount + assert res is None assert trade.fee_open_currency is None assert trade.fee_open_cost is None message = "Not updating buy-fee - rate: None, POINT." @@ -4624,7 +4626,7 @@ def test_get_real_amount_in_point(default_conf_usdt, buy_order_fee, fee, mocker, caplog.clear() freqtrade.config['exchange']['unknown_fee_rate'] = 1 res = freqtrade.get_real_amount(trade, limit_buy_order_usdt, order_obj) - assert res == amount + assert res is None assert trade.fee_open_currency == 'POINT' assert pytest.approx(trade.fee_open_cost) == 0.3046651026 assert trade.fee_open == 0.002 @@ -4633,12 +4635,12 @@ def test_get_real_amount_in_point(default_conf_usdt, buy_order_fee, fee, mocker, @pytest.mark.parametrize('amount,fee_abs,wallet,amount_exp', [ - (8.0, 0.0, 10, 8), - (8.0, 0.0, 0, 8), - (8.0, 0.1, 0, 7.9), - (8.0, 0.1, 10, 8), - (8.0, 0.1, 8.0, 8.0), - (8.0, 0.1, 7.9, 7.9), + (8.0, 0.0, 10, None), + (8.0, 0.0, 0, None), + (8.0, 0.1, 0, 0.1), + (8.0, 0.1, 10, None), + (8.0, 0.1, 8.0, None), + (8.0, 0.1, 7.9, 0.1), ]) def test_apply_fee_conditional(default_conf_usdt, fee, mocker, amount, fee_abs, wallet, amount_exp): From 10e0d538603338d0df0ffc57fa27b93c04647a19 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 30 Aug 2022 20:49:53 +0200 Subject: [PATCH 10/65] Simplify 2 more tests --- tests/test_freqtradebot.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 902343c1e..e6c6e7978 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1051,8 +1051,6 @@ def test_add_stoploss_on_exchange(mocker, default_conf_usdt, limit_order, is_sho mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_trade', MagicMock(return_value=True)) mocker.patch('freqtrade.exchange.Exchange.fetch_order', return_value=order) mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[]) - mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount', - return_value=order['amount']) stoploss = MagicMock(return_value={'id': 13434334}) mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss) @@ -1875,8 +1873,6 @@ def test_exit_positions(mocker, default_conf_usdt, limit_order, is_short, caplog mocker.patch('freqtrade.exchange.Exchange.fetch_order', return_value=limit_order[entry_side(is_short)]) mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[]) - mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount', - return_value=limit_order[entry_side(is_short)]['amount']) trade = MagicMock() trade.is_short = is_short @@ -1886,14 +1882,13 @@ def test_exit_positions(mocker, default_conf_usdt, limit_order, is_short, caplog n = freqtrade.exit_positions(trades) assert n == 0 # Test amount not modified by fee-logic - assert not log_has( - 'Applying fee to amount for Trade {} from 30.0 to 90.81'.format(trade), caplog - ) + assert not log_has_re(r'Applying fee to amount for Trade .*', caplog) - mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount', return_value=90.81) + gra = mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount', return_value=0.0) # test amount modified by fee-logic n = freqtrade.exit_positions(trades) assert n == 0 + assert gra.call_count == 0 @pytest.mark.parametrize("is_short", [False, True]) From 4aec2db14dadb7e2fec6a6d883a6a7f3e48dd311 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 31 Aug 2022 08:18:28 +0000 Subject: [PATCH 11/65] Remove isClose from tests in favor of pytest.approx --- tests/data/test_btanalysis.py | 5 ++- tests/exchange/test_exchange.py | 45 ++++++++++++------------- tests/leverage/test_interest.py | 6 ++-- tests/strategy/test_strategy_helpers.py | 4 +-- tests/test_persistence.py | 7 ++-- 5 files changed, 30 insertions(+), 37 deletions(-) diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index 977140ebb..72084d067 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -1,4 +1,3 @@ -from math import isclose from pathlib import Path from unittest.mock import MagicMock @@ -269,7 +268,7 @@ def test_create_cum_profit(testdatadir): "cum_profits", timeframe="5m") assert "cum_profits" in cum_profits.columns assert cum_profits.iloc[0]['cum_profits'] == 0 - assert isclose(cum_profits.iloc[-1]['cum_profits'], 8.723007518796964e-06) + assert pytest.approx(cum_profits.iloc[-1]['cum_profits']) == 8.723007518796964e-06 def test_create_cum_profit1(testdatadir): @@ -287,7 +286,7 @@ def test_create_cum_profit1(testdatadir): "cum_profits", timeframe="5m") assert "cum_profits" in cum_profits.columns assert cum_profits.iloc[0]['cum_profits'] == 0 - assert isclose(cum_profits.iloc[-1]['cum_profits'], 8.723007518796964e-06) + assert pytest.approx(cum_profits.iloc[-1]['cum_profits']) == 8.723007518796964e-06 with pytest.raises(ValueError, match='Trade dataframe empty.'): create_cum_profit(df.set_index('date'), bt_data[bt_data["pair"] == 'NOTAPAIR'], diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 800aa5381..5456b3098 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -2,7 +2,6 @@ import copy import logging from copy import deepcopy from datetime import datetime, timedelta, timezone -from math import isclose from random import randint from unittest.mock import MagicMock, Mock, PropertyMock, patch @@ -407,10 +406,10 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None: # min result = exchange.get_min_pair_stake_amount('ETH/BTC', 1, stoploss) expected_result = 2 * (1 + 0.05) / (1 - abs(stoploss)) - assert isclose(result, expected_result) + assert pytest.approx(result) == expected_result # With Leverage result = exchange.get_min_pair_stake_amount('ETH/BTC', 1, stoploss, 3.0) - assert isclose(result, expected_result / 3) + assert pytest.approx(result) == expected_result / 3 # max result = exchange.get_max_pair_stake_amount('ETH/BTC', 2) assert result == 10000 @@ -426,10 +425,10 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None: ) result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss) expected_result = 2 * 2 * (1 + 0.05) / (1 - abs(stoploss)) - assert isclose(result, expected_result) + assert pytest.approx(result) == expected_result # With Leverage result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss, 5.0) - assert isclose(result, expected_result / 5) + assert pytest.approx(result) == expected_result / 5 # max result = exchange.get_max_pair_stake_amount('ETH/BTC', 2) assert result == 20000 @@ -445,10 +444,10 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None: ) result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss) expected_result = max(2, 2 * 2) * (1 + 0.05) / (1 - abs(stoploss)) - assert isclose(result, expected_result) + assert pytest.approx(result) == expected_result # With Leverage result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss, 10) - assert isclose(result, expected_result / 10) + assert pytest.approx(result) == expected_result / 10 # min amount and cost are set (amount is minial) markets["ETH/BTC"]["limits"] = { @@ -461,20 +460,20 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None: ) result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss) expected_result = max(8, 2 * 2) * (1 + 0.05) / (1 - abs(stoploss)) - assert isclose(result, expected_result) + assert pytest.approx(result) == expected_result # With Leverage result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss, 7.0) - assert isclose(result, expected_result / 7.0) + assert pytest.approx(result) == expected_result / 7.0 # Max result = exchange.get_max_pair_stake_amount('ETH/BTC', 2) assert result == 1000 result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -0.4) expected_result = max(8, 2 * 2) * 1.5 - assert isclose(result, expected_result) + assert pytest.approx(result) == expected_result # With Leverage result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -0.4, 8.0) - assert isclose(result, expected_result / 8.0) + assert pytest.approx(result) == expected_result / 8.0 # Max result = exchange.get_max_pair_stake_amount('ETH/BTC', 2) assert result == 1000 @@ -482,10 +481,10 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None: # Really big stoploss result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -1) expected_result = max(8, 2 * 2) * 1.5 - assert isclose(result, expected_result) + assert pytest.approx(result) == expected_result # With Leverage result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -1, 12.0) - assert isclose(result, expected_result / 12) + assert pytest.approx(result) == expected_result / 12 # Max result = exchange.get_max_pair_stake_amount('ETH/BTC', 2) assert result == 1000 @@ -501,7 +500,7 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None: # Contract size 0.01 result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -1) - assert isclose(result, expected_result * 0.01) + assert pytest.approx(result) == expected_result * 0.01 # Max result = exchange.get_max_pair_stake_amount('ETH/BTC', 2) assert result == 10 @@ -513,7 +512,7 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None: ) # With Leverage, Contract size 10 result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -1, 12.0) - assert isclose(result, (expected_result / 12) * 10.0) + assert pytest.approx(result) == (expected_result / 12) * 10.0 # Max result = exchange.get_max_pair_stake_amount('ETH/BTC', 2) assert result == 10000 @@ -3239,7 +3238,7 @@ def test_get_trades_for_order(default_conf, mocker, exchange_name, trading_mode, orders = exchange.get_trades_for_order(order_id, 'ETH/USDT:USDT', since) assert len(orders) == 1 assert orders[0]['price'] == 165 - assert isclose(orders[0]['amount'], amount) + assert pytest.approx(orders[0]['amount']) == amount assert api_mock.fetch_my_trades.call_count == 1 # since argument should be assert isinstance(api_mock.fetch_my_trades.call_args[0][1], int) @@ -3776,8 +3775,8 @@ def test__get_funding_fees_from_exchange(default_conf, mocker, exchange_name): since=unix_time ) - assert (isclose(expected_fees, fees_from_datetime)) - assert (isclose(expected_fees, fees_from_unix_time)) + assert pytest.approx(expected_fees) == fees_from_datetime + assert pytest.approx(expected_fees) == fees_from_unix_time ccxt_exceptionhandlers( mocker, @@ -4514,7 +4513,7 @@ def test_liquidation_price( default_conf['liquidation_buffer'] = 0.0 exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) exchange.get_maintenance_ratio_and_amt = MagicMock(return_value=(mm_ratio, maintenance_amt)) - assert isclose(round(exchange.get_liquidation_price( + assert pytest.approx(round(exchange.get_liquidation_price( pair='DOGE/USDT', open_rate=open_rate, is_short=is_short, @@ -4523,7 +4522,7 @@ def test_liquidation_price( upnl_ex_1=upnl_ex_1, amount=amount, stake_amount=open_rate * amount, - ), 2), expected) + ), 2)) == expected def test_get_max_pair_stake_amount( @@ -4868,8 +4867,8 @@ def test_get_max_leverage_futures(default_conf, mocker, leverage_tiers): assert exchange.get_max_leverage("BNB/BUSD", 1.0) == 20.0 assert exchange.get_max_leverage("BNB/USDT", 100.0) == 75.0 assert exchange.get_max_leverage("BTC/USDT", 170.30) == 125.0 - assert isclose(exchange.get_max_leverage("BNB/BUSD", 99999.9), 5.000005) - assert isclose(exchange.get_max_leverage("BNB/USDT", 1500), 33.333333333333333) + assert pytest.approx(exchange.get_max_leverage("BNB/BUSD", 99999.9)) == 5.000005 + assert pytest.approx(exchange.get_max_leverage("BNB/USDT", 1500)) == 33.333333333333333 assert exchange.get_max_leverage("BTC/USDT", 300000000) == 2.0 assert exchange.get_max_leverage("BTC/USDT", 600000000) == 1.0 # Last tier @@ -5145,7 +5144,7 @@ def test_get_liquidation_price( else: buffer_amount = liquidation_buffer * abs(open_rate - expected_liq) expected_liq = expected_liq - buffer_amount if is_short else expected_liq + buffer_amount - assert isclose(expected_liq, liq) + assert pytest.approx(expected_liq) == liq @pytest.mark.parametrize('contract_size,order_amount', [ diff --git a/tests/leverage/test_interest.py b/tests/leverage/test_interest.py index 7bdf4c2f0..64e99b6b4 100644 --- a/tests/leverage/test_interest.py +++ b/tests/leverage/test_interest.py @@ -1,5 +1,3 @@ -from math import isclose - import pytest from freqtrade.leverage import interest @@ -30,9 +28,9 @@ twentyfive_hours = FtPrecise(25.0) def test_interest(exchange, interest_rate, hours, expected): borrowed = FtPrecise(60.0) - assert isclose(interest( + assert pytest.approx(float(interest( exchange_name=exchange, borrowed=borrowed, rate=FtPrecise(interest_rate), hours=hours - ), expected) + ))) == expected diff --git a/tests/strategy/test_strategy_helpers.py b/tests/strategy/test_strategy_helpers.py index 244fd3919..a7c2da26a 100644 --- a/tests/strategy/test_strategy_helpers.py +++ b/tests/strategy/test_strategy_helpers.py @@ -1,5 +1,3 @@ -from math import isclose - import numpy as np import pandas as pd import pytest @@ -165,7 +163,7 @@ def test_stoploss_from_open(): or (side == 'short' and expected_stop_price < current_price)): assert stoploss == 0 else: - assert isclose(stop_price, expected_stop_price, rel_tol=0.00001) + assert pytest.approx(stop_price) == expected_stop_price def test_stoploss_from_absolute(): diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 2460fde68..f16c8b054 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -1,7 +1,6 @@ # pragma pylint: disable=missing-docstring, C0103 import logging from datetime import datetime, timedelta, timezone -from math import isclose from pathlib import Path from types import FunctionType from unittest.mock import MagicMock @@ -630,9 +629,9 @@ def test_calc_open_close_trade_price( trade.open_rate = 2.0 trade.close_rate = 2.2 trade.recalc_open_trade_value() - assert isclose(trade._calc_open_trade_value(trade.amount, trade.open_rate), open_value) - assert isclose(trade.calc_close_trade_value(trade.close_rate), close_value) - assert isclose(trade.calc_profit(trade.close_rate), round(profit, 8)) + assert pytest.approx(trade._calc_open_trade_value(trade.amount, trade.open_rate)) == open_value + assert pytest.approx(trade.calc_close_trade_value(trade.close_rate)) == close_value + assert pytest.approx(trade.calc_profit(trade.close_rate)) == round(profit, 8) assert pytest.approx(trade.calc_profit_ratio(trade.close_rate)) == profit_ratio From 7ba4fda5d7c4f472bb61bf03fe91e7f2b1564762 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 31 Aug 2022 10:26:47 +0000 Subject: [PATCH 12/65] Implement PR feedback --- freqtrade/freqai/utils.py | 12 ++++-------- tests/freqai/test_freqai_backtesting.py | 6 ------ 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/freqtrade/freqai/utils.py b/freqtrade/freqai/utils.py index d56702049..6081b6ce5 100644 --- a/freqtrade/freqai/utils.py +++ b/freqtrade/freqai/utils.py @@ -22,21 +22,17 @@ def download_all_data_for_training(dp: DataProvider, config: dict) -> None: :param dp: DataProvider instance attached to the strategy """ - if dp._exchange is not None: - markets = [p for p, m in dp._exchange.markets.items() if market_is_active(m) - or config.get('include_inactive')] - else: - # This should not occur: + if dp._exchange is None: raise OperationalException('No exchange object found.') + markets = [p for p, m in dp._exchange.markets.items() if market_is_active(m) + or config.get('include_inactive')] all_pairs = dynamic_expand_pairlist(config, markets) timerange = get_required_data_timerange(config) new_pairs_days = int((timerange.stopts - timerange.startts) / 86400) - if not dp._exchange: - # Not realistic - this is only called in live mode. - raise OperationalException("Dataprovider did not have an exchange attached.") + refresh_backtest_ohlcv_data( dp._exchange, pairs=all_pairs, diff --git a/tests/freqai/test_freqai_backtesting.py b/tests/freqai/test_freqai_backtesting.py index c8a51edb0..ea127fa99 100644 --- a/tests/freqai/test_freqai_backtesting.py +++ b/tests/freqai/test_freqai_backtesting.py @@ -48,10 +48,4 @@ def test_freqai_backtest_load_data(freqai_conf, mocker, caplog): assert log_has_re('Increasing startup_candle_count for freqai to.*', caplog) - # del freqai_conf['freqai']['startup_candles'] - # backtesting = Backtesting(freqai_conf) - # with pytest.raises(OperationalException, - # match=r'FreqAI backtesting module.*startup_candles in config.'): - # backtesting.load_bt_data() - Backtesting.cleanup() From 13ccd940d5e9d9bacedb896cbe4859217f487dde Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 31 Aug 2022 10:26:58 +0000 Subject: [PATCH 13/65] Remove startup_candle_count from freqai sample config to avoid confusion --- config_examples/config_freqai.example.json | 8 +++++--- freqtrade/templates/FreqaiHybridExampleStrategy.py | 1 - 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/config_examples/config_freqai.example.json b/config_examples/config_freqai.example.json index 7112fc225..13c7a94ea 100644 --- a/config_examples/config_freqai.example.json +++ b/config_examples/config_freqai.example.json @@ -9,7 +9,6 @@ "dry_run": true, "timeframe": "3m", "dry_run_wallet": 1000, - "startup_candle_count": 20, "cancel_open_orders_on_exit": true, "unfilledtimeout": { "entry": 10, @@ -76,7 +75,10 @@ "principal_component_analysis": false, "use_SVM_to_remove_outliers": true, "indicator_max_period_candles": 20, - "indicator_periods_candles": [10, 20] + "indicator_periods_candles": [ + 10, + 20 + ] }, "data_split_parameters": { "test_size": 0.33, @@ -92,4 +94,4 @@ "internals": { "process_throttle_secs": 5 } -} +} \ No newline at end of file diff --git a/freqtrade/templates/FreqaiHybridExampleStrategy.py b/freqtrade/templates/FreqaiHybridExampleStrategy.py index 0a91455f5..5d1e149dd 100644 --- a/freqtrade/templates/FreqaiHybridExampleStrategy.py +++ b/freqtrade/templates/FreqaiHybridExampleStrategy.py @@ -45,7 +45,6 @@ class FreqaiExampleHybridStrategy(IStrategy): "weight_factor": 0.9, "principal_component_analysis": false, "use_SVM_to_remove_outliers": true, - "indicator_max_period_candles": 20, "indicator_periods_candles": [10, 20] }, "data_split_parameters": { From 57ff6f8ac592678c5399e83e75656c66076bd863 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 31 Aug 2022 10:28:31 +0000 Subject: [PATCH 14/65] Init timerange object properly --- freqtrade/freqai/utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqai/utils.py b/freqtrade/freqai/utils.py index 6081b6ce5..6a70f050f 100644 --- a/freqtrade/freqai/utils.py +++ b/freqtrade/freqai/utils.py @@ -55,7 +55,6 @@ def get_required_data_timerange( for auto data-download in FreqAI """ time = datetime.now(tz=timezone.utc).timestamp() - data_load_timerange = TimeRange() timeframes = config["freqai"]["feature_parameters"].get("include_timeframes") @@ -75,12 +74,13 @@ def get_required_data_timerange( additional_seconds = max_period * max_tf_seconds - data_load_timerange.startts = int( + startts = int( time - config["freqai"].get("train_period_days", 0) * 86400 - additional_seconds ) - data_load_timerange.stopts = int(time) + stopts = int(time) + data_load_timerange = TimeRange('date', 'date', startts, stopts) return data_load_timerange From df51da22ee699e9a362d980747dba28e578d6c47 Mon Sep 17 00:00:00 2001 From: Wagner Costa Santos Date: Wed, 31 Aug 2022 11:23:48 -0300 Subject: [PATCH 15/65] refactoring freqai backtesting --- freqtrade/freqai/data_kitchen.py | 37 +++++++++- freqtrade/freqai/freqai_interface.py | 104 ++++++++++++++++++++++----- 2 files changed, 122 insertions(+), 19 deletions(-) diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index 763a07375..80b795b8e 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -1,6 +1,7 @@ import copy import datetime import logging +import os import shutil from pathlib import Path from typing import Any, Dict, List, Tuple @@ -780,9 +781,10 @@ class FreqaiDataKitchen: weights = np.exp(-np.arange(num_weights) / (wfactor * num_weights))[::-1] return weights - def append_predictions(self, predictions: DataFrame, do_predict: npt.ArrayLike) -> None: + def get_predictions_to_append(self, predictions: DataFrame, + do_predict: npt.ArrayLike) -> DataFrame: """ - Append backtest prediction from current backtest period to all previous periods + Get backtest prediction from current backtest period """ append_df = DataFrame() @@ -797,12 +799,19 @@ class FreqaiDataKitchen: if self.freqai_config["feature_parameters"].get("DI_threshold", 0) > 0: append_df["DI_values"] = self.DI_values + return append_df + + def append_predictions(self, append_df: DataFrame) -> None: + """ + Append backtest prediction from current backtest period to all previous periods + """ + if self.full_df.empty: self.full_df = append_df else: self.full_df = pd.concat([self.full_df, append_df], axis=0) - return + return append_df def fill_predictions(self, dataframe): """ @@ -1089,3 +1098,25 @@ class FreqaiDataKitchen: if self.unique_classes: for label in self.unique_classes: self.unique_class_list += list(self.unique_classes[label]) + + def save_backtesting_prediction( + self, file_name: str, root_folder: str, append_df: DataFrame + ) -> None: + + """ + Save prediction dataframe from backtesting to h5 file format + :param file_name: h5 file name + :param root_folder: folder to save h5 file + """ + os.makedirs(root_folder, exist_ok=True) + append_df.to_hdf(file_name, key='append_df', mode='w') + + def get_backtesting_prediction(self, prediction_file_name: str) -> DataFrame: + """ + Retrive from disk the prediction dataframe + :param prediction_file_name: prediction file full path + :return: + :Dataframe: Backtesting prediction from current backtesting period + """ + append_df = pd.read_hdf(prediction_file_name) + return append_df diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index 4106f24e0..d396113e8 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -224,28 +224,50 @@ class IFreqaiModel(ABC): "trains" ) + trained_timestamp_int = int(trained_timestamp.stopts) dk.data_path = Path( dk.full_path / - f"sub-train-{metadata['pair'].split('/')[0]}_{int(trained_timestamp.stopts)}" + f"sub-train-{metadata['pair'].split('/')[0]}_{trained_timestamp_int}" ) - if not self.model_exists( - metadata["pair"], dk, trained_timestamp=int(trained_timestamp.stopts) - ): - dk.find_features(dataframe_train) - self.model = self.train(dataframe_train, metadata["pair"], dk) - self.dd.pair_dict[metadata["pair"]]["trained_timestamp"] = int( - trained_timestamp.stopts) - dk.set_new_model_names(metadata["pair"], trained_timestamp) - self.dd.save_data(self.model, metadata["pair"], dk) - else: - self.model = self.dd.load_data(metadata["pair"], dk) - self.check_if_feature_list_matches_strategy(dataframe_train, dk) - - pred_df, do_preds = self.predict(dataframe_backtest, dk) + if self.backtest_prediction_exists( + metadata["pair"], dk, trained_timestamp=trained_timestamp_int + ): + prediction_filename, _ = self.get_backtesting_prediction_file_name( + metadata["pair"], + dk, + trained_timestamp=int(trained_timestamp.stopts)) - dk.append_predictions(pred_df, do_preds) + append_df = dk.get_backtesting_prediction(prediction_filename) + dk.append_predictions(append_df) + else: + if not self.model_exists( + metadata["pair"], dk, trained_timestamp=trained_timestamp_int + ): + dk.find_features(dataframe_train) + self.model = self.train(dataframe_train, metadata["pair"], dk) + self.dd.pair_dict[metadata["pair"]]["trained_timestamp"] = int( + trained_timestamp.stopts) + dk.set_new_model_names(metadata["pair"], trained_timestamp) + self.dd.save_data(self.model, metadata["pair"], dk) + else: + self.model = self.dd.load_data(metadata["pair"], dk) + + self.check_if_feature_list_matches_strategy(dataframe_train, dk) + + pred_df, do_preds = self.predict(dataframe_backtest, dk) + append_df = dk.get_predictions_to_append(pred_df, do_preds) + dk.append_predictions(append_df) + + prediction_file_name, root_prediction = self.get_backtesting_prediction_file_name( + metadata["pair"], + dk, + trained_timestamp_int) + + dk.save_backtesting_prediction(prediction_file_name, + root_prediction, + append_df) dk.fill_predictions(dataframe) @@ -643,6 +665,56 @@ class IFreqaiModel(ABC): self.train_time = 0 return + def backtest_prediction_exists( + self, + pair: str, + dk: FreqaiDataKitchen, + trained_timestamp: int, + scanning: bool = False, + ) -> bool: + """ + Given a pair and path, check if a backtesting prediction already exists + :param pair: pair e.g. BTC/USD + :param path: path to prediction + :return: + :boolean: whether the prediction file exists or not. + """ + if not self.live: + prediction_file_name, _ = self.get_backtesting_prediction_file_name( + pair, dk, trained_timestamp + ) + path_to_predictionfile = Path(prediction_file_name) + + file_exists = path_to_predictionfile.is_file() + if file_exists and not scanning: + logger.info("Found backtesting prediction file at %s", prediction_file_name) + elif not scanning: + logger.info( + "Could not find backtesting prediction file at %s", prediction_file_name + ) + return file_exists + else: + return False + + def get_backtesting_prediction_file_name( + self, pair: str, dk: FreqaiDataKitchen, trained_timestamp: int + ): + """ + Given a pair, path and a trained timestamp, + returns the path and name of the predictions file + :param pair: pair e.g. BTC/USD + :param dk: FreqaiDataKitchen + :trained_timestamp: current backtesting timestamp period + :return: + :str: prediction file name + :str: prediction root path + """ + coin, _ = pair.split("/") + prediction_base_filename = f"{coin.lower()}_{trained_timestamp}" + root_prediction = f'{dk.full_path}/backtesting_predictions' + prediction_file_name = f"{root_prediction}/{prediction_base_filename}_predictions.h5" + return prediction_file_name, root_prediction + # Following methods which are overridden by user made prediction models. # See freqai/prediction_models/CatboostPredictionModel.py for an example. From 7bed0450d2c6ae90dd00d98a51b18701be6c4874 Mon Sep 17 00:00:00 2001 From: Wagner Costa Santos Date: Wed, 31 Aug 2022 15:36:29 -0300 Subject: [PATCH 16/65] pr review - refactoring backtesting freqai --- freqtrade/freqai/data_kitchen.py | 19 ++++++++++++++----- freqtrade/freqai/freqai_interface.py | 12 ++++++------ tests/freqai/test_freqai_interface.py | 8 ++++---- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index 80b795b8e..8dc94e9ec 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -1,7 +1,6 @@ import copy import datetime import logging -import os import shutil from pathlib import Path from typing import Any, Dict, List, Tuple @@ -1108,15 +1107,25 @@ class FreqaiDataKitchen: :param file_name: h5 file name :param root_folder: folder to save h5 file """ - os.makedirs(root_folder, exist_ok=True) - append_df.to_hdf(file_name, key='append_df', mode='w') + backtesting_root = Path( + self.full_path + / root_folder + ) + if not backtesting_root.is_dir(): + backtesting_root.mkdir(parents=True, exist_ok=True) - def get_backtesting_prediction(self, prediction_file_name: str) -> DataFrame: + full_file_path = Path(self.full_path / root_folder / file_name) + append_df.to_hdf(full_file_path, key='append_df', mode='w') + + def get_backtesting_prediction( + self, root_prediction: str, prediction_file_name: str + ) -> DataFrame: """ Retrive from disk the prediction dataframe :param prediction_file_name: prediction file full path :return: :Dataframe: Backtesting prediction from current backtesting period """ - append_df = pd.read_hdf(prediction_file_name) + prediction_path = Path(self.full_path / root_prediction / prediction_file_name) + append_df = pd.read_hdf(prediction_path) return append_df diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index d396113e8..ad64588a7 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -234,12 +234,12 @@ class IFreqaiModel(ABC): if self.backtest_prediction_exists( metadata["pair"], dk, trained_timestamp=trained_timestamp_int ): - prediction_filename, _ = self.get_backtesting_prediction_file_name( + prediction_filename, root_prediction = self.get_backtesting_prediction_file_name( metadata["pair"], dk, trained_timestamp=int(trained_timestamp.stopts)) - append_df = dk.get_backtesting_prediction(prediction_filename) + append_df = dk.get_backtesting_prediction(root_prediction, prediction_filename) dk.append_predictions(append_df) else: if not self.model_exists( @@ -680,10 +680,10 @@ class IFreqaiModel(ABC): :boolean: whether the prediction file exists or not. """ if not self.live: - prediction_file_name, _ = self.get_backtesting_prediction_file_name( + prediction_file_name, root_prediction = self.get_backtesting_prediction_file_name( pair, dk, trained_timestamp ) - path_to_predictionfile = Path(prediction_file_name) + path_to_predictionfile = Path(dk.full_path / root_prediction / prediction_file_name) file_exists = path_to_predictionfile.is_file() if file_exists and not scanning: @@ -711,8 +711,8 @@ class IFreqaiModel(ABC): """ coin, _ = pair.split("/") prediction_base_filename = f"{coin.lower()}_{trained_timestamp}" - root_prediction = f'{dk.full_path}/backtesting_predictions' - prediction_file_name = f"{root_prediction}/{prediction_base_filename}_predictions.h5" + root_prediction = 'backtesting_predictions' + prediction_file_name = f"{prediction_base_filename}_predictions.h5" return prediction_file_name, root_prediction # Following methods which are overridden by user made prediction models. diff --git a/tests/freqai/test_freqai_interface.py b/tests/freqai/test_freqai_interface.py index 792ffc467..09f5d27ff 100644 --- a/tests/freqai/test_freqai_interface.py +++ b/tests/freqai/test_freqai_interface.py @@ -192,7 +192,7 @@ def test_start_backtesting(mocker, freqai_conf): freqai.start_backtesting(df, metadata, freqai.dk) model_folders = [x for x in freqai.dd.full_path.iterdir() if x.is_dir()] - assert len(model_folders) == 5 + assert len(model_folders) == 6 shutil.rmtree(Path(freqai.dk.full_path)) @@ -217,7 +217,7 @@ def test_start_backtesting_subdaily_backtest_period(mocker, freqai_conf): metadata = {"pair": "LTC/BTC"} freqai.start_backtesting(df, metadata, freqai.dk) model_folders = [x for x in freqai.dd.full_path.iterdir() if x.is_dir()] - assert len(model_folders) == 8 + assert len(model_folders) == 9 shutil.rmtree(Path(freqai.dk.full_path)) @@ -242,7 +242,7 @@ def test_start_backtesting_from_existing_folder(mocker, freqai_conf, caplog): freqai.start_backtesting(df, metadata, freqai.dk) model_folders = [x for x in freqai.dd.full_path.iterdir() if x.is_dir()] - assert len(model_folders) == 5 + assert len(model_folders) == 6 # without deleting the exiting folder structure, re-run @@ -263,7 +263,7 @@ def test_start_backtesting_from_existing_folder(mocker, freqai_conf, caplog): freqai.start_backtesting(df, metadata, freqai.dk) assert log_has_re( - "Found model at ", + "Found backtesting prediction ", caplog, ) From ba2eb7cf0f9f517f526a44b3efc792674911a5da Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 1 Sep 2022 06:35:24 +0200 Subject: [PATCH 17/65] Fix BNB fee bug when selling thanks @epigramx, for reporting and for the detailed data. --- freqtrade/freqtradebot.py | 16 +++++++++++----- tests/test_freqtradebot.py | 8 +++++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 5393e3d39..37bc6dfed 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1778,7 +1778,7 @@ class FreqtradeBot(LoggingMixin): self.rpc.send_msg(msg) def apply_fee_conditional(self, trade: Trade, trade_base_currency: str, - amount: float, fee_abs: float) -> Optional[float]: + amount: float, fee_abs: float, order_obj: Order) -> Optional[float]: """ Applies the fee to amount (either from Order or from Trades). Can eat into dust if more than the required asset is available. @@ -1786,7 +1786,12 @@ class FreqtradeBot(LoggingMixin): never in base currency. """ self.wallets.update() - if fee_abs != 0 and self.wallets.get_free(trade_base_currency) >= amount: + amount_ = amount + if order_obj.ft_order_side == trade.exit_side or order_obj.ft_order_side == 'stoploss': + # check against remaining amount! + amount_ = trade.amount - amount + + if fee_abs != 0 and self.wallets.get_free(trade_base_currency) >= amount_: # Eat into dust if we own more than base currency logger.info(f"Fee amount for {trade} was in base currency - " f"Eating Fee {fee_abs} into dust.") @@ -1833,7 +1838,8 @@ class FreqtradeBot(LoggingMixin): if trade_base_currency == fee_currency: # Apply fee to amount return self.apply_fee_conditional(trade, trade_base_currency, - amount=order_amount, fee_abs=fee_cost) + amount=order_amount, fee_abs=fee_cost, + order_obj=order_obj) return None return self.fee_detection_from_trades( trade, order, order_obj, order_amount, order.get('trades', [])) @@ -1892,8 +1898,8 @@ class FreqtradeBot(LoggingMixin): raise DependencyException("Half bought? Amounts don't match") if fee_abs != 0: - return self.apply_fee_conditional(trade, trade_base_currency, - amount=amount, fee_abs=fee_abs) + return self.apply_fee_conditional( + trade, trade_base_currency, amount=amount, fee_abs=fee_abs, order_obj=order_obj) return None def get_valid_price(self, custom_price: float, proposed_price: float) -> float: diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index e6c6e7978..aff0504b3 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -4650,11 +4650,17 @@ def test_apply_fee_conditional(default_conf_usdt, fee, mocker, fee_close=fee.return_value, open_order_id="123456" ) + order = Order( + ft_order_side='buy', + order_id='100', + ft_pair=trade.pair, + ft_is_open=True, + ) freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt) walletmock.reset_mock() # Amount is kept as is - assert freqtrade.apply_fee_conditional(trade, 'LTC', amount, fee_abs) == amount_exp + assert freqtrade.apply_fee_conditional(trade, 'LTC', amount, fee_abs, order) == amount_exp assert walletmock.call_count == 1 From f3c73189d55be454845a4e9cc7d8b084a2b0853c Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 1 Sep 2022 06:49:51 +0200 Subject: [PATCH 18/65] Remove pointless default on wallet_balance argument --- freqtrade/exchange/exchange.py | 2 +- tests/exchange/test_exchange.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 9d08d3d19..c3dca43a8 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -2600,7 +2600,7 @@ class Exchange: is_short: bool, amount: float, # Absolute value of position size stake_amount: float, - wallet_balance: float = 0.0, + wallet_balance: float, mm_ex_1: float = 0.0, # (Binance) Cross only upnl_ex_1: float = 0.0, # (Binance) Cross only ) -> Optional[float]: diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 5456b3098..3352019a9 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -4985,6 +4985,7 @@ def test_get_liquidation_price1(mocker, default_conf): is_short=False, amount=0.8, stake_amount=18.884 * 0.8, + wallet_balance=18.884 * 0.8, ) assert liq_price == 17.47 @@ -4996,6 +4997,7 @@ def test_get_liquidation_price1(mocker, default_conf): is_short=False, amount=0.8, stake_amount=18.884 * 0.8, + wallet_balance=18.884 * 0.8, ) assert liq_price == 17.540699999999998 @@ -5007,6 +5009,7 @@ def test_get_liquidation_price1(mocker, default_conf): is_short=False, amount=0.8, stake_amount=18.884 * 0.8, + wallet_balance=18.884 * 0.8, ) assert liq_price is None default_conf['trading_mode'] = 'margin' @@ -5019,6 +5022,7 @@ def test_get_liquidation_price1(mocker, default_conf): is_short=False, amount=0.8, stake_amount=18.884 * 0.8, + wallet_balance=18.884 * 0.8, ) From d6e115178a117e6f22f648b1d0def25b90eec471 Mon Sep 17 00:00:00 2001 From: Wagner Costa Santos Date: Thu, 1 Sep 2022 07:09:23 -0300 Subject: [PATCH 19/65] refactoring freqai backtesting - remove duplicate code --- freqtrade/freqai/data_kitchen.py | 32 ++++++-------- freqtrade/freqai/freqai_interface.py | 64 ++++++---------------------- 2 files changed, 25 insertions(+), 71 deletions(-) diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index 361d9872d..f88e20223 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -69,6 +69,8 @@ class FreqaiDataKitchen: self.label_list: List = [] self.training_features_list: List = [] self.model_filename: str = "" + self.backtesting_results_path = Path() + self.backtesting_prediction_folder: str = "backtesting_predictions" self.live = live self.pair = pair @@ -808,8 +810,6 @@ class FreqaiDataKitchen: else: self.full_df = pd.concat([self.full_df, append_df], axis=0) - return append_df - def fill_predictions(self, dataframe): """ Back fill values to before the backtesting range so that the dataframe matches size @@ -1070,33 +1070,25 @@ class FreqaiDataKitchen: self.unique_class_list += list(self.unique_classes[label]) def save_backtesting_prediction( - self, file_name: str, root_folder: str, append_df: DataFrame + self, append_df: DataFrame ) -> None: """ Save prediction dataframe from backtesting to h5 file format - :param file_name: h5 file name - :param root_folder: folder to save h5 file + :param append_df: dataframe for backtesting period """ - backtesting_root = Path( - self.full_path - / root_folder - ) - if not backtesting_root.is_dir(): - backtesting_root.mkdir(parents=True, exist_ok=True) + full_predictions_folder = Path(self.full_path / self.backtesting_prediction_folder) + if not full_predictions_folder.is_dir(): + full_predictions_folder.mkdir(parents=True, exist_ok=True) - full_file_path = Path(self.full_path / root_folder / file_name) - append_df.to_hdf(full_file_path, key='append_df', mode='w') + append_df.to_hdf(self.backtesting_results_path, key='append_df', mode='w') def get_backtesting_prediction( - self, root_prediction: str, prediction_file_name: str + self ) -> DataFrame: + """ - Retrive from disk the prediction dataframe - :param prediction_file_name: prediction file full path - :return: - :Dataframe: Backtesting prediction from current backtesting period + Get prediction dataframe from h5 file format """ - prediction_path = Path(self.full_path / root_prediction / prediction_file_name) - append_df = pd.read_hdf(prediction_path) + append_df = pd.read_hdf(self.backtesting_results_path) return append_df diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index 2297811b4..0a63e36ea 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -231,15 +231,11 @@ class IFreqaiModel(ABC): f"sub-train-{metadata['pair'].split('/')[0]}_{trained_timestamp_int}" ) - if self.backtest_prediction_exists( - metadata["pair"], dk, trained_timestamp=trained_timestamp_int - ): - prediction_filename, root_prediction = self.get_backtesting_prediction_file_name( - metadata["pair"], - dk, - trained_timestamp=int(trained_timestamp.stopts)) - - append_df = dk.get_backtesting_prediction(root_prediction, prediction_filename) + coin, _ = metadata["pair"].split("/") + dk.model_filename = f"cb_{coin.lower()}_{trained_timestamp_int}" + + if self.backtest_prediction_exists(dk): + append_df = dk.get_backtesting_prediction() dk.append_predictions(append_df) else: if not self.model_exists( @@ -259,15 +255,7 @@ class IFreqaiModel(ABC): pred_df, do_preds = self.predict(dataframe_backtest, dk) append_df = dk.get_predictions_to_append(pred_df, do_preds) dk.append_predictions(append_df) - - prediction_file_name, root_prediction = self.get_backtesting_prediction_file_name( - metadata["pair"], - dk, - trained_timestamp_int) - - dk.save_backtesting_prediction(prediction_file_name, - root_prediction, - append_df) + dk.save_backtesting_prediction(append_df) dk.fill_predictions(dataframe) @@ -478,11 +466,6 @@ class IFreqaiModel(ABC): :return: :boolean: whether the model file exists or not. """ - coin, _ = pair.split("/") - - if not self.live: - dk.model_filename = model_filename = f"cb_{coin.lower()}_{trained_timestamp}" - path_to_modelfile = Path(dk.data_path / f"{model_filename}_model.joblib") file_exists = path_to_modelfile.is_file() if file_exists and not scanning: @@ -661,23 +644,21 @@ class IFreqaiModel(ABC): def backtest_prediction_exists( self, - pair: str, dk: FreqaiDataKitchen, - trained_timestamp: int, scanning: bool = False, ) -> bool: """ - Given a pair and path, check if a backtesting prediction already exists - :param pair: pair e.g. BTC/USD - :param path: path to prediction + Check if a backtesting prediction already exists + :param dk: FreqaiDataKitchen :return: :boolean: whether the prediction file exists or not. """ if not self.live: - prediction_file_name, root_prediction = self.get_backtesting_prediction_file_name( - pair, dk, trained_timestamp - ) - path_to_predictionfile = Path(dk.full_path / root_prediction / prediction_file_name) + prediction_file_name = dk.model_filename + path_to_predictionfile = Path(dk.full_path / + dk.backtesting_prediction_folder / + f"{prediction_file_name}_prediction.h5") + dk.backtesting_results_path = path_to_predictionfile file_exists = path_to_predictionfile.is_file() if file_exists and not scanning: @@ -690,25 +671,6 @@ class IFreqaiModel(ABC): else: return False - def get_backtesting_prediction_file_name( - self, pair: str, dk: FreqaiDataKitchen, trained_timestamp: int - ): - """ - Given a pair, path and a trained timestamp, - returns the path and name of the predictions file - :param pair: pair e.g. BTC/USD - :param dk: FreqaiDataKitchen - :trained_timestamp: current backtesting timestamp period - :return: - :str: prediction file name - :str: prediction root path - """ - coin, _ = pair.split("/") - prediction_base_filename = f"{coin.lower()}_{trained_timestamp}" - root_prediction = 'backtesting_predictions' - prediction_file_name = f"{prediction_base_filename}_predictions.h5" - return prediction_file_name, root_prediction - # Following methods which are overridden by user made prediction models. # See freqai/prediction_models/CatboostPredictionModel.py for an example. From 61d5fc0e0836aa880ce00bf60981027a0bce7f40 Mon Sep 17 00:00:00 2001 From: epigramx Date: Thu, 1 Sep 2022 17:22:34 +0300 Subject: [PATCH 20/65] Make the recommendation for Binance/Kucoin blacklisting more accurate. Now that a recent bug regarding selling BNB is fixed, it should be safe to trade it, but with a warning that the user may have to manually maintain extra BNB. Also the old text implied those features are always unabled so this texts makes it clear those fee-related features can be also disabled. I'm not sure if it's still true that an "eaten by fees" position becomes unsellable but I left that as it is. --- docs/exchanges.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/exchanges.md b/docs/exchanges.md index 407a67d70..b55eaac74 100644 --- a/docs/exchanges.md +++ b/docs/exchanges.md @@ -61,8 +61,8 @@ Binance supports [time_in_force](configuration.md#understand-order_time_in_force ### Binance Blacklist -For Binance, please add `"BNB/"` to your blacklist to avoid issues. -Accounts having BNB accounts use this to pay for fees - if your first trade happens to be on `BNB`, further trades will consume this position and make the initial BNB trade unsellable as the expected amount is not there anymore. +For Binance, it is suggested to add `"BNB/"` to your blacklist to avoid issues, unless you are willing to maintain enough extra `BNB` on the account or, unless you're willing to disable using `BNB` for fees. +Binance accounts may use `BNB` for fees, and if a trade happens to be on `BNB`, further trades may consume this position and make the initial BNB trade unsellable as the expected amount is not there anymore. ### Binance Futures @@ -205,8 +205,8 @@ Kucoin supports [time_in_force](configuration.md#understand-order_time_in_force) ### Kucoin Blacklists -For Kucoin, please add `"KCS/"` to your blacklist to avoid issues. -Accounts having KCS accounts use this to pay for fees - if your first trade happens to be on `KCS`, further trades will consume this position and make the initial KCS trade unsellable as the expected amount is not there anymore. +For Kucoin, it is suggested to add `"KCS/"` to your blacklist to avoid issues, unless you are willing to maintain enough extra `KCS` on the account or, unless you're willing to disable using `KCS` for fees. +Kucoin accounts may use `KCS` for fees, and if a trade happens to be on `KCS`, further trades may consume this position and make the initial `KCS` trade unsellable as the expected amount is not there anymore. ## Huobi From 11fbfd3402996db93870b5d4beadc2b0840bc37c Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 1 Sep 2022 19:39:20 +0200 Subject: [PATCH 21/65] Remove unnecessary assignment --- freqtrade/persistence/trade_model.py | 1 - 1 file changed, 1 deletion(-) diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index 23997f835..1f14f110e 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -648,7 +648,6 @@ class LocalTrade(): """ self.close_rate = rate self.close_date = self.close_date or datetime.utcnow() - self.close_profit_abs = self.calc_profit(rate) + self.realized_profit self.is_open = False self.exit_order_status = 'closed' self.open_order_id = None From 3f8400df10abd51f814b566a2c17ea5423963f34 Mon Sep 17 00:00:00 2001 From: th0rntwig Date: Thu, 1 Sep 2022 21:51:33 +0200 Subject: [PATCH 22/65] Normalise PCA space --- freqtrade/freqai/data_kitchen.py | 64 ++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index f38c69fae..2a3d00cc5 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -287,19 +287,26 @@ class FreqaiDataKitchen: :returns: :data_dictionary: updated dictionary with standardized values. """ + + df_train_features = data_dictionary["train_features"] # standardize the data by training stats - train_max = data_dictionary["train_features"].max() - train_min = data_dictionary["train_features"].min() - data_dictionary["train_features"] = ( - 2 * (data_dictionary["train_features"] - train_min) / (train_max - train_min) - 1 + train_max = df_train_features.max() + train_min = df_train_features.min() + df_train_features = ( + 2 * (df_train_features - train_min) / (train_max - train_min) - 1 ) data_dictionary["test_features"] = ( 2 * (data_dictionary["test_features"] - train_min) / (train_max - train_min) - 1 ) for item in train_max.keys(): - self.data[item + "_max"] = train_max[item] - self.data[item + "_min"] = train_min[item] + if not [col for col in df_train_features.columns if col.startwith('PC')]: + self.data[item + "_max"] = train_max[item] + self.data[item + "_min"] = train_min[item] + else: + # if PCA is enabled and has transformed the training features + self.data[item + "_pca_max"] = train_max[item] + self.data[item + "_pca_min"] = train_min[item] for item in data_dictionary["train_labels"].keys(): if data_dictionary["train_labels"][item].dtype == object: @@ -320,8 +327,14 @@ class FreqaiDataKitchen: - 1 ) - self.data[f"{item}_max"] = train_labels_max # .to_dict() - self.data[f"{item}_min"] = train_labels_min # .to_dict() + if not [col for col in df_train_features.columns if col.startwith('PC')]: + self.data[f"{item}_max"] = train_labels_max # .to_dict() + self.data[f"{item}_min"] = train_labels_min # .to_dict() + else: + # if PCA is enabled and has transformed the training features + self.data[f"{item}_pca_max"] = train_labels_max # .to_dict() + self.data[f"{item}_pca_min"] = train_labels_min # .to_dict() + return data_dictionary def normalize_data_from_metadata(self, df: DataFrame) -> DataFrame: @@ -331,11 +344,17 @@ class FreqaiDataKitchen: :param df: Dataframe to be standardized """ + if not [col for col in df.columns if col.startwith('PC')]: + id_str = '' + else: + # if PCA is enabled + id_str = '_pca' + for item in df.keys(): df[item] = ( 2 - * (df[item] - self.data[f"{item}_min"]) - / (self.data[f"{item}_max"] - self.data[f"{item}_min"]) + * (df[item] - self.data[f"{item}{id_str}_min"]) + / (self.data[f"{item}{id_str}_max"] - self.data[f"{item}{id_str}_min"]) - 1 ) @@ -450,22 +469,23 @@ class FreqaiDataKitchen: from sklearn.decomposition import PCA # avoid importing if we dont need it - n_components = self.data_dictionary["train_features"].shape[1] - pca = PCA(n_components=n_components) + pca = PCA(0.999) pca = pca.fit(self.data_dictionary["train_features"]) - n_keep_components = np.argmin(pca.explained_variance_ratio_.cumsum() < 0.999) - pca2 = PCA(n_components=n_keep_components) + n_keep_components = pca.n_components_ self.data["n_kept_components"] = n_keep_components - pca2 = pca2.fit(self.data_dictionary["train_features"]) + n_components = self.data_dictionary["train_features"].shape[1] logger.info("reduced feature dimension by %s", n_components - n_keep_components) - logger.info("explained variance %f", np.sum(pca2.explained_variance_ratio_)) - train_components = pca2.transform(self.data_dictionary["train_features"]) + logger.info("explained variance %f", np.sum(pca.explained_variance_ratio_)) + train_components = pca.transform(self.data_dictionary["train_features"]) self.data_dictionary["train_features"] = pd.DataFrame( data=train_components, columns=["PC" + str(i) for i in range(0, n_keep_components)], index=self.data_dictionary["train_features"].index, ) + # normalsing transformed training features + self.data_dictionary["train_features"] = self.normalize_data( + self.data_dictionary["train_features"]) # keeping a copy of the non-transformed features so we can check for errors during # model load from disk @@ -473,15 +493,18 @@ class FreqaiDataKitchen: self.training_features_list = self.data_dictionary["train_features"].columns if self.freqai_config.get('data_split_parameters', {}).get('test_size', 0.1) != 0: - test_components = pca2.transform(self.data_dictionary["test_features"]) + test_components = pca.transform(self.data_dictionary["test_features"]) self.data_dictionary["test_features"] = pd.DataFrame( data=test_components, columns=["PC" + str(i) for i in range(0, n_keep_components)], index=self.data_dictionary["test_features"].index, ) + # normalise transformed test feature to transformed training features + self.data_dictionary["test_features"] = self.normalize_data_from_metadata( + self.data_dictionary["test_features"]) self.data["n_kept_components"] = n_keep_components - self.pca = pca2 + self.pca = pca logger.info(f"PCA reduced total features from {n_components} to {n_keep_components}") @@ -502,6 +525,9 @@ class FreqaiDataKitchen: columns=["PC" + str(i) for i in range(0, self.data["n_kept_components"])], index=filtered_dataframe.index, ) + # normalise transformed predictions to transformed training features + self.data_dictionary["prediction_features"] = self.normalize_data_from_metadata( + self.data_dictionary["prediction_features"]) def compute_distances(self) -> float: """ From 11b2bc269ed1e4851f9cb51331b21a3faefe68a5 Mon Sep 17 00:00:00 2001 From: th0rntwig Date: Thu, 1 Sep 2022 22:37:32 +0200 Subject: [PATCH 23/65] Added missing s --- freqtrade/freqai/data_kitchen.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index 2a3d00cc5..69ce5272d 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -300,7 +300,7 @@ class FreqaiDataKitchen: ) for item in train_max.keys(): - if not [col for col in df_train_features.columns if col.startwith('PC')]: + if not [col for col in df_train_features.columns if col.startswith('PC')]: self.data[item + "_max"] = train_max[item] self.data[item + "_min"] = train_min[item] else: @@ -327,7 +327,7 @@ class FreqaiDataKitchen: - 1 ) - if not [col for col in df_train_features.columns if col.startwith('PC')]: + if not [col for col in df_train_features.columns if col.startswith('PC')]: self.data[f"{item}_max"] = train_labels_max # .to_dict() self.data[f"{item}_min"] = train_labels_min # .to_dict() else: @@ -344,7 +344,7 @@ class FreqaiDataKitchen: :param df: Dataframe to be standardized """ - if not [col for col in df.columns if col.startwith('PC')]: + if not [col for col in df.columns if col.startswith('PC')]: id_str = '' else: # if PCA is enabled From b53791fef20990d2a46b9dbf6795fb8cfc490c2f Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 2 Sep 2022 07:11:20 +0200 Subject: [PATCH 24/65] Futures volumepairlist to account for contract size --- freqtrade/plugins/pairlist/VolumePairList.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/freqtrade/plugins/pairlist/VolumePairList.py b/freqtrade/plugins/pairlist/VolumePairList.py index 8138a5fb6..d7cc6e5ec 100644 --- a/freqtrade/plugins/pairlist/VolumePairList.py +++ b/freqtrade/plugins/pairlist/VolumePairList.py @@ -186,6 +186,7 @@ class VolumePairList(IPairList): needed_pairs, since_ms=since_ms, cache=False ) for i, p in enumerate(filtered_tickers): + contract_size = self._exchange.markets[p['symbol']].get('contractSize', 1.0) or 1.0 pair_candles = candles[ (p['symbol'], self._lookback_timeframe, self._def_candletype) ] if ( @@ -199,6 +200,7 @@ class VolumePairList(IPairList): pair_candles['quoteVolume'] = ( pair_candles['volume'] * pair_candles['typical_price'] + * contract_size ) else: # Exchange ohlcv data is in quote volume already. From a948e51389108d7b827d4ad4551fd861b88bdb71 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 2 Sep 2022 19:56:12 +0200 Subject: [PATCH 25/65] Update futures docs to define pair namings #7334, #7136, ... --- docs/leverage.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/leverage.md b/docs/leverage.md index 491e6eda0..429aff86c 100644 --- a/docs/leverage.md +++ b/docs/leverage.md @@ -13,7 +13,7 @@ Please only use advanced trading modes when you know how freqtrade (and your strategy) works. Also, never risk more than what you can afford to lose. -Please read the [strategy migration guide](strategy_migration.md#strategy-migration-between-v2-and-v3) to migrate your strategy from a freqtrade v2 strategy, to v3 strategy that can short and trade futures. +If you already have an existing strategy, please read the [strategy migration guide](strategy_migration.md#strategy-migration-between-v2-and-v3) to migrate your strategy from a freqtrade v2 strategy, to strategy of version 3 which can short and trade futures. ## Shorting @@ -62,6 +62,13 @@ You will also have to pick a "margin mode" (explanation below) - with freqtrade "margin_mode": "isolated" ``` +##### Pair namings + +Freqtrade follows the [ccxt naming conventions for futures](https://docs.ccxt.com/en/latest/manual.html?#perpetual-swap-perpetual-future). +A futures pair will therefore have the naming of `base/quote:settle` (e.g. `ETH/USDT:USDT`). + +Binance is currently still an exception to this naming scheme, where pairs are named `ETH/USDT` also for futures markets, but will be aligned as soon as CCXT is ready. + ### Margin mode On top of `trading_mode` - you will also have to configure your `margin_mode`. From b26126cb57300cefb51222ddf185a4f929bdbba8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 2 Sep 2022 20:08:38 +0200 Subject: [PATCH 26/65] Don't use ticker['symbol'] but use "pair" instead closes #7262 --- docs/exchanges.md | 4 ++-- freqtrade/plugins/pairlist/PrecisionFilter.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/exchanges.md b/docs/exchanges.md index b55eaac74..b5470f65a 100644 --- a/docs/exchanges.md +++ b/docs/exchanges.md @@ -61,7 +61,7 @@ Binance supports [time_in_force](configuration.md#understand-order_time_in_force ### Binance Blacklist -For Binance, it is suggested to add `"BNB/"` to your blacklist to avoid issues, unless you are willing to maintain enough extra `BNB` on the account or, unless you're willing to disable using `BNB` for fees. +For Binance, it is suggested to add `"BNB/"` to your blacklist to avoid issues, unless you are willing to maintain enough extra `BNB` on the account or unless you're willing to disable using `BNB` for fees. Binance accounts may use `BNB` for fees, and if a trade happens to be on `BNB`, further trades may consume this position and make the initial BNB trade unsellable as the expected amount is not there anymore. ### Binance Futures @@ -205,7 +205,7 @@ Kucoin supports [time_in_force](configuration.md#understand-order_time_in_force) ### Kucoin Blacklists -For Kucoin, it is suggested to add `"KCS/"` to your blacklist to avoid issues, unless you are willing to maintain enough extra `KCS` on the account or, unless you're willing to disable using `KCS` for fees. +For Kucoin, it is suggested to add `"KCS/"` to your blacklist to avoid issues, unless you are willing to maintain enough extra `KCS` on the account or unless you're willing to disable using `KCS` for fees. Kucoin accounts may use `KCS` for fees, and if a trade happens to be on `KCS`, further trades may consume this position and make the initial `KCS` trade unsellable as the expected amount is not there anymore. ## Huobi diff --git a/freqtrade/plugins/pairlist/PrecisionFilter.py b/freqtrade/plugins/pairlist/PrecisionFilter.py index dcd153d8e..61150f03d 100644 --- a/freqtrade/plugins/pairlist/PrecisionFilter.py +++ b/freqtrade/plugins/pairlist/PrecisionFilter.py @@ -52,7 +52,7 @@ class PrecisionFilter(IPairList): :return: True if the pair can stay, false if it should be removed """ if ticker.get('last', None) is None: - self.log_once(f"Removed {ticker['symbol']} from whitelist, because " + self.log_once(f"Removed {pair} from whitelist, because " "ticker['last'] is empty (Usually no trade in the last 24h).", logger.info) return False @@ -62,10 +62,10 @@ class PrecisionFilter(IPairList): sp = self._exchange.price_to_precision(pair, stop_price) stop_gap_price = self._exchange.price_to_precision(pair, stop_price * 0.99) - logger.debug(f"{ticker['symbol']} - {sp} : {stop_gap_price}") + logger.debug(f"{pair} - {sp} : {stop_gap_price}") if sp <= stop_gap_price: - self.log_once(f"Removed {ticker['symbol']} from whitelist, because " + self.log_once(f"Removed {pair} from whitelist, because " f"stop price {sp} would be <= stop limit {stop_gap_price}", logger.info) return False From af5460cebf2b17ea440f1d7f037a7b8c88681d6a Mon Sep 17 00:00:00 2001 From: Wagner Costa Santos Date: Fri, 2 Sep 2022 22:01:53 -0300 Subject: [PATCH 27/65] Add option to keep models only in memory for backtest --- config_examples/config_freqai.example.json | 3 ++- docs/freqai.md | 1 + freqtrade/freqai/freqai_interface.py | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/config_examples/config_freqai.example.json b/config_examples/config_freqai.example.json index 13c7a94ea..846d37a82 100644 --- a/config_examples/config_freqai.example.json +++ b/config_examples/config_freqai.example.json @@ -56,6 +56,7 @@ "purge_old_models": true, "train_period_days": 15, "backtest_period_days": 7, + "backtest_save_model": true, "live_retrain_hours": 0, "identifier": "uniqe-id", "feature_parameters": { @@ -94,4 +95,4 @@ "internals": { "process_throttle_secs": 5 } -} \ No newline at end of file +} diff --git a/docs/freqai.md b/docs/freqai.md index 482a56d2b..6ee124b9b 100644 --- a/docs/freqai.md +++ b/docs/freqai.md @@ -93,6 +93,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `purge_old_models` | Delete obsolete models (otherwise, all historic models will remain on disk).
**Datatype:** Boolean. Default: `False`. | `train_period_days` | **Required.**
Number of days to use for the training data (width of the sliding window).
**Datatype:** Positive integer. | `backtest_period_days` | **Required.**
Number of days to inference from the trained model before sliding the window defined above, and retraining the model. This can be fractional days, but beware that the user-provided `timerange` will be divided by this number to yield the number of trainings necessary to complete the backtest.
**Datatype:** Float. +| `backtest_save_model` | Saves models to disk when running backtesting.
**Datatype:** Boolean. Default: `True`. | `identifier` | **Required.**
A unique name for the current model. This can be reused to reload pre-trained models/data.
**Datatype:** String. | `live_retrain_hours` | Frequency of retraining during dry/live runs.
Default set to 0, which means the model will retrain as often as possible.
**Datatype:** Float > 0. | `expiration_hours` | Avoid making predictions if a model is more than `expiration_hours` old.
Defaults set to 0, which means models never expire.
**Datatype:** Positive integer. diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index 0a63e36ea..9c7ef05a7 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -71,6 +71,7 @@ class IFreqaiModel(ABC): self.first = True self.set_full_path() self.follow_mode: bool = self.freqai_info.get("follow_mode", False) + self.backtest_save_model: bool = self.freqai_info.get("backtest_save_model", True) self.dd = FreqaiDataDrawer(Path(self.full_path), self.config, self.follow_mode) self.identifier: str = self.freqai_info.get("identifier", "no_id_provided") self.scanning = False @@ -246,7 +247,8 @@ class IFreqaiModel(ABC): self.dd.pair_dict[metadata["pair"]]["trained_timestamp"] = int( trained_timestamp.stopts) dk.set_new_model_names(metadata["pair"], trained_timestamp) - self.dd.save_data(self.model, metadata["pair"], dk) + if self.backtest_save_model: + self.dd.save_data(self.model, metadata["pair"], dk) else: self.model = self.dd.load_data(metadata["pair"], dk) From 966de1961180e39061277ffef00fdf78f1d86bdf Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 3 Sep 2022 08:16:33 +0200 Subject: [PATCH 28/65] Improve test resiliance by properly setting Order object --- tests/plugins/test_protections.py | 2 ++ tests/test_persistence.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/plugins/test_protections.py b/tests/plugins/test_protections.py index acfe124a8..820eced20 100644 --- a/tests/plugins/test_protections.py +++ b/tests/plugins/test_protections.py @@ -37,6 +37,7 @@ def generate_mock_trade(pair: str, fee: float, is_open: bool, trade.orders.append(Order( ft_order_side=trade.entry_side, order_id=f'{pair}-{trade.entry_side}-{trade.open_date}', + ft_is_open=False, ft_pair=pair, amount=trade.amount, filled=trade.amount, @@ -51,6 +52,7 @@ def generate_mock_trade(pair: str, fee: float, is_open: bool, trade.orders.append(Order( ft_order_side=trade.exit_side, order_id=f'{pair}-{trade.exit_side}-{trade.close_date}', + ft_is_open=False, ft_pair=pair, amount=trade.amount, filled=trade.amount, diff --git a/tests/test_persistence.py b/tests/test_persistence.py index f16c8b054..3ce8a0a2c 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -654,6 +654,7 @@ def test_trade_close(fee): trade.orders.append(Order( ft_order_side=trade.entry_side, order_id=f'{trade.pair}-{trade.entry_side}-{trade.open_date}', + ft_is_open=False, ft_pair=trade.pair, amount=trade.amount, filled=trade.amount, @@ -667,6 +668,7 @@ def test_trade_close(fee): trade.orders.append(Order( ft_order_side=trade.exit_side, order_id=f'{trade.pair}-{trade.exit_side}-{trade.open_date}', + ft_is_open=False, ft_pair=trade.pair, amount=trade.amount, filled=trade.amount, From be192fae910612b745c9b062788d54903bf1c95c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 3 Sep 2022 10:53:51 +0200 Subject: [PATCH 29/65] Test should use proper Order objects --- tests/test_persistence.py | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 3ce8a0a2c..23ccc67f3 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -581,25 +581,25 @@ def test_update_market_order(market_buy_order_usdt, market_sell_order_usdt, fee, @pytest.mark.parametrize( 'exchange,is_short,lev,open_value,close_value,profit,profit_ratio,trading_mode,funding_fees', [ ("binance", False, 1, 60.15, 65.835, 5.685, 0.09451371, spot, 0.0), - ("binance", True, 1, 59.850, 66.1663784375, -6.3163784375, -0.1055368, margin, 0.0), + ("binance", True, 1, 65.835, 60.151253125, 5.68374687, 0.08633321, margin, 0.0), ("binance", False, 3, 60.15, 65.83416667, 5.68416667, 0.28349958, margin, 0.0), - ("binance", True, 3, 59.85, 66.1663784375, -6.3163784375, -0.31661044, margin, 0.0), + ("binance", True, 3, 65.835, 60.151253125, 5.68374687, 0.25899963, margin, 0.0), ("kraken", False, 1, 60.15, 65.835, 5.685, 0.09451371, spot, 0.0), - ("kraken", True, 1, 59.850, 66.231165, -6.381165, -0.1066192, margin, 0.0), + ("kraken", True, 1, 65.835, 60.21015, 5.62485, 0.0854386, margin, 0.0), ("kraken", False, 3, 60.15, 65.795, 5.645, 0.28154613, margin, 0.0), - ("kraken", True, 3, 59.850, 66.231165, -6.381165, -0.3198578, margin, 0.0), + ("kraken", True, 3, 65.835, 60.21015, 5.62485, 0.25631579, margin, 0.0), ("binance", False, 1, 60.15, 65.835, 5.685, 0.09451371, futures, 0.0), ("binance", False, 1, 60.15, 66.835, 6.685, 0.11113881, futures, 1.0), - ("binance", True, 1, 59.85, 66.165, -6.315, -0.10551378, futures, 0.0), - ("binance", True, 1, 59.85, 67.165, -7.315, -0.12222222, futures, -1.0), + ("binance", True, 1, 65.835, 60.15, 5.685, 0.08635224, futures, 0.0), + ("binance", True, 1, 65.835, 61.15, 4.685, 0.07116276, futures, -1.0), + ("binance", True, 3, 65.835, 59.15, 6.685, 0.3046252, futures, 1.0), ("binance", False, 3, 60.15, 64.835, 4.685, 0.23366583, futures, -1.0), - ("binance", True, 3, 59.85, 65.165, -5.315, -0.26641604, futures, 1.0), ]) @pytest.mark.usefixtures("init_persistence") def test_calc_open_close_trade_price( - limit_buy_order_usdt, limit_sell_order_usdt, fee, exchange, is_short, lev, + limit_order, fee, exchange, is_short, lev, open_value, close_value, profit, profit_ratio, trading_mode, funding_fees ): trade: Trade = Trade( @@ -617,22 +617,24 @@ def test_calc_open_close_trade_price( trading_mode=trading_mode, funding_fees=funding_fees ) - + entry_order = limit_order[trade.entry_side] + exit_order = limit_order[trade.exit_side] trade.open_order_id = f'something-{is_short}-{lev}-{exchange}' - oobj = Order.parse_from_ccxt_object(limit_buy_order_usdt, 'ADA/USDT', 'buy') + oobj = Order.parse_from_ccxt_object(entry_order, 'ADA/USDT', trade.entry_side) + trade.orders.append(oobj) trade.update_trade(oobj) - oobj = Order.parse_from_ccxt_object(limit_sell_order_usdt, 'ADA/USDT', 'sell') + oobj = Order.parse_from_ccxt_object(exit_order, 'ADA/USDT', trade.exit_side) + trade.orders.append(oobj) trade.update_trade(oobj) - trade.open_rate = 2.0 - trade.close_rate = 2.2 - trade.recalc_open_trade_value() + assert trade.is_open is False + assert pytest.approx(trade._calc_open_trade_value(trade.amount, trade.open_rate)) == open_value assert pytest.approx(trade.calc_close_trade_value(trade.close_rate)) == close_value - assert pytest.approx(trade.calc_profit(trade.close_rate)) == round(profit, 8) - assert pytest.approx(trade.calc_profit_ratio(trade.close_rate)) == profit_ratio + assert pytest.approx(trade.close_profit_abs) == profit + assert pytest.approx(trade.close_profit) == profit_ratio @pytest.mark.usefixtures("init_persistence") From 599c1c79fb8170a7ea4bf9d250a4a3db0a3234ba Mon Sep 17 00:00:00 2001 From: robcaulk Date: Sat, 3 Sep 2022 14:00:01 +0200 Subject: [PATCH 30/65] reorganized backtest utilities, test new functionality, improve/update doc --- config_examples/config_freqai.example.json | 2 - docs/freqai.md | 32 +++++++------ freqtrade/freqai/data_kitchen.py | 27 ++++++++++- freqtrade/freqai/freqai_interface.py | 50 +++++--------------- freqtrade/templates/FreqaiExampleStrategy.py | 2 +- tests/freqai/test_freqai_interface.py | 9 +++- 6 files changed, 63 insertions(+), 59 deletions(-) diff --git a/config_examples/config_freqai.example.json b/config_examples/config_freqai.example.json index 846d37a82..12eb30128 100644 --- a/config_examples/config_freqai.example.json +++ b/config_examples/config_freqai.example.json @@ -56,7 +56,6 @@ "purge_old_models": true, "train_period_days": 15, "backtest_period_days": 7, - "backtest_save_model": true, "live_retrain_hours": 0, "identifier": "uniqe-id", "feature_parameters": { @@ -75,7 +74,6 @@ "weight_factor": 0.9, "principal_component_analysis": false, "use_SVM_to_remove_outliers": true, - "indicator_max_period_candles": 20, "indicator_periods_candles": [ 10, 20 diff --git a/docs/freqai.md b/docs/freqai.md index 6ee124b9b..3646362c3 100644 --- a/docs/freqai.md +++ b/docs/freqai.md @@ -89,11 +89,10 @@ Mandatory parameters are marked as **Required**, which means that they are requi |------------|-------------| | | **General configuration parameters** | `freqai` | **Required.**
The parent dictionary containing all the parameters for controlling FreqAI.
**Datatype:** Dictionary. -| `startup_candles` | Number of candles needed for *backtesting only* to ensure all indicators are non NaNs at the start of the first train period.
**Datatype:** Positive integer. | `purge_old_models` | Delete obsolete models (otherwise, all historic models will remain on disk).
**Datatype:** Boolean. Default: `False`. | `train_period_days` | **Required.**
Number of days to use for the training data (width of the sliding window).
**Datatype:** Positive integer. | `backtest_period_days` | **Required.**
Number of days to inference from the trained model before sliding the window defined above, and retraining the model. This can be fractional days, but beware that the user-provided `timerange` will be divided by this number to yield the number of trainings necessary to complete the backtest.
**Datatype:** Float. -| `backtest_save_model` | Saves models to disk when running backtesting.
**Datatype:** Boolean. Default: `True`. +| `save_backtest_models` | Backtesting operates most efficiently by saving the prediction data and reusing them directly for subsequent runs (when users wish to tune entry/exit parameters). If a user wishes to save models to disk when running backtesting, they should activate `save_backtest_models`. A user may wish to do this if they plan to use the same model files for starting a dry/live instance with the same `identifier`.
**Datatype:** Boolean. Default: `False`. | `identifier` | **Required.**
A unique name for the current model. This can be reused to reload pre-trained models/data.
**Datatype:** String. | `live_retrain_hours` | Frequency of retraining during dry/live runs.
Default set to 0, which means the model will retrain as often as possible.
**Datatype:** Float > 0. | `expiration_hours` | Avoid making predictions if a model is more than `expiration_hours` old.
Defaults set to 0, which means models never expire.
**Datatype:** Positive integer. @@ -280,6 +279,17 @@ The FreqAI strategy requires the user to include the following lines of code in Notice how the `populate_any_indicators()` is where the user adds their own features ([more information](#feature-engineering)) and labels ([more information](#setting-classifier-targets)). See a full example at `templates/FreqaiExampleStrategy.py`. +### Setting the `startup_candle_count` +Users need to take care to set the `startup_candle_count` in their strategy the same way they would for any normal Freqtrade strategy (see details [here](strategy-customization.md/#strategy-startup-period)). This value is used by Freqtrade to ensure that a sufficient amount of data is provided when calling on the `dataprovider` to avoid any NaNs at the beginning of the first training. Users can easily set this value by identifying the longest period (in candle units) that they pass to their indicator creation functions (e.g. talib functions). In the present example, the user would pass 20 to as this value (since it is the maximum value in their `indicators_periods_candles`). + +!!! Note + Typically it is best for users to be safe and multiply their expected `startup_candle_count` by 2. There are instances where the talib functions actually require more data than just the passed `period`. Anecdotally, multiplying the `startup_candle_count` by 2 always leads to a fully NaN free training dataset. Look out for this log message to confirm that your data is clean: + + ``` + 2022-08-31 15:14:04 - freqtrade.freqai.data_kitchen - INFO - dropped 0 training points due to NaNs in populated dataset 4319. + ``` + + ## Creating a dynamic target The `&*_std/mean` return values describe the statistical fit of the user defined label *during the most recent training*. This value allows the user to know the rarity of a given prediction. For example, `templates/FreqaiExampleStrategy.py`, creates a `target_roi` which is based on filtering out predictions that are below a given z-score of 1.25. @@ -505,7 +515,7 @@ and if a full `live_retrain_hours` has elapsed since the end of the loaded model The FreqAI backtesting module can be executed with the following command: ```bash -freqtrade backtesting --strategy FreqaiExampleStrategy --config config_freqai.example.json --freqaimodel LightGBMRegressor --timerange 20210501-20210701 +freqtrade backtesting --strategy FreqaiExampleStrategy --config config_examples/config_freqai.example.json --freqaimodel LightGBMRegressor --timerange 20210501-20210701 ``` Backtesting mode requires the user to have the data pre-downloaded (unlike in dry/live mode where FreqAI automatically downloads the necessary data). The user should be careful to consider that the time range of the downloaded data is more than the backtesting time range. This is because FreqAI needs data prior to the desired backtesting time range in order to train a model to be ready to make predictions on the first candle of the user-set backtesting time range. More details on how to calculate the data to download can be found [here](#deciding-the-sliding-training-window-and-backtesting-duration). @@ -532,20 +542,14 @@ the user is asking FreqAI to use a training period of 30 days and backtest on th This means that if the user sets `--timerange 20210501-20210701`, FreqAI will train have trained 8 separate models at the end of `--timerange` (because the full range comprises 8 weeks). After the training of the model, FreqAI will backtest the subsequent 7 days. The "sliding window" then moves one week forward (emulating FreqAI retraining once per week in live mode) and the new model uses the previous 30 days (including the 7 days used for backtesting by the previous model) to train. This is repeated until the end of `--timerange`. -In live mode, the required training data is automatically computed and downloaded. However, in backtesting mode, -the user must manually enter the required number of `startup_candles` in the config. This value -is used to increase the data to FreqAI, which should be sufficient to enable all indicators -to be NaN free at the beginning of the first training. This is done by identifying the -longest timeframe (`4h` in presented example config) and the longest indicator period (`20` days in presented example config) -and adding this to the `train_period_days`. The units need to be in the base candle time frame: -`startup_candles` = ( 4 hours * 20 max period * 60 minutes/hour + 30 day train_period_days * 1440 minutes per day ) / 5 min (base time frame) = 9360. - -!!! Note - In dry/live mode, this is all precomputed and handled automatically. Thus, `startup_candle` has no influence on dry/live mode. - !!! Note Although fractional `backtest_period_days` is allowed, the user should be aware that the `--timerange` is divided by this value to determine the number of models that FreqAI will need to train in order to backtest the full range. For example, if the user wants to set a `--timerange` of 10 days, and asks for a `backtest_period_days` of 0.1, FreqAI will need to train 100 models per pair to complete the full backtest. Because of this, a true backtest of FreqAI adaptive training would take a *very* long time. The best way to fully test a model is to run it dry and let it constantly train. In this case, backtesting would take the exact same amount of time as a dry run. +### Downloading data for backtesting +Live/dry instances will download the data automatically for the user, but users who wish to use backtesting functionality still need to download the necessary data using `download-data` (details [here](data-download/#data-downloading)). FreqAI users need to pay careful attention to understanding how much *additional* data needs to be downloaded to ensure that they have a sufficient amount of training data *before* the start of their backtesting timerange. The amount of additional data can be roughly estimated by taking subtracting `train_period_days` and the `startup_candle_count` ([details](#setting-the-startupcandlecount)) from the beginning of the desired backtesting timerange. + +As an example, if we wish to backtest the `--timerange` above of `20210501-20210701`, and we use the example config which sets `train_period_days` to 15. The startup candle count is 40 on a maximum `include_timeframes` of 1h. We would need 20210501 - 15 days - 40 * 1h / 24 hours = 20210414 (16.7 days earlier than the start of the desired training timerange). + ### Defining model expirations During dry/live mode, FreqAI trains each coin pair sequentially (on separate threads/GPU from the main Freqtrade bot). This means that there is always an age discrepancy between models. If a user is training on 50 pairs, and each pair requires 5 minutes to train, the oldest model will be over 4 hours old. This may be undesirable if the characteristic time scale (the trade duration target) for a strategy is less than 4 hours. The user can decide to only make trade entries if the model is less than diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index f88e20223..13af1e0d2 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -70,7 +70,7 @@ class FreqaiDataKitchen: self.training_features_list: List = [] self.model_filename: str = "" self.backtesting_results_path = Path() - self.backtesting_prediction_folder: str = "backtesting_predictions" + self.backtest_predictions_folder: str = "backtesting_predictions" self.live = live self.pair = pair @@ -1077,7 +1077,7 @@ class FreqaiDataKitchen: Save prediction dataframe from backtesting to h5 file format :param append_df: dataframe for backtesting period """ - full_predictions_folder = Path(self.full_path / self.backtesting_prediction_folder) + full_predictions_folder = Path(self.full_path / self.backtest_predictions_folder) if not full_predictions_folder.is_dir(): full_predictions_folder.mkdir(parents=True, exist_ok=True) @@ -1092,3 +1092,26 @@ class FreqaiDataKitchen: """ append_df = pd.read_hdf(self.backtesting_results_path) return append_df + + def check_if_backtest_prediction_exists( + self + ) -> bool: + """ + Check if a backtesting prediction already exists + :param dk: FreqaiDataKitchen + :return: + :boolean: whether the prediction file exists or not. + """ + path_to_predictionfile = Path(self.full_path / + self.backtest_predictions_folder / + f"{self.model_filename}_prediction.h5") + self.backtesting_results_path = path_to_predictionfile + + file_exists = path_to_predictionfile.is_file() + if file_exists: + logger.info(f"Found backtesting prediction file at {path_to_predictionfile}") + else: + logger.info( + f"Could not find backtesting prediction file at {path_to_predictionfile}" + ) + return file_exists diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index 9c7ef05a7..399568c7d 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -71,7 +71,9 @@ class IFreqaiModel(ABC): self.first = True self.set_full_path() self.follow_mode: bool = self.freqai_info.get("follow_mode", False) - self.backtest_save_model: bool = self.freqai_info.get("backtest_save_model", True) + self.save_backtest_models: bool = self.freqai_info.get("save_backtest_models", False) + if self.save_backtest_models: + logger.info('Backtesting module configured to save all models.') self.dd = FreqaiDataDrawer(Path(self.full_path), self.config, self.follow_mode) self.identifier: str = self.freqai_info.get("identifier", "no_id_provided") self.scanning = False @@ -125,10 +127,9 @@ class IFreqaiModel(ABC): elif not self.follow_mode: self.dk = FreqaiDataKitchen(self.config, self.live, metadata["pair"]) logger.info(f"Training {len(self.dk.training_timeranges)} timeranges") - with self.analysis_lock: - dataframe = self.dk.use_strategy_to_populate_indicators( - strategy, prediction_dataframe=dataframe, pair=metadata["pair"] - ) + dataframe = self.dk.use_strategy_to_populate_indicators( + strategy, prediction_dataframe=dataframe, pair=metadata["pair"] + ) dk = self.start_backtesting(dataframe, metadata, self.dk) dataframe = dk.remove_features_from_df(dk.return_dataframe) @@ -232,10 +233,9 @@ class IFreqaiModel(ABC): f"sub-train-{metadata['pair'].split('/')[0]}_{trained_timestamp_int}" ) - coin, _ = metadata["pair"].split("/") - dk.model_filename = f"cb_{coin.lower()}_{trained_timestamp_int}" + dk.set_new_model_names(metadata["pair"], trained_timestamp) - if self.backtest_prediction_exists(dk): + if dk.check_if_backtest_prediction_exists(): append_df = dk.get_backtesting_prediction() dk.append_predictions(append_df) else: @@ -246,8 +246,9 @@ class IFreqaiModel(ABC): self.model = self.train(dataframe_train, metadata["pair"], dk) self.dd.pair_dict[metadata["pair"]]["trained_timestamp"] = int( trained_timestamp.stopts) - dk.set_new_model_names(metadata["pair"], trained_timestamp) - if self.backtest_save_model: + + if self.save_backtest_models: + logger.info('Saving backtest model to disk.') self.dd.save_data(self.model, metadata["pair"], dk) else: self.model = self.dd.load_data(metadata["pair"], dk) @@ -644,35 +645,6 @@ class IFreqaiModel(ABC): self.train_time = 0 return - def backtest_prediction_exists( - self, - dk: FreqaiDataKitchen, - scanning: bool = False, - ) -> bool: - """ - Check if a backtesting prediction already exists - :param dk: FreqaiDataKitchen - :return: - :boolean: whether the prediction file exists or not. - """ - if not self.live: - prediction_file_name = dk.model_filename - path_to_predictionfile = Path(dk.full_path / - dk.backtesting_prediction_folder / - f"{prediction_file_name}_prediction.h5") - dk.backtesting_results_path = path_to_predictionfile - - file_exists = path_to_predictionfile.is_file() - if file_exists and not scanning: - logger.info("Found backtesting prediction file at %s", prediction_file_name) - elif not scanning: - logger.info( - "Could not find backtesting prediction file at %s", prediction_file_name - ) - return file_exists - else: - return False - # Following methods which are overridden by user made prediction models. # See freqai/prediction_models/CatboostPredictionModel.py for an example. diff --git a/freqtrade/templates/FreqaiExampleStrategy.py b/freqtrade/templates/FreqaiExampleStrategy.py index aa584bfbc..0e822a028 100644 --- a/freqtrade/templates/FreqaiExampleStrategy.py +++ b/freqtrade/templates/FreqaiExampleStrategy.py @@ -44,7 +44,7 @@ class FreqaiExampleStrategy(IStrategy): stoploss = -0.05 use_exit_signal = True # this is the maximum period fed to talib (timeframe independent) - startup_candle_count: int = 20 + startup_candle_count: int = 40 can_short = False linear_roi_offset = DecimalParameter( diff --git a/tests/freqai/test_freqai_interface.py b/tests/freqai/test_freqai_interface.py index 09f5d27ff..5441b3c24 100644 --- a/tests/freqai/test_freqai_interface.py +++ b/tests/freqai/test_freqai_interface.py @@ -174,6 +174,7 @@ def test_train_model_in_series_LightGBMClassifier(mocker, freqai_conf): def test_start_backtesting(mocker, freqai_conf): freqai_conf.update({"timerange": "20180120-20180130"}) + freqai_conf.get("freqai", {}).update({"save_backtest_models": True}) strategy = get_patched_freqai_strategy(mocker, freqai_conf) exchange = get_patched_exchange(mocker, freqai_conf) strategy.dp = DataProvider(freqai_conf, exchange) @@ -200,6 +201,7 @@ def test_start_backtesting(mocker, freqai_conf): def test_start_backtesting_subdaily_backtest_period(mocker, freqai_conf): freqai_conf.update({"timerange": "20180120-20180124"}) freqai_conf.get("freqai", {}).update({"backtest_period_days": 0.5}) + freqai_conf.get("freqai", {}).update({"save_backtest_models": True}) strategy = get_patched_freqai_strategy(mocker, freqai_conf) exchange = get_patched_exchange(mocker, freqai_conf) strategy.dp = DataProvider(freqai_conf, exchange) @@ -224,6 +226,7 @@ def test_start_backtesting_subdaily_backtest_period(mocker, freqai_conf): def test_start_backtesting_from_existing_folder(mocker, freqai_conf, caplog): freqai_conf.update({"timerange": "20180120-20180130"}) + freqai_conf.get("freqai", {}).update({"save_backtest_models": True}) strategy = get_patched_freqai_strategy(mocker, freqai_conf) exchange = get_patched_exchange(mocker, freqai_conf) strategy.dp = DataProvider(freqai_conf, exchange) @@ -263,10 +266,14 @@ def test_start_backtesting_from_existing_folder(mocker, freqai_conf, caplog): freqai.start_backtesting(df, metadata, freqai.dk) assert log_has_re( - "Found backtesting prediction ", + "Found backtesting prediction file ", caplog, ) + path = (freqai.dd.full_path / freqai.dk.backtest_predictions_folder) + prediction_files = [x for x in path.iterdir() if x.is_file()] + assert len(prediction_files) == 5 + shutil.rmtree(Path(freqai.dk.full_path)) From 80b5f035aba23f382363dc81499477977cea1e27 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 3 Sep 2022 15:01:28 +0200 Subject: [PATCH 31/65] Remove typo in log message --- freqtrade/freqai/freqai_interface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index 6b4ac183a..0bd88c64f 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -613,8 +613,8 @@ class IFreqaiModel(ABC): logger.info( f'Total time spent inferencing pairlist {self.inference_time:.2f} seconds') if self.inference_time > 0.25 * self.base_tf_seconds: - logger.warning('Inference took over 25/% of the candle time. Reduce pairlist to' - ' avoid blinding open trades and degrading performance.') + logger.warning("Inference took over 25% of the candle time. Reduce pairlist to" + " avoid blinding open trades and degrading performance.") self.pair_it = 0 self.inference_time = 0 return From df50b1928d6d58b130d1d2b40dcaad334800bcc3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 2 Sep 2022 06:51:30 +0200 Subject: [PATCH 32/65] Fix funding fee calculation for backtesting --- freqtrade/optimize/backtesting.py | 2 +- freqtrade/persistence/trade_model.py | 34 +++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 77bf3d8ad..8f6b6b332 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -686,7 +686,7 @@ class Backtesting: self.futures_data[trade.pair], amount=trade.amount, is_short=trade.is_short, - open_date=trade.open_date_utc, + open_date=trade.date_last_filled_utc, close_date=exit_candle_time, ) diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index 1f14f110e..9c9c7f381 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -65,6 +65,8 @@ class Order(_DECL_BASE): order_filled_date = Column(DateTime, nullable=True) order_update_date = Column(DateTime, nullable=True) + funding_fee = Column(Float, nullable=True) + ft_fee_base = Column(Float, nullable=True) @property @@ -72,6 +74,13 @@ class Order(_DECL_BASE): """ Order-date with UTC timezoneinfo""" return self.order_date.replace(tzinfo=timezone.utc) + @property + def order_filled_utc(self) -> Optional[datetime]: + """ last order-date with UTC timezoneinfo""" + return ( + self.order_filled_date.replace(tzinfo=timezone.utc) if self.order_filled_date else None + ) + @property def safe_price(self) -> float: return self.average or self.price @@ -179,6 +188,10 @@ class Order(_DECL_BASE): self.remaining = 0 self.status = 'closed' self.ft_is_open = False + # Assign funding fees to Order. + # Assumes backtesting will use date_last_filled_utc to calculate future funding fees. + self.funding_fee = trade.funding_fees + if (self.ft_order_side == trade.entry_side): trade.open_rate = self.price trade.recalc_trade_from_orders() @@ -346,6 +359,12 @@ class LocalTrade(): else: return self.amount + @property + def date_last_filled_utc(self): + """ Date of the last filled order""" + return max([self.open_date_utc, + max(o.order_filled_utc for o in self.orders if o.filled and not o.ft_is_open)]) + @property def open_date_utc(self): return self.open_date.replace(tzinfo=timezone.utc) @@ -843,10 +862,14 @@ class LocalTrade(): close_profit = 0.0 close_profit_abs = 0.0 profit = None - for o in self.orders: + # Reset funding fees + self.funding_fees = 0.0 + funding_fees = 0.0 + ordercount = len(self.orders) - 1 + for i, o in enumerate(self.orders): if o.ft_is_open or not o.filled: continue - + funding_fees += (o.funding_fee or 0.0) tmp_amount = FtPrecise(o.safe_amount_after_fee) tmp_price = FtPrecise(o.safe_price) @@ -861,7 +884,11 @@ class LocalTrade(): avg_price = current_stake / current_amount if is_exit: - # Process partial exits + # Process exits + if i == ordercount and is_closing: + # Apply funding fees only to the last order + self.funding_fees = funding_fees + exit_rate = o.safe_price exit_amount = o.safe_amount_after_fee profit = self.calc_profit(rate=exit_rate, amount=exit_amount, @@ -871,6 +898,7 @@ class LocalTrade(): exit_rate, amount=exit_amount, open_rate=avg_price) else: total_stake = total_stake + self._calc_open_trade_value(tmp_amount, price) + self.funding_fees = funding_fees if close_profit: self.close_profit = close_profit From 0c6a02687a49b48c433ec841200911b21efc8f24 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 2 Sep 2022 20:55:13 +0200 Subject: [PATCH 33/65] Don't calculate funding fees if we're not going to use them. --- freqtrade/freqtradebot.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 37bc6dfed..95b42155f 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -726,10 +726,11 @@ class FreqtradeBot(LoggingMixin): fee = self.exchange.get_fee(symbol=pair, taker_or_maker='maker') base_currency = self.exchange.get_pair_base_currency(pair) open_date = datetime.now(timezone.utc) - funding_fees = self.exchange.get_funding_fees( - pair=pair, amount=amount, is_short=is_short, open_date=open_date) + # This is a new trade if trade is None: + funding_fees = self.exchange.get_funding_fees( + pair=pair, amount=amount, is_short=is_short, open_date=open_date) trade = Trade( pair=pair, base_currency=base_currency, From 0f483ee31f043ceafaa7a5c19eaa77ade2e1d323 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 3 Sep 2022 10:06:23 +0200 Subject: [PATCH 34/65] Use "since last order" approach for live as well. --- freqtrade/freqtradebot.py | 4 ++-- freqtrade/persistence/trade_model.py | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 95b42155f..5323a5fc0 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -281,7 +281,7 @@ class FreqtradeBot(LoggingMixin): pair=trade.pair, amount=trade.amount, is_short=trade.is_short, - open_date=trade.open_date_utc + open_date=trade.date_last_filled_utc ) trade.funding_fees = funding_fees else: @@ -1485,7 +1485,7 @@ class FreqtradeBot(LoggingMixin): pair=trade.pair, amount=trade.amount, is_short=trade.is_short, - open_date=trade.open_date_utc, + open_date=trade.date_last_filled_utc, ) exit_type = 'exit' exit_reason = exit_tag or exit_check.exit_reason diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index 9c9c7f381..c2a87daaa 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -128,6 +128,10 @@ class Order(_DECL_BASE): self.ft_is_open = True if self.status in NON_OPEN_EXCHANGE_STATES: self.ft_is_open = False + if self.trade: + # Assign funding fee up to this point + # (represents the funding fee since the last order) + self.funding_fee = self.trade.funding_fees if (order.get('filled', 0.0) or 0.0) > 0: self.order_filled_date = datetime.now(timezone.utc) self.order_update_date = datetime.now(timezone.utc) @@ -360,10 +364,12 @@ class LocalTrade(): return self.amount @property - def date_last_filled_utc(self): + def date_last_filled_utc(self) -> datetime: """ Date of the last filled order""" - return max([self.open_date_utc, - max(o.order_filled_utc for o in self.orders if o.filled and not o.ft_is_open)]) + orders = self.select_filled_orders() + if not orders: + return self.open_date_utc + return max([self.open_date_utc, max(o.order_filled_utc for o in orders)]) @property def open_date_utc(self): From b95b3d8391f4df3bb3510173711349d7356a08ec Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 3 Sep 2022 15:09:50 +0200 Subject: [PATCH 35/65] Update test to actually test funding fee appliance --- tests/test_persistence.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 23ccc67f3..cdca3bc4d 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -615,21 +615,25 @@ def test_calc_open_close_trade_price( is_short=is_short, leverage=lev, trading_mode=trading_mode, - funding_fees=funding_fees ) entry_order = limit_order[trade.entry_side] exit_order = limit_order[trade.exit_side] trade.open_order_id = f'something-{is_short}-{lev}-{exchange}' oobj = Order.parse_from_ccxt_object(entry_order, 'ADA/USDT', trade.entry_side) - trade.orders.append(oobj) + oobj.trade = trade + oobj.update_from_ccxt_object(entry_order) trade.update_trade(oobj) + trade.funding_fees = funding_fees + oobj = Order.parse_from_ccxt_object(exit_order, 'ADA/USDT', trade.exit_side) - trade.orders.append(oobj) + oobj.trade = trade + oobj.update_from_ccxt_object(exit_order) trade.update_trade(oobj) assert trade.is_open is False + assert trade.funding_fees == funding_fees assert pytest.approx(trade._calc_open_trade_value(trade.amount, trade.open_rate)) == open_value assert pytest.approx(trade.calc_close_trade_value(trade.close_rate)) == close_value From ed4cc18cddaaff7bdb95738ee4a3d5093530b0e0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 3 Sep 2022 15:18:09 +0200 Subject: [PATCH 36/65] Migration to check order funding fee --- freqtrade/persistence/migrations.py | 10 ++++++---- freqtrade/persistence/trade_model.py | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/freqtrade/persistence/migrations.py b/freqtrade/persistence/migrations.py index 1131c88b4..1f1330ba7 100644 --- a/freqtrade/persistence/migrations.py +++ b/freqtrade/persistence/migrations.py @@ -212,17 +212,18 @@ def migrate_orders_table(engine, table_back_name: str, cols_order: List): ft_fee_base = get_column_def(cols_order, 'ft_fee_base', 'null') average = get_column_def(cols_order, 'average', 'null') stop_price = get_column_def(cols_order, 'stop_price', 'null') + funding_fee = get_column_def(cols_order, 'funding_fee', '0.0') # sqlite does not support literals for booleans with engine.begin() as connection: connection.execute(text(f""" insert into orders (id, ft_trade_id, ft_order_side, ft_pair, ft_is_open, order_id, status, symbol, order_type, side, price, amount, filled, average, remaining, cost, - stop_price, order_date, order_filled_date, order_update_date, ft_fee_base) + stop_price, order_date, order_filled_date, order_update_date, ft_fee_base, funding_fee) select id, ft_trade_id, ft_order_side, ft_pair, ft_is_open, order_id, status, symbol, order_type, side, price, amount, filled, {average} average, remaining, cost, {stop_price} stop_price, order_date, order_filled_date, - order_update_date, {ft_fee_base} ft_fee_base + order_update_date, {ft_fee_base} ft_fee_base {funding_fee} funding_fee from {table_back_name} """)) @@ -307,9 +308,10 @@ def check_migrate(engine, decl_base, previous_tables) -> None: # Check if migration necessary # Migrates both trades and orders table! # if ('orders' not in previous_tables - # or not has_column(cols_orders, 'stop_price')): + # or not has_column(cols_orders, 'funding_fee')): migrating = False - if not has_column(cols_trades, 'contract_size'): + if not has_column(cols_orders, 'funding_fee'): + # if not has_column(cols_trades, 'contract_size'): migrating = True logger.info(f"Running database migration for trades - " f"backup: {table_back_name}, {order_table_bak_name}") diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index c2a87daaa..6127c502d 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -892,7 +892,7 @@ class LocalTrade(): if is_exit: # Process exits if i == ordercount and is_closing: - # Apply funding fees only to the last order + # Apply funding fees only to the last closing order self.funding_fees = funding_fees exit_rate = o.safe_price From c21808ff9830b8f0e98b93fdc1e998b4ee37b4c0 Mon Sep 17 00:00:00 2001 From: robcaulk Date: Sat, 3 Sep 2022 16:54:30 +0200 Subject: [PATCH 37/65] remove metadata redundancy, fix pca bug --- freqtrade/freqai/data_kitchen.py | 55 +++++++++++++++----------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index 69ce5272d..ff8f72490 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -288,25 +288,20 @@ class FreqaiDataKitchen: :data_dictionary: updated dictionary with standardized values. """ - df_train_features = data_dictionary["train_features"] + df = data_dictionary["train_features"] # standardize the data by training stats - train_max = df_train_features.max() - train_min = df_train_features.min() - df_train_features = ( - 2 * (df_train_features - train_min) / (train_max - train_min) - 1 + train_max = df.max() + train_min = df.min() + df = ( + 2 * (df - train_min) / (train_max - train_min) - 1 ) data_dictionary["test_features"] = ( 2 * (data_dictionary["test_features"] - train_min) / (train_max - train_min) - 1 ) for item in train_max.keys(): - if not [col for col in df_train_features.columns if col.startswith('PC')]: - self.data[item + "_max"] = train_max[item] - self.data[item + "_min"] = train_min[item] - else: - # if PCA is enabled and has transformed the training features - self.data[item + "_pca_max"] = train_max[item] - self.data[item + "_pca_min"] = train_min[item] + self.data[item + "_max"] = train_max[item] + self.data[item + "_min"] = train_min[item] for item in data_dictionary["train_labels"].keys(): if data_dictionary["train_labels"][item].dtype == object: @@ -327,16 +322,24 @@ class FreqaiDataKitchen: - 1 ) - if not [col for col in df_train_features.columns if col.startswith('PC')]: - self.data[f"{item}_max"] = train_labels_max # .to_dict() - self.data[f"{item}_min"] = train_labels_min # .to_dict() - else: - # if PCA is enabled and has transformed the training features - self.data[f"{item}_pca_max"] = train_labels_max # .to_dict() - self.data[f"{item}_pca_min"] = train_labels_min # .to_dict() - + self.data[f"{item}_max"] = train_labels_max + self.data[f"{item}_min"] = train_labels_min return data_dictionary + def normalize_single_dataframe(self, df: DataFrame) -> DataFrame: + + train_max = df.max() + train_min = df.min() + df = ( + 2 * (df - train_min) / (train_max - train_min) - 1 + ) + + for item in train_max.keys(): + self.data[item + "_max"] = train_max[item] + self.data[item + "_min"] = train_min[item] + + return df + def normalize_data_from_metadata(self, df: DataFrame) -> DataFrame: """ Normalize a set of data using the mean and standard deviation from @@ -344,17 +347,11 @@ class FreqaiDataKitchen: :param df: Dataframe to be standardized """ - if not [col for col in df.columns if col.startswith('PC')]: - id_str = '' - else: - # if PCA is enabled - id_str = '_pca' - for item in df.keys(): df[item] = ( 2 - * (df[item] - self.data[f"{item}{id_str}_min"]) - / (self.data[f"{item}{id_str}_max"] - self.data[f"{item}{id_str}_min"]) + * (df[item] - self.data[f"{item}_min"]) + / (self.data[f"{item}_max"] - self.data[f"{item}_min"]) - 1 ) @@ -484,7 +481,7 @@ class FreqaiDataKitchen: index=self.data_dictionary["train_features"].index, ) # normalsing transformed training features - self.data_dictionary["train_features"] = self.normalize_data( + self.data_dictionary["train_features"] = self.normalize_single_dataframe( self.data_dictionary["train_features"]) # keeping a copy of the non-transformed features so we can check for errors during From 5cfb4154ebce933997cd45b0e1d3c57876271e5f Mon Sep 17 00:00:00 2001 From: robcaulk Date: Sat, 3 Sep 2022 19:48:30 +0200 Subject: [PATCH 38/65] revert all changes in normalize_data() --- freqtrade/freqai/data_kitchen.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index ff8f72490..3335503d3 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -288,12 +288,11 @@ class FreqaiDataKitchen: :data_dictionary: updated dictionary with standardized values. """ - df = data_dictionary["train_features"] # standardize the data by training stats - train_max = df.max() - train_min = df.min() - df = ( - 2 * (df - train_min) / (train_max - train_min) - 1 + train_max = data_dictionary["train_features"].max() + train_min = data_dictionary["train_features"].min() + data_dictionary["train_features"] = ( + 2 * (data_dictionary["train_features"] - train_min) / (train_max - train_min) - 1 ) data_dictionary["test_features"] = ( 2 * (data_dictionary["test_features"] - train_min) / (train_max - train_min) - 1 @@ -322,8 +321,8 @@ class FreqaiDataKitchen: - 1 ) - self.data[f"{item}_max"] = train_labels_max - self.data[f"{item}_min"] = train_labels_min + self.data[f"{item}_max"] = train_labels_max + self.data[f"{item}_min"] = train_labels_min return data_dictionary def normalize_single_dataframe(self, df: DataFrame) -> DataFrame: From 16573b19e3d478b3a5625a81d2504823dee4cdf8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 3 Sep 2022 19:34:38 +0200 Subject: [PATCH 39/65] Fix migration syntax error --- freqtrade/persistence/migrations.py | 4 ++-- freqtrade/persistence/trade_model.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/freqtrade/persistence/migrations.py b/freqtrade/persistence/migrations.py index 1f1330ba7..a54c5570f 100644 --- a/freqtrade/persistence/migrations.py +++ b/freqtrade/persistence/migrations.py @@ -223,7 +223,7 @@ def migrate_orders_table(engine, table_back_name: str, cols_order: List): select id, ft_trade_id, ft_order_side, ft_pair, ft_is_open, order_id, status, symbol, order_type, side, price, amount, filled, {average} average, remaining, cost, {stop_price} stop_price, order_date, order_filled_date, - order_update_date, {ft_fee_base} ft_fee_base {funding_fee} funding_fee + order_update_date, {ft_fee_base} ft_fee_base, {funding_fee} funding_fee from {table_back_name} """)) @@ -310,8 +310,8 @@ def check_migrate(engine, decl_base, previous_tables) -> None: # if ('orders' not in previous_tables # or not has_column(cols_orders, 'funding_fee')): migrating = False - if not has_column(cols_orders, 'funding_fee'): # if not has_column(cols_trades, 'contract_size'): + if not has_column(cols_orders, 'funding_fee'): migrating = True logger.info(f"Running database migration for trades - " f"backup: {table_back_name}, {order_table_bak_name}") diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index 6127c502d..ea60796a4 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -369,7 +369,8 @@ class LocalTrade(): orders = self.select_filled_orders() if not orders: return self.open_date_utc - return max([self.open_date_utc, max(o.order_filled_utc for o in orders)]) + return max([self.open_date_utc, + max(o.order_filled_utc for o in orders if o.order_filled_utc)]) @property def open_date_utc(self): From dae3b3d86adde0f6c7065ce1d083d9ceac62e5ef Mon Sep 17 00:00:00 2001 From: Timothy Pogue Date: Sat, 3 Sep 2022 13:24:14 -0600 Subject: [PATCH 40/65] support shutting down freqai --- freqtrade/freqai/freqai_interface.py | 37 +++++++++++++++++++--------- freqtrade/freqtradebot.py | 2 ++ freqtrade/strategy/interface.py | 10 ++++++++ 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index eac5cba07..a9c21fb65 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -7,7 +7,7 @@ import time from abc import ABC, abstractmethod from pathlib import Path from threading import Lock -from typing import Any, Dict, Tuple +from typing import Any, Dict, List, Tuple import numpy as np import pandas as pd @@ -27,13 +27,6 @@ pd.options.mode.chained_assignment = None logger = logging.getLogger(__name__) -def threaded(fn): - def wrapper(*args, **kwargs): - threading.Thread(target=fn, args=args, kwargs=kwargs).start() - - return wrapper - - class IFreqaiModel(ABC): """ Class containing all tools for training and prediction in the strategy. @@ -94,6 +87,9 @@ class IFreqaiModel(ABC): self.begin_time_train: float = 0 self.base_tf_seconds = timeframe_to_seconds(self.config['timeframe']) + self._threads: List[threading.Thread] = [] + self._stop_event = threading.Event() + def assert_config(self, config: Dict[str, Any]) -> None: if not config.get("freqai", {}): @@ -147,15 +143,34 @@ class IFreqaiModel(ABC): self.model = None self.dk = None - @threaded - def start_scanning(self, strategy: IStrategy) -> None: + def shutdown(self): + """ + Cleans up threads on Shutdown, set stop event. Join threads to wait + for current training iteration. + """ + logger.info("Stopping FreqAI") + self._stop_event.set() + + logger.info("Waiting on Training iteration") + for _thread in self._threads: + _thread.join() + + def start_scanning(self, *args, **kwargs) -> None: + """ + Start `self._start_scanning` in a separate thread + """ + _thread = threading.Thread(target=self._start_scanning, args=args, kwargs=kwargs) + self._threads.append(_thread) + _thread.start() + + def _start_scanning(self, strategy: IStrategy) -> None: """ Function designed to constantly scan pairs for retraining on a separate thread (intracandle) to improve model youth. This function is agnostic to data preparation/collection/storage, it simply trains on what ever data is available in the self.dd. :param strategy: IStrategy = The user defined strategy class """ - while 1: + while not self._stop_event.is_set(): time.sleep(1) for pair in self.config.get("exchange", {}).get("pair_whitelist"): diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 37bc6dfed..883417219 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -148,6 +148,8 @@ class FreqtradeBot(LoggingMixin): self.check_for_open_trades() + self.strategy.ft_bot_cleanup() + self.rpc.cleanup() Trade.commit() self.exchange.close() diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index c7ea95bda..562a16b18 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -168,6 +168,10 @@ class IStrategy(ABC, HyperStrategyMixin): raise OperationalException( 'freqAI is not enabled. ' 'Please enable it in your config to use this strategy.') + + def cleanup(self, *args, **kwargs): + pass + self.freqai = DummyClass() # type: ignore def ft_bot_start(self, **kwargs) -> None: @@ -181,6 +185,12 @@ class IStrategy(ABC, HyperStrategyMixin): self.ft_load_hyper_params(self.config.get('runmode') == RunMode.HYPEROPT) + def ft_bot_cleanup(self) -> None: + """ + Clean up FreqAI and child threads + """ + self.freqai.shutdown() + @abstractmethod def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ From 3b5e5fc57b7a11402c76f13bddede071bd9eaf9e Mon Sep 17 00:00:00 2001 From: Timothy Pogue Date: Sat, 3 Sep 2022 14:10:23 -0600 Subject: [PATCH 41/65] fix method name in dummy class --- freqtrade/strategy/interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 562a16b18..70cc7fdb3 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -169,7 +169,7 @@ class IStrategy(ABC, HyperStrategyMixin): 'freqAI is not enabled. ' 'Please enable it in your config to use this strategy.') - def cleanup(self, *args, **kwargs): + def shutdown(self, *args, **kwargs): pass self.freqai = DummyClass() # type: ignore From ec76214d023a6c53ffab0af8d43bc5b72b1d66af Mon Sep 17 00:00:00 2001 From: robcaulk Date: Sun, 4 Sep 2022 15:56:07 +0200 Subject: [PATCH 42/65] backup historical predictions pickle and load the backup in case of corruption --- freqtrade/freqai/data_drawer.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/freqtrade/freqai/data_drawer.py b/freqtrade/freqai/data_drawer.py index b6a1a15d7..9eeabef8f 100644 --- a/freqtrade/freqai/data_drawer.py +++ b/freqtrade/freqai/data_drawer.py @@ -76,6 +76,8 @@ class FreqaiDataDrawer: self.full_path / f"follower_dictionary-{self.follower_name}.json" ) self.historic_predictions_path = Path(self.full_path / "historic_predictions.pkl") + self.historic_predictions_bkp_path = Path( + self.full_path / "historic_predictions.backup.pkl") self.pair_dictionary_path = Path(self.full_path / "pair_dictionary.json") self.follow_mode = follow_mode if follow_mode: @@ -118,13 +120,21 @@ class FreqaiDataDrawer: """ exists = self.historic_predictions_path.is_file() if exists: - with open(self.historic_predictions_path, "rb") as fp: - self.historic_predictions = cloudpickle.load(fp) - logger.info( - f"Found existing historic predictions at {self.full_path}, but beware " - "that statistics may be inaccurate if the bot has been offline for " - "an extended period of time." - ) + try: + with open(self.historic_predictions_path, "rb") as fp: + self.historic_predictions = cloudpickle.load(fp) + logger.info( + f"Found existing historic predictions at {self.full_path}, but beware " + "that statistics may be inaccurate if the bot has been offline for " + "an extended period of time." + ) + except EOFError: + logger.warning( + 'Historical prediction file was corrupted. Trying to load backup file.') + with open(self.historic_predictions_bkp_path, "rb") as fp: + self.historic_predictions = cloudpickle.load(fp) + logger.warning('FreqAI successfully loaded the backup historical predictions file.') + elif not self.follow_mode: logger.info("Could not find existing historic_predictions, starting from scratch") else: @@ -142,6 +152,9 @@ class FreqaiDataDrawer: with open(self.historic_predictions_path, "wb") as fp: cloudpickle.dump(self.historic_predictions, fp, protocol=cloudpickle.DEFAULT_PROTOCOL) + # create a backup + shutil.copy(self.historic_predictions_path, self.historic_predictions_bkp_path) + def save_drawer_to_disk(self): """ Save data drawer full of all pair model metadata in present model folder. From d43ed186fcc375f9087b059a00d2fb3b5ec6fdfe Mon Sep 17 00:00:00 2001 From: Wagner Costa Santos Date: Sun, 4 Sep 2022 16:55:47 -0300 Subject: [PATCH 43/65] fix issue with freqai backtesting at slice dataframe --- freqtrade/freqai/data_kitchen.py | 15 +++++++++++++++ freqtrade/freqai/freqai_interface.py | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index 7595942fe..d525ae4ac 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -458,6 +458,21 @@ class FreqaiDataKitchen: return df + def slice_dataframe_backtesting(self, timerange: TimeRange, df: DataFrame) -> DataFrame: + """ + Given a full dataframe, extract the user desired window + :param tr: timerange string that we wish to extract from df + :param df: Dataframe containing all candles to run the entire backtest. Here + it is sliced down to just the present training period. + """ + + start = datetime.datetime.fromtimestamp(timerange.startts, tz=datetime.timezone.utc) + stop = datetime.datetime.fromtimestamp(timerange.stopts, tz=datetime.timezone.utc) + df = df.loc[df["date"] >= start, :] + df = df.loc[df["date"] < stop, :] + + return df + def principal_component_analysis(self) -> None: """ Performs Principal Component Analysis on the data for dimensionality reduction diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index a9c21fb65..b17f8c9ab 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -225,8 +225,8 @@ class IFreqaiModel(ABC): train_it += 1 total_trains = len(dk.backtesting_timeranges) self.training_timerange = tr_train - dataframe_train = dk.slice_dataframe(tr_train, dataframe) - dataframe_backtest = dk.slice_dataframe(tr_backtest, dataframe) + dataframe_train = dk.slice_dataframe_backtesting(tr_train, dataframe) + dataframe_backtest = dk.slice_dataframe_backtesting(tr_backtest, dataframe) trained_timestamp = tr_train tr_train_startts_str = datetime.datetime.utcfromtimestamp(tr_train.startts).strftime( From 78d01810ed1dd3ecee954b914e9066267d5e969a Mon Sep 17 00:00:00 2001 From: robcaulk Date: Mon, 5 Sep 2022 00:07:05 +0200 Subject: [PATCH 44/65] reduce code redundancy, ensure live always gets the latest data --- freqtrade/freqai/data_kitchen.py | 18 ++---------------- freqtrade/freqai/freqai_interface.py | 4 ++-- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index d525ae4ac..828734520 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -454,22 +454,8 @@ class FreqaiDataKitchen: start = datetime.datetime.fromtimestamp(timerange.startts, tz=datetime.timezone.utc) stop = datetime.datetime.fromtimestamp(timerange.stopts, tz=datetime.timezone.utc) df = df.loc[df["date"] >= start, :] - df = df.loc[df["date"] <= stop, :] - - return df - - def slice_dataframe_backtesting(self, timerange: TimeRange, df: DataFrame) -> DataFrame: - """ - Given a full dataframe, extract the user desired window - :param tr: timerange string that we wish to extract from df - :param df: Dataframe containing all candles to run the entire backtest. Here - it is sliced down to just the present training period. - """ - - start = datetime.datetime.fromtimestamp(timerange.startts, tz=datetime.timezone.utc) - stop = datetime.datetime.fromtimestamp(timerange.stopts, tz=datetime.timezone.utc) - df = df.loc[df["date"] >= start, :] - df = df.loc[df["date"] < stop, :] + if not self.live: + df = df.loc[df["date"] < stop, :] return df diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index b17f8c9ab..a9c21fb65 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -225,8 +225,8 @@ class IFreqaiModel(ABC): train_it += 1 total_trains = len(dk.backtesting_timeranges) self.training_timerange = tr_train - dataframe_train = dk.slice_dataframe_backtesting(tr_train, dataframe) - dataframe_backtest = dk.slice_dataframe_backtesting(tr_backtest, dataframe) + dataframe_train = dk.slice_dataframe(tr_train, dataframe) + dataframe_backtest = dk.slice_dataframe(tr_backtest, dataframe) trained_timestamp = tr_train tr_train_startts_str = datetime.datetime.utcfromtimestamp(tr_train.startts).strftime( From c8a9ac900c2bdec9620c6d2745ee78a3d78cfbdc Mon Sep 17 00:00:00 2001 From: robcaulk Date: Mon, 5 Sep 2022 00:52:26 +0200 Subject: [PATCH 45/65] fix broken CI --- tests/freqai/test_freqai_datakitchen.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/freqai/test_freqai_datakitchen.py b/tests/freqai/test_freqai_datakitchen.py index 9ef955695..44c721515 100644 --- a/tests/freqai/test_freqai_datakitchen.py +++ b/tests/freqai/test_freqai_datakitchen.py @@ -74,7 +74,7 @@ def test_use_DBSCAN_to_remove_outliers(mocker, freqai_conf, caplog): # freqai_conf['freqai']['feature_parameters'].update({"outlier_protection_percentage": 1}) freqai.dk.use_DBSCAN_to_remove_outliers(predict=False) assert log_has_re( - "DBSCAN found eps of 2.42.", + "DBSCAN found eps of 2.36.", caplog, ) @@ -83,7 +83,7 @@ def test_compute_distances(mocker, freqai_conf): freqai = make_data_dictionary(mocker, freqai_conf) freqai_conf['freqai']['feature_parameters'].update({"DI_threshold": 1}) avg_mean_dist = freqai.dk.compute_distances() - assert round(avg_mean_dist, 2) == 2.56 + assert round(avg_mean_dist, 2) == 2.54 def test_use_SVM_to_remove_outliers_and_outlier_protection(mocker, freqai_conf, caplog): @@ -91,6 +91,6 @@ def test_use_SVM_to_remove_outliers_and_outlier_protection(mocker, freqai_conf, freqai_conf['freqai']['feature_parameters'].update({"outlier_protection_percentage": 0.1}) freqai.dk.use_SVM_to_remove_outliers(predict=False) assert log_has_re( - "SVM detected 8.46%", + "SVM detected 8.09%", caplog, ) From a035a69a61e344fa5b7a7a01e2f01cfad46de7af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Sep 2022 13:09:53 +0000 Subject: [PATCH 46/65] Bump arrow from 1.2.2 to 1.2.3 Bumps [arrow](https://github.com/arrow-py/arrow) from 1.2.2 to 1.2.3. - [Release notes](https://github.com/arrow-py/arrow/releases) - [Changelog](https://github.com/arrow-py/arrow/blob/master/CHANGELOG.rst) - [Commits](https://github.com/arrow-py/arrow/compare/1.2.2...1.2.3) --- updated-dependencies: - dependency-name: arrow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index cbd5e31ba..99139f92b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ cryptography==37.0.4 aiohttp==3.8.1 SQLAlchemy==1.4.40 python-telegram-bot==13.13 -arrow==1.2.2 +arrow==1.2.3 cachetools==4.2.2 requests==2.28.1 urllib3==1.26.12 From 7cc8ac0a3429f0fd40c2be30974457f32259d744 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Sep 2022 13:10:02 +0000 Subject: [PATCH 47/65] Bump psutil from 5.9.1 to 5.9.2 Bumps [psutil](https://github.com/giampaolo/psutil) from 5.9.1 to 5.9.2. - [Release notes](https://github.com/giampaolo/psutil/releases) - [Changelog](https://github.com/giampaolo/psutil/blob/master/HISTORY.rst) - [Commits](https://github.com/giampaolo/psutil/compare/release-5.9.1...release-5.9.2) --- updated-dependencies: - dependency-name: psutil dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index cbd5e31ba..240eb0057 100644 --- a/requirements.txt +++ b/requirements.txt @@ -38,7 +38,7 @@ fastapi==0.81.0 uvicorn==0.18.3 pyjwt==2.4.0 aiofiles==0.8.0 -psutil==5.9.1 +psutil==5.9.2 # Support for colorized terminal output colorama==0.4.5 From af7e4d7bf0a5ce6f47e7a46d6f55dd814a43e22d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Sep 2022 13:10:11 +0000 Subject: [PATCH 48/65] Bump pytest from 7.1.2 to 7.1.3 Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.1.2 to 7.1.3. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.1.2...7.1.3) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 26df7115c..40ca4e154 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -10,7 +10,7 @@ flake8==5.0.4 flake8-tidy-imports==4.8.0 mypy==0.971 pre-commit==2.20.0 -pytest==7.1.2 +pytest==7.1.3 pytest-asyncio==0.19.0 pytest-cov==3.0.0 pytest-mock==3.8.2 From 3d038568457a7cfadfc0765ecc1e2ca5867f04e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Sep 2022 13:10:31 +0000 Subject: [PATCH 49/65] Bump ccxt from 1.92.84 to 1.93.3 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.92.84 to 1.93.3. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg) - [Commits](https://github.com/ccxt/ccxt/compare/1.92.84...1.93.3) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index cbd5e31ba..d70eebdd8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ numpy==1.23.2 pandas==1.4.3 pandas-ta==0.3.14b -ccxt==1.92.84 +ccxt==1.93.3 # Pin cryptography for now due to rust build errors with piwheels cryptography==37.0.4 aiohttp==3.8.1 From 90fbb794712cce946ae65caeacafa0f8724ae691 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Sep 2022 13:10:44 +0000 Subject: [PATCH 50/65] Bump prompt-toolkit from 3.0.30 to 3.0.31 Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.30 to 3.0.31. - [Release notes](https://github.com/prompt-toolkit/python-prompt-toolkit/releases) - [Changelog](https://github.com/prompt-toolkit/python-prompt-toolkit/blob/master/CHANGELOG) - [Commits](https://github.com/prompt-toolkit/python-prompt-toolkit/compare/3.0.30...3.0.31) --- updated-dependencies: - dependency-name: prompt-toolkit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index cbd5e31ba..ff1eabe38 100644 --- a/requirements.txt +++ b/requirements.txt @@ -44,7 +44,7 @@ psutil==5.9.1 colorama==0.4.5 # Building config files interactively questionary==1.10.0 -prompt-toolkit==3.0.30 +prompt-toolkit==3.0.31 # Extensions to datetime library python-dateutil==2.8.2 From 6f6afca0277de0ffeab2d104fb4b1068446dafc3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Sep 2022 13:10:53 +0000 Subject: [PATCH 51/65] Bump fastapi from 0.81.0 to 0.82.0 Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.81.0 to 0.82.0. - [Release notes](https://github.com/tiangolo/fastapi/releases) - [Commits](https://github.com/tiangolo/fastapi/compare/0.81.0...0.82.0) --- updated-dependencies: - dependency-name: fastapi dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index cbd5e31ba..2ddf3fbd9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -34,7 +34,7 @@ orjson==3.8.0 sdnotify==0.3.2 # API Server -fastapi==0.81.0 +fastapi==0.82.0 uvicorn==0.18.3 pyjwt==2.4.0 aiofiles==0.8.0 From f5500350f9364fd619415e56cd9d43eb42911f78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Sep 2022 13:11:24 +0000 Subject: [PATCH 52/65] Bump pandas from 1.4.3 to 1.4.4 Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.4.3 to 1.4.4. - [Release notes](https://github.com/pandas-dev/pandas/releases) - [Changelog](https://github.com/pandas-dev/pandas/blob/main/RELEASE.md) - [Commits](https://github.com/pandas-dev/pandas/compare/v1.4.3...v1.4.4) --- updated-dependencies: - dependency-name: pandas dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index cbd5e31ba..6bd828059 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ numpy==1.23.2 -pandas==1.4.3 +pandas==1.4.4 pandas-ta==0.3.14b ccxt==1.92.84 From 48dc1f2d88bf82f5721aba621b6768cc953f6ca9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Sep 2022 13:11:29 +0000 Subject: [PATCH 53/65] Bump pycoingecko from 2.2.0 to 3.0.0 Bumps [pycoingecko](https://github.com/man-c/pycoingecko) from 2.2.0 to 3.0.0. - [Release notes](https://github.com/man-c/pycoingecko/releases) - [Changelog](https://github.com/man-c/pycoingecko/blob/master/CHANGELOG.md) - [Commits](https://github.com/man-c/pycoingecko/compare/2.2.0...3.0.0) --- updated-dependencies: - dependency-name: pycoingecko dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index cbd5e31ba..20796bd26 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ jsonschema==4.14.0 TA-Lib==0.4.24 technical==1.3.0 tabulate==0.8.10 -pycoingecko==2.2.0 +pycoingecko==3.0.0 jinja2==3.1.2 tables==3.7.0 blosc==1.10.6 From 9f5642fd972affbf12f16859e391a3f243bc45ad Mon Sep 17 00:00:00 2001 From: Italo <45588475+italodamato@users.noreply.github.com> Date: Mon, 5 Sep 2022 18:12:19 +0200 Subject: [PATCH 54/65] fix hyperopt df preprocessing --- freqtrade/optimize/hyperopt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index fea2a672f..4c8613a7a 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -423,7 +423,7 @@ class Hyperopt: # Trim startup period from analyzed dataframe to get correct dates for output. processed = trim_dataframes(preprocessed, self.timerange, self.backtesting.required_startup) self.min_date, self.max_date = get_timerange(processed) - return processed + return preprocessed def prepare_hyperopt_data(self) -> None: HyperoptStateContainer.set_state(HyperoptState.DATALOAD) From 949f618d42530d4c4ca3e6a06eba5b99443a8bd1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Sep 2022 16:30:43 +0000 Subject: [PATCH 55/65] Bump python-telegram-bot from 13.13 to 13.14 Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 13.13 to 13.14. - [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases) - [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/v13.14/CHANGES.rst) - [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v13.13...v13.14) --- updated-dependencies: - dependency-name: python-telegram-bot dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c7d55ba78..3cb321b2b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ ccxt==1.93.3 cryptography==37.0.4 aiohttp==3.8.1 SQLAlchemy==1.4.40 -python-telegram-bot==13.13 +python-telegram-bot==13.14 arrow==1.2.3 cachetools==4.2.2 requests==2.28.1 From 4628bfa580c49d8f80bf1372b66c95f6557b683c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Sep 2022 17:30:55 +0000 Subject: [PATCH 56/65] Bump jsonschema from 4.14.0 to 4.15.0 Bumps [jsonschema](https://github.com/python-jsonschema/jsonschema) from 4.14.0 to 4.15.0. - [Release notes](https://github.com/python-jsonschema/jsonschema/releases) - [Changelog](https://github.com/python-jsonschema/jsonschema/blob/main/CHANGELOG.rst) - [Commits](https://github.com/python-jsonschema/jsonschema/compare/v4.14.0...v4.15.0) --- updated-dependencies: - dependency-name: jsonschema dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 8b994cb88..fdbe6ac28 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ arrow==1.2.3 cachetools==4.2.2 requests==2.28.1 urllib3==1.26.12 -jsonschema==4.14.0 +jsonschema==4.15.0 TA-Lib==0.4.24 technical==1.3.0 tabulate==0.8.10 From 36e5c18fa600a3dbf3c58f6e2e7ee149a5b71ede Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 5 Sep 2022 20:54:03 +0200 Subject: [PATCH 57/65] Don't raise exception when a message is not implemented in telegram --- freqtrade/rpc/telegram.py | 12 +++++++----- tests/rpc/test_rpc_telegram.py | 10 +++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 8c988d570..4a759f6ec 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -6,6 +6,7 @@ This module manage Telegram communication import json import logging import re +from copy import deepcopy from dataclasses import dataclass from datetime import date, datetime, timedelta from functools import partial @@ -374,7 +375,7 @@ class Telegram(RPCHandler): message += f"\n*Duration:* `{msg['duration']} ({msg['duration_min']:.1f} min)`" return message - def compose_message(self, msg: Dict[str, Any], msg_type: RPCMessageType) -> str: + def compose_message(self, msg: Dict[str, Any], msg_type: RPCMessageType) -> Optional[str]: if msg_type in [RPCMessageType.ENTRY, RPCMessageType.ENTRY_FILL]: message = self._format_entry_msg(msg) @@ -411,7 +412,8 @@ class Telegram(RPCHandler): elif msg_type == RPCMessageType.STRATEGY_MSG: message = f"{msg['msg']}" else: - raise NotImplementedError(f"Unknown message type: {msg_type}") + logger.debug("Unknown message type: %s", msg_type) + return None return message def send_msg(self, msg: Dict[str, Any]) -> None: @@ -438,9 +440,9 @@ class Telegram(RPCHandler): # Notification disabled return - message = self.compose_message(msg, msg_type) - - self._send_msg(message, disable_notification=(noti == 'silent')) + message = self.compose_message(deepcopy(msg), msg_type) + if message: + self._send_msg(message, disable_notification=(noti == 'silent')) def _get_sell_emoji(self, msg): """ diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index cde7025a7..f2e490dff 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -2138,11 +2138,11 @@ def test_send_msg_strategy_msg_notification(default_conf, mocker) -> None: def test_send_msg_unknown_type(default_conf, mocker) -> None: - telegram, _, _ = get_telegram_testobject(mocker, default_conf) - with pytest.raises(NotImplementedError, match=r'Unknown message type: None'): - telegram.send_msg({ - 'type': None, - }) + telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf) + telegram.send_msg({ + 'type': None, + }) + msg_mock.call_count == 0 @pytest.mark.parametrize('message_type,enter,enter_signal,leverage', [ From 689b193240a77dc2e9619583a9bef3c9c7f07b56 Mon Sep 17 00:00:00 2001 From: robcaulk Date: Mon, 5 Sep 2022 20:57:42 +0200 Subject: [PATCH 58/65] improve clarity on data download requirements --- docs/freqai.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/freqai.md b/docs/freqai.md index 3646362c3..d04d2fa6b 100644 --- a/docs/freqai.md +++ b/docs/freqai.md @@ -280,7 +280,7 @@ The FreqAI strategy requires the user to include the following lines of code in Notice how the `populate_any_indicators()` is where the user adds their own features ([more information](#feature-engineering)) and labels ([more information](#setting-classifier-targets)). See a full example at `templates/FreqaiExampleStrategy.py`. ### Setting the `startup_candle_count` -Users need to take care to set the `startup_candle_count` in their strategy the same way they would for any normal Freqtrade strategy (see details [here](strategy-customization.md/#strategy-startup-period)). This value is used by Freqtrade to ensure that a sufficient amount of data is provided when calling on the `dataprovider` to avoid any NaNs at the beginning of the first training. Users can easily set this value by identifying the longest period (in candle units) that they pass to their indicator creation functions (e.g. talib functions). In the present example, the user would pass 20 to as this value (since it is the maximum value in their `indicators_periods_candles`). +Users need to take care to set the `startup_candle_count` in their strategy the same way they would for any normal Freqtrade strategy (see details [here](strategy-customization.md#strategy-startup-period)). This value is used by Freqtrade to ensure that a sufficient amount of data is provided when calling on the `dataprovider` to avoid any NaNs at the beginning of the first training. Users can easily set this value by identifying the longest period (in candle units) that they pass to their indicator creation functions (e.g. talib functions). In the present example, the user would pass 20 to as this value (since it is the maximum value in their `indicators_periods_candles`). !!! Note Typically it is best for users to be safe and multiply their expected `startup_candle_count` by 2. There are instances where the talib functions actually require more data than just the passed `period`. Anecdotally, multiplying the `startup_candle_count` by 2 always leads to a fully NaN free training dataset. Look out for this log message to confirm that your data is clean: @@ -515,10 +515,11 @@ and if a full `live_retrain_hours` has elapsed since the end of the loaded model The FreqAI backtesting module can be executed with the following command: ```bash -freqtrade backtesting --strategy FreqaiExampleStrategy --config config_examples/config_freqai.example.json --freqaimodel LightGBMRegressor --timerange 20210501-20210701 +freqtrade download-data --config config_examples/config_freqai.example.json --strategy FreqaiExampleStrategy --strategy-path freqtrade/templates -t 3m 15m 1h --timerange 20210315-20210701 +freqtrade backtesting --strategy FreqaiExampleStrategy --strategy-path freqtrade/templates --config config_examples/config_freqai.example.json --freqaimodel LightGBMRegressor --timerange 20210501-20210701 ``` -Backtesting mode requires the user to have the data pre-downloaded (unlike in dry/live mode where FreqAI automatically downloads the necessary data). The user should be careful to consider that the time range of the downloaded data is more than the backtesting time range. This is because FreqAI needs data prior to the desired backtesting time range in order to train a model to be ready to make predictions on the first candle of the user-set backtesting time range. More details on how to calculate the data to download can be found [here](#deciding-the-sliding-training-window-and-backtesting-duration). +Backtesting mode requires the user to have the data [pre-downloaded](#downloading-data-for-backtesting) (unlike in dry/live mode where FreqAI automatically downloads the necessary data). The user should be careful to consider that the time range of the downloaded data is more than the backtesting time range. This is because FreqAI needs data prior to the desired backtesting time range in order to train a model to be ready to make predictions on the first candle of the user-set backtesting time range. More details on how to calculate the data to download can be found [here](#deciding-the-sliding-training-window-and-backtesting-duration). If this command has never been executed with the existing config file, it will train a new model for each pair, for each backtesting window within the expanded `--timerange`. @@ -546,7 +547,7 @@ FreqAI will train have trained 8 separate models at the end of `--timerange` (be Although fractional `backtest_period_days` is allowed, the user should be aware that the `--timerange` is divided by this value to determine the number of models that FreqAI will need to train in order to backtest the full range. For example, if the user wants to set a `--timerange` of 10 days, and asks for a `backtest_period_days` of 0.1, FreqAI will need to train 100 models per pair to complete the full backtest. Because of this, a true backtest of FreqAI adaptive training would take a *very* long time. The best way to fully test a model is to run it dry and let it constantly train. In this case, backtesting would take the exact same amount of time as a dry run. ### Downloading data for backtesting -Live/dry instances will download the data automatically for the user, but users who wish to use backtesting functionality still need to download the necessary data using `download-data` (details [here](data-download/#data-downloading)). FreqAI users need to pay careful attention to understanding how much *additional* data needs to be downloaded to ensure that they have a sufficient amount of training data *before* the start of their backtesting timerange. The amount of additional data can be roughly estimated by taking subtracting `train_period_days` and the `startup_candle_count` ([details](#setting-the-startupcandlecount)) from the beginning of the desired backtesting timerange. +Live/dry instances will download the data automatically for the user, but users who wish to use backtesting functionality still need to download the necessary data using `download-data` (details [here](data-download.md#data-downloading)). FreqAI users need to pay careful attention to understanding how much *additional* data needs to be downloaded to ensure that they have a sufficient amount of training data *before* the start of their backtesting timerange. The amount of additional data can be roughly estimated by moving the start date of the timerange backwards by `train_period_days` and the `startup_candle_count` ([details](#setting-the-startupcandlecount)) from the beginning of the desired backtesting timerange. As an example, if we wish to backtest the `--timerange` above of `20210501-20210701`, and we use the example config which sets `train_period_days` to 15. The startup candle count is 40 on a maximum `include_timeframes` of 1h. We would need 20210501 - 15 days - 40 * 1h / 24 hours = 20210414 (16.7 days earlier than the start of the desired training timerange). From 9fb3517adc9b6d078fe3fc00d7393a79fcddae15 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 5 Sep 2022 21:08:01 +0200 Subject: [PATCH 59/65] Fix non-resolvable freqai test this test could never succeed in UI's as the name was constantly changing. --- tests/freqai/test_freqai_datakitchen.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/tests/freqai/test_freqai_datakitchen.py b/tests/freqai/test_freqai_datakitchen.py index 44c721515..908223c20 100644 --- a/tests/freqai/test_freqai_datakitchen.py +++ b/tests/freqai/test_freqai_datakitchen.py @@ -1,5 +1,5 @@ -import datetime import shutil +from datetime import datetime, timedelta, timezone from pathlib import Path import pytest @@ -56,16 +56,13 @@ def test_split_timerange( shutil.rmtree(Path(dk.full_path)) -@pytest.mark.parametrize( - "timestamp, expected", - [ - (datetime.datetime.now(tz=datetime.timezone.utc).timestamp() - 7200, True), - (datetime.datetime.now(tz=datetime.timezone.utc).timestamp(), False), - ], -) -def test_check_if_model_expired(mocker, freqai_conf, timestamp, expected): +def test_check_if_model_expired(mocker, freqai_conf): + dk = get_patched_data_kitchen(mocker, freqai_conf) - assert dk.check_if_model_expired(timestamp) == expected + now = datetime.now(tz=timezone.utc).timestamp() + assert dk.check_if_model_expired(now) is False + now = (datetime.now(tz=timezone.utc) - timedelta(hours=2)).timestamp() + assert dk.check_if_model_expired(now) is True shutil.rmtree(Path(dk.full_path)) From 1ea703d527b341322a64d0f8e2327117a2bca7a8 Mon Sep 17 00:00:00 2001 From: robcaulk Date: Mon, 5 Sep 2022 22:20:38 +0200 Subject: [PATCH 60/65] remove download-data command --- docs/freqai.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/freqai.md b/docs/freqai.md index d04d2fa6b..303c2f151 100644 --- a/docs/freqai.md +++ b/docs/freqai.md @@ -515,7 +515,6 @@ and if a full `live_retrain_hours` has elapsed since the end of the loaded model The FreqAI backtesting module can be executed with the following command: ```bash -freqtrade download-data --config config_examples/config_freqai.example.json --strategy FreqaiExampleStrategy --strategy-path freqtrade/templates -t 3m 15m 1h --timerange 20210315-20210701 freqtrade backtesting --strategy FreqaiExampleStrategy --strategy-path freqtrade/templates --config config_examples/config_freqai.example.json --freqaimodel LightGBMRegressor --timerange 20210501-20210701 ``` From 4dec19de9f9ca55565c7972c62eb65afa33d1f48 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 6 Sep 2022 06:52:50 +0200 Subject: [PATCH 61/65] Add comment to explain why we use the non-trimmed DF --- freqtrade/optimize/hyperopt.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 4c8613a7a..3becf857f 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -421,8 +421,9 @@ class Hyperopt: preprocessed = self.backtesting.strategy.advise_all_indicators(data) # Trim startup period from analyzed dataframe to get correct dates for output. - processed = trim_dataframes(preprocessed, self.timerange, self.backtesting.required_startup) - self.min_date, self.max_date = get_timerange(processed) + trimmed = trim_dataframes(preprocessed, self.timerange, self.backtesting.required_startup) + self.min_date, self.max_date = get_timerange(trimmed) + # Real trimming will happen as part of backtesting. return preprocessed def prepare_hyperopt_data(self) -> None: From 8597b52e345abca6111869bb5da71c01ce7d4107 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 6 Sep 2022 16:29:24 +0200 Subject: [PATCH 62/65] Slightly update docs to link to full sample --- docs/strategy-customization.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index a452b8f05..2b6e1fb2f 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -824,6 +824,8 @@ Options: - Merge the dataframe without lookahead bias - Forward-fill (optional) +For a full sample, please refer to the [complete data provider example](#complete-data-provider-sample) below. + All columns of the informative dataframe will be available on the returning dataframe in a renamed fashion: !!! Example "Column renaming" From f2f811a2feed0a8ff427d638ac773d6aea670eaa Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 6 Sep 2022 19:55:18 +0200 Subject: [PATCH 63/65] Fix telegram bug with open partial exit orders --- freqtrade/rpc/rpc.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 11311f671..05599074c 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -261,11 +261,15 @@ class RPC: profit_str += f" ({fiat_profit:.2f})" fiat_profit_sum = fiat_profit if isnan(fiat_profit_sum) \ else fiat_profit_sum + fiat_profit + open_order = (trade.select_order_by_order_id( + trade.open_order_id) if trade.open_order_id else None) + detail_trade = [ f'{trade.id} {direction_str}', - trade.pair + ('*' if (trade.open_order_id is not None - and trade.close_rate_requested is None) else '') - + ('**' if (trade.close_rate_requested is not None) else ''), + trade.pair + ('*' if (open_order + and open_order.ft_order_side == trade.entry_side) else '') + + ('**' if (open_order and + open_order.ft_order_side == trade.exit_side is not None) else ''), shorten_date(arrow.get(trade.open_date).humanize(only_distance=True)), profit_str ] From 90ec336c70e02e0ae8156a768bf69b4ac0fa55b5 Mon Sep 17 00:00:00 2001 From: th0rntwig <107926911+th0rntwig@users.noreply.github.com> Date: Tue, 6 Sep 2022 19:58:25 +0200 Subject: [PATCH 64/65] Update+correct descriptions and figure (#7323) --- docs/assets/freqai_weight-factor.jpg | Bin 195825 -> 189828 bytes docs/freqai.md | 14 +++++++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/assets/freqai_weight-factor.jpg b/docs/assets/freqai_weight-factor.jpg index 4f8b23e1849588058fa8a55d5adf67466ca90c86..c7580787de79862f2af2539eb904682050614a53 100644 GIT binary patch literal 189828 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

atyK_sD60U=mK;s}+C5jk3N@uK`3!!+T-9Td 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%0DZ+e9?q9jI}lqMU6O_;grg|T!qwHDN+&5x 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

H^AUqc2mXm60lZX+5Q? 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%0DY|A%{7gkA4hXNH} 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 diff --git a/docs/freqai.md b/docs/freqai.md index 303c2f151..c0844bf32 100644 --- a/docs/freqai.md +++ b/docs/freqai.md @@ -112,15 +112,15 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `DI_threshold` | Activates the Dissimilarity Index for outlier detection when > 0. See details about how it works [here](#removing-outliers-with-the-dissimilarity-index).
**Datatype:** Positive float (typically < 1). | `use_SVM_to_remove_outliers` | Train a support vector machine to detect and remove outliers from the training data set, as well as from incoming data points. See details about how it works [here](#removing-outliers-using-a-support-vector-machine-svm).
**Datatype:** Boolean. | `svm_params` | All parameters available in Sklearn's `SGDOneClassSVM()`. See details about some select parameters [here](#removing-outliers-using-a-support-vector-machine-svm).
**Datatype:** Dictionary. -| `use_DBSCAN_to_remove_outliers` | Cluster data using DBSCAN to identify and remove outliers from training and prediction data. See details about how it works [here](#removing-outliers-with-dbscan).
**Datatype:** Boolean. -| `outlier_protection_percentage` | If more than `outlier_protection_percentage` fraction of points are removed as outliers, FreqAI will log a warning message and ignore outlier detection while keeping the original dataset intact.
**Datatype:** float. Default: `30` -| `reverse_train_test_order` | If true, FreqAI will train on the latest data split and test on historical split of the data. This allows the model to be trained up to the most recent data point, while avoiding overfitting. However, users should be careful to understand unorthodox nature of this parameter before employing it.
**Datatype:** bool. Default: False +| `use_DBSCAN_to_remove_outliers` | Cluster data using DBSCAN to identify and remove outliers from training and prediction data. See details about how it works [here](#removing-outliers-with-dbscan).
**Datatype:** Boolean. +| `outlier_protection_percentage` | If more than `outlier_protection_percentage` % of points are detected as outliers by the SVM or DBSCAN, FreqAI will log a warning message and ignore outlier detection while keeping the original dataset intact. If the outlier protection is triggered, no predictions will be made based on the training data.
**Datatype:** Float. Default: `30` +| `reverse_train_test_order` | If true, FreqAI will train on the latest data split and test on historical split of the data. This allows the model to be trained up to the most recent data point, while avoiding overfitting. However, users should be careful to understand unorthodox nature of this parameter before employing it.
**Datatype:** Boolean. Default: False | | **Data split parameters** | `data_split_parameters` | Include any additional parameters available from Scikit-learn `test_train_split()`, which are shown [here](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) (external website).
**Datatype:** Dictionary. | `test_size` | Fraction of data that should be used for testing instead of training.
**Datatype:** Positive float < 1. -| `shuffle` | Shuffle the training data points during training. Typically, for time-series forecasting, this is set to `False`.
+| `shuffle` | Shuffle the training data points during training. Typically, for time-series forecasting, this is set to `False`.
**Datatype:** Boolean. | | **Model training parameters** -| `model_training_parameters` | A flexible dictionary that includes all parameters available by the user selected model library. For example, if the user uses `LightGBMRegressor`, this dictionary can contain any parameter available by the `LightGBMRegressor` [here](https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.LGBMRegressor.html) (external website). If the user selects a different model, this dictionary can contain any parameter from that model.
**Datatype:** Dictionary.**Datatype:** Boolean. +| `model_training_parameters` | A flexible dictionary that includes all parameters available by the user selected model library. For example, if the user uses `LightGBMRegressor`, this dictionary can contain any parameter available by the `LightGBMRegressor` [here](https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.LGBMRegressor.html) (external website). If the user selects a different model, this dictionary can contain any parameter from that model.
**Datatype:** Dictionary. | `n_estimators` | The number of boosted trees to fit in regression.
**Datatype:** Integer. | `learning_rate` | Boosting learning rate during regression.
**Datatype:** Float. | `n_jobs`, `thread_count`, `task_type` | Set the number of threads for parallel processing and the `task_type` (`gpu` or `cpu`). Different model libraries use different parameter names.
**Datatype:** Float. @@ -738,7 +738,7 @@ Given a number of data points $N$, and a distance $\varepsilon$, DBSCAN clusters ![dbscan](assets/freqai_dbscan.jpg) -FreqAI uses `sklearn.cluster.DBSCAN` (details are available on scikit-learn's webpage [here](#https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html)) with `min_samples` ($N$) taken as double the no. of user-defined features, and `eps` ($\varepsilon$) taken as the longest distance in the *k-distance graph* computed from the nearest neighbors in the pairwise distances of all data points in the feature set. +FreqAI uses `sklearn.cluster.DBSCAN` (details are available on scikit-learn's webpage [here](#https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html)) with `min_samples` ($N$) taken as 1/4 of the no. of time points in the feature set, and `eps` ($\varepsilon$) taken as the elbow point in the *k-distance graph* computed from the nearest neighbors in the pairwise distances of all data points in the feature set. ## Additional information @@ -763,5 +763,5 @@ Code review, software architecture brainstorming: @xmatthias Beta testing and bug reporting: -@bloodhunter4rc, Salah Lamkadem @ikonx, @ken11o2, @longyu, @paranoidandy, @smidelis, @smarm +@bloodhunter4rc, Salah Lamkadem @ikonx, @ken11o2, @longyu, @paranoidandy, @smidelis, @smarm, Juha Nykänen @suikula, Wagner Costa @wagnercosta From dc4a4bdf09cfc3ecb588cdabb3877e07b5762ab0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 6 Sep 2022 20:25:46 +0200 Subject: [PATCH 65/65] Wrap cleanup in try/finally handler If a database has errors, the database cleanups would fail, causing cleanup to be incomplete. closes #7364 --- freqtrade/freqtradebot.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index f7dca1d75..1d171ae89 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -142,17 +142,20 @@ class FreqtradeBot(LoggingMixin): :return: None """ logger.info('Cleaning up modules ...') + try: + # Wrap db activities in shutdown to avoid problems if database is gone, + # and raises further exceptions. + if self.config['cancel_open_orders_on_exit']: + self.cancel_all_open_orders() - if self.config['cancel_open_orders_on_exit']: - self.cancel_all_open_orders() - - self.check_for_open_trades() + self.check_for_open_trades() - self.strategy.ft_bot_cleanup() + finally: + self.strategy.ft_bot_cleanup() - self.rpc.cleanup() - Trade.commit() - self.exchange.close() + self.rpc.cleanup() + Trade.commit() + self.exchange.close() def startup(self) -> None: """