From 985f1868ac457cc60e444f0250d823f628cf8769 Mon Sep 17 00:00:00 2001 From: OtenMoten <32872932+OtenMoten@users.noreply.github.com> Date: Mon, 23 Dec 2019 20:20:55 +0100 Subject: [PATCH 1/2] Add Hyperopt file for AverageStrategy --- user_data/hyperopts/AverageHyperopt.py | 148 ++++++++++++++++++ .../berlinguyinca/AverageStrategy.py | 3 - 2 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 user_data/hyperopts/AverageHyperopt.py diff --git a/user_data/hyperopts/AverageHyperopt.py b/user_data/hyperopts/AverageHyperopt.py new file mode 100644 index 000000000..5677b4a83 --- /dev/null +++ b/user_data/hyperopts/AverageHyperopt.py @@ -0,0 +1,148 @@ +import talib.abstract as ta +from pandas import DataFrame +from typing import Dict, Any, Callable, List +from functools import reduce + +from skopt.space import Categorical, Dimension, Integer, Real + +import freqtrade.vendor.qtpylib.indicators as qtpylib +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +shortRangeBegin = 10 +shortRangeEnd = 40 +mediumRangeBegin = 50 +mediumRangeEnd = 150 + + +class AverageHyperopt(IHyperOpt): + """ + Hyperopt file for optimizing AverageStrategy. + Uses ranges of EMA periods to find the best parameter combination. + """ + + @staticmethod + def populate_indicators(dataframe: DataFrame, metadata: dict) -> DataFrame: + + for short in range(shortRangeBegin, shortRangeEnd): + dataframe[f'maShort({short})'] = ta.EMA(dataframe, timeperiod=short) + + for medium in range(mediumRangeBegin, mediumRangeEnd): + dataframe[f'maMedium({medium})'] = ta.EMA(dataframe, timeperiod=medium) + + return dataframe + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by hyperopt + """ + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use + """ + conditions = [] + + # TRIGGERS + if 'trigger' in params: + for short in range(shortRangeBegin, shortRangeEnd): + for medium in range(mediumRangeBegin, mediumRangeEnd): + if params['trigger'] == f"cross_short({short})_above_medium({medium})": + conditions.append(qtpylib.crossed_above( + dataframe[f'maShort({short})'], dataframe[f'maMedium({medium})'])) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching strategy parameters + """ + buyTriggerList = [] + for short in range(shortRangeBegin, shortRangeEnd): + for medium in range(mediumRangeBegin, mediumRangeEnd): + buyTriggerList.append( + f'cross_short({short})_above_medium({medium}') + return [ + Categorical(buyTriggerList, name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by hyperopt + """ + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use + """ + # print(params) + conditions = [] + + # TRIGGERS + if 'sell-trigger' in params: + for short in range(shortRangeBegin, shortRangeEnd): + for medium in range(mediumRangeBegin, mediumRangeEnd): + if params['sell-trigger'] == f'cross_medium({medium})_above_short({short})': + conditions.append(qtpylib.crossed_above( + dataframe[f'maMedium({medium})'], dataframe[f'maShort({short})'])) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters + """ + sellTriggerList = [] + for short in range(shortRangeBegin, shortRangeEnd): + for medium in range(mediumRangeBegin, mediumRangeEnd): + sellTriggerList.append( + f'cross_medium(medium)_above_short({short})') + + return [ + Categorical(sellTriggerList, name='sell-trigger') + ] + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators. Should be a copy of from strategy + must align to populate_indicators in this file + Only used when --spaces does not include buy + """ + dataframe.loc[ + ( + qtpylib.crossed_above( + dataframe['maShort'], dataframe['maMedium']) + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators. Should be a copy of from strategy + must align to populate_indicators in this file + Only used when --spaces does not include sell + """ + dataframe.loc[ + ( + qtpylib.crossed_above( + dataframe['maMedium'], dataframe['maShort']) + ), + 'sell'] = 1 + + return dataframe diff --git a/user_data/strategies/berlinguyinca/AverageStrategy.py b/user_data/strategies/berlinguyinca/AverageStrategy.py index 3a32e9002..4765988c7 100644 --- a/user_data/strategies/berlinguyinca/AverageStrategy.py +++ b/user_data/strategies/berlinguyinca/AverageStrategy.py @@ -1,7 +1,5 @@ # --- Do not remove these libs --- from freqtrade.strategy.interface import IStrategy -from typing import Dict, List -from functools import reduce from pandas import DataFrame # -------------------------------- @@ -32,7 +30,6 @@ class AverageStrategy(IStrategy): ticker_interval = '4h' def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: - macd = ta.MACD(dataframe) dataframe['maShort'] = ta.EMA(dataframe, timeperiod=8) dataframe['maMedium'] = ta.EMA(dataframe, timeperiod=21) From abb95aaf7fd28d4a08d91e74b738caf2fd98d165 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 7 Apr 2020 17:49:41 +0200 Subject: [PATCH 2/2] Simplify and fix AverageHyperopt --- user_data/hyperopts/AverageHyperopt.py | 39 ++++++++++++++------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/user_data/hyperopts/AverageHyperopt.py b/user_data/hyperopts/AverageHyperopt.py index 5677b4a83..0e6797b0d 100644 --- a/user_data/hyperopts/AverageHyperopt.py +++ b/user_data/hyperopts/AverageHyperopt.py @@ -9,9 +9,9 @@ from freqtrade.optimize.hyperopt_interface import IHyperOpt shortRangeBegin = 10 -shortRangeEnd = 40 -mediumRangeBegin = 50 -mediumRangeEnd = 150 +shortRangeEnd = 20 +mediumRangeBegin = 100 +mediumRangeEnd = 120 class AverageHyperopt(IHyperOpt): @@ -41,14 +41,12 @@ def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: Buy strategy Hyperopt will build and use """ conditions = [] - # TRIGGERS if 'trigger' in params: - for short in range(shortRangeBegin, shortRangeEnd): - for medium in range(mediumRangeBegin, mediumRangeEnd): - if params['trigger'] == f"cross_short({short})_above_medium({medium})": - conditions.append(qtpylib.crossed_above( - dataframe[f'maShort({short})'], dataframe[f'maMedium({medium})'])) + conditions.append(qtpylib.crossed_above( + dataframe[f"maShort({params['trigger'][0]})"], + dataframe[f"maMedium({params['trigger'][1]})"]) + ) if conditions: dataframe.loc[ @@ -67,8 +65,10 @@ def indicator_space() -> List[Dimension]: buyTriggerList = [] for short in range(shortRangeBegin, shortRangeEnd): for medium in range(mediumRangeBegin, mediumRangeEnd): + # The output will be (short, long) buyTriggerList.append( - f'cross_short({short})_above_medium({medium}') + (short, medium) + ) return [ Categorical(buyTriggerList, name='trigger') ] @@ -87,11 +87,10 @@ def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: # TRIGGERS if 'sell-trigger' in params: - for short in range(shortRangeBegin, shortRangeEnd): - for medium in range(mediumRangeBegin, mediumRangeEnd): - if params['sell-trigger'] == f'cross_medium({medium})_above_short({short})': - conditions.append(qtpylib.crossed_above( - dataframe[f'maMedium({medium})'], dataframe[f'maShort({short})'])) + conditions.append(qtpylib.crossed_above( + dataframe[f"maMedium({params['sell-trigger'][1]})"], + dataframe[f"maShort({params['sell-trigger'][0]})"]) + ) if conditions: dataframe.loc[ @@ -110,8 +109,10 @@ def sell_indicator_space() -> List[Dimension]: sellTriggerList = [] for short in range(shortRangeBegin, shortRangeEnd): for medium in range(mediumRangeBegin, mediumRangeEnd): + # The output will be (short, long) sellTriggerList.append( - f'cross_medium(medium)_above_short({short})') + (short, medium) + ) return [ Categorical(sellTriggerList, name='sell-trigger') @@ -126,7 +127,8 @@ def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ ( qtpylib.crossed_above( - dataframe['maShort'], dataframe['maMedium']) + dataframe[f'maShort({shortRangeBegin})'], + dataframe[f'maMedium({mediumRangeBegin})']) ), 'buy'] = 1 @@ -141,7 +143,8 @@ def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame dataframe.loc[ ( qtpylib.crossed_above( - dataframe['maMedium'], dataframe['maShort']) + dataframe[f'maMedium({mediumRangeBegin})'], + dataframe[f'maShort({shortRangeBegin})']) ), 'sell'] = 1