Force sell telergam inline keyboard selection
This commit is contained in:
parent
858d2329e5
commit
c1600188b6
@ -7,9 +7,9 @@ import arrow
|
|||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
from sqlalchemy import and_, func, text
|
from sqlalchemy import and_, func, text
|
||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
from telegram import ParseMode, Bot, Update, ReplyKeyboardMarkup
|
from telegram import ParseMode, Bot, Update, ReplyKeyboardMarkup, InlineKeyboardButton, InlineKeyboardMarkup
|
||||||
from telegram.error import NetworkError, TelegramError
|
from telegram.error import NetworkError, TelegramError
|
||||||
from telegram.ext import CommandHandler, Updater
|
from telegram.ext import CommandHandler, Updater, CallbackQueryHandler
|
||||||
|
|
||||||
from freqtrade import exchange, __version__
|
from freqtrade import exchange, __version__
|
||||||
from freqtrade.misc import get_state, State, update_state
|
from freqtrade.misc import get_state, State, update_state
|
||||||
@ -51,10 +51,14 @@ def init(config: dict) -> None:
|
|||||||
CommandHandler('performance', _performance),
|
CommandHandler('performance', _performance),
|
||||||
CommandHandler('count', _count),
|
CommandHandler('count', _count),
|
||||||
CommandHandler('help', _help),
|
CommandHandler('help', _help),
|
||||||
CommandHandler('version', _version),
|
CommandHandler('version', _version)
|
||||||
]
|
]
|
||||||
|
|
||||||
for handle in handles:
|
for handle in handles:
|
||||||
_UPDATER.dispatcher.add_handler(handle)
|
_UPDATER.dispatcher.add_handler(handle)
|
||||||
|
|
||||||
|
_UPDATER.dispatcher.add_handler(CallbackQueryHandler(_sell_callback))
|
||||||
|
|
||||||
_UPDATER.start_polling(
|
_UPDATER.start_polling(
|
||||||
clean=True,
|
clean=True,
|
||||||
bootstrap_retries=-1,
|
bootstrap_retries=-1,
|
||||||
@ -322,6 +326,47 @@ def _stop(bot: Bot, update: Update) -> None:
|
|||||||
send_msg('*Status:* `already stopped`', bot=bot)
|
send_msg('*Status:* `already stopped`', bot=bot)
|
||||||
|
|
||||||
|
|
||||||
|
@authorized_only
|
||||||
|
def _sell(bot: Bot, update: Update) -> None:
|
||||||
|
"""
|
||||||
|
Handler for /sell <id>.
|
||||||
|
Sells the given trade at current price
|
||||||
|
:param bot: telegram bot
|
||||||
|
:param update: message update
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
if get_state() != State.RUNNING:
|
||||||
|
send_msg('`trader is not running`', bot=bot)
|
||||||
|
return
|
||||||
|
|
||||||
|
trades = Trade.query.filter(Trade.is_open.is_(True)).all()
|
||||||
|
if not trades:
|
||||||
|
send_msg('no active trade', bot=bot)
|
||||||
|
return
|
||||||
|
|
||||||
|
button_list = []
|
||||||
|
for trade in trades:
|
||||||
|
# calculate profit and send message to user
|
||||||
|
current_rate = exchange.get_ticker(trade.pair)['bid']
|
||||||
|
current_profit = trade.calc_profit(current_rate)
|
||||||
|
|
||||||
|
message = '#{trade_id} [{pair}] ({current_profit:.2f}%)'.format(
|
||||||
|
trade_id=trade.id,
|
||||||
|
pair=trade.pair,
|
||||||
|
current_profit=round(current_profit * 100, 2)
|
||||||
|
)
|
||||||
|
button_list.append(InlineKeyboardButton(message, callback_data=trade.id))
|
||||||
|
|
||||||
|
reply_markup = InlineKeyboardMarkup(build_menu(button_list, n_cols=1))
|
||||||
|
|
||||||
|
send_msg('Choose order for sell:', inline_markup=reply_markup)
|
||||||
|
|
||||||
|
|
||||||
|
def _sell_callback(bot, update):
|
||||||
|
query = update.callback_query
|
||||||
|
sell_order(query.data)
|
||||||
|
|
||||||
|
|
||||||
@authorized_only
|
@authorized_only
|
||||||
def _forcesell(bot: Bot, update: Update) -> None:
|
def _forcesell(bot: Bot, update: Update) -> None:
|
||||||
"""
|
"""
|
||||||
@ -339,25 +384,10 @@ def _forcesell(bot: Bot, update: Update) -> None:
|
|||||||
if trade_id == 'all':
|
if trade_id == 'all':
|
||||||
# Execute sell for all open orders
|
# Execute sell for all open orders
|
||||||
for trade in Trade.query.filter(Trade.is_open.is_(True)).all():
|
for trade in Trade.query.filter(Trade.is_open.is_(True)).all():
|
||||||
# Get current rate
|
sell_order(trade.id)
|
||||||
current_rate = exchange.get_ticker(trade.pair)['bid']
|
|
||||||
from freqtrade.main import execute_sell
|
|
||||||
execute_sell(trade, current_rate)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Query for trade
|
sell_order(trade_id)
|
||||||
trade = Trade.query.filter(and_(
|
|
||||||
Trade.id == trade_id,
|
|
||||||
Trade.is_open.is_(True)
|
|
||||||
)).first()
|
|
||||||
if not trade:
|
|
||||||
send_msg('Invalid argument. See `/help` to view usage')
|
|
||||||
logger.warning('/forcesell: Invalid argument received')
|
|
||||||
return
|
|
||||||
# Get current rate
|
|
||||||
current_rate = exchange.get_ticker(trade.pair)['bid']
|
|
||||||
from freqtrade.main import execute_sell
|
|
||||||
execute_sell(trade, current_rate)
|
|
||||||
|
|
||||||
|
|
||||||
@authorized_only
|
@authorized_only
|
||||||
@ -463,12 +493,15 @@ def shorten_date(date):
|
|||||||
return new_date
|
return new_date
|
||||||
|
|
||||||
|
|
||||||
def send_msg(msg: str, bot: Bot = None, parse_mode: ParseMode = ParseMode.MARKDOWN) -> None:
|
def send_msg(msg: str, bot: Bot = None,
|
||||||
|
parse_mode: ParseMode = ParseMode.MARKDOWN,
|
||||||
|
inline_markup: InlineKeyboardMarkup = None) -> None:
|
||||||
"""
|
"""
|
||||||
Send given markdown message
|
Send given markdown message
|
||||||
:param msg: message
|
:param msg: message
|
||||||
:param bot: alternative bot
|
:param bot: alternative bot
|
||||||
:param parse_mode: telegram parse mode
|
:param parse_mode: telegram parse mode
|
||||||
|
:param inline_markup: inline_markup
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if not is_enabled():
|
if not is_enabled():
|
||||||
@ -478,9 +511,9 @@ def send_msg(msg: str, bot: Bot = None, parse_mode: ParseMode = ParseMode.MARKDO
|
|||||||
|
|
||||||
keyboard = [['/status table', '/profit', '/performance', ],
|
keyboard = [['/status table', '/profit', '/performance', ],
|
||||||
['/balance', '/status', '/count'],
|
['/balance', '/status', '/count'],
|
||||||
['/start', '/stop', '/help']]
|
['/start', '/stop', '/sell']]
|
||||||
|
|
||||||
reply_markup = ReplyKeyboardMarkup(keyboard)
|
reply_markup = inline_markup or ReplyKeyboardMarkup(keyboard)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
@ -495,3 +528,39 @@ def send_msg(msg: str, bot: Bot = None, parse_mode: ParseMode = ParseMode.MARKDO
|
|||||||
bot.send_message(_CONF['telegram']['chat_id'], msg, parse_mode=parse_mode, reply_markup=reply_markup)
|
bot.send_message(_CONF['telegram']['chat_id'], msg, parse_mode=parse_mode, reply_markup=reply_markup)
|
||||||
except TelegramError as telegram_err:
|
except TelegramError as telegram_err:
|
||||||
logger.warning('Got TelegramError: %s! Giving up on that message.', telegram_err.message)
|
logger.warning('Got TelegramError: %s! Giving up on that message.', telegram_err.message)
|
||||||
|
|
||||||
|
|
||||||
|
def sell_order(trade_id) -> None:
|
||||||
|
"""
|
||||||
|
Sell order by trade id
|
||||||
|
:param trade_id: trade id
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
# Query for trade
|
||||||
|
trade = Trade.query.filter(and_(
|
||||||
|
Trade.id == trade_id,
|
||||||
|
Trade.is_open.is_(True)
|
||||||
|
)).first()
|
||||||
|
if not trade:
|
||||||
|
send_msg('Order #{} not found'.format(trade_id))
|
||||||
|
logger.warning('/forcesell: Invalid argument received')
|
||||||
|
return
|
||||||
|
|
||||||
|
# Get current rate
|
||||||
|
current_rate = exchange.get_ticker(trade.pair)['bid']
|
||||||
|
from freqtrade.main import execute_sell
|
||||||
|
execute_sell(trade, current_rate)
|
||||||
|
|
||||||
|
|
||||||
|
def build_menu(buttons,
|
||||||
|
n_cols,
|
||||||
|
header_buttons=None,
|
||||||
|
footer_buttons=None):
|
||||||
|
menu = [buttons[i:i + n_cols] for i in range(0, len(buttons), n_cols)]
|
||||||
|
if header_buttons:
|
||||||
|
menu.insert(0, header_buttons)
|
||||||
|
if footer_buttons:
|
||||||
|
menu.append(footer_buttons)
|
||||||
|
|
||||||
|
return menu
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user