┏━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┓

┃   Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃    Avg Duration ┃  Win  Draw  Loss  Win% ┃           Drawdown ┃
┡━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━┩
│ EmptyShort │     34 │         1.08 │         379.432 │        37.94 │ 1 day, 10:30:00 │   18     0    16  52.9 │ 81.299 USDT  6.08% │
└────────────┴────────┴──────────────┴─────────────────┴──────────────┴─────────────────┴────────────────────────┴────────────────────┘
This commit is contained in:
Jérôme Delacotte
2026-03-29 18:16:38 +02:00
parent 8b030f46f0
commit a599160501
2 changed files with 273 additions and 315 deletions

View File

@@ -373,24 +373,25 @@ class EmptyShort(IStrategy):
last_candle_2 = dataframe.iloc[-2].squeeze()
last_candle_3 = dataframe.iloc[-3].squeeze()
if entry_tag == 'Range-':
self.pairs[pair]['count_of_lost'] = 0
if entry_tag == 'Force':
if self.pairs[pair]['count_of_lost'] >= 1:
self.pairs[pair]['count_of_lost'] = 0
condition = False
else:
condition = False if self.pairs[pair]['count_of_lost'] >= 1 \
and (last_candle['sma12_deriv1_1h'] < 0.00) \
and entry_tag != 'dist' else True
reason = ''
if not condition:
reason = 'lost'
if condition:
if last_candle['range_pos'] > 0.05:# and self.pairs[pair]['force_stop']:
condition = last_candle['sma5'] > last_candle['sma60']
if not condition:
reason = 'range'
condition = True
# if entry_tag == 'Range-':
# self.pairs[pair]['count_of_lost'] = 0
# if entry_tag == 'Force':
# if self.pairs[pair]['count_of_lost'] >= 1:
# self.pairs[pair]['count_of_lost'] = 0
# condition = False
# else:
# condition = False if self.pairs[pair]['count_of_lost'] >= 1 \
# and (last_candle['sma12_deriv1_1h'] < 0.00) \
# and entry_tag != 'dist' else True
# reason = ''
# if not condition:
# reason = 'lost'
# if condition:
# if last_candle['range_pos'] > 0.05:# and self.pairs[pair]['force_stop']:
# condition = last_candle['sma5'] > last_candle['sma60']
# if not condition:
# reason = 'range'
# if self.pairs[pair]['force_stop'] and last_candle['range_pos'] < 0.02:
# self.pairs[pair]['force_stop'] = False
@@ -563,17 +564,17 @@ class EmptyShort(IStrategy):
is_short = (trade.enter_tag == 'short')
if trade.enter_tag == 'short':
tp_price = self.pairs[pair]['take_profit']
tp_price = max(0.02, self.pairs[pair]['take_profit'])
# if current_profit < self.sell_force_sell.value \
# and last_candle[f"close"] > last_candle[self.sell_indicator.value]:
# self.pairs[pair]['force_sell'] = True
# return 'sma'
#
# if current_profit > tp_price and \
# (baisse > self.baisse.value and last_candle[f"close"] > last_candle[self.b30_indicateur.value]) \
# and last_candle['hapercent'] > 0:
# self.pairs[pair]['force_sell'] = True
# return 'B30Sht'
if current_profit > tp_price and \
(baisse > last_candle[f"range_pos"] and last_candle[f"close"] > last_candle[self.b30_indicateur.value]) \
and last_candle['hapercent'] > 0 and last_candle['sma12_deriv1_1h'] > -0.004:
self.pairs[pair]['force_sell'] = True
return 'B30Sht'
return None
# self.log_trade(
@@ -598,12 +599,12 @@ class EmptyShort(IStrategy):
# and last_candle[f"close"] <= last_candle[self.sell_indicator.value]:
# self.pairs[pair]['force_sell'] = True
# return 'sma'
if current_profit > 0.00 and \
(baisse > self.baisse.value and last_candle[f"close"] <= last_candle[self.b30_indicateur.value]) \
and last_candle['hapercent'] <0 :
if current_profit > 0.01:
self.pairs[pair]['force_buy'] = True
tp_price = max(0.02, self.pairs[pair]['take_profit'])
if current_profit > tp_price and \
(baisse > min(last_candle[f"range_pos"], 0.5) and last_candle[f"close"] <= last_candle[self.b30_indicateur.value]) \
and last_candle['hapercent'] <0 and last_candle['sma12_deriv1_1h'] < 0.004:
# if current_profit > 0.01:
# self.pairs[pair]['force_buy'] = True
self.pairs[pair]['force_sell'] = True
return 'B30'
@@ -611,9 +612,9 @@ class EmptyShort(IStrategy):
# self.pairs[pair]['force_sell'] = True
# return 'B50'
if current_profit > - self.sell_force_sell.value and last_candle['has_cross_sma3_1h'] == 1:
self.pairs[pair]['force_sell'] = True
return 'Cross'
# if current_profit > - self.sell_force_sell.value and last_candle['has_cross_sma3_1h'] == 1:
# self.pairs[pair]['force_sell'] = True
# return 'Cross'
# if profit > max(5, expected_profit) and last_candle['sma5_deriv1_1h'] < 0 and baisse > 0.15:
# self.pairs[pair]['force_sell'] = True
@@ -844,6 +845,8 @@ class EmptyShort(IStrategy):
range_max = dataframe[f"max12_1d"]
dataframe[f"range_pos"] = ((dataframe['mid'] - range_min) / (range_max - range_min)) #.rolling(5).mean()
dataframe['min_max_12_1d'] = ((range_max - dataframe['close']) / range_min)
dataframe['pct_min_max_12_1d'] = ((range_max - range_min) / range_min)
# dataframe['cross_sma60'] = qtpylib.crossed_below(dataframe[self.sell_sma_indicators.value], dataframe[self.sell_crossed_sma_indicators.value])
@@ -875,310 +878,82 @@ class EmptyShort(IStrategy):
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
pair = metadata['pair']
conditions = list()
# #####################################################################################
# CA MONTE !!
# #####################################################################################
# conditions.append(dataframe[f"{self.start_bull_indicator.value}_deriv1_1h" ] > self.start_bull_deriv1.value)
# conditions.append(dataframe[f"{self.start_bull_indicator.value}_deriv2_1h"] > self.start_bull_deriv2.value)
# conditions.append(dataframe['sma12_deriv1'] > self.buy_deriv1_sma60.value)
# conditions.append(dataframe['sma5_deriv1_1h'] > self.buy_deriv1_sma5d.value)
# conditions.append(dataframe['sma12_deriv1_1h'] > self.buy_deriv1_sma12d.value)
# conditions.append(dataframe['sma36_deriv2'] > self.buy_deriv2_sma60.value)
# conditions.append(dataframe['sma5_deriv2_1h'] > self.buy_deriv2_sma5d.value)
# conditions.append(dataframe['sma12_deriv2_1h'] > self.buy_deriv2_sma12d.value)
conditions.append(dataframe['hapercent'] > 0)
# conditions.append(dataframe['percent12'] < 0.01)
# conditions.append(dataframe['percent5'] < 0.01)
# conditions.append(dataframe['max_rsi_24'] < 80)
# dynamic_rsi_threshold = 70 + 15 * np.tanh(dataframe["dist_sma200_1h"] * 5)
# conditions.append((dataframe['max_rsi_12_1h'] < dynamic_rsi_threshold))
# conditions.append(dataframe[f"close"] > dataframe['sma60'])
# conditions.append(((dataframe[f"range_pos"] < 0.05) ) | ((dataframe['sma12_deriv1'] > 0) & (dataframe['sma12_deriv2'] > 0)))
#
# conditions.append(
# (dataframe['close_1h'] > dataframe[f'sma{self.buy_longue.value}_1h'])
# | (dataframe['sma60_inv_1h'] == -1)
# )
# if conditions:
# dataframe.loc[
# reduce(lambda x, y: x & y, conditions),
# ['enter_long', 'enter_tag']
# ] = (1, 'bull')
# #####################################################################################
# conditions = list()
# conditions.append(dataframe['dist_sma200_1h'] < -0.05)
# conditions.append(dataframe['sma12_inv'] == 1)
# # conditions.append(dataframe['sma100_deriv1_1h'] > 0)
# if conditions:
# dataframe.loc[
# reduce(lambda x, y: x & y, conditions),
# ['enter_long', 'enter_tag']
# ] = (1, 'dist')
# #####################################################################################
# conditions = list()
# conditions.append(dataframe['close'] < dataframe['sma100_1h'])
# conditions.append(dataframe['mid_smooth12'] > dataframe['mid_smooth12'].shift(1))
# conditions.append(dataframe['sma100_deriv1_1h'] > 0)
# conditions.append(dataframe[f"range_pos"] < 0.01)
# if conditions:
# dataframe.loc[
# reduce(lambda x, y: x & y, conditions),
# ['enter_long', 'enter_tag']
# ] = (1, 'dist')
# #####################################################################################
# CA BAISSE !!
# "buy": {
# "buy_deriv1_sma12d": 0.0,
# "buy_deriv1_sma5d": 0.0,
# "buy_deriv1_sma60": 0.003,
# "buy_deriv2_sma12d": -0.03,
# "buy_deriv2_sma5d": 0.0,
# "buy_deriv2_sma60": -0.002,
# "buy_longue": 200,
# "buy_longue_derive": "sma160_deriv1_1h"
# },
# "protection": {
# "drop_from_last_entry": -0.03,
# "b30_indicateur": "sma3",
# "baisse": 0.31
# },
# #####################################################################################
conditions = list()
# conditions.append(dataframe[f"{self.start_bull_indicator.value}_deriv1_1h" ] < self.start_bull_deriv1.value)
# conditions.append(dataframe[f"{self.start_bull_indicator.value}_deriv2_1h"] < self.start_bull_deriv2.value)
# conditions.append(dataframe[f"{self.start_bear_indicator.value}_deriv1_1h" ] > self.start_bear_deriv1.value)
# conditions.append(dataframe[f"{self.start_bear_indicator.value}_deriv2_1h"] > self.start_bear_deriv2.value)
# conditions.append(dataframe['sma12_deriv1'] > self.buy_deriv1_sma60.value)
# conditions.append(dataframe['sma5_deriv1_1h'] > self.buy_deriv1_sma5d.value)
# conditions.append(dataframe['sma12_deriv1_1h'] > self.buy_deriv1_sma12d.value)
#
# # conditions.append(dataframe['sma12_deriv2'] > -0.002)
# # conditions.append(dataframe['sma5_deriv2_1h'] > 0)
# # conditions.append(dataframe['sma12_deriv2_1h'] > -0.03)
#
# conditions.append(dataframe['hapercent'] > 0)
# # conditions.append(dataframe['percent12'] < 0.01)
# # conditions.append(dataframe['percent5'] < 0.01)
# conditions.append(dataframe['max_rsi_24'] < 80)
#
# dynamic_rsi_threshold = 70 + 15 * np.tanh(dataframe["dist_sma200_1h"] * 5)
# conditions.append((dataframe['max_rsi_12_1h'] < dynamic_rsi_threshold))
# conditions.append(dataframe[f"close"] > dataframe['sma60'])
# conditions.append(((dataframe[f"range_pos"] < 0.05) ) | ((dataframe['sma12_deriv1'] > 0) & (dataframe['sma12_deriv2'] > 0)))
#
# conditions.append(
# (dataframe['close_1h'] > dataframe[f'sma{self.buy_longue.value}_1h'])
# | (dataframe['sma60_inv_1h'] == -1)
# )
# if conditions:
# dataframe.loc[
# reduce(lambda x, y: x & y, conditions),
# ['enter_long', 'enter_tag']
# ] = (1, 'bear')
# conditions = list()
# conditions.append(dataframe['close_1h'] < dataframe[f'sma{self.buy_longue.value}_1h'])
# conditions.append(dataframe['has_cross_min'].rolling(6).max() == 1)
# conditions.append(dataframe['mid_smooth5'] > dataframe['mid_smooth5'].shift(1))
# conditions.append(dataframe['hapercent'] > 0)
# conditions.append(dataframe['percent5'] < 0.01)
# dataframe.loc[
# reduce(lambda x, y: x & y, conditions),
# ['enter_long', 'enter_tag']
# ] = (1, 'cross_min')
# conditions = list()
# conditions.append(dataframe['sma12_deriv1'] > 0.00)
# conditions.append(dataframe['sma60_deriv1'] > 0.0)
# conditions.append(dataframe['sma5_deriv1_1h'] > 0.0)
# conditions.append(dataframe['sma12_deriv1_1h'] > 0.0)
# conditions.append(dataframe['sma24_deriv1_1h'] > 0.0)
# conditions.append(dataframe['sma100_deriv1_1h'] > 0.0)
# conditions.append(dataframe[f"range_pos"] < 0.025)
# conditions.append(dataframe['sma12_deriv1_1h'] > 0.0)
# # conditions.append(dataframe['close_1h'] < dataframe[f'sma{self.buy_longue.value}_1h'])
# # conditions.append(dataframe['has_cross_min'].rolling(6).max() == 1)
# # conditions.append(dataframe['mid_smooth5'] > dataframe['mid_smooth5'].shift(1))
# conditions.append(dataframe['min12'] == dataframe['min12'].shift(3))
# conditions.append((dataframe['percent24'] < -0.025) | (dataframe['percent12'] < -0.025))
# dataframe.loc[
# reduce(lambda x, y: x & y, conditions),
# ['enter_long', 'enter_tag']
# ] = (1, 'Rise')
# conditions = list()
# conditions.append(dataframe['has_cross_min_6'] == True)
# conditions.append(dataframe['min36'] == dataframe['min36'].shift(3))
# dataframe.loc[
# reduce(lambda x, y: x & y, conditions),
# ['enter_long', 'enter_tag']
# ] = (1, 'Force')
conditions = list()
# conditions.append(dataframe['mid_regression'].shift(2) > dataframe['mid_regression'].shift(1))
# conditions.append(dataframe['mid_regression'].shift(1) < dataframe['mid_regression'])
conditions.append(dataframe['close'] <= dataframe['min12_1h'])
conditions.append(dataframe['min60'] == dataframe['min60'].shift(5))
conditions.append(dataframe['has_cross_min_6'] == 1)
conditions.append(dataframe['down_count'] <= 5)
conditions.append(dataframe['down_count'] <= 5)
# conditions.append(dataframe['sma12_deriv1'] >= 0)
# dataframe.loc[
# reduce(lambda x, y: x & y, conditions),
# ['enter_long', 'enter_tag']
# ] = (1, 'Mid')
dataframe.loc[
(
# (qtpylib.crossed_above(dataframe['sma60'], dataframe['mid_regression_1h']))
(dataframe['sma12_1h'] > dataframe['sma12_1h'].shift(61))
& (dataframe['range_pos'] < 0.05)
& (dataframe['close'] < dataframe['close_1d'])
& (dataframe['close'] < dataframe['close_1h'])
(dataframe['sma12_deriv1_1h'] > 0)
& (dataframe['max_rsi_12'] < 70)
& (dataframe['max_rsi_12_1h'] < 70)
& (dataframe['range_pos'] < 1)
& (dataframe['hapercent'] > 0)
& (dataframe['pct_min_max_12_1d'] < 0.04)
),
['enter_long', 'enter_tag']
] = (1, 'long')
dataframe.loc[
(
# (qtpylib.crossed_below(
# dataframe['sma60'],
# dataframe['mid_regression_1h'])
# ) &
(
# (dataframe['close'] > dataframe['max5_1h'])
# & (dataframe['sma12'] < dataframe['sma12'].shift(1))
# # & (dataframe['sma120_inv'] == 1)
# & (dataframe['close'] > dataframe['close_1h'])
# & (dataframe['close'] > dataframe['close_1d'])
# (dataframe['rsi_1h'] >= 65)
# & (dataframe['max_rsi_12_1h'] == dataframe['rsi_1h'])
# & (dataframe['hapercent'] < 0)
#
(dataframe['sma12_1h'] < dataframe['sma12_1h'].shift(61))
& (dataframe['range_pos'] > 0.05)
& (dataframe['close'] > dataframe['close_1d'])
& (dataframe['close'] > dataframe['close_1h'])
(dataframe['sma12_deriv1_1h'] < -0.0005)
& (dataframe['max_rsi_12'] < 60)
& (
(
(dataframe['max_rsi_24_1h'] > 60) & (dataframe['range_pos'] > 0.8)
| (dataframe['sma12_deriv1_1d'] < -0.01)
)
)
& (dataframe['hapercent'] < 0)
# & (dataframe['pct_min_max_12_1d'] > 0.04)
),
['enter_short', 'enter_tag']
] = (1, 'short')
# dataframe.loc[
# (
# (dataframe['close'] >= dataframe['max5_1h'])
# & (dataframe['close'] >= dataframe['max12_1d'])
# & (dataframe['sma12_1h'] <= dataframe['max12_1d'])
# & (dataframe['mid_1h'] <= dataframe['mid_1h'].shift(61))
# & (dataframe['hapercent'] < 0)
# # & (dataframe['sma60'] < dataframe['sma60'].shift(1))
# ),
# ['enter_short', 'enter_tag']
# ] = (1, 'short')
dataframe['short'] = np.where(dataframe['enter_short'] == 1, dataframe['close'] * 0.99, np.nan)
dataframe['long'] = np.where(dataframe['enter_long'] == 1, dataframe['close'] * 1.01, np.nan)
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = list()
# # TODO: Its not dry code!
# sell_indicator = self.sell_indicator0.value
# sell_crossed_indicator = self.sell_crossed_indicator0.value
# sell_operator = self.sell_operator0.value
# sell_real_num = self.sell_real_num0.value
# condition, dataframe = condition_generator(
# dataframe,
# sell_operator,
# sell_indicator,
# sell_crossed_indicator,
# sell_real_num
# )
# conditions.append(condition)
# conditions = list()
# dataframe.loc[
# (
# # (qtpylib.crossed_above(
# # dataframe['sma'],
# # dataframe['mid_regression_1h'])
# # )
# # (dataframe['sma12_1h'] < dataframe['sma12_1h'].shift(61))
# # & (dataframe['range_pos'] > 0.5)
# # & (dataframe['close'] > dataframe['close_1d'])
# # & (dataframe['close'] > dataframe['close_1h'])
#
# sell_indicator = self.sell_indicator1.value
# sell_crossed_indicator = self.sell_crossed_indicator1.value
# sell_operator = self.sell_operator1.value
# sell_real_num = self.sell_real_num1.value
# condition, dataframe = condition_generator(
# dataframe,
# sell_operator,
# sell_indicator,
# sell_crossed_indicator,
# sell_real_num
# )
# conditions.append(condition)
# (dataframe['sma12_deriv1_1h'] < -0.0005)
# # & (dataframe['max_rsi_12'] < 70)
# # & (dataframe['max_rsi_12_1h'] < 70)
# # & (dataframe['range_pos'] > 0.8)
# & (dataframe['hapercent'] < 0)
#
# sell_indicator = self.sell_indicator2.value
# sell_crossed_indicator = self.sell_crossed_indicator2.value
# sell_operator = self.sell_operator2.value
# sell_real_num = self.sell_real_num2.value
# condition, dataframe = condition_generator(
# dataframe,
# sell_operator,
# sell_indicator,
# sell_crossed_indicator,
# sell_real_num
# )
# conditions.append(condition)
# ),
# ['exit_long', 'exit_tag']
# ] = (1, 'long')
#
# dataframe.loc[
# (
# # (qtpylib.crossed_above(
# # dataframe['sma'],
# # dataframe['mid_regression_1h'])
# # )
#
# print(f"SELL indicators tested \n"
# f"{self.sell_indicator0.value} {self.sell_crossed_indicator0.value} {self.sell_operator0.value} {self.sell_real_num0.value} \n"
# f"{self.sell_indicator1.value} {self.sell_crossed_indicator1.value} {self.sell_operator1.value} {self.sell_real_num1.value} \n"
# f"{self.sell_indicator2.value} {self.sell_crossed_indicator2.value} {self.sell_operator2.value} {self.sell_real_num2.value} \n"
# )
# # (dataframe['rsi_1h'] <= 30)
# # & (dataframe['min_rsi_12_1h'] == dataframe['rsi_1h'])
# # & (dataframe['hapercent'] > 0)
# # & (dataframe['sma60'] >= dataframe['sma60'].shift(1))
#
#
# 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')
dataframe.loc[
(
# (qtpylib.crossed_above(
# dataframe['sma'],
# dataframe['mid_regression_1h'])
# )
(dataframe['sma12_1h'] < dataframe['sma12_1h'].shift(61))
& (dataframe['range_pos'] > 0.01)
& (dataframe['close'] > dataframe['close_1d'])
& (dataframe['close'] > dataframe['close_1h'])
),
['exit_long', 'exit_tag']
] = (1, 'long')
dataframe.loc[
(
# (qtpylib.crossed_above(
# dataframe['sma'],
# dataframe['mid_regression_1h'])
# )
# (dataframe['rsi_1h'] <= 30)
# & (dataframe['min_rsi_12_1h'] == dataframe['rsi_1h'])
# & (dataframe['hapercent'] > 0)
# & (dataframe['sma60'] >= dataframe['sma60'].shift(1))
(dataframe['sma12_1h'] > dataframe['sma12_1h'].shift(61))
& (dataframe['range_pos'] < 0.01)
& (dataframe['close'] < dataframe['close_1d'])
& (dataframe['close'] < dataframe['close_1h'])
),
['exit_short', 'exit_tag']
] = (1, 'short')
# (dataframe['sma12_deriv1_1h'] > 0.0005)
# # & (dataframe['max_rsi_12'] < 70)
# # & (dataframe['max_rsi_12_1h'] < 70)
# # & (dataframe['range_pos'] < 0.2)
# & (dataframe['hapercent'] > 0)
# ),
# ['exit_short', 'exit_tag']
# ] = (1, 'short')
return dataframe