Merge pull request #1697 from freqtrade/feat/rpc_blacklist
add pairs to blacklist dynamically
This commit is contained in:
commit
b13735e4cc
@ -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`
|
||||||
|
@ -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
|
||||||
|
@ -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`"
|
||||||
|
|
||||||
|
@ -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": {
|
||||||
|
@ -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']
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user