diff --git a/user_data/hyperopts/GodStraHo.py b/user_data/hyperopts/GodStraHo.py new file mode 100644 index 0000000..e7f4cff --- /dev/null +++ b/user_data/hyperopts/GodStraHo.py @@ -0,0 +1,199 @@ +# GodStra Strategy Hyperopt +# Author: @Mablue (Masoud Azizi) +# github: https://github.com/mablue/ +# IMPORTANT: INSTALL TA BEFOUR RUN: +# :~$ pip install ta +# freqtrade hyperopt --hyperopt GodStraHo --hyperopt-loss SharpeHyperOptLossDaily --spaces all --strategy GodStra --config config.json -e 100 + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +# import talib.abstract as ta # noqa +from ta import add_all_ta_features +from ta.utils import dropna +import freqtrade.vendor.qtpylib.indicators as qtpylib +# this is your trading strategy DNA Size +# you can change it and see the results... +DNA_SIZE = 1 + + +GodGenes = ["open", "high", "low", "close", "volume", "volume_adi", "volume_obv", + "volume_cmf", "volume_fi", "volume_mfi", "volume_em", "volume_sma_em", "volume_vpt", + "volume_nvi", "volume_vwap", "volatility_atr", "volatility_bbm", "volatility_bbh", + "volatility_bbl", "volatility_bbw", "volatility_bbp", "volatility_bbhi", + "volatility_bbli", "volatility_kcc", "volatility_kch", "volatility_kcl", + "volatility_kcw", "volatility_kcp", "volatility_kchi", "volatility_kcli", + "volatility_dcl", "volatility_dch", "volatility_dcm", "volatility_dcw", + "volatility_dcp", "volatility_ui", "trend_macd", "trend_macd_signal", + "trend_macd_diff", "trend_sma_fast", "trend_sma_slow", "trend_ema_fast", + "trend_ema_slow", "trend_adx", "trend_adx_pos", "trend_adx_neg", "trend_vortex_ind_pos", + "trend_vortex_ind_neg", "trend_vortex_ind_diff", "trend_trix", + "trend_mass_index", "trend_cci", "trend_dpo", "trend_kst", + "trend_kst_sig", "trend_kst_diff", "trend_ichimoku_conv", + "trend_ichimoku_base", "trend_ichimoku_a", "trend_ichimoku_b", + "trend_visual_ichimoku_a", "trend_visual_ichimoku_b", "trend_aroon_up", + "trend_aroon_down", "trend_aroon_ind", "trend_psar_up", "trend_psar_down", + "trend_psar_up_indicator", "trend_psar_down_indicator", "trend_stc", + "momentum_rsi", "momentum_stoch_rsi", "momentum_stoch_rsi_k", + "momentum_stoch_rsi_d", "momentum_tsi", "momentum_uo", "momentum_stoch", + "momentum_stoch_signal", "momentum_wr", "momentum_ao", "momentum_kama", + "momentum_roc", "momentum_ppo", "momentum_ppo_signal", "momentum_ppo_hist", + "others_dr", "others_dlr", "others_cr"] + + +class GodStraHo(IHyperOpt): + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + gene = list() + + for i in range(DNA_SIZE): + gene.append(Categorical(GodGenes, name=f'buy-indicator-{i}')) + gene.append(Categorical(GodGenes, name=f'buy-cross-{i}')) + gene.append(Integer(-1, 101, name=f'buy-int-{i}')) + gene.append(Real(-1.1, 1.1, name=f'buy-real-{i}')) + # Operations + # CA: Crossed Above, CB: Crossed Below, + # I: Integer, R: Real, D: Disabled + gene.append(Categorical(["D", ">", "<", "=", "CA", "CB", + ">I", "=I", "R", "=R", " 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 = [] + # GUARDS AND TRENDS + for i in range(DNA_SIZE): + + OPR = params[f'buy-oper-{i}'] + IND = params[f'buy-indicator-{i}'] + CRS = params[f'buy-cross-{i}'] + INT = params[f'buy-int-{i}'] + REAL = params[f'buy-real-{i}'] + DFIND = dataframe[IND] + DFCRS = dataframe[CRS] + + if OPR == ">": + conditions.append(DFIND > DFCRS) + elif OPR == "=": + conditions.append(np.isclose(DFIND, DFCRS)) + elif OPR == "<": + conditions.append(DFIND < DFCRS) + elif OPR == "CA": + conditions.append(qtpylib.crossed_above(DFIND, DFCRS)) + elif OPR == "CB": + conditions.append(qtpylib.crossed_below(DFIND, DFCRS)) + elif OPR == ">I": + conditions.append(DFIND > INT) + elif OPR == "=I": + conditions.append(DFIND == INT) + elif OPR == "R": + conditions.append(DFIND > REAL) + elif OPR == "=R": + conditions.append(np.isclose(DFIND, REAL)) + elif OPR == " List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + gene = list() + + for i in range(DNA_SIZE): + gene.append(Categorical(GodGenes, name=f'sell-indicator-{i}')) + gene.append(Categorical(GodGenes, name=f'sell-cross-{i}')) + gene.append(Integer(-1, 101, name=f'sell-int-{i}')) + gene.append(Real(-0.01, 1.01, name=f'sell-real-{i}')) + # Operations + # CA: Crossed Above, CB: Crossed Below, + # I: Integer, R: Real, D: Disabled + gene.append(Categorical(["D", ">", "<", "=", "CA", "CB", + ">I", "=I", "R", "=R", " 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. + """ + conditions = [] + + # GUARDS AND TRENDS + for i in range(DNA_SIZE): + + OPR = params[f'sell-oper-{i}'] + IND = params[f'sell-indicator-{i}'] + CRS = params[f'sell-cross-{i}'] + INT = params[f'sell-int-{i}'] + REAL = params[f'sell-real-{i}'] + DFIND = dataframe[IND] + DFCRS = dataframe[CRS] + + if OPR == ">": + conditions.append(DFIND > DFCRS) + elif OPR == "=": + conditions.append(np.isclose(DFIND, DFCRS)) + elif OPR == "<": + conditions.append(DFIND < DFCRS) + elif OPR == "CA": + conditions.append(qtpylib.crossed_above(DFIND, DFCRS)) + elif OPR == "CB": + conditions.append(qtpylib.crossed_below(DFIND, DFCRS)) + elif OPR == ">I": + conditions.append(DFIND > INT) + elif OPR == "=I": + conditions.append(DFIND == INT) + elif OPR == "R": + conditions.append(DFIND > REAL) + elif OPR == "=R": + conditions.append(np.isclose(DFIND, REAL)) + elif OPR == " List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + + return [ + Real(-0.1, 1.1, name='buy-div'), + Integer(0, 5, name='DFINDShift'), + Integer(0, 5, name='DFCRSShift'), + ] + + @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 = [] + + IND = 'volatility_dcp' + CRS = 'volatility_kcw' + DFIND = dataframe[IND] + DFCRS = dataframe[CRS] + + conditions.append( + DFIND.shift(params['DFINDShift']).div( + DFCRS.shift(params['DFCRSShift']) + ) <= params['buy-div'] + ) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @ staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Real(1.e-10, 1.e-0, name='sell-rtol'), + Real(1.e-16, 1.e-0, name='sell-atol'), + Integer(0, 5, name='DFINDShift'), + Integer(0, 5, name='DFCRSShift'), + ] + + @ 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. + """ + conditions = [] + + IND = 'trend_ema_fast' + CRS = 'trend_macd_signal' + DFIND = dataframe[IND] + DFCRS = dataframe[CRS] + + conditions.append( + np.isclose( + DFIND.shift(params['DFINDShift']), + DFCRS.shift(params['DFCRSShift']), + rtol=params['sell-rtol'], + atol=params['sell-atol'] + ) + ) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell']=1 + + return dataframe + + return populate_sell_trend diff --git a/user_data/strategies/GodStra.py b/user_data/strategies/GodStra.py new file mode 100644 index 0000000..bf11c70 --- /dev/null +++ b/user_data/strategies/GodStra.py @@ -0,0 +1,167 @@ +# GodStra Strategy +# Author: @Mablue (Masoud Azizi) +# github: https://github.com/mablue/ +# IMPORTANT:Add to your pairlists inside config.json (Under StaticPairList): +# { +# "method": "AgeFilter", +# "min_days_listed": 30 +# }, +# IMPORTANT: INSTALL TA BEFOUR RUN(pip install ta) +# IMPORTANT: Use Smallest "max_open_trades" for getting best results inside config.json + +# --- Do not remove these libs --- +import logging + +from numpy.lib import math +from freqtrade.strategy.interface import IStrategy +from pandas import DataFrame +# -------------------------------- + +# Add your lib to import here +# import talib.abstract as ta +import pandas as pd +# import talib.abstract as ta +from ta import add_all_ta_features +from ta.utils import dropna +import freqtrade.vendor.qtpylib.indicators as qtpylib +from functools import reduce +import numpy as np + + +class GodStra(IStrategy): + # 5/66: 9 trades. 8/0/1 Wins/Draws/Losses. Avg profit 21.83%. Median profit 35.52%. Total profit 1060.11476586 USDT ( 196.50Σ%). Avg duration 3440.0 min. Objective: -7.06960 + # +--------+---------+----------+------------------+--------------+-------------------------------+----------------+-------------+ + # | Best | Epoch | Trades | Win Draw Loss | Avg profit | Profit | Avg duration | Objective | + # |--------+---------+----------+------------------+--------------+-------------------------------+----------------+-------------| + # | * Best | 1/500 | 11 | 2 1 8 | 5.22% | 280.74230393 USDT (57.40%) | 2,421.8 m | -2.85206 | + # | * Best | 2/500 | 10 | 7 0 3 | 18.76% | 983.46414442 USDT (187.58%) | 360.0 m | -4.32665 | + # | * Best | 5/500 | 9 | 8 0 1 | 21.83% | 1,060.11476586 USDT (196.50%) | 3,440.0 m | -7.0696 | + + # Buy hyperspace params: + buy_params = { + 'buy-cross-0': 'volatility_kcc', + 'buy-indicator-0': 'trend_ichimoku_base', + 'buy-int-0': 42, + 'buy-oper-0': ' DataFrame: + # Add all ta features + dataframe = dropna(dataframe) + dataframe = add_all_ta_features( + dataframe, open="open", high="high", low="low", close="close", volume="volume", fillna=True) + # dataframe.to_csv("df.csv", index=True) + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + conditions = list() + # /5: Cuz We have 5 Group of variables inside buy_param + for i in range(int(len(self.buy_params)/5)): + + OPR = self.buy_params[f'buy-oper-{i}'] + IND = self.buy_params[f'buy-indicator-{i}'] + CRS = self.buy_params[f'buy-cross-{i}'] + INT = self.buy_params[f'buy-int-{i}'] + REAL = self.buy_params[f'buy-real-{i}'] + DFIND = dataframe[IND] + DFCRS = dataframe[CRS] + + if OPR == ">": + conditions.append(DFIND > DFCRS) + elif OPR == "=": + conditions.append(np.isclose(DFIND, DFCRS)) + elif OPR == "<": + conditions.append(DFIND < DFCRS) + elif OPR == "CA": + conditions.append(qtpylib.crossed_above(DFIND, DFCRS)) + elif OPR == "CB": + conditions.append(qtpylib.crossed_below(DFIND, DFCRS)) + elif OPR == ">I": + conditions.append(DFIND > INT) + elif OPR == "=I": + conditions.append(DFIND == INT) + elif OPR == "R": + conditions.append(DFIND > REAL) + elif OPR == "=R": + conditions.append(np.isclose(DFIND, REAL)) + elif OPR == " DataFrame: + conditions = list() + for i in range(int(len(self.sell_params)/5)): + OPR = self.sell_params[f'sell-oper-{i}'] + IND = self.sell_params[f'sell-indicator-{i}'] + CRS = self.sell_params[f'sell-cross-{i}'] + INT = self.sell_params[f'sell-int-{i}'] + REAL = self.sell_params[f'sell-real-{i}'] + DFIND = dataframe[IND] + DFCRS = dataframe[CRS] + + if OPR == ">": + conditions.append(DFIND > DFCRS) + elif OPR == "=": + conditions.append(np.isclose(DFIND, DFCRS)) + elif OPR == "<": + conditions.append(DFIND < DFCRS) + elif OPR == "CA": + conditions.append(qtpylib.crossed_above(DFIND, DFCRS)) + elif OPR == "CB": + conditions.append(qtpylib.crossed_below(DFIND, DFCRS)) + elif OPR == ">I": + conditions.append(DFIND > INT) + elif OPR == "=I": + conditions.append(DFIND == INT) + elif OPR == "R": + conditions.append(DFIND > REAL) + elif OPR == "=R": + conditions.append(np.isclose(DFIND, REAL)) + elif OPR == " DataFrame: + # Add all ta features + dataframe = dropna(dataframe) + + dataframe['volatility_kcw'] = ta.volatility.keltner_channel_wband( + dataframe['high'], + dataframe['low'], + dataframe['close'], + window=20, + window_atr=10, + fillna=False, + original_version=True + ) + dataframe['volatility_dcp'] = ta.volatility.donchian_channel_pband( + dataframe['high'], + dataframe['low'], + dataframe['close'], + window=10, + offset=0, + fillna=False + ) + dataframe['trend_macd_signal'] = ta.trend.macd_signal( + dataframe['close'], + window_slow=26, + window_fast=12, + window_sign=9, + fillna=False + ) + + dataframe['trend_ema_fast'] = ta.trend.EMAIndicator( + close=dataframe['close'], window=12, fillna=False + ).ema_indicator() + + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + + IND = self.buy_params['buy-indicator-0'] + CRS = self.buy_params['buy-cross-0'] + DFIND = dataframe[IND] + DFCRS = dataframe[CRS] + + dataframe.loc[ + (DFIND < DFCRS), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + IND = self.sell_params['sell-indicator-0'] + CRS = self.sell_params['sell-cross-0'] + + DFIND = dataframe[IND] + DFCRS = dataframe[CRS] + + dataframe.loc[ + (qtpylib.crossed_below(DFIND, DFCRS)), + 'sell'] = 1 + + return dataframe