simplify hybrid template

This commit is contained in:
smarmau 2022-08-28 11:29:48 +02:00 committed by robcaulk
parent 6189aa817c
commit 005594c29c

View File

@ -4,6 +4,7 @@ import numpy as np
import pandas as pd import pandas as pd
import talib.abstract as ta import talib.abstract as ta
from pandas import DataFrame from pandas import DataFrame
from technical import qtpylib
from freqtrade.strategy import IntParameter, IStrategy, merge_informative_pair from freqtrade.strategy import IntParameter, IStrategy, merge_informative_pair
@ -48,7 +49,7 @@ class FreqaiExampleHybridStrategy(IStrategy):
"indicator_periods_candles": [10, 20] "indicator_periods_candles": [10, 20]
}, },
"data_split_parameters": { "data_split_parameters": {
"test_size": 0.33, "test_size": 0,
"random_state": 1 "random_state": 1
}, },
"model_training_parameters": { "model_training_parameters": {
@ -56,49 +57,44 @@ class FreqaiExampleHybridStrategy(IStrategy):
} }
}, },
Thanks to @smarm and @jooopieeert for developing and sharing the strategy. Thanks to @smarmau and @johanvulgt for developing and sharing the strategy.
""" """
minimal_roi = {"0": 0.1, "30": 0.75, "60": 0.05, "120": 0.025, "240": -1} minimal_roi = {
"60": 0.01,
"30": 0.02,
"0": 0.04
}
plot_config = {
'main_plot': {
'tema': {},
},
'subplots': {
"MACD": {
'macd': {'color': 'blue'},
'macdsignal': {'color': 'orange'},
},
"RSI": {
'rsi': {'color': 'red'},
},
"Up_or_down": {
'&s-up_or_down': {'color': 'green'},
}
}
}
process_only_new_candles = True process_only_new_candles = True
stoploss = -0.1 stoploss = -0.05
use_exit_signal = True use_exit_signal = True
startup_candle_count: int = 300 startup_candle_count: int = 300
can_short = True can_short = True
buy_params = { # Hyperoptable parameters
"buy_m1": 4, buy_rsi = IntParameter(low=1, high=50, default=30, space='buy', optimize=True, load=True)
"buy_m2": 7, sell_rsi = IntParameter(low=50, high=100, default=70, space='sell', optimize=True, load=True)
"buy_m3": 1, short_rsi = IntParameter(low=51, high=100, default=70, space='sell', optimize=True, load=True)
"buy_p1": 8, exit_short_rsi = IntParameter(low=1, high=50, default=30, space='buy', optimize=True, load=True)
"buy_p2": 9,
"buy_p3": 8,
}
# Sell hyperspace params:
sell_params = {
"sell_m1": 1,
"sell_m2": 3,
"sell_m3": 6,
"sell_p1": 16,
"sell_p2": 18,
"sell_p3": 18,
}
buy_m1 = IntParameter(1, 7, default=1)
buy_m2 = IntParameter(1, 7, default=3)
buy_m3 = IntParameter(1, 7, default=4)
buy_p1 = IntParameter(7, 21, default=14)
buy_p2 = IntParameter(7, 21, default=10)
buy_p3 = IntParameter(7, 21, default=10)
sell_m1 = IntParameter(1, 7, default=1)
sell_m2 = IntParameter(1, 7, default=3)
sell_m3 = IntParameter(1, 7, default=4)
sell_p1 = IntParameter(7, 21, default=14)
sell_p2 = IntParameter(7, 21, default=10)
sell_p3 = IntParameter(7, 21, default=10)
# FreqAI required function, leave as is or add additional informatives to existing structure. # FreqAI required function, leave as is or add additional informatives to existing structure.
def informative_pairs(self): def informative_pairs(self):
@ -143,7 +139,6 @@ class FreqaiExampleHybridStrategy(IStrategy):
informative[f"%-{coin}adx-period_{t}"] = ta.ADX(informative, window=t) informative[f"%-{coin}adx-period_{t}"] = ta.ADX(informative, window=t)
informative[f"%-{coin}sma-period_{t}"] = ta.SMA(informative, timeperiod=t) informative[f"%-{coin}sma-period_{t}"] = ta.SMA(informative, timeperiod=t)
informative[f"%-{coin}ema-period_{t}"] = ta.EMA(informative, timeperiod=t) informative[f"%-{coin}ema-period_{t}"] = ta.EMA(informative, timeperiod=t)
informative[f"%-{coin}mfi-period_{t}"] = ta.MFI(informative, timeperiod=t)
informative[f"%-{coin}roc-period_{t}"] = ta.ROC(informative, timeperiod=t) informative[f"%-{coin}roc-period_{t}"] = ta.ROC(informative, timeperiod=t)
informative[f"%-{coin}relative_volume-period_{t}"] = ( informative[f"%-{coin}relative_volume-period_{t}"] = (
informative["volume"] / informative["volume"].rolling(t).mean() informative["volume"] / informative["volume"].rolling(t).mean()
@ -183,150 +178,85 @@ class FreqaiExampleHybridStrategy(IStrategy):
# User creates their own custom strat here. Present example is a supertrend # User creates their own custom strat here. Present example is a supertrend
# based strategy. # based strategy.
for multiplier in self.buy_m1.range:
for period in self.buy_p1.range:
dataframe[f"supertrend_1_buy_{multiplier}_{period}"] = self.supertrend(
dataframe, multiplier, period
)["STX"]
for multiplier in self.buy_m2.range:
for period in self.buy_p2.range:
dataframe[f"supertrend_2_buy_{multiplier}_{period}"] = self.supertrend(
dataframe, multiplier, period
)["STX"]
for multiplier in self.buy_m3.range:
for period in self.buy_p3.range:
dataframe[f"supertrend_3_buy_{multiplier}_{period}"] = self.supertrend(
dataframe, multiplier, period
)["STX"]
for multiplier in self.sell_m1.range:
for period in self.sell_p1.range:
dataframe[f"supertrend_1_sell_{multiplier}_{period}"] = self.supertrend(
dataframe, multiplier, period
)["STX"]
for multiplier in self.sell_m2.range:
for period in self.sell_p2.range:
dataframe[f"supertrend_2_sell_{multiplier}_{period}"] = self.supertrend(
dataframe, multiplier, period
)["STX"]
for multiplier in self.sell_m3.range:
for period in self.sell_p3.range:
dataframe[f"supertrend_3_sell_{multiplier}_{period}"] = self.supertrend(
dataframe, multiplier, period
)["STX"]
dataframe = self.freqai.start(dataframe, metadata, self) dataframe = self.freqai.start(dataframe, metadata, self)
# TA indicators to combine with the Freqai targets
# RSI
dataframe['rsi'] = ta.RSI(dataframe)
# Bollinger Bands
bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
dataframe['bb_lowerband'] = bollinger['lower']
dataframe['bb_middleband'] = bollinger['mid']
dataframe['bb_upperband'] = bollinger['upper']
dataframe["bb_percent"] = (
(dataframe["close"] - dataframe["bb_lowerband"]) /
(dataframe["bb_upperband"] - dataframe["bb_lowerband"])
)
dataframe["bb_width"] = (
(dataframe["bb_upperband"] - dataframe["bb_lowerband"]) / dataframe["bb_middleband"]
)
# TEMA - Triple Exponential Moving Average
dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9)
return dataframe return dataframe
def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame: def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
# User now can use their custom strat creation in addition to their df.loc[
# future prediction "up" or "down". (
# Signal: RSI crosses above 30
(qtpylib.crossed_above(df['rsi'], self.buy_rsi.value)) &
(df['tema'] <= df['bb_middleband']) & # Guard: tema below BB middle
(df['tema'] > df['tema'].shift(1)) & # Guard: tema is raising
(df['volume'] > 0) & # Make sure Volume is not 0
(df['do_predict'] == 1) & # Make sure Freqai is confident in the prediction
# Only enter trade if Freqai thinks the trend is in this direction
(df['&s-up_or_down'] == 'up')
),
'enter_long'] = 1
df.loc[ df.loc[
(df[f"supertrend_1_buy_{self.buy_m1.value}_{self.buy_p1.value}"] == "up") & (
(df[f"supertrend_2_buy_{self.buy_m2.value}_{self.buy_p2.value}"] == "up") & # Signal: RSI crosses above 70
(df[f"supertrend_3_buy_{self.buy_m3.value}_{self.buy_p3.value}"] == "up") & (qtpylib.crossed_above(df['rsi'], self.short_rsi.value)) &
(df["do_predict"] == 1) & (df['tema'] > df['bb_middleband']) & # Guard: tema above BB middle
(df['&s-up_or_down'] == 'up'), (df['tema'] < df['tema'].shift(1)) & # Guard: tema is falling
"enter_long", (df['volume'] > 0) & # Make sure Volume is not 0
] = 1 (df['do_predict'] == 1) & # Make sure Freqai is confident in the prediction
# Only enter trade if Freqai thinks the trend is in this direction
df.loc[ (df['&s-up_or_down'] == 'down')
(df[f"supertrend_1_sell_{self.sell_m1.value}_{self.sell_p1.value}"] == "down") & ),
(df[f"supertrend_2_sell_{self.sell_m2.value}_{self.sell_p2.value}"] == "down") & 'enter_short'] = 1
(df[f"supertrend_3_sell_{self.sell_m3.value}_{self.sell_p3.value}"] == "down") &
(df["do_predict"] == 1) &
(df['&s-up_or_down'] == 'down'),
"enter_short",
] = 1
return df return df
def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame: def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
df.loc[ df.loc[
(df[f"supertrend_2_sell_{self.sell_m2.value}_{self.sell_p2.value}"] == "down"), (
"exit_long", # Signal: RSI crosses above 70
] = 1 (qtpylib.crossed_above(df['rsi'], self.sell_rsi.value)) &
(df['tema'] > df['bb_middleband']) & # Guard: tema above BB middle
(df['tema'] < df['tema'].shift(1)) & # Guard: tema is falling
(df['volume'] > 0) # Make sure Volume is not 0
),
'exit_long'] = 1
df.loc[ df.loc[
(df[f"supertrend_2_buy_{self.buy_m2.value}_{self.buy_p2.value}"] == "up"), (
"exit_short", # Signal: RSI crosses above 30
] = 1 (qtpylib.crossed_above(df['rsi'], self.exit_short_rsi.value)) &
# Guard: tema below BB middle
(df['tema'] <= df['bb_middleband']) &
(df['tema'] > df['tema'].shift(1)) & # Guard: tema is raising
(df['volume'] > 0) # Make sure Volume is not 0
),
'exit_short'] = 1
return df return df
def get_ticker_indicator(self): def get_ticker_indicator(self):
return int(self.config["timeframe"][:-1]) return int(self.config["timeframe"][:-1])
def confirm_trade_entry(self, pair: str, order_type: str, amount: float,
rate: float, time_in_force: str, current_time, entry_tag, side: str,
**kwargs, ) -> bool:
df, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = df.iloc[-1].squeeze()
if side == "long":
if rate > (last_candle["close"] * (1 + 0.0025)):
return False
else:
if rate < (last_candle["close"] * (1 - 0.0025)):
return False
return True
"""
Supertrend Indicator; adapted for freqtrade, optimized by the math genius.
from: Perkmeister#2394
"""
def supertrend(self, dataframe: DataFrame, multiplier, period):
df = dataframe.copy()
last_row = dataframe.tail(1).index.item()
df['TR'] = ta.TRANGE(df)
df['ATR'] = ta.SMA(df['TR'], period)
st = 'ST_' + str(period) + '_' + str(multiplier)
stx = 'STX_' + str(period) + '_' + str(multiplier)
# Compute basic upper and lower bands
BASIC_UB = ((df['high'] + df['low']) / 2 + multiplier * df['ATR']).values
BASIC_LB = ((df['high'] + df['low']) / 2 - multiplier * df['ATR']).values
FINAL_UB = np.zeros(last_row + 1)
FINAL_LB = np.zeros(last_row + 1)
ST = np.zeros(last_row + 1)
CLOSE = df['close'].values
# Compute final upper and lower bands
for i in range(period, last_row + 1):
FINAL_UB[i] = (BASIC_UB[i] if BASIC_UB[i] < FINAL_UB[i - 1]
or CLOSE[i - 1] > FINAL_UB[i - 1] else FINAL_UB[i - 1])
FINAL_LB[i] = (BASIC_LB[i] if BASIC_LB[i] > FINAL_LB[i - 1]
or CLOSE[i - 1] < FINAL_LB[i - 1] else FINAL_LB[i - 1])
# Set the Supertrend value
for i in range(period, last_row + 1):
ST[i] = FINAL_UB[i] if ST[i - 1] == FINAL_UB[i - 1] and CLOSE[i] <= FINAL_UB[i] else \
FINAL_LB[i] if ST[i - 1] == FINAL_UB[i - 1] and CLOSE[i] > FINAL_UB[i] else \
FINAL_LB[i] if ST[i - 1] == FINAL_LB[i - 1] and CLOSE[i] >= FINAL_LB[i] else \
FINAL_UB[i] if ST[i - 1] == FINAL_LB[i - 1] and CLOSE[i] < FINAL_LB[i] else 0.00
df_ST = pd.DataFrame(ST, columns=[st])
df = pd.concat([df, df_ST], axis=1)
# Mark the trend direction up/down
df[stx] = np.where((df[st] > 0.00), np.where((df['close'] < df[st]), 'down', 'up'), np.NaN)
df.fillna(0, inplace=True)
return DataFrame(index=df.index, data={
'ST': df[st],
'STX': df[stx]
})