Timeframe
5m
Direction
Long Only
Stoploss
-27.5%
Trailing Stop
No
ROI
0m: 21.5%, 40m: 3.2%, 87m: 1.6%, 201m: 0.0%
Interface Version
N/A
Startup Candles
96
Indicators
6
freqtrade/freqtrade-strategies
Strategy 003 author@: Gerald Lonlas github@: https://github.com/freqtrade/freqtrade-strategies
# --- Do not remove these libs ---
from sqlalchemy import true
from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame, Series
import copy
import logging
import pathlib
import rapidjson
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
import pandas as pd # noqa
pd.options.mode.chained_assignment = None # default='warn'
import technical.indicators as ftt
from freqtrade.exchange import timeframe_to_prev_date
from functools import reduce
from datetime import datetime, timedelta, timezone
import numpy as np
from technical.util import resample_to_interval, resampled_merge
from freqtrade.strategy import informative
from freqtrade.strategy import stoploss_from_open
from freqtrade.strategy import (BooleanParameter,timeframe_to_minutes, merge_informative_pair,
DecimalParameter, IntParameter, CategoricalParameter)
from freqtrade.persistence import Trade
from typing import Dict
import numpy # noqa
import math
import pandas_ta as pta
from typing import List
from skopt.space import Dimension, Integer
import time
from warnings import simplefilter
from technical.indicators import zema
logger = logging.getLogger(__name__)
simplefilter(action="ignore", category=pd.errors.PerformanceWarning)
##### SETINGS #####
# It hyperopt just one set of params for all buy and sell strategies if true.
DUALFIT = False
COUNT = 10
GAP = 3
### END SETINGS ###
def max_pump_detect_price_15m(dataframe, period=14, pause = 288 ):
df = dataframe.copy()
df['size'] = df['high'] - df['low']
cumulativeup = 0
countup = 0
cumulativedown = 0
countdown = 0
for i in range(period):
cumulativeup = cumulativeup + df['volume'].shift(i) * df['size'].shift(i) * np.where(df['close'].shift(i) > df['open'].shift(i), 1, 0)
cumulativedown = cumulativedown + df['volume'].shift(i) * df['size'].shift(i) * np.where(df['close'].shift(i) > df['open'].shift(i), 0, 1)
flow_price = cumulativeup - cumulativedown
flow_price_normalized = flow_price / (df['volume'].rolling(499).mean() * (df['high']-df['low']).rolling(499).mean())
max_flow_price = flow_price_normalized.rolling(pause).max()
return max_flow_price
def flow_price_15m(dataframe, period=14, pause = 288 ):
df = dataframe.copy()
df['size'] = df['high'] - df['low']
cumulativeup = 0
countup = 0
cumulativedown = 0
countdown = 0
for i in range(period):
cumulativeup = cumulativeup + df['volume'].shift(i) * df['size'].shift(i) * np.where(df['close'].shift(i) > df['open'].shift(i), 1, 0)
cumulativedown = cumulativedown + df['volume'].shift(i) * df['size'].shift(i) * np.where(df['close'].shift(i) > df['open'].shift(i), 0, 1)
flow_price = cumulativeup - cumulativedown
flow_price_normalized = flow_price / (df['volume'].rolling(499).mean() * (df['high']-df['low']).rolling(499).mean())
return flow_price_normalized
def to_minutes(**timdelta_kwargs):
return int(timedelta(**timdelta_kwargs).total_seconds() / 60)
#########################################################
####################### ichiV1_Mod #####################
#########################################################
#############################################
class ichiV1_Marius(IStrategy):
class HyperOpt:
@staticmethod
def generate_roi_table(params: dict):
"""
Generate the ROI table that will be used by Hyperopt
This implementation generates the default legacy Freqtrade ROI tables.
Change it if you need different number of steps in the generated
ROI tables or other structure of the ROI tables.
Please keep it aligned with parameters in the 'roi' optimization
hyperspace defined by the roi_space method.
"""
roi_table = {}
roi_table[0] = 0.05
roi_table[params['roi_t6']] = 0.04
roi_table[params['roi_t5']] = 0.03
roi_table[params['roi_t4']] = 0.02
roi_table[params['roi_t3']] = 0.01
roi_table[params['roi_t2']] = 0.0001
roi_table[params['roi_t1']] = -10
return roi_table
@staticmethod
def roi_space() -> List[Dimension]:
"""
Values to search for each ROI steps
Override it if you need some different ranges for the parameters in the
'roi' optimization hyperspace.
Please keep it aligned with the implementation of the
generate_roi_table method.
"""
return [
Integer(240, 720, name='roi_t1'),
Integer(120, 240, name='roi_t2'),
Integer(90, 120, name='roi_t3'),
Integer(60, 90, name='roi_t4'),
Integer(30, 60, name='roi_t5'),
Integer(1, 30, name='roi_t6'),
]
DATESTAMP = 0
SELLMA = 1
# Buy hyperspace params:
buy_params = {
"max_slip": 0.668,
"antipump_threshold": 0.265,
"antipump_threshold_2": 0.133,
"buy_btc_safe_1d": -0.236,
"buy_btc_safe": -213,
"buy_threshold": 0.012,
##
"pump_limit": 1000,
"pump_pause_duration": 192,
"pump_period": 14,
"pump_recorver_price": 1.1,
##
"buy_trend_above_senkou_level": 1,
"buy_trend_bullish_level": 6,
"tesla_enabled": True,
# "buy_fan_magnitude_shift_value": 3,
"buy_min_fan_magnitude_gain": 1.0022, # NOTE: Good value (Win% ~70%), alot of trades
#"buy_min_fan_magnitude_gain": 1.008 # NOTE: Very save value (Win% ~90%), only the biggest moves 1.008,
}
sell_params = {
"ProfitLoss1": 0.005,
"ProfitLoss2": 0.021,
"ProfitMargin1": 0.018,
"ProfitMargin2": 0.051,
"pHSL": -0.08,
"sell_trend_indicator": "trend_close_2h",
}
# minimum conditions to match in buy
buy_minimum_conditions = IntParameter(
1, 2, default=1, space="buy", optimize=False, load=True
)
position_adjustment_enable = True
max_dca_orders = 2
max_dca_multiplier = 1.25
dca_stake_multiplier = 1.25
def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float,
proposed_stake: float, min_stake: float, max_stake: float,
**kwargs) -> float:
if (self.config['position_adjustment_enable'] == True) and (self.config['stake_amount'] == 'unlimited'):
return self.wallets.get_total_stake_amount() / self.config['max_open_trades'] / self.max_dca_multiplier
else:
return proposed_stake
def adjust_trade_position(self, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, min_stake: float,
max_stake: float, **kwargs):
if current_profit > -0.05:
return None
dataframe, _ = self.dp.get_analyzed_dataframe(trade.pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
previous_candle = dataframe.iloc[-2].squeeze()
if last_candle['close'] < previous_candle['close']:
return None
filled_buys = trade.select_filled_orders('buy')
count_of_buys = len(filled_buys)
if 0 < count_of_buys <= self.max_dca_orders:
try:
stake_amount = filled_buys[0].cost
# This then calculates current safety order size
stake_amount = stake_amount * self.dca_stake_multiplier
return stake_amount
except Exception as exception:
return None
return None
# Pump protection
pump_period = IntParameter(
5, 24, default=buy_params['pump_period'], space='buy', optimize=False)
pump_limit = IntParameter(
100,10000, default=buy_params['pump_limit'], space='buy', optimize=True)
pump_recorver_price = DecimalParameter(
1.0, 1.3, default=buy_params['pump_recorver_price'], space='buy', optimize=True)
pump_pause_duration = IntParameter(
6, 500, default=buy_params['pump_pause_duration'], space='buy', optimize=True)
##################################################################
## Slippage params
is_optimize_slip = False
max_slip = DecimalParameter(0.33, 0.80, default=0.33, decimals=3, optimize=is_optimize_slip , load=True)
buy_btc_safe = IntParameter(-300, 50, default=buy_params['buy_btc_safe'], optimize = True)
buy_btc_safe_1d = DecimalParameter(-0.5, -0.015, default=buy_params['buy_btc_safe_1d'], optimize=True)
antipump_threshold = DecimalParameter(0, 0.4, default=buy_params['antipump_threshold'], space='buy', optimize=True)
antipump_threshold_2 = DecimalParameter(0, 0.4, default=buy_params['antipump_threshold_2'], space='buy', optimize=True)
buy_min_fan_magnitude_gain = DecimalParameter(70, 90, default=buy_params['buy_min_fan_magnitude_gain'], space='buy', optimize=False, load=True) # Multi Offset
buy_threshold = DecimalParameter(0.003, 0.012, default=buy_params['buy_threshold'], optimize=True)
#######################################################################
# ROI table:
minimal_roi = {
"0": 0.215,
"40": 0.032,
"87": 0.016,
"201": 0
}
# Stoploss:
stoploss = -0.275 # value loaded from strategy
# Trailing stop:
trailing_stop = False
#trailing_stop_positive = 0.001
#trailing_stop_positive_offset = 0.016
#trailing_only_offset_is_reached = True
window_buy = IntParameter(60, 1000, default=500, space='buy', optimize=True)
bandwidth_buy = IntParameter(2, 15, default=8, space='buy', optimize=True)
mult_buy = DecimalParameter(0.5, 20.0, default=3, space='buy', optimize=True)
# Optional order time in force.
order_time_in_force = {
'buy': 'gtc',
'sell': 'gtc'
}
use_custom_stoploss = True
# Optimal timeframe for the strategy
timeframe = '5m'
informative_timeframe = '1h'
inf_15m = '15m' #use for pump detection
timeframe_minutes = timeframe_to_minutes(timeframe)
# storage dict for custom info
custom_info = {}
startup_candle_count: int = 499
# startup_candle_count = 96
process_only_new_candles = True
timeperiods = [
# 50 // timeframe_minutes,
# 85 // timeframe_minutes,
180 // timeframe_minutes,
360 // timeframe_minutes,
420 // timeframe_minutes,
560 // timeframe_minutes,
]
use_sell_signal = False
sell_profit_only = False
ignore_roi_if_buy_signal = True
# trailing stoploss hyperopt parameters
pHSL = DecimalParameter(-0.15, -0.08, default=sell_params['pHSL'], decimals=3, space='sell', optimize=True)
ProfitMargin1 = DecimalParameter(0.009, 0.019, default=sell_params['ProfitMargin1'], decimals=3, space='sell', optimize=True)
ProfitLoss1 = DecimalParameter(0.005, 0.012, default=sell_params['ProfitLoss1'], decimals=3, space='sell', optimize=True)
ProfitMargin2 = DecimalParameter(0.033, 0.099, default=sell_params['ProfitMargin2'], decimals=3, space='sell', optimize=True)
ProfitLoss2 = DecimalParameter(0.010, 0.025, default=sell_params['ProfitLoss2'], decimals=3, space='sell', optimize=True)
plot_config = {
'main_plot': {
# fill area between senkou_a and senkou_b
'senkou_a': {
'color': 'green', #optional
'fill_to': 'senkou_b',
'fill_label': 'Ichimoku Cloud', #optional
'fill_color': 'rgba(255,76,46,0.2)', #optional
},
# plot senkou_b, too. Not only the area to it.
'senkou_b': {},
},
'subplots': {
'fan_magnitude': {
'fan_magnitude': {}
},
'fan_magnitude_gain': {
'fan_magnitude_gain': {}
}
}
}
slippage_protection = {
'retries': 3,
'max_slippage': -0.02
}
def custom_sell(self, pair: str, trade: 'Trade', current_time: 'datetime', current_rate: float, current_profit: float, **kwargs):
if ((current_time - trade.open_date_utc).seconds / 60 > 1440):
return 'unclog'
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
HSL = self.pHSL.value
if (current_profit > self.ProfitMargin2.value):
sl_profit = self.ProfitLoss2.value
elif (current_profit > self.ProfitMargin1.value):
sl_profit = self.ProfitLoss1.value + ((current_profit - self.ProfitMargin1.value) * (self.ProfitLoss2.value - self.ProfitLoss1.value) / (self.ProfitMargin2.value - self.ProfitMargin1.value))
else:
sl_profit = HSL
return sl_profit
def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float,
rate: float, time_in_force: str, sell_reason: str,
current_time: datetime, **kwargs) -> bool:
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1]
current_profit = trade.calc_profit_ratio(rate)
if 'tesla_' in trade.buy_tag and current_profit > 0.01:
return True
if (trade.buy_tag == 'telsa_'):
if (sell_reason in ['sell_signal'])or (sell_reason in ['roi']) or (sell_reason in ['trailing_stop_loss']):
return False
if (last_candle is not None):
if (sell_reason in ['sell_signal']):
if (last_candle['hma_50'] > last_candle['ema_100']) and (last_candle['rsi'] < 45): #*1.2
return False
if (last_candle is not None):
if (sell_reason in ['sell_signal']):
if (last_candle['hma_50']*1.149 > last_candle['ema_100']) and (last_candle['close'] < last_candle['ema_100']*0.951): #*1.2
return False
# slippage
try:
state = self.slippage_protection['__pair_retries']
except KeyError:
state = self.slippage_protection['__pair_retries'] = {}
candle = dataframe.iloc[-1].squeeze()
slippage = (rate / candle['close']) - 1
if slippage < self.slippage_protection['max_slippage']:
pair_retries = state.get(pair, 0)
if pair_retries < self.slippage_protection['retries']:
state[pair] = pair_retries + 1
return False
state[pair] = 0
return True
age_filter = 30
@informative('1d')
def populate_indicators_1d(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe['age_filter_ok'] = (dataframe['volume'].rolling(window=self.age_filter, min_periods=self.age_filter).min() > 0)
return dataframe
def informative_pairs(self):
# get access to all pairs available in whitelist.
pairs = self.dp.current_whitelist()
# Assign tf to each pair so they can be downloaded and cached for strategy.
informative_pairs = [(pair, '1h') for pair in pairs]
informative_pairs = [(pair, '15m') for pair in pairs]
informative_pairs.extend([(pair, self.informative_timeframe) for pair in pairs])
informative_pairs += [("BTC/USDT", "1m")]
informative_pairs += [("BTC/USDT", "5m")]
informative_pairs += [("BTC/USDT", "1d")]
return informative_pairs
def get_informative_indicators(self, metadata: dict):
dataframe = self.dp.get_pair_dataframe(
pair=metadata['pair'], timeframe=self.informative_timeframe)
return dataframe
def informative_1h_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
tik = time.perf_counter()
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.informative_timeframe)
# RSI
informative_1h['rsi'] = ta.RSI(informative_1h, timeperiod=14)
#Weekly average close price
informative_1h['weekly_close_avg'] = informative_1h['close'].rolling(168).mean()
return informative_1h
#######################################################################
# Informative indicator for pump detection
def informative_15m_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
assert self.dp, "DataProvider is required for multiple timeframes."
# Get the informative pair
informative_15m = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.inf_15m)
informative_15m['max_flow_price'] = max_pump_detect_price_15m(informative_15m, period=self.pump_period.value, pause=self.pump_pause_duration.value)
informative_15m['flow_price'] = flow_price_15m(informative_15m, period=self.pump_period.value, pause=self.pump_pause_duration.value)
return informative_15m
#######################################################################
def top_percent_change(self, dataframe: DataFrame, length: int) -> float:
"""
Percentage change of the current close from the range maximum Open price
:param dataframe: DataFrame The original OHLC dataframe
:param length: int The length to look back
"""
df = dataframe.copy()
if length == 0:
return ((df['open'] - df['close']) / df['close'])
else:
return ((df['open'].rolling(length).max() - df['close']) / df['close'])
def normal_tf_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
### BTC protection
if self.config['stake_currency'] in ['USDT','BUSD','USDC','DAI','TUSD','PAX','USD','EUR','GBP']:
btc_info_pair = f"BTC/{self.config['stake_currency']}"
else:
btc_info_pair = "BTC/USDT"
btc_df = self.dp.get_pair_dataframe(pair=btc_info_pair, timeframe=self.timeframe)
dataframe['btc_rsi'] = normalize(ta.RSI(btc_df, timeperiod=14), 0, 100)
### BTC protection
dataframe['btc_5m']= self.dp.get_pair_dataframe('BTC/USDT', timeframe='5m')['close']
btc_1d = self.dp.get_pair_dataframe('BTC/USDT', timeframe='1d')[['date', 'close']].rename(columns={"close": "btc"}).shift(1)
dataframe = merge_informative_pair(dataframe, btc_1d, '5m', '1d', ffill=True)
# BTC info
informative = self.dp.get_pair_dataframe(pair="BTC/USDT", timeframe="5m")
informative_past = informative.copy().shift(1)
# BTC 5m dump protection
informative_past_source = (informative_past['open'] + informative_past['close'] + informative_past['high'] + informative_past['low']) / 4 # Get BTC price
informative_threshold = informative_past_source * self.buy_threshold.value # BTC dump n% in 5 min
informative_past_delta = informative_past['close'].shift(1) - informative_past['close'] # should be positive if dump
informative_diff = informative_threshold - informative_past_delta # Need be larger than 0
dataframe['btc_threshold'] = informative_threshold
dataframe['btc_diff'] = informative_diff
# BTC 1d dump protection
informative_past_1d = informative.copy().shift(288)
informative_past_source_1d = (informative_past_1d['open'] + informative_past_1d['close'] + informative_past_1d['high'] + informative_past_1d['low']) / 4
dataframe['btc_5m'] = informative_past_source
dataframe['btc_1d'] = informative_past_source_1d
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
# strategy ClucMay72018
dataframe['ema_slow'] = ta.EMA(dataframe, timeperiod=50)
dataframe['volume_mean_slow'] = dataframe['volume'].rolling(window=30).mean()
dataframe['hma_50'] = qtpylib.hull_moving_average(dataframe['close'], window=50)
dataframe['ema_100'] = ta.EMA(dataframe, timeperiod=100)
dataframe['ema21'] = ta.EMA(dataframe, timeperiod=21)
dataframe['ema55'] = ta.EMA(dataframe, timeperiod=55)
# Pump strength
dataframe['ema_50'] = ta.EMA(dataframe, timeperiod=50)
dataframe['ema_200'] = ta.EMA(dataframe, timeperiod=200)
dataframe['zema_30'] = ftt.zema(dataframe, period=30)
dataframe['zema_200'] = ftt.zema(dataframe, period=200)
dataframe['pump_strength'] = (dataframe['zema_30'] - dataframe['zema_200']) / dataframe['zema_30']
dataframe['pump_strength_2'] = (dataframe['ema_50'] - dataframe['ema_200']) / dataframe['ema_50']
heikinashi = qtpylib.heikinashi(dataframe)
heikinashi["volume"] = dataframe["volume"]
dataframe['open'] = heikinashi['open']
#dataframe['close'] = heikinashi['close']
dataframe['high'] = heikinashi['high']
dataframe['low'] = heikinashi['low']
dataframe['trend_close_5m'] = dataframe['close']
dataframe['trend_close_15m'] = ta.EMA(dataframe['close'], timeperiod=3)
dataframe['trend_close_30m'] = ta.EMA(dataframe['close'], timeperiod=6)
dataframe['trend_close_1h'] = ta.EMA(dataframe['close'], timeperiod=12)
dataframe['trend_close_2h'] = ta.EMA(dataframe['close'], timeperiod=24)
dataframe['trend_close_4h'] = ta.EMA(dataframe['close'], timeperiod=48)
dataframe['trend_close_6h'] = ta.EMA(dataframe['close'], timeperiod=72)
dataframe['trend_close_8h'] = ta.EMA(dataframe['close'], timeperiod=96)
dataframe['trend_open_5m'] = dataframe['open']
dataframe['trend_open_15m'] = ta.EMA(dataframe['open'], timeperiod=3)
dataframe['trend_open_30m'] = ta.EMA(dataframe['open'], timeperiod=6)
dataframe['trend_open_1h'] = ta.EMA(dataframe['open'], timeperiod=12)
dataframe['trend_open_2h'] = ta.EMA(dataframe['open'], timeperiod=24)
dataframe['trend_open_4h'] = ta.EMA(dataframe['open'], timeperiod=48)
dataframe['trend_open_6h'] = ta.EMA(dataframe['open'], timeperiod=72)
dataframe['trend_open_8h'] = ta.EMA(dataframe['open'], timeperiod=96)
dataframe['fan_magnitude'] = (dataframe['trend_close_1h'] / dataframe['trend_close_8h'])
dataframe['fan_magnitude_gain'] = dataframe['fan_magnitude'] / dataframe['fan_magnitude'].shift(1)
ichimoku = ftt.ichimoku(dataframe, conversion_line_period=20, base_line_periods=60, laggin_span=120, displacement=30)
dataframe['chikou_span'] = ichimoku['chikou_span']
dataframe['tenkan_sen'] = ichimoku['tenkan_sen']
dataframe['kijun_sen'] = ichimoku['kijun_sen']
dataframe['senkou_a'] = ichimoku['senkou_span_a']
dataframe['senkou_b'] = ichimoku['senkou_span_b']
dataframe['leading_senkou_span_a'] = ichimoku['leading_senkou_span_a']
dataframe['leading_senkou_span_b'] = ichimoku['leading_senkou_span_b']
dataframe['cloud_green'] = ichimoku['cloud_green']
dataframe['cloud_red'] = ichimoku['cloud_red']
dataframe['atr'] = ta.ATR(dataframe)
# MFI
dataframe['mfi'] = ta.MFI(dataframe)
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.informative_timeframe, ffill=True)
# The indicators for the normal (5m) timeframe
dataframe = self.normal_tf_indicators(dataframe, metadata)
#Import 15m indicators
informative_15m = self.informative_15m_indicators(dataframe, metadata)
dataframe = merge_informative_pair(dataframe, informative_15m, self.timeframe, self.inf_15m, ffill=True)
drop_columns = [(s + "_" + self.inf_15m) for s in ['date']]
dataframe.drop(columns=dataframe.columns.intersection(drop_columns), inplace=True)
#Pump protection
dataframe['weekly_close_avg_offset'] = self.pump_recorver_price.value * dataframe['weekly_close_avg_1h']
dataframe['price_test'] = dataframe['close'] > dataframe['weekly_close_avg_offset']
dataframe['pump_price_test'] = dataframe['max_flow_price_15m'] > self.pump_limit.value
# Check if a pump uccured during pump_pause_duration and coin didn't recovered its pre pump value
dataframe['pump_dump_alert'] = dataframe['price_test'] & dataframe['pump_price_test']
dataframe['buy_ok'] = np.where(dataframe['pump_dump_alert'], False, True)
return dataframe
## Confirm Entry
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float, time_in_force: str, **kwargs) -> bool:
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
max_slip = self.max_slip.value
if(len(dataframe) < 1):
return False
dataframe = dataframe.iloc[-1].squeeze()
if ((rate > dataframe['close'])) :
slippage = ( (rate / dataframe['close']) - 1 ) * 100
if slippage < max_slip:
return True
else:
return False
return True
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = []
dataframe.loc[:, 'buy_tag'] = ''
is_protection = (
(pct_change(dataframe['btc_1d'], dataframe['btc_5m']).fillna(0) > self.buy_btc_safe_1d.value) &
(dataframe['pump_strength_2'] < self.antipump_threshold_2.value)&
(dataframe['buy_ok'])&
(dataframe['volume'] > 0)
)
if self.buy_params['tesla_enabled'] >= True:
tesla = (
(dataframe['rsi'] > dataframe['rsi_1h']) &
(dataframe['trend_close_8h'] > dataframe['trend_close_6h'])&
(dataframe['trend_close_15m'] > dataframe['trend_close_30m'])&
(dataframe['trend_open_5m'] > dataframe['trend_open_15m'])&
(dataframe['trend_close_1h']> dataframe['ema55'])&
(dataframe['ema21']> dataframe['trend_close_4h'])&
(dataframe['trend_open_1h'] > dataframe['trend_open_2h'])&
(dataframe['mfi'] < 70)&
(dataframe['fan_magnitude_gain'] >= self.buy_min_fan_magnitude_gain.value) &
(dataframe['fan_magnitude'] > 0.99)
)
conditions.append(tesla)
dataframe.loc[tesla, 'buy_tag'] += 'tesla_'
if conditions:
dataframe.loc[
is_protection &
reduce(lambda x, y: x & y, conditions),
'buy'] = 1
return dataframe
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = []
conditions.append(qtpylib.crossed_below(dataframe['trend_close_5m'], dataframe[self.sell_params['sell_trend_indicator']]))
if conditions:
dataframe.loc[
reduce(lambda x, y: x & y, conditions),
'sell'] = 1
return dataframe
def rollingNormalize(self, dataframe, name):
df = dataframe.copy()
df[name + '_nmin'] = df[name].rolling(window=1440 // self.timeframe_minutes).min()
df[name + '_nmax'] = df[name].rolling(window=1440 // self.timeframe_minutes).max()
return np.where(df[name + '_nmin'] == df[name + '_nmax'], 0, (2.0*(df[name]-df[name + '_nmin'])/(df[name + '_nmax']-df[name + '_nmin'])-1.0))
def normalize(data, min_value, max_value):
return (data - min_value) / (max_value - min_value)
def pct_change(a, b):
return (b - a) / a
# smoothed Heiken Ashi
def HA(dataframe, smoothing=None):
df = dataframe.copy()
df['HA_Close']=(df['open'] + df['high'] + df['low'] + df['close'])/4
df.reset_index(inplace=True)
ha_open = [ (df['open'][0] + df['close'][0]) / 2 ]
[ ha_open.append((ha_open[i] + df['HA_Close'].values[i]) / 2) for i in range(0, len(df)-1) ]
df['HA_Open'] = ha_open
df.set_index('index', inplace=True)
df['HA_High']=df[['HA_Open','HA_Close','high']].max(axis=1)
df['HA_Low']=df[['HA_Open','HA_Close','low']].min(axis=1)
if smoothing is not None:
sml = abs(int(smoothing))
if sml > 0:
df['Smooth_HA_O']=ta.EMA(df['HA_Open'], sml)
df['Smooth_HA_C']=ta.EMA(df['HA_Close'], sml)
df['Smooth_HA_H']=ta.EMA(df['HA_High'], sml)
df['Smooth_HA_L']=ta.EMA(df['HA_Low'], sml)
return df
def pump_warning(dataframe, perc=15):
df = dataframe.copy()
df["change"] = df["high"] - df["low"]
df["test1"] = (df["close"] > df["open"])
df["test2"] = ((df["change"]/df["low"]) > (perc/100))
df["result"] = (df["test1"] & df["test2"]).astype('int')
return df['result']