Add `/forceshort` command

This commit is contained in:
Matthias 2022-01-26 19:53:46 +01:00
parent e2ddea79ee
commit 7afaf4b5d4
2 changed files with 24 additions and 10 deletions

View File

@ -19,6 +19,7 @@ from freqtrade.constants import CANCEL_REASON, DATETIME_PRINT_FORMAT
from freqtrade.data.history import load_data from freqtrade.data.history import load_data
from freqtrade.enums import SellType, State from freqtrade.enums import SellType, State
from freqtrade.enums.signaltype import SignalDirection from freqtrade.enums.signaltype import SignalDirection
from freqtrade.enums.tradingmode import TradingMode
from freqtrade.exceptions import ExchangeError, PricingError from freqtrade.exceptions import ExchangeError, PricingError
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_msecs from freqtrade.exchange import timeframe_to_minutes, timeframe_to_msecs
from freqtrade.loggers import bufferHandler from freqtrade.loggers import bufferHandler
@ -729,6 +730,9 @@ class RPC:
if self._freqtrade.state != State.RUNNING: if self._freqtrade.state != State.RUNNING:
raise RPCException('trader is not running') raise RPCException('trader is not running')
if order_side == SignalDirection.SHORT and self._freqtrade.trading_mode == TradingMode.SPOT:
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')
if not self._freqtrade.exchange.get_pair_quote_currency(pair) == stake_currency: if not self._freqtrade.exchange.get_pair_quote_currency(pair) == stake_currency:

View File

@ -7,6 +7,7 @@ import json
import logging import logging
import re import re
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta
from functools import partial
from html import escape from html import escape
from itertools import chain from itertools import chain
from math import isnan from math import isnan
@ -23,6 +24,7 @@ from telegram.utils.helpers import escape_markdown
from freqtrade.__init__ import __version__ from freqtrade.__init__ import __version__
from freqtrade.constants import DUST_PER_COIN from freqtrade.constants import DUST_PER_COIN
from freqtrade.enums import RPCMessageType from freqtrade.enums import RPCMessageType
from freqtrade.enums.signaltype import SignalDirection
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.misc import chunks, plural, round_coin_value from freqtrade.misc import chunks, plural, round_coin_value
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
@ -151,7 +153,8 @@ class Telegram(RPCHandler):
CommandHandler('start', self._start), CommandHandler('start', self._start),
CommandHandler('stop', self._stop), CommandHandler('stop', self._stop),
CommandHandler('forcesell', self._forcesell), CommandHandler('forcesell', self._forcesell),
CommandHandler('forcebuy', self._forcebuy), CommandHandler(['forcebuy', 'forcelong'], partial(self._forcebuy, order_side=SignalDirection.LONG)),
CommandHandler('forceshort', partial(self._forcebuy, 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),
@ -866,19 +869,20 @@ class Telegram(RPCHandler):
except RPCException as e: except RPCException as e:
self._send_msg(str(e)) self._send_msg(str(e))
def _forcebuy_action(self, pair, price=None): def _forceenter_action(self, pair, price: Optional[float], order_side: SignalDirection):
try: try:
self._rpc._rpc_force_entry(pair, price) self._rpc._rpc_force_entry(pair, price, order_side=order_side)
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 _forcebuy_inline(self, update: Update, _: CallbackContext) -> None:
if update.callback_query: if update.callback_query:
query = update.callback_query query = update.callback_query
pair = query.data pair, side = query.data.split('_||_')
order_side = SignalDirection(side)
query.answer() query.answer()
query.edit_message_text(text=f"Force Buying: {pair}") query.edit_message_text(text=f"Manually entering {order_side} for {pair}")
self._forcebuy_action(pair) self._forceenter_action(pair, None, order_side)
@staticmethod @staticmethod
def _layout_inline_keyboard(buttons: List[InlineKeyboardButton], def _layout_inline_keyboard(buttons: List[InlineKeyboardButton],
@ -886,7 +890,8 @@ class Telegram(RPCHandler):
return [buttons[i:i + cols] for i in range(0, len(buttons), cols)] return [buttons[i:i + cols] for i in range(0, len(buttons), cols)]
@authorized_only @authorized_only
def _forcebuy(self, update: Update, context: CallbackContext) -> None: def _forcebuy(
self, update: Update, context: CallbackContext, order_side: SignalDirection) -> None:
""" """
Handler for /forcebuy <asset> <price>. Handler for /forcebuy <asset> <price>.
Buys a pair trade at the given or current price Buys a pair trade at the given or current price
@ -897,13 +902,18 @@ class Telegram(RPCHandler):
if context.args: if context.args:
pair = context.args[0] pair = context.args[0]
price = float(context.args[1]) if len(context.args) > 1 else None price = float(context.args[1]) if len(context.args) > 1 else None
self._forcebuy_action(pair, price) self._forceenter_action(pair, price, order_side)
else: else:
whitelist = self._rpc._rpc_whitelist()['whitelist'] whitelist = self._rpc._rpc_whitelist()['whitelist']
pairs = [InlineKeyboardButton(text=pair, callback_data=pair) for pair in whitelist] pair_buttons = [
InlineKeyboardButton(text=pair, callback_data=f"{pair}_||_{order_side}")
for pair in whitelist
]
self._send_msg(msg="Which pair?", self._send_msg(msg="Which pair?",
keyboard=self._layout_inline_keyboard(pairs)) keyboard=self._layout_inline_keyboard(pair_buttons),
callback_path="update_forcelong",
query=update.callback_query)
@authorized_only @authorized_only
def _trades(self, update: Update, context: CallbackContext) -> None: def _trades(self, update: Update, context: CallbackContext) -> None: