sell_reason -> exit_reason
This commit is contained in:
@@ -108,7 +108,7 @@ class SellReason(BaseModel):
|
||||
|
||||
|
||||
class Stats(BaseModel):
|
||||
sell_reasons: Dict[str, SellReason]
|
||||
exit_reasons: Dict[str, SellReason]
|
||||
durations: Dict[str, Union[str, float]]
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@ class TradeSchema(BaseModel):
|
||||
profit_pct: Optional[float]
|
||||
profit_abs: Optional[float]
|
||||
profit_fiat: Optional[float]
|
||||
sell_reason: Optional[str]
|
||||
exit_reason: Optional[str]
|
||||
exit_order_status: Optional[str]
|
||||
stop_loss_abs: Optional[float]
|
||||
stop_loss_ratio: Optional[float]
|
||||
|
||||
@@ -416,11 +416,11 @@ class RPC:
|
||||
return 'draws'
|
||||
trades = trades = Trade.get_trades([Trade.is_open.is_(False)])
|
||||
# Sell reason
|
||||
sell_reasons = {}
|
||||
exit_reasons = {}
|
||||
for trade in trades:
|
||||
if trade.sell_reason not in sell_reasons:
|
||||
sell_reasons[trade.sell_reason] = {'wins': 0, 'losses': 0, 'draws': 0}
|
||||
sell_reasons[trade.sell_reason][trade_win_loss(trade)] += 1
|
||||
if trade.exit_reason not in exit_reasons:
|
||||
exit_reasons[trade.exit_reason] = {'wins': 0, 'losses': 0, 'draws': 0}
|
||||
exit_reasons[trade.exit_reason][trade_win_loss(trade)] += 1
|
||||
|
||||
# Duration
|
||||
dur: Dict[str, List[int]] = {'wins': [], 'draws': [], 'losses': []}
|
||||
@@ -434,7 +434,7 @@ class RPC:
|
||||
losses_dur = sum(dur['losses']) / len(dur['losses']) if len(dur['losses']) > 0 else 'N/A'
|
||||
|
||||
durations = {'wins': wins_dur, 'draws': draws_dur, 'losses': losses_dur}
|
||||
return {'sell_reasons': sell_reasons, 'durations': durations}
|
||||
return {'exit_reasons': exit_reasons, 'durations': durations}
|
||||
|
||||
def _rpc_trade_statistics(
|
||||
self, stake_currency: str, fiat_display_currency: str,
|
||||
@@ -672,12 +672,12 @@ class RPC:
|
||||
closing_side = "buy" if trade.is_short else "sell"
|
||||
current_rate = self._freqtrade.exchange.get_rate(
|
||||
trade.pair, refresh=False, side=closing_side)
|
||||
sell_reason = SellCheckTuple(sell_type=SellType.FORCE_SELL)
|
||||
exit_reason = SellCheckTuple(sell_type=SellType.FORCE_SELL)
|
||||
order_type = ordertype or self._freqtrade.strategy.order_types.get(
|
||||
"forcesell", self._freqtrade.strategy.order_types["sell"])
|
||||
|
||||
self._freqtrade.execute_trade_exit(
|
||||
trade, current_rate, sell_reason, ordertype=order_type)
|
||||
trade, current_rate, exit_reason, ordertype=order_type)
|
||||
# ---- EOF def _exec_forcesell ----
|
||||
|
||||
if self._freqtrade.state != State.RUNNING:
|
||||
@@ -799,16 +799,16 @@ class RPC:
|
||||
"""
|
||||
return Trade.get_enter_tag_performance(pair)
|
||||
|
||||
def _rpc_sell_reason_performance(self, pair: Optional[str]) -> List[Dict[str, Any]]:
|
||||
def _rpc_exit_reason_performance(self, pair: Optional[str]) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
Handler for sell reason performance.
|
||||
Shows a performance statistic from finished trades
|
||||
"""
|
||||
return Trade.get_sell_reason_performance(pair)
|
||||
return Trade.get_exit_reason_performance(pair)
|
||||
|
||||
def _rpc_mix_tag_performance(self, pair: Optional[str]) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
Handler for mix tag (enter_tag + sell_reason) performance.
|
||||
Handler for mix tag (enter_tag + exit_reason) performance.
|
||||
Shows a performance statistic from finished trades
|
||||
"""
|
||||
mix_tags = Trade.get_mix_tag_performance(pair)
|
||||
@@ -872,7 +872,7 @@ class RPC:
|
||||
else:
|
||||
errors[pair] = {
|
||||
'error_msg': f"Pair {pair} is not in the current blacklist."
|
||||
}
|
||||
}
|
||||
resp = self._rpc_blacklist()
|
||||
resp['errors'] = errors
|
||||
return resp
|
||||
|
||||
@@ -156,7 +156,7 @@ class Telegram(RPCHandler):
|
||||
CommandHandler('delete', self._delete_trade),
|
||||
CommandHandler('performance', self._performance),
|
||||
CommandHandler(['buys', 'entries'], self._enter_tag_performance),
|
||||
CommandHandler('sells', self._sell_reason_performance),
|
||||
CommandHandler('sells', self._exit_reason_performance),
|
||||
CommandHandler('mix_tags', self._mix_tag_performance),
|
||||
CommandHandler('stats', self._stats),
|
||||
CommandHandler('daily', self._daily),
|
||||
@@ -186,8 +186,8 @@ class Telegram(RPCHandler):
|
||||
CallbackQueryHandler(self._performance, pattern='update_performance'),
|
||||
CallbackQueryHandler(self._enter_tag_performance,
|
||||
pattern='update_enter_tag_performance'),
|
||||
CallbackQueryHandler(self._sell_reason_performance,
|
||||
pattern='update_sell_reason_performance'),
|
||||
CallbackQueryHandler(self._exit_reason_performance,
|
||||
pattern='update_exit_reason_performance'),
|
||||
CallbackQueryHandler(self._mix_tag_performance, pattern='update_mix_tag_performance'),
|
||||
CallbackQueryHandler(self._count, pattern='update_count'),
|
||||
CallbackQueryHandler(self._forcebuy_inline),
|
||||
@@ -284,7 +284,7 @@ class Telegram(RPCHandler):
|
||||
f"*{'Profit' if is_fill else 'Unrealized Profit'}:* "
|
||||
f"`{msg['profit_ratio']:.2%}{msg['profit_extra']}`\n"
|
||||
f"*Enter Tag:* `{msg['enter_tag']}`\n"
|
||||
f"*Exit Reason:* `{msg['sell_reason']}`\n"
|
||||
f"*Exit Reason:* `{msg['exit_reason']}`\n"
|
||||
f"*Duration:* `{msg['duration']} ({msg['duration_min']:.1f} min)`\n"
|
||||
f"*Direction:* `{msg['direction']}`\n"
|
||||
f"{msg['leverage_text']}"
|
||||
@@ -355,7 +355,7 @@ class Telegram(RPCHandler):
|
||||
if isinstance(sell_noti, str):
|
||||
noti = sell_noti
|
||||
else:
|
||||
noti = sell_noti.get(str(msg['sell_reason']), default_noti)
|
||||
noti = sell_noti.get(str(msg['exit_reason']), default_noti)
|
||||
else:
|
||||
noti = self._config['telegram'] \
|
||||
.get('notification_settings', {}).get(str(msg_type), default_noti)
|
||||
@@ -378,7 +378,7 @@ class Telegram(RPCHandler):
|
||||
return "\N{ROCKET}"
|
||||
elif float(msg['profit_percent']) >= 0.0:
|
||||
return "\N{EIGHT SPOKED ASTERISK}"
|
||||
elif msg['sell_reason'] == "stop_loss":
|
||||
elif msg['exit_reason'] == "stop_loss":
|
||||
return "\N{WARNING SIGN}"
|
||||
else:
|
||||
return "\N{CROSS MARK}"
|
||||
@@ -697,23 +697,23 @@ class Telegram(RPCHandler):
|
||||
'force_sell': 'Forcesell',
|
||||
'emergency_sell': 'Emergency Sell',
|
||||
}
|
||||
sell_reasons_tabulate = [
|
||||
exit_reasons_tabulate = [
|
||||
[
|
||||
reason_map.get(reason, reason),
|
||||
sum(count.values()),
|
||||
count['wins'],
|
||||
count['losses']
|
||||
] for reason, count in stats['sell_reasons'].items()
|
||||
] for reason, count in stats['exit_reasons'].items()
|
||||
]
|
||||
sell_reasons_msg = 'No trades yet.'
|
||||
for reason in chunks(sell_reasons_tabulate, 25):
|
||||
sell_reasons_msg = tabulate(
|
||||
exit_reasons_msg = 'No trades yet.'
|
||||
for reason in chunks(exit_reasons_tabulate, 25):
|
||||
exit_reasons_msg = tabulate(
|
||||
reason,
|
||||
headers=['Sell Reason', 'Sells', 'Wins', 'Losses']
|
||||
)
|
||||
if len(sell_reasons_tabulate) > 25:
|
||||
self._send_msg(sell_reasons_msg, ParseMode.MARKDOWN)
|
||||
sell_reasons_msg = ''
|
||||
if len(exit_reasons_tabulate) > 25:
|
||||
self._send_msg(exit_reasons_msg, ParseMode.MARKDOWN)
|
||||
exit_reasons_msg = ''
|
||||
|
||||
durations = stats['durations']
|
||||
duration_msg = tabulate(
|
||||
@@ -725,7 +725,7 @@ class Telegram(RPCHandler):
|
||||
],
|
||||
headers=['', 'Avg. Duration']
|
||||
)
|
||||
msg = (f"""```\n{sell_reasons_msg}```\n```\n{duration_msg}```""")
|
||||
msg = (f"""```\n{exit_reasons_msg}```\n```\n{duration_msg}```""")
|
||||
|
||||
self._send_msg(msg, ParseMode.MARKDOWN)
|
||||
|
||||
@@ -1026,7 +1026,7 @@ class Telegram(RPCHandler):
|
||||
self._send_msg(str(e))
|
||||
|
||||
@authorized_only
|
||||
def _sell_reason_performance(self, update: Update, context: CallbackContext) -> None:
|
||||
def _exit_reason_performance(self, update: Update, context: CallbackContext) -> None:
|
||||
"""
|
||||
Handler for /sells.
|
||||
Shows a performance statistic from finished trades
|
||||
@@ -1039,11 +1039,11 @@ class Telegram(RPCHandler):
|
||||
if context.args and isinstance(context.args[0], str):
|
||||
pair = context.args[0]
|
||||
|
||||
trades = self._rpc._rpc_sell_reason_performance(pair)
|
||||
trades = self._rpc._rpc_exit_reason_performance(pair)
|
||||
output = "<b>Sell Reason Performance:</b>\n"
|
||||
for i, trade in enumerate(trades):
|
||||
stat_line = (
|
||||
f"{i+1}.\t <code>{trade['sell_reason']}\t"
|
||||
f"{i+1}.\t <code>{trade['exit_reason']}\t"
|
||||
f"{round_coin_value(trade['profit_abs'], self._config['stake_currency'])} "
|
||||
f"({trade['profit_ratio']:.2%}) "
|
||||
f"({trade['count']})</code>\n")
|
||||
@@ -1055,7 +1055,7 @@ class Telegram(RPCHandler):
|
||||
output += stat_line
|
||||
|
||||
self._send_msg(output, parse_mode=ParseMode.HTML,
|
||||
reload_able=True, callback_path="update_sell_reason_performance",
|
||||
reload_able=True, callback_path="update_exit_reason_performance",
|
||||
query=update.callback_query)
|
||||
except RPCException as e:
|
||||
self._send_msg(str(e))
|
||||
|
||||
Reference in New Issue
Block a user