Adds options for /status command

This commit is contained in:
Sebastien Moreau 2017-10-29 18:57:48 -04:00
parent 0e1eb20781
commit 8bdace68f6
4 changed files with 95 additions and 94 deletions

View File

@ -1,18 +0,0 @@
# http://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
max_line_length = 80
trim_trailing_whitespace = true
[*.md]
max_line_length = 0
trim_trailing_whitespace = false
[COMMIT_EDITMSG]
max_line_length = 0

View File

@ -1,74 +0,0 @@
#!/bin/bash
# Check if docker image exists
CMD_CHECK_IMAGE="docker images -q freqtrade:latest"
REBUILD=false
DRY_RUN=false
while getopts rdh option
do
case "${option}"
in
r) REBUILD=true
;;
d) DRY_RUN=true
;;
h) cat << EOF
Commands available :
-r Rebuild the container
-d Dry Run
-h This help message
EOF
exit 0
;;
esac
done
# Ensures files exists
[ -d ~/.freqtrade ] || mkdir ~/.freqtrade
cp config.json ~/.freqtrade/
touch ~/.freqtrade/tradesv2.sqlite
touch ~/.freqtrade/tradesv2.dry_run.sqlite
echo 'Stopping container...'
docker stop freqtrade > /dev/null \
&& docker rm freqtrade > /dev/null \
&& echo 'Container stopped'
if [[ -z $($CMD_CHECK_IMAGE) || $REBUILD = true ]]; then
echo "Building container"
docker build -t freqtrade .
fi
# Generates Docker commands based on options
DOCKER_CMD="docker run -d \
--name freqtrade \
-v ~/.freqtrade/config.json:/freqtrade/config.json"
if [[ $DRY_RUN = true ]]; then
DOCKER_CMD="$DOCKER_CMD \
-v ~/.freqtrade/tradesv2.dry_run.sqlite:/freqtrade/tradesv2.dry_run.sqlite"
else
DOCKER_CMD="$DOCKER_CMD \
-v ~/.freqtrade/tradesv2.sqlite:/freqtrade/tradesv2.sqlite"
fi
DOCKER_CMD="$DOCKER_CMD freqtrade"
echo 'Starting container'
eval $DOCKER_CMD \ > /dev/null \
&& echo 'Container ready' \
|| echo 'Problem starting container'
exit 0
docker run -d \
--name freqtrade \
-v ~/.freqtrade/config.json:/freqtrade/config.json \
-v ~/.freqtrade/tradesv2.dry_run.sqlite:/freqtrade/tradesv2.dry_run.sqlite \
freqtrade

View File

@ -1,6 +1,8 @@
import logging import logging
from datetime import timedelta from datetime import timedelta
from typing import Callable, Any from typing import Callable, Any
from pandas import DataFrame
from tabulate import tabulate
import arrow import arrow
from sqlalchemy import and_, func, text from sqlalchemy import and_, func, text
@ -100,6 +102,14 @@ def _status(bot: Bot, update: Update) -> None:
:param update: message update :param update: message update
:return: None :return: None
""" """
# Check if additional parameters are passed
params = update.message.text.replace('/status', '').split(' ') \
if update.message.text else []
if 'table' in params:
_status_table(bot, update)
return
# Fetch open trade # Fetch open trade
trades = Trade.query.filter(Trade.is_open.is_(True)).all() trades = Trade.query.filter(Trade.is_open.is_(True)).all()
if get_state() != State.RUNNING: if get_state() != State.RUNNING:
@ -145,6 +155,71 @@ def _status(bot: Bot, update: Update) -> None:
send_msg(message, bot=bot) send_msg(message, bot=bot)
@authorized_only
def _status_table(bot: Bot, update: Update) -> None:
"""
Handler for /status table.
Returns the current TradeThread status in table format
:param bot: telegram bot
:param update: message update
:return: None
"""
short_version = False
params = update.message.text.replace('/status', '').split(' ')
if 'short' in params:
short_version = True
# Fetch open trade
trades = Trade.query.filter(Trade.is_open.is_(True)).all()
if get_state() != State.RUNNING:
send_msg('*Status:* `trader is not running`', bot=bot)
elif not trades:
send_msg('*Status:* `no active order`', bot=bot)
else:
trades_list = []
for trade in trades:
# calculate profit and send message to user
current_rate = exchange.get_ticker(trade.pair)['bid']
current_profit = 100 * ((current_rate - trade.open_rate) / trade.open_rate)
orders = exchange.get_open_orders(trade.pair)
orders = [o for o in orders if o['id'] == trade.open_order_id]
order = orders[0] if orders else None
fmt_close_profit = '{:.2f}'.format(trade.close_profit) if trade.close_profit else 'No'
fmt_current_profit = '{:.2f}'.format(current_profit)
row = [
trade.id,
trade.pair,
shorten_date(arrow.get(trade.open_date).humanize()),
round(trade.amount, 8),
trade.open_rate,
trade.close_rate,
current_rate,
fmt_close_profit,
fmt_current_profit,
'{} ({})'.format(order['remaining'], order['type']) if order else 'No'
]
trades_list.append(row)
columns = ['ID', 'Pair', 'Since', 'Amount', 'Open Rate',
'Close Rate', 'Cur. Rate', 'Close Profit', 'Profit',
'Open Order']
df = DataFrame.from_records(trades_list, columns=columns)
df = df.set_index(columns[0])
columns_short = ['Pair', 'Since', 'Profit']
if short_version == True:
df = df[columns_short]
message = tabulate(df, headers='keys', tablefmt='simple')
message = "<pre>{}</pre>".format(message)
send_msg(message, parse_mode=ParseMode.HTML)
@authorized_only @authorized_only
def _profit(bot: Bot, update: Update) -> None: def _profit(bot: Bot, update: Update) -> None:
""" """
@ -346,15 +421,32 @@ def _help(bot: Bot, update: Update) -> None:
message = """ message = """
*/start:* `Starts the trader` */start:* `Starts the trader`
*/stop:* `Stops the trader` */stop:* `Stops the trader`
*/status:* `Lists all open trades` */status [table [short]]:* `Lists all open trades`
*table :* `will display trades in a table`
*short :* `condensed output`
*/profit:* `Lists cumulative profit from all finished trades` */profit:* `Lists cumulative profit from all finished trades`
*/forcesell <trade_id>:* `Instantly sells the given trade, regardless of profit` */forcesell <trade_id>:* `Instantly sells the given trade, regardless of profit`
*/performance:* `Show performance of each finished trade grouped by pair` */performance:* `Show performance of each finished trade grouped by pair`
*/count:* `Show number of trades running compared to allowed number of trades`
*/help:* `This help message` */help:* `This help message`
""" """
send_msg(message, bot=bot) send_msg(message, bot=bot)
def shorten_date(date):
return date.replace('ago', '') \
.replace('seconds', 's') \
.replace('minutes', 'm') \
.replace('minute', 'm') \
.replace('hours', 'h') \
.replace('hour', 'h') \
.replace('days', 'd') \
.replace('day', 'd') \
.replace('an', '1') \
.replace('a', '1') \
.replace(' ', '')
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) -> None:
""" """
Send given markdown message Send given markdown message

View File

@ -17,6 +17,7 @@ pytest-cov==2.5.1
hyperopt==0.1 hyperopt==0.1
# do not upgrade networkx before this is fixed https://github.com/hyperopt/hyperopt/issues/325 # do not upgrade networkx before this is fixed https://github.com/hyperopt/hyperopt/issues/325
networkx==1.11 networkx==1.11
tabulate==0.8.1
# Required for plotting data # Required for plotting data
#matplotlib==2.1.0 #matplotlib==2.1.0