More forceenter updates
This commit is contained in:
parent
6e72effbf0
commit
c4f71cc103
@ -731,7 +731,7 @@ class RPC:
|
|||||||
raise RPCException('trader is not running')
|
raise RPCException('trader is not running')
|
||||||
|
|
||||||
if order_side == SignalDirection.SHORT and self._freqtrade.trading_mode == TradingMode.SPOT:
|
if order_side == SignalDirection.SHORT and self._freqtrade.trading_mode == TradingMode.SPOT:
|
||||||
raise RPCException("Can't go short on Spot markets")
|
raise RPCException("Can't go short on Spot markets.")
|
||||||
|
|
||||||
# Check if pair quote currency equals to the stake currency.
|
# Check if pair quote currency equals to the stake currency.
|
||||||
stake_currency = self._freqtrade.config.get('stake_currency')
|
stake_currency = self._freqtrade.config.get('stake_currency')
|
||||||
|
@ -155,8 +155,10 @@ class Telegram(RPCHandler):
|
|||||||
CommandHandler('start', self._start),
|
CommandHandler('start', self._start),
|
||||||
CommandHandler('stop', self._stop),
|
CommandHandler('stop', self._stop),
|
||||||
CommandHandler(['forcesell', 'forceexit'], self._forceexit),
|
CommandHandler(['forcesell', 'forceexit'], self._forceexit),
|
||||||
CommandHandler(['forcebuy', 'forcelong'], partial(self._forceenter, order_side=SignalDirection.LONG)),
|
CommandHandler(['forcebuy', 'forcelong'], partial(
|
||||||
CommandHandler('forceshort', partial(self._forceenter, order_side=SignalDirection.SHORT)),
|
self._forceenter, order_side=SignalDirection.LONG)),
|
||||||
|
CommandHandler('forceshort', partial(
|
||||||
|
self._forceenter, order_side=SignalDirection.SHORT)),
|
||||||
CommandHandler('trades', self._trades),
|
CommandHandler('trades', self._trades),
|
||||||
CommandHandler('delete', self._delete_trade),
|
CommandHandler('delete', self._delete_trade),
|
||||||
CommandHandler('performance', self._performance),
|
CommandHandler('performance', self._performance),
|
||||||
@ -195,7 +197,7 @@ class Telegram(RPCHandler):
|
|||||||
pattern='update_sell_reason_performance'),
|
pattern='update_sell_reason_performance'),
|
||||||
CallbackQueryHandler(self._mix_tag_performance, pattern='update_mix_tag_performance'),
|
CallbackQueryHandler(self._mix_tag_performance, pattern='update_mix_tag_performance'),
|
||||||
CallbackQueryHandler(self._count, pattern='update_count'),
|
CallbackQueryHandler(self._count, pattern='update_count'),
|
||||||
CallbackQueryHandler(self._forcebuy_inline),
|
CallbackQueryHandler(self._forceenter_inline),
|
||||||
]
|
]
|
||||||
for handle in handles:
|
for handle in handles:
|
||||||
self._updater.dispatcher.add_handler(handle)
|
self._updater.dispatcher.add_handler(handle)
|
||||||
@ -877,14 +879,15 @@ class Telegram(RPCHandler):
|
|||||||
except RPCException as e:
|
except RPCException as e:
|
||||||
self._send_msg(str(e))
|
self._send_msg(str(e))
|
||||||
|
|
||||||
def _forcebuy_inline(self, update: Update, _: CallbackContext) -> None:
|
def _forceenter_inline(self, update: Update, _: CallbackContext) -> None:
|
||||||
if update.callback_query:
|
if update.callback_query:
|
||||||
query = update.callback_query
|
query = update.callback_query
|
||||||
pair, side = query.data.split('_||_')
|
if query.data and '_||_' in query.data:
|
||||||
order_side = SignalDirection(side)
|
pair, side = query.data.split('_||_')
|
||||||
query.answer()
|
order_side = SignalDirection(side)
|
||||||
query.edit_message_text(text=f"Manually entering {order_side} for {pair}")
|
query.answer()
|
||||||
self._forceenter_action(pair, None, order_side)
|
query.edit_message_text(text=f"Manually entering {order_side} for {pair}")
|
||||||
|
self._forceenter_action(pair, None, order_side)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _layout_inline_keyboard(buttons: List[InlineKeyboardButton],
|
def _layout_inline_keyboard(buttons: List[InlineKeyboardButton],
|
||||||
@ -1281,14 +1284,14 @@ class Telegram(RPCHandler):
|
|||||||
:param update: message update
|
:param update: message update
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
forcebuy_text = ("*/forcelong <pair> [<rate>]:* `Instantly buys the given pair. "
|
forceenter_text = ("*/forcelong <pair> [<rate>]:* `Instantly buys the given pair. "
|
||||||
"Optionally takes a rate at which to buy "
|
"Optionally takes a rate at which to buy "
|
||||||
"(only applies to limit orders).` \n"
|
"(only applies to limit orders).` \n"
|
||||||
)
|
)
|
||||||
if self._rpc._freqtrade.trading_mode != TradingMode.SPOT:
|
if self._rpc._freqtrade.trading_mode != TradingMode.SPOT:
|
||||||
forcebuy_text += ("*/forceshort <pair> [<rate>]:* `Instantly shorts the given pair. "
|
forceenter_text += ("*/forceshort <pair> [<rate>]:* `Instantly shorts the given pair. "
|
||||||
"Optionally takes a rate at which to sell "
|
"Optionally takes a rate at which to sell "
|
||||||
"(only applies to limit orders).` \n")
|
"(only applies to limit orders).` \n")
|
||||||
message = (
|
message = (
|
||||||
"_BotControl_\n"
|
"_BotControl_\n"
|
||||||
"------------\n"
|
"------------\n"
|
||||||
@ -1297,7 +1300,7 @@ class Telegram(RPCHandler):
|
|||||||
"*/stopbuy:* `Stops buying, but handles open trades gracefully` \n"
|
"*/stopbuy:* `Stops buying, but handles open trades gracefully` \n"
|
||||||
"*/forceexit <trade_id>|all:* `Instantly exits the given trade or all trades, "
|
"*/forceexit <trade_id>|all:* `Instantly exits the given trade or all trades, "
|
||||||
"regardless of profit`\n"
|
"regardless of profit`\n"
|
||||||
f"{forcebuy_text if self._config.get('forcebuy_enable', False) else ''}"
|
f"{forceenter_text if self._config.get('forcebuy_enable', False) else ''}"
|
||||||
"*/delete <trade_id>:* `Instantly delete the given trade in the database`\n"
|
"*/delete <trade_id>:* `Instantly delete the given trade in the database`\n"
|
||||||
"*/whitelist:* `Show current whitelist` \n"
|
"*/whitelist:* `Show current whitelist` \n"
|
||||||
"*/blacklist [pair]:* `Show current blacklist, or adds one or more pairs "
|
"*/blacklist [pair]:* `Show current blacklist, or adds one or more pairs "
|
||||||
|
@ -9,6 +9,7 @@ from numpy import isnan
|
|||||||
|
|
||||||
from freqtrade.edge import PairInfo
|
from freqtrade.edge import PairInfo
|
||||||
from freqtrade.enums import State, TradingMode
|
from freqtrade.enums import State, TradingMode
|
||||||
|
from freqtrade.enums.signaltype import SignalDirection
|
||||||
from freqtrade.exceptions import ExchangeError, InvalidOrderException, TemporaryError
|
from freqtrade.exceptions import ExchangeError, InvalidOrderException, TemporaryError
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.persistence.pairlock_middleware import PairLocks
|
from freqtrade.persistence.pairlock_middleware import PairLocks
|
||||||
@ -1165,6 +1166,18 @@ def test_rpc_forceentry_disabled(mocker, default_conf) -> None:
|
|||||||
rpc._rpc_force_entry(pair, None)
|
rpc._rpc_force_entry(pair, None)
|
||||||
|
|
||||||
|
|
||||||
|
def test_rpc_forceentry_wrong_mode(mocker, default_conf) -> None:
|
||||||
|
default_conf['forcebuy_enable'] = True
|
||||||
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
|
|
||||||
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
|
patch_get_signal(freqtradebot)
|
||||||
|
rpc = RPC(freqtradebot)
|
||||||
|
pair = 'ETH/BTC'
|
||||||
|
with pytest.raises(RPCException, match="Can't go short on Spot markets."):
|
||||||
|
rpc._rpc_force_entry(pair, None, order_side=SignalDirection.SHORT)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("init_persistence")
|
@pytest.mark.usefixtures("init_persistence")
|
||||||
def test_rpc_delete_lock(mocker, default_conf):
|
def test_rpc_delete_lock(mocker, default_conf):
|
||||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
|
@ -1145,7 +1145,7 @@ def test_forceenter_handle(default_conf, update, mocker) -> None:
|
|||||||
telegram, freqtradebot, _ = get_telegram_testobject(mocker, default_conf)
|
telegram, freqtradebot, _ = get_telegram_testobject(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot)
|
patch_get_signal(freqtradebot)
|
||||||
|
|
||||||
# /forcebuy ETH/BTC
|
# /forcelong ETH/BTC
|
||||||
context = MagicMock()
|
context = MagicMock()
|
||||||
context.args = ["ETH/BTC"]
|
context.args = ["ETH/BTC"]
|
||||||
telegram._forceenter(update=update, context=context, order_side=SignalDirection.LONG)
|
telegram._forceenter(update=update, context=context, order_side=SignalDirection.LONG)
|
||||||
@ -1153,11 +1153,12 @@ def test_forceenter_handle(default_conf, update, mocker) -> None:
|
|||||||
assert fbuy_mock.call_count == 1
|
assert fbuy_mock.call_count == 1
|
||||||
assert fbuy_mock.call_args_list[0][0][0] == 'ETH/BTC'
|
assert fbuy_mock.call_args_list[0][0][0] == 'ETH/BTC'
|
||||||
assert fbuy_mock.call_args_list[0][0][1] is None
|
assert fbuy_mock.call_args_list[0][0][1] is None
|
||||||
|
assert fbuy_mock.call_args_list[0][1]['order_side'] == SignalDirection.LONG
|
||||||
|
|
||||||
# Reset and retry with specified price
|
# Reset and retry with specified price
|
||||||
fbuy_mock = MagicMock(return_value=None)
|
fbuy_mock = MagicMock(return_value=None)
|
||||||
mocker.patch('freqtrade.rpc.RPC._rpc_force_entry', fbuy_mock)
|
mocker.patch('freqtrade.rpc.RPC._rpc_force_entry', fbuy_mock)
|
||||||
# /forcebuy ETH/BTC 0.055
|
# /forcelong ETH/BTC 0.055
|
||||||
context = MagicMock()
|
context = MagicMock()
|
||||||
context.args = ["ETH/BTC", "0.055"]
|
context.args = ["ETH/BTC", "0.055"]
|
||||||
telegram._forceenter(update=update, context=context, order_side=SignalDirection.LONG)
|
telegram._forceenter(update=update, context=context, order_side=SignalDirection.LONG)
|
||||||
@ -1204,7 +1205,7 @@ def test_forceenter_no_pair(default_conf, update, mocker) -> None:
|
|||||||
update = MagicMock()
|
update = MagicMock()
|
||||||
update.callback_query = MagicMock()
|
update.callback_query = MagicMock()
|
||||||
update.callback_query.data = 'XRP/USDT_||_long'
|
update.callback_query.data = 'XRP/USDT_||_long'
|
||||||
telegram._forcebuy_inline(update, None)
|
telegram._forceenter_inline(update, None)
|
||||||
assert fbuy_mock.call_count == 1
|
assert fbuy_mock.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user