Merge pull request #1697 from freqtrade/feat/rpc_blacklist

add pairs to blacklist dynamically
This commit is contained in:
Misagh 2019-03-25 09:44:12 +01:00 committed by GitHub
commit b13735e4cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 104 additions and 4 deletions

View File

@ -28,6 +28,8 @@ official commands. You can ask at any moment for help with `/help`.
| `/performance` | | Show performance of each finished trade grouped by pair | `/performance` | | Show performance of each finished trade grouped by pair
| `/balance` | | Show account balance per currency | `/balance` | | Show account balance per currency
| `/daily <n>` | 7 | Shows profit or loss per day, over the last n days | `/daily <n>` | 7 | Shows profit or loss per day, over the last n days
| `/whitelist` | | Show the current whitelist
| `/blacklist [pair]` | | Show the current blacklist, or adds a pair to the blacklist.
| `/help` | | Show help message | `/help` | | Show help message
| `/version` | | Show version | `/version` | | Show version
@ -160,6 +162,23 @@ Day Profit BTC Profit USD
2018-01-01 0.00269130 BTC 34.986 USD 2018-01-01 0.00269130 BTC 34.986 USD
``` ```
### /whitelist
Shows the current whitelist
> Using whitelist `StaticPairList` with 22 pairs
> `IOTA/BTC, NEO/BTC, TRX/BTC, VET/BTC, ADA/BTC, ETC/BTC, NCASH/BTC, DASH/BTC, XRP/BTC, XVG/BTC, EOS/BTC, LTC/BTC, OMG/BTC, BTG/BTC, LSK/BTC, ZEC/BTC, HOT/BTC, IOTX/BTC, XMR/BTC, AST/BTC, XLM/BTC, NANO/BTC`
### /blacklist [pair]
Shows the current blacklist.
If Pair is set, then this pair will be added to the pairlist.
Also supports multiple pairs, seperated by a space.
Use `/reload_conf` to reset the blacklist.
> Using blacklist `StaticPairList` with 2 pairs
>`DODGE/BTC`, `HOT/BTC`.
### /version ### /version
> **Version:** `0.14.3` > **Version:** `0.14.3`

View File

@ -456,7 +456,18 @@ class RPC(object):
def _rpc_whitelist(self) -> Dict: def _rpc_whitelist(self) -> Dict:
""" Returns the currently active whitelist""" """ Returns the currently active whitelist"""
res = {'method': self._freqtrade.pairlists.name, res = {'method': self._freqtrade.pairlists.name,
'length': len(self._freqtrade.pairlists.whitelist), 'length': len(self._freqtrade.active_pair_whitelist),
'whitelist': self._freqtrade.active_pair_whitelist 'whitelist': self._freqtrade.active_pair_whitelist
} }
return res return res
def _rpc_blacklist(self, add: List[str]) -> Dict:
""" Returns the currently active blacklist"""
if add:
self._freqtrade.pairlists.blacklist.extend(add)
res = {'method': self._freqtrade.pairlists.name,
'length': len(self._freqtrade.pairlists.blacklist),
'blacklist': self._freqtrade.pairlists.blacklist
}
return res

View File

@ -4,7 +4,7 @@
This module manage Telegram communication This module manage Telegram communication
""" """
import logging import logging
from typing import Any, Callable, Dict from typing import Any, Callable, Dict, List
from tabulate import tabulate from tabulate import tabulate
from telegram import Bot, ParseMode, ReplyKeyboardMarkup, Update from telegram import Bot, ParseMode, ReplyKeyboardMarkup, Update
@ -20,7 +20,7 @@ logger = logging.getLogger(__name__)
logger.debug('Included module rpc.telegram ...') logger.debug('Included module rpc.telegram ...')
def authorized_only(command_handler: Callable[[Any, Bot, Update], None]) -> Callable[..., Any]: def authorized_only(command_handler: Callable[..., None]) -> Callable[..., Any]:
""" """
Decorator to check if the message comes from the correct chat_id Decorator to check if the message comes from the correct chat_id
:param command_handler: Telegram CommandHandler :param command_handler: Telegram CommandHandler
@ -93,6 +93,7 @@ class Telegram(RPC):
CommandHandler('reload_conf', self._reload_conf), CommandHandler('reload_conf', self._reload_conf),
CommandHandler('stopbuy', self._stopbuy), CommandHandler('stopbuy', self._stopbuy),
CommandHandler('whitelist', self._whitelist), CommandHandler('whitelist', self._whitelist),
CommandHandler('blacklist', self._blacklist, pass_args=True),
CommandHandler('help', self._help), CommandHandler('help', self._help),
CommandHandler('version', self._version), CommandHandler('version', self._version),
] ]
@ -470,6 +471,24 @@ class Telegram(RPC):
except RPCException as e: except RPCException as e:
self._send_msg(str(e), bot=bot) self._send_msg(str(e), bot=bot)
@authorized_only
def _blacklist(self, bot: Bot, update: Update, args: List[str]) -> None:
"""
Handler for /blacklist
Shows the currently active blacklist
"""
try:
blacklist = self._rpc_blacklist(args)
message = f"Blacklist contains {blacklist['length']} pairs\n"
message += f"`{', '.join(blacklist['blacklist'])}`"
logger.debug(message)
self._send_msg(message)
except RPCException as e:
self._send_msg(str(e), bot=bot)
@authorized_only @authorized_only
def _help(self, bot: Bot, update: Update) -> None: def _help(self, bot: Bot, update: Update) -> None:
""" """
@ -497,6 +516,8 @@ class Telegram(RPC):
"*/stopbuy:* `Stops buying, but handles open trades gracefully` \n" \ "*/stopbuy:* `Stops buying, but handles open trades gracefully` \n" \
"*/reload_conf:* `Reload configuration file` \n" \ "*/reload_conf:* `Reload configuration file` \n" \
"*/whitelist:* `Show current whitelist` \n" \ "*/whitelist:* `Show current whitelist` \n" \
"*/blacklist [pair]:* `Show current blacklist, or adds one or more pairs " \
"to the blacklist.` \n" \
"*/help:* `This help message`\n" \ "*/help:* `This help message`\n" \
"*/version:* `Show version`" "*/version:* `Show version`"

View File

@ -171,6 +171,10 @@ def default_conf():
"LTC/BTC", "LTC/BTC",
"XRP/BTC", "XRP/BTC",
"NEO/BTC" "NEO/BTC"
],
"pair_blacklist": [
"DOGE/BTC",
"HOT/BTC",
] ]
}, },
"telegram": { "telegram": {

View File

@ -693,3 +693,23 @@ def test_rpc_whitelist_dynamic(mocker, default_conf) -> None:
assert ret['method'] == 'VolumePairList' assert ret['method'] == 'VolumePairList'
assert ret['length'] == 4 assert ret['length'] == 4
assert ret['whitelist'] == default_conf['exchange']['pair_whitelist'] assert ret['whitelist'] == default_conf['exchange']['pair_whitelist']
def test_rpc_blacklist(mocker, default_conf) -> None:
patch_coinmarketcap(mocker)
patch_exchange(mocker)
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
freqtradebot = FreqtradeBot(default_conf)
rpc = RPC(freqtradebot)
ret = rpc._rpc_blacklist(None)
assert ret['method'] == 'StaticPairList'
assert len(ret['blacklist']) == 2
assert ret['blacklist'] == default_conf['exchange']['pair_blacklist']
assert ret['blacklist'] == ['DOGE/BTC', 'HOT/BTC']
ret = rpc._rpc_blacklist(["ETH/BTC"])
assert ret['method'] == 'StaticPairList'
assert len(ret['blacklist']) == 3
assert ret['blacklist'] == default_conf['exchange']['pair_blacklist']
assert ret['blacklist'] == ['DOGE/BTC', 'HOT/BTC', 'ETH/BTC']

View File

@ -74,7 +74,7 @@ def test_init(default_conf, mocker, caplog) -> None:
message_str = "rpc.telegram is listening for following commands: [['status'], ['profit'], " \ message_str = "rpc.telegram is listening for following commands: [['status'], ['profit'], " \
"['balance'], ['start'], ['stop'], ['forcesell'], ['forcebuy'], " \ "['balance'], ['start'], ['stop'], ['forcesell'], ['forcebuy'], " \
"['performance'], ['daily'], ['count'], ['reload_conf'], " \ "['performance'], ['daily'], ['count'], ['reload_conf'], " \
"['stopbuy'], ['whitelist'], ['help'], ['version']]" "['stopbuy'], ['whitelist'], ['blacklist'], ['help'], ['version']]"
assert log_has(message_str, caplog.record_tuples) assert log_has(message_str, caplog.record_tuples)
@ -1074,6 +1074,31 @@ def test_whitelist_dynamic(default_conf, update, mocker) -> None:
in msg_mock.call_args_list[0][0][0]) in msg_mock.call_args_list[0][0][0])
def test_blacklist_static(default_conf, update, mocker) -> None:
patch_coinmarketcap(mocker)
msg_mock = MagicMock()
mocker.patch.multiple(
'freqtrade.rpc.telegram.Telegram',
_init=MagicMock(),
_send_msg=msg_mock
)
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
telegram = Telegram(freqtradebot)
telegram._blacklist(bot=MagicMock(), update=update, args=[])
assert msg_mock.call_count == 1
assert ("Blacklist contains 2 pairs\n`DOGE/BTC, HOT/BTC`"
in msg_mock.call_args_list[0][0][0])
msg_mock.reset_mock()
telegram._blacklist(bot=MagicMock(), update=update, args=["ETH/BTC"])
assert msg_mock.call_count == 1
assert ("Blacklist contains 3 pairs\n`DOGE/BTC, HOT/BTC, ETH/BTC`"
in msg_mock.call_args_list[0][0][0])
assert freqtradebot.pairlists.blacklist == ["DOGE/BTC", "HOT/BTC", "ETH/BTC"]
def test_help_handle(default_conf, update, mocker) -> None: def test_help_handle(default_conf, update, mocker) -> None:
patch_coinmarketcap(mocker) patch_coinmarketcap(mocker)
msg_mock = MagicMock() msg_mock = MagicMock()