From 5f46653b2d8af080a9fc50875bf5208e9fed3051 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Sep 2021 19:25:35 +0200 Subject: [PATCH] Update averageStrategy to use Strategy parameters --- user_data/hyperopts/AverageHyperopt.py | 134 ------------------ .../berlinguyinca/AverageStrategy.py | 22 ++- 2 files changed, 18 insertions(+), 138 deletions(-) delete mode 100644 user_data/hyperopts/AverageHyperopt.py diff --git a/user_data/hyperopts/AverageHyperopt.py b/user_data/hyperopts/AverageHyperopt.py deleted file mode 100644 index d7410fd..0000000 --- a/user_data/hyperopts/AverageHyperopt.py +++ /dev/null @@ -1,134 +0,0 @@ -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 = 20 -mediumRangeBegin = 100 -mediumRangeEnd = 120 - - -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: - trigger = [int(item) for item in params['trigger'].split('-')] - - conditions.append(qtpylib.crossed_above( - dataframe[f"maShort({trigger[0]})"], - dataframe[f"maMedium({trigger[1]})"]) - ) - - # Check that volume is not 0 - conditions.append(dataframe['volume'] > 0) - - 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): - """ - The output will be '{short}-{long}' so we can split it on the trigger - this will prevent an error on scikit-optimize not accepting tuples as - first argument to Categorical - """ - buyTriggerList.append( - '{}-{}'.format(short, 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: - trigger = [int(item) for item in params['sell-trigger'].split('-')] - - conditions.append(qtpylib.crossed_above( - dataframe[f"maMedium({trigger[1]})"], - dataframe[f"maShort({trigger[0]})"]) - ) - - 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): - """ - The output will be '{short}-{long}' so we can split it on the trigger - this will prevent an error on scikit-optimize not accepting tuples as - first argument to Categorical - """ - sellTriggerList.append( - '{}-{}'.format(short, medium) - ) - - return [ - Categorical(sellTriggerList, name='sell-trigger') - ] diff --git a/user_data/strategies/berlinguyinca/AverageStrategy.py b/user_data/strategies/berlinguyinca/AverageStrategy.py index 87c45f0..3f996af 100644 --- a/user_data/strategies/berlinguyinca/AverageStrategy.py +++ b/user_data/strategies/berlinguyinca/AverageStrategy.py @@ -1,5 +1,7 @@ # --- Do not remove these libs --- +from functools import reduce from freqtrade.strategy import IStrategy +from freqtrade.strategy import CategoricalParameter, DecimalParameter, IntParameter from pandas import DataFrame # -------------------------------- @@ -29,10 +31,14 @@ class AverageStrategy(IStrategy): # Optimal timeframe for the strategy timeframe = '4h' + buy_range_short = IntParameter(5, 20, default=8) + buy_range_long = IntParameter(20, 120, default=21) + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: - dataframe['maShort'] = ta.EMA(dataframe, timeperiod=8) - dataframe['maMedium'] = ta.EMA(dataframe, timeperiod=21) + # Combine all ranges ... to avoid duplicate calculation + for val in list(set(list(self.buy_range_short.range) + list(self.buy_range_long.range))): + dataframe[f'ema{val}'] = ta.EMA(dataframe, timeperiod=val) return dataframe @@ -44,7 +50,11 @@ class AverageStrategy(IStrategy): """ dataframe.loc[ ( - qtpylib.crossed_above(dataframe['maShort'], dataframe['maMedium']) + qtpylib.crossed_above( + dataframe[f'ema{self.buy_range_short.value}'], + dataframe[f'ema{self.buy_range_long.value}'] + ) & + (dataframe['volume'] > 0) ), 'buy'] = 1 @@ -58,7 +68,11 @@ class AverageStrategy(IStrategy): """ dataframe.loc[ ( - qtpylib.crossed_above(dataframe['maMedium'], dataframe['maShort']) + qtpylib.crossed_above( + dataframe[f'ema{self.buy_range_long.value}'], + dataframe[f'ema{self.buy_range_short.value}'] + ) & + (dataframe['volume'] > 0) ), 'sell'] = 1 return dataframe