Multiple paire detection / limit 3
This commit is contained in:
@@ -27,6 +27,7 @@ import requests
|
|||||||
from datetime import timezone, timedelta
|
from datetime import timezone, timedelta
|
||||||
from scipy.signal import savgol_filter
|
from scipy.signal import savgol_filter
|
||||||
from ta.trend import SMAIndicator, EMAIndicator, MACD, ADXIndicator
|
from ta.trend import SMAIndicator, EMAIndicator, MACD, ADXIndicator
|
||||||
|
from collections import Counter
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -261,6 +262,9 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
|||||||
# if count < 3:
|
# if count < 3:
|
||||||
# allow_to_buy = False
|
# allow_to_buy = False
|
||||||
|
|
||||||
|
if not self.should_enter_trade(pair):
|
||||||
|
allow_to_buy = False
|
||||||
|
|
||||||
if allow_to_buy:
|
if allow_to_buy:
|
||||||
self.trades = list()
|
self.trades = list()
|
||||||
self.pairs[pair]['first_buy'] = rate
|
self.pairs[pair]['first_buy'] = rate
|
||||||
@@ -925,6 +929,9 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
|||||||
days_since_open = (current_time_utc - open_date).days
|
days_since_open = (current_time_utc - open_date).days
|
||||||
pair = trade.pair
|
pair = trade.pair
|
||||||
|
|
||||||
|
if not self.should_enter_trade(pair):
|
||||||
|
return None
|
||||||
|
|
||||||
pct_first = 0
|
pct_first = 0
|
||||||
if self.pairs[pair]['first_buy']:
|
if self.pairs[pair]['first_buy']:
|
||||||
pct_first = round((last_candle['close'] - self.pairs[pair]['first_buy']) / self.pairs[pair]['first_buy'], 3)
|
pct_first = round((last_candle['close'] - self.pairs[pair]['first_buy']) / self.pairs[pair]['first_buy'], 3)
|
||||||
@@ -950,10 +957,12 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
|||||||
if (len(dataframe) < 1):
|
if (len(dataframe) < 1):
|
||||||
print("skip dataframe")
|
print("skip dataframe")
|
||||||
return None
|
return None
|
||||||
if self.dp.runmode.value in ('dry_run'):
|
|
||||||
if pair not in ('BTC/USDT', 'BTC/USDC', 'XRP/USDT', 'XRP/USDC', 'ETH/USDT', 'ETH/USDC'):
|
# if self.dp.runmode.value in ('dry_run'):
|
||||||
# print(f"skip pair {pair}")
|
# if pair not in ('BTC/USDT', 'BTC/USDC', 'XRP/USDT', 'XRP/USDC', 'ETH/USDT', 'ETH/USDC', 'SOL/USDT', 'SOL/USDT'):
|
||||||
return None
|
# # print(f"skip pair {pair}")
|
||||||
|
# return None
|
||||||
|
|
||||||
# else:
|
# else:
|
||||||
# if pair not in ('BTC/USDT', 'BTC/USDC'):
|
# if pair not in ('BTC/USDT', 'BTC/USDC'):
|
||||||
# btc_count = self.pairs['BTC/USDT']['count_of_buys'] + self.pairs['BTC/USDC']['count_of_buys']
|
# btc_count = self.pairs['BTC/USDT']['count_of_buys'] + self.pairs['BTC/USDC']['count_of_buys']
|
||||||
@@ -1166,6 +1175,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
|||||||
def adjust_stake_amount(self, pair: str, last_candle: DataFrame):
|
def adjust_stake_amount(self, pair: str, last_candle: DataFrame):
|
||||||
# Calculer le minimum des 14 derniers jours
|
# Calculer le minimum des 14 derniers jours
|
||||||
base_stake_amount = self.config.get('stake_amount') # Montant de base configuré
|
base_stake_amount = self.config.get('stake_amount') # Montant de base configuré
|
||||||
|
if not pair.startswith('BTC'):
|
||||||
|
base_stake_amount = base_stake_amount * 0.75
|
||||||
|
|
||||||
first_price = self.pairs[pair]['first_buy']
|
first_price = self.pairs[pair]['first_buy']
|
||||||
if (first_price == 0):
|
if (first_price == 0):
|
||||||
@@ -1371,50 +1382,50 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
|||||||
return numeric_matrice[row_idx, col_idx]
|
return numeric_matrice[row_idx, col_idx]
|
||||||
|
|
||||||
|
|
||||||
# @property
|
@property
|
||||||
# def protections(self):
|
def protections(self):
|
||||||
# return [
|
return [
|
||||||
|
{
|
||||||
|
"method": "CooldownPeriod",
|
||||||
|
"stop_duration_candles": 12
|
||||||
|
}
|
||||||
# {
|
# {
|
||||||
# "method": "CooldownPeriod",
|
# "method": "MaxDrawdown",
|
||||||
# "stop_duration_candles": 12
|
# "lookback_period_candles": self.lookback.value,
|
||||||
|
# "trade_limit": self.trade_limit.value,
|
||||||
|
# "stop_duration_candles": self.protection_stop.value,
|
||||||
|
# "max_allowed_drawdown": self.protection_max_allowed_dd.value,
|
||||||
|
# "only_per_pair": False
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "method": "StoplossGuard",
|
||||||
|
# "lookback_period_candles": 24,
|
||||||
|
# "trade_limit": 4,
|
||||||
|
# "stop_duration_candles": self.protection_stoploss_stop.value,
|
||||||
|
# "only_per_pair": False
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "method": "StoplossGuard",
|
||||||
|
# "lookback_period_candles": 24,
|
||||||
|
# "trade_limit": 4,
|
||||||
|
# "stop_duration_candles": 2,
|
||||||
|
# "only_per_pair": False
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "method": "LowProfitPairs",
|
||||||
|
# "lookback_period_candles": 6,
|
||||||
|
# "trade_limit": 2,
|
||||||
|
# "stop_duration_candles": 60,
|
||||||
|
# "required_profit": 0.02
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "method": "LowProfitPairs",
|
||||||
|
# "lookback_period_candles": 24,
|
||||||
|
# "trade_limit": 4,
|
||||||
|
# "stop_duration_candles": 2,
|
||||||
|
# "required_profit": 0.01
|
||||||
# }
|
# }
|
||||||
# # {
|
]
|
||||||
# # "method": "MaxDrawdown",
|
|
||||||
# # "lookback_period_candles": self.lookback.value,
|
|
||||||
# # "trade_limit": self.trade_limit.value,
|
|
||||||
# # "stop_duration_candles": self.protection_stop.value,
|
|
||||||
# # "max_allowed_drawdown": self.protection_max_allowed_dd.value,
|
|
||||||
# # "only_per_pair": False
|
|
||||||
# # },
|
|
||||||
# # {
|
|
||||||
# # "method": "StoplossGuard",
|
|
||||||
# # "lookback_period_candles": 24,
|
|
||||||
# # "trade_limit": 4,
|
|
||||||
# # "stop_duration_candles": self.protection_stoploss_stop.value,
|
|
||||||
# # "only_per_pair": False
|
|
||||||
# # },
|
|
||||||
# # {
|
|
||||||
# # "method": "StoplossGuard",
|
|
||||||
# # "lookback_period_candles": 24,
|
|
||||||
# # "trade_limit": 4,
|
|
||||||
# # "stop_duration_candles": 2,
|
|
||||||
# # "only_per_pair": False
|
|
||||||
# # },
|
|
||||||
# # {
|
|
||||||
# # "method": "LowProfitPairs",
|
|
||||||
# # "lookback_period_candles": 6,
|
|
||||||
# # "trade_limit": 2,
|
|
||||||
# # "stop_duration_candles": 60,
|
|
||||||
# # "required_profit": 0.02
|
|
||||||
# # },
|
|
||||||
# # {
|
|
||||||
# # "method": "LowProfitPairs",
|
|
||||||
# # "lookback_period_candles": 24,
|
|
||||||
# # "trade_limit": 4,
|
|
||||||
# # "stop_duration_candles": 2,
|
|
||||||
# # "required_profit": 0.01
|
|
||||||
# # }
|
|
||||||
# ]
|
|
||||||
|
|
||||||
def conditional_smoothing(self, series, threshold=0.002):
|
def conditional_smoothing(self, series, threshold=0.002):
|
||||||
smoothed = [series.iloc[0]]
|
smoothed = [series.iloc[0]]
|
||||||
@@ -1697,3 +1708,40 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
|||||||
# Résultat
|
# Résultat
|
||||||
print("Moyenne des valeurs par double-tranche :")
|
print("Moyenne des valeurs par double-tranche :")
|
||||||
print(pivot_mean.round(2))
|
print(pivot_mean.round(2))
|
||||||
|
|
||||||
|
def should_enter_trade(self, pair: str) -> bool:
|
||||||
|
|
||||||
|
limit = 3
|
||||||
|
|
||||||
|
if pair.startswith('BTC'):
|
||||||
|
return True # BTC toujours autorisé
|
||||||
|
|
||||||
|
# Filtrer les paires non-BTC
|
||||||
|
non_btc_pairs = [p for p in self.pairs if not p.startswith('BTC')]
|
||||||
|
|
||||||
|
# Compter les positions actives sur les paires non-BTC
|
||||||
|
has_more_than_3 = False
|
||||||
|
total_non_btc = 0
|
||||||
|
for p in non_btc_pairs:
|
||||||
|
nb_trades = self.pairs[p]['count_of_buys']
|
||||||
|
if nb_trades > 0:
|
||||||
|
if nb_trades > limit and pair != p:
|
||||||
|
has_more_than_3 = True
|
||||||
|
total_non_btc += nb_trades
|
||||||
|
|
||||||
|
this_pair_count = self.pairs[p]['count_of_buys']
|
||||||
|
|
||||||
|
if total_non_btc >= 12:
|
||||||
|
# print("total_non_btc > 10")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if this_pair_count >= limit:
|
||||||
|
# Si une autre paire non-BTC a aussi >3 trades, blocage
|
||||||
|
# for other_pair, count in pair_counts.items():
|
||||||
|
# if other_pair != pair and count >= 3:
|
||||||
|
# return False
|
||||||
|
if not has_more_than_3:
|
||||||
|
print(f"{pair} Cette paire est la seule avec >=3 / {this_pair_count}")
|
||||||
|
return not has_more_than_3
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|||||||
Reference in New Issue
Block a user