improve docs, make example strat hyperoptable

This commit is contained in:
robcaulk 2022-09-08 22:22:50 +02:00
parent bf3ee51167
commit bc7295579f
2 changed files with 39 additions and 14 deletions

View File

@ -538,12 +538,28 @@ for each pair, for each backtesting window within the expanded `--timerange`.
### Hyperopt ### Hyperopt
The [Hyperopt](hyperopt.md) module can be executed with some restrictions: Users can hyperopt using the same command as typical [hyperopt](hyperopt.md):
```bash
freqtrade hyperopt --hyperopt-loss SharpeHyperOptLoss --strategy FreqaiExampleStrategy --strategy-path freqtrade/templates --config config_examples/config_freqai.example.json --timerange 20220428-20220507
```
Users need to have the data pre-downloaded in the same fashion as if they were doing a FreqAI [backtest](#backtesting). In addition, users must consider some restrictions when trying to [Hyperopt](hyperopt.md) FreqAI strategies:
- The `--analyze-per-epoch` hyperopt parameter is not compatible with FreqAI. - The `--analyze-per-epoch` hyperopt parameter is not compatible with FreqAI.
- It's not possible to hyperopt indicators in `populate_any_indicators()` function. This means that the user cannot optimize model parameters using hyperopt. Apart from this exception, it is possible to optimize all other [spaces](hyperopt.md#running-hyperopt-with-smaller-search-space). - It's not possible to hyperopt indicators in `populate_any_indicators()` function. This means that the user cannot optimize model parameters using hyperopt. Apart from this exception, it is possible to optimize all other [spaces](hyperopt.md#running-hyperopt-with-smaller-search-space).
- The [Backtesting](#backtesting) instructions also apply apply to Hyperopt. - The [Backtesting](#backtesting) instructions also apply to Hyperopt.
The best method for combining hyperopt and FreqAI is to focus on hyperopting entry/exit thresholds/criteria. Users need to focus on hyperopting parameters that are not used in their FreqAI features. For example, users should not try to hyperopt rolling window lengths in their feature creation, or any of their FreqAI config which changes predictions. In order to efficiently hyperopt the FreqAI strategy, FreqAI stores predictions as dataframes and reuses them. Hence the requirement to hyperopt entry/exit thresholds/criteria only.
A good example of a hyperoptable parameter in FreqAI is a value for `DI_values` beyond which we consider outliers and below which we consider inliers:
```python
di_max = IntParameter(low=1, high=20, default=10, space='buy', optimize=True, load=True)
dataframe['outlier'] = np.where(dataframe['DI_values'] > self.di_max.value/10, 1, 0)
```
Which would help the user understand the appropriate Dissimilarity Index values for their particular parameter space.
### Deciding the size of the sliding training window and backtesting duration ### Deciding the size of the sliding training window and backtesting duration

View File

@ -6,7 +6,7 @@ import talib.abstract as ta
from pandas import DataFrame from pandas import DataFrame
from technical import qtpylib from technical import qtpylib
from freqtrade.strategy import IStrategy, merge_informative_pair from freqtrade.strategy import IStrategy, merge_informative_pair, CategoricalParameter
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -29,9 +29,6 @@ class FreqaiExampleStrategy(IStrategy):
"main_plot": {}, "main_plot": {},
"subplots": { "subplots": {
"prediction": {"prediction": {"color": "blue"}}, "prediction": {"prediction": {"color": "blue"}},
"target_roi": {
"target_roi": {"color": "brown"},
},
"do_predict": { "do_predict": {
"do_predict": {"color": "brown"}, "do_predict": {"color": "brown"},
}, },
@ -45,6 +42,11 @@ class FreqaiExampleStrategy(IStrategy):
startup_candle_count: int = 40 startup_candle_count: int = 40
can_short = False can_short = False
std_dev_multiplier_buy = CategoricalParameter(
[0.75, 1, 1.25, 1.5, 1.75], default=1.25, space="buy", optimize=True)
std_dev_multiplier_sell = CategoricalParameter(
[0.1, 0.25, 0.4], space="sell", default=0.2, optimize=True)
def informative_pairs(self): def informative_pairs(self):
whitelist_pairs = self.dp.current_whitelist() whitelist_pairs = self.dp.current_whitelist()
corr_pairs = self.config["freqai"]["feature_parameters"]["include_corr_pairlist"] corr_pairs = self.config["freqai"]["feature_parameters"]["include_corr_pairlist"]
@ -182,21 +184,26 @@ class FreqaiExampleStrategy(IStrategy):
# `populate_any_indicators()` for each training period. # `populate_any_indicators()` for each training period.
dataframe = self.freqai.start(dataframe, metadata, self) dataframe = self.freqai.start(dataframe, metadata, self)
for val in self.std_dev_multiplier_buy.range:
dataframe["target_roi"] = dataframe["&-s_close_mean"] + dataframe["&-s_close_std"] * 1.25 dataframe[f'target_roi_{val}'] = dataframe["&-s_close_mean"] + \
dataframe["sell_roi"] = dataframe["&-s_close_mean"] - dataframe["&-s_close_std"] * 1.25 dataframe["&-s_close_std"] * val
for val in self.std_dev_multiplier_sell.range:
dataframe[f'sell_roi_{val}'] = dataframe["&-s_close_mean"] - \
dataframe["&-s_close_std"] * val
return dataframe return dataframe
def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame: def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
enter_long_conditions = [df["do_predict"] == 1, df["&-s_close"] > df["target_roi"]] enter_long_conditions = [df["do_predict"] == 1, df["&-s_close"]
> df[f"target_roi_{self.std_dev_multiplier_buy.value}"]]
if enter_long_conditions: if enter_long_conditions:
df.loc[ df.loc[
reduce(lambda x, y: x & y, enter_long_conditions), ["enter_long", "enter_tag"] reduce(lambda x, y: x & y, enter_long_conditions), ["enter_long", "enter_tag"]
] = (1, "long") ] = (1, "long")
enter_short_conditions = [df["do_predict"] == 1, df["&-s_close"] < df["sell_roi"]] enter_short_conditions = [df["do_predict"] == 1, df["&-s_close"]
< df[f"sell_roi_{self.std_dev_multiplier_sell.value}"]]
if enter_short_conditions: if enter_short_conditions:
df.loc[ df.loc[
@ -206,11 +213,13 @@ class FreqaiExampleStrategy(IStrategy):
return df return df
def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame: def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
exit_long_conditions = [df["do_predict"] == 1, df["&-s_close"] < df["sell_roi"] * 0.25] exit_long_conditions = [df["do_predict"] == 1, df["&-s_close"] <
df[f"sell_roi_{self.std_dev_multiplier_sell.value}"] * 0.25]
if exit_long_conditions: if exit_long_conditions:
df.loc[reduce(lambda x, y: x & y, exit_long_conditions), "exit_long"] = 1 df.loc[reduce(lambda x, y: x & y, exit_long_conditions), "exit_long"] = 1
exit_short_conditions = [df["do_predict"] == 1, df["&-s_close"] > df["target_roi"] * 0.25] exit_short_conditions = [df["do_predict"] == 1, df["&-s_close"] >
df[f"target_roi_{self.std_dev_multiplier_buy.value}"] * 0.25]
if exit_short_conditions: if exit_short_conditions:
df.loc[reduce(lambda x, y: x & y, exit_short_conditions), "exit_short"] = 1 df.loc[reduce(lambda x, y: x & y, exit_short_conditions), "exit_short"] = 1