Empty logtrade
This commit is contained in:
258
Empty.py
258
Empty.py
@@ -22,11 +22,21 @@ import freqtrade.vendor.qtpylib.indicators as qtpylib
|
||||
|
||||
from functools import reduce
|
||||
from random import shuffle
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Couleurs ANSI de base
|
||||
RED = "\033[31m"
|
||||
GREEN = "\033[32m"
|
||||
YELLOW = "\033[33m"
|
||||
BLUE = "\033[34m"
|
||||
MAGENTA = "\033[35m"
|
||||
CYAN = "\033[36m"
|
||||
RESET = "\033[0m"
|
||||
|
||||
timeperiods = [3, 5, 12, 24, 48, 60]
|
||||
|
||||
score_indicators = list()
|
||||
stop_buying_indicators = list()
|
||||
god_genes_with_timeperiod = list()
|
||||
for timeperiod in timeperiods:
|
||||
# god_genes_with_timeperiod.append(f'max{timeperiod}')
|
||||
@@ -36,10 +46,6 @@ for timeperiod in timeperiods:
|
||||
god_genes_with_timeperiod.append(f"sma{timeperiod}_deriv1")
|
||||
god_genes_with_timeperiod.append(f"sma{timeperiod}_deriv2")
|
||||
god_genes_with_timeperiod.append(f"sma{timeperiod}_score")
|
||||
|
||||
# stoploss_indicators.append(f"stop_buying{timeperiod}")
|
||||
stop_buying_indicators.append(f"stop_buying{timeperiod}_1d")
|
||||
|
||||
score_indicators.append(f"sma{timeperiod}_score")
|
||||
# score_indicators.append(f"sma{timeperiod}_score_1d")
|
||||
|
||||
@@ -48,7 +54,6 @@ for timeperiod in timeperiods:
|
||||
# god_genes_with_timeperiod.append(f"sma{timeperiod}_trend_change_up")
|
||||
# god_genes_with_timeperiod.append(f"sma{timeperiod}_trend_change_down")
|
||||
|
||||
print(stop_buying_indicators)
|
||||
|
||||
operators = [
|
||||
"D", # Disabled gene
|
||||
@@ -283,6 +288,7 @@ class Empty(IStrategy):
|
||||
|
||||
# Number of candles the strategy requires before producing valid signals
|
||||
startup_candle_count: int = 30
|
||||
columns_logged = False
|
||||
|
||||
pairs = {
|
||||
pair: {
|
||||
@@ -388,8 +394,6 @@ class Empty(IStrategy):
|
||||
drop_from_last_entry = DecimalParameter(-0.1, 0, decimals=2, default=-0.025, 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(stop_buying_indicators, default="stop_buying12_1d", space='protection')
|
||||
|
||||
# stoploss_timeperiod = CategoricalParameter(timeperiods, default="12", space='protection')
|
||||
|
||||
@@ -478,12 +482,31 @@ class Empty(IStrategy):
|
||||
drop_from_last_entry = (current_rate - last_entry_price) / last_entry_price
|
||||
|
||||
if drop_from_last_entry <= self.drop_from_last_entry.value and last_candle['min60'] == last_candle_3['min60'] \
|
||||
and (last_candle[self.stop_buying_indicator.value] == False or (last_candle['range_pos'] < 0))\
|
||||
and (last_candle['range_pos'] < 0)\
|
||||
and last_candle['hapercent'] > 0:
|
||||
# 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}")
|
||||
# print(f"adjust {pair} {current_time} dispo={dispo} amount={stake_amount} rate={current_rate}")
|
||||
|
||||
trade_type = last_candle['enter_tag'] if last_candle['enter_long'] == 1 else 'pct48'
|
||||
self.pairs[trade.pair]['count_of_buys'] += 1
|
||||
self.pairs[pair]['total_amount'] += stake_amount
|
||||
self.log_trade(
|
||||
last_candle=last_candle,
|
||||
date=current_time,
|
||||
action="🟧 Loss -",
|
||||
dispo=dispo,
|
||||
pair=trade.pair,
|
||||
rate=current_rate,
|
||||
trade_type=trade_type,
|
||||
profit=round(profit, 1),
|
||||
buys=trade.nr_of_successful_entries + 1,
|
||||
stake=round(stake_amount, 2)
|
||||
)
|
||||
self.pairs[trade.pair]['last_buy'] = current_rate
|
||||
self.pairs[trade.pair]['max_touch'] = last_candle['close']
|
||||
self.pairs[trade.pair]['last_candle'] = last_candle
|
||||
|
||||
return stake_amount
|
||||
|
||||
return None
|
||||
@@ -539,27 +562,26 @@ 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()
|
||||
|
||||
stake_amount = self.adjust_stake_amount(pair, last_candle)
|
||||
self.pairs[pair]['first_amount'] = stake_amount
|
||||
self.pairs[pair]['total_amount'] = stake_amount
|
||||
print(f"Buy {pair} {current_time} {entry_tag} dispo={dispo} amount={stake_amount} rate={rate} rate={rate}")
|
||||
# print(f"Buy {pair} {current_time} {entry_tag} dispo={dispo} amount={stake_amount} rate={rate} rate={rate}")
|
||||
|
||||
# self.log_trade(
|
||||
# last_candle=last_candle,
|
||||
# date=current_time,
|
||||
# action=("🟩Buy" if allow_to_buy else "Canceled") + " " + str(minutes),
|
||||
# pair=pair,
|
||||
# rate=rate,
|
||||
# dispo=dispo,
|
||||
# profit=0,
|
||||
# trade_type=entry_tag,
|
||||
# buys=1,
|
||||
# stake=round(stake_amount, 2)
|
||||
# )
|
||||
self.log_trade(
|
||||
last_candle=last_candle,
|
||||
date=current_time,
|
||||
action=("🟩Buy" if allow_to_buy else "Canceled") + " " + str(minutes),
|
||||
pair=pair,
|
||||
rate=rate,
|
||||
dispo=dispo,
|
||||
profit=0,
|
||||
trade_type=entry_tag,
|
||||
buys=1,
|
||||
stake=round(stake_amount, 2)
|
||||
)
|
||||
|
||||
return allow_to_buy
|
||||
|
||||
@@ -584,17 +606,17 @@ class Empty(IStrategy):
|
||||
profit = trade.calc_profit(rate)
|
||||
self.pairs[pair]['previous_profit'] = profit
|
||||
dispo = round(self.wallets.get_available_stake_amount())
|
||||
print(f"Sell {pair} {current_time} {exit_reason} dispo={dispo} rate={rate} open_rate={trade.open_rate} profit={profit}")
|
||||
# self.log_trade(
|
||||
# last_candle=last_candle,
|
||||
# date=current_time,
|
||||
# action="🟥Sell " + str(minutes),
|
||||
# pair=pair,
|
||||
# trade_type=exit_reason,
|
||||
# rate=last_candle['close'],
|
||||
# dispo=dispo,
|
||||
# profit=round(profit, 2)
|
||||
# )
|
||||
# print(f"Sell {pair} {current_time} {exit_reason} dispo={dispo} rate={rate} open_rate={trade.open_rate} profit={profit}")
|
||||
self.log_trade(
|
||||
last_candle=last_candle,
|
||||
date=current_time,
|
||||
action="🟥Sell " + str(minutes),
|
||||
pair=pair,
|
||||
trade_type=exit_reason,
|
||||
rate=last_candle['close'],
|
||||
dispo=dispo,
|
||||
profit=round(profit, 2)
|
||||
)
|
||||
self.pairs[pair]['first_amount'] = 0
|
||||
self.pairs[pair]['force_sell'] = False
|
||||
self.pairs[pair]['has_gain'] = 0
|
||||
@@ -618,6 +640,11 @@ class Empty(IStrategy):
|
||||
self.pairs[pair]['current_trade'] = trade
|
||||
momentum = last_candle[self.sell_score_indicator.value]
|
||||
|
||||
# if self.pairs[pair]['force_sell'] and self.pairs[pair]['last_trade'].close_profit > 0.02:
|
||||
# return "Force"
|
||||
if last_candle['stop_buying']:
|
||||
self.pairs[pair]['force_sell'] = True
|
||||
return 'Stop'
|
||||
# Si momentum fort → on laisse courir
|
||||
if momentum > 1:
|
||||
return None
|
||||
@@ -637,10 +664,11 @@ class Empty(IStrategy):
|
||||
|
||||
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
|
||||
# if profit < - 100 :
|
||||
# print("stop loss detected")
|
||||
# self.pairs[pair]['force_sell'] = True
|
||||
# return 0
|
||||
|
||||
# # 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"]
|
||||
@@ -682,7 +710,7 @@ class Empty(IStrategy):
|
||||
dataframe['haclose'] = heikinashi['close']
|
||||
dataframe['hapercent'] = (dataframe['haclose'] - dataframe['haopen']) / dataframe['haclose']
|
||||
dataframe['mid'] = dataframe['haopen'] + (dataframe['haclose'] - dataframe['haopen']) / 2
|
||||
dataframe['zero'] = 0;
|
||||
dataframe['zero'] = 0
|
||||
|
||||
for timeperiod in timeperiods:
|
||||
dataframe[f'max{timeperiod}'] = talib.MAX(dataframe['close'], timeperiod=timeperiod)
|
||||
@@ -691,19 +719,6 @@ class Empty(IStrategy):
|
||||
dataframe[f"sma{timeperiod}"] = dataframe['mid'].ewm(span=timeperiod, adjust=False).mean()
|
||||
self.calculeDerivees(dataframe, f"sma{timeperiod}", timeframe=self.timeframe, ema_period=timeperiod)
|
||||
|
||||
dataframe[f'stop_buying{timeperiod}_deb'] = (dataframe[f'sma{timeperiod}_trend_change_down'] == 1)
|
||||
dataframe[f'stop_buying{timeperiod}_end'] = (dataframe[f'sma{timeperiod}_trend_change_up'] == 1)
|
||||
latched = np.zeros(len(dataframe), dtype=bool)
|
||||
|
||||
for i in range(1, len(dataframe)):
|
||||
if dataframe[f'stop_buying{timeperiod}_deb'].iloc[i]:
|
||||
latched[i] = True
|
||||
elif dataframe[f'stop_buying{timeperiod}_end'].iloc[i]:
|
||||
latched[i] = False
|
||||
else:
|
||||
latched[i] = latched[i - 1]
|
||||
dataframe[f'stop_buying{timeperiod}'] = latched
|
||||
|
||||
# ######################################################################################################
|
||||
################### INFORMATIVE 1d
|
||||
informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe="1d")
|
||||
@@ -721,27 +736,16 @@ class Empty(IStrategy):
|
||||
informative[f"sma{timeperiod}"] = informative['mid'].ewm(span=timeperiod, adjust=False).mean()
|
||||
self.calculeDerivees(informative, f"sma{timeperiod}", timeframe=self.timeframe, ema_period=timeperiod)
|
||||
|
||||
informative[f'stop_buying_deb{timeperiod}'] = (informative[f'sma{timeperiod}_trend_change_down'] == 1)
|
||||
informative[f'stop_buying_end{timeperiod}'] = (informative[f'sma{timeperiod}_trend_change_up'] == 1)
|
||||
latched = np.zeros(len(informative), dtype=bool)
|
||||
|
||||
for i in range(1, len(informative)):
|
||||
if informative[f'stop_buying_deb{timeperiod}'].iloc[i]:
|
||||
latched[i] = True
|
||||
elif informative[f'stop_buying_end{timeperiod}'].iloc[i]:
|
||||
latched[i] = False
|
||||
else:
|
||||
latched[i] = latched[i - 1]
|
||||
informative[f'stop_buying{timeperiod}'] = latched
|
||||
|
||||
dataframe = merge_informative_pair(dataframe, informative, self.timeframe, "1d", ffill=True)
|
||||
# ######################################################################################################
|
||||
|
||||
range_min = dataframe[f"min12_1d"]
|
||||
range_min = dataframe[f"min24_1d"]
|
||||
range_max = dataframe[f"max48"]
|
||||
|
||||
dataframe[f"range_pos"] = ((dataframe['mid'] - range_min) / (range_max)).rolling(5).mean()
|
||||
|
||||
dataframe[f'stop_buying'] = qtpylib.crossed_below(dataframe[f"sma12"], dataframe['sma48'])
|
||||
|
||||
# récupérer le dernier trade fermé
|
||||
trades = Trade.get_trades_proxy(pair=pair,is_open=False)
|
||||
@@ -806,11 +810,11 @@ class Empty(IStrategy):
|
||||
# buy_real_num
|
||||
# )
|
||||
# conditions.append(condition)
|
||||
conditions.append((dataframe[self.stop_buying_indicator.value] == False) | (dataframe['range_pos'] < 0))
|
||||
# conditions.append((dataframe[self.stop_buying_indicator.value] == False) | (dataframe['range_pos'] < 0))
|
||||
|
||||
conditions.append(dataframe['hapercent'] > 0)
|
||||
# # conditions.append(dataframe[f"range_pos"] <= 0.5)
|
||||
# conditions.append((dataframe[f"range_pos"] < 0.01) | ((dataframe[f"sma5_deriv1"] > 0) & (dataframe[f"sma12_deriv1"] > 0) & (dataframe[f"sma24_deriv1"] > 0)))
|
||||
conditions.append(((dataframe[f"range_pos"] < 0.05) ) | ((dataframe['sma12_deriv1'] > 0) & (dataframe['sma12_deriv2'] > 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"
|
||||
@@ -993,6 +997,109 @@ class Empty(IStrategy):
|
||||
# }
|
||||
]
|
||||
|
||||
def log_trade(self, action, pair, date, trade_type=None, rate=None, dispo=None, profit=None, buys=None, stake=None,
|
||||
last_candle=None):
|
||||
# Afficher les colonnes une seule fois
|
||||
if self.config.get('runmode') == 'hyperopt' or self.dp.runmode.value in ('hyperopt'):
|
||||
return
|
||||
if self.columns_logged % 10 == 0:
|
||||
self.printLog(
|
||||
f"| {'Date':<16} | {'Action':<10} |{'Pair':<5}| {'Trade Type':<18} |{'Rate':>8} | {'Dispo':>6} | {'Profit':>8} "
|
||||
f"| {'Pct':>6} | {'max_touch':>11} | {'last_lost':>12} | {'last_max':>7}| {'last_max':>7}|{'Buys':>5}| {'Stake':>5} |"
|
||||
f"{'rsi':>6}|Distmax|s201d|s5_1d|s5_2d|s51h|s52h|smt1h|smt2h|tdc1d|tdc1h"
|
||||
)
|
||||
self.printLineLog()
|
||||
df = pd.DataFrame.from_dict(self.pairs, orient='index')
|
||||
colonnes_a_exclure = ['last_candle',
|
||||
'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']
|
||||
|
||||
print(df_filtered)
|
||||
|
||||
self.columns_logged += 1
|
||||
date = str(date)[:16] if date else "-"
|
||||
limit = None
|
||||
# if buys is not None:
|
||||
# limit = round(last_rate * (1 - self.fibo[buys] / 100), 4)
|
||||
|
||||
rsi = ''
|
||||
rsi_pct = ''
|
||||
# if last_candle is not None:
|
||||
# if (not np.isnan(last_candle['rsi_1d'])) and (not np.isnan(last_candle['rsi_1h'])):
|
||||
# rsi = str(int(last_candle['rsi_1d'])) + " " + str(int(last_candle['rsi_1h']))
|
||||
# if (not np.isnan(last_candle['rsi_pct_1d'])) and (not np.isnan(last_candle['rsi_pct_1h'])):
|
||||
# rsi_pct = str(int(10000 * last_candle['bb_mid_pct_1d'])) + " " + str(
|
||||
# int(last_candle['rsi_pct_1d'])) + " " + str(int(last_candle['rsi_pct_1h']))
|
||||
|
||||
# first_rate = self.percent_threshold.value
|
||||
# last_rate = self.threshold.value
|
||||
# action = self.color_line(action, action)
|
||||
sma5_1d = ''
|
||||
sma5_1h = ''
|
||||
|
||||
sma5 = str(sma5_1d) + ' ' + str(sma5_1h)
|
||||
|
||||
last_lost = self.getLastLost(last_candle, pair)
|
||||
|
||||
if buys is None:
|
||||
buys = ''
|
||||
|
||||
max_touch = '' # round(last_candle['max12_1d'], 1) #round(self.pairs[pair]['max_touch'], 1)
|
||||
pct_max = self.getPctFirstBuy(pair, last_candle)
|
||||
|
||||
total_counts = str(buys) + '/' + str(sum(pair_data['count_of_buys'] for pair_data in self.pairs.values()))
|
||||
|
||||
dist_max = self.getDistMax(last_candle, pair)
|
||||
|
||||
# if trade_type is not None:
|
||||
# if np.isnan(last_candle['rsi_1d']):
|
||||
# string = ' '
|
||||
# else:
|
||||
# string = (str(int(last_candle['rsi_1d']))) + " " + str(int(last_candle['rsi_deriv1_1d']))
|
||||
# trade_type = trade_type \
|
||||
# + " " + string \
|
||||
# + " " + str(int(last_candle['rsi_1h'])) \
|
||||
# + " " + str(int(last_candle['rsi_deriv1_1h']))
|
||||
|
||||
# val144 = self.getProbaHausse144(last_candle)
|
||||
# val1h = self.getProbaHausse1h(last_candle)
|
||||
|
||||
color = GREEN if profit > 0 else RED
|
||||
# color_sma24 = GREEN if last_candle['sma24_deriv1_1d'] > 0 else RED
|
||||
# color_sma24_2 = GREEN if last_candle['sma24_deriv2_1d'] > 0 else RED
|
||||
# color_sma5 = GREEN if last_candle['mid_smooth_5_deriv1_1d'] > 0 else RED
|
||||
# color_sma5_2 = GREEN if last_candle['mid_smooth_5_deriv2_1d'] > 0 else RED
|
||||
# color_sma5_1h = GREEN if last_candle['sma60_deriv1'] > 0 else RED
|
||||
# color_sma5_2h = GREEN if last_candle['sma60_deriv2'] > 0 else RED
|
||||
# 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)
|
||||
|
||||
profit = str(profit) + '/' + str(round(self.pairs[pair]['max_profit'], 2))
|
||||
|
||||
# 🟢 Dérivée 1 > 0 et dérivée 2 > 0: tendance haussière qui s’accélère.
|
||||
# 🟡 Dérivée 1 > 0 et dérivée 2 < 0: tendance haussière qui ralentit → essoufflement potentiel.
|
||||
# 🔴 Dérivée 1 < 0 et dérivée 2 < 0: tendance baissière qui s’accélère.
|
||||
# 🟠 Dérivée 1 < 0 et dérivée 2 > 0: tendance baissière qui ralentit → possible bottom.
|
||||
|
||||
self.printLog(
|
||||
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}"
|
||||
)
|
||||
|
||||
def printLineLog(self):
|
||||
# f"sum1h|sum1d|Tdc|Tdh|Tdd| drv1 |drv_1h|drv_1d|"
|
||||
self.printLog(
|
||||
f"+{'-' * 18}+{'-' * 12}+{'-' * 5}+{'-' * 20}+{'-' * 9}+{'-' * 8}+{'-' * 12}+{'-' * 8}+{'-' * 13}+{'-' * 14}+{'-' * 9}{'-' * 9}+{'-' * 5}+{'-' * 7}+"
|
||||
f"+{'-' * 6}+{'-' * 7}+{'-' * 5}+{'-' * 5}+{'-' * 5}+{'-' * 5}+{'-' * 5}+{'-' * 5}+"
|
||||
)
|
||||
|
||||
def printLog(self, str):
|
||||
if self.config.get('runmode') == 'hyperopt' or self.dp.runmode.value in ('hyperopt'):
|
||||
return;
|
||||
@@ -1001,3 +1108,18 @@ class Empty(IStrategy):
|
||||
else:
|
||||
if not self.dp.runmode.value in ('hyperopt'):
|
||||
print(str)
|
||||
|
||||
def getLastLost(self, last_candle, pair):
|
||||
last_lost = round((last_candle['close'] - self.pairs[pair]['max_touch']) / self.pairs[pair]['max_touch'], 3)
|
||||
return last_lost
|
||||
|
||||
def getDistMax(self, last_candle, pair):
|
||||
mx = last_candle['max12_1d']
|
||||
dist_max = round(100 * (mx - last_candle['close']) / mx, 0)
|
||||
return dist_max
|
||||
|
||||
def getPctFirstBuy(self, pair, last_candle):
|
||||
return round((last_candle['close'] - self.pairs[pair]['first_buy']) / self.pairs[pair]['first_buy'], 3)
|
||||
|
||||
def getPctLastBuy(self, pair, last_candle):
|
||||
return round((last_candle['close'] - self.pairs[pair]['last_buy']) / self.pairs[pair]['last_buy'], 4)
|
||||
|
||||
Reference in New Issue
Block a user