changed variable names to be more unique, started work on unit tests
This commit is contained in:
parent
5939729e03
commit
39ffcecffa
@ -264,60 +264,60 @@ There are 3 different types of dynamic ROI algorithms available, `linear`, `expo
|
|||||||
Exapmple Linear Config:
|
Exapmple Linear Config:
|
||||||
```json
|
```json
|
||||||
"dynamic_roi": {
|
"dynamic_roi": {
|
||||||
"enabled": true,
|
"dynamic_roi_enabled": true,
|
||||||
"type": "linear",
|
"dynamic_roi_type": "linear",
|
||||||
"decay-time": 720,
|
"dynamic_roi_time": 720,
|
||||||
"start": 0.10,
|
"dynamic_roi_start": 0.10,
|
||||||
"end": 0
|
"dynamic_roi_end": 0
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Exapmple Linear Config for strategy:
|
Exapmple Linear Config for strategy:
|
||||||
```python
|
```python
|
||||||
dynamic_roi = {
|
dynamic_roi = {
|
||||||
'enabled': True,
|
'dynamic_roi_enabled': True,
|
||||||
'type': 'linear',
|
'dynamic_roi_type': 'linear',
|
||||||
'decay-time': 720,
|
'dynamic_roi_time': 720,
|
||||||
'start': 0.10,
|
'dynamic_roi_start': 0.10,
|
||||||
'end': 0
|
'dynamic_roi_end': 0
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Exapmple Exponential Config:
|
Exapmple Exponential Config:
|
||||||
```json
|
```json
|
||||||
"dynamic_roi": {
|
"dynamic_roi": {
|
||||||
"enabled": true,
|
"dynamic_roi_enabled": true,
|
||||||
"type": "exponential",
|
"dynamic_roi_type": "exponential",
|
||||||
"decay-rate": 0.015,
|
"dynamic_roi_rate": 0.015,
|
||||||
"start": 0.10,
|
"dynamic_roi_start": 0.10,
|
||||||
"end": 0
|
"dynamic_roi_end": 0
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Example Exponential Config for strategy:
|
Example Exponential Config for strategy:
|
||||||
```python
|
```python
|
||||||
dynamic_roi = {
|
dynamic_roi = {
|
||||||
'enabled': True,
|
'dynamic_roi_enabled': True,
|
||||||
'type': 'exponential',
|
'dynamic_roi_type': 'exponential',
|
||||||
'decay-rate': 0.015,
|
'dynamic_roi_rate': 0.015,
|
||||||
'start': 0.10,
|
'dynamic_roi_start': 0.10,
|
||||||
'end': 0
|
'dynamic_roi_end': 0
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Example Connect Config:
|
Example Connect Config:
|
||||||
```json
|
```json
|
||||||
"dynamic_roi": {
|
"dynamic_roi": {
|
||||||
"enabled": true,
|
"dynamic_roi_enabled": true,
|
||||||
"type": "connect"
|
"dynamic_roi_type": "connect"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Example Connect Config for strategy:
|
Example Connect Config for strategy:
|
||||||
```python
|
```python
|
||||||
dynamic_roi = {
|
dynamic_roi = {
|
||||||
'enabled': True,
|
'dynamic_roi_enabled': True,
|
||||||
'type': 'connect'
|
'dynamic_roi_type': 'connect'
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -625,12 +625,12 @@ Best result:
|
|||||||
|
|
||||||
# Dynamic ROI table:
|
# Dynamic ROI table:
|
||||||
dynamic_roi = {
|
dynamic_roi = {
|
||||||
'decay-rate': 0.02356,
|
'dynamic_roi_rate': 0.02356,
|
||||||
'decay-time': 909,
|
'dynamic_roi_time': 909,
|
||||||
'enabled': True,
|
'dynamic_roi_enabled': True,
|
||||||
'end': 0.002,
|
'dynamic_roi_end': 0.002,
|
||||||
'start': 0.07778,
|
'dynamic_roi_start': 0.07778,
|
||||||
'type': 'connect'
|
'dynamic_roi_type': 'connect'
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -129,12 +129,12 @@ CONF_SCHEMA = {
|
|||||||
'dynamic_roi': {
|
'dynamic_roi': {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'properties': {
|
'properties': {
|
||||||
'enabled': {'type': 'boolean'},
|
'dynamic_roi_enabled': {'type': 'boolean'},
|
||||||
'type': {'type': 'string', 'enum': DYNAMIC_ROI_TYPES},
|
'dynamic_roi_type': {'type': 'string', 'enum': DYNAMIC_ROI_TYPES},
|
||||||
'decay-rate': {'type': 'number', 'minimum': 0.0001, 'maximum': 0.9},
|
'dynamic_roi_rate': {'type': 'number', 'minimum': 0.0001, 'maximum': 0.9},
|
||||||
'decay-time': {'type': 'integer', 'minimum': 1},
|
'dynamic_roi_time': {'type': 'integer', 'minimum': 1},
|
||||||
'start': {'type': 'number', 'minimum': 0.0, 'maximum': 1.0},
|
'dynamic_roi_start': {'type': 'number', 'minimum': 0.0, 'maximum': 1.0},
|
||||||
'end': {'type': 'number', 'minimum': 0.0}
|
'dynamic_roi_end': {'type': 'number', 'minimum': 0.0}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'amount_reserve_percent': {'type': 'number', 'minimum': 0.0, 'maximum': 0.5},
|
'amount_reserve_percent': {'type': 'number', 'minimum': 0.0, 'maximum': 0.5},
|
||||||
|
@ -222,12 +222,12 @@ class IHyperOpt(ABC):
|
|||||||
Create a dynamic_roi table.
|
Create a dynamic_roi table.
|
||||||
"""
|
"""
|
||||||
dynamic_roi_table = {
|
dynamic_roi_table = {
|
||||||
'enabled': params['enabled'],
|
'dynamic_roi_enabled': params['enabled'],
|
||||||
'type': params['type'],
|
'dynamic_roi_type': params['type'],
|
||||||
'decay-rate': params['decay-rate'],
|
'dynamic_roi_rate': params['decay-rate'],
|
||||||
'decay-time': params['decay-time'],
|
'dynamic_roi_time': params['decay-time'],
|
||||||
'start': params['start'],
|
'dynamic_roi_start': params['start'],
|
||||||
'end': params['end']
|
'dynamic_roi_end': params['end']
|
||||||
}
|
}
|
||||||
|
|
||||||
return dynamic_roi_table
|
return dynamic_roi_table
|
||||||
@ -240,12 +240,12 @@ class IHyperOpt(ABC):
|
|||||||
You may override it in your custom Hyperopt class.
|
You may override it in your custom Hyperopt class.
|
||||||
"""
|
"""
|
||||||
return [
|
return [
|
||||||
Categorical([True, False], name='enabled'),
|
Categorical([True, False], name='dynamic_roi_enabled'),
|
||||||
Categorical(['linear', 'exponential', 'connect'], name='type'),
|
Categorical(['linear', 'exponential', 'connect'], name='dynamic_roi_type'),
|
||||||
Real(0.001, 0.03, name='decay-rate'),
|
Real(0.001, 0.03, name='dynamic_roi_rate'),
|
||||||
Integer(180, 1440, name='decay-time'),
|
Integer(180, 1440, name='dynamic_roi_time'),
|
||||||
Real(0.05, 0.25, name='start'),
|
Real(0.05, 0.25, name='dynamic_roi_start'),
|
||||||
Real(0, 0.005, name='end')
|
Real(0, 0.005, name='dynamic_roi_end')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -636,17 +636,18 @@ class IStrategy(ABC):
|
|||||||
"""
|
"""
|
||||||
dynamic_roi = self.dynamic_roi
|
dynamic_roi = self.dynamic_roi
|
||||||
minimal_roi = self.minimal_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 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)
|
# linear decay: f(t) = start - (rate * t)
|
||||||
if dynamic_roi['type'] == 'linear':
|
if dynamic_roi['dynamic_roi_type'] == 'linear':
|
||||||
rate = (dynamic_roi['start'] - dynamic_roi['end']) / dynamic_roi['decay-time']
|
rate = (start - end) / dynamic_roi['dynamic_roi_time']
|
||||||
min_roi = max(dynamic_roi['end'], dynamic_roi['start'] - (rate * trade_dur))
|
min_roi = max(end, start - (rate * trade_dur))
|
||||||
# exponential decay: f(t) = start * e^(-rate*t)
|
# exponential decay: f(t) = start * e^(-rate*t)
|
||||||
elif dynamic_roi['type'] == 'exponential':
|
elif dynamic_roi['dynamic_roi_type'] == 'exponential':
|
||||||
min_roi = max(dynamic_roi['end'], dynamic_roi['start'] * np.exp(-dynamic_roi['decay-rate']*trade_dur))
|
min_roi = max(end, start * np.exp(-dynamic_roi['dynamic_roi_rate']*trade_dur))
|
||||||
elif dynamic_roi['type'] == 'connect':
|
elif dynamic_roi['dynamic_roi_type'] == 'connect':
|
||||||
# connect the points in the defined table with lines
|
# connect the points in the defined table with lines
|
||||||
past_roi = list(filter(lambda x: x <= trade_dur, minimal_roi.keys()))
|
past_roi = list(filter(lambda x: x <= trade_dur, minimal_roi.keys()))
|
||||||
next_roi = list(filter(lambda x: x > trade_dur, minimal_roi.keys()))
|
next_roi = list(filter(lambda x: x > trade_dur, minimal_roi.keys()))
|
||||||
|
@ -280,12 +280,12 @@ class AdvancedSampleHyperOpt(IHyperOpt):
|
|||||||
the ranges for decay-rate, decay-time, start, or end.
|
the ranges for decay-rate, decay-time, start, or end.
|
||||||
"""
|
"""
|
||||||
return [
|
return [
|
||||||
Categorical([True, False], name='enabled'),
|
Categorical([True, False], name='dynamic_roi_enabled'),
|
||||||
Categorical(['linear', 'exponential', 'connect'], name='type'),
|
Categorical(['linear', 'exponential', 'connect'], name='dynamic_roi_type'),
|
||||||
Real(0.001, 0.03, name='decay-rate'),
|
Real(0.001, 0.03, name='dynamic_roi_rate'),
|
||||||
Integer(180, 1440, name='decay-time'),
|
Integer(180, 1440, name='dynamic_roi_time'),
|
||||||
Real(0.05, 0.25, name='start'),
|
Real(0.05, 0.25, name='dynamic_roi_start'),
|
||||||
Real(0, 0.005, name='end')
|
Real(0, 0.005, name='dynamic_roi_end')
|
||||||
]
|
]
|
||||||
|
|
||||||
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||||
|
@ -473,34 +473,59 @@ def test_format_results(hyperopt):
|
|||||||
|
|
||||||
@pytest.mark.parametrize("spaces, expected_results", [
|
@pytest.mark.parametrize("spaces, expected_results", [
|
||||||
(['buy'],
|
(['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'],
|
(['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'],
|
(['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'],
|
(['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'],
|
(['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', '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', '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', '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'],
|
(['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'],
|
(['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'],
|
(['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'],
|
(['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'],
|
(['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):
|
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})
|
hyperopt.config.update({'spaces': spaces})
|
||||||
assert hyperopt.has_space(s) == expected_results[s]
|
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': 0.02,
|
||||||
'trailing_stop_positive_offset_p1': 0.05,
|
'trailing_stop_positive_offset_p1': 0.05,
|
||||||
'trailing_only_offset_is_reached': False,
|
'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 = {
|
response_expected = {
|
||||||
'loss': 1.9840569076926293,
|
'loss': 1.9840569076926293,
|
||||||
@ -654,7 +685,13 @@ def test_generate_optimizer(mocker, hyperopt_conf) -> None:
|
|||||||
'trailing': {'trailing_only_offset_is_reached': False,
|
'trailing': {'trailing_only_offset_is_reached': False,
|
||||||
'trailing_stop': True,
|
'trailing_stop': True,
|
||||||
'trailing_stop_positive': 0.02,
|
'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,
|
'params_dict': optimizer_param,
|
||||||
'results_metrics': {'avg_profit': 2.3117,
|
'results_metrics': {'avg_profit': 2.3117,
|
||||||
'draws': 0,
|
'draws': 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user