From 39ffcecffae104cec1b04ada1c02beec290825e3 Mon Sep 17 00:00:00 2001 From: werkkrew Date: Sat, 13 Mar 2021 11:29:55 -0500 Subject: [PATCH] changed variable names to be more unique, started work on unit tests --- docs/configuration.md | 48 ++++++------- docs/hyperopt.md | 12 ++-- freqtrade/constants.py | 12 ++-- freqtrade/optimize/hyperopt_interface.py | 24 +++---- freqtrade/strategy/interface.py | 15 +++-- .../templates/sample_hyperopt_advanced.py | 12 ++-- tests/optimize/test_hyperopt.py | 67 ++++++++++++++----- 7 files changed, 114 insertions(+), 76 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 5115b06f3..d2004149b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -264,60 +264,60 @@ There are 3 different types of dynamic ROI algorithms available, `linear`, `expo Exapmple Linear Config: ```json "dynamic_roi": { - "enabled": true, - "type": "linear", - "decay-time": 720, - "start": 0.10, - "end": 0 + "dynamic_roi_enabled": true, + "dynamic_roi_type": "linear", + "dynamic_roi_time": 720, + "dynamic_roi_start": 0.10, + "dynamic_roi_end": 0 } ``` Exapmple Linear Config for strategy: ```python dynamic_roi = { - 'enabled': True, - 'type': 'linear', - 'decay-time': 720, - 'start': 0.10, - 'end': 0 + 'dynamic_roi_enabled': True, + 'dynamic_roi_type': 'linear', + 'dynamic_roi_time': 720, + 'dynamic_roi_start': 0.10, + 'dynamic_roi_end': 0 } ``` Exapmple Exponential Config: ```json "dynamic_roi": { - "enabled": true, - "type": "exponential", - "decay-rate": 0.015, - "start": 0.10, - "end": 0 + "dynamic_roi_enabled": true, + "dynamic_roi_type": "exponential", + "dynamic_roi_rate": 0.015, + "dynamic_roi_start": 0.10, + "dynamic_roi_end": 0 } ``` Example Exponential Config for strategy: ```python dynamic_roi = { - 'enabled': True, - 'type': 'exponential', - 'decay-rate': 0.015, - 'start': 0.10, - 'end': 0 + 'dynamic_roi_enabled': True, + 'dynamic_roi_type': 'exponential', + 'dynamic_roi_rate': 0.015, + 'dynamic_roi_start': 0.10, + 'dynamic_roi_end': 0 } ``` Example Connect Config: ```json "dynamic_roi": { - "enabled": true, - "type": "connect" + "dynamic_roi_enabled": true, + "dynamic_roi_type": "connect" } ``` Example Connect Config for strategy: ```python dynamic_roi = { - 'enabled': True, - 'type': 'connect' + 'dynamic_roi_enabled': True, + 'dynamic_roi_type': 'connect' } ``` diff --git a/docs/hyperopt.md b/docs/hyperopt.md index 709615f12..6c13981cf 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -625,12 +625,12 @@ Best result: # Dynamic ROI table: dynamic_roi = { - 'decay-rate': 0.02356, - 'decay-time': 909, - 'enabled': True, - 'end': 0.002, - 'start': 0.07778, - 'type': 'connect' + 'dynamic_roi_rate': 0.02356, + 'dynamic_roi_time': 909, + 'dynamic_roi_enabled': True, + 'dynamic_roi_end': 0.002, + 'dynamic_roi_start': 0.07778, + 'dynamic_roi_type': 'connect' } ``` diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 690b2ff35..56d9d5b61 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -129,12 +129,12 @@ CONF_SCHEMA = { 'dynamic_roi': { 'type': 'object', 'properties': { - 'enabled': {'type': 'boolean'}, - 'type': {'type': 'string', 'enum': DYNAMIC_ROI_TYPES}, - 'decay-rate': {'type': 'number', 'minimum': 0.0001, 'maximum': 0.9}, - 'decay-time': {'type': 'integer', 'minimum': 1}, - 'start': {'type': 'number', 'minimum': 0.0, 'maximum': 1.0}, - 'end': {'type': 'number', 'minimum': 0.0} + 'dynamic_roi_enabled': {'type': 'boolean'}, + 'dynamic_roi_type': {'type': 'string', 'enum': DYNAMIC_ROI_TYPES}, + 'dynamic_roi_rate': {'type': 'number', 'minimum': 0.0001, 'maximum': 0.9}, + 'dynamic_roi_time': {'type': 'integer', 'minimum': 1}, + 'dynamic_roi_start': {'type': 'number', 'minimum': 0.0, 'maximum': 1.0}, + 'dynamic_roi_end': {'type': 'number', 'minimum': 0.0} } }, 'amount_reserve_percent': {'type': 'number', 'minimum': 0.0, 'maximum': 0.5}, diff --git a/freqtrade/optimize/hyperopt_interface.py b/freqtrade/optimize/hyperopt_interface.py index d2fe42dba..c654ce68a 100644 --- a/freqtrade/optimize/hyperopt_interface.py +++ b/freqtrade/optimize/hyperopt_interface.py @@ -222,12 +222,12 @@ class IHyperOpt(ABC): Create a dynamic_roi table. """ dynamic_roi_table = { - 'enabled': params['enabled'], - 'type': params['type'], - 'decay-rate': params['decay-rate'], - 'decay-time': params['decay-time'], - 'start': params['start'], - 'end': params['end'] + 'dynamic_roi_enabled': params['enabled'], + 'dynamic_roi_type': params['type'], + 'dynamic_roi_rate': params['decay-rate'], + 'dynamic_roi_time': params['decay-time'], + 'dynamic_roi_start': params['start'], + 'dynamic_roi_end': params['end'] } return dynamic_roi_table @@ -240,12 +240,12 @@ class IHyperOpt(ABC): You may override it in your custom Hyperopt class. """ return [ - Categorical([True, False], name='enabled'), - Categorical(['linear', 'exponential', 'connect'], name='type'), - Real(0.001, 0.03, name='decay-rate'), - Integer(180, 1440, name='decay-time'), - Real(0.05, 0.25, name='start'), - Real(0, 0.005, name='end') + Categorical([True, False], name='dynamic_roi_enabled'), + Categorical(['linear', 'exponential', 'connect'], name='dynamic_roi_type'), + Real(0.001, 0.03, name='dynamic_roi_rate'), + Integer(180, 1440, name='dynamic_roi_time'), + Real(0.05, 0.25, name='dynamic_roi_start'), + Real(0, 0.005, name='dynamic_roi_end') ] diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 4bc5f80c1..627000195 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -636,17 +636,18 @@ class IStrategy(ABC): """ dynamic_roi = self.dynamic_roi minimal_roi = self.minimal_roi + start, end = dynamic_roi['dynamic_roi_start'], dynamic_roi['dynamic_roi_end'] # if the dynamic_roi dict is defined and enabled, use it, otherwise fallback to default functionality - if dynamic_roi and dynamic_roi['enabled']: + if dynamic_roi and dynamic_roi['dynamic_roi_enabled']: # linear decay: f(t) = start - (rate * t) - if dynamic_roi['type'] == 'linear': - rate = (dynamic_roi['start'] - dynamic_roi['end']) / dynamic_roi['decay-time'] - min_roi = max(dynamic_roi['end'], dynamic_roi['start'] - (rate * trade_dur)) + if dynamic_roi['dynamic_roi_type'] == 'linear': + rate = (start - end) / dynamic_roi['dynamic_roi_time'] + min_roi = max(end, start - (rate * trade_dur)) # exponential decay: f(t) = start * e^(-rate*t) - elif dynamic_roi['type'] == 'exponential': - min_roi = max(dynamic_roi['end'], dynamic_roi['start'] * np.exp(-dynamic_roi['decay-rate']*trade_dur)) - elif dynamic_roi['type'] == 'connect': + elif dynamic_roi['dynamic_roi_type'] == 'exponential': + min_roi = max(end, start * np.exp(-dynamic_roi['dynamic_roi_rate']*trade_dur)) + elif dynamic_roi['dynamic_roi_type'] == 'connect': # connect the points in the defined table with lines past_roi = list(filter(lambda x: x <= trade_dur, minimal_roi.keys())) next_roi = list(filter(lambda x: x > trade_dur, minimal_roi.keys())) diff --git a/freqtrade/templates/sample_hyperopt_advanced.py b/freqtrade/templates/sample_hyperopt_advanced.py index b2b471912..29a413dcb 100644 --- a/freqtrade/templates/sample_hyperopt_advanced.py +++ b/freqtrade/templates/sample_hyperopt_advanced.py @@ -280,12 +280,12 @@ class AdvancedSampleHyperOpt(IHyperOpt): the ranges for decay-rate, decay-time, start, or end. """ return [ - Categorical([True, False], name='enabled'), - Categorical(['linear', 'exponential', 'connect'], name='type'), - Real(0.001, 0.03, name='decay-rate'), - Integer(180, 1440, name='decay-time'), - Real(0.05, 0.25, name='start'), - Real(0, 0.005, name='end') + Categorical([True, False], name='dynamic_roi_enabled'), + Categorical(['linear', 'exponential', 'connect'], name='dynamic_roi_type'), + Real(0.001, 0.03, name='dynamic_roi_rate'), + Integer(180, 1440, name='dynamic_roi_time'), + Real(0.05, 0.25, name='dynamic_roi_start'), + Real(0, 0.005, name='dynamic_roi_end') ] def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 9ebdad2b5..6c46f8287 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -473,34 +473,59 @@ def test_format_results(hyperopt): @pytest.mark.parametrize("spaces, expected_results", [ (['buy'], - {'buy': True, 'sell': False, 'roi': False, 'stoploss': False, 'trailing': False}), + {'buy': True, 'sell': False, 'roi': False, 'stoploss': False, 'trailing': False, + 'dynamic-roi': False}), (['sell'], - {'buy': False, 'sell': True, 'roi': False, 'stoploss': False, 'trailing': False}), + {'buy': False, 'sell': True, 'roi': False, 'stoploss': False, 'trailing': False, + 'dynamic-roi': False}), (['roi'], - {'buy': False, 'sell': False, 'roi': True, 'stoploss': False, 'trailing': False}), + {'buy': False, 'sell': False, 'roi': True, 'stoploss': False, 'trailing': False, + 'dynamic-roi': False}), (['stoploss'], - {'buy': False, 'sell': False, 'roi': False, 'stoploss': True, 'trailing': False}), + {'buy': False, 'sell': False, 'roi': False, 'stoploss': True, 'trailing': False, + 'dynamic-roi': False}), (['trailing'], - {'buy': False, 'sell': False, 'roi': False, 'stoploss': False, 'trailing': True}), + {'buy': False, 'sell': False, 'roi': False, 'stoploss': False, 'trailing': True, + 'dynamic-roi': False}), + (['dynamic-roi'], + {'buy': False, 'sell': False, 'roi': False, 'stoploss': False, 'trailing': False, + 'dynamic-roi': True}), (['buy', 'sell', 'roi', 'stoploss'], - {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': False}), + {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': False, + 'dynamic-roi': False}), (['buy', 'sell', 'roi', 'stoploss', 'trailing'], - {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True}), + {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True, + 'dynamic-roi': False}), + (['buy', 'sell', 'roi', 'stoploss', 'trailing', 'dynamic-roi'], + {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True, + 'dynamic-roi': True}), (['buy', 'roi'], - {'buy': True, 'sell': False, 'roi': True, 'stoploss': False, 'trailing': False}), + {'buy': True, 'sell': False, 'roi': True, 'stoploss': False, 'trailing': False, + 'dynamic-roi': False}), + (['buy', 'roi', 'dynamic-roi'], + {'buy': True, 'sell': False, 'roi': True, 'stoploss': False, 'trailing': False, + 'dynamic-roi': True}), + (['roi', 'dynamic-roi'], + {'buy': False, 'sell': False, 'roi': True, 'stoploss': False, 'trailing': False, + 'dynamic-roi': True}), (['all'], - {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True}), + {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True, + 'dynamic-roi': True}), (['default'], - {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': False}), + {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': False, + 'dynamic-roi': False}), (['default', 'trailing'], - {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True}), + {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True, + 'dynamic-roi': False}), (['all', 'buy'], - {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True}), + {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True, + 'dynamic-roi': True}), (['default', 'buy'], - {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': False}), + {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': False, + 'dynamic-roi': False}), ]) def test_has_space(hyperopt, spaces, expected_results): - for s in ['buy', 'sell', 'roi', 'stoploss', 'trailing']: + for s in ['buy', 'sell', 'roi', 'stoploss', 'trailing', 'dynamic-roi']: hyperopt.config.update({'spaces': spaces}) assert hyperopt.has_space(s) == expected_results[s] @@ -620,6 +645,12 @@ def test_generate_optimizer(mocker, hyperopt_conf) -> None: 'trailing_stop_positive': 0.02, 'trailing_stop_positive_offset_p1': 0.05, 'trailing_only_offset_is_reached': False, + 'dynamic_roi_enabled': False, + 'dynamic_roi_type': 'linear', + 'dynamic_roi_rate': 0.015, + 'dynamic_roi_time': 720, + 'dynamic_roi_start': 0.10, + 'dynamic_roi_end': 0 } response_expected = { 'loss': 1.9840569076926293, @@ -654,7 +685,13 @@ def test_generate_optimizer(mocker, hyperopt_conf) -> None: 'trailing': {'trailing_only_offset_is_reached': False, 'trailing_stop': True, 'trailing_stop_positive': 0.02, - 'trailing_stop_positive_offset': 0.07}}, + 'trailing_stop_positive_offset': 0.07}, + 'dynamic_roi': {'dynamic_roi_enabled': False, + 'dynamic_roi_type': 'linear', + 'dynamic_roi_rate': 0.015, + 'dynamic_roi_time': 720, + 'dynamic_roi_start': 0.10, + 'dynamic_roi_end': 0}}, 'params_dict': optimizer_param, 'results_metrics': {'avg_profit': 2.3117, 'draws': 0,