From 1e056ee415593b502dbb6277ecfc26e280956383 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 May 2019 14:07:08 +0200 Subject: [PATCH 1/4] Move trade jsonification to trade class --- freqtrade/persistence.py | 17 +++++++++++++++++ freqtrade/rpc/rpc.py | 19 ++++--------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index 5a18a922a..d25ea9fed 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -213,6 +213,23 @@ class Trade(_DECL_BASE): return (f'Trade(id={self.id}, pair={self.pair}, amount={self.amount:.8f}, ' f'open_rate={self.open_rate:.8f}, open_since={open_since})') + def to_json(self) -> Dict[str, Any]: + + return { + 'trade_id': self.id, + 'pair': self.pair, + 'date': arrow.get(self.open_date), + 'open_rate': self.open_rate, + 'close_rate': self.close_rate, + 'amount': round(self.amount, 8), + 'stake_amount': round(self.stake_amount, 8), + 'stop_loss': self.stop_loss, + 'stop_loss_pct': (self.stop_loss_pct * 100) if self.stop_loss_pct else None, + 'initial_stop_loss': self.initial_stop_loss, + 'initial_stop_loss_pct': (self.initial_stop_loss_pct * 100) + if self.initial_stop_loss_pct else None, + } + def adjust_min_max_rates(self, current_price: float): """ Adjust the max_rate and min_rate. diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index af384da45..37312318a 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -100,28 +100,17 @@ class RPC(object): current_profit = trade.calc_profit_percent(current_rate) fmt_close_profit = (f'{round(trade.close_profit * 100, 2):.2f}%' if trade.close_profit else None) - results.append(dict( - trade_id=trade.id, - pair=trade.pair, + trade_dict = trade.to_json() + trade_dict.update(dict( base_currency=self._freqtrade.config['stake_currency'], - date=arrow.get(trade.open_date), - open_rate=trade.open_rate, - close_rate=trade.close_rate, - current_rate=current_rate, - amount=round(trade.amount, 8), - stake_amount=round(trade.stake_amount, 8), close_profit=fmt_close_profit, + current_rate=current_rate, current_profit=round(current_profit * 100, 2), - stop_loss=trade.stop_loss, - stop_loss_pct=(trade.stop_loss_pct * 100) - if trade.stop_loss_pct else None, - initial_stop_loss=trade.initial_stop_loss, - initial_stop_loss_pct=(trade.initial_stop_loss_pct * 100) - if trade.initial_stop_loss_pct else None, open_order='({} {} rem={:.8f})'.format( order['type'], order['side'], order['remaining'] ) if order else None, )) + results.append(trade_dict) return results def _rpc_status_table(self) -> DataFrame: From 31d271084fe78f29a2358d719a95fb8e4e119128 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 6 May 2019 06:55:12 +0200 Subject: [PATCH 2/4] Move json to persistence --- freqtrade/persistence.py | 12 ++++++++---- freqtrade/rpc/telegram.py | 5 +---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index d25ea9fed..6088dba72 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -214,11 +214,15 @@ class Trade(_DECL_BASE): f'open_rate={self.open_rate:.8f}, open_since={open_since})') def to_json(self) -> Dict[str, Any]: - return { 'trade_id': self.id, 'pair': self.pair, - 'date': arrow.get(self.open_date), + 'open_date_hum': arrow.get(self.open_date).humanize(), + 'open_date': self.open_date.strftime("%Y-%m-%d %H:%M:%S"), + 'close_date_hum': (arrow.get(self.close_date).humanize() + if self.close_date else None), + 'close_date': (self.close_date.strftime("%Y-%m-%d %H:%M:%S") + if self.close_date else None), 'open_rate': self.open_rate, 'close_rate': self.close_rate, 'amount': round(self.amount, 8), @@ -226,8 +230,8 @@ class Trade(_DECL_BASE): 'stop_loss': self.stop_loss, 'stop_loss_pct': (self.stop_loss_pct * 100) if self.stop_loss_pct else None, 'initial_stop_loss': self.initial_stop_loss, - 'initial_stop_loss_pct': (self.initial_stop_loss_pct * 100) - if self.initial_stop_loss_pct else None, + 'initial_stop_loss_pct': (self.initial_stop_loss_pct * 100 + if self.initial_stop_loss_pct else None), } def adjust_min_max_rates(self, current_price: float): diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index dc0bad2b2..497c117ac 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -193,14 +193,11 @@ class Telegram(RPC): try: results = self._rpc_trade_status() - # pre format data - for result in results: - result['date'] = result['date'].humanize() messages = [] for r in results: lines = [ - "*Trade ID:* `{trade_id}` `(since {date})`", + "*Trade ID:* `{trade_id}` `(since {open_date_hum})`", "*Current Pair:* {pair}", "*Amount:* `{amount} ({stake_amount} {base_currency})`", "*Open Rate:* `{open_rate:.8f}`", From 2b78f73fe5e0ecb689c9d7d57b8f67bb6bc90b96 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 6 May 2019 06:56:07 +0200 Subject: [PATCH 3/4] Adapt tests to to_json method --- freqtrade/tests/rpc/test_rpc.py | 12 +++++++++--- freqtrade/tests/rpc/test_rpc_telegram.py | 5 ++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/freqtrade/tests/rpc/test_rpc.py b/freqtrade/tests/rpc/test_rpc.py index 93de6ef89..1f3f26dc9 100644 --- a/freqtrade/tests/rpc/test_rpc.py +++ b/freqtrade/tests/rpc/test_rpc.py @@ -47,12 +47,15 @@ def test_rpc_trade_status(default_conf, ticker, fee, markets, mocker) -> None: freqtradebot.create_trade() results = rpc._rpc_trade_status() - + print(results[0]) assert { 'trade_id': 1, 'pair': 'ETH/BTC', 'base_currency': 'BTC', - 'date': ANY, + 'open_date': ANY, + 'open_date_hum': ANY, + 'close_date': None, + 'close_date_hum': None, 'open_rate': 1.099e-05, 'close_rate': None, 'current_rate': 1.098e-05, @@ -78,7 +81,10 @@ def test_rpc_trade_status(default_conf, ticker, fee, markets, mocker) -> None: 'trade_id': 1, 'pair': 'ETH/BTC', 'base_currency': 'BTC', - 'date': ANY, + 'open_date': ANY, + 'open_date_hum': ANY, + 'close_date': None, + 'close_date_hum': None, 'open_rate': 1.099e-05, 'close_rate': None, 'current_rate': ANY, diff --git a/freqtrade/tests/rpc/test_rpc_telegram.py b/freqtrade/tests/rpc/test_rpc_telegram.py index f2f3f3945..86d728290 100644 --- a/freqtrade/tests/rpc/test_rpc_telegram.py +++ b/freqtrade/tests/rpc/test_rpc_telegram.py @@ -192,7 +192,10 @@ def test_status(default_conf, update, mocker, fee, ticker, markets) -> None: 'trade_id': 1, 'pair': 'ETH/BTC', 'base_currency': 'BTC', - 'date': arrow.utcnow(), + 'open_date': arrow.utcnow(), + 'open_date_hum': arrow.utcnow().humanize, + 'close_date': None, + 'close_date_hum': None, 'open_rate': 1.099e-05, 'close_rate': None, 'current_rate': 1.098e-05, From 1a677c7441e0773826a12f8000384dd485062a32 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 6 May 2019 06:56:22 +0200 Subject: [PATCH 4/4] Add explicit test for to_json --- freqtrade/tests/rpc/test_rpc.py | 1 - freqtrade/tests/test_persistence.py | 69 ++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/freqtrade/tests/rpc/test_rpc.py b/freqtrade/tests/rpc/test_rpc.py index 1f3f26dc9..6ce543f3d 100644 --- a/freqtrade/tests/rpc/test_rpc.py +++ b/freqtrade/tests/rpc/test_rpc.py @@ -47,7 +47,6 @@ def test_rpc_trade_status(default_conf, ticker, fee, markets, mocker) -> None: freqtradebot.create_trade() results = rpc._rpc_trade_status() - print(results[0]) assert { 'trade_id': 1, 'pair': 'ETH/BTC', diff --git a/freqtrade/tests/test_persistence.py b/freqtrade/tests/test_persistence.py index f57a466e3..8c15fa8e8 100644 --- a/freqtrade/tests/test_persistence.py +++ b/freqtrade/tests/test_persistence.py @@ -1,7 +1,8 @@ # pragma pylint: disable=missing-docstring, C0103 -from unittest.mock import MagicMock import logging +from unittest.mock import MagicMock +import arrow import pytest from sqlalchemy import create_engine @@ -710,3 +711,69 @@ def test_get_open(default_conf, fee): Trade.session.add(trade) assert len(Trade.get_open_trades()) == 2 + + +def test_to_json(default_conf, fee): + init(default_conf) + + # Simulate dry_run entries + trade = Trade( + pair='ETH/BTC', + stake_amount=0.001, + amount=123.0, + fee_open=fee.return_value, + fee_close=fee.return_value, + open_date=arrow.utcnow().shift(hours=-2).datetime, + open_rate=0.123, + exchange='bittrex', + open_order_id='dry_run_buy_12345' + ) + result = trade.to_json() + assert isinstance(result, dict) + print(result) + + assert result == {'trade_id': None, + 'pair': 'ETH/BTC', + 'open_date_hum': '2 hours ago', + 'open_date': trade.open_date.strftime("%Y-%m-%d %H:%M:%S"), + 'close_date_hum': None, + 'close_date': None, + 'open_rate': 0.123, + 'close_rate': None, + 'amount': 123.0, + 'stake_amount': 0.001, + 'stop_loss': None, + 'stop_loss_pct': None, + 'initial_stop_loss': None, + 'initial_stop_loss_pct': None} + + # Simulate dry_run entries + trade = Trade( + pair='XRP/BTC', + stake_amount=0.001, + amount=100.0, + fee_open=fee.return_value, + fee_close=fee.return_value, + open_date=arrow.utcnow().shift(hours=-2).datetime, + close_date=arrow.utcnow().shift(hours=-1).datetime, + open_rate=0.123, + close_rate=0.125, + exchange='bittrex', + ) + result = trade.to_json() + assert isinstance(result, dict) + + assert result == {'trade_id': None, + 'pair': 'XRP/BTC', + 'open_date_hum': '2 hours ago', + 'open_date': trade.open_date.strftime("%Y-%m-%d %H:%M:%S"), + 'close_date_hum': 'an hour ago', + 'close_date': trade.close_date.strftime("%Y-%m-%d %H:%M:%S"), + 'open_rate': 0.123, + 'close_rate': 0.125, + 'amount': 100.0, + 'stake_amount': 0.001, + 'stop_loss': None, + 'stop_loss_pct': None, + 'initial_stop_loss': None, + 'initial_stop_loss_pct': None}