diff --git a/user_data/hyperopts/HeraclesHo.py b/user_data/hyperopts/HeraclesHo.py deleted file mode 100644 index aa174ee..0000000 --- a/user_data/hyperopts/HeraclesHo.py +++ /dev/null @@ -1,118 +0,0 @@ -# Heracles 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 --gene 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... - - -class HeraclesHo(IHyperOpt): - - @staticmethod - def indicator_space() -> 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/Heracles.py b/user_data/strategies/Heracles.py index 48967f4..8ecc27e 100644 --- a/user_data/strategies/Heracles.py +++ b/user_data/strategies/Heracles.py @@ -8,19 +8,14 @@ # "min_days_listed": 100 # }, # IMPORTANT: INSTALL TA BEFOUR RUN(pip install ta) +# +# freqtrade hyperopt --hyperopt-loss SharpeHyperOptLoss --spaces roi buy sell --strategy Heracles # ###################################################################### -# Optimal config settings: -# "max_open_trades": 100, -# "stake_amount": "unlimited", - # --- Do not remove these libs --- -import logging - -from numpy.lib import math +from freqtrade.strategy.hyper import IntParameter, DecimalParameter 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 @@ -31,103 +26,154 @@ from functools import reduce import numpy as np +def normalize(df): + # To enable normalization outcomment below line: + df = (df-df.min())/(df.max()-df.min()) + return df + class Heracles(IStrategy): - # 65/600: 2275 trades. 1438/7/830 W/D/L. - # Avg profit 3.10%. Median profit 3.06%. - # Total profit 113171 USDT ( 7062 Σ%). - # Avg duration 345 min. Objective: -23.0 + ########################################## RESULT PASTE PLACE ########################################## + # 35/50: 129 trades. 96/15/18 Wins/Draws/Losses. Avg profit 3.57%. Median profit 4.30%. Total profit 2302.93351920 USDT ( 46.06Σ%). Avg duration 2 days, 19:04:00 min. Objective: -21.29091 + # Buy hyperspace params: buy_params = { - 'buy-cross-0': 'volatility_kcw', - 'buy-indicator-0': 'volatility_dcp', - 'buy-oper-0': '<', + "buy_crossed_indicator_shift": -5, + "buy_div": 4.7968, + "buy_indicator_shift": 5, } # Sell hyperspace params: sell_params = { - 'sell-cross-0': 'trend_macd_signal', - 'sell-indicator-0': 'trend_ema_fast', - 'sell-oper-0': '=', + "sell_atol": 0.21256, + "sell_crossed_indicator_shift": 0, + "sell_indicator_shift": -1, + "sell_rtol": 0.11195, } # ROI table: minimal_roi = { - "0": 0.32836, - "1629": 0.17896, - "6302": 0.05372, - "10744": 0 + "0": 0.43, + "994": 0.076, + "2864": 0.043, + "6947": 0 } - + # Stoploss: - stoploss = -0.04655 + stoploss = -0.312 + + ########################################## END RESULT PASTE PLACE ###################################### - # Trailing stop: - trailing_stop = True - trailing_stop_positive = 0.02444 - trailing_stop_positive_offset = 0.04406 - trailing_only_offset_is_reached = True - # Buy hypers - timeframe = '12h' + # buy params + buy_div = DecimalParameter(-5, 5, default=0.51844, decimals=4, space='buy') + buy_indicator_shift = IntParameter(-5, 5, default=4, space='buy') + buy_crossed_indicator_shift = IntParameter(-5, 5, default=1, space='buy') + # sell params + sell_rtol = DecimalParameter(1.e-10, 1.e-0, default=0.05468, decimals=10, space='sell') + sell_atol = DecimalParameter(1.e-16, 1.e-0, default=0.00019, decimals=10, space='sell') + sell_indicator_shift = IntParameter(-5, 5, default=4, space='sell') + sell_crossed_indicator_shift = IntParameter(-5, 5, default=1, space='sell') + + + # Optimal timeframe use it in your config + timeframe = '4h' + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> 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['volatility_kcw'] = normalize(ta.volatility.keltner_channel_wband( + dataframe['high'], + dataframe['low'], + dataframe['close'], + window=20, + window_atr=10, + fillna=False, + original_version=True + )) + + dataframe['volatility_dcp'] =normalize(ta.volatility.donchian_channel_pband( + dataframe['high'], + dataframe['low'], + dataframe['close'], + window=10, + offset=0, + fillna=False + )) + + dataframe['trend_macd_signal'] =normalize(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() + dataframe['trend_ema_fast'] =normalize(ta.trend.EMAIndicator( + close=dataframe['close'], window=12, fillna=False + ).ema_indicator()) + + + # for checking crossovers! + # but we dont need to crossovers we just calculate dividation + + # import matplotlib.pyplot as plt + # dataframe.iloc[:,6:].plot(subplots=False) + # plt.tight_layout() + # plt.show() return dataframe def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] - IND = self.buy_params['buy-indicator-0'] - CRS = self.buy_params['buy-cross-0'] + IND = 'volatility_dcp' + CRS = 'volatility_kcw' DFIND = dataframe[IND] DFCRS = dataframe[CRS] - dataframe.loc[ - (DFIND < DFCRS), - 'buy'] = 1 + conditions.append( + DFIND.shift(self.buy_indicator_shift.value).div( + DFCRS.shift(self.buy_crossed_indicator_shift.value) + ) <= self.buy_div.value + ) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + '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'] + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + IND = 'trend_ema_fast' + CRS = 'trend_macd_signal' DFIND = dataframe[IND] DFCRS = dataframe[CRS] - dataframe.loc[ - (qtpylib.crossed_below(DFIND, DFCRS)), - 'sell'] = 1 + conditions.append( + np.isclose( + DFIND.shift(self.sell_indicator_shift.value), + DFCRS.shift(self.sell_crossed_indicator_shift.value), + rtol=self.sell_rtol.value, + atol=self.sell_rtol.value + ) + ) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell']=1 return dataframe