diff --git a/docs/hyperopt.md b/docs/hyperopt.md index 0bfa9ae2d..71f8b0cd4 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -19,8 +19,8 @@ your strategy file located into [user_data/strategies/](https://github.com/gcarq ### 1. Configure your Guards and Triggers There are two places you need to change in your strategy file to add a new buy strategy for testing: -- Inside [populate_buy_trend()](https://github.com/gcarq/freqtrade/blob/develop/user_data/strategies/test_strategy.py#L278-L294). -- Inside [hyperopt_space()](https://github.com/gcarq/freqtrade/blob/develop/user_data/strategies/test_strategy.py#L244-L297) known as `SPACE`. +- Inside [populate_buy_trend()](https://github.com/gcarq/freqtrade/blob/develop/user_data/strategies/test_strategy.py#L273-L294). +- Inside [indicator_space()](https://github.com/gcarq/freqtrade/blob/develop/user_data/strategies/test_strategy.py#L251-L67). There you have two different type of indicators: 1. `guards` and 2. `triggers`. @@ -55,29 +55,33 @@ Your hyperopt file must contain `guards` to find the right value for `(dataframe['adx'] > 65)` & and `(dataframe['plus_di'] > 0.5)`. That means you will need to enable/disable triggers. -In our case the `SPACE` and `populate_buy_trend` in your strategy file +In our case the `indicator_space` and `populate_buy_trend` in your strategy file will look like: ```python -space = { - 'rsi': hp.choice('rsi', [ - {'enabled': False}, - {'enabled': True, 'value': hp.quniform('rsi-value', 20, 40, 1)} - ]), - 'adx': hp.choice('adx', [ - {'enabled': False}, - {'enabled': True, 'value': hp.quniform('adx-value', 15, 50, 1)} - ]), - 'trigger': hp.choice('trigger', [ - {'type': 'lower_bb'}, - {'type': 'faststoch10'}, - {'type': 'ao_cross_zero'}, - {'type': 'ema5_cross_ema10'}, - {'type': 'macd_cross_signal'}, - {'type': 'sar_reversal'}, - {'type': 'stochf_cross'}, - {'type': 'ht_sine'}, - ]), -} + def indicator_space(self) -> Dict[str, Any]: + """ + Define your Hyperopt space for searching strategy parameters + """ + return { + 'rsi': hp.choice('rsi', [ + {'enabled': False}, + {'enabled': True, 'value': hp.quniform('rsi-value', 20, 40, 1)} + ]), + 'adx': hp.choice('adx', [ + {'enabled': False}, + {'enabled': True, 'value': hp.quniform('adx-value', 15, 50, 1)} + ]), + 'trigger': hp.choice('trigger', [ + {'type': 'lower_bb'}, + {'type': 'faststoch10'}, + {'type': 'ao_cross_zero'}, + {'type': 'ema5_cross_ema10'}, + {'type': 'macd_cross_signal'}, + {'type': 'sar_reversal'}, + {'type': 'stochf_cross'}, + {'type': 'ht_sine'}, + ]), + } ... @@ -100,7 +104,13 @@ def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: 'stochf_cross': (crossed_above(dataframe['fastk'], dataframe['fastd'])), 'ht_sine': (crossed_above(dataframe['htleadsine'], dataframe['htsine'])), } - ... + conditions.append(triggers.get(params['trigger']['type'])) + + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe ``` @@ -116,7 +126,7 @@ The Hyperopt configuration is located in ## Advanced notions ### Understand the Guards and Triggers When you need to add the new guards and triggers to be hyperopt -parameters, you do this by adding them into the [hyperopt_space()](https://github.com/gcarq/freqtrade/blob/develop/user_data/strategies/test_strategy.py#L244-L297). +parameters, you do this by adding them into the [indicator_space()](https://github.com/gcarq/freqtrade/blob/develop/user_data/strategies/test_strategy.py#L251-L267). If it's a trigger, you add one line to the 'trigger' choice group and that's it. diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 72b6cbbc4..e2f82e26e 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -7,18 +7,14 @@ import os import pickle import signal import sys -from functools import reduce from math import exp from operator import itemgetter -from typing import Dict, Any, Callable +from typing import Dict, Any -import numpy -import talib.abstract as ta -from hyperopt import STATUS_FAIL, STATUS_OK, Trials, fmin, hp, space_eval, tpe +from hyperopt import STATUS_FAIL, STATUS_OK, Trials, fmin, space_eval, tpe from hyperopt.mongoexp import MongoTrials from pandas import DataFrame -import freqtrade.vendor.qtpylib.indicators as qtpylib # Monkey patch config from freqtrade import main # noqa; noqa from freqtrade import exchange, misc, optimize diff --git a/freqtrade/strategy/default_strategy.py b/freqtrade/strategy/default_strategy.py index 01fb66298..65771f8db 100644 --- a/freqtrade/strategy/default_strategy.py +++ b/freqtrade/strategy/default_strategy.py @@ -4,7 +4,7 @@ import talib.abstract as ta from pandas import DataFrame from typing import Dict, Any, Callable import freqtrade.vendor.qtpylib.indicators as qtpylib -from hyperopt import STATUS_FAIL, STATUS_OK, Trials, fmin, hp, space_eval, tpe +from hyperopt import hp from functools import reduce from freqtrade.strategy.interface import IStrategy from freqtrade.indicator_helpers import fishers_inverse @@ -301,7 +301,7 @@ class DefaultStrategy(IStrategy): {'type': 'di_cross'}, ]), } - + def buy_strategy_generator(self, params: Dict[str, Any]) -> Callable: """ Define the buy strategy parameters to be used by hyperopt @@ -374,7 +374,7 @@ class DefaultStrategy(IStrategy): return dataframe return populate_buy_trend - + def roi_space(self) -> Dict[str, Any]: return { 'roi_t1': hp.quniform('roi_t1', 10, 120, 20), @@ -385,8 +385,7 @@ class DefaultStrategy(IStrategy): 'roi_p3': hp.quniform('roi_p3', 0.01, 0.20, 0.01), } - def stoploss_space(self) -> Dict[str, Any]: return { 'stoploss': hp.quniform('stoploss', -0.5, -0.02, 0.02), - } \ No newline at end of file + } diff --git a/freqtrade/strategy/strategy.py b/freqtrade/strategy/strategy.py index b4f2d87b8..8271383c0 100644 --- a/freqtrade/strategy/strategy.py +++ b/freqtrade/strategy/strategy.py @@ -185,16 +185,15 @@ class Strategy(object): Define your Hyperopt space for searching strategy parameters """ return self.custom_strategy.indicator_space() - + def buy_strategy_generator(self, params: Dict[str, Any]) -> Callable: """ Define the buy strategy parameters to be used by hyperopt """ return self.custom_strategy.buy_strategy_generator(params) - + def roi_space(self) -> Dict[str, Any]: return self.custom_strategy.roi_space() - + def stoploss_space(self) -> Dict[str, Any]: return self.custom_strategy.stoploss_space() - \ No newline at end of file