Add telegram pair unlocking
This commit is contained in:
parent
6640156ac7
commit
007ac7abb5
@ -146,6 +146,7 @@ official commands. You can ask at any moment for help with `/help`.
|
||||
| `/delete <trade_id>` | Delete a specific trade from the Database. Tries to close open orders. Requires manual handling of this trade on the exchange.
|
||||
| `/count` | Displays number of trades used and available
|
||||
| `/locks` | Show currently locked pairs.
|
||||
| `/unlock <pair | 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
|
||||
| `/forcesell <trade_id>` | Instantly sells the given trade (Ignoring `minimum_roi`).
|
||||
| `/forcesell all` | Instantly sells all open trades (Ignoring `minimum_roi`).
|
||||
|
@ -11,13 +11,14 @@ from freqtrade.data.history import get_datahandler
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.rpc import RPC
|
||||
from freqtrade.rpc.api_server.api_schemas import (AvailablePairs, Balances, BlacklistPayload,
|
||||
BlacklistResponse, Count, Daily, DeleteLockRequest, DeleteTrade,
|
||||
ForceBuyPayload, ForceBuyResponse,
|
||||
ForceSellPayload, Locks, Logs, OpenTradeSchema,
|
||||
PairHistory, PerformanceEntry, Ping, PlotConfig,
|
||||
Profit, ResultMsg, ShowConfig, Stats, StatusMsg,
|
||||
StrategyListResponse, StrategyResponse,
|
||||
TradeResponse, Version, WhitelistResponse)
|
||||
BlacklistResponse, Count, Daily,
|
||||
DeleteLockRequest, DeleteTrade, ForceBuyPayload,
|
||||
ForceBuyResponse, ForceSellPayload, Locks, Logs,
|
||||
OpenTradeSchema, PairHistory, PerformanceEntry,
|
||||
Ping, PlotConfig, Profit, ResultMsg, ShowConfig,
|
||||
Stats, StatusMsg, StrategyListResponse,
|
||||
StrategyResponse, TradeResponse, Version,
|
||||
WhitelistResponse)
|
||||
from freqtrade.rpc.api_server.deps import get_config, get_rpc, get_rpc_optional
|
||||
from freqtrade.rpc.rpc import RPCException
|
||||
|
||||
|
@ -6,6 +6,7 @@ This module manage Telegram communication
|
||||
import json
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
from html import escape
|
||||
from itertools import chain
|
||||
from typing import Any, Callable, Dict, List, Union
|
||||
|
||||
@ -144,6 +145,7 @@ class Telegram(RPCHandler):
|
||||
CommandHandler('daily', self._daily),
|
||||
CommandHandler('count', self._count),
|
||||
CommandHandler('locks', self._locks),
|
||||
CommandHandler(['unlock', 'delete_locks'], self._delete_locks),
|
||||
CommandHandler(['reload_config', 'reload_conf'], self._reload_config),
|
||||
CommandHandler(['show_config', 'show_conf'], self._show_config),
|
||||
CommandHandler('stopbuy', self._stopbuy),
|
||||
@ -722,17 +724,39 @@ class Telegram(RPCHandler):
|
||||
try:
|
||||
locks = self._rpc._rpc_locks()
|
||||
message = tabulate([[
|
||||
lock['id'],
|
||||
lock['pair'],
|
||||
lock['lock_end_time'],
|
||||
lock['reason']] for lock in locks['locks']],
|
||||
headers=['Pair', 'Until', 'Reason'],
|
||||
headers=['ID', 'Pair', 'Until', 'Reason'],
|
||||
tablefmt='simple')
|
||||
message = "<pre>{}</pre>".format(message)
|
||||
message = f"<pre>{escape(message)}</pre>"
|
||||
logger.debug(message)
|
||||
self._send_msg(message, parse_mode=ParseMode.HTML)
|
||||
except RPCException as e:
|
||||
self._send_msg(str(e))
|
||||
|
||||
@authorized_only
|
||||
def _delete_locks(self, update: Update, context: CallbackContext) -> None:
|
||||
"""
|
||||
Handler for /delete_locks.
|
||||
Returns the currently active locks
|
||||
"""
|
||||
try:
|
||||
arg = context.args[0] if context.args and len(context.args) > 0 else None
|
||||
lockid = None
|
||||
pair = None
|
||||
if arg:
|
||||
try:
|
||||
lockid = int(arg)
|
||||
except ValueError:
|
||||
pair = arg
|
||||
|
||||
self._rpc._rpc_delete_lock(lockid=lockid, pair=pair)
|
||||
self._locks(update, context)
|
||||
except RPCException as e:
|
||||
self._send_msg(str(e))
|
||||
|
||||
@authorized_only
|
||||
def _whitelist(self, update: Update, context: CallbackContext) -> None:
|
||||
"""
|
||||
@ -850,6 +874,7 @@ class Telegram(RPCHandler):
|
||||
"Avg. holding durationsfor buys and sells.`\n"
|
||||
"*/count:* `Show number of active trades compared to allowed number of trades`\n"
|
||||
"*/locks:* `Show currently locked pairs`\n"
|
||||
"*/unlock <pair|id>:* `Unlock this Pair (or this lock id if it's numeric)`\n"
|
||||
"*/balance:* `Show account balance per currency`\n"
|
||||
"*/stopbuy:* `Stops buying, but handles open trades gracefully` \n"
|
||||
"*/reload_config:* `Reload configuration file` \n"
|
||||
|
@ -2,7 +2,6 @@
|
||||
# pragma pylint: disable=invalid-sequence-index, invalid-name, too-many-arguments
|
||||
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from freqtrade.persistence.pairlock_middleware import PairLocks
|
||||
from unittest.mock import ANY, MagicMock, PropertyMock
|
||||
|
||||
import pytest
|
||||
@ -11,6 +10,7 @@ from numpy import isnan
|
||||
from freqtrade.edge import PairInfo
|
||||
from freqtrade.exceptions import ExchangeError, InvalidOrderException, TemporaryError
|
||||
from freqtrade.persistence import Trade
|
||||
from freqtrade.persistence.pairlock_middleware import PairLocks
|
||||
from freqtrade.rpc import RPC, RPCException
|
||||
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
|
||||
from freqtrade.state import State
|
||||
|
@ -92,7 +92,8 @@ def test_telegram_init(default_conf, mocker, caplog) -> None:
|
||||
message_str = ("rpc.telegram is listening for following commands: [['status'], ['profit'], "
|
||||
"['balance'], ['start'], ['stop'], ['forcesell'], ['forcebuy'], ['trades'], "
|
||||
"['delete'], ['performance'], ['stats'], ['daily'], ['count'], ['locks'], "
|
||||
"['reload_config', 'reload_conf'], ['show_config', 'show_conf'], ['stopbuy'], "
|
||||
"['unlock', 'delete_locks'], ['reload_config', 'reload_conf'], "
|
||||
"['show_config', 'show_conf'], ['stopbuy'], "
|
||||
"['whitelist'], ['blacklist'], ['logs'], ['edge'], ['help'], ['version']"
|
||||
"]")
|
||||
|
||||
@ -981,6 +982,16 @@ def test_telegram_lock_handle(default_conf, update, ticker, fee, mocker) -> None
|
||||
assert 'deadbeef' in msg_mock.call_args_list[0][0][0]
|
||||
assert 'randreason' in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
context = MagicMock()
|
||||
context.args = ['XRP/BTC']
|
||||
msg_mock.reset_mock()
|
||||
telegram._delete_locks(update=update, context=context)
|
||||
|
||||
assert 'ETH/BTC' in msg_mock.call_args_list[0][0][0]
|
||||
assert 'randreason' in msg_mock.call_args_list[0][0][0]
|
||||
assert 'XRP/BTC' not in msg_mock.call_args_list[0][0][0]
|
||||
assert 'deadbeef' not in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
|
||||
def test_whitelist_static(default_conf, update, mocker) -> None:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user