diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py
index 73d9bb382..5ecf5b2a3 100644
--- a/freqtrade/freqtradebot.py
+++ b/freqtrade/freqtradebot.py
@@ -1150,6 +1150,7 @@ class FreqtradeBot(LoggingMixin):
trade.close_rate_requested = limit
trade.sell_reason = sell_reason.sell_reason
if(exit_tag is not None):
+ trade.sell_reason = exit_tag
trade.exit_tag = exit_tag
# In case of market sell orders the order can be closed immediately
if order.get('status', 'unknown') in ('closed', 'expired'):
@@ -1191,8 +1192,8 @@ class FreqtradeBot(LoggingMixin):
'current_rate': current_rate,
'profit_amount': profit_trade,
'profit_ratio': profit_ratio,
+ 'buy_tag': trade.buy_tag,
'sell_reason': trade.sell_reason,
- 'exit_tag': trade.exit_tag,
'open_date': trade.open_date,
'close_date': trade.close_date or datetime.utcnow(),
'stake_currency': self.config['stake_currency'],
@@ -1235,8 +1236,8 @@ class FreqtradeBot(LoggingMixin):
'current_rate': current_rate,
'profit_amount': profit_trade,
'profit_ratio': profit_ratio,
+ 'buy_tag': trade.buy_tag,
'sell_reason': trade.sell_reason,
- 'exit_tag': trade.exit_tag,
'open_date': trade.open_date,
'close_date': trade.close_date or datetime.now(timezone.utc),
'stake_currency': self.config['stake_currency'],
diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py
index 6c2a20cb1..827be4d76 100644
--- a/freqtrade/optimize/backtesting.py
+++ b/freqtrade/optimize/backtesting.py
@@ -360,11 +360,10 @@ class Backtesting:
if sell.sell_flag:
trade.close_date = sell_candle_time
- if(sell_row[EXIT_TAG_IDX] is not None):
- trade.exit_tag = sell_row[EXIT_TAG_IDX]
- else:
- trade.exit_tag = None
trade.sell_reason = sell.sell_reason
+ if(sell_row[EXIT_TAG_IDX] is not None):
+ trade.sell_reason = sell_row[EXIT_TAG_IDX]
+ trade.exit_tag = sell_row[EXIT_TAG_IDX]
trade_dur = int((trade.close_date_utc - trade.open_date_utc).total_seconds() // 60)
closerate = self._get_close_rate(sell_row, trade, sell, trade_dur)
diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py
index 30005f524..67dacd7c6 100644
--- a/freqtrade/optimize/optimize_reports.py
+++ b/freqtrade/optimize/optimize_reports.py
@@ -387,8 +387,6 @@ def generate_strategy_stats(btdata: Dict[str, DataFrame],
buy_tag_results = generate_tag_metrics("buy_tag", starting_balance=starting_balance,
results=results, skip_nan=False)
- exit_tag_results = generate_tag_metrics("exit_tag", starting_balance=starting_balance,
- results=results, skip_nan=False)
sell_reason_stats = generate_sell_reason_stats(max_open_trades=max_open_trades,
results=results)
@@ -414,7 +412,6 @@ def generate_strategy_stats(btdata: Dict[str, DataFrame],
'worst_pair': worst_pair,
'results_per_pair': pair_results,
'results_per_buy_tag': buy_tag_results,
- 'results_per_exit_tag': exit_tag_results,
'sell_reason_summary': sell_reason_stats,
'left_open_trades': left_open_results,
'total_trades': len(results),
@@ -744,15 +741,6 @@ def show_backtest_result(strategy: str, results: Dict[str, Any], stake_currency:
print(' BUY TAG STATS '.center(len(table.splitlines()[0]), '='))
print(table)
- table = text_table_tags(
- "exit_tag",
- results['results_per_exit_tag'],
- stake_currency=stake_currency)
-
- if isinstance(table, str) and len(table) > 0:
- print(' SELL TAG STATS '.center(len(table.splitlines()[0]), '='))
- print(table)
-
table = text_table_sell_reason(sell_reason_stats=results['sell_reason_summary'],
stake_currency=stake_currency)
if isinstance(table, str) and len(table) > 0:
diff --git a/freqtrade/persistence/models.py b/freqtrade/persistence/models.py
index 945201982..e03830d7f 100644
--- a/freqtrade/persistence/models.py
+++ b/freqtrade/persistence/models.py
@@ -325,7 +325,6 @@ class LocalTrade():
'profit_pct': round(self.close_profit * 100, 2) if self.close_profit else None,
'profit_abs': self.close_profit_abs,
- # +str(self.sell_reason) ## CHANGE TO BUY TAG IF NEEDED
'sell_reason': (f' ({self.sell_reason})' if self.sell_reason else ''),
'exit_tag': (f' ({self.exit_tag})' if self.exit_tag else ''),
'sell_order_status': self.sell_order_status,
@@ -904,15 +903,15 @@ class Trade(_DECL_BASE, LocalTrade):
]
@staticmethod
- def get_exit_tag_performance(pair: str) -> List[Dict[str, Any]]:
+ def get_sell_reason_performance(pair: str) -> List[Dict[str, Any]]:
"""
- Returns List of dicts containing all Trades, based on exit tag performance
+ Returns List of dicts containing all Trades, based on sell reason performance
Can either be average for all pairs or a specific pair provided
NOTE: Not supported in Backtesting.
"""
if(pair is not None):
tag_perf = Trade.query.with_entities(
- Trade.exit_tag,
+ Trade.sell_reason,
func.sum(Trade.close_profit).label('profit_sum'),
func.sum(Trade.close_profit_abs).label('profit_sum_abs'),
func.count(Trade.pair).label('count')
@@ -922,29 +921,29 @@ class Trade(_DECL_BASE, LocalTrade):
.all()
else:
tag_perf = Trade.query.with_entities(
- Trade.exit_tag,
+ Trade.sell_reason,
func.sum(Trade.close_profit).label('profit_sum'),
func.sum(Trade.close_profit_abs).label('profit_sum_abs'),
func.count(Trade.pair).label('count')
).filter(Trade.is_open.is_(False))\
- .group_by(Trade.exit_tag) \
+ .group_by(Trade.sell_reason) \
.order_by(desc('profit_sum_abs')) \
.all()
return [
{
- 'exit_tag': exit_tag if exit_tag is not None else "Other",
+ 'sell_reason': sell_reason if sell_reason is not None else "Other",
'profit': profit,
'profit_abs': profit_abs,
'count': count
}
- for exit_tag, profit, profit_abs, count in tag_perf
+ for sell_reason, profit, profit_abs, count in tag_perf
]
@staticmethod
def get_mix_tag_performance(pair: str) -> List[Dict[str, Any]]:
"""
- Returns List of dicts containing all Trades, based on buy_tag + exit_tag performance
+ Returns List of dicts containing all Trades, based on buy_tag + sell_reason performance
Can either be average for all pairs or a specific pair provided
NOTE: Not supported in Backtesting.
"""
@@ -952,7 +951,7 @@ class Trade(_DECL_BASE, LocalTrade):
tag_perf = Trade.query.with_entities(
Trade.id,
Trade.buy_tag,
- Trade.exit_tag,
+ Trade.sell_reason,
func.sum(Trade.close_profit).label('profit_sum'),
func.sum(Trade.close_profit_abs).label('profit_sum_abs'),
func.count(Trade.pair).label('count')
@@ -965,7 +964,7 @@ class Trade(_DECL_BASE, LocalTrade):
tag_perf = Trade.query.with_entities(
Trade.id,
Trade.buy_tag,
- Trade.exit_tag,
+ Trade.sell_reason,
func.sum(Trade.close_profit).label('profit_sum'),
func.sum(Trade.close_profit_abs).label('profit_sum_abs'),
func.count(Trade.pair).label('count')
@@ -975,12 +974,12 @@ class Trade(_DECL_BASE, LocalTrade):
.all()
return_list = []
- for id, buy_tag, exit_tag, profit, profit_abs, count in tag_perf:
+ for id, buy_tag, sell_reason, profit, profit_abs, count in tag_perf:
buy_tag = buy_tag if buy_tag is not None else "Other"
- exit_tag = exit_tag if exit_tag is not None else "Other"
+ sell_reason = sell_reason if sell_reason is not None else "Other"
- if(exit_tag is not None and buy_tag is not None):
- mix_tag = buy_tag + " " + exit_tag
+ if(sell_reason is not None and buy_tag is not None):
+ mix_tag = buy_tag + " " + sell_reason
i = 0
if not any(item["mix_tag"] == mix_tag for item in return_list):
return_list.append({'mix_tag': mix_tag,
@@ -990,8 +989,6 @@ class Trade(_DECL_BASE, LocalTrade):
else:
while i < len(return_list):
if return_list[i]["mix_tag"] == mix_tag:
- print("item below")
- print(return_list[i])
return_list[i] = {
'mix_tag': mix_tag,
'profit': profit + return_list[i]["profit"],
diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py
index 508ce6894..2a664e7bc 100644
--- a/freqtrade/rpc/rpc.py
+++ b/freqtrade/rpc/rpc.py
@@ -161,6 +161,8 @@ class RPC:
current_rate = NAN
else:
current_rate = trade.close_rate
+
+ buy_tag = trade.buy_tag
current_profit = trade.calc_profit_ratio(current_rate)
current_profit_abs = trade.calc_profit(current_rate)
current_profit_fiat: Optional[float] = None
@@ -191,6 +193,7 @@ class RPC:
profit_pct=round(current_profit * 100, 2),
profit_abs=current_profit_abs,
profit_fiat=current_profit_fiat,
+ buy_tag=buy_tag,
stoploss_current_dist=stoploss_current_dist,
stoploss_current_dist_ratio=round(stoploss_current_dist_ratio, 8),
@@ -696,19 +699,19 @@ class RPC:
[x.update({'profit': round(x['profit'] * 100, 2)}) for x in buy_tags]
return buy_tags
- def _rpc_exit_tag_performance(self, pair: str) -> List[Dict[str, Any]]:
+ def _rpc_sell_reason_performance(self, pair: str) -> List[Dict[str, Any]]:
"""
- Handler for sell tag performance.
+ Handler for sell reason performance.
Shows a performance statistic from finished trades
"""
- exit_tags = Trade.get_exit_tag_performance(pair)
+ sell_reasons = Trade.get_sell_reason_performance(pair)
# Round and convert to %
- [x.update({'profit': round(x['profit'] * 100, 2)}) for x in exit_tags]
- return exit_tags
+ [x.update({'profit': round(x['profit'] * 100, 2)}) for x in sell_reasons]
+ return sell_reasons
def _rpc_mix_tag_performance(self, pair: str) -> List[Dict[str, Any]]:
"""
- Handler for mix tag performance.
+ Handler for mix tag (buy_tag + exit_tag) performance.
Shows a performance statistic from finished trades
"""
mix_tags = Trade.get_mix_tag_performance(pair)
diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py
index 0a84b588a..2352d366a 100644
--- a/freqtrade/rpc/telegram.py
+++ b/freqtrade/rpc/telegram.py
@@ -156,7 +156,7 @@ class Telegram(RPCHandler):
CommandHandler('delete', self._delete_trade),
CommandHandler('performance', self._performance),
CommandHandler('buys', self._buy_tag_performance),
- CommandHandler('sells', self._exit_tag_performance),
+ CommandHandler('sells', self._sell_reason_performance),
CommandHandler('mix_tags', self._mix_tag_performance),
CommandHandler('stats', self._stats),
CommandHandler('daily', self._daily),
@@ -244,8 +244,8 @@ class Telegram(RPCHandler):
msg['duration'] = msg['close_date'].replace(
microsecond=0) - msg['open_date'].replace(microsecond=0)
msg['duration_min'] = msg['duration'].total_seconds() / 60
- msg['tags'] = self._get_tags_string(msg)
+ msg['buy_tag'] = msg['buy_tag'] if "buy_tag" in msg.keys() else None
msg['emoji'] = self._get_sell_emoji(msg)
# Check if all sell properties are available.
@@ -261,7 +261,7 @@ class Telegram(RPCHandler):
message = ("{emoji} *{exchange}:* Selling {pair} (#{trade_id})\n"
"*Profit:* `{profit_percent:.2f}%{profit_extra}`\n"
- "{tags}"
+ "*Buy Tag:* `{buy_tag}`\n"
"*Sell Reason:* `{sell_reason}`\n"
"*Duration:* `{duration} ({duration_min:.1f} min)`\n"
"*Amount:* `{amount:.8f}`\n"
@@ -357,18 +357,6 @@ class Telegram(RPCHandler):
else:
return "\N{CROSS MARK}"
- def _get_tags_string(self, msg):
- """
- Get string lines for buy/sell tags to display when a sell is made
- """
- tag_lines = ""
-
- if ("buy_tag" in msg.keys() and msg['buy_tag'] is not None):
- tag_lines += ("*Buy Tag:* `{buy_tag}`\n").format(msg['buy_tag'])
- if ("exit_tag" in msg.keys() and msg['exit_tag'] is not None):
- tag_lines += ("*Sell Tag:* `{exit_tag}`\n").format(msg['exit_tag'])
- return tag_lines
-
@authorized_only
def _status(self, update: Update, context: CallbackContext) -> None:
"""
@@ -401,7 +389,6 @@ class Telegram(RPCHandler):
"*Current Pair:* {pair}",
"*Amount:* `{amount} ({stake_amount} {base_currency})`",
"*Buy Tag:* `{buy_tag}`" if r['buy_tag'] else "",
- "*Sell Tag:* `{exit_tag}`" if r['exit_tag'] else "",
"*Open Rate:* `{open_rate:.8f}`",
"*Close Rate:* `{close_rate}`" if r['close_rate'] else "",
"*Current Rate:* `{current_rate:.8f}`",
@@ -925,7 +912,7 @@ class Telegram(RPCHandler):
self._send_msg(str(e))
@authorized_only
- def _exit_tag_performance(self, update: Update, context: CallbackContext) -> None:
+ def _sell_reason_performance(self, update: Update, context: CallbackContext) -> None:
"""
Handler for /sells.
Shows a performance statistic from finished trades
@@ -938,11 +925,11 @@ class Telegram(RPCHandler):
if context.args:
pair = context.args[0]
- trades = self._rpc._rpc_exit_tag_performance(pair)
- output = "Sell Tag Performance:\n"
+ trades = self._rpc._rpc_sell_reason_performance(pair)
+ output = "Sell Reason Performance:\n"
for i, trade in enumerate(trades):
stat_line = (
- f"{i+1}.\t {trade['exit_tag']}\t"
+ f"{i+1}.\t {trade['sell_reason']}\t"
f"{round_coin_value(trade['profit_abs'], self._config['stake_currency'])} "
f"({trade['profit']:.2f}%) "
f"({trade['count']})
\n")
@@ -954,7 +941,7 @@ class Telegram(RPCHandler):
output += stat_line
self._send_msg(output, parse_mode=ParseMode.HTML,
- reload_able=True, callback_path="update_exit_tag_performance",
+ reload_able=True, callback_path="update_sell_reason_performance",
query=update.callback_query)
except RPCException as e:
self._send_msg(str(e))