From 684727b32ea11c8f1b4a4e8a120db215bb32fa7e Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 24 Mar 2019 16:08:48 +0100 Subject: [PATCH 01/10] Add black blacklist handler (ro) --- freqtrade/rpc/rpc.py | 10 +++++++++- freqtrade/rpc/telegram.py | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index a0ffff107..687ee9375 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -456,7 +456,15 @@ class RPC(object): def _rpc_whitelist(self) -> Dict: """ Returns the currently active whitelist""" 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 } return res + + def _rpc_blacklist(self) -> Dict: + """ Returns the currently active blacklist""" + res = {'method': self._freqtrade.pairlists.name, + 'length': len(self._freqtrade.pairlists.blacklist), + 'blacklist': self._freqtrade.pairlists.blacklist + } + return res diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 6771ec803..903efe7d1 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -93,6 +93,7 @@ class Telegram(RPC): CommandHandler('reload_conf', self._reload_conf), CommandHandler('stopbuy', self._stopbuy), CommandHandler('whitelist', self._whitelist), + CommandHandler('blacklist', self._blacklist), CommandHandler('help', self._help), CommandHandler('version', self._version), ] @@ -470,6 +471,23 @@ class Telegram(RPC): except RPCException as e: self._send_msg(str(e), bot=bot) + @authorized_only + def _blacklist(self, bot: Bot, update: Update) -> None: + """ + Handler for /blacklist + Shows the currently active blacklist + """ + try: + blacklist = self._rpc_blacklist() + + message = f"Using blacklist `{blacklist['method']}` with {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 def _help(self, bot: Bot, update: Update) -> None: """ @@ -497,6 +515,7 @@ class Telegram(RPC): "*/stopbuy:* `Stops buying, but handles open trades gracefully` \n" \ "*/reload_conf:* `Reload configuration file` \n" \ "*/whitelist:* `Show current whitelist` \n" \ + "*/blacklist:* `Show current blacklist` \n" \ "*/help:* `This help message`\n" \ "*/version:* `Show version`" From ffdca7eea7d62969e9c580fe9a4599453241e541 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 24 Mar 2019 16:09:04 +0100 Subject: [PATCH 02/10] Add blacklist to default_config --- freqtrade/tests/conftest.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/freqtrade/tests/conftest.py b/freqtrade/tests/conftest.py index 26262cb4b..c0f8e49b7 100644 --- a/freqtrade/tests/conftest.py +++ b/freqtrade/tests/conftest.py @@ -171,6 +171,10 @@ def default_conf(): "LTC/BTC", "XRP/BTC", "NEO/BTC" + ], + "pair_blacklist": [ + "DOGE/BTC", + "HOT/BTC", ] }, "telegram": { From 8b2174d249135b285932892cbd417af5c470747a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 24 Mar 2019 16:09:20 +0100 Subject: [PATCH 03/10] Add tests for /blacklist handler --- freqtrade/tests/rpc/test_rpc.py | 12 ++++++++++++ freqtrade/tests/rpc/test_rpc_telegram.py | 20 +++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/freqtrade/tests/rpc/test_rpc.py b/freqtrade/tests/rpc/test_rpc.py index baddc0685..b1fbd27ff 100644 --- a/freqtrade/tests/rpc/test_rpc.py +++ b/freqtrade/tests/rpc/test_rpc.py @@ -693,3 +693,15 @@ def test_rpc_whitelist_dynamic(mocker, default_conf) -> None: assert ret['method'] == 'VolumePairList' assert ret['length'] == 4 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() + assert ret['method'] == 'StaticPairList' + assert ret['blacklist'] == default_conf['exchange']['pair_blacklist'] diff --git a/freqtrade/tests/rpc/test_rpc_telegram.py b/freqtrade/tests/rpc/test_rpc_telegram.py index 8e8d1f1bb..fec2e508c 100644 --- a/freqtrade/tests/rpc/test_rpc_telegram.py +++ b/freqtrade/tests/rpc/test_rpc_telegram.py @@ -74,7 +74,7 @@ def test_init(default_conf, mocker, caplog) -> None: message_str = "rpc.telegram is listening for following commands: [['status'], ['profit'], " \ "['balance'], ['start'], ['stop'], ['forcesell'], ['forcebuy'], " \ "['performance'], ['daily'], ['count'], ['reload_conf'], " \ - "['stopbuy'], ['whitelist'], ['help'], ['version']]" + "['stopbuy'], ['whitelist'], ['blacklist'], ['help'], ['version']]" assert log_has(message_str, caplog.record_tuples) @@ -1074,6 +1074,24 @@ def test_whitelist_dynamic(default_conf, update, mocker) -> None: 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) + assert msg_mock.call_count == 1 + assert ('Using blacklist `StaticPairList` with 2 pairs\n`DOGE/BTC, HOT/BTC`' + in msg_mock.call_args_list[0][0][0]) + + def test_help_handle(default_conf, update, mocker) -> None: patch_coinmarketcap(mocker) msg_mock = MagicMock() From 7b99d5ebcbb742d724232c606ca5a87691e9bcdb Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 24 Mar 2019 16:16:39 +0100 Subject: [PATCH 04/10] Add blacklist and whitelist commands to telegram docs --- docs/telegram-usage.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/telegram-usage.md b/docs/telegram-usage.md index 92d60c7ed..671229242 100644 --- a/docs/telegram-usage.md +++ b/docs/telegram-usage.md @@ -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 | `/balance` | | Show account balance per currency | `/daily ` | 7 | Shows profit or loss per day, over the last n days +| `/whitelist` | | Show the current whitelist +| `/blacklist` | | Show the current blacklist | `/help` | | Show help message | `/version` | | Show version @@ -160,6 +162,21 @@ Day Profit BTC Profit 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 + +Shows the current blacklist + +> Using blacklist `StaticPairList` with 2 pairs +>`DODGE/BTC`, `HOT/BTC`. + ### /version > **Version:** `0.14.3` From 9d6f629f6a50f29d8f497b2baaf8623995f87dcd Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 24 Mar 2019 16:28:14 +0100 Subject: [PATCH 05/10] Support adding pairs to blacklist --- freqtrade/rpc/rpc.py | 5 ++++- freqtrade/rpc/telegram.py | 11 ++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 687ee9375..cacca4e3c 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -461,8 +461,11 @@ class RPC(object): } return res - def _rpc_blacklist(self) -> Dict: + 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 diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 903efe7d1..92108ded9 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -4,7 +4,7 @@ This module manage Telegram communication """ import logging -from typing import Any, Callable, Dict +from typing import Any, Callable, Dict, List from tabulate import tabulate from telegram import Bot, ParseMode, ReplyKeyboardMarkup, Update @@ -93,7 +93,7 @@ class Telegram(RPC): CommandHandler('reload_conf', self._reload_conf), CommandHandler('stopbuy', self._stopbuy), CommandHandler('whitelist', self._whitelist), - CommandHandler('blacklist', self._blacklist), + CommandHandler('blacklist', self._blacklist, pass_args=True), CommandHandler('help', self._help), CommandHandler('version', self._version), ] @@ -472,15 +472,16 @@ class Telegram(RPC): self._send_msg(str(e), bot=bot) @authorized_only - def _blacklist(self, bot: Bot, update: Update) -> None: + def _blacklist(self, bot: Bot, update: Update, args: List[str]) -> None: """ Handler for /blacklist Shows the currently active blacklist """ try: - blacklist = self._rpc_blacklist() - message = f"Using blacklist `{blacklist['method']}` with {blacklist['length']} pairs\n" + blacklist = self._rpc_blacklist(args) + + message = f"Blacklist contains {blacklist['length']} pairs\n" message += f"`{', '.join(blacklist['blacklist'])}`" logger.debug(message) From f0d3901b6b77976836a0fb300b7980b7f3b9fdfc Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 24 Mar 2019 16:29:58 +0100 Subject: [PATCH 06/10] Add blacklist-pair to documentation --- docs/telegram-usage.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/telegram-usage.md b/docs/telegram-usage.md index 671229242..d0ee2849d 100644 --- a/docs/telegram-usage.md +++ b/docs/telegram-usage.md @@ -29,7 +29,7 @@ official commands. You can ask at any moment for help with `/help`. | `/balance` | | Show account balance per currency | `/daily ` | 7 | Shows profit or loss per day, over the last n days | `/whitelist` | | Show the current whitelist -| `/blacklist` | | Show the current blacklist +| `/blacklist [pair]` | | Show the current blacklist, or adds a pair to the blacklist. | `/help` | | Show help message | `/version` | | Show version @@ -169,10 +169,11 @@ 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] -### /blacklist - -Shows the current blacklist +Shows the current blacklist. +If Pair is set, then this pair will be added to the pairlist. +Use `/reload_conf` to reset the blacklist. > Using blacklist `StaticPairList` with 2 pairs >`DODGE/BTC`, `HOT/BTC`. From 042354d00f2ede1a9052ceb935f6c3edf2dffb73 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 24 Mar 2019 16:30:11 +0100 Subject: [PATCH 07/10] Test blacklist-adding --- freqtrade/tests/rpc/test_rpc_telegram.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/freqtrade/tests/rpc/test_rpc_telegram.py b/freqtrade/tests/rpc/test_rpc_telegram.py index fec2e508c..6adcda77b 100644 --- a/freqtrade/tests/rpc/test_rpc_telegram.py +++ b/freqtrade/tests/rpc/test_rpc_telegram.py @@ -1086,11 +1086,19 @@ def test_blacklist_static(default_conf, update, mocker) -> None: telegram = Telegram(freqtradebot) - telegram._blacklist(bot=MagicMock(), update=update) + telegram._blacklist(bot=MagicMock(), update=update, args=[]) assert msg_mock.call_count == 1 - assert ('Using blacklist `StaticPairList` with 2 pairs\n`DOGE/BTC, HOT/BTC`' + 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: patch_coinmarketcap(mocker) From 49559f1a1a4b553476ae986bc6bd677dc7f49890 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 24 Mar 2019 16:32:56 +0100 Subject: [PATCH 08/10] Improve documentation and help message --- docs/telegram-usage.md | 1 + freqtrade/rpc/telegram.py | 3 ++- freqtrade/tests/rpc/test_rpc_telegram.py | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/telegram-usage.md b/docs/telegram-usage.md index d0ee2849d..2f7e9ada8 100644 --- a/docs/telegram-usage.md +++ b/docs/telegram-usage.md @@ -173,6 +173,7 @@ Shows the current whitelist 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 diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 92108ded9..553ac4ed9 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -516,7 +516,8 @@ class Telegram(RPC): "*/stopbuy:* `Stops buying, but handles open trades gracefully` \n" \ "*/reload_conf:* `Reload configuration file` \n" \ "*/whitelist:* `Show current whitelist` \n" \ - "*/blacklist:* `Show current blacklist` \n" \ + "*/blacklist [pair]:* `Show current blacklist, or adds one or more pairs " \ + "to the blacklist.` \n" \ "*/help:* `This help message`\n" \ "*/version:* `Show version`" diff --git a/freqtrade/tests/rpc/test_rpc_telegram.py b/freqtrade/tests/rpc/test_rpc_telegram.py index 6adcda77b..dd49b0000 100644 --- a/freqtrade/tests/rpc/test_rpc_telegram.py +++ b/freqtrade/tests/rpc/test_rpc_telegram.py @@ -1099,7 +1099,6 @@ def test_blacklist_static(default_conf, update, mocker) -> None: assert freqtradebot.pairlists.blacklist == ["DOGE/BTC", "HOT/BTC", "ETH/BTC"] - def test_help_handle(default_conf, update, mocker) -> None: patch_coinmarketcap(mocker) msg_mock = MagicMock() From 14167f826ba8924c629438461294ab2fb4179690 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 24 Mar 2019 19:44:52 +0100 Subject: [PATCH 09/10] Fix typehints --- freqtrade/rpc/telegram.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 553ac4ed9..2c419e417 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -20,7 +20,7 @@ logger = logging.getLogger(__name__) 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 :param command_handler: Telegram CommandHandler From 29b9bb96f3bc745a0ee88b83b39db7584e732175 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 24 Mar 2019 19:49:49 +0100 Subject: [PATCH 10/10] Fix test to support adding things to pairlist --- freqtrade/tests/rpc/test_rpc.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/freqtrade/tests/rpc/test_rpc.py b/freqtrade/tests/rpc/test_rpc.py index b1fbd27ff..e6f7ea41e 100644 --- a/freqtrade/tests/rpc/test_rpc.py +++ b/freqtrade/tests/rpc/test_rpc.py @@ -702,6 +702,14 @@ def test_rpc_blacklist(mocker, default_conf) -> None: freqtradebot = FreqtradeBot(default_conf) rpc = RPC(freqtradebot) - ret = rpc._rpc_blacklist() + 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']