Merge pull request #4982 from eschava/profit_day_week
day/week options for Telegram '/profit' command
This commit is contained in:
commit
e71d965e32
@ -123,7 +123,7 @@ Telegram is not mandatory. However, this is a great way to control your bot. Mor
|
||||
- `/stop`: Stops the trader.
|
||||
- `/stopbuy`: Stop entering new trades.
|
||||
- `/status <trade_id>|[table]`: Lists all or specific open trades.
|
||||
- `/profit`: Lists cumulative profit from all finished trades
|
||||
- `/profit [<n>]`: Lists cumulative profit from all finished trades, over the last n days.
|
||||
- `/forcesell <trade_id>|all`: Instantly sells the given trade (Ignoring `minimum_roi`).
|
||||
- `/performance`: Show performance of each finished trade grouped by pair
|
||||
- `/balance`: Show account balance per currency.
|
||||
|
@ -163,7 +163,7 @@ official commands. You can ask at any moment for help with `/help`.
|
||||
| `/count` | Displays number of trades used and available
|
||||
| `/locks` | Show currently locked pairs.
|
||||
| `/unlock <pair or lock_id>` | Remove the lock for this pair (or for this lock id).
|
||||
| `/profit` | Display a summary of your profit/loss from close trades and some stats about your performance
|
||||
| `/profit [<n>]` | Display a summary of your profit/loss from close trades and some stats about your performance, over the last n days (all trades by default)
|
||||
| `/forcesell <trade_id>` | Instantly sells the given trade (Ignoring `minimum_roi`).
|
||||
| `/forcesell all` | Instantly sells all open trades (Ignoring `minimum_roi`).
|
||||
| `/forcebuy <pair> [rate]` | Instantly buys the given pair. Rate is optional. (`forcebuy_enable` must be set to True)
|
||||
|
@ -355,9 +355,10 @@ class RPC:
|
||||
return {'sell_reasons': sell_reasons, 'durations': durations}
|
||||
|
||||
def _rpc_trade_statistics(
|
||||
self, stake_currency: str, fiat_display_currency: str) -> Dict[str, Any]:
|
||||
self, stake_currency: str, fiat_display_currency: str,
|
||||
start_date: datetime = datetime.fromtimestamp(0)) -> Dict[str, Any]:
|
||||
""" Returns cumulative profit statistics """
|
||||
trades = Trade.get_trades().order_by(Trade.id).all()
|
||||
trades = Trade.get_trades([Trade.open_date >= start_date]).order_by(Trade.id).all()
|
||||
|
||||
profit_all_coin = []
|
||||
profit_all_ratio = []
|
||||
|
@ -5,7 +5,8 @@ This module manage Telegram communication
|
||||
"""
|
||||
import json
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
import re
|
||||
from datetime import date, datetime, timedelta
|
||||
from html import escape
|
||||
from itertools import chain
|
||||
from math import isnan
|
||||
@ -99,23 +100,27 @@ class Telegram(RPCHandler):
|
||||
# TODO: DRY! - its not good to list all valid cmds here. But otherwise
|
||||
# this needs refacoring of the whole telegram module (same
|
||||
# problem in _help()).
|
||||
valid_keys: List[str] = ['/start', '/stop', '/status', '/status table',
|
||||
'/trades', '/profit', '/performance', '/daily',
|
||||
'/stats', '/count', '/locks', '/balance',
|
||||
'/stopbuy', '/reload_config', '/show_config',
|
||||
'/logs', '/whitelist', '/blacklist', '/edge',
|
||||
'/help', '/version']
|
||||
valid_keys: List[str] = [r'/start$', r'/stop$', r'/status$', r'/status table$',
|
||||
r'/trades$', r'/performance$', 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$',
|
||||
r'/logs$', r'/whitelist$', r'/blacklist$', r'/edge$',
|
||||
r'/forcebuy$', r'/help$', r'/version$']
|
||||
# Create keys for generation
|
||||
valid_keys_print = [k.replace('$', '') for k in valid_keys]
|
||||
|
||||
# custom keyboard specified in config.json
|
||||
cust_keyboard = self._config['telegram'].get('keyboard', [])
|
||||
if cust_keyboard:
|
||||
combined = "(" + ")|(".join(valid_keys) + ")"
|
||||
# check for valid shortcuts
|
||||
invalid_keys = [b for b in chain.from_iterable(cust_keyboard)
|
||||
if b not in valid_keys]
|
||||
if not re.match(combined, b)]
|
||||
if len(invalid_keys):
|
||||
err_msg = ('config.telegram.keyboard: Invalid commands for '
|
||||
f'custom Telegram keyboard: {invalid_keys}'
|
||||
f'\nvalid commands are: {valid_keys}')
|
||||
f'\nvalid commands are: {valid_keys_print}')
|
||||
raise OperationalException(err_msg)
|
||||
else:
|
||||
self._keyboard = cust_keyboard
|
||||
@ -457,9 +462,20 @@ class Telegram(RPCHandler):
|
||||
stake_cur = self._config['stake_currency']
|
||||
fiat_disp_cur = self._config.get('fiat_display_currency', '')
|
||||
|
||||
start_date = datetime.fromtimestamp(0)
|
||||
timescale = None
|
||||
try:
|
||||
if context.args:
|
||||
timescale = int(context.args[0])
|
||||
today_start = datetime.combine(date.today(), datetime.min.time())
|
||||
start_date = today_start - timedelta(days=timescale)
|
||||
except (TypeError, ValueError, IndexError):
|
||||
pass
|
||||
|
||||
stats = self._rpc._rpc_trade_statistics(
|
||||
stake_cur,
|
||||
fiat_disp_cur)
|
||||
fiat_disp_cur,
|
||||
start_date)
|
||||
profit_closed_coin = stats['profit_closed_coin']
|
||||
profit_closed_percent_mean = stats['profit_closed_percent_mean']
|
||||
profit_closed_percent_sum = stats['profit_closed_percent_sum']
|
||||
@ -487,13 +503,15 @@ class Telegram(RPCHandler):
|
||||
else:
|
||||
markdown_msg = "`No closed trade` \n"
|
||||
|
||||
markdown_msg += (f"*ROI:* All trades\n"
|
||||
markdown_msg += (
|
||||
f"*ROI:* All trades\n"
|
||||
f"∙ `{round_coin_value(profit_all_coin, stake_cur)} "
|
||||
f"({profit_all_percent_mean:.2f}%) "
|
||||
f"({profit_all_percent_sum} \N{GREEK CAPITAL LETTER SIGMA}%)`\n"
|
||||
f"∙ `{round_coin_value(profit_all_fiat, fiat_disp_cur)}`\n"
|
||||
f"*Total Trade Count:* `{trade_count}`\n"
|
||||
f"*First Trade opened:* `{first_trade_date}`\n"
|
||||
f"*{'First Trade opened' if not timescale else 'Showing Profit since'}:* "
|
||||
f"`{first_trade_date}`\n"
|
||||
f"*Latest Trade opened:* `{latest_trade_date}\n`"
|
||||
f"*Win / Loss:* `{stats['winning_trades']} / {stats['losing_trades']}`"
|
||||
)
|
||||
@ -959,7 +977,8 @@ class Telegram(RPCHandler):
|
||||
" `pending buy orders are marked with an asterisk (*)`\n"
|
||||
" `pending sell orders are marked with a double asterisk (**)`\n"
|
||||
"*/trades [limit]:* `Lists last closed trades (limited to 10 by default)`\n"
|
||||
"*/profit:* `Lists cumulative profit from all finished trades`\n"
|
||||
"*/profit [<n>]:* `Lists cumulative profit from all finished trades, "
|
||||
"over the last n days`\n"
|
||||
"*/forcesell <trade_id>|all:* `Instantly sells the given trade or all trades, "
|
||||
"regardless of profit`\n"
|
||||
f"{forcebuy_text if self._config.get('forcebuy_enable', False) else ''}"
|
||||
|
@ -1607,7 +1607,7 @@ def test__send_msg_keyboard(default_conf, mocker, caplog) -> None:
|
||||
['/count', '/start', '/stop', '/help']]
|
||||
default_keyboard = ReplyKeyboardMarkup(default_keys_list)
|
||||
|
||||
custom_keys_list = [['/daily', '/stats', '/balance', '/profit'],
|
||||
custom_keys_list = [['/daily', '/stats', '/balance', '/profit', '/profit 5'],
|
||||
['/count', '/start', '/reload_config', '/help']]
|
||||
custom_keyboard = ReplyKeyboardMarkup(custom_keys_list)
|
||||
|
||||
@ -1641,5 +1641,5 @@ def test__send_msg_keyboard(default_conf, mocker, caplog) -> None:
|
||||
used_keyboard = bot.send_message.call_args[1]['reply_markup']
|
||||
assert used_keyboard == custom_keyboard
|
||||
assert log_has("using custom keyboard from config.json: "
|
||||
"[['/daily', '/stats', '/balance', '/profit'], ['/count', "
|
||||
"[['/daily', '/stats', '/balance', '/profit', '/profit 5'], ['/count', "
|
||||
"'/start', '/reload_config', '/help']]", caplog)
|
||||
|
Loading…
Reference in New Issue
Block a user