strategies

This commit is contained in:
root 2023-01-10 16:25:49 +07:00
parent 6d5cfba012
commit 4907a66fc1
9 changed files with 37052 additions and 0 deletions

566
strategies/BigZ06.py Executable file
View File

@ -0,0 +1,566 @@
import freqtrade.vendor.qtpylib.indicators as qtpylib
import numpy as np
import talib.abstract as ta
from freqtrade.persistence import Trade
from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame
from datetime import datetime, timedelta
from freqtrade.strategy import merge_informative_pair, CategoricalParameter, DecimalParameter, IntParameter
from functools import reduce
###########################################################################################################
## BigZ06 by ilya ##
## ##
## https://github.com/i1ya/freqtrade-strategies ##
## The stratagy most inspired by iterativ (authors of the CombinedBinHAndClucV6) ##
## ## ##
###########################################################################################################
## The main point of this strat is: ##
## - make drawdown as low as possible ##
## - buy at dip ##
## - sell quick as fast as you can (release money for the next buy) ##
## - soft check if market if rising ##
## - hard check is market if fallen ##
## - 14 buy signals ##
## - stoploss function preventing from big fall ##
## - no sell signal. Whether ROI or stoploss =) ##
## ##
###########################################################################################################
## GENERAL RECOMMENDATIONS ##
## ##
## For optimal performance, suggested to use between 3 and 5 open trades. ##
## ##
## As a pairlist you can use VolumePairlist. ##
## ##
## Ensure that you don't override any variables in your config.json. Especially ##
## the timeframe (must be 5m). ##
## ##
## sell_profit_only: ##
## True - risk more (gives you higher profit and higher Drawdown) ##
## False (default) - risk less (gives you less ~10-15% profit and much lower Drawdown) ##
## ##
## BigZ06 using market orders. ##
## Ensure you're familar with https://www.freqtrade.io/en/stable/configuration/#market-order-pricing ##
## ##
###########################################################################################################
## DONATIONS 2 @iterativ (author of the original strategy) ##
## ##
## Absolutely not required. However, will be accepted as a token of appreciation. ##
## ##
## BTC: bc1qvflsvddkmxh7eqhc4jyu5z5k6xcw3ay8jl49sk ##
## ETH: 0x83D3cFb8001BDC5d2211cBeBB8cB3461E5f7Ec91 ##
## ##
###########################################################################################################
class BigZ06(IStrategy):
INTERFACE_VERSION = 2
minimal_roi = {
"0": 0.028, # I feel lucky!
"10": 0.018,
"40": 0.005,
"180": 0.018, # We're going up?
}
stoploss = -0.99 # effectively disabled.
timeframe = '5m'
inf_1h = '1h'
# Sell signal
use_exit_signal = True
exit_profit_only = False
exit_profit_offset = 0.001 # it doesn't meant anything, just to guarantee there is a minimal profit.
ignore_roi_if_entry_signal = False
# Trailing stoploss
trailing_stop = False
trailing_only_offset_is_reached = False
trailing_stop_positive = 0.01
trailing_stop_positive_offset = 0.025
# Custom stoploss
use_custom_stoploss = True
# Run "populate_indicators()" only for new candle.
process_only_new_candles = True
# Number of candles the strategy requires before producing valid signals
startup_candle_count: int = 200
# Optional order type mapping.
order_types = {
'entry': 'market',
'exit': 'market',
'stoploss': 'market',
'stoploss_on_exchange': False
}
buy_params = {
#############
# Enable/Disable conditions
"buy_condition_0_enable": True,
"buy_condition_1_enable": True,
"buy_condition_2_enable": True,
"buy_condition_3_enable": True,
"buy_condition_4_enable": True,
"buy_condition_5_enable": True,
"buy_condition_6_enable": True,
"buy_condition_7_enable": True,
"buy_condition_8_enable": True,
"buy_condition_9_enable": True,
"buy_condition_10_enable": True,
"buy_condition_11_enable": True,
"buy_condition_12_enable": True,
"buy_condition_13_enable": True,
}
############################################################################
# Buy
buy_condition_0_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_1_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_2_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_3_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_4_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_5_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_6_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_7_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_8_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_9_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_10_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_11_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_12_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_13_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_bb20_close_bblowerband_safe_1 = DecimalParameter(0.7, 1.1, default=0.989, space='buy', optimize=False, load=True)
buy_bb20_close_bblowerband_safe_2 = DecimalParameter(0.7, 1.1, default=0.982, space='buy', optimize=False, load=True)
buy_volume_pump_1 = DecimalParameter(0.1, 0.9, default=0.4, space='buy', decimals=1, optimize=False, load=True)
buy_volume_drop_1 = DecimalParameter(1, 10, default=3.8, space='buy', decimals=1, optimize=False, load=True)
buy_volume_drop_2 = DecimalParameter(1, 10, default=3, space='buy', decimals=1, optimize=False, load=True)
buy_volume_drop_3 = DecimalParameter(1, 10, default=2.7, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1h_1 = DecimalParameter(10.0, 40.0, default=16.5, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1h_2 = DecimalParameter(10.0, 40.0, default=15.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1h_3 = DecimalParameter(10.0, 40.0, default=20.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1h_4 = DecimalParameter(10.0, 40.0, default=35.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1h_5 = DecimalParameter(10.0, 60.0, default=39.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1 = DecimalParameter(10.0, 40.0, default=28.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_2 = DecimalParameter(7.0, 40.0, default=10.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_3 = DecimalParameter(7.0, 40.0, default=14.2, space='buy', decimals=1, optimize=False, load=True)
buy_macd_1 = DecimalParameter(0.01, 0.09, default=0.02, space='buy', decimals=2, optimize=False, load=True)
buy_macd_2 = DecimalParameter(0.01, 0.09, default=0.03, space='buy', decimals=2, optimize=False, load=True)
def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float,
rate: float, time_in_force: str, sell_reason: str, **kwargs) -> bool:
return True
def custom_sell(self, pair: str, trade: 'Trade', current_time: 'datetime', current_rate: float,
current_profit: float, **kwargs):
return False
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
last_candle_2 = dataframe.iloc[-2].squeeze()
if (last_candle is not None):
if (last_candle['high'] > last_candle['bb_upperband']) & (last_candle['volume'] > (last_candle_2['volume'] * 1.5)):
return 'sell_signal_1'
return False
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
# Manage losing trades and open room for better ones.
if (current_profit > 0):
return 0.99
else:
trade_time_50 = trade.open_date_utc + timedelta(minutes=50)
# Trade open more then 60 minutes. For this strategy it's means -> loss
# Let's try to minimize the loss
if (current_time > trade_time_50):
try:
number_of_candle_shift = int((current_time - trade_time_50).total_seconds() / 300)
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
candle = dataframe.iloc[-number_of_candle_shift].squeeze()
# We are at bottom. Wait...
if candle['rsi_1h'] < 40:
return 0.99
# Are we still sinking?
if candle['close'] > candle['ema_200']:
if current_rate * 1.035 < candle['open']:
return 0.01
if current_rate * 1.025 < candle['open']:
return 0.01
except IndexError as error:
# Whoops, set stoploss at 10%
return 0.1
return 0.99
def informative_pairs(self):
pairs = self.dp.current_whitelist()
informative_pairs = [(pair, '1h') for pair in pairs]
return informative_pairs
def informative_1h_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
assert self.dp, "DataProvider is required for multiple timeframes."
# Get the informative pair
informative_1h = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.inf_1h)
# EMA
informative_1h['ema_50'] = ta.EMA(informative_1h, timeperiod=50)
informative_1h['ema_200'] = ta.EMA(informative_1h, timeperiod=200)
# RSI
informative_1h['rsi'] = ta.RSI(informative_1h, timeperiod=14)
bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
informative_1h['bb_lowerband'] = bollinger['lower']
informative_1h['bb_middleband'] = bollinger['mid']
informative_1h['bb_upperband'] = bollinger['upper']
return informative_1h
def normal_tf_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
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['volume_mean_slow'] = dataframe['volume'].rolling(window=48).mean()
# EMA
dataframe['ema_200'] = ta.EMA(dataframe, timeperiod=200)
dataframe['ema_26'] = ta.EMA(dataframe, timeperiod=26)
dataframe['ema_12'] = ta.EMA(dataframe, timeperiod=12)
# MACD
dataframe['macd'], dataframe['signal'], dataframe['hist'] = ta.MACD(dataframe['close'], fastperiod=12, slowperiod=26, signalperiod=9)
# SMA
dataframe['sma_5'] = ta.EMA(dataframe, timeperiod=5)
# RSI
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
# Chaikin A/D Oscillator
dataframe['mfv'] = MFV(dataframe)
dataframe['cmf'] = dataframe['mfv'].rolling(20).sum()/dataframe['volume'].rolling(20).sum()
return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# The indicators for the 1h informative timeframe
informative_1h = self.informative_1h_indicators(dataframe, metadata)
dataframe = merge_informative_pair(dataframe, informative_1h, self.timeframe, self.inf_1h, ffill=True)
# The indicators for the normal (5m) timeframe
dataframe = self.normal_tf_indicators(dataframe, metadata)
return dataframe
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = []
conditions.append(
(
self.buy_condition_13_enable.value &
(dataframe['close'] > dataframe['ema_200_1h']) &
(dataframe['cmf'] < -0.435) &
(dataframe['rsi'] < 22) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_12_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['close'] > dataframe['ema_200_1h']) &
(dataframe['close'] < dataframe['bb_lowerband'] * 0.993) &
(dataframe['low'] < dataframe['bb_lowerband'] * 0.985) &
(dataframe['close'].shift() > dataframe['bb_lowerband']) &
(dataframe['rsi_1h'] < 72.8) &
(dataframe['open'] > dataframe['close']) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
((dataframe['open'] - dataframe['close']) < dataframe['bb_upperband'].shift(2) - dataframe['bb_lowerband'].shift(2)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_11_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['hist'] > 0) &
(dataframe['hist'].shift() > 0) &
(dataframe['hist'].shift(2) > 0) &
(dataframe['hist'].shift(3) > 0) &
(dataframe['hist'].shift(5) > 0) &
(dataframe['bb_middleband'] - dataframe['bb_middleband'].shift(5) > dataframe['close']/200) &
(dataframe['bb_middleband'] - dataframe['bb_middleband'].shift(10) > dataframe['close']/100) &
((dataframe['bb_upperband'] - dataframe['bb_lowerband']) < (dataframe['close']*0.1)) &
((dataframe['open'].shift() - dataframe['close'].shift()) < (dataframe['close'] * 0.018)) &
(dataframe['rsi'] > 51) &
(dataframe['open'] < dataframe['close']) &
(dataframe['open'].shift() > dataframe['close'].shift()) &
(dataframe['close'] > dataframe['bb_middleband']) &
(dataframe['close'].shift() < dataframe['bb_middleband'].shift()) &
(dataframe['low'].shift(2) > dataframe['bb_middleband'].shift(2)) &
(dataframe['volume'] > 0) # Make sure Volume is not 0
)
)
conditions.append(
(
self.buy_condition_0_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['rsi'] < 30) &
(dataframe['close'] * 1.024 < dataframe['open'].shift(3)) &
(dataframe['rsi_1h'] < 71) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] > 0) # Make sure Volume is not 0
)
)
conditions.append(
(
self.buy_condition_1_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['close'] > dataframe['ema_200_1h']) &
(dataframe['close'] < dataframe['bb_lowerband'] * self.buy_bb20_close_bblowerband_safe_1.value) &
(dataframe['rsi_1h'] < 69) &
(dataframe['open'] > dataframe['close']) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
((dataframe['open'] - dataframe['close']) < dataframe['bb_upperband'].shift(2) - dataframe['bb_lowerband'].shift(2)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_2_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['close'] < dataframe['bb_lowerband'] * self.buy_bb20_close_bblowerband_safe_2.value) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['open'] - dataframe['close'] < dataframe['bb_upperband'].shift(2) - dataframe['bb_lowerband'].shift(2)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_3_enable.value &
(dataframe['close'] > dataframe['ema_200_1h']) &
(dataframe['close'] < dataframe['bb_lowerband']) &
(dataframe['rsi'] < self.buy_rsi_3.value) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_3.value)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_4_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_1.value) &
(dataframe['close'] < dataframe['bb_lowerband']) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_5_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['close'] > dataframe['ema_200_1h']) &
(dataframe['ema_26'] > dataframe['ema_12']) &
((dataframe['ema_26'] - dataframe['ema_12']) > (dataframe['open'] * self.buy_macd_1.value)) &
((dataframe['ema_26'].shift() - dataframe['ema_12'].shift()) > (dataframe['open']/100)) &
(dataframe['close'] < (dataframe['bb_lowerband'])) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] > 0) # Make sure Volume is not 0
)
)
conditions.append(
(
self.buy_condition_6_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_5.value) &
(dataframe['ema_26'] > dataframe['ema_12']) &
((dataframe['ema_26'] - dataframe['ema_12']) > (dataframe['open'] * self.buy_macd_2.value)) &
((dataframe['ema_26'].shift() - dataframe['ema_12'].shift()) > (dataframe['open']/100)) &
(dataframe['close'] < (dataframe['bb_lowerband'])) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_7_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_2.value) &
(dataframe['ema_26'] > dataframe['ema_12']) &
((dataframe['ema_26'] - dataframe['ema_12']) > (dataframe['open'] * self.buy_macd_1.value)) &
((dataframe['ema_26'].shift() - dataframe['ema_12'].shift()) > (dataframe['open']/100)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_8_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_3.value) &
(dataframe['rsi'] < self.buy_rsi_1.value) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_9_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_4.value) &
(dataframe['rsi'] < self.buy_rsi_2.value) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_10_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_4.value) &
(dataframe['close_1h'] < dataframe['bb_lowerband_1h']) &
(dataframe['hist'] > 0) &
(dataframe['hist'].shift(2) < 0) &
(dataframe['rsi'] < 40.5) &
(dataframe['hist'] > dataframe['close'] * 0.0012) &
(dataframe['open'] < dataframe['close']) &
(dataframe['volume'] > 0)
)
)
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:
dataframe.loc[
(
(dataframe['close'] > dataframe['bb_middleband'] * 1.01) & # Don't be gready, sell fast
(dataframe['volume'] > 0) # Make sure Volume is not 0
)
,
'sell'
] = 0
return dataframe
# Chaikin Money Flow Volume
def MFV(dataframe):
df = dataframe.copy()
N = ((df['close'] - df['low']) - (df['high'] - df['close'])) / (df['high'] - df['low'])
M = N * df['volume']
return M

596
strategies/BigZ07.py Executable file
View File

@ -0,0 +1,596 @@
import freqtrade.vendor.qtpylib.indicators as qtpylib
import numpy as np
import talib.abstract as ta
from freqtrade.persistence import Trade
from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame
from datetime import datetime, timedelta
from freqtrade.strategy import merge_informative_pair, CategoricalParameter, DecimalParameter, IntParameter
from functools import reduce
###########################################################################################################
## BigZ07 by ilya ##
## ##
## https://github.com/i1ya/freqtrade-strategies ##
## The stratagy most inspired by iterativ (authors of the CombinedBinHAndClucV6) ##
## ## ##
###########################################################################################################
## The main point of this strat is: ##
## - make drawdown as low as possible ##
## - buy at dip ##
## - sell quick as fast as you can (release money for the next buy) ##
## - soft check if market if rising ##
## - hard check is market if fallen ##
## - 14 buy signals ##
## - stoploss function preventing from big fall ##
## - no sell signal. Whether ROI or stoploss =) ##
## ##
###########################################################################################################
## GENERAL RECOMMENDATIONS ##
## ##
## For optimal performance, suggested to use between 3 and 5 open trades. ##
## ##
## As a pairlist you can use VolumePairlist. ##
## ##
## Ensure that you don't override any variables in your config.json. Especially ##
## the timeframe (must be 5m). ##
## ##
## sell_profit_only: ##
## True - risk more (gives you higher profit and higher Drawdown) ##
## False (default) - risk less (gives you less ~10-15% profit and much lower Drawdown) ##
## ##
## BigZ06 using market orders. ##
## Ensure you're familar with https://www.freqtrade.io/en/stable/configuration/#market-order-pricing ##
## ##
###########################################################################################################
## DONATIONS 2 @iterativ (author of the original strategy) ##
## ##
## Absolutely not required. However, will be accepted as a token of appreciation. ##
## ##
## BTC: bc1qvflsvddkmxh7eqhc4jyu5z5k6xcw3ay8jl49sk ##
## ETH: 0x83D3cFb8001BDC5d2211cBeBB8cB3461E5f7Ec91 ##
## ##
###########################################################################################################
class BigZ07(IStrategy):
INTERFACE_VERSION = 2
minimal_roi = {
"0": 0.028, # I feel lucky!
"10": 0.018,
"40": 0.005,
"180": 0.018, # We're going up?
}
stoploss = -0.99 # effectively disabled.
timeframe = '5m'
inf_1h = '1h'
# Sell signal
use_sell_signal = True
sell_profit_only = False
sell_profit_offset = 0.001 # it doesn't meant anything, just to guarantee there is a minimal profit.
ignore_roi_if_buy_signal = False
# Trailing stoploss
trailing_stop = False
trailing_only_offset_is_reached = False
trailing_stop_positive = 0.01
trailing_stop_positive_offset = 0.025
# Custom stoploss
use_custom_stoploss = True
# Run "populate_indicators()" only for new candle.
process_only_new_candles = True
# Number of candles the strategy requires before producing valid signals
startup_candle_count: int = 200
# Optional order type mapping.
order_types = {
'buy': 'market',
'sell': 'market',
'stoploss': 'market',
'stoploss_on_exchange': False
}
buy_params = {
#############
# Enable/Disable conditions
"buy_condition_0_enable": True,
"buy_condition_1_enable": True,
"buy_condition_2_enable": True,
"buy_condition_3_enable": True,
"buy_condition_4_enable": True,
"buy_condition_5_enable": True,
"buy_condition_6_enable": True,
"buy_condition_7_enable": True,
"buy_condition_8_enable": True,
"buy_condition_9_enable": True,
"buy_condition_10_enable": True,
"buy_condition_11_enable": True,
"buy_condition_12_enable": True,
"buy_condition_13_enable": True,
}
############################################################################
# Buy
buy_condition_0_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_1_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_2_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_3_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_4_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_5_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_6_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_7_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_8_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_9_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_10_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_11_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_12_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_13_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_bb20_close_bblowerband_safe_1 = DecimalParameter(0.7, 1.1, default=0.989, space='buy', optimize=False,
load=True)
buy_bb20_close_bblowerband_safe_2 = DecimalParameter(0.7, 1.1, default=0.982, space='buy', optimize=False,
load=True)
buy_volume_pump_1 = DecimalParameter(0.1, 0.9, default=0.4, space='buy', decimals=1, optimize=False, load=True)
buy_volume_drop_1 = DecimalParameter(1, 10, default=3.8, space='buy', decimals=1, optimize=False, load=True)
buy_volume_drop_2 = DecimalParameter(1, 10, default=3, space='buy', decimals=1, optimize=False, load=True)
buy_volume_drop_3 = DecimalParameter(1, 10, default=2.7, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1h_1 = DecimalParameter(10.0, 40.0, default=16.5, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1h_2 = DecimalParameter(10.0, 40.0, default=15.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1h_3 = DecimalParameter(10.0, 40.0, default=20.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1h_4 = DecimalParameter(10.0, 40.0, default=35.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1h_5 = DecimalParameter(10.0, 60.0, default=39.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1 = DecimalParameter(10.0, 40.0, default=28.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_2 = DecimalParameter(7.0, 40.0, default=10.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_3 = DecimalParameter(7.0, 40.0, default=14.2, space='buy', decimals=1, optimize=False, load=True)
buy_macd_1 = DecimalParameter(0.01, 0.09, default=0.02, space='buy', decimals=2, optimize=False, load=True)
buy_macd_2 = DecimalParameter(0.01, 0.09, default=0.03, space='buy', decimals=2, optimize=False, load=True)
def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float,
rate: float, time_in_force: str, sell_reason: str, **kwargs) -> bool:
return True
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
last_candle_1 = dataframe.iloc[-2].squeeze()
if (sell_reason == 'roi'):
# Looks like we can get a little have more
if (last_candle['cmf'] < -0.1) & (last_candle['close'] > last_candle['ema_200_1h']):
return False
return True
def custom_sell(self, pair: str, trade: 'Trade', current_time: 'datetime', current_rate: float,
current_profit: float, **kwargs):
return False
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
last_candle_2 = dataframe.iloc[-2].squeeze()
if (last_candle is not None):
if (last_candle['high'] > last_candle['bb_upperband']) & (
last_candle['volume'] > (last_candle_2['volume'] * 1.5)):
return 'sell_signal_1'
return False
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
# Manage losing trades and open room for better ones.
if (current_profit > 0):
return 0.99
else:
trade_time_50 = trade.open_date_utc + timedelta(minutes=50)
# Trade open more then 60 minutes. For this strategy it's means -> loss
# Let's try to minimize the loss
if (current_time > trade_time_50):
try:
number_of_candle_shift = int((current_time - trade_time_50).total_seconds() / 300)
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
candle = dataframe.iloc[-number_of_candle_shift].squeeze()
# We are at bottom. Wait...
if candle['rsi_1h'] < 40:
return 0.99
if candle['open_1h'] > candle['ema_200_1h']:
return 0.1
# Are we still sinking?
if current_rate * 1.025 < candle['open']:
return 0.01
except IndexError as error:
# Whoops, set stoploss at 10%
return 0.1
return 0.99
def informative_pairs(self):
pairs = self.dp.current_whitelist()
informative_pairs = [(pair, '1h') for pair in pairs]
return informative_pairs
def informative_1h_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
assert self.dp, "DataProvider is required for multiple timeframes."
# Get the informative pair
informative_1h = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.inf_1h)
# EMA
informative_1h['ema_50'] = ta.EMA(informative_1h, timeperiod=50)
informative_1h['ema_200'] = ta.EMA(informative_1h, timeperiod=200)
# RSI
informative_1h['rsi'] = ta.RSI(informative_1h, timeperiod=14)
bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
informative_1h['bb_lowerband'] = bollinger['lower']
informative_1h['bb_middleband'] = bollinger['mid']
informative_1h['bb_upperband'] = bollinger['upper']
return informative_1h
def normal_tf_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
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['volume_mean_slow'] = dataframe['volume'].rolling(window=48).mean()
# EMA
dataframe['ema_200'] = ta.EMA(dataframe, timeperiod=200)
dataframe['ema_26'] = ta.EMA(dataframe, timeperiod=26)
dataframe['ema_12'] = ta.EMA(dataframe, timeperiod=12)
# MACD
dataframe['macd'], dataframe['signal'], dataframe['hist'] = ta.MACD(dataframe['close'], fastperiod=12,
slowperiod=26, signalperiod=9)
# RSI
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
# Chaikin A/D Oscillator
dataframe['mfv'] = MFV(dataframe)
dataframe['cmf'] = dataframe['mfv'].rolling(20).sum() / dataframe['volume'].rolling(20).sum()
return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# The indicators for the 1h informative timeframe
informative_1h = self.informative_1h_indicators(dataframe, metadata)
dataframe = merge_informative_pair(dataframe, informative_1h, self.timeframe, self.inf_1h, ffill=True)
# The indicators for the normal (5m) timeframe
dataframe = self.normal_tf_indicators(dataframe, metadata)
return dataframe
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = []
conditions.append(
(
self.buy_condition_13_enable.value &
(dataframe['close'] > dataframe['ema_200_1h']) &
(dataframe['cmf'] < -0.435) &
(dataframe['rsi'] < 22) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(
48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(
48)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_12_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['close'] > dataframe['ema_200_1h']) &
(dataframe['close'] < dataframe['bb_lowerband'] * 0.993) &
(dataframe['low'] < dataframe['bb_lowerband'] * 0.985) &
(dataframe['close'].shift() > dataframe['bb_lowerband']) &
(dataframe['rsi_1h'] < 72.8) &
(dataframe['open'] > dataframe['close']) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(
48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(
48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
((dataframe['open'] - dataframe['close']) < dataframe['bb_upperband'].shift(2) - dataframe[
'bb_lowerband'].shift(2)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_11_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['hist'] > 0) &
(dataframe['hist'].shift() > 0) &
(dataframe['hist'].shift(2) > 0) &
(dataframe['hist'].shift(3) > 0) &
(dataframe['hist'].shift(5) > 0) &
(dataframe['bb_middleband'] - dataframe['bb_middleband'].shift(5) > dataframe['close'] / 200) &
(dataframe['bb_middleband'] - dataframe['bb_middleband'].shift(10) > dataframe['close'] / 100) &
((dataframe['bb_upperband'] - dataframe['bb_lowerband']) < (dataframe['close'] * 0.1)) &
((dataframe['open'].shift() - dataframe['close'].shift()) < (dataframe['close'] * 0.018)) &
(dataframe['rsi'] > 51) &
(dataframe['open'] < dataframe['close']) &
(dataframe['open'].shift() > dataframe['close'].shift()) &
(dataframe['close'] > dataframe['bb_middleband']) &
(dataframe['close'].shift() < dataframe['bb_middleband'].shift()) &
(dataframe['low'].shift(2) > dataframe['bb_middleband'].shift(2)) &
(dataframe['volume'] > 0) # Make sure Volume is not 0
)
)
conditions.append(
(
self.buy_condition_0_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['rsi'] < 30) &
(dataframe['close'] * 1.024 < dataframe['open'].shift(3)) &
(dataframe['rsi_1h'] < 71) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(
48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(
48)) &
(dataframe['volume'] > 0) # Make sure Volume is not 0
)
)
conditions.append(
(
self.buy_condition_1_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['close'] > dataframe['ema_200_1h']) &
(dataframe['close'] < dataframe['bb_lowerband'] * self.buy_bb20_close_bblowerband_safe_1.value) &
(dataframe['rsi_1h'] < 69) &
(dataframe['open'] > dataframe['close']) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(
48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(
48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
((dataframe['open'] - dataframe['close']) < dataframe['bb_upperband'].shift(2) - dataframe[
'bb_lowerband'].shift(2)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_2_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['close'] < dataframe['bb_lowerband'] * self.buy_bb20_close_bblowerband_safe_2.value) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(
48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(
48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['open'] - dataframe['close'] < dataframe['bb_upperband'].shift(2) - dataframe[
'bb_lowerband'].shift(2)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_3_enable.value &
(dataframe['close'] > dataframe['ema_200_1h']) &
(dataframe['close'] < dataframe['bb_lowerband']) &
(dataframe['rsi'] < self.buy_rsi_3.value) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(
48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(
48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_3.value)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_4_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_1.value) &
(dataframe['close'] < dataframe['bb_lowerband']) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(
48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(
48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_5_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['close'] > dataframe['ema_200_1h']) &
(dataframe['ema_26'] > dataframe['ema_12']) &
((dataframe['ema_26'] - dataframe['ema_12']) > (dataframe['open'] * self.buy_macd_1.value)) &
((dataframe['ema_26'].shift() - dataframe['ema_12'].shift()) > (dataframe['open'] / 100)) &
(dataframe['close'] < (dataframe['bb_lowerband'])) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(
48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(
48)) &
(dataframe['volume'] > 0) # Make sure Volume is not 0
)
)
conditions.append(
(
self.buy_condition_6_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_5.value) &
(dataframe['ema_26'] > dataframe['ema_12']) &
((dataframe['ema_26'] - dataframe['ema_12']) > (dataframe['open'] * self.buy_macd_2.value)) &
((dataframe['ema_26'].shift() - dataframe['ema_12'].shift()) > (dataframe['open'] / 100)) &
(dataframe['close'] < (dataframe['bb_lowerband'])) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(
48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(
48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_7_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_2.value) &
(dataframe['ema_26'] > dataframe['ema_12']) &
((dataframe['ema_26'] - dataframe['ema_12']) > (dataframe['open'] * self.buy_macd_1.value)) &
((dataframe['ema_26'].shift() - dataframe['ema_12'].shift()) > (dataframe['open'] / 100)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(
48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(
48)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_8_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_3.value) &
(dataframe['rsi'] < self.buy_rsi_1.value) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_9_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_4.value) &
(dataframe['rsi'] < self.buy_rsi_2.value) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(
48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(
48)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_10_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_4.value) &
(dataframe['close_1h'] < dataframe['bb_lowerband_1h']) &
(dataframe['hist'] > 0) &
(dataframe['hist'].shift(2) < 0) &
(dataframe['rsi'] < 40.5) &
(dataframe['hist'] > dataframe['close'] * 0.0012) &
(dataframe['open'] < dataframe['close']) &
(dataframe['volume'] > 0)
)
)
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:
dataframe.loc[
(
(dataframe['close'] > dataframe['bb_middleband'] * 1.01) & # Don't be gready, sell fast
(dataframe['volume'] > 0) # Make sure Volume is not 0
)
,
'sell'
] = 0
return dataframe
# Chaikin Money Flow Volume
def MFV(dataframe):
df = dataframe.copy()
N = ((df['close'] - df['low']) - (df['high'] - df['close'])) / (df['high'] - df['low'])
M = N * df['volume']
return M

2617
strategies/E0V1E.py Executable file

File diff suppressed because one or more lines are too long

23206
strategies/NostalgiaForInfinityX.py Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

595
strategies/ROuGGy.py Executable file
View File

@ -0,0 +1,595 @@
import freqtrade.vendor.qtpylib.indicators as qtpylib
import numpy as np
import talib.abstract as ta
from freqtrade.persistence import Trade
from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame
from datetime import datetime, timedelta
from freqtrade.strategy import merge_informative_pair, CategoricalParameter, DecimalParameter, IntParameter
from functools import reduce
###########################################################################################################
## BigZ06 by ilya ##
## ##
## https://github.com/i1ya/freqtrade-strategies ##
## The stratagy most inspired by iterativ (authors of the CombinedBinHAndClucV6) ##
## ## ##
###########################################################################################################
## The main point of this strat is: ##
## - make drawdown as low as possible ##
## - buy at dip ##
## - sell quick as fast as you can (release money for the next buy) ##
## - soft check if market if rising ##
## - hard check is market if fallen ##
## - 14 buy signals ##
## - stoploss function preventing from big fall ##
## - no sell signal. Whether ROI or stoploss =) ##
## ##
###########################################################################################################
## GENERAL RECOMMENDATIONS ##
## ##
## For optimal performance, suggested to use between 3 and 5 open trades. ##
## ##
## As a pairlist you can use VolumePairlist. ##
## ##
## Ensure that you don't override any variables in your config.json. Especially ##
## the timeframe (must be 5m). ##
## ##
## sell_profit_only: ##
## True - risk more (gives you higher profit and higher Drawdown) ##
## False (default) - risk less (gives you less ~10-15% profit and much lower Drawdown) ##
## ##
## BigZ06 using market orders. ##
## Ensure you're familar with https://www.freqtrade.io/en/stable/configuration/#market-order-pricing ##
## ##
###########################################################################################################
## DONATIONS 2 @iterativ (author of the original strategy) ##
## ##
## Absolutely not required. However, will be accepted as a token of appreciation. ##
## ##
## BTC: bc1qvflsvddkmxh7eqhc4jyu5z5k6xcw3ay8jl49sk ##
## ETH: 0x83D3cFb8001BDC5d2211cBeBB8cB3461E5f7Ec91 ##
## ##
###########################################################################################################
class ROuGGy(IStrategy):
INTERFACE_VERSION = 2
minimal_roi = {
"0": 0.028, # I feel lucky!
"10": 0.018,
"40": 0.005,
"180": 0.018, # We're going up?
}
stoploss = -0.99 # effectively disabled.
timeframe = '5m'
inf_1h = '1h'
# Sell signal
use_exit_signal = True
exit_profit_only = False
exit_profit_offset = 0.001 # it doesn't meant anything, just to guarantee there is a minimal profit.
ignore_roi_if_entry_signal = False
# Trailing stoploss
trailing_stop = False
trailing_only_offset_is_reached = False
trailing_stop_positive = 0.01
trailing_stop_positive_offset = 0.025
# Custom stoploss
use_custom_stoploss = True
# Run "populate_indicators()" only for new candle.
process_only_new_candles = True
# Number of candles the strategy requires before producing valid signals
startup_candle_count: int = 200
# Optional order type mapping.
order_types = {
'entry': 'market',
'exit': 'market',
'stoploss': 'market',
'stoploss_on_exchange': False
}
buy_params = {
#############
# Enable/Disable conditions
"buy_condition_0_enable": True,
"buy_condition_1_enable": True,
"buy_condition_2_enable": True,
"buy_condition_3_enable": True,
"buy_condition_4_enable": True,
"buy_condition_5_enable": True,
"buy_condition_6_enable": True,
"buy_condition_7_enable": True,
"buy_condition_8_enable": True,
"buy_condition_9_enable": True,
"buy_condition_10_enable": True,
"buy_condition_11_enable": True,
"buy_condition_12_enable": True,
"buy_condition_13_enable": True,
"buy_condition_14_enable": True,
}
############################################################################
# Buy
buy_condition_0_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_1_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_2_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_3_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_4_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_5_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_6_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_7_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_8_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_9_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_10_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_11_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_12_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_13_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_condition_14_enable = CategoricalParameter([True, False], default=True, space='buy', optimize=False, load=True)
buy_bb20_close_bblowerband_safe_1 = DecimalParameter(0.7, 1.1, default=0.989, space='buy', optimize=False, load=True)
buy_bb20_close_bblowerband_safe_2 = DecimalParameter(0.7, 1.1, default=0.982, space='buy', optimize=False, load=True)
buy_volume_pump_1 = DecimalParameter(0.1, 0.9, default=0.4, space='buy', decimals=1, optimize=False, load=True)
buy_volume_drop_1 = DecimalParameter(1, 10, default=3.8, space='buy', decimals=1, optimize=False, load=True)
buy_volume_drop_2 = DecimalParameter(1, 10, default=3, space='buy', decimals=1, optimize=False, load=True)
buy_volume_drop_3 = DecimalParameter(1, 10, default=2.7, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1h_1 = DecimalParameter(10.0, 40.0, default=16.5, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1h_2 = DecimalParameter(10.0, 40.0, default=15.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1h_3 = DecimalParameter(10.0, 40.0, default=20.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1h_4 = DecimalParameter(10.0, 40.0, default=35.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1h_5 = DecimalParameter(10.0, 60.0, default=39.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_1 = DecimalParameter(10.0, 40.0, default=28.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_2 = DecimalParameter(7.0, 40.0, default=10.0, space='buy', decimals=1, optimize=False, load=True)
buy_rsi_3 = DecimalParameter(7.0, 40.0, default=14.2, space='buy', decimals=1, optimize=False, load=True)
buy_macd_1 = DecimalParameter(0.01, 0.09, default=0.02, space='buy', decimals=2, optimize=False, load=True)
buy_macd_2 = DecimalParameter(0.01, 0.09, default=0.03, space='buy', decimals=2, optimize=False, load=True)
def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float,
rate: float, time_in_force: str, sell_reason: str, **kwargs) -> bool:
return True
def custom_sell(self, pair: str, trade: 'Trade', current_time: 'datetime', current_rate: float,
current_profit: float, **kwargs):
return False
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
last_candle_2 = dataframe.iloc[-2].squeeze()
if (last_candle is not None):
if (last_candle['high'] > last_candle['bb_upperband']) & (last_candle['volume'] > (last_candle_2['volume'] * 1.5)):
return 'sell_signal_1'
return False
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
# Manage losing trades and open room for better ones.
if (current_profit > 0):
return 0.99
else:
trade_time_50 = trade.open_date_utc + timedelta(minutes=50)
# Trade open more then 60 minutes. For this strategy it's means -> loss
# Let's try to minimize the loss
if (current_time > trade_time_50):
try:
number_of_candle_shift = int((current_time - trade_time_50).total_seconds() / 300)
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
candle = dataframe.iloc[-number_of_candle_shift].squeeze()
# We are at bottom. Wait...
if candle['rsi_1h'] < 40:
return 0.99
# Are we still sinking?
if candle['close'] > candle['ema_200']:
if current_rate * 1.035 < candle['open']:
return 0.01
if current_rate * 1.025 < candle['open']:
return 0.01
except IndexError as error:
# Whoops, set stoploss at 10%
return 0.1
return 0.99
def informative_pairs(self):
pairs = self.dp.current_whitelist()
informative_pairs = [(pair, '1h') for pair in pairs]
return informative_pairs
def informative_1h_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
assert self.dp, "DataProvider is required for multiple timeframes."
# Get the informative pair
informative_1h = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.inf_1h)
# EMA
informative_1h['ema_50'] = ta.EMA(informative_1h, timeperiod=50)
informative_1h['ema_200'] = ta.EMA(informative_1h, timeperiod=200)
# RSI
informative_1h['rsi'] = ta.RSI(informative_1h, timeperiod=14)
bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
informative_1h['bb_lowerband'] = bollinger['lower']
informative_1h['bb_middleband'] = bollinger['mid']
informative_1h['bb_upperband'] = bollinger['upper']
return informative_1h
def normal_tf_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
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['volume_mean_slow'] = dataframe['volume'].rolling(window=48).mean()
# EMA
dataframe['ema_200'] = ta.EMA(dataframe, timeperiod=200)
dataframe['ema_26'] = ta.EMA(dataframe, timeperiod=26)
dataframe['ema_12'] = ta.EMA(dataframe, timeperiod=12)
# For sell checks
dataframe['crossed_below_ema_12_26'] = qtpylib.crossed_below(dataframe['ema_12'], dataframe['ema_26'])
# For buy checks
dataframe['crossed_above_ema_12_26'] = qtpylib.crossed_above(dataframe['ema_12'], dataframe['ema_26'])
# MACD
dataframe['macd'], dataframe['signal'], dataframe['hist'] = ta.MACD(dataframe['close'], fastperiod=12, slowperiod=26, signalperiod=9)
# SMA
dataframe['sma_5'] = ta.EMA(dataframe, timeperiod=5)
# RSI
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
# Chaikin A/D Oscillator
dataframe['mfv'] = MFV(dataframe)
dataframe['cmf'] = dataframe['mfv'].rolling(20).sum()/dataframe['volume'].rolling(20).sum()
return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# The indicators for the 1h informative timeframe
informative_1h = self.informative_1h_indicators(dataframe, metadata)
dataframe = merge_informative_pair(dataframe, informative_1h, self.timeframe, self.inf_1h, ffill=True)
# The indicators for the normal (5m) timeframe
dataframe = self.normal_tf_indicators(dataframe, metadata)
print(dataframe)
return dataframe
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = []
conditions.append(
(
self.buy_condition_14_enable.value &
(dataframe['cmf'] > 0) &
(dataframe['crossed_above_ema_12_26']) &
(dataframe['rsi'] < 45) &
# (dataframe['open'] < dataframe['bb_lowerband']) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_13_enable.value &
(dataframe['close'] > dataframe['ema_200_1h']) &
(dataframe['cmf'] < -0.435) &
(dataframe['rsi'] < 22) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_12_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['close'] > dataframe['ema_200_1h']) &
(dataframe['close'] < dataframe['bb_lowerband'] * 0.993) &
(dataframe['low'] < dataframe['bb_lowerband'] * 0.985) &
(dataframe['close'].shift() > dataframe['bb_lowerband']) &
(dataframe['rsi_1h'] < 72.8) &
(dataframe['open'] > dataframe['close']) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
((dataframe['open'] - dataframe['close']) < dataframe['bb_upperband'].shift(2) - dataframe['bb_lowerband'].shift(2)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_11_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['hist'] > 0) &
(dataframe['hist'].shift() > 0) &
(dataframe['hist'].shift(2) > 0) &
(dataframe['hist'].shift(3) > 0) &
(dataframe['hist'].shift(5) > 0) &
(dataframe['bb_middleband'] - dataframe['bb_middleband'].shift(5) > dataframe['close']/200) &
(dataframe['bb_middleband'] - dataframe['bb_middleband'].shift(10) > dataframe['close']/100) &
((dataframe['bb_upperband'] - dataframe['bb_lowerband']) < (dataframe['close']*0.1)) &
((dataframe['open'].shift() - dataframe['close'].shift()) < (dataframe['close'] * 0.018)) &
(dataframe['rsi'] > 51) &
(dataframe['open'] < dataframe['close']) &
(dataframe['open'].shift() > dataframe['close'].shift()) &
(dataframe['close'] > dataframe['bb_middleband']) &
(dataframe['close'].shift() < dataframe['bb_middleband'].shift()) &
(dataframe['low'].shift(2) > dataframe['bb_middleband'].shift(2)) &
(dataframe['volume'] > 0) # Make sure Volume is not 0
)
)
conditions.append(
(
self.buy_condition_0_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['rsi'] < 30) &
(dataframe['close'] * 1.024 < dataframe['open'].shift(3)) &
(dataframe['rsi_1h'] < 71) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] > 0) # Make sure Volume is not 0
)
)
conditions.append(
(
self.buy_condition_1_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['close'] > dataframe['ema_200_1h']) &
(dataframe['close'] < dataframe['bb_lowerband'] * self.buy_bb20_close_bblowerband_safe_1.value) &
(dataframe['rsi_1h'] < 69) &
(dataframe['open'] > dataframe['close']) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
((dataframe['open'] - dataframe['close']) < dataframe['bb_upperband'].shift(2) - dataframe['bb_lowerband'].shift(2)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_2_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['close'] < dataframe['bb_lowerband'] * self.buy_bb20_close_bblowerband_safe_2.value) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['open'] - dataframe['close'] < dataframe['bb_upperband'].shift(2) - dataframe['bb_lowerband'].shift(2)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_3_enable.value &
(dataframe['close'] > dataframe['ema_200_1h']) &
(dataframe['close'] < dataframe['bb_lowerband']) &
(dataframe['rsi'] < self.buy_rsi_3.value) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_3.value)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_4_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_1.value) &
(dataframe['close'] < dataframe['bb_lowerband']) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_5_enable.value &
(dataframe['close'] > dataframe['ema_200']) &
(dataframe['close'] > dataframe['ema_200_1h']) &
(dataframe['ema_26'] > dataframe['ema_12']) &
((dataframe['ema_26'] - dataframe['ema_12']) > (dataframe['open'] * self.buy_macd_1.value)) &
((dataframe['ema_26'].shift() - dataframe['ema_12'].shift()) > (dataframe['open']/100)) &
(dataframe['close'] < (dataframe['bb_lowerband'])) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] > 0) # Make sure Volume is not 0
)
)
conditions.append(
(
self.buy_condition_6_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_5.value) &
(dataframe['ema_26'] > dataframe['ema_12']) &
((dataframe['ema_26'] - dataframe['ema_12']) > (dataframe['open'] * self.buy_macd_2.value)) &
((dataframe['ema_26'].shift() - dataframe['ema_12'].shift()) > (dataframe['open']/100)) &
(dataframe['close'] < (dataframe['bb_lowerband'])) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_7_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_2.value) &
(dataframe['ema_26'] > dataframe['ema_12']) &
((dataframe['ema_26'] - dataframe['ema_12']) > (dataframe['open'] * self.buy_macd_1.value)) &
((dataframe['ema_26'].shift() - dataframe['ema_12'].shift()) > (dataframe['open']/100)) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_8_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_3.value) &
(dataframe['rsi'] < self.buy_rsi_1.value) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_9_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_4.value) &
(dataframe['rsi'] < self.buy_rsi_2.value) &
(dataframe['volume'] < (dataframe['volume'].shift() * self.buy_volume_drop_1.value)) &
(dataframe['volume_mean_slow'] > dataframe['volume_mean_slow'].shift(48) * self.buy_volume_pump_1.value) &
(dataframe['volume_mean_slow'] * self.buy_volume_pump_1.value < dataframe['volume_mean_slow'].shift(48)) &
(dataframe['volume'] > 0)
)
)
conditions.append(
(
self.buy_condition_10_enable.value &
(dataframe['rsi_1h'] < self.buy_rsi_1h_4.value) &
(dataframe['close_1h'] < dataframe['bb_lowerband_1h']) &
(dataframe['hist'] > 0) &
(dataframe['hist'].shift(2) < 0) &
(dataframe['rsi'] < 40.5) &
(dataframe['hist'] > dataframe['close'] * 0.0012) &
(dataframe['open'] < dataframe['close']) &
(dataframe['volume'] > 0)
)
)
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:
# dataframe.loc[
# (
# (dataframe['close'] > dataframe['bb_middleband'] * 1.01) & # Don't be gready, sell fast
# (dataframe['volume'] > 0) # Make sure Volume is not 0
# )
# ,
# 'sell'
# ] = 0
dataframe.loc[
(
(dataframe['crossed_below_ema_12_26']) &
(dataframe['volume'] > 0) # Make sure Volume is not 0
)
,
'sell'
] = 0
return dataframe
# Chaikin Money Flow Volume
def MFV(dataframe):
df = dataframe.copy()
N = ((df['close'] - df['low']) - (df['high'] - df['close'])) / (df['high'] - df['low'])
M = N * df['volume']
return M

568
strategies/RSIDivergence.py Executable file
View File

@ -0,0 +1,568 @@
# --- Do not remove these libs ---
from freqtrade.strategy.interface import IStrategy
from typing import Dict, List
from functools import reduce
from pandas import DataFrame
# --------------------------------
import talib.abstract as ta
import numpy as np
import freqtrade.vendor.qtpylib.indicators as qtpylib
import datetime
from technical.util import resample_to_interval, resampled_merge
from freqtrade.strategy import DecimalParameter, IntParameter, BooleanParameter
rangeUpper = 60
rangeLower = 5
def EWO(dataframe, ema_length=5, ema2_length=35):
df = dataframe.copy()
ema1 = ta.EMA(df, timeperiod=ema_length)
ema2 = ta.EMA(df, timeperiod=ema2_length)
emadif = (ema1 - ema2) / df['close'] * 100
return emadif
def valuewhen(dataframe, condition, source, occurrence):
copy = dataframe.copy()
copy['colFromIndex'] = copy.index
copy = copy.sort_values(by=[condition, 'colFromIndex'], ascending=False).reset_index(drop=True)
copy['valuewhen'] = np.where(copy[condition] > 0, copy[source].shift(-occurrence), copy[source])
copy['barrsince'] = copy['colFromIndex'] - copy['colFromIndex'].shift(-occurrence)
copy.loc[
(
(rangeLower <= copy['barrsince']) &
(copy['barrsince'] <= rangeUpper)
)
, "in_range"] = 1
copy['in_range'] = copy['in_range'].fillna(0)
copy = copy.sort_values(by=['colFromIndex'], ascending=True).reset_index(drop=True)
return copy['valuewhen'], copy['in_range']
class Divergence(IStrategy):
INTERFACE_VERSION = 2
# Buy hyperspace params:
buy_params = {
'use_bull': True,
'use_hidden_bull': False,
"ewo_high": 5.835,
"low_rsi_buy": 30,
"high_rsi_buy": 60,
"low_adx_buy": 30,
"high_adx_buy": 30,
"low_stoch_buy": 20,
"high_stoch_buy": 80,
"low_osc_buy": 80,
"high_osc_buy": 80,
}
# Sell hyperspace params:
sell_params = {
'use_bear': True,
'use_hidden_bear': True
}
# ROI table:
minimal_roi = {
"0": 0.05,
}
# Stoploss:
stoploss = -0.08
# Trailing stop:
trailing_stop = True
trailing_stop_positive = 0.005
trailing_stop_positive_offset = 0.02
trailing_only_offset_is_reached = True
# Optimal timeframe for the strategy
timeframe = '5m'
use_custom_stoploss = False
use_bull = BooleanParameter(default=buy_params['use_bull'], space='buy', optimize=False)
use_hidden_bull = BooleanParameter(default=buy_params['use_hidden_bull'], space='buy', optimize=False)
use_bear = BooleanParameter(default=sell_params['use_bear'], space='sell', optimize=True)
use_hidden_bear = BooleanParameter(default=sell_params['use_hidden_bear'], space='sell', optimize=True)
# Protection
fast_ewo = 50
slow_ewo = 200
ewo_high = DecimalParameter(0, 7.0, default=buy_params['ewo_high'], space='buy', optimize=False)
low_rsi_buy = IntParameter(0, 100, default=buy_params['low_rsi_buy'], space='buy', optimize=True)
high_rsi_buy = IntParameter(0, 100, default=buy_params['high_rsi_buy'], space='buy', optimize=True)
low_adx_buy = IntParameter(0, 100, default=buy_params['low_adx_buy'], space='buy', optimize=True)
high_adx_buy = IntParameter(0, 100, default=buy_params['high_adx_buy'], space='buy', optimize=True)
low_stoch_buy = IntParameter(0, 100, default=buy_params['low_stoch_buy'], space='buy', optimize=True)
high_stoch_buy = IntParameter(0, 100, default=buy_params['high_stoch_buy'], space='buy', optimize=True)
low_osc_buy = IntParameter(0, 100, default=buy_params['low_osc_buy'], space='buy', optimize=True)
high_osc_buy = IntParameter(0, 100, default=buy_params['high_osc_buy'], space='buy', optimize=True)
# Number of candles the strategy requires before producing valid signals
startup_candle_count: int = 30
osc = 'slowd'
len = 14
src = 'close'
lbL = 5
lbR = 5
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
study(title="Divergence Indicator", format=format.price, resolution="")
len = input(title="RSI Period", minval=1, defval=14)
src = input(title="RSI Source", defval=close)
lbR = input(title="Pivot Lookback Right", defval=5) # lookahead
lbL = input(title="Pivot Lookback Left", defval=5)
rangeUpper = input(title="Max of Lookback Range", defval=60)
rangeLower = input(title="Min of Lookback Range", defval=5)
plotBull = input(title="Plot Bullish", defval=true)
plotHiddenBull = input(title="Plot Hidden Bullish", defval=false)
plotBear = input(title="Plot Bearish", defval=true)
plotHiddenBear = input(title="Plot Hidden Bearish", defval=false)
bearColor = color.red
bullColor = color.green
hiddenBullColor = color.new(color.green, 80)
hiddenBearColor = color.new(color.red, 80)
textColor = color.white
noneColor = color.new(color.white, 100)
osc = rsi(src, len)
"""
dataframe['RSI'] = ta.RSI(dataframe[self.src], self.len)
dataframe['RSI'] = dataframe['RSI'].fillna(0)
stoch = ta.STOCH(dataframe, fastk_period=10, slowk_period=3, slowk_matype=0, slowd_period=3, slowd_matype=0)
dataframe['slowk'] = stoch['slowk']
dataframe['slowd'] = stoch['slowd']
dataframe['osc'] = dataframe[self.osc]
# plFound = na(pivotlow(osc, lbL, lbR)) ? false : true
dataframe['min'] = dataframe['osc'].rolling(self.lbL).min()
dataframe['prevMin'] = np.where(dataframe['min'] > dataframe['min'].shift(), dataframe['min'].shift(), dataframe['min'])
dataframe.loc[
(
(dataframe['osc'].shift(1) == dataframe['prevMin'].shift(1)) &
(dataframe['osc'] != dataframe['prevMin'])
)
, 'plFound'] = 1
# phFound = na(pivothigh(osc, lbL, lbR)) ? false : true
dataframe['max'] = dataframe['osc'].rolling(self.lbL).max()
dataframe['prevMax'] = np.where(dataframe['max'] < dataframe['max'].shift(), dataframe['max'].shift(), dataframe['max'])
dataframe.loc[
(
(dataframe['osc'].shift(1) == dataframe['prevMax'].shift(1)) &
(dataframe['osc'] != dataframe['prevMax'])
)
, 'phFound'] = 1
#------------------------------------------------------------------------------
# Regular Bullish
# Osc: Higher Low
# oscHL = osc[lbR] > valuewhen(plFound, osc[lbR], 1) and _inRange(plFound[1])
dataframe['valuewhen_plFound_osc'], dataframe['inrange_plFound_osc'] = valuewhen(dataframe, 'plFound', 'osc', 1)
dataframe.loc[
(
(dataframe['osc'] > dataframe['valuewhen_plFound_osc']) &
(dataframe['inrange_plFound_osc'] == 1)
)
, 'oscHL'] = 1
# Price: Lower Low
# priceLL = low[lbR] < valuewhen(plFound, low[lbR], 1)
dataframe['valuewhen_plFound_low'], dataframe['inrange_plFound_low'] = valuewhen(dataframe, 'plFound', 'low', 1)
dataframe.loc[
(dataframe['low'] < dataframe['valuewhen_plFound_low'])
, 'priceLL'] = 1
#bullCond = plotBull and priceLL and oscHL and plFound
dataframe.loc[
(
(dataframe['priceLL'] == 1) &
(dataframe['oscHL'] == 1) &
(dataframe['plFound'] == 1)
)
, 'bullCond'] = 1
# plot(
# plFound ? osc[lbR] : na,
# offset=-lbR,
# title="Regular Bullish",
# linewidth=2,
# color=(bullCond ? bullColor : noneColor)
# )
#
# plotshape(
# bullCond ? osc[lbR] : na,
# offset=-lbR,
# title="Regular Bullish Label",
# text=" Bull ",
# style=shape.labelup,
# location=location.absolute,
# color=bullColor,
# textcolor=textColor
# )
# //------------------------------------------------------------------------------
# // Hidden Bullish
# // Osc: Lower Low
#
# oscLL = osc[lbR] < valuewhen(plFound, osc[lbR], 1) and _inRange(plFound[1])
dataframe['valuewhen_plFound_osc'], dataframe['inrange_plFound_osc'] = valuewhen(dataframe, 'plFound', 'osc', 1)
dataframe.loc[
(
(dataframe['osc'] < dataframe['valuewhen_plFound_osc']) &
(dataframe['inrange_plFound_osc'] == 1)
)
, 'oscLL'] = 1
#
# // Price: Higher Low
#
# priceHL = low[lbR] > valuewhen(plFound, low[lbR], 1)
dataframe['valuewhen_plFound_low'], dataframe['inrange_plFound_low'] = valuewhen(dataframe,'plFound', 'low', 1)
dataframe.loc[
(dataframe['low'] > dataframe['valuewhen_plFound_low'])
, 'priceHL'] = 1
# hiddenBullCond = plotHiddenBull and priceHL and oscLL and plFound
dataframe.loc[
(
(dataframe['priceHL'] == 1) &
(dataframe['oscLL'] == 1) &
(dataframe['plFound'] == 1)
)
, 'hiddenBullCond'] = 1
#
# plot(
# plFound ? osc[lbR] : na,
# offset=-lbR,
# title="Hidden Bullish",
# linewidth=2,
# color=(hiddenBullCond ? hiddenBullColor : noneColor)
# )
#
# plotshape(
# hiddenBullCond ? osc[lbR] : na,
# offset=-lbR,
# title="Hidden Bullish Label",
# text=" H Bull ",
# style=shape.labelup,
# location=location.absolute,
# color=bullColor,
# textcolor=textColor
# )
#
# //------------------------------------------------------------------------------
# // Regular Bearish
# // Osc: Lower High
#
# oscLH = osc[lbR] < valuewhen(phFound, osc[lbR], 1) and _inRange(phFound[1])
dataframe['valuewhen_phFound_osc'], dataframe['inrange_phFound_osc'] = valuewhen(dataframe, 'phFound', 'osc', 1)
dataframe.loc[
(
(dataframe['osc'] < dataframe['valuewhen_phFound_osc']) &
(dataframe['inrange_phFound_osc'] == 1)
)
, 'oscLH'] = 1
#
# // Price: Higher High
#
# priceHH = high[lbR] > valuewhen(phFound, high[lbR], 1)
dataframe['valuewhen_phFound_high'], dataframe['inrange_phFound_high'] = valuewhen(dataframe, 'phFound', 'high', 1)
dataframe.loc[
(dataframe['high'] > dataframe['valuewhen_phFound_high'])
, 'priceHH'] = 1
#
# bearCond = plotBear and priceHH and oscLH and phFound
dataframe.loc[
(
(dataframe['priceHH'] == 1) &
(dataframe['oscLH'] == 1) &
(dataframe['phFound'] == 1)
)
, 'bearCond'] = 1
#
# plot(
# phFound ? osc[lbR] : na,
# offset=-lbR,
# title="Regular Bearish",
# linewidth=2,
# color=(bearCond ? bearColor : noneColor)
# )
#
# plotshape(
# bearCond ? osc[lbR] : na,
# offset=-lbR,
# title="Regular Bearish Label",
# text=" Bear ",
# style=shape.labeldown,
# location=location.absolute,
# color=bearColor,
# textcolor=textColor
# )
#
# //------------------------------------------------------------------------------
# // Hidden Bearish
# // Osc: Higher High
#
# oscHH = osc[lbR] > valuewhen(phFound, osc[lbR], 1) and _inRange(phFound[1])
dataframe['valuewhen_phFound_osc'], dataframe['inrange_phFound_osc'] = valuewhen(dataframe, 'phFound', 'osc', 1)
dataframe.loc[
(
(dataframe['osc'] > dataframe['valuewhen_phFound_osc']) &
(dataframe['inrange_phFound_osc'] == 1)
)
, 'oscHH'] = 1
#
# // Price: Lower High
#
# priceLH = high[lbR] < valuewhen(phFound, high[lbR], 1)
dataframe['valuewhen_phFound_high'], dataframe['inrange_phFound_high'] = valuewhen(dataframe, 'phFound', 'high', 1)
dataframe.loc[
(dataframe['high'] < dataframe['valuewhen_phFound_high'])
, 'priceLH'] = 1
#
# hiddenBearCond = plotHiddenBear and priceLH and oscHH and phFound
dataframe.loc[
(
(dataframe['priceLH'] == 1) &
(dataframe['oscHH'] == 1) &
(dataframe['phFound'] == 1)
)
, 'hiddenBearCond'] = 1
#
# plot(
# phFound ? osc[lbR] : na,
# offset=-lbR,
# title="Hidden Bearish",
# linewidth=2,
# color=(hiddenBearCond ? hiddenBearColor : noneColor)
# )
#
# plotshape(
# hiddenBearCond ? osc[lbR] : na,
# offset=-lbR,
# title="Hidden Bearish Label",
# text=" H Bear ",
# style=shape.labeldown,
# location=location.absolute,
# color=bearColor,
# textcolor=textColor
# )"""
# Elliot
dataframe['EWO'] = EWO(dataframe, self.fast_ewo, self.slow_ewo)
dataframe['ADX'] = ta.ADX(dataframe, timeperiod=14)
return dataframe
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = []
if self.use_bull.value:
conditions.append(
(
(dataframe['bullCond'] > 0) &
(dataframe['valuewhen_plFound_osc'] > self.low_osc_buy.value) &
(dataframe['valuewhen_plFound_osc'] < self.high_osc_buy.value) &
#(dataframe['EWO'] > self.ewo_high.value) &
(dataframe['RSI'] < self.high_rsi_buy.value) &
(dataframe['RSI'] > self.low_rsi_buy.value) &
(dataframe['ADX'] > self.low_adx_buy.value) &
(dataframe['ADX'] < self.high_adx_buy.value) &
(dataframe['slowk'] < self.high_stoch_buy.value) &
(dataframe['slowk'] > self.low_stoch_buy.value) &
(dataframe['volume'] > 0)
)
)
if self.use_hidden_bull.value:
conditions.append(
(
(dataframe['hiddenBullCond'] > 0) &
(dataframe['valuewhen_plFound_osc'] > self.low_osc_buy.value) &
(dataframe['valuewhen_plFound_osc'] < self.high_osc_buy.value) &
(dataframe['RSI'] < self.high_rsi_buy.value) &
(dataframe['RSI'] > self.low_rsi_buy.value) &
(dataframe['slowk'] < self.high_stoch_buy.value) &
(dataframe['slowk'] > self.low_stoch_buy.value) &
(dataframe['ADX'] > self.low_adx_buy.value) &
(dataframe['ADX'] < self.high_adx_buy.value) &
(dataframe['volume'] > 0)
)
)
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:
conditions = []
if self.use_bear.value:
conditions.append(
(
(dataframe['bearCond'] > 0) &
(dataframe['volume'] > 0)
)
)
if self.use_hidden_bear.value:
conditions.append(
(
(dataframe['hiddenBearCond'] > 0) &
(dataframe['volume'] > 0)
)
)
if conditions:
dataframe.loc[
reduce(lambda x, y: x | y, conditions),
'sell'
] = 1
dataframe.to_csv('user_data/csvs/%s_%s.csv' % (self.__class__.__name__, metadata["pair"].replace("/", "_")))
return dataframe
class RSIDivergence(SOTCHDivergence):
# Buy hyperspace params:
buy_params = {
"high_adx_buy": 68,
"high_osc_buy": 74,
"high_rsi_buy": 53,
"high_stoch_buy": 64,
"low_adx_buy": 41,
"low_osc_buy": 15,
"low_rsi_buy": 9,
"low_stoch_buy": 13,
"ewo_high": 5.835, # value loaded from strategy
"use_bull": True, # value loaded from strategy
"use_hidden_bull": False, # value loaded from strategy
}
# Sell hyperspace params:
sell_params = {
"use_bear": False, # value loaded from strategy
"use_hidden_bear": False, # value loaded from strategy
}
# ROI table: # value loaded from strategy
minimal_roi = {
"0": 0.131,
"13": 0.073,
"56": 0.022,
"133": 0
}
# Stoploss:
stoploss = -0.2 # value loaded from strategy
# Trailing stop:
trailing_stop = True # value loaded from strategy
trailing_stop_positive = 0.005 # value loaded from strategy
trailing_stop_positive_offset = 0.02 # value loaded from strategy
trailing_only_offset_is_reached = True # value loaded from strategy
osc = 'RSI'
len = 14
src = 'close'
lbL = 40
class RSIDivergenceNPOriginal(RSIDivergence):
# Buy hyperspace params:
buy_params = {
"adx_buy": 36,
"high_rsi_buy": 60,
"high_stoch_buy": 92,
"low_rsi_buy": 21,
"low_stoch_buy": 6,
"use_bull": True,
"use_hidden_bull": False,
"ewo_high": 5.835, # value loaded from strategy
}
# Sell hyperspace params:
sell_params = {
"use_bear": False,
"use_hidden_bear": False,
}
# ROI table: # value loaded from strategy
minimal_roi = {
"0": 0.05
}
# Stoploss:
stoploss = -0.2 # value loaded from strategy
# Trailing stop:
trailing_stop = True
trailing_stop_positive = 0.001
trailing_stop_positive_offset = 0.02
trailing_only_offset_is_reached = True
osc = 'RSI'
len = 14
src = 'close'
lbL = 40
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = []
if self.use_bull.value:
conditions.append(
(
(dataframe['bullCond'] > 0) &
(dataframe['volume'] > 0)
)
)
if self.use_hidden_bull.value:
conditions.append(
(
(dataframe['hiddenBullCond'] > 0) &
(dataframe['volume'] > 0)
)
)
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:
conditions = []
if self.use_bear.value:
conditions.append(
(
(dataframe['bearCond'] > 0) &
(dataframe['volume'] > 0)
)
)
if self.use_hidden_bear.value:
conditions.append(
(
(dataframe['hiddenBearCond'] > 0) &
(dataframe['volume'] > 0)
)
)
if conditions:
dataframe.loc[
reduce(lambda x, y: x | y, conditions),
'sell'
] = 1
dataframe.to_csv('user_data/csvs/%s_%s.csv' % (self.__class__.__name__, metadata["pair"].replace("/", "_")))
return dataframe

110
strategies/SwingHighToSky.py Executable file
View File

@ -0,0 +1,110 @@
"""
author = "Kevin Ossenbrück"
copyright = "Free For Use"
credits = ["Bloom Trading, Mohsen Hassan"]
license = "MIT"
version = "1.0"
maintainer = "Kevin Ossenbrück"
email = "kevin.ossenbrueck@pm.de"
status = "Live"
"""
from freqtrade.strategy import IStrategy
from freqtrade.strategy import IntParameter
from functools import reduce
from pandas import DataFrame
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
import numpy
# CCI timerperiods and values
cciBuyTP = 72
cciBuyVal = -175
cciSellTP = 66
cciSellVal = -106
# RSI timeperiods and values
rsiBuyTP = 36
rsiBuyVal = 90
rsiSellTP = 45
rsiSellVal = 88
class SwingHighToSky(IStrategy):
INTERFACE_VERSION = 3
timeframe = '15m'
stoploss = -0.34338
minimal_roi = {"0": 0.27058, "33": 0.0853, "64": 0.04093, "244": 0}
buy_cci = IntParameter(low=-200, high=200, default=100, space='buy', optimize=True)
buy_cciTime = IntParameter(low=10, high=80, default=20, space='buy', optimize=True)
buy_rsi = IntParameter(low=10, high=90, default=30, space='buy', optimize=True)
buy_rsiTime = IntParameter(low=10, high=80, default=26, space='buy', optimize=True)
sell_cci = IntParameter(low=-200, high=200, default=100, space='sell', optimize=True)
sell_cciTime = IntParameter(low=10, high=80, default=20, space='sell', optimize=True)
sell_rsi = IntParameter(low=10, high=90, default=30, space='sell', optimize=True)
sell_rsiTime = IntParameter(low=10, high=80, default=26, space='sell', optimize=True)
# Buy hyperspace params:
buy_params = {
"buy_cci": -175,
"buy_cciTime": 72,
"buy_rsi": 90,
"buy_rsiTime": 36,
}
# Sell hyperspace params:
sell_params = {
"sell_cci": -106,
"sell_cciTime": 66,
"sell_rsi": 88,
"sell_rsiTime": 45,
}
def informative_pairs(self):
return []
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
for val in self.buy_cciTime.range:
dataframe[f'cci-{val}'] = ta.CCI(dataframe, timeperiod=val)
for val in self.sell_cciTime.range:
dataframe[f'cci-sell-{val}'] = ta.CCI(dataframe, timeperiod=val)
for val in self.buy_rsiTime.range:
dataframe[f'rsi-{val}'] = ta.RSI(dataframe, timeperiod=val)
for val in self.sell_rsiTime.range:
dataframe[f'rsi-sell-{val}'] = ta.RSI(dataframe, timeperiod=val)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(dataframe[f'cci-{self.buy_cciTime.value}'] < self.buy_cci.value) &
(dataframe[f'rsi-{self.buy_rsiTime.value}'] < self.buy_rsi.value)
),
'enter_long'] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(dataframe[f'cci-sell-{self.sell_cciTime.value}'] > self.sell_cci.value) &
(dataframe[f'rsi-sell-{self.sell_rsiTime.value}'] > self.sell_rsi.value)
),
'exit_long'] = 1
return dataframe

404
strategies/sample_strategy.py Executable file
View File

@ -0,0 +1,404 @@
# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
# flake8: noqa: F401
# isort: skip_file
# --- Do not remove these libs ---
import numpy as np # noqa
import pandas as pd # noqa
from pandas import DataFrame
from typing import Optional, Union
from freqtrade.strategy import (BooleanParameter, CategoricalParameter, DecimalParameter,
IStrategy, IntParameter)
# --------------------------------
# Add your lib to import here
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
# This class is a sample. Feel free to customize it.
class SampleStrategy(IStrategy):
"""
This is a sample strategy to inspire you.
More information in https://www.freqtrade.io/en/latest/strategy-customization/
You can:
:return: a Dataframe with all mandatory indicators for the strategies
- Rename the class name (Do not forget to update class_name)
- Add any methods you want to build your strategy
- Add any lib you need to build your strategy
You must keep:
- the lib in the section "Do not remove these libs"
- the methods: populate_indicators, populate_entry_trend, populate_exit_trend
You should keep:
- timeframe, minimal_roi, stoploss, trailing_*
"""
# Strategy interface version - allow new iterations of the strategy interface.
# Check the documentation or the Sample strategy to get the latest version.
INTERFACE_VERSION = 3
# Can this strategy go short?
can_short: bool = False
# Minimal ROI designed for the strategy.
# This attribute will be overridden if the config file contains "minimal_roi".
minimal_roi = {
"60": 0.01,
"30": 0.02,
"0": 0.04
}
# Optimal stoploss designed for the strategy.
# This attribute will be overridden if the config file contains "stoploss".
stoploss = -0.10
# Trailing stoploss
trailing_stop = False
# trailing_only_offset_is_reached = False
# trailing_stop_positive = 0.01
# trailing_stop_positive_offset = 0.0 # Disabled / not configured
# Optimal timeframe for the strategy.
timeframe = '5m'
# Run "populate_indicators()" only for new candle.
process_only_new_candles = True
# These values can be overridden in the config.
use_exit_signal = True
exit_profit_only = False
ignore_roi_if_entry_signal = False
# Hyperoptable parameters
buy_rsi = IntParameter(low=1, high=50, default=30, space='buy', optimize=True, load=True)
sell_rsi = IntParameter(low=50, high=100, default=70, space='sell', optimize=True, load=True)
short_rsi = IntParameter(low=51, high=100, default=70, space='sell', optimize=True, load=True)
exit_short_rsi = IntParameter(low=1, high=50, default=30, space='buy', optimize=True, load=True)
# Number of candles the strategy requires before producing valid signals
startup_candle_count: int = 30
# Optional order type mapping.
order_types = {
'entry': 'limit',
'exit': 'limit',
'stoploss': 'market',
'stoploss_on_exchange': False
}
# Optional order time in force.
order_time_in_force = {
'entry': 'GTC',
'exit': 'GTC'
}
plot_config = {
'main_plot': {
'tema': {},
'sar': {'color': 'white'},
},
'subplots': {
"MACD": {
'macd': {'color': 'blue'},
'macdsignal': {'color': 'orange'},
},
"RSI": {
'rsi': {'color': 'red'},
}
}
}
def informative_pairs(self):
"""
Define additional, informative pair/interval combinations to be cached from the exchange.
These pair/interval combinations are non-tradeable, unless they are part
of the whitelist as well.
For more information, please consult the documentation
:return: List of tuples in the format (pair, interval)
Sample: return [("ETH/USDT", "5m"),
("BTC/USDT", "15m"),
]
"""
return []
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Adds several different TA indicators to the given DataFrame
Performance Note: For the best performance be frugal on the number of indicators
you are using. Let uncomment only the indicator you are using in your strategies
or your hyperopt configuration, otherwise you will waste your memory and CPU usage.
:param dataframe: Dataframe with data from the exchange
:param metadata: Additional information, like the currently traded pair
:return: a Dataframe with all mandatory indicators for the strategies
"""
# Momentum Indicators
# ------------------------------------
# ADX
dataframe['adx'] = ta.ADX(dataframe)
# # Plus Directional Indicator / Movement
# dataframe['plus_dm'] = ta.PLUS_DM(dataframe)
# dataframe['plus_di'] = ta.PLUS_DI(dataframe)
# # Minus Directional Indicator / Movement
# dataframe['minus_dm'] = ta.MINUS_DM(dataframe)
# dataframe['minus_di'] = ta.MINUS_DI(dataframe)
# # Aroon, Aroon Oscillator
# aroon = ta.AROON(dataframe)
# dataframe['aroonup'] = aroon['aroonup']
# dataframe['aroondown'] = aroon['aroondown']
# dataframe['aroonosc'] = ta.AROONOSC(dataframe)
# # Awesome Oscillator
# dataframe['ao'] = qtpylib.awesome_oscillator(dataframe)
# # Keltner Channel
# keltner = qtpylib.keltner_channel(dataframe)
# dataframe["kc_upperband"] = keltner["upper"]
# dataframe["kc_lowerband"] = keltner["lower"]
# dataframe["kc_middleband"] = keltner["mid"]
# dataframe["kc_percent"] = (
# (dataframe["close"] - dataframe["kc_lowerband"]) /
# (dataframe["kc_upperband"] - dataframe["kc_lowerband"])
# )
# dataframe["kc_width"] = (
# (dataframe["kc_upperband"] - dataframe["kc_lowerband"]) / dataframe["kc_middleband"]
# )
# # Ultimate Oscillator
# dataframe['uo'] = ta.ULTOSC(dataframe)
# # Commodity Channel Index: values [Oversold:-100, Overbought:100]
# dataframe['cci'] = ta.CCI(dataframe)
# RSI
dataframe['rsi'] = ta.RSI(dataframe)
# # Inverse Fisher transform on RSI: values [-1.0, 1.0] (https://goo.gl/2JGGoy)
# rsi = 0.1 * (dataframe['rsi'] - 50)
# dataframe['fisher_rsi'] = (np.exp(2 * rsi) - 1) / (np.exp(2 * rsi) + 1)
# # Inverse Fisher transform on RSI normalized: values [0.0, 100.0] (https://goo.gl/2JGGoy)
# dataframe['fisher_rsi_norma'] = 50 * (dataframe['fisher_rsi'] + 1)
# # Stochastic Slow
# stoch = ta.STOCH(dataframe)
# dataframe['slowd'] = stoch['slowd']
# dataframe['slowk'] = stoch['slowk']
# Stochastic Fast
stoch_fast = ta.STOCHF(dataframe)
dataframe['fastd'] = stoch_fast['fastd']
dataframe['fastk'] = stoch_fast['fastk']
# # Stochastic RSI
# Please read https://github.com/freqtrade/freqtrade/issues/2961 before using this.
# STOCHRSI is NOT aligned with tradingview, which may result in non-expected results.
# stoch_rsi = ta.STOCHRSI(dataframe)
# dataframe['fastd_rsi'] = stoch_rsi['fastd']
# dataframe['fastk_rsi'] = stoch_rsi['fastk']
# MACD
macd = ta.MACD(dataframe)
dataframe['macd'] = macd['macd']
dataframe['macdsignal'] = macd['macdsignal']
dataframe['macdhist'] = macd['macdhist']
# MFI
dataframe['mfi'] = ta.MFI(dataframe)
# # ROC
# dataframe['roc'] = ta.ROC(dataframe)
# Overlap Studies
# ------------------------------------
# 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"]
)
# Bollinger Bands - Weighted (EMA based instead of SMA)
# weighted_bollinger = qtpylib.weighted_bollinger_bands(
# qtpylib.typical_price(dataframe), window=20, stds=2
# )
# dataframe["wbb_upperband"] = weighted_bollinger["upper"]
# dataframe["wbb_lowerband"] = weighted_bollinger["lower"]
# dataframe["wbb_middleband"] = weighted_bollinger["mid"]
# dataframe["wbb_percent"] = (
# (dataframe["close"] - dataframe["wbb_lowerband"]) /
# (dataframe["wbb_upperband"] - dataframe["wbb_lowerband"])
# )
# dataframe["wbb_width"] = (
# (dataframe["wbb_upperband"] - dataframe["wbb_lowerband"]) /
# dataframe["wbb_middleband"]
# )
# # EMA - Exponential Moving Average
# dataframe['ema3'] = ta.EMA(dataframe, timeperiod=3)
# dataframe['ema5'] = ta.EMA(dataframe, timeperiod=5)
# dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10)
# dataframe['ema21'] = ta.EMA(dataframe, timeperiod=21)
# dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50)
# dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100)
# # SMA - Simple Moving Average
# dataframe['sma3'] = ta.SMA(dataframe, timeperiod=3)
# dataframe['sma5'] = ta.SMA(dataframe, timeperiod=5)
# dataframe['sma10'] = ta.SMA(dataframe, timeperiod=10)
# dataframe['sma21'] = ta.SMA(dataframe, timeperiod=21)
# dataframe['sma50'] = ta.SMA(dataframe, timeperiod=50)
# dataframe['sma100'] = ta.SMA(dataframe, timeperiod=100)
# Parabolic SAR
dataframe['sar'] = ta.SAR(dataframe)
# TEMA - Triple Exponential Moving Average
dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9)
# Cycle Indicator
# ------------------------------------
# Hilbert Transform Indicator - SineWave
hilbert = ta.HT_SINE(dataframe)
dataframe['htsine'] = hilbert['sine']
dataframe['htleadsine'] = hilbert['leadsine']
# Pattern Recognition - Bullish candlestick patterns
# ------------------------------------
# # Hammer: values [0, 100]
# dataframe['CDLHAMMER'] = ta.CDLHAMMER(dataframe)
# # Inverted Hammer: values [0, 100]
# dataframe['CDLINVERTEDHAMMER'] = ta.CDLINVERTEDHAMMER(dataframe)
# # Dragonfly Doji: values [0, 100]
# dataframe['CDLDRAGONFLYDOJI'] = ta.CDLDRAGONFLYDOJI(dataframe)
# # Piercing Line: values [0, 100]
# dataframe['CDLPIERCING'] = ta.CDLPIERCING(dataframe) # values [0, 100]
# # Morningstar: values [0, 100]
# dataframe['CDLMORNINGSTAR'] = ta.CDLMORNINGSTAR(dataframe) # values [0, 100]
# # Three White Soldiers: values [0, 100]
# dataframe['CDL3WHITESOLDIERS'] = ta.CDL3WHITESOLDIERS(dataframe) # values [0, 100]
# Pattern Recognition - Bearish candlestick patterns
# ------------------------------------
# # Hanging Man: values [0, 100]
# dataframe['CDLHANGINGMAN'] = ta.CDLHANGINGMAN(dataframe)
# # Shooting Star: values [0, 100]
# dataframe['CDLSHOOTINGSTAR'] = ta.CDLSHOOTINGSTAR(dataframe)
# # Gravestone Doji: values [0, 100]
# dataframe['CDLGRAVESTONEDOJI'] = ta.CDLGRAVESTONEDOJI(dataframe)
# # Dark Cloud Cover: values [0, 100]
# dataframe['CDLDARKCLOUDCOVER'] = ta.CDLDARKCLOUDCOVER(dataframe)
# # Evening Doji Star: values [0, 100]
# dataframe['CDLEVENINGDOJISTAR'] = ta.CDLEVENINGDOJISTAR(dataframe)
# # Evening Star: values [0, 100]
# dataframe['CDLEVENINGSTAR'] = ta.CDLEVENINGSTAR(dataframe)
# Pattern Recognition - Bullish/Bearish candlestick patterns
# ------------------------------------
# # Three Line Strike: values [0, -100, 100]
# dataframe['CDL3LINESTRIKE'] = ta.CDL3LINESTRIKE(dataframe)
# # Spinning Top: values [0, -100, 100]
# dataframe['CDLSPINNINGTOP'] = ta.CDLSPINNINGTOP(dataframe) # values [0, -100, 100]
# # Engulfing: values [0, -100, 100]
# dataframe['CDLENGULFING'] = ta.CDLENGULFING(dataframe) # values [0, -100, 100]
# # Harami: values [0, -100, 100]
# dataframe['CDLHARAMI'] = ta.CDLHARAMI(dataframe) # values [0, -100, 100]
# # Three Outside Up/Down: values [0, -100, 100]
# dataframe['CDL3OUTSIDE'] = ta.CDL3OUTSIDE(dataframe) # values [0, -100, 100]
# # Three Inside Up/Down: values [0, -100, 100]
# dataframe['CDL3INSIDE'] = ta.CDL3INSIDE(dataframe) # values [0, -100, 100]
# # Chart type
# # ------------------------------------
# # Heikin Ashi Strategy
# heikinashi = qtpylib.heikinashi(dataframe)
# dataframe['ha_open'] = heikinashi['open']
# dataframe['ha_close'] = heikinashi['close']
# dataframe['ha_high'] = heikinashi['high']
# dataframe['ha_low'] = heikinashi['low']
# Retrieve best bid and best ask from the orderbook
# ------------------------------------
"""
# first check if dataprovider is available
if self.dp:
if self.dp.runmode.value in ('live', 'dry_run'):
ob = self.dp.orderbook(metadata['pair'], 1)
dataframe['best_bid'] = ob['bids'][0][0]
dataframe['best_ask'] = ob['asks'][0][0]
"""
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Based on TA indicators, populates the entry signal for the given dataframe
:param dataframe: DataFrame
:param metadata: Additional information, like the currently traded pair
:return: DataFrame with entry columns populated
"""
dataframe.loc[
(
# Signal: RSI crosses above 30
(qtpylib.crossed_above(dataframe['rsi'], self.buy_rsi.value)) &
(dataframe['tema'] <= dataframe['bb_middleband']) & # Guard: tema below BB middle
(dataframe['tema'] > dataframe['tema'].shift(1)) & # Guard: tema is raising
(dataframe['volume'] > 0) # Make sure Volume is not 0
),
'enter_long'] = 1
dataframe.loc[
(
# Signal: RSI crosses above 70
(qtpylib.crossed_above(dataframe['rsi'], self.short_rsi.value)) &
(dataframe['tema'] > dataframe['bb_middleband']) & # Guard: tema above BB middle
(dataframe['tema'] < dataframe['tema'].shift(1)) & # Guard: tema is falling
(dataframe['volume'] > 0) # Make sure Volume is not 0
),
'enter_short'] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Based on TA indicators, populates the exit signal for the given dataframe
:param dataframe: DataFrame
:param metadata: Additional information, like the currently traded pair
:return: DataFrame with exit columns populated
"""
dataframe.loc[
(
# Signal: RSI crosses above 70
(qtpylib.crossed_above(dataframe['rsi'], self.sell_rsi.value)) &
(dataframe['tema'] > dataframe['bb_middleband']) & # Guard: tema above BB middle
(dataframe['tema'] < dataframe['tema'].shift(1)) & # Guard: tema is falling
(dataframe['volume'] > 0) # Make sure Volume is not 0
),
'exit_long'] = 1
dataframe.loc[
(
# Signal: RSI crosses above 30
(qtpylib.crossed_above(dataframe['rsi'], self.exit_short_rsi.value)) &
# Guard: tema below BB middle
(dataframe['tema'] <= dataframe['bb_middleband']) &
(dataframe['tema'] > dataframe['tema'].shift(1)) & # Guard: tema is raising
(dataframe['volume'] > 0) # Make sure Volume is not 0
),
'exit_short'] = 1
return dataframe