Improve some telegram terminology

This commit is contained in:
Matthias 2022-04-03 10:39:35 +02:00
parent 157f8f8139
commit cd78792f48
8 changed files with 42 additions and 39 deletions

View File

@ -180,7 +180,9 @@ official commands. You can ask at any moment for help with `/help`.
| `/daily <n>` | Shows profit or loss per day, over the last n days (n defaults to 7) | `/daily <n>` | Shows profit or loss per day, over the last n days (n defaults to 7)
| `/weekly <n>` | Shows profit or loss per week, over the last n weeks (n defaults to 8) | `/weekly <n>` | Shows profit or loss per week, over the last n weeks (n defaults to 8)
| `/monthly <n>` | Shows profit or loss per month, over the last n months (n defaults to 6) | `/monthly <n>` | Shows profit or loss per month, over the last n months (n defaults to 6)
| `/stats` | Shows Wins / losses by Sell reason as well as Avg. holding durations for buys and sells | `/stats` | Shows Wins / losses by Exit reason as well as Avg. holding durations for buys and sells
| `/exits` | Shows Wins / losses by Exit reason as well as Avg. holding durations for buys and sells
| `/entries` | Shows Wins / losses by Exit reason as well as Avg. holding durations for buys and sells
| `/whitelist` | Show the current whitelist | `/whitelist` | Show the current whitelist
| `/blacklist [pair]` | Show the current blacklist, or adds a pair to the blacklist. | `/blacklist [pair]` | Show the current blacklist, or adds a pair to the blacklist.
| `/edge` | Show validated pairs by Edge if it is enabled. | `/edge` | Show validated pairs by Edge if it is enabled.

View File

@ -234,7 +234,7 @@ def check_migrate(engine, decl_base, previous_tables) -> None:
# Migrates both trades and orders table! # Migrates both trades and orders table!
# if ('orders' not in previous_tables # if ('orders' not in previous_tables
# or not has_column(cols_orders, 'leverage')): # or not has_column(cols_orders, 'leverage')):
if not has_column(cols, 'liquidation_price'): if not has_column(cols, 'exit_reason'):
logger.info(f"Running database migration for trades - " logger.info(f"Running database migration for trades - "
f"backup: {table_back_name}, {order_table_bak_name}") f"backup: {table_back_name}, {order_table_bak_name}")
migrate_trades_and_orders_table( migrate_trades_and_orders_table(

View File

@ -1289,7 +1289,7 @@ class Trade(_DECL_BASE, LocalTrade):
] ]
@staticmethod @staticmethod
def get_sell_reason_performance(pair: Optional[str]) -> List[Dict[str, Any]]: def get_exit_reason_performance(pair: Optional[str]) -> List[Dict[str, Any]]:
""" """
Returns List of dicts containing all Trades, based on sell reason 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 Can either be average for all pairs or a specific pair provided
@ -1312,13 +1312,13 @@ class Trade(_DECL_BASE, LocalTrade):
return [ return [
{ {
'sell_reason': sell_reason if sell_reason is not None else "Other", 'exit_reason': exit_reason if exit_reason is not None else "Other",
'profit_ratio': profit, 'profit_ratio': profit,
'profit_pct': round(profit * 100, 2), 'profit_pct': round(profit * 100, 2),
'profit_abs': profit_abs, 'profit_abs': profit_abs,
'count': count 'count': count
} }
for sell_reason, profit, profit_abs, count in sell_tag_perf for exit_reason, profit, profit_abs, count in sell_tag_perf
] ]
@staticmethod @staticmethod

View File

@ -848,12 +848,12 @@ class RPC:
""" """
return Trade.get_enter_tag_performance(pair) 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. Handler for sell reason performance.
Shows a performance statistic from finished trades 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]]: def _rpc_mix_tag_performance(self, pair: Optional[str]) -> List[Dict[str, Any]]:
""" """

View File

@ -108,7 +108,8 @@ class Telegram(RPCHandler):
# this needs refactoring of the whole telegram module (same # this needs refactoring of the whole telegram module (same
# problem in _help()). # problem in _help()).
valid_keys: List[str] = [r'/start$', r'/stop$', r'/status$', r'/status table$', valid_keys: List[str] = [r'/start$', r'/stop$', r'/status$', r'/status table$',
r'/trades$', r'/performance$', r'/buys', r'/sells', r'/mix_tags', r'/trades$', r'/performance$', r'/buys', r'/entries',
r'/sells', r'/exits', r'/mix_tags',
r'/daily$', r'/daily \d+$', r'/profit$', r'/profit \d+', r'/daily$', r'/daily \d+$', r'/profit$', r'/profit \d+',
r'/stats$', r'/count$', r'/locks$', r'/balance$', r'/stats$', r'/count$', r'/locks$', r'/balance$',
r'/stopbuy$', r'/reload_config$', r'/show_config$', r'/stopbuy$', r'/reload_config$', r'/show_config$',
@ -161,7 +162,7 @@ class Telegram(RPCHandler):
CommandHandler('delete', self._delete_trade), CommandHandler('delete', self._delete_trade),
CommandHandler('performance', self._performance), CommandHandler('performance', self._performance),
CommandHandler(['buys', 'entries'], self._enter_tag_performance), CommandHandler(['buys', 'entries'], self._enter_tag_performance),
CommandHandler('sells', self._sell_reason_performance), CommandHandler(['sells', 'exits'], self._exit_reason_performance),
CommandHandler('mix_tags', self._mix_tag_performance), CommandHandler('mix_tags', self._mix_tag_performance),
CommandHandler('stats', self._stats), CommandHandler('stats', self._stats),
CommandHandler('daily', self._daily), CommandHandler('daily', self._daily),
@ -192,8 +193,8 @@ class Telegram(RPCHandler):
CallbackQueryHandler(self._performance, pattern='update_performance'), CallbackQueryHandler(self._performance, pattern='update_performance'),
CallbackQueryHandler(self._enter_tag_performance, CallbackQueryHandler(self._enter_tag_performance,
pattern='update_enter_tag_performance'), pattern='update_enter_tag_performance'),
CallbackQueryHandler(self._sell_reason_performance, CallbackQueryHandler(self._exit_reason_performance,
pattern='update_sell_reason_performance'), pattern='update_exit_reason_performance'),
CallbackQueryHandler(self._mix_tag_performance, pattern='update_mix_tag_performance'), CallbackQueryHandler(self._mix_tag_performance, pattern='update_mix_tag_performance'),
CallbackQueryHandler(self._count, pattern='update_count'), CallbackQueryHandler(self._count, pattern='update_count'),
CallbackQueryHandler(self._forceenter_inline), CallbackQueryHandler(self._forceenter_inline),
@ -1101,7 +1102,7 @@ class Telegram(RPCHandler):
pair = context.args[0] pair = context.args[0]
trades = self._rpc._rpc_enter_tag_performance(pair) trades = self._rpc._rpc_enter_tag_performance(pair)
output = "<b>Buy Tag Performance:</b>\n" output = "<b>Entry Tag Performance:</b>\n"
for i, trade in enumerate(trades): for i, trade in enumerate(trades):
stat_line = ( stat_line = (
f"{i+1}.\t <code>{trade['enter_tag']}\t" f"{i+1}.\t <code>{trade['enter_tag']}\t"
@ -1122,7 +1123,7 @@ class Telegram(RPCHandler):
self._send_msg(str(e)) self._send_msg(str(e))
@authorized_only @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. Handler for /sells.
Shows a performance statistic from finished trades Shows a performance statistic from finished trades
@ -1135,11 +1136,11 @@ class Telegram(RPCHandler):
if context.args and isinstance(context.args[0], str): if context.args and isinstance(context.args[0], str):
pair = context.args[0] 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" output = "<b>Exit Reason Performance:</b>\n"
for i, trade in enumerate(trades): for i, trade in enumerate(trades):
stat_line = ( 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"{round_coin_value(trade['profit_abs'], self._config['stake_currency'])} "
f"({trade['profit_ratio']:.2%}) " f"({trade['profit_ratio']:.2%}) "
f"({trade['count']})</code>\n") f"({trade['count']})</code>\n")
@ -1151,7 +1152,7 @@ class Telegram(RPCHandler):
output += stat_line output += stat_line
self._send_msg(output, parse_mode=ParseMode.HTML, 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) query=update.callback_query)
except RPCException as e: except RPCException as e:
self._send_msg(str(e)) self._send_msg(str(e))

View File

@ -1010,7 +1010,7 @@ def test_enter_tag_performance_handle_2(mocker, default_conf, markets, fee):
assert prec_satoshi(res[0]['profit_pct'], 0.5) assert prec_satoshi(res[0]['profit_pct'], 0.5)
def test_sell_reason_performance_handle(default_conf, ticker, limit_buy_order, fee, def test_exit_reason_performance_handle(default_conf, ticker, limit_buy_order, fee,
limit_sell_order, mocker) -> None: limit_sell_order, mocker) -> None:
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
mocker.patch.multiple( mocker.patch.multiple(
@ -1039,23 +1039,23 @@ def test_sell_reason_performance_handle(default_conf, ticker, limit_buy_order, f
trade.close_date = datetime.utcnow() trade.close_date = datetime.utcnow()
trade.is_open = False trade.is_open = False
res = rpc._rpc_sell_reason_performance(None) res = rpc._rpc_exit_reason_performance(None)
assert len(res) == 1 assert len(res) == 1
assert res[0]['sell_reason'] == 'Other' assert res[0]['exit_reason'] == 'Other'
assert res[0]['count'] == 1 assert res[0]['count'] == 1
assert prec_satoshi(res[0]['profit_pct'], 6.2) assert prec_satoshi(res[0]['profit_pct'], 6.2)
trade.exit_reason = "TEST1" trade.exit_reason = "TEST1"
res = rpc._rpc_sell_reason_performance(None) res = rpc._rpc_exit_reason_performance(None)
assert len(res) == 1 assert len(res) == 1
assert res[0]['sell_reason'] == 'TEST1' assert res[0]['exit_reason'] == 'TEST1'
assert res[0]['count'] == 1 assert res[0]['count'] == 1
assert prec_satoshi(res[0]['profit_pct'], 6.2) assert prec_satoshi(res[0]['profit_pct'], 6.2)
def test_sell_reason_performance_handle_2(mocker, default_conf, markets, fee): def test_exit_reason_performance_handle_2(mocker, default_conf, markets, fee):
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
mocker.patch.multiple( mocker.patch.multiple(
'freqtrade.exchange.Exchange', 'freqtrade.exchange.Exchange',
@ -1066,21 +1066,21 @@ def test_sell_reason_performance_handle_2(mocker, default_conf, markets, fee):
create_mock_trades(fee) create_mock_trades(fee)
rpc = RPC(freqtradebot) rpc = RPC(freqtradebot)
res = rpc._rpc_sell_reason_performance(None) res = rpc._rpc_exit_reason_performance(None)
assert len(res) == 2 assert len(res) == 2
assert res[0]['sell_reason'] == 'sell_signal' assert res[0]['exit_reason'] == 'sell_signal'
assert res[0]['count'] == 1 assert res[0]['count'] == 1
assert prec_satoshi(res[0]['profit_pct'], 0.5) assert prec_satoshi(res[0]['profit_pct'], 0.5)
assert res[1]['sell_reason'] == 'roi' assert res[1]['exit_reason'] == 'roi'
assert res[1]['count'] == 1 assert res[1]['count'] == 1
assert prec_satoshi(res[1]['profit_pct'], 1.0) assert prec_satoshi(res[1]['profit_pct'], 1.0)
# Test for a specific pair # Test for a specific pair
res = rpc._rpc_sell_reason_performance('ETC/BTC') res = rpc._rpc_exit_reason_performance('ETC/BTC')
assert len(res) == 1 assert len(res) == 1
assert res[0]['count'] == 1 assert res[0]['count'] == 1
assert res[0]['sell_reason'] == 'sell_signal' assert res[0]['exit_reason'] == 'sell_signal'
assert prec_satoshi(res[0]['profit_pct'], 0.5) assert prec_satoshi(res[0]['profit_pct'], 0.5)

View File

@ -97,7 +97,7 @@ def test_telegram_init(default_conf, mocker, caplog) -> None:
"['balance'], ['start'], ['stop'], " "['balance'], ['start'], ['stop'], "
"['forcesell', 'forceexit'], ['forcebuy', 'forcelong'], ['forceshort'], " "['forcesell', 'forceexit'], ['forcebuy', 'forcelong'], ['forceshort'], "
"['trades'], ['delete'], ['performance'], " "['trades'], ['delete'], ['performance'], "
"['buys', 'entries'], ['sells'], ['mix_tags'], " "['buys', 'entries'], ['sells', 'exits'], ['mix_tags'], "
"['stats'], ['daily'], ['weekly'], ['monthly'], " "['stats'], ['daily'], ['weekly'], ['monthly'], "
"['count'], ['locks'], ['unlock', 'delete_locks'], " "['count'], ['locks'], ['unlock', 'delete_locks'], "
"['reload_config', 'reload_conf'], ['show_config', 'show_conf'], " "['reload_config', 'reload_conf'], ['show_config', 'show_conf'], "
@ -1337,8 +1337,8 @@ def test_telegram_performance_handle(default_conf, update, ticker, fee,
assert '<code>ETH/BTC\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0] assert '<code>ETH/BTC\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0]
def test_telegram_buy_tag_performance_handle(default_conf, update, ticker, fee, def test_telegram_entry_tag_performance_handle(
limit_buy_order, limit_sell_order, mocker) -> None: default_conf, update, ticker, fee, limit_buy_order, limit_sell_order, mocker) -> None:
mocker.patch.multiple( mocker.patch.multiple(
'freqtrade.exchange.Exchange', 'freqtrade.exchange.Exchange',
fetch_ticker=ticker, fetch_ticker=ticker,
@ -1366,7 +1366,7 @@ def test_telegram_buy_tag_performance_handle(default_conf, update, ticker, fee,
context = MagicMock() context = MagicMock()
telegram._enter_tag_performance(update=update, context=context) telegram._enter_tag_performance(update=update, context=context)
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'Buy Tag Performance' in msg_mock.call_args_list[0][0][0] assert 'Entry Tag Performance' in msg_mock.call_args_list[0][0][0]
assert '<code>TESTBUY\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0] assert '<code>TESTBUY\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0]
context.args = [trade.pair] context.args = [trade.pair]
@ -1382,7 +1382,7 @@ def test_telegram_buy_tag_performance_handle(default_conf, update, ticker, fee,
assert "Error" in msg_mock.call_args_list[0][0][0] assert "Error" in msg_mock.call_args_list[0][0][0]
def test_telegram_sell_reason_performance_handle(default_conf, update, ticker, fee, def test_telegram_exit_reason_performance_handle(default_conf, update, ticker, fee,
limit_buy_order, limit_sell_order, mocker) -> None: limit_buy_order, limit_sell_order, mocker) -> None:
mocker.patch.multiple( mocker.patch.multiple(
'freqtrade.exchange.Exchange', 'freqtrade.exchange.Exchange',
@ -1408,19 +1408,19 @@ def test_telegram_sell_reason_performance_handle(default_conf, update, ticker, f
trade.close_date = datetime.utcnow() trade.close_date = datetime.utcnow()
trade.is_open = False trade.is_open = False
context = MagicMock() context = MagicMock()
telegram._sell_reason_performance(update=update, context=context) telegram._exit_reason_performance(update=update, context=context)
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'Sell Reason Performance' in msg_mock.call_args_list[0][0][0] assert 'Exit Reason Performance' in msg_mock.call_args_list[0][0][0]
assert '<code>TESTSELL\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0] assert '<code>TESTSELL\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0]
context.args = [trade.pair] context.args = [trade.pair]
telegram._sell_reason_performance(update=update, context=context) telegram._exit_reason_performance(update=update, context=context)
assert msg_mock.call_count == 2 assert msg_mock.call_count == 2
msg_mock.reset_mock() msg_mock.reset_mock()
mocker.patch('freqtrade.rpc.rpc.RPC._rpc_sell_reason_performance', mocker.patch('freqtrade.rpc.rpc.RPC._rpc_exit_reason_performance',
side_effect=RPCException('Error')) side_effect=RPCException('Error'))
telegram._sell_reason_performance(update=update, context=MagicMock()) telegram._exit_reason_performance(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert "Error" in msg_mock.call_args_list[0][0][0] assert "Error" in msg_mock.call_args_list[0][0][0]

View File

@ -2197,7 +2197,7 @@ def test_Trade_object_idem():
'get_open_trades_without_assigned_fees', 'get_open_trades_without_assigned_fees',
'get_open_order_trades', 'get_open_order_trades',
'get_trades', 'get_trades',
'get_sell_reason_performance', 'get_exit_reason_performance',
'get_enter_tag_performance', 'get_enter_tag_performance',
'get_mix_tag_performance', 'get_mix_tag_performance',