Improve some telegram terminology
This commit is contained in:
parent
157f8f8139
commit
cd78792f48
@ -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)
|
||||
| `/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)
|
||||
| `/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
|
||||
| `/blacklist [pair]` | Show the current blacklist, or adds a pair to the blacklist.
|
||||
| `/edge` | Show validated pairs by Edge if it is enabled.
|
||||
|
@ -234,7 +234,7 @@ def check_migrate(engine, decl_base, previous_tables) -> None:
|
||||
# Migrates both trades and orders table!
|
||||
# if ('orders' not in previous_tables
|
||||
# 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 - "
|
||||
f"backup: {table_back_name}, {order_table_bak_name}")
|
||||
migrate_trades_and_orders_table(
|
||||
|
@ -1289,7 +1289,7 @@ class Trade(_DECL_BASE, LocalTrade):
|
||||
]
|
||||
|
||||
@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
|
||||
Can either be average for all pairs or a specific pair provided
|
||||
@ -1312,13 +1312,13 @@ class Trade(_DECL_BASE, LocalTrade):
|
||||
|
||||
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_pct': round(profit * 100, 2),
|
||||
'profit_abs': profit_abs,
|
||||
'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
|
||||
|
@ -848,12 +848,12 @@ 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]]:
|
||||
"""
|
||||
|
@ -108,7 +108,8 @@ class Telegram(RPCHandler):
|
||||
# this needs refactoring of the whole telegram module (same
|
||||
# problem in _help()).
|
||||
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'/stats$', r'/count$', r'/locks$', r'/balance$',
|
||||
r'/stopbuy$', r'/reload_config$', r'/show_config$',
|
||||
@ -161,7 +162,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', 'exits'], self._exit_reason_performance),
|
||||
CommandHandler('mix_tags', self._mix_tag_performance),
|
||||
CommandHandler('stats', self._stats),
|
||||
CommandHandler('daily', self._daily),
|
||||
@ -192,8 +193,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._forceenter_inline),
|
||||
@ -1101,7 +1102,7 @@ class Telegram(RPCHandler):
|
||||
pair = context.args[0]
|
||||
|
||||
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):
|
||||
stat_line = (
|
||||
f"{i+1}.\t <code>{trade['enter_tag']}\t"
|
||||
@ -1122,7 +1123,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
|
||||
@ -1135,11 +1136,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)
|
||||
output = "<b>Sell Reason Performance:</b>\n"
|
||||
trades = self._rpc._rpc_exit_reason_performance(pair)
|
||||
output = "<b>Exit 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")
|
||||
@ -1151,7 +1152,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))
|
||||
|
@ -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)
|
||||
|
||||
|
||||
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:
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
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.is_open = False
|
||||
res = rpc._rpc_sell_reason_performance(None)
|
||||
res = rpc._rpc_exit_reason_performance(None)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0]['sell_reason'] == 'Other'
|
||||
assert res[0]['exit_reason'] == 'Other'
|
||||
assert res[0]['count'] == 1
|
||||
assert prec_satoshi(res[0]['profit_pct'], 6.2)
|
||||
|
||||
trade.exit_reason = "TEST1"
|
||||
res = rpc._rpc_sell_reason_performance(None)
|
||||
res = rpc._rpc_exit_reason_performance(None)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0]['sell_reason'] == 'TEST1'
|
||||
assert res[0]['exit_reason'] == 'TEST1'
|
||||
assert res[0]['count'] == 1
|
||||
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.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
@ -1066,21 +1066,21 @@ def test_sell_reason_performance_handle_2(mocker, default_conf, markets, fee):
|
||||
create_mock_trades(fee)
|
||||
rpc = RPC(freqtradebot)
|
||||
|
||||
res = rpc._rpc_sell_reason_performance(None)
|
||||
res = rpc._rpc_exit_reason_performance(None)
|
||||
|
||||
assert len(res) == 2
|
||||
assert res[0]['sell_reason'] == 'sell_signal'
|
||||
assert res[0]['exit_reason'] == 'sell_signal'
|
||||
assert res[0]['count'] == 1
|
||||
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 prec_satoshi(res[1]['profit_pct'], 1.0)
|
||||
|
||||
# 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 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)
|
||||
|
||||
|
||||
|
@ -97,7 +97,7 @@ def test_telegram_init(default_conf, mocker, caplog) -> None:
|
||||
"['balance'], ['start'], ['stop'], "
|
||||
"['forcesell', 'forceexit'], ['forcebuy', 'forcelong'], ['forceshort'], "
|
||||
"['trades'], ['delete'], ['performance'], "
|
||||
"['buys', 'entries'], ['sells'], ['mix_tags'], "
|
||||
"['buys', 'entries'], ['sells', 'exits'], ['mix_tags'], "
|
||||
"['stats'], ['daily'], ['weekly'], ['monthly'], "
|
||||
"['count'], ['locks'], ['unlock', 'delete_locks'], "
|
||||
"['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]
|
||||
|
||||
|
||||
def test_telegram_buy_tag_performance_handle(default_conf, update, ticker, fee,
|
||||
limit_buy_order, limit_sell_order, mocker) -> None:
|
||||
def test_telegram_entry_tag_performance_handle(
|
||||
default_conf, update, ticker, fee, limit_buy_order, limit_sell_order, mocker) -> None:
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
fetch_ticker=ticker,
|
||||
@ -1366,7 +1366,7 @@ def test_telegram_buy_tag_performance_handle(default_conf, update, ticker, fee,
|
||||
context = MagicMock()
|
||||
telegram._enter_tag_performance(update=update, context=context)
|
||||
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]
|
||||
|
||||
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]
|
||||
|
||||
|
||||
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:
|
||||
mocker.patch.multiple(
|
||||
'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.is_open = False
|
||||
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 '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]
|
||||
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
|
||||
|
||||
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'))
|
||||
telegram._sell_reason_performance(update=update, context=MagicMock())
|
||||
telegram._exit_reason_performance(update=update, context=MagicMock())
|
||||
|
||||
assert msg_mock.call_count == 1
|
||||
assert "Error" in msg_mock.call_args_list[0][0][0]
|
||||
|
@ -2197,7 +2197,7 @@ def test_Trade_object_idem():
|
||||
'get_open_trades_without_assigned_fees',
|
||||
'get_open_order_trades',
|
||||
'get_trades',
|
||||
'get_sell_reason_performance',
|
||||
'get_exit_reason_performance',
|
||||
'get_enter_tag_performance',
|
||||
'get_mix_tag_performance',
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user