Add /forceshort
command
This commit is contained in:
parent
e2ddea79ee
commit
7afaf4b5d4
@ -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:
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user