move roi_space, stoploss_space, generate_roi_table to IHyperOpt

This commit is contained in:
hroff-1902 2019-08-05 17:54:53 +03:00
parent eeecdd4e5a
commit c6444a10a8
4 changed files with 99 additions and 102 deletions

View File

@ -18,20 +18,25 @@ Configuring hyperopt is similar to writing your own strategy, and many tasks wil
### Checklist on all tasks / possibilities in hyperopt ### Checklist on all tasks / possibilities in hyperopt
Depending on the space you want to optimize, only some of the below are required. Depending on the space you want to optimize, only some of the below are required:
* fill `populate_indicators` - probably a copy from your strategy * fill `populate_indicators` - probably a copy from your strategy
* fill `buy_strategy_generator` - for buy signal optimization * fill `buy_strategy_generator` - for buy signal optimization
* fill `indicator_space` - for buy signal optimzation * fill `indicator_space` - for buy signal optimzation
* fill `sell_strategy_generator` - for sell signal optimization * fill `sell_strategy_generator` - for sell signal optimization
* fill `sell_indicator_space` - for sell signal optimzation * fill `sell_indicator_space` - for sell signal optimzation
* fill `roi_space` - for ROI optimization
* fill `generate_roi_table` - for ROI optimization (if you need more than 3 entries) Optional, but recommended:
* fill `stoploss_space` - stoploss optimization
* Optional but recommended
* copy `populate_buy_trend` from your strategy - otherwise default-strategy will be used * copy `populate_buy_trend` from your strategy - otherwise default-strategy will be used
* copy `populate_sell_trend` from your strategy - otherwise default-strategy will be used * copy `populate_sell_trend` from your strategy - otherwise default-strategy will be used
Rarely you may also need to override:
* `roi_space` - for custom ROI optimization (if you need the ranges for the ROI parameters in the optimization hyperspace that differ from default)
* `generate_roi_table` - for custom ROI optimization (if you need more than 4 entries in the ROI table)
* `stoploss_space` - for custom stoploss optimization (if you need the range for the stoploss parameter in the optimization hyperspace that differs from default)
### 1. Install a Custom Hyperopt File ### 1. Install a Custom Hyperopt File
Put your hyperopt file into the directory `user_data/hyperopts`. Put your hyperopt file into the directory `user_data/hyperopts`.
@ -345,7 +350,7 @@ def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame:
### Understand Hyperopt ROI results ### Understand Hyperopt ROI results
If you are optimizing ROI, you're result will look as follows and include a ROI table. If you are optimizing ROI, your result will look as follows and include a ROI table:
``` ```
Best result: Best result:
@ -376,6 +381,41 @@ minimal_roi = {
} }
``` ```
If you are optimizing ROI, Freqtrade creates the 'roi' optimization hyperspace for you -- it's the hyperspace of components for the ROI tables. By default, each ROI table generated by the Freqtrade consists of 4 rows (steps) with the values that can vary in the following ranges:
| # | minutes | ROI percentage |
|---|---|---|
| 1 | always 0 | 0.03...0.31 |
| 2 | 10...40 | 0.02...0.11 |
| 3 | 20...100 | 0.01...0.04 |
| 4 | 30...220 | always 0 |
This structure of the ROI table is sufficient in most cases. Override the `roi_space()` method defining the ranges desired if you need components of the ROI tables to vary in other ranges.
Override the `generate_roi_table()` and `roi_space()` methods and implement your own custom approach for generation of the ROI tables during hyperoptimization in these methods if you need a different structure of the ROI table or other amount of rows (steps) in the ROI tables.
### Understand Hyperopt Stoploss results
If you are optimizing stoploss values, your result will look as follows and include stoploss:
```
Best result:
44/100: 135 trades. Avg profit 0.57%. Total profit 0.03871918 BTC (0.7722Σ%). Avg duration 180.4 mins. Objective: 1.94367
Buy hyperspace params:
{ 'adx-value': 44,
'rsi-value': 29,
'adx-enabled': False,
'rsi-enabled': True,
'trigger': 'bb_lower'}
Stoploss: -0.37996664668703606
```
If you are optimizing stoploss values, Freqtrade creates the 'stoploss' optimization hyperspace for you. By default, the stoploss values in that hyperspace can vary in the range -0.5...-0.02, which is sufficient in most cases.
Override the `stoploss_space()` method and define the desired range in it if you need stoploss values to vary in other range during hyperoptimization.
### Validate backtesting results ### Validate backtesting results
Once the optimized strategy has been implemented into your strategy, you should backtest this strategy to make sure everything is working as expected. Once the optimized strategy has been implemented into your strategy, you should backtest this strategy to make sure everything is working as expected.

View File

@ -5,7 +5,7 @@ from typing import Any, Callable, Dict, List
import talib.abstract as ta import talib.abstract as ta
from pandas import DataFrame from pandas import DataFrame
from skopt.space import Categorical, Dimension, Integer, Real from skopt.space import Categorical, Dimension, Integer
import freqtrade.vendor.qtpylib.indicators as qtpylib import freqtrade.vendor.qtpylib.indicators as qtpylib
from freqtrade.optimize.hyperopt_interface import IHyperOpt from freqtrade.optimize.hyperopt_interface import IHyperOpt
@ -156,42 +156,6 @@ class DefaultHyperOpts(IHyperOpt):
'sell-sar_reversal'], name='sell-trigger') 'sell-sar_reversal'], name='sell-trigger')
] ]
@staticmethod
def generate_roi_table(params: Dict) -> Dict[int, float]:
"""
Generate the ROI table that will be used by Hyperopt
"""
roi_table = {}
roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3']
roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2']
roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1']
roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0
return roi_table
@staticmethod
def stoploss_space() -> List[Dimension]:
"""
Stoploss Value to search
"""
return [
Real(-0.5, -0.02, name='stoploss'),
]
@staticmethod
def roi_space() -> List[Dimension]:
"""
Values to search for each ROI steps
"""
return [
Integer(10, 120, name='roi_t1'),
Integer(10, 60, name='roi_t2'),
Integer(10, 40, name='roi_t3'),
Real(0.01, 0.04, name='roi_p1'),
Real(0.01, 0.07, name='roi_p2'),
Real(0.01, 0.20, name='roi_p3'),
]
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
""" """
Based on TA indicators. Should be a copy of from strategy Based on TA indicators. Should be a copy of from strategy

View File

@ -7,7 +7,7 @@ from abc import ABC, abstractmethod
from typing import Dict, Any, Callable, List from typing import Dict, Any, Callable, List
from pandas import DataFrame from pandas import DataFrame
from skopt.space import Dimension from skopt.space import Dimension, Integer, Real
class IHyperOpt(ABC): class IHyperOpt(ABC):
@ -26,56 +26,80 @@ class IHyperOpt(ABC):
@abstractmethod @abstractmethod
def populate_indicators(dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_indicators(dataframe: DataFrame, metadata: dict) -> DataFrame:
""" """
Populate indicators that will be used in the Buy and Sell strategy Populate indicators that will be used in the Buy and Sell strategy.
:param dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe() :param dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe().
:return: a Dataframe with all mandatory indicators for the strategies :return: A Dataframe with all mandatory indicators for the strategies.
""" """
@staticmethod @staticmethod
@abstractmethod @abstractmethod
def buy_strategy_generator(params: Dict[str, Any]) -> Callable: def buy_strategy_generator(params: Dict[str, Any]) -> Callable:
""" """
Create a buy strategy generator Create a buy strategy generator.
""" """
@staticmethod @staticmethod
@abstractmethod @abstractmethod
def sell_strategy_generator(params: Dict[str, Any]) -> Callable: def sell_strategy_generator(params: Dict[str, Any]) -> Callable:
""" """
Create a sell strategy generator Create a sell strategy generator.
""" """
@staticmethod @staticmethod
@abstractmethod @abstractmethod
def indicator_space() -> List[Dimension]: def indicator_space() -> List[Dimension]:
""" """
Create an indicator space Create an indicator space.
""" """
@staticmethod @staticmethod
@abstractmethod @abstractmethod
def sell_indicator_space() -> List[Dimension]: def sell_indicator_space() -> List[Dimension]:
""" """
Create a sell indicator space Create a sell indicator space.
""" """
@staticmethod @staticmethod
@abstractmethod
def generate_roi_table(params: Dict) -> Dict[int, float]: def generate_roi_table(params: Dict) -> Dict[int, float]:
""" """
Create an roi table Create a ROI table.
Generates the ROI table that will be used by Hyperopt.
You may override it in your custom Hyperopt class.
""" """
roi_table = {}
roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3']
roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2']
roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1']
roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0
return roi_table
@staticmethod @staticmethod
@abstractmethod
def stoploss_space() -> List[Dimension]: def stoploss_space() -> List[Dimension]:
""" """
Create a stoploss space Create a stoploss space.
Defines range of stoploss values to search.
You may override it in your custom Hyperopt class.
""" """
return [
Real(-0.5, -0.02, name='stoploss'),
]
@staticmethod @staticmethod
@abstractmethod
def roi_space() -> List[Dimension]: def roi_space() -> List[Dimension]:
""" """
Create a roi space Create a ROI space.
Defines values to search for each ROI steps.
You may override it in your custom Hyperopt class.
""" """
return [
Integer(10, 120, name='roi_t1'),
Integer(10, 60, name='roi_t2'),
Integer(10, 40, name='roi_t3'),
Real(0.01, 0.04, name='roi_p1'),
Real(0.01, 0.07, name='roi_p2'),
Real(0.01, 0.20, name='roi_p3'),
]

View File

@ -18,14 +18,19 @@ from freqtrade.optimize.hyperopt_interface import IHyperOpt
class SampleHyperOpts(IHyperOpt): class SampleHyperOpts(IHyperOpt):
""" """
This is a test hyperopt to inspire you. This is a test hyperopt to inspire you.
More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/hyperopt.md More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/hyperopt.md
You can: You can:
- Rename the class name (Do not forget to update class_name) - Rename the class name.
- Add any methods you want to build your hyperopt - Add any methods you want to build your hyperopt.
- Add any lib you need to build your hyperopt - Add any lib you need to build your hyperopt.
You must keep: You must keep:
- the prototype for the methods: populate_indicators, indicator_space, buy_strategy_generator, - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator.
roi_space, generate_roi_table, stoploss_space
The roi_space, generate_roi_table, stoploss_space methods were moved to the parent class, you may
override them here if you need it.
""" """
@staticmethod @staticmethod
@ -167,42 +172,6 @@ class SampleHyperOpts(IHyperOpt):
'sell-sar_reversal'], name='sell-trigger') 'sell-sar_reversal'], name='sell-trigger')
] ]
@staticmethod
def generate_roi_table(params: Dict) -> Dict[int, float]:
"""
Generate the ROI table that will be used by Hyperopt
"""
roi_table = {}
roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3']
roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2']
roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1']
roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0
return roi_table
@staticmethod
def stoploss_space() -> List[Dimension]:
"""
Stoploss Value to search
"""
return [
Real(-0.5, -0.02, name='stoploss'),
]
@staticmethod
def roi_space() -> List[Dimension]:
"""
Values to search for each ROI steps
"""
return [
Integer(10, 120, name='roi_t1'),
Integer(10, 60, name='roi_t2'),
Integer(10, 40, name='roi_t3'),
Real(0.01, 0.04, name='roi_p1'),
Real(0.01, 0.07, name='roi_p2'),
Real(0.01, 0.20, name='roi_p3'),
]
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
""" """
Based on TA indicators. Should be a copy of from strategy Based on TA indicators. Should be a copy of from strategy