┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ Drawdown ┃ ┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩ │ Empty │ 49 │ 2.64 │ 680.535 │ 68.05 │ 14 days, 0:38:00 │ 44 0 5 89.8 │ 629.763 USDT 27.26% │ └──────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┴──────────────────────┘
This commit is contained in:
117
Empty.py
117
Empty.py
@@ -266,7 +266,7 @@ class Empty(IStrategy):
|
||||
# trailing_only_offset_is_reached = False
|
||||
|
||||
position_adjustment_enable = True
|
||||
use_custom_stoploss = False
|
||||
use_custom_stoploss = True
|
||||
|
||||
#max_open_trades = 3
|
||||
|
||||
@@ -385,9 +385,11 @@ class Empty(IStrategy):
|
||||
|
||||
sell_score_indicator = CategoricalParameter(score_indicators, default="sma24_score", space='sell')
|
||||
|
||||
stoploss_indicator = CategoricalParameter(stoploss_indicators, default="stop_buying12_1d", space='protection')
|
||||
range_pos_stoploss = DecimalParameter(0, 0.1, decimals=2, default=0.05, space='protection')
|
||||
stoploss_force = DecimalParameter(-0.2, 0, decimals=2, default=-0.05, space='protection')
|
||||
stoploss_indicator = CategoricalParameter(god_genes_with_timeperiod, default="stop_buying12_1d", space='protection')
|
||||
stop_buying_indicator = CategoricalParameter(stoploss_indicators, default="stop_buying12_1d", space='protection')
|
||||
stoploss_timeperiod = CategoricalParameter(timeperiods, default="12", space='protection')
|
||||
# stoploss_timeperiod = CategoricalParameter(timeperiods, default="12", space='protection')
|
||||
|
||||
def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float,
|
||||
proposed_stake: float, min_stake: float, max_stake: float,
|
||||
@@ -409,8 +411,8 @@ class Empty(IStrategy):
|
||||
# range_pos = (last_candle['close'] - range_min) / (range_max - range_min)
|
||||
|
||||
range_pos = last_candle[f"range_pos"]
|
||||
sl_min = self.wallets.get_available_stake_amount() / 2
|
||||
sl_max = self.wallets.get_available_stake_amount() / 6
|
||||
sl_min = self.wallets.get_available_stake_amount() / 6
|
||||
sl_max = self.wallets.get_available_stake_amount() / 2
|
||||
|
||||
amount = sl_min + (1 - range_pos) * (sl_max - sl_min)
|
||||
# amount = self.wallets.get_available_stake_amount() / 8
|
||||
@@ -470,13 +472,18 @@ class Empty(IStrategy):
|
||||
last_buy = max(filled_buys, key=lambda o: o.order_date)
|
||||
last_entry_price = last_buy.price
|
||||
|
||||
drop_from_last_entry = (current_rate - last_entry_price) / last_entry_price
|
||||
if last_entry_price:
|
||||
drop_from_last_entry = (current_rate - last_entry_price) / last_entry_price
|
||||
|
||||
if drop_from_last_entry <= -0.025 and last_candle['min60'] == last_candle_3['min60']:
|
||||
# stake_amount = trade.stake_amount
|
||||
print(f"adjust {current_time} {stake_amount}")
|
||||
print(f"adjust {pair} {current_time} dispo={dispo} amount={stake_amount} rate={current_rate}")
|
||||
return stake_amount
|
||||
if drop_from_last_entry <= -0.025 and last_candle['min60'] == last_candle_3['min60'] \
|
||||
and last_candle[self.stop_buying_indicator.value] == False\
|
||||
and ((last_candle['stop_buying5_1d'] == False) or (last_candle['range_pos'] < 0)) \
|
||||
and last_candle['range_pos'] <= -0.01:
|
||||
# stake_amount = trade.stake_amount
|
||||
self.pairs[trade.pair]['last_buy'] = current_rate
|
||||
print(f"adjust {current_time} {stake_amount}")
|
||||
print(f"adjust {pair} {current_time} dispo={dispo} amount={stake_amount} rate={current_rate}")
|
||||
return stake_amount
|
||||
|
||||
return None
|
||||
|
||||
@@ -494,7 +501,8 @@ class Empty(IStrategy):
|
||||
|
||||
condition = True
|
||||
|
||||
if self.pairs[pair]['last_trade'] and self.pairs[pair]['last_trade'].close_date:
|
||||
|
||||
if False and self.pairs[pair]['last_trade'].close_date is not None:
|
||||
# base cooldown = n bougies / cooldown proportionnel au profit
|
||||
# bougies de plus par %
|
||||
cooldown_candles = 12 + 6 * (int(self.pairs[pair]['last_profit'] / 0.01)) # réglable
|
||||
@@ -504,7 +512,7 @@ class Empty(IStrategy):
|
||||
|
||||
condition = (candles_since_close >= cooldown_candles)
|
||||
|
||||
print(f"Cool down {round(self.pairs[pair]['last_profit'], 3)} {cooldown_candles} {candles_since_close}")
|
||||
print(f"Cool close date = trade={self.pairs[pair]['last_trade'].close_date} down {round(self.pairs[pair]['last_profit'], 3)} {cooldown_candles} {candles_since_close}")
|
||||
|
||||
# self.should_enter_trade(pair, last_candle, current_time)
|
||||
allow_to_buy = (condition and not self.pairs[pair]['stop']) | (entry_tag == 'force_entry')
|
||||
@@ -530,6 +538,7 @@ class Empty(IStrategy):
|
||||
self.pairs[pair]['last_min'] = min(last_candle['close'], self.pairs[pair]['last_min'])
|
||||
self.pairs[pair]['last_date'] = current_time
|
||||
|
||||
|
||||
dispo = round(self.wallets.get_available_stake_amount())
|
||||
# self.printLineLog()
|
||||
|
||||
@@ -563,7 +572,7 @@ class Empty(IStrategy):
|
||||
|
||||
profit = trade.calc_profit(rate)
|
||||
force = self.pairs[pair]['force_sell']
|
||||
allow_to_sell = (last_candle['hapercent'] < 0 and profit > 0) or force or (exit_reason == 'force_exit') or (exit_reason == 'stop_loss') or (exit_reason == 'trailing_stop_loss')
|
||||
allow_to_sell = (last_candle['hapercent'] < 0 and profit > 0) or force or (exit_reason == 'god') or (exit_reason == 'force_exit') or (exit_reason == 'stop_loss') or (exit_reason == 'trailing_stop_loss')
|
||||
|
||||
minutes = int(round((current_time - trade.date_last_filled_utc).total_seconds() / 60, 0))
|
||||
|
||||
@@ -594,7 +603,7 @@ class Empty(IStrategy):
|
||||
self.pairs[pair]['max_touch'] = 0
|
||||
self.pairs[pair]['last_buy'] = 0
|
||||
self.pairs[pair]['last_date'] = current_time
|
||||
self.pairs[pair]['last_trade'] = self.pairs[pair]['current_trade']
|
||||
self.pairs[pair]['last_trade'] = trade
|
||||
self.pairs[pair]['current_trade'] = None
|
||||
else:
|
||||
print(f"{current_time} STOP triggered for {pair} ({exit_reason}) but condition blocked", "warning")
|
||||
@@ -620,36 +629,41 @@ class Empty(IStrategy):
|
||||
|
||||
return None
|
||||
|
||||
# def custom_stoploss(self, pair, trade, current_time, current_rate, current_profit, **kwargs):
|
||||
# dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
||||
# last_candle = dataframe.iloc[-1]
|
||||
# profit = trade.calc_profit(current_rate)
|
||||
#
|
||||
# # print(f'test stop loss {self.stoploss} {last_candle["stop_buying12_1d"]}')
|
||||
# if last_candle[self.stoploss_indicator.value] and (trade.nr_of_successful_entries >= 4 or self.wallets.get_available_stake_amount() < 300): # and profit < - 30 :
|
||||
# range_min = last_candle[f"min{self.stoploss_timeperiod.value}_1d"]
|
||||
# range_max = last_candle[f"max{self.stoploss_timeperiod.value}_1d"]
|
||||
#
|
||||
# if range_max == range_min:
|
||||
# print(f'ranges={range_min}')
|
||||
# return -0.1 # sécurité
|
||||
#
|
||||
# range_pos = (current_rate - range_min) / (range_max - range_min)
|
||||
#
|
||||
# if (range_pos > 1):
|
||||
# return -1
|
||||
#
|
||||
# sl_min = -0.02
|
||||
# sl_max = -0.1 #self.stoploss
|
||||
#
|
||||
# dynamic_sl = (sl_min + (1 - range_pos) * (sl_max - sl_min))
|
||||
#
|
||||
# print(f'{current_time} Loss ranges={round(range_min,0)} {round(range_max, 0)} range_pos={round(range_pos, 3)} dynamic_sl={round(dynamic_sl, 3)} '
|
||||
# f'profit={profit} current={current_profit} {self.stoploss_indicator.value} {self.stoploss_timeperiod.value} {last_candle[self.stoploss_indicator.value]}')
|
||||
#
|
||||
# return dynamic_sl
|
||||
#
|
||||
# return -1
|
||||
def custom_stoploss(self, pair, trade, current_time, current_rate, current_profit, **kwargs):
|
||||
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
||||
last_candle = dataframe.iloc[-1]
|
||||
profit = trade.calc_profit(current_rate)
|
||||
|
||||
candle_at_buy = self.pairs[pair]['last_candle']
|
||||
|
||||
if candle_at_buy['range_pos'] > self.range_pos_stoploss.value and candle_at_buy[self.stoploss_indicator.value] < 0:
|
||||
return self.stoploss_force.value
|
||||
|
||||
# # print(f'test stop loss {self.stoploss} {last_candle["stop_buying12_1d"]}')
|
||||
# if last_candle[self.stoploss_indicator.value] and (trade.nr_of_successful_entries >= 4 or self.wallets.get_available_stake_amount() < 300): # and profit < - 30 :
|
||||
# range_min = last_candle[f"min{self.stoploss_timeperiod.value}_1d"]
|
||||
# range_max = last_candle[f"max{self.stoploss_timeperiod.value}_1d"]
|
||||
#
|
||||
# if range_max == range_min:
|
||||
# print(f'ranges={range_min}')
|
||||
# return -0.1 # sécurité
|
||||
#
|
||||
# range_pos = (current_rate - range_min) / (range_max - range_min)
|
||||
#
|
||||
# if (range_pos > 1):
|
||||
# return -1
|
||||
#
|
||||
# sl_min = -0.02
|
||||
# sl_max = -0.1 #self.stoploss
|
||||
#
|
||||
# dynamic_sl = (sl_min + (1 - range_pos) * (sl_max - sl_min))
|
||||
#
|
||||
# print(f'{current_time} Loss ranges={round(range_min,0)} {round(range_max, 0)} range_pos={round(range_pos, 3)} dynamic_sl={round(dynamic_sl, 3)} '
|
||||
# f'profit={profit} current={current_profit} {self.stoploss_indicator.value} {self.stoploss_timeperiod.value} {last_candle[self.stoploss_indicator.value]}')
|
||||
#
|
||||
# return dynamic_sl
|
||||
|
||||
return -1
|
||||
|
||||
def informative_pairs(self):
|
||||
# get access to all pairs available in whitelist.
|
||||
@@ -725,7 +739,7 @@ class Empty(IStrategy):
|
||||
range_min = dataframe[f"min12_1d"]
|
||||
range_max = dataframe[f"max48"]
|
||||
|
||||
dataframe[f"range_pos"] = (dataframe['close'] - range_min) / (range_max - range_min)
|
||||
dataframe[f"range_pos"] = ((dataframe['mid'] - range_min) / (range_max)).rolling(5).mean()
|
||||
|
||||
|
||||
# récupérer le dernier trade fermé
|
||||
@@ -791,11 +805,11 @@ class Empty(IStrategy):
|
||||
# buy_real_num
|
||||
# )
|
||||
# conditions.append(condition)
|
||||
conditions.append((dataframe[self.stop_buying_indicator.value] == False))
|
||||
conditions.append((dataframe[self.stop_buying_indicator.value] == False) | (dataframe['range_pos'] < 0))
|
||||
|
||||
# conditions.append(dataframe['hapercent'] > 0)
|
||||
conditions.append(dataframe['hapercent'] > 0)
|
||||
# # conditions.append(dataframe[f"range_pos"] <= 0.5)
|
||||
# conditions.append(dataframe[f"sma5_deriv1"] > 0)
|
||||
# conditions.append((dataframe[f"range_pos"] < 0.01) | ((dataframe[f"sma5_deriv1"] > 0) & (dataframe[f"sma12_deriv1"] > 0) & (dataframe[f"sma24_deriv1"] > 0)))
|
||||
|
||||
print(f"BUY indicators tested \n"
|
||||
f"{self.buy_indicator0.value} {self.buy_crossed_indicator0.value} {self.buy_operator0.value} {self.buy_real_num0.value} \n"
|
||||
@@ -812,7 +826,7 @@ class Empty(IStrategy):
|
||||
return dataframe
|
||||
|
||||
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
# conditions = list()
|
||||
conditions = list()
|
||||
# # TODO: Its not dry code!
|
||||
# sell_indicator = self.sell_indicator0.value
|
||||
# sell_crossed_indicator = self.sell_crossed_indicator0.value
|
||||
@@ -861,6 +875,9 @@ class Empty(IStrategy):
|
||||
# )
|
||||
#
|
||||
#
|
||||
# conditions.append(qtpylib.crossed_below(dataframe['mid'], dataframe['sma24']))
|
||||
# conditions.append((dataframe['range_pos'] > 0.04))
|
||||
#
|
||||
# if conditions:
|
||||
# dataframe.loc[reduce(lambda x, y: x & y, conditions), ['exit_long', 'exit_tag']] = (1, 'god')
|
||||
return dataframe
|
||||
|
||||
Reference in New Issue
Block a user