Compare commits
7 Commits
1bc5a38796
...
Multiple_p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a925a28389 | ||
|
|
3302266b4a | ||
|
|
7954c518bd | ||
|
|
a599160501 | ||
|
|
8b030f46f0 | ||
|
|
2a7dd0beb4 | ||
|
|
5b1e8bede4 |
@@ -4,9 +4,6 @@
|
||||
"roi": {
|
||||
"0": 5
|
||||
},
|
||||
"stoploss": {
|
||||
"stoploss": -1.0
|
||||
},
|
||||
"trailing": {
|
||||
"trailing_stop": false,
|
||||
"trailing_stop_positive": null,
|
||||
@@ -25,8 +22,11 @@
|
||||
"protection": {
|
||||
"drop_from_last_entry": 0.0,
|
||||
"mises_bull": 4
|
||||
},
|
||||
"stoploss": {
|
||||
"stoploss": -0.02
|
||||
}
|
||||
},
|
||||
"ft_stratparam_v": 1,
|
||||
"export_time": "2026-03-07 20:20:17.895644+00:00"
|
||||
"export_time": "2026-03-29 18:29:54.986316+00:00"
|
||||
}
|
||||
682
EmptyShort.py
682
EmptyShort.py
@@ -103,7 +103,7 @@ class EmptyShort(IStrategy):
|
||||
# trailing_only_offset_is_reached = False
|
||||
|
||||
position_adjustment_enable = True
|
||||
use_custom_stoploss = True
|
||||
use_custom_stoploss = False
|
||||
|
||||
#max_open_trades = 3
|
||||
|
||||
@@ -151,7 +151,8 @@ class EmptyShort(IStrategy):
|
||||
'current_trade': None,
|
||||
'last_trade': None,
|
||||
'force_stop': False,
|
||||
'count_of_lost': 0
|
||||
'count_of_lost': 0,
|
||||
'take_profit': 0.01
|
||||
}
|
||||
for pair in ["BTC/USDC", "BTC/USDT", 'BTC/USDT:USDT']
|
||||
}
|
||||
@@ -261,7 +262,7 @@ class EmptyShort(IStrategy):
|
||||
# if last_candle['enter_tag'] in ['fall', 'bear', 'Force', 'Range-']:
|
||||
# amount = self.wallets.get_available_stake_amount() / self.mises_bear.value
|
||||
# else:
|
||||
amount = self.wallets.get_available_stake_amount() / self.mises_bull.value # / (2 * self.pairs[pair]['count_of_lost'] + 1)
|
||||
amount = self.wallets.get_available_stake_amount() #/ self.mises_bull.value # / (2 * self.pairs[pair]['count_of_lost'] + 1)
|
||||
|
||||
# factor = 1
|
||||
#
|
||||
@@ -372,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
|
||||
|
||||
@@ -439,10 +441,25 @@ class EmptyShort(IStrategy):
|
||||
self.pairs[pair]['total_amount'] = stake_amount
|
||||
# print(f"Buy {pair} {current_time} {entry_tag} dispo={dispo} amount={stake_amount} rate={rate} rate={rate}")
|
||||
|
||||
|
||||
# sl_price = rate * (1 - last_candle['up_pct_1h'] / 2)
|
||||
#
|
||||
# self.custom_trade_info[pair] = {
|
||||
# "custom_exit": last_candle['up_pct_1h'] / 200
|
||||
# }
|
||||
|
||||
# trade = kwargs.get("trade", None)
|
||||
# if trade:
|
||||
# trade.set_custom_data({
|
||||
# # "stoploss": rate * 0.95,
|
||||
# "takeprofit": last_candle['up_pct_1h'] / 200
|
||||
# })
|
||||
self.pairs[pair]['take_profit'] = last_candle['up_pct_1h'] / 200
|
||||
|
||||
self.log_trade(
|
||||
last_candle=last_candle,
|
||||
date=current_time,
|
||||
action=("🟩Buy" if allow_to_buy else "Canceled") + " " + str(minutes),
|
||||
action=("🟩Buy") + " " + str(minutes),
|
||||
pair=pair,
|
||||
rate=rate,
|
||||
dispo=dispo,
|
||||
@@ -455,7 +472,7 @@ class EmptyShort(IStrategy):
|
||||
self.log_trade(
|
||||
last_candle=last_candle,
|
||||
date=current_time,
|
||||
action=("🟩Buy" if allow_to_buy else "Canceled") + " " + reason,
|
||||
action=("Canceled") + " " + reason,
|
||||
pair=pair,
|
||||
rate=rate,
|
||||
dispo=dispo,
|
||||
@@ -477,7 +494,7 @@ class EmptyShort(IStrategy):
|
||||
profit = trade.calc_profit(rate)
|
||||
force = self.pairs[pair]['force_sell']
|
||||
allow_to_sell = (last_candle['hapercent'] < 0 and profit > 0) or force \
|
||||
or (trade.enter_tag == 'short' and profit > 0 and last_candle['hapercent'] > 0) or (exit_reason == 'force_exit') or (exit_reason == 'stop_loss') or (exit_reason == 'trailing_stop_loss')
|
||||
or (trade.is_short) or (exit_reason == 'force_exit') or (exit_reason == 'stop_loss') or (exit_reason == 'trailing_stop_loss')
|
||||
|
||||
minutes = int(round((current_time - trade.date_last_filled_utc).total_seconds() / 60, 0))
|
||||
|
||||
@@ -545,20 +562,28 @@ class EmptyShort(IStrategy):
|
||||
|
||||
dispo = round(self.wallets.get_available_stake_amount() + self.pairs[pair]['total_amount'])
|
||||
|
||||
is_short = (trade.enter_tag == 'short')
|
||||
if trade.enter_tag == 'short':
|
||||
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 > 0.01 and \
|
||||
(baisse > self.baisse.value and last_candle[f"close"] > last_candle[self.b30_indicateur.value]) \
|
||||
and last_candle['hapercent'] > 0:
|
||||
if trade.is_short:
|
||||
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 > 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_deriv2_1h'] > 0.0:
|
||||
self.pairs[pair]['force_sell'] = True
|
||||
return 'B30Sht'
|
||||
|
||||
return None
|
||||
# if current_profit < - 0.01 and last_candle['sma60_deriv1'] > 0 and last_candle['sma60_deriv2'] > 0:
|
||||
# self.pairs[pair]['force_sell'] = True
|
||||
# return 'StpSht'
|
||||
|
||||
# if last_candle['sma12_inv_1h'] == -1:
|
||||
# return 'InvSht'
|
||||
# return None
|
||||
|
||||
|
||||
# self.log_trade(
|
||||
# last_candle=last_candle,
|
||||
# date=current_time,
|
||||
@@ -572,28 +597,21 @@ class EmptyShort(IStrategy):
|
||||
# stake=0
|
||||
# )
|
||||
else:
|
||||
if self.pairs[pair]['current_trade'].enter_tag in ['bear', 'Force', 'Range-']:
|
||||
if current_profit < - 0.02 and last_candle[f"close"] <= last_candle['sma60'] and self.wallets.get_available_stake_amount() < 50:
|
||||
self.pairs[pair]['force_sell'] = True
|
||||
return 'smaBF'
|
||||
else:
|
||||
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 is_short:
|
||||
if current_profit > 0.005 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'
|
||||
else:
|
||||
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
|
||||
# if self.pairs[pair]['current_trade'].enter_tag in ['bear', 'Force', 'Range-']:
|
||||
# if current_profit < - 0.02 and last_candle[f"close"] <= last_candle['sma60'] and self.wallets.get_available_stake_amount() < 50:
|
||||
# self.pairs[pair]['force_sell'] = True
|
||||
# return 'smaBF'
|
||||
# else:
|
||||
# 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'
|
||||
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'
|
||||
|
||||
@@ -601,9 +619,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
|
||||
@@ -644,41 +662,41 @@ class EmptyShort(IStrategy):
|
||||
|
||||
return None
|
||||
|
||||
def custom_stoploss(self, pair, trade, current_time, current_rate, current_profit, **kwargs):
|
||||
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
||||
last_candle = dataframe.iloc[-1]
|
||||
profit = trade.calc_profit(current_rate)
|
||||
|
||||
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
|
||||
|
||||
# # print(f'test stop loss {self.stoploss} {last_candle["stop_buying12_1h"]}')
|
||||
# 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}_1h"]
|
||||
# range_max = last_candle[f"max{self.stoploss_timeperiod.value}_1h"]
|
||||
# def custom_stoploss(self, pair, trade, current_time, current_rate, current_profit, **kwargs):
|
||||
# dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
||||
# last_candle = dataframe.iloc[-1]
|
||||
# profit = trade.calc_profit(current_rate)
|
||||
#
|
||||
# if range_max == range_min:
|
||||
# print(f'ranges={range_min}')
|
||||
# return -0.1 # sécurité
|
||||
# candle_at_buy = self.pairs[pair]['last_candle']
|
||||
#
|
||||
# range_pos = (current_rate - range_min) / (range_max - range_min)
|
||||
# # 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
|
||||
#
|
||||
# # # print(f'test stop loss {self.stoploss} {last_candle["stop_buying12_1h"]}')
|
||||
# # 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}_1h"]
|
||||
# # range_max = last_candle[f"max{self.stoploss_timeperiod.value}_1h"]
|
||||
# #
|
||||
# # if range_max == range_min:
|
||||
# # print(f'ranges={range_min}')
|
||||
# # return -0.1 # sécurité
|
||||
# #
|
||||
# # range_pos = (current_rate - range_min) / (range_max - range_min)
|
||||
# #
|
||||
# # if (range_pos > 1):
|
||||
# # return -1
|
||||
# #
|
||||
# # sl_min = -0.02
|
||||
# # sl_max = -0.1 #self.stoploss
|
||||
# #
|
||||
# # dynamic_sl = (sl_min + (1 - range_pos) * (sl_max - sl_min))
|
||||
# #
|
||||
# # print(f'{current_time} Loss ranges={round(range_min,0)} {round(range_max, 0)} range_pos={round(range_pos, 3)} dynamic_sl={round(dynamic_sl, 3)} '
|
||||
# # f'profit={profit} current={current_profit} {self.stoploss_indicator.value} {self.stoploss_timeperiod.value} {last_candle[self.stoploss_indicator.value]}')
|
||||
# #
|
||||
# # return dynamic_sl
|
||||
#
|
||||
# if (range_pos > 1):
|
||||
# return -1
|
||||
#
|
||||
# sl_min = -0.02
|
||||
# sl_max = -0.1 #self.stoploss
|
||||
#
|
||||
# dynamic_sl = (sl_min + (1 - range_pos) * (sl_max - sl_min))
|
||||
#
|
||||
# print(f'{current_time} Loss ranges={round(range_min,0)} {round(range_max, 0)} range_pos={round(range_pos, 3)} dynamic_sl={round(dynamic_sl, 3)} '
|
||||
# f'profit={profit} current={current_profit} {self.stoploss_indicator.value} {self.stoploss_timeperiod.value} {last_candle[self.stoploss_indicator.value]}')
|
||||
#
|
||||
# return dynamic_sl
|
||||
|
||||
return -1
|
||||
|
||||
def informative_pairs(self):
|
||||
# get access to all pairs available in whitelist.
|
||||
@@ -699,12 +717,15 @@ class EmptyShort(IStrategy):
|
||||
dataframe['zero'] = 0
|
||||
|
||||
dataframe[f"percent"] = dataframe['close'].pct_change()
|
||||
for timeperiod in timeperiods:
|
||||
for timeperiod in timeperiods + long_timeperiods:
|
||||
dataframe[f"mid_smooth{timeperiod}"] = dataframe['mid'].rolling(timeperiod).mean()
|
||||
dataframe[f'max{timeperiod}'] = talib.MAX(dataframe['close'], timeperiod=timeperiod)
|
||||
dataframe[f'min{timeperiod}'] = talib.MIN(dataframe['close'], timeperiod=timeperiod)
|
||||
dataframe[f"percent{timeperiod}"] = dataframe['close'].pct_change(timeperiod)
|
||||
dataframe[f"sma{timeperiod}"] = dataframe['mid'].ewm(span=timeperiod, adjust=False).mean()
|
||||
# dataframe[f"sma{timeperiod}"] = dataframe['mid'].ewm(span=timeperiod, adjust=False).mean()
|
||||
ema = dataframe['mid'].ewm(span=timeperiod, adjust=False).mean()
|
||||
dataframe[f"sma{timeperiod}"] = ema.ewm(span=int(timeperiod / 2), adjust=False).mean()
|
||||
|
||||
# dataframe[f"high{timeperiod}"] = dataframe['high'].ewm(span=timeperiod, adjust=False).mean()
|
||||
# dataframe[f"low{timeperiod}"] = dataframe['low'].ewm(span=timeperiod, adjust=False).mean()
|
||||
# dataframe = self.calculateRegression(dataframe, column=f"high{timeperiod}", window=10, degree=1, future_offset=12)
|
||||
@@ -712,15 +733,19 @@ class EmptyShort(IStrategy):
|
||||
|
||||
self.calculeDerivees(dataframe, f"sma{timeperiod}", timeframe=self.timeframe, ema_period=timeperiod)
|
||||
|
||||
dataframe = self.calculateRegression(dataframe, column='mid', window=30, degree=1, future_offset=12)
|
||||
dataframe = self.calculateRegression(dataframe, column='sma24', window=30, degree=1, future_offset=12)
|
||||
self.calculeDerivees(dataframe, "sma24_regression", timeframe=self.timeframe, ema_period=12)
|
||||
dataframe = self.calculateRegression(dataframe, column='mid', window=30, degree=1, future_offset=6)
|
||||
dataframe = self.calculateRegression(dataframe, column='sma120', window=60, degree=2, future_offset=30)
|
||||
# self.calculeDerivees(dataframe, "sma24_regression", timeframe=self.timeframe, ema_period=12)
|
||||
|
||||
dataframe["percent"] = dataframe["mid"].pct_change(1)
|
||||
dataframe["percent3"] = dataframe["mid"].pct_change(3)
|
||||
|
||||
dataframe["volume_mean"] = dataframe["volume"].rolling(20).mean()
|
||||
dataframe["volume_ratio"] = dataframe["volume"] / dataframe["volume_mean"]
|
||||
dataframe['volume2'] = dataframe['volume']
|
||||
dataframe.loc[dataframe['hapercent'] < 0, 'volume2'] *= -1
|
||||
dataframe['volume_spike'] = (abs(dataframe['volume2']) > abs(dataframe['volume2'].rolling(window=20).mean() * 5)) \
|
||||
& (dataframe['volume'].rolling(window=5).max() > 1000)
|
||||
|
||||
dataframe["market_state"] = 0
|
||||
|
||||
@@ -738,7 +763,7 @@ class EmptyShort(IStrategy):
|
||||
informative['haclose'] = heikinashi['close']
|
||||
informative['hapercent'] = (informative['haclose'] - informative['haopen']) / informative['haclose']
|
||||
informative['mid'] = informative['open'] + (informative['close'] - informative['open']) / 2
|
||||
for timeperiod in timeperiods:
|
||||
for timeperiod in [3, 5, 12, 50, 200]:
|
||||
informative[f'max{timeperiod}'] = talib.MAX(informative['close'], timeperiod=timeperiod)
|
||||
informative[f'min{timeperiod}'] = talib.MIN(informative['close'], timeperiod=timeperiod)
|
||||
# informative[f"range{timeperiod}"] = ((informative["close"] - informative[f'min{timeperiod}']) / (informative[f'max{timeperiod}'] - informative[f'min{timeperiod}']))
|
||||
@@ -746,32 +771,34 @@ class EmptyShort(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 = self.calculateRegression(informative, column='mid', window=10, degree=1, future_offset=12)
|
||||
informative = self.calculateRegression(informative, column='sma3', window=10, degree=1, future_offset=12)
|
||||
informative = self.calculateRegression(informative, column='low', window=10, degree=1, future_offset=12)
|
||||
informative = self.calculateRegression(informative, column='mid', window=10, degree=1, future_offset=2)
|
||||
informative = self.calculateRegression(informative, column='sma3', window=10, degree=1, future_offset=2)
|
||||
informative = self.calculateRegression(informative, column='low', window=10, degree=1, future_offset=2)
|
||||
|
||||
for timeperiod in long_timeperiods:
|
||||
informative[f"sma{timeperiod}"] = informative['mid'].ewm(span=timeperiod, adjust=False).mean()
|
||||
self.calculeDerivees(informative, f"sma{timeperiod}", timeframe=self.timeframe, ema_period=timeperiod)
|
||||
# for timeperiod in long_timeperiods:
|
||||
# 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['rsi'] = talib.RSI(informative['close'], timeperiod=14)
|
||||
self.calculeDerivees(informative, f"rsi", timeframe=self.timeframe, ema_period=14)
|
||||
informative['max_rsi_12'] = talib.MAX(informative['rsi'], timeperiod=12)
|
||||
informative['max_rsi_24'] = talib.MAX(informative['rsi'], timeperiod=24)
|
||||
informative['min_rsi_12'] = talib.MIN(informative['rsi'], timeperiod=12)
|
||||
informative['min_rsi_24'] = talib.MIN(informative['rsi'], timeperiod=24)
|
||||
|
||||
informative[f'stop_buying_deb'] = qtpylib.crossed_below(informative[f"sma12"], informative['sma36']) & (informative['close'] < informative['sma100'])
|
||||
informative[f'stop_buying_end'] = qtpylib.crossed_above(informative[f"sma12"], informative['sma36']) & (informative['close'] > informative['sma100'])
|
||||
# informative[f'stop_buying_deb'] = qtpylib.crossed_below(informative[f"sma12"], informative['sma36']) & (informative['close'] < informative['sma100'])
|
||||
# informative[f'stop_buying_end'] = qtpylib.crossed_above(informative[f"sma12"], informative['sma36']) & (informative['close'] > informative['sma100'])
|
||||
|
||||
latched = np.zeros(len(informative), dtype=bool)
|
||||
|
||||
for i in range(1, len(informative)):
|
||||
if informative['stop_buying_deb'].iloc[i]:
|
||||
latched[i] = True
|
||||
elif informative['stop_buying_end'].iloc[i]:
|
||||
latched[i] = False
|
||||
else:
|
||||
latched[i] = latched[i - 1]
|
||||
informative['stop_buying'] = latched
|
||||
# latched = np.zeros(len(informative), dtype=bool)
|
||||
#
|
||||
# for i in range(1, len(informative)):
|
||||
# if informative['stop_buying_deb'].iloc[i]:
|
||||
# latched[i] = True
|
||||
# elif informative['stop_buying_end'].iloc[i]:
|
||||
# latched[i] = False
|
||||
# else:
|
||||
# latched[i] = latched[i - 1]
|
||||
# informative['stop_buying'] = latched
|
||||
informative = self.calculateDownAndUp(informative, limit=0.0001)
|
||||
|
||||
dataframe = merge_informative_pair(dataframe, informative, self.timeframe, "1h", ffill=True)
|
||||
@@ -787,7 +814,7 @@ class EmptyShort(IStrategy):
|
||||
# informative['haclose'] = heikinashi['close']
|
||||
# informative['hapercent'] = (informative['haclose'] - informative['haopen']) / informative['haclose']
|
||||
informative['mid'] = informative['open'] + (informative['close'] - informative['open']) / 2
|
||||
for timeperiod in timeperiods:
|
||||
for timeperiod in [3, 5, 12]:
|
||||
informative[f'max{timeperiod}'] = talib.MAX(informative['close'], timeperiod=timeperiod)
|
||||
informative[f'min{timeperiod}'] = talib.MIN(informative['close'], timeperiod=timeperiod)
|
||||
# informative[f"range{timeperiod}"] = ((informative["close"] - informative[f'min{timeperiod}']) / (informative[f'max{timeperiod}'] - informative[f'min{timeperiod}']))
|
||||
@@ -795,36 +822,42 @@ class EmptyShort(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)
|
||||
|
||||
for timeperiod in long_timeperiods:
|
||||
informative[f"sma{timeperiod}"] = informative['mid'].ewm(span=timeperiod, adjust=False).mean()
|
||||
self.calculeDerivees(informative, f"sma{timeperiod}", timeframe=self.timeframe, ema_period=timeperiod)
|
||||
# for timeperiod in long_timeperiods:
|
||||
# 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['rsi'] = talib.RSI(informative['close'], timeperiod=14)
|
||||
self.calculeDerivees(informative, f"rsi", timeframe=self.timeframe, ema_period=14)
|
||||
informative['max_rsi_12'] = talib.MAX(informative['rsi'], timeperiod=12)
|
||||
informative['max_rsi_24'] = talib.MAX(informative['rsi'], timeperiod=24)
|
||||
|
||||
informative[f'stop_buying_deb'] = qtpylib.crossed_below(informative[f"sma12"], informative['sma36']) & (informative['close'] < informative['sma100'])
|
||||
informative[f'stop_buying_end'] = qtpylib.crossed_above(informative[f"sma12"], informative['sma36']) & (informative['close'] > informative['sma100'])
|
||||
# informative = self.calculateRegression(informative, column='mid', window=10, degree=1, future_offset=2)
|
||||
informative = self.calculateRegression(informative, column='sma3', window=10, degree=1, future_offset=2)
|
||||
# informative = self.calculateRegression(informative, column='low', window=10, degree=1, future_offset=2)
|
||||
|
||||
latched = np.zeros(len(informative), dtype=bool)
|
||||
|
||||
for i in range(1, len(informative)):
|
||||
if informative['stop_buying_deb'].iloc[i]:
|
||||
latched[i] = True
|
||||
elif informative['stop_buying_end'].iloc[i]:
|
||||
latched[i] = False
|
||||
else:
|
||||
latched[i] = latched[i - 1]
|
||||
informative['stop_buying'] = latched
|
||||
# informative[f'stop_buying_deb'] = qtpylib.crossed_below(informative[f"sma12"], informative['sma36']) & (informative['close'] < informative['sma100'])
|
||||
# informative[f'stop_buying_end'] = qtpylib.crossed_above(informative[f"sma12"], informative['sma36']) & (informative['close'] > informative['sma100'])
|
||||
#
|
||||
# latched = np.zeros(len(informative), dtype=bool)
|
||||
#
|
||||
# for i in range(1, len(informative)):
|
||||
# if informative['stop_buying_deb'].iloc[i]:
|
||||
# latched[i] = True
|
||||
# elif informative['stop_buying_end'].iloc[i]:
|
||||
# latched[i] = False
|
||||
# else:
|
||||
# latched[i] = latched[i - 1]
|
||||
# informative['stop_buying'] = latched
|
||||
|
||||
dataframe = merge_informative_pair(dataframe, informative, self.timeframe, "1d", ffill=True)
|
||||
# ######################################################################################################
|
||||
|
||||
range_min = dataframe[f"min12_1h"]
|
||||
range_max = dataframe[f"max48"]
|
||||
range_min = dataframe[f"min12_1d"]
|
||||
range_max = dataframe[f"max12_1d"]
|
||||
|
||||
dataframe[f"range_pos"] = ((dataframe['mid'] - range_min) / (range_max)).rolling(5).mean()
|
||||
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])
|
||||
|
||||
@@ -845,6 +878,8 @@ class EmptyShort(IStrategy):
|
||||
# Compter les baisses / hausses consécutives
|
||||
dataframe = self.calculateDownAndUp(dataframe, limit=0.0001)
|
||||
|
||||
dataframe['sma5_1h'] = dataframe['sma5_1h'].rolling(window=60).mean()
|
||||
|
||||
# récupérer le dernier trade fermé
|
||||
trades = Trade.get_trades_proxy(pair=pair,is_open=False)
|
||||
if trades:
|
||||
@@ -856,261 +891,139 @@ 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)
|
||||
dataframe.loc[
|
||||
(
|
||||
# (dataframe['sma5_1h'] > dataframe['close'])
|
||||
# & (dataframe['sma12_deriv1_1h'] > 0)
|
||||
# & (dataframe['max_rsi_12'] > 45)
|
||||
# & (
|
||||
# (
|
||||
# (dataframe['max_rsi_24_1h'] < 45) & (dataframe['range_pos'] < 0.3)
|
||||
# | (dataframe['sma12_deriv1_1d'] > 0)
|
||||
# )
|
||||
|
||||
# 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['sma60_deriv1'] > 0)
|
||||
& (dataframe['sma60_deriv2'] > 0)
|
||||
# & (dataframe['sma5_deriv1_1h'] > 0)
|
||||
& (dataframe['hapercent'] > 0)
|
||||
& (dataframe['up_count'] >= 3)
|
||||
& (dataframe['up_count'] <= 7)
|
||||
# & (dataframe['open'] < dataframe['sma5_1h'] * 1.01)
|
||||
),
|
||||
['enter_long', 'enter_tag']
|
||||
] = (1, 'long')
|
||||
|
||||
# dataframe.loc[
|
||||
# (
|
||||
# (qtpylib.crossed_above(
|
||||
# dataframe['sma60'],
|
||||
# dataframe['mid_regression_1h'])
|
||||
# )
|
||||
# # (dataframe['sma5_1h'] > dataframe['close'])
|
||||
# (dataframe['sma60_deriv1'] < 0)
|
||||
# & (dataframe['sma60_deriv2'] < 0)
|
||||
# & (dataframe['sma12_deriv1_1h'] > 0)
|
||||
# & (dataframe['volume_spike'] == 1)
|
||||
# & (dataframe['down_count'] >= 3)
|
||||
# & (dataframe['down_count'] < 15)
|
||||
# & (dataframe['hapercent'] > 0)
|
||||
# & (dataframe['sma60'] > dataframe['sma60'].shift(1))
|
||||
# ),
|
||||
# ['enter_long', 'enter_tag']
|
||||
# ] = (1, 'long')
|
||||
# ] = (1, 'long_spike')
|
||||
|
||||
dataframe.loc[
|
||||
(
|
||||
# (qtpylib.crossed_below(
|
||||
# dataframe['sma60'],
|
||||
# dataframe['mid_regression_1h'])
|
||||
# ) &
|
||||
(
|
||||
(dataframe['close'] > dataframe['max5_1h'])
|
||||
& (dataframe['sma12'] < dataframe['sma12'].shift(1))
|
||||
)
|
||||
# (dataframe['sma5_1h'] < dataframe['close'])
|
||||
# & (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['sma60_deriv1'] < 0)
|
||||
& (dataframe['sma60_deriv2'] < 0)
|
||||
# & (dataframe['sma5_deriv1_1h'] < 0)
|
||||
& (dataframe['hapercent'] < 0)
|
||||
# & (dataframe['pct_min_max_12_1d'] > 0.04)
|
||||
& (dataframe['down_count'] <= -3)
|
||||
& (dataframe['down_count'] >= -7)
|
||||
# & (dataframe['open'] > dataframe['sma5_1h'] * 1.01)
|
||||
),
|
||||
['enter_short', 'enter_tag']
|
||||
] = (1, 'short')
|
||||
|
||||
# dataframe.loc[
|
||||
# (
|
||||
# (dataframe['sma5_1h'] < dataframe['close'])
|
||||
# & (dataframe['volume_spike'] == 1)
|
||||
# & (dataframe['down_count'] <= -3)
|
||||
# & (dataframe['down_count'] > -15)
|
||||
# & (dataframe['hapercent'] < 0)
|
||||
# & (dataframe['sma60'] < dataframe['sma60'].shift(1))
|
||||
# ),
|
||||
# ['enter_short', 'enter_tag']
|
||||
# ] = (1, 'short_spike')
|
||||
|
||||
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)
|
||||
|
||||
# no_trade = (
|
||||
# # range
|
||||
# (abs(dataframe['sma50_1h'] - dataframe['sma200_1h']) / dataframe['close'] < 0.002)
|
||||
# # momentum faible
|
||||
# | (abs(dataframe['sma12_deriv1']) < 0.0002)
|
||||
# # RSI neutre
|
||||
# | ((dataframe['rsi'] > 45) & (dataframe['rsi'] < 55))
|
||||
# # faible volatilité
|
||||
# | (dataframe['atr'] / dataframe['close'] < 0.003)
|
||||
# # milieu de range
|
||||
# | (dataframe['range_pos'].between(0.4, 0.6))
|
||||
# )
|
||||
|
||||
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['sma60'],
|
||||
dataframe['mid_regression_1h'])
|
||||
)
|
||||
),
|
||||
['exit_short', 'exit_tag']
|
||||
] = (1, 'long')
|
||||
# (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
|
||||
|
||||
@@ -1143,7 +1056,34 @@ class EmptyShort(IStrategy):
|
||||
dataframe[d1_col] = (dataframe[name] - dataframe[name].shift(3)) / dataframe[name].shift(3)
|
||||
dataframe[d2_col] = (dataframe[d1_col] - dataframe[d1_col].shift(1))
|
||||
|
||||
dataframe[f"{name}{suffixe}_inv"] = np.where(cond_bas, -1, np.where(cond_haut, 1, 0))
|
||||
# dataframe[f"{name}{suffixe}_inv"] = np.where(cond_bas, -1, np.where(cond_haut, 1, 0))
|
||||
|
||||
# col = f"{name}{suffixe}"
|
||||
# slope = dataframe[col].diff()
|
||||
# threshold = 0.02 #slope.rolling(20).std() * 0.1
|
||||
# sign = np.sign(slope.where(slope.abs() > threshold, 0))
|
||||
# turn = sign.diff()
|
||||
# dataframe[f"{name}{suffixe}_inv"] = np.where(turn == -2, 1, np.where(turn == 2, -1, 0))
|
||||
# # dataframe[f"{name}{suffixe}_inv"] = (
|
||||
# # (dataframe[f"{name}{suffixe}_inv"] != 0) &
|
||||
# # (dataframe['slope'].abs() > dataframe['slope'].rolling(20).mean())
|
||||
# # )
|
||||
|
||||
col = f"{name}{suffixe}"
|
||||
# pente (variation)
|
||||
dataframe['slope'] = dataframe[col].diff()
|
||||
# signe de la pente
|
||||
dataframe['sign'] = dataframe['slope'].apply(lambda x: 1 if x > 0 else (-1 if x < 0 else 0))
|
||||
# changement de signe = inversion
|
||||
dataframe[f"{name}{suffixe}_turn"] = dataframe['sign'].diff()
|
||||
# mapping :
|
||||
# +2 -> passage -1 → +1 => creux => inversion haussière
|
||||
# -2 -> passage +1 → -1 => sommet => inversion baissière
|
||||
col_inv = f"{name}{suffixe}_inv"
|
||||
dataframe[col_inv] = 0
|
||||
dataframe.loc[dataframe[f"{name}{suffixe}_turn"] == -2, col_inv] = 1 # sommet (max)
|
||||
dataframe.loc[dataframe[f"{name}{suffixe}_turn"] == 2, col_inv] = -1 # creux (min)
|
||||
|
||||
|
||||
short = d1.rolling(pmin).mean()
|
||||
long = d1.rolling(ema_period).mean()
|
||||
@@ -1446,7 +1386,7 @@ class EmptyShort(IStrategy):
|
||||
# df[f"{column}_regression_deriv2"] = round(
|
||||
# 10 * df[f"{column}_regression_deriv1"].rolling(int(window / 4)).mean().diff(), 4)
|
||||
#
|
||||
# df[f"{column}_future_{future_offset}"] = regression_future_fit
|
||||
df[f"{column}_future_{future_offset}"] = regression_future_fit
|
||||
|
||||
# # 2. Dérivée première = différence entre deux bougies successives
|
||||
# df[f"{column}_future_{future_offset}_deriv1"] = round(100 * df[f"{column}_future_{future_offset}"].diff() / df[f"{column}_future_{future_offset}"], 4)
|
||||
@@ -1457,8 +1397,8 @@ class EmptyShort(IStrategy):
|
||||
return df
|
||||
|
||||
def calculateDownAndUp(self, dataframe, limit=0.0001):
|
||||
dataframe['down'] = dataframe['mid_regression'] <= dataframe['mid_regression'].shift(1)
|
||||
dataframe['up'] = dataframe['mid_regression'] >= dataframe['mid_regression'].shift(1)
|
||||
dataframe['down'] = dataframe['hapercent'] < 0
|
||||
dataframe['up'] = dataframe['hapercent'] > 0
|
||||
dataframe['down_count'] = - dataframe['down'].astype(int) * (
|
||||
dataframe['down'].groupby((dataframe['down'] != dataframe['down'].shift()).cumsum()).cumcount() + 1)
|
||||
dataframe['up_count'] = dataframe['up'].astype(int) * (
|
||||
|
||||
188
EmptyShort.txt
Normal file
188
EmptyShort.txt
Normal file
@@ -0,0 +1,188 @@
|
||||
BACKTESTING REPORT
|
||||
┏━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃ Pair ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃
|
||||
┡━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
|
||||
│ BTC/USDT:USDT │ 54 │ 0.75 │ 422.136 │ 42.21 │ 1 day, 5:07:00 │ 25 0 29 46.3 │
|
||||
│ TOTAL │ 54 │ 0.75 │ 422.136 │ 42.21 │ 1 day, 5:07:00 │ 25 0 29 46.3 │
|
||||
└───────────────┴────────┴──────────────┴─────────────────┴──────────────┴────────────────┴────────────────────────┘
|
||||
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 │ 28 │ 0.72 │ 211.154 │ 21.12 │ 19:27:00 │ 13 0 15 46.4 │
|
||||
│ short_spike │ 25 │ 0.65 │ 174.806 │ 17.48 │ 1 day, 10:54:00 │ 11 0 14 44.0 │
|
||||
│ long │ 1 │ 3.75 │ 36.176 │ 3.62 │ 6 days, 10:57:00 │ 1 0 0 100 │
|
||||
│ TOTAL │ 54 │ 0.75 │ 422.136 │ 42.21 │ 1 day, 5:07:00 │ 25 0 29 46.3 │
|
||||
└─────────────┴─────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┘
|
||||
EXIT REASON STATS
|
||||
┏━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃ Exit Reason ┃ Exits ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃
|
||||
┡━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
|
||||
│ B30Sht │ 24 │ 4.06 │ 1155.077 │ 115.51 │ 1 day, 10:30:00 │ 24 0 0 100 │
|
||||
│ B30 │ 1 │ 3.75 │ 36.176 │ 3.62 │ 6 days, 10:57:00 │ 1 0 0 100 │
|
||||
│ stop_loss │ 29 │ -2.1 │ -769.117 │ -76.91 │ 20:19:00 │ 0 0 29 0 │
|
||||
│ TOTAL │ 54 │ 0.75 │ 422.136 │ 42.21 │ 1 day, 5:07:00 │ 25 0 29 46.3 │
|
||||
└─────────────┴───────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┘
|
||||
MIXED TAG STATS
|
||||
┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃ Enter Tag ┃ Exit Reason ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃
|
||||
┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
|
||||
│ short │ B30Sht │ 13 │ 3.98 │ 601.641 │ 60.16 │ 1 day, 9:46:00 │ 13 0 0 100 │
|
||||
│ short_spike │ B30Sht │ 11 │ 4.16 │ 553.436 │ 55.34 │ 1 day, 11:22:00 │ 11 0 0 100 │
|
||||
│ long │ B30 │ 1 │ 3.75 │ 36.176 │ 3.62 │ 6 days, 10:57:00 │ 1 0 0 100 │
|
||||
│ short_spike │ stop_loss │ 14 │ -2.1 │ -378.630 │ -37.86 │ 1 day, 10:32:00 │ 0 0 14 0 │
|
||||
│ short │ stop_loss │ 15 │ -2.1 │ -390.487 │ -39.05 │ 7:03:00 │ 0 0 15 0 │
|
||||
│ TOTAL │ │ 54 │ 0.75 │ 422.136 │ 42.21 │ 1 day, 5:07:00 │ 25 0 29 46.3 │
|
||||
└─────────────┴─────────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┘
|
||||
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 │ 1 │ -20.15 │ 0.0 │ 0 0 1 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.664 │ 0.0 │ 1 0 0 100 │
|
||||
│ 21/01/2026 │ 1 │ 20.963 │ 0.0 │ 1 0 0 100 │
|
||||
│ 22/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
|
||||
│ 23/01/2026 │ 1 │ -22.227 │ 0.0 │ 0 0 1 0 │
|
||||
│ 24/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
|
||||
│ 25/01/2026 │ 1 │ 32.61 │ 0.0 │ 1 0 0 100 │
|
||||
│ 26/01/2026 │ 1 │ -21.707 │ 0.0 │ 0 0 1 0 │
|
||||
│ 27/01/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
|
||||
│ 28/01/2026 │ 1 │ -21.939 │ 0.0 │ 0 0 1 0 │
|
||||
│ 29/01/2026 │ 1 │ 50.715 │ 0.0 │ 1 0 0 100 │
|
||||
│ 30/01/2026 │ 1 │ -22.455 │ 0.0 │ 0 0 1 0 │
|
||||
│ 31/01/2026 │ 1 │ 59.691 │ 0.0 │ 1 0 0 100 │
|
||||
│ 01/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
|
||||
│ 02/02/2026 │ 3 │ -7.976 │ 0.83 │ 1 0 2 33.3 │
|
||||
│ 03/02/2026 │ 1 │ 22.032 │ 0.0 │ 1 0 0 100 │
|
||||
│ 04/02/2026 │ 1 │ 33.959 │ 0.0 │ 1 0 0 100 │
|
||||
│ 05/02/2026 │ 1 │ 39.293 │ 0.0 │ 1 0 0 100 │
|
||||
│ 06/02/2026 │ 4 │ 74.327 │ 1.89 │ 1 0 3 25.0 │
|
||||
│ 07/02/2026 │ 2 │ 12.485 │ 1.46 │ 1 0 1 50.0 │
|
||||
│ 08/02/2026 │ 2 │ -54.289 │ 0.0 │ 0 0 2 0 │
|
||||
│ 09/02/2026 │ 2 │ -1.939 │ 0.93 │ 1 0 1 50.0 │
|
||||
│ 10/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
|
||||
│ 11/02/2026 │ 4 │ 20.391 │ 1.38 │ 2 0 2 50.0 │
|
||||
│ 12/02/2026 │ 1 │ 35.171 │ 0.0 │ 1 0 0 100 │
|
||||
│ 13/02/2026 │ 1 │ -26.178 │ 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 │ 36.046 │ 0.0 │ 1 0 0 100 │
|
||||
│ 19/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
|
||||
│ 20/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
|
||||
│ 21/02/2026 │ 1 │ -26.642 │ 0.0 │ 0 0 1 0 │
|
||||
│ 22/02/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
|
||||
│ 23/02/2026 │ 1 │ 57.25 │ 0.0 │ 1 0 0 100 │
|
||||
│ 24/02/2026 │ 2 │ 7.103 │ 1.25 │ 1 0 1 50.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 │ 87.891 │ 0.0 │ 1 0 0 100 │
|
||||
│ 01/03/2026 │ 1 │ -29.21 │ 0.0 │ 0 0 1 0 │
|
||||
│ 02/03/2026 │ 1 │ -29.332 │ 0.0 │ 0 0 1 0 │
|
||||
│ 03/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
|
||||
│ 04/03/2026 │ 2 │ -57.218 │ 0.0 │ 0 0 2 0 │
|
||||
│ 05/03/2026 │ 1 │ -27.178 │ 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 │ 104.735 │ 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 │ 1 │ -30.23 │ 0.0 │ 0 0 1 0 │
|
||||
│ 14/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
|
||||
│ 15/03/2026 │ 1 │ -28.727 │ 0.0 │ 0 0 1 0 │
|
||||
│ 16/03/2026 │ 1 │ -27.688 │ 0.0 │ 0 0 1 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 │ 59.772 │ 0.0 │ 1 0 0 100 │
|
||||
│ 22/03/2026 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
|
||||
│ 23/03/2026 │ 1 │ -29.287 │ 0.0 │ 0 0 1 0 │
|
||||
│ 24/03/2026 │ 1 │ 29.577 │ 0.0 │ 1 0 0 100 │
|
||||
│ 25/03/2026 │ 1 │ -27.872 │ 0.0 │ 0 0 1 0 │
|
||||
│ 26/03/2026 │ 1 │ 36.754 │ 0.0 │ 1 0 0 100 │
|
||||
│ 27/03/2026 │ 1 │ 27.777 │ 0.0 │ 1 0 0 100 │
|
||||
└────────────┴────────┴─────────────────┴───────────────┴────────────────────────┘
|
||||
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 │ 54 / 0.64 │
|
||||
│ Starting balance │ 1000 USDT │
|
||||
│ Final balance │ 1422.136 USDT │
|
||||
│ Absolute profit │ 422.136 USDT │
|
||||
│ Total profit % │ 42.21% │
|
||||
│ CAGR % │ 353.68% │
|
||||
│ Sortino │ 36.18 │
|
||||
│ Sharpe │ 2.25 │
|
||||
│ Calmar │ 96.27 │
|
||||
│ SQN │ 1.35 │
|
||||
│ Profit factor │ 1.55 │
|
||||
│ Expectancy (Ratio) │ 7.82 (0.29) │
|
||||
│ Avg. daily profit │ 4.966 USDT │
|
||||
│ Avg. stake amount │ 1224.501 USDT │
|
||||
│ Total trade volume │ 131900.967 USDT │
|
||||
│ │ │
|
||||
│ Long / Short trades │ 1 / 53 │
|
||||
│ Long / Short profit % │ 3.62% / 38.60% │
|
||||
│ Long / Short profit USDT │ 36.176 / 385.960 │
|
||||
│ │ │
|
||||
│ Best Pair │ BTC/USDT:USDT 42.21% │
|
||||
│ Worst Pair │ BTC/USDT:USDT 42.21% │
|
||||
│ Best trade │ BTC/USDT:USDT 13.07% │
|
||||
│ Worst trade │ BTC/USDT:USDT -2.14% │
|
||||
│ Best day │ 104.735 USDT │
|
||||
│ Worst day │ -57.218 USDT │
|
||||
│ Days win/draw/lose │ 22 / 39 / 19 │
|
||||
│ Min/Max/Avg. Duration Winners │ 0d 00:58 / 6d 10:57 / 1d 15:19 │
|
||||
│ Min/Max/Avg. Duration Losers │ 0d 00:18 / 5d 19:41 / 0d 20:19 │
|
||||
│ Max Consecutive Wins / Loss │ 4 / 5 │
|
||||
│ Rejected Entry signals │ 0 │
|
||||
│ Entry/Exit Timeouts │ 0 / 0 │
|
||||
│ │ │
|
||||
│ Min balance │ 1016.026 USDT │
|
||||
│ Max balance │ 1450.263 USDT │
|
||||
│ Max % of account underwater │ 9.86% │
|
||||
│ Absolute drawdown │ 142.938 USDT (9.86%) │
|
||||
│ Drawdown duration │ 4 days 23:26:00 │
|
||||
│ Profit at drawdown start │ 450.263 USDT │
|
||||
│ Profit at drawdown end │ 307.325 USDT │
|
||||
│ Drawdown start │ 2026-02-28 11:00:00 │
|
||||
│ Drawdown end │ 2026-03-05 10:26: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 │ 54 │ 0.75 │ 422.136 │ 42.21 │ 1 day, 5:07:00 │ 25 0 29 46.3 │ 142.938 USDT 9.86% │
|
||||
└────────────┴────────┴──────────────┴─────────────────┴──────────────┴────────────────┴────────────────────────┴─────────────────────┘
|
||||
@@ -5,7 +5,7 @@
|
||||
"0": 10
|
||||
},
|
||||
"stoploss": {
|
||||
"stoploss": -1.0
|
||||
"stoploss": -0.02
|
||||
},
|
||||
"trailing": {
|
||||
"trailing_stop": false,
|
||||
|
||||
1812
FrictradeLearning.py
1812
FrictradeLearning.py
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user