diff --git a/Zeus_8_3_2_B_4_2.py b/Zeus_8_3_2_B_4_2.py index b61b4d9..46e0f03 100644 --- a/Zeus_8_3_2_B_4_2.py +++ b/Zeus_8_3_2_B_4_2.py @@ -104,19 +104,23 @@ class Zeus_8_3_2_B_4_2(IStrategy): }, "subplots": { "Rsi": { - "rsi_1h": { - "color": "red" - }, - "rsi_1d": { + "max_rsi_24": { "color": "blue" + } + # "rsi_1h": { + # "color": "red" + # }, + # "rsi_1d": { + # "color": "blue" + # } }, "Rsi_deriv1": { - "rsi_deriv1_1h": { - "color": "red" - }, - "rsi_deriv1_1d": { - "color": "blue" - }, + # "rsi_deriv1_1h": { + # "color": "red" + # }, + # "rsi_deriv1_1d": { + # "color": "blue" + # }, "sma60_deriv1": { "color": "green" } @@ -131,34 +135,6 @@ class Zeus_8_3_2_B_4_2(IStrategy): "sma60_deriv2": { "color": "green" } - }, - # "Down": { - # "down_count_1h": { - # "color": "green" - # }, - # "up_count_1h": { - # "color": "blue" - # } - # }, - # "Diff": { - # "sma10_deriv1": { - # "color": "#74effc" - # } - # }, - # "smooth": { - # 'sma60_deriv1': { - # "color": "blue" - # }, - # # 'mid_smooth_1h_deriv1': { - # # "color": "red" - # # }, - # 'sma5_deriv2_1h': { - # "color": "pink" - # }, - # # 'mid_smooth_1h_deriv2': { - # # "color": "#da59a6" - # # } - # } } } } @@ -199,10 +175,10 @@ class Zeus_8_3_2_B_4_2(IStrategy): # 50 50 50 100 100 150 200 250 350 450 600 1050 fibo = [1, 1, 1, 2, 2, 3, 4, 5, 7, 9, 12, 16, 21] baisse = [1, 2, 3, 5, 7, 10, 14, 19, 26, 35, 47, 63, 84] - # Ma suite 1 1 1 2 2 3 4 5 7 9 12 16 21 - # Mise 50 50 50 100 100 150 200 250 350 450 600 800 1050 - # Somme Mises 50 100 150 250 350 500 700 950 1300 1750 2350 3150 4200 - # baisse 1 2 3 5 7 10 14 19 26 35 47 63 84 + # Ma suite 1 1 1 2 2 3 4 5 7 9 12 16 21 + # Mise 50 50 50 100 100 150 200 250 350 450 600 800 1050 + # Somme Mises 50 100 150 250 350 500 700 950 1300 1750 2350 3150 4200 + # baisse 1 2 3 5 7 10 14 19 26 35 47 63 84 # factors = [1, 1.1, 1.25, 1.5, 2.0, 3] # thresholds = [2, 5, 10, 20, 30, 50] @@ -216,27 +192,28 @@ class Zeus_8_3_2_B_4_2(IStrategy): # sma20_deriv1_1d_stop_protection = DecimalParameter(-0.2, 0.2, default=0.05, decimals=2, space='protection', # optimize=True, load=True) sma5_deriv1_1d_stop_protection = DecimalParameter(-5, 0, default=0.5, decimals=1, space='protection', - optimize=True, load=True) + optimize=True, load=True) sma5_deriv2_1d_stop_protection = DecimalParameter(-5, 0, default=0.5, decimals=1, space='protection', optimize=True, - load=True) + load=True) # sma20_deriv1_1d_start_protection = DecimalParameter(-0.2, 0.2, default=0.05, decimals=2, space='protection', # optimize=True, load=True) sma5_deriv1_1d_restart_protection = DecimalParameter(0, 5, default=0.5, decimals=1, space='protection', - optimize=True, load=True) - sma5_deriv2_1d_restart_protection = DecimalParameter(0, 5, default=0.5, decimals=1, space='protection', optimize=True, - load=True) + optimize=True, load=True) + sma5_deriv2_1d_restart_protection = DecimalParameter(0, 5, default=0.5, decimals=1, space='protection', + optimize=True, + load=True) mise_factor_buy = DecimalParameter(0.01, 0.2, default=0.05, decimals=2, space='buy', optimize=True, load=True) sma5_deriv1_1d_stop_sell = DecimalParameter(-5, 5, default=0.5, decimals=1, space='sell', - optimize=True, load=True) + optimize=True, load=True) sma5_deriv2_1d_stop_sell = DecimalParameter(-5, 5, default=0.5, decimals=1, space='sell', optimize=True, - load=True) + load=True) sma5_deriv1_1h_stop_sell = DecimalParameter(-5, 5, default=0.5, decimals=1, space='sell', - optimize=True, load=True) + optimize=True, load=True) sma5_deriv2_1h_stop_sell = DecimalParameter(-5, 5, default=0.5, decimals=1, space='sell', optimize=True, - load=True) + load=True) # Récupération des labels ordonnés # labels = ['B5', 'B4', 'B3', 'B2', 'B1', 'N0', 'H1', 'H2', 'H3', 'H4', 'H5'] # index_labels = ['B5', 'B4', 'B3', 'B2', 'B1', 'N0', 'H1', 'H2', 'H3', 'H4', 'H5'] @@ -320,7 +297,8 @@ class Zeus_8_3_2_B_4_2(IStrategy): # val = self.getProbaHausse144(last_candle) # allow_to_buy = True #(not self.stop_all) #& (not self.all_down) - allow_to_buy = not self.pairs[pair]['stop'] # and val > self.buy_val.value #not last_candle['tendency'] in ('B-', 'B--') # (rate <= float(limit)) | (entry_tag == 'force_entry') + allow_to_buy = not self.pairs[pair][ + 'stop'] # and val > self.buy_val.value #not last_candle['tendency'] in ('B-', 'B--') # (rate <= float(limit)) | (entry_tag == 'force_entry') # if allow_to_buy: # poly_func, x_future, y_future, count = self.polynomial_forecast( @@ -381,7 +359,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): last_candle = dataframe.iloc[-1].squeeze() force = self.pairs[pair]['force_sell'] - allow_to_sell = (last_candle['percent'] < 0) #or force + allow_to_sell = (last_candle['percent'] < 0) # or force minutes = int(round((current_time - trade.date_last_filled_utc).total_seconds() / 60, 0)) @@ -457,7 +435,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): max_profit = self.pairs[pair]['max_profit'] baisse = 0 if profit > 0: - baisse = max_profit - profit + baisse = 1 - (profit / max_profit) mx = max_profit / 5 self.pairs[pair]['count_of_buys'] = count_of_buys self.pairs[pair]['current_profit'] = profit @@ -500,31 +478,27 @@ class Zeus_8_3_2_B_4_2(IStrategy): # self.pairs[pair]['force_sell'] = False # return 'Force' + pair_name + '_' + str(count_of_buys) + '_' + str(self.pairs[pair]['has_gain']) - # if profit > - 2 and last_candle['rsi_1h'] < 50 \ - # and (last_candle['sma20'] - before_last_candle['sma20'] < 0) \ - # and (last_candle['rsi_deriv1_1h'] < -4 and last_candle['rsi_deriv2_1h'] < -4) : - # self.pairs[pair]['force_sell'] = False - # return 'stoploss_' + pair_name + '_' + str(count_of_buys) + '_' + str(self.pairs[pair]['has_gain']) + if profit > 0.5 * count_of_buys and baisse > 0.15: + self.pairs[pair]['force_sell'] = False + return str(count_of_buys) + '_' + 'Bas_' + pair_name + '_' + str(self.pairs[pair]['has_gain']) factor = 1 if (self.getShortName(pair) == 'BTC'): factor = 0.5 - if baisse > 2 and baisse > factor * self.pairs[pair]['total_amount'] / 100: - self.pairs[pair]['force_sell'] = False - self.pairs[pair]['force_buy'] = (self.pairs[pair]['count_of_buys'] - self.pairs[pair]['has_gain'] > 3) - return 'Baisse_' + pair_name + '_' + str(count_of_buys) + '_' + str(self.pairs[pair]['has_gain']) - # - # # if 1 <= count_of_buys <= 3: - # if last_candle['rsi_1h'] < 50 \ - # and last_candle['mid_smooth_1h_deriv1'] < 0 and profit > expected_profit \ - # and (last_candle['sma20'] - before_last_candle['sma20'] < 0) : + # if baisse > 2 and baisse > factor * self.pairs[pair]['total_amount'] / 100: # self.pairs[pair]['force_sell'] = False - # return 'Drv3_' + pair_name + '_' + str(count_of_buys) + '_' + str(self.pairs[pair]['has_gain']) - - if last_candle['mid_smooth_1h_deriv1'] < 0 and last_candle['rsi_1h'] < 50 and profit > expected_profit: + # self.pairs[pair]['force_buy'] = (self.pairs[pair]['count_of_buys'] - self.pairs[pair]['has_gain'] > 3) + # return 'Baisse_' + pair_name + '_' + str(count_of_buys) + '_' + str(self.pairs[pair]['has_gain']) + # + # if 1 <= count_of_buys <= 3: + if last_candle['max_rsi_24'] > 75 and profit > expected_profit and (last_candle['hapercent'] < 0) and last_candle['sma60_deriv1'] < 0: self.pairs[pair]['force_sell'] = False - self.pairs[pair]['force_buy'] = (self.pairs[pair]['count_of_buys'] - self.pairs[pair]['has_gain'] > 5) - return 'Drv3_' + pair_name + '_' + str(count_of_buys) + '_' + str(self.pairs[pair]['has_gain']) + return str(count_of_buys) + '_' + 'Rsi_' + pair_name + '_' + str(self.pairs[pair]['has_gain']) + + # if last_candle['mid_smooth_1h_deriv1'] < 0 and profit > expected_profit: + # self.pairs[pair]['force_sell'] = False + # self.pairs[pair]['force_buy'] = (self.pairs[pair]['count_of_buys'] - self.pairs[pair]['has_gain'] > 5) + # return str(count_of_buys) + '_' + 'Drv3_' + pair_name + '_' + str(self.pairs[pair]['has_gain']) # if 4 <= count_of_buys <= 6: # if ((before_last_candle_2['mid_smooth_12_deriv1'] <= before_last_candle['mid_smooth_12_deriv1']) @@ -592,12 +566,12 @@ class Zeus_8_3_2_B_4_2(IStrategy): if self.columns_logged % 10 == 0: self.printLog( f"| {'Date':<16} | {'Action':<10} |{'Pair':<5}| {'Trade Type':<18} |{'Rate':>8} | {'Dispo':>6} | {'Profit':>8} | {'Pct':>6} | {'max_touch':>11} | {'last_lost':>12} | {'last_max':>7}| {'last_max':>7}|{'Buys':>5}| {'Stake':>5} |" - f"Tdc|{'val':>6}|Distmax|s201d|s5_1d|s5_2d|s51h|s52h|smt1h|smt2h|" + f"Tdc|{'rsi':>6}|Distmax|s201d|s5_1d|s5_2d|s51h|s52h|smt1h|smt2h|" ) self.printLineLog() df = pd.DataFrame.from_dict(self.pairs, orient='index') - colonnes_a_exclure = ['last_candle', 'last_trade', 'last_palier_index', 'current_trade', - 'trade_info', 'last_date', 'expected_profit', 'last_count_of_buys', 'base_stake_amount', 'stop_buy'] + colonnes_a_exclure = ['last_candle', 'last_trade', 'last_palier_index', #'current_trade', + 'trade_info', 'last_date', 'last_count_of_buys', 'base_stake_amount', 'stop_buy'] df_filtered = df[df['count_of_buys'] > 0].drop(columns=colonnes_a_exclure) # df_filtered = df_filtered["first_buy", "last_max", "max_touch", "last_sell","last_buy", 'count_of_buys', 'current_profit'] @@ -663,8 +637,10 @@ class Zeus_8_3_2_B_4_2(IStrategy): color_smooth_1h = GREEN if last_candle['mid_smooth_1h_deriv1'] > 0 else RED color_smooth2_1h = GREEN if last_candle['mid_smooth_1h_deriv2'] > 0 else RED - last_max = int(self.pairs[pair]['last_max']) if self.pairs[pair]['last_max'] > 1 else round(self.pairs[pair]['last_max'],3) - last_min = int(self.pairs[pair]['last_min']) if self.pairs[pair]['last_min'] > 1 else round(self.pairs[pair]['last_min'], 3) + last_max = int(self.pairs[pair]['last_max']) if self.pairs[pair]['last_max'] > 1 else round( + self.pairs[pair]['last_max'], 3) + last_min = int(self.pairs[pair]['last_min']) if self.pairs[pair]['last_min'] > 1 else round( + self.pairs[pair]['last_min'], 3) profit = str(profit) + '/' + str(round(self.pairs[pair]['max_profit'], 2)) @@ -678,10 +654,10 @@ class Zeus_8_3_2_B_4_2(IStrategy): f"| {date:<16} |{action:<10} | {pair[0:3]:<3} | {trade_type or '-':<18} |{rate or '-':>9}| {dispo or '-':>6} " f"|{color}{profit or '-':>10}{RESET}| {pct_max or '-':>6} | {round(self.pairs[pair]['max_touch'], 2) or '-':>11} | {last_lost or '-':>12} " f"| {last_max or '-':>7} | {last_min or '-':>7} |{total_counts or '-':>5}|{stake or '-':>7}" - f"|{ last_candle['tendency_12'] or '-':>3}|" # {last_candle['tendency_1h'] or '-':>3}|{last_candle['tendency_1d'] or '-':>3}" + f"|{last_candle['tendency_12'] or '-':>3}|" # {last_candle['tendency_1h'] or '-':>3}|{last_candle['tendency_1d'] or '-':>3}" # f"|{round(last_candle['mid_smooth_24_deriv1'],3) or '-':>6}|{round(last_candle['mid_smooth_1h_deriv1'],3) or '-':>6}|{round(last_candle['mid_smooth_deriv1_1d'],3) or '-' :>6}|" # f"{round(last_candle['mid_smooth_24_deriv2'],3) or '-' :>6}|{round(last_candle['mid_smooth_1h_deriv2'],3) or '-':>6}|{round(last_candle['mid_smooth_deriv2_1d'],3) or '-':>6}|" - f"{round(val, 1) or '-' :>6}|" + f"{round(last_candle['max_rsi_24'], 1) or '-' :>6}|" f"{dist_max:>7}|{color_sma20}{round(last_candle['sma20_deriv1_1d'], 2):>5}{RESET}" f"|{color_sma5}{round(last_candle['mid_smooth_5_deriv1_1d'], 2):>5}{RESET}|{color_sma5_2}{round(last_candle['mid_smooth_5_deriv2_1d'], 2):>5}{RESET}" f"|{color_sma5_1h}{round(last_candle['sma60_deriv1'], 2):>5}{RESET}|{color_sma5_2h}{round(last_candle['sma60_deriv2'], 2):>5}{RESET}" @@ -771,7 +747,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): # print(metadata['pair']) dataframe['rsi'] = talib.RSI(dataframe['close'], timeperiod=14) - dataframe['max_rsi_12'] = talib.MAX(dataframe['rsi'], timeperiod=12) + dataframe['max_rsi_24'] = talib.MAX(dataframe['rsi'], timeperiod=24) self.calculeDerivees(dataframe, 'rsi', horizon=12) dataframe['max48'] = talib.MAX(dataframe['close'], timeperiod=48) @@ -895,13 +871,13 @@ class Zeus_8_3_2_B_4_2(IStrategy): # self.calculateStats(informative, 'sma5_deriv1', 'futur_percent_3') if self.dp.runmode.value in ('backtest'): - informative['futur_percent'] = 100 * (informative['close'].shift(-1) - informative['close']) / informative['close'] + informative['futur_percent'] = 100 * (informative['close'].shift(-1) - informative['close']) / informative[ + 'close'] # informative['futur_percent_3d'] = 100 * (informative['close'].shift(-3) - informative['close']) / informative['close'] # # self.calculateProbabilite2Index(informative, ['futur_percent_1d'], 'rsi_deriv1', 'rsi') # # self.calculateProbabilite2Index(dataframe, ['futur_percent_3d'], 'rsi_deriv1', 'sma5') - # informative['close_smooth'] = self.conditional_smoothing(informative['mid'].dropna(), threshold=0.0015).dropna() # informative['smooth'], informative['deriv1'], informative['deriv2'] = self.smooth_and_derivatives(informative['close_smooth']) # informative['deriv1'] = 100 * informative['deriv1'] / informative['mid'] @@ -1064,7 +1040,8 @@ class Zeus_8_3_2_B_4_2(IStrategy): return dataframe def calculeDerivees(self, dataframe, indic, factor_1=100, factor_2=10, horizon=5): - dataframe[f"{indic}_deriv1"] = (factor_1 * dataframe[f"{indic}"].diff() / dataframe[f"{indic}"]).rolling(horizon).mean() + dataframe[f"{indic}_deriv1"] = (factor_1 * dataframe[f"{indic}"].diff() / dataframe[f"{indic}"]).rolling( + horizon).mean() dataframe[f"{indic}_deriv2"] = (factor_2 * dataframe[f"{indic}_deriv1"].diff()).rolling(horizon).mean() def calculateDownAndUp(self, dataframe, limit=0.0001): @@ -1160,21 +1137,21 @@ class Zeus_8_3_2_B_4_2(IStrategy): # (valid_inversion & inversion_last5 ) (dataframe['mid_smooth_3'].shift(1) < dataframe['mid_smooth_3']) & (dataframe['hapercent'] > 0) - & (dataframe['max_rsi_12'] < 70) + & (dataframe['max_rsi_24'] < 70) & (dataframe['open'] <= dataframe['bb_middleband']) - # valid_inversion - # ((dataframe['bb_cross_down'] < - 0.1) - # | (dataframe['bb_cross_down'].shift(1) < - 0.1) - # | (dataframe['bb_cross_down'].shift(2) < - 0.1) - # | (dataframe['bb_cross_down'].shift(3) < - 0.1) - # ) - # & (dataframe['hapercent'] > 0) - # & (dataframe['close'] * factor < dataframe['bb_upperband5']) - # - # - # (dataframe['mid_smooth_1h_deriv1'] >= 0) - # & (dataframe['mid_smooth_1h_deriv1'] >= 0) + # valid_inversion + # ((dataframe['bb_cross_down'] < - 0.1) + # | (dataframe['bb_cross_down'].shift(1) < - 0.1) + # | (dataframe['bb_cross_down'].shift(2) < - 0.1) + # | (dataframe['bb_cross_down'].shift(3) < - 0.1) + # ) + # & (dataframe['hapercent'] > 0) + # & (dataframe['close'] * factor < dataframe['bb_upperband5']) + # + # + & (dataframe['mid_smooth_1h_deriv1'] >= 0) + & (dataframe['mid_smooth_1h_deriv2'] >= 0) # & (dataframe['mid_smooth_1h_deriv1'].shift(1) <= 0) # & (dataframe['mid_smooth_1h_deriv1'] >= dataframe['mid_smooth_1h_deriv1'].shift(1)) ), ['enter_long', 'enter_tag']] = (1, 'smth') @@ -1485,7 +1462,8 @@ class Zeus_8_3_2_B_4_2(IStrategy): max_amount = self.config.get('stake_amount') * 2.5 # stake_amount = min(stake_amount, self.wallets.get_available_stake_amount()) stake_amount = min(min(max_amount, self.wallets.get_available_stake_amount()), - self.adjust_stake_amount(pair, last_candle) - 10 * pct_first / self.mise_factor_buy.value) # min(200, self.adjust_stake_amount(pair, last_candle) * self.fibo[count_of_buys]) + self.adjust_stake_amount(pair, + last_candle) - 10 * pct_first / self.mise_factor_buy.value) # min(200, self.adjust_stake_amount(pair, last_candle) * self.fibo[count_of_buys]) if self.wallets.get_available_stake_amount() > stake_amount: trade_type = last_candle['enter_tag'] if last_candle['enter_long'] == 1 else 'pct48' @@ -1541,12 +1519,13 @@ class Zeus_8_3_2_B_4_2(IStrategy): last_lost = self.getLastLost(last_candle, pair) - if (hours > 6 + if (current_profit > 0 and hours > 6 # and last_candle['sma60_deriv1'] > 0 and last_candle['rsi_1h'] < 65 and last_candle['rsi_deriv1_1h'] > 0 and last_candle['mid_smooth_5_deriv1_1d'] > 0 and last_candle['sma60_deriv1'] > 0 + and last_candle['sma60_deriv2'] > 0 ): try: stake_amount = self.pairs[pair]['first_amount'] / 2 @@ -1729,7 +1708,10 @@ class Zeus_8_3_2_B_4_2(IStrategy): # if last_candle['close'] < max_60: # pct_to_max = 0.25 * (max_60 - last_candle['close']) / max_60 # pct_to_max = pct_to_max * (2 - pctClose60) - expected_profit = lim * self.pairs[pair]['total_amount'] #min(3 * lim, max(lim, pct_to_max)) # 0.004 + 0.002 * self.pairs[pair]['count_of_buys'] #min(0.01, first_max) + expected_profit = lim * self.pairs[pair][ + 'total_amount'] # min(3 * lim, max(lim, pct_to_max)) # 0.004 + 0.002 * self.pairs[pair]['count_of_buys'] #min(0.01, first_max) + + self.pairs[pair]['expected_profit'] = expected_profit # print( # f"Expected profit price={current_price:.4f} min_max={min_max:.4f} min_14={min_14_days:.4f} max_14={max_14_days:.4f} percent={percent:.4f} expected_profit={expected_profit:.4f}") @@ -2255,7 +2237,8 @@ class Zeus_8_3_2_B_4_2(IStrategy): # if not pair.startswith('BTC'): dispo = round(self.wallets.get_available_stake_amount()) - if self.pairs[pair]['stop'] and last_candle['mid_smooth_5_deriv1_1d'] > -0.9 and last_candle['sma5_deriv1_1d'] > 0 and last_candle['sma5_deriv2_1d'] > 0: + if self.pairs[pair]['stop'] and last_candle['mid_smooth_5_deriv1_1d'] > -0.9 and last_candle[ + 'sma5_deriv1_1d'] > 0 and last_candle['sma5_deriv2_1d'] > 0: self.pairs[pair]['stop'] = False self.log_trade( last_candle=last_candle, @@ -2270,7 +2253,8 @@ class Zeus_8_3_2_B_4_2(IStrategy): stake=0 ) else: - if self.pairs[pair]['stop'] == False and (last_candle['sma5_deriv1_1d'] < -0.2 or last_candle['sma5_deriv2_1d'] < -3): + if self.pairs[pair]['stop'] == False and ( + last_candle['sma5_deriv1_1d'] < -0.2 or last_candle['sma5_deriv2_1d'] < -3): self.pairs[pair]['stop'] = True # if self.pairs[pair]['current_profit'] > 0: # self.pairs[pair]['force_sell'] = True @@ -2299,13 +2283,14 @@ class Zeus_8_3_2_B_4_2(IStrategy): if last_candle['sma5_deriv1_1h'] < 0.0 and last_candle['sma5_deriv2_1h'] < -0.0: return False - if last_candle['mid_smooth_1h_deriv1'] < 0.0 and last_candle['mid_smooth_1h_deriv2'] < -0.0 and last_candle['sma5_deriv2_1h'] < 0: + if last_candle['mid_smooth_1h_deriv1'] < 0.0 and last_candle['mid_smooth_1h_deriv2'] < -0.0 and last_candle[ + 'sma5_deriv2_1h'] < 0: return False # if pair.startswith('BTC'): # return True # BTC toujours autorisé - #return True + # return True # Filtrer les paires non-BTC non_btc_pairs = [p for p in self.pairs if not p.startswith('BTC')] @@ -2344,7 +2329,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): # or last_candle['sma5_deriv2_1d'] < -0.2: # return False - if last_candle['mid_smooth_1h_deriv1'] < -0.02: # and last_candle['mid_smooth_1h_deriv2'] > 0): + if last_candle['mid_smooth_1h_deriv1'] < -0.02: # and last_candle['mid_smooth_1h_deriv2'] > 0): return False # if self.pairs[pair]['count_of_buys'] >= 3: @@ -2369,7 +2354,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): pct_max_max = self.getPctFirstBuy(max_pair, last_candle) # print(f"days_since_open {days_since_open} max_pair={max_pair} pair={pair}") return max_pair == pair or pct_max < - 0.25 or ( - pct_max_max < - 0.15 and max_pair != pair and days_since_open > 30) + pct_max_max < - 0.15 and max_pair != pair and days_since_open > 30) else: return True