diff --git a/EmptyShort.py b/EmptyShort.py index aab3910..b9c1d74 100644 --- a/EmptyShort.py +++ b/EmptyShort.py @@ -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 diff --git a/EmptyShort.txt b/EmptyShort.txt new file mode 100644 index 0000000..78dce78 --- /dev/null +++ b/EmptyShort.txt @@ -0,0 +1,183 @@ + BACKTESTING REPORT +┏━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Pair ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ +┡━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ BTC/USDT:USDT │ 34 │ 1.08 │ 379.432 │ 37.94 │ 1 day, 10:30:00 │ 18 0 16 52.9 │ +│ TOTAL │ 34 │ 1.08 │ 379.432 │ 37.94 │ 1 day, 10:30:00 │ 18 0 16 52.9 │ +└───────────────┴────────┴──────────────┴─────────────────┴──────────────┴─────────────────┴────────────────────────┘ + LEFT OPEN TRADES REPORT +┏━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Pair ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ +┡━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ TOTAL │ 0 │ 0.0 │ 0.000 │ 0.0 │ 0:00 │ 0 0 0 0 │ +└───────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────┴────────────────────────┘ + ENTER TAG STATS +┏━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Enter Tag ┃ Entries ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ +┡━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ short │ 33 │ 0.99 │ 343.256 │ 34.33 │ 1 day, 6:51:00 │ 17 0 16 51.5 │ +│ long │ 1 │ 3.75 │ 36.176 │ 3.62 │ 6 days, 10:57:00 │ 1 0 0 100 │ +│ TOTAL │ 34 │ 1.08 │ 379.432 │ 37.94 │ 1 day, 10:30:00 │ 18 0 16 52.9 │ +└───────────┴─────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┘ + EXIT REASON STATS +┏━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Exit Reason ┃ Exits ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ +┡━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ B30Sht │ 17 │ 3.91 │ 770.836 │ 77.08 │ 1 day, 18:12:00 │ 17 0 0 100 │ +│ B30 │ 1 │ 3.75 │ 36.176 │ 3.62 │ 6 days, 10:57:00 │ 1 0 0 100 │ +│ stop_loss │ 16 │ -2.1 │ -427.580 │ -42.76 │ 18:48:00 │ 0 0 16 0 │ +│ TOTAL │ 34 │ 1.08 │ 379.432 │ 37.94 │ 1 day, 10:30:00 │ 18 0 16 52.9 │ +└─────────────┴───────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┘ + MIXED TAG STATS +┏━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Enter Tag ┃ Exit Reason ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ +┡━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ short │ B30Sht │ 17 │ 3.91 │ 770.836 │ 77.08 │ 1 day, 18:12:00 │ 17 0 0 100 │ +│ long │ B30 │ 1 │ 3.75 │ 36.176 │ 3.62 │ 6 days, 10:57:00 │ 1 0 0 100 │ +│ short │ stop_loss │ 16 │ -2.1 │ -427.580 │ -42.76 │ 18:48:00 │ 0 0 16 0 │ +│ TOTAL │ │ 34 │ 1.08 │ 379.432 │ 37.94 │ 1 day, 10:30:00 │ 18 0 16 52.9 │ +└───────────┴─────────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┘ + DAY BREAKDOWN +┏━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Day ┃ Trades ┃ Tot Profit USDT ┃ Profit Factor ┃ Win Draw Loss Win% ┃ +┡━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ 07/01/2026 │ 1 │ 36.176 │ 0.0 │ 1 0 0 100 │ +│ 08/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 09/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 10/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 11/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 12/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 13/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 14/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 15/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 16/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 17/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 18/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 19/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 20/01/2026 │ 1 │ 49.877 │ 0.0 │ 1 0 0 100 │ +│ 21/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 22/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 23/01/2026 │ 1 │ -22.186 │ 0.0 │ 0 0 1 0 │ +│ 24/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 25/01/2026 │ 1 │ 23.333 │ 0.0 │ 1 0 0 100 │ +│ 26/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 27/01/2026 │ 1 │ -21.693 │ 0.0 │ 0 0 1 0 │ +│ 28/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 29/01/2026 │ 1 │ 44.977 │ 0.0 │ 1 0 0 100 │ +│ 30/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 31/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 01/02/2026 │ 2 │ 78.6 │ 0.0 │ 2 0 0 100 │ +│ 02/02/2026 │ 3 │ -23.839 │ 0.52 │ 1 0 2 33.3 │ +│ 03/02/2026 │ 1 │ 33.135 │ 0.0 │ 1 0 0 100 │ +│ 04/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 05/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 06/02/2026 │ 2 │ 111.129 │ 5.0 │ 1 0 1 50.0 │ +│ 07/02/2026 │ 1 │ -27.273 │ 0.0 │ 0 0 1 0 │ +│ 08/02/2026 │ 1 │ -26.223 │ 0.0 │ 0 0 1 0 │ +│ 09/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 10/02/2026 │ 1 │ 24.285 │ 0.0 │ 1 0 0 100 │ +│ 11/02/2026 │ 3 │ 26.089 │ 1.94 │ 2 0 1 66.7 │ +│ 12/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 13/02/2026 │ 1 │ -26.778 │ 0.0 │ 0 0 1 0 │ +│ 14/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 15/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 16/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 17/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 18/02/2026 │ 1 │ 32.734 │ 0.0 │ 1 0 0 100 │ +│ 19/02/2026 │ 1 │ 25.775 │ 0.0 │ 1 0 0 100 │ +│ 20/02/2026 │ 2 │ -54.318 │ 0.0 │ 0 0 2 0 │ +│ 21/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 22/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 23/02/2026 │ 1 │ 40.137 │ 0.0 │ 1 0 0 100 │ +│ 24/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 25/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 26/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 27/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 28/02/2026 │ 1 │ 52.892 │ 0.0 │ 1 0 0 100 │ +│ 01/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 02/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 03/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 04/03/2026 │ 1 │ -28.629 │ 0.0 │ 0 0 1 0 │ +│ 05/03/2026 │ 1 │ -27.218 │ 0.0 │ 0 0 1 0 │ +│ 06/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 07/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 08/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 09/03/2026 │ 1 │ 85.083 │ 0.0 │ 1 0 0 100 │ +│ 10/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 11/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 12/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 13/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 14/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 15/03/2026 │ 1 │ -28.661 │ 0.0 │ 0 0 1 0 │ +│ 16/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 17/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 18/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 19/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 20/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 21/03/2026 │ 1 │ 61.417 │ 0.0 │ 1 0 0 100 │ +│ 22/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 23/03/2026 │ 1 │ -29.977 │ 0.0 │ 0 0 1 0 │ +│ 24/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │ +│ 25/03/2026 │ 1 │ -29.414 │ 0.0 │ 0 0 1 0 │ +└────────────┴────────┴─────────────────┴───────────────┴────────────────────────┘ + SUMMARY METRICS +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Metric ┃ Value ┃ +┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ Backtesting from │ 2026-01-01 00:00:00 │ +│ Backtesting to │ 2026-03-27 15:43:00 │ +│ Trading Mode │ Isolated Futures │ +│ Max open trades │ 1 │ +│ │ │ +│ Total/Daily Avg Trades │ 34 / 0.4 │ +│ Starting balance │ 1000 USDT │ +│ Final balance │ 1379.432 USDT │ +│ Absolute profit │ 379.432 USDT │ +│ Total profit % │ 37.94% │ +│ CAGR % │ 298.01% │ +│ Sortino │ 37.32 │ +│ Sharpe │ 2.08 │ +│ Calmar │ 140.28 │ +│ SQN │ 1.56 │ +│ Profit factor │ 1.89 │ +│ Expectancy (Ratio) │ 11.16 (0.42) │ +│ Avg. daily profit │ 4.464 USDT │ +│ Avg. stake amount │ 1212.112 USDT │ +│ Total trade volume │ 82120.278 USDT │ +│ │ │ +│ Long / Short trades │ 1 / 33 │ +│ Long / Short profit % │ 3.62% / 34.33% │ +│ Long / Short profit USDT │ 36.176 / 343.256 │ +│ │ │ +│ Best Pair │ BTC/USDT:USDT 37.94% │ +│ Worst Pair │ BTC/USDT:USDT 37.94% │ +│ Best trade │ BTC/USDT:USDT 12.24% │ +│ Worst trade │ BTC/USDT:USDT -2.12% │ +│ Best day │ 111.129 USDT │ +│ Worst day │ -54.318 USDT │ +│ Days win/draw/lose │ 15 / 51 / 12 │ +│ Min/Max/Avg. Duration Winners │ 0d 00:58 / 6d 10:57 / 2d 00:28 │ +│ Min/Max/Avg. Duration Losers │ 0d 02:23 / 2d 01:26 / 0d 18:48 │ +│ Max Consecutive Wins / Loss │ 4 / 3 │ +│ Rejected Entry signals │ 0 │ +│ Entry/Exit Timeouts │ 0 / 0 │ +│ │ │ +│ Min balance │ 1036.176 USDT │ +│ Max balance │ 1438.823 USDT │ +│ Max % of account underwater │ 6.08% │ +│ Absolute drawdown │ 81.299 USDT (6.08%) │ +│ Drawdown duration │ 2 days 02:32:00 │ +│ Profit at drawdown start │ 337.312 USDT │ +│ Profit at drawdown end │ 256.013 USDT │ +│ Drawdown start │ 2026-02-06 06:00:00 │ +│ Drawdown end │ 2026-02-08 08:32:00 │ +│ Market change │ -24.27% │ +└───────────────────────────────┴────────────────────────────────┘ + +Backtested 2026-01-01 00:00:00 -> 2026-03-27 15:43:00 | Max open trades : 1 + STRATEGY SUMMARY +┏━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┓ +┃ 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% │ +└────────────┴────────┴──────────────┴─────────────────┴──────────────┴─────────────────┴────────────────────────┴────────────────────┘