From 560802c326e9e8baed1e4873a7794531e40988ec Mon Sep 17 00:00:00 2001 From: theluxaz Date: Thu, 28 Oct 2021 21:39:42 +0300 Subject: [PATCH] Added tests for the new rpc/telegram functions --- freqtrade/rpc/telegram.py | 6 +- tests/conftest.py | 25 ----- tests/conftest_trades.py | 3 + tests/conftest_trades_tags.py | 165 --------------------------------- tests/rpc/test_rpc.py | 138 ++++++++++++++++++++------- tests/rpc/test_rpc_telegram.py | 32 +++---- 6 files changed, 125 insertions(+), 244 deletions(-) delete mode 100644 tests/conftest_trades_tags.py diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index f79f8d457..23938c686 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -887,7 +887,7 @@ class Telegram(RPCHandler): """ try: pair = None - if context.args: + if context.args and isinstance(context.args[0], str): pair = context.args[0] trades = self._rpc._rpc_buy_tag_performance(pair) @@ -922,7 +922,7 @@ class Telegram(RPCHandler): """ try: pair = None - if context.args: + if context.args and isinstance(context.args[0], str): pair = context.args[0] trades = self._rpc._rpc_sell_reason_performance(pair) @@ -957,7 +957,7 @@ class Telegram(RPCHandler): """ try: pair = None - if context.args: + if context.args and isinstance(context.args[0], str): pair = context.args[0] trades = self._rpc._rpc_mix_tag_performance(pair) diff --git a/tests/conftest.py b/tests/conftest.py index a2a9f77c6..501cfc9b9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -32,7 +32,6 @@ from tests.conftest_trades import ( mock_trade_6) from tests.conftest_trades_usdt import (mock_trade_usdt_1, mock_trade_usdt_2, mock_trade_usdt_3, mock_trade_usdt_4, mock_trade_usdt_5, mock_trade_usdt_6) -from tests.conftest_trades_tags import (mock_trade_tags_1, mock_trade_tags_2, mock_trade_tags_3) logging.getLogger('').setLevel(logging.INFO) @@ -234,30 +233,6 @@ def create_mock_trades(fee, use_db: bool = True): Trade.commit() -def create_mock_trades_tags(fee, use_db: bool = True): - """ - Create some fake trades to simulate buy tags and sell reasons - """ - def add_trade(trade): - if use_db: - Trade.query.session.add(trade) - else: - LocalTrade.add_bt_trade(trade) - - # Simulate dry_run entries - trade = mock_trade_tags_1(fee) - add_trade(trade) - - trade = mock_trade_tags_2(fee) - add_trade(trade) - - trade = mock_trade_tags_3(fee) - add_trade(trade) - - if use_db: - Trade.commit() - - def create_mock_trades_usdt(fee, use_db: bool = True): """ Create some fake trades ... diff --git a/tests/conftest_trades.py b/tests/conftest_trades.py index 024803be0..4496df37d 100644 --- a/tests/conftest_trades.py +++ b/tests/conftest_trades.py @@ -89,6 +89,7 @@ def mock_trade_2(fee): open_order_id='dry_run_sell_12345', strategy='StrategyTestV2', timeframe=5, + buy_tag='TEST1', sell_reason='sell_signal', open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=20), close_date=datetime.now(tz=timezone.utc) - timedelta(minutes=2), @@ -241,6 +242,7 @@ def mock_trade_5(fee): open_rate=0.123, exchange='binance', strategy='SampleStrategy', + buy_tag='TEST1', stoploss_order_id='prod_stoploss_3455', timeframe=5, ) @@ -295,6 +297,7 @@ def mock_trade_6(fee): open_rate=0.15, exchange='binance', strategy='SampleStrategy', + buy_tag='TEST2', open_order_id="prod_sell_6", timeframe=5, ) diff --git a/tests/conftest_trades_tags.py b/tests/conftest_trades_tags.py deleted file mode 100644 index db0d3d3bd..000000000 --- a/tests/conftest_trades_tags.py +++ /dev/null @@ -1,165 +0,0 @@ -from datetime import datetime, timedelta, timezone - -from freqtrade.persistence.models import Order, Trade - - -MOCK_TRADE_COUNT = 3 - - -def mock_order_1(): - return { - 'id': 'prod_buy_1', - 'symbol': 'LTC/BTC', - 'status': 'closed', - 'side': 'buy', - 'type': 'limit', - 'price': 0.15, - 'amount': 2.0, - 'filled': 2.0, - 'remaining': 0.0, - } - - -def mock_order_1_sell(): - return { - 'id': 'prod_sell_1', - 'symbol': 'LTC/BTC', - 'status': 'open', - 'side': 'sell', - 'type': 'limit', - 'price': 0.20, - 'amount': 2.0, - 'filled': 0.0, - 'remaining': 2.0, - } - - -def mock_trade_tags_1(fee): - trade = Trade( - pair='LTC/BTC', - stake_amount=0.001, - amount=2.0, - amount_requested=2.0, - fee_open=fee.return_value, - fee_close=fee.return_value, - is_open=True, - open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=15), - open_rate=0.15, - exchange='binance', - open_order_id='dry_run_buy_123455', - strategy='StrategyTestV2', - timeframe=5, - buy_tag="BUY_TAG1", - sell_reason="SELL_REASON2" - ) - o = Order.parse_from_ccxt_object(mock_order_1(), 'LTC/BTC', 'buy') - trade.orders.append(o) - o = Order.parse_from_ccxt_object(mock_order_1_sell(), 'LTC/BTC', 'sell') - trade.orders.append(o) - return trade - - -def mock_order_2(): - return { - 'id': '1239', - 'symbol': 'LTC/BTC', - 'status': 'closed', - 'side': 'buy', - 'type': 'limit', - 'price': 0.120, - 'amount': 100.0, - 'filled': 100.0, - 'remaining': 0.0, - } - - -def mock_order_2_sell(): - return { - 'id': '12392', - 'symbol': 'LTC/BTC', - 'status': 'closed', - 'side': 'sell', - 'type': 'limit', - 'price': 0.138, - 'amount': 100.0, - 'filled': 100.0, - 'remaining': 0.0, - } - - -def mock_trade_tags_2(fee): - trade = Trade( - pair='LTC/BTC', - stake_amount=0.001, - amount=100.0, - amount_requested=100.0, - fee_open=fee.return_value, - fee_close=fee.return_value, - is_open=True, - open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=13), - open_rate=0.120, - exchange='binance', - open_order_id='dry_run_buy_123456', - strategy='StrategyTestV2', - timeframe=5, - buy_tag="BUY_TAG2", - sell_reason="SELL_REASON1" - ) - o = Order.parse_from_ccxt_object(mock_order_2(), 'LTC/BTC', 'buy') - trade.orders.append(o) - o = Order.parse_from_ccxt_object(mock_order_2_sell(), 'LTC/BTC', 'sell') - trade.orders.append(o) - return trade - - -def mock_order_3(): - return { - 'id': '1235', - 'symbol': 'ETC/BTC', - 'status': 'closed', - 'side': 'buy', - 'type': 'limit', - 'price': 0.123, - 'amount': 123.0, - 'filled': 123.0, - 'remaining': 0.0, - } - - -def mock_order_3_sell(): - return { - 'id': '12352', - 'symbol': 'ETC/BTC', - 'status': 'closed', - 'side': 'sell', - 'type': 'limit', - 'price': 0.128, - 'amount': 123.0, - 'filled': 123.0, - 'remaining': 0.0, - } - - -def mock_trade_tags_3(fee): - trade = Trade( - pair='ETC/BTC', - stake_amount=0.001, - amount=123.0, - amount_requested=123.0, - fee_open=fee.return_value, - fee_close=fee.return_value, - is_open=True, - open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=12), - open_rate=0.123, - exchange='binance', - open_order_id='dry_run_buy_123457', - strategy='StrategyTestV2', - timeframe=5, - buy_tag="BUY_TAG1", - sell_reason="SELL_REASON2" - ) - o = Order.parse_from_ccxt_object(mock_order_3(), 'ETC/BTC', 'buy') - trade.orders.append(o) - o = Order.parse_from_ccxt_object(mock_order_3_sell(), 'ETC/BTC', 'sell') - trade.orders.append(o) - return trade diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index bce618f30..aeb0483de 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -14,7 +14,7 @@ from freqtrade.persistence import Trade from freqtrade.persistence.pairlock_middleware import PairLocks from freqtrade.rpc import RPC, RPCException from freqtrade.rpc.fiat_convert import CryptoToFiatConverter -from tests.conftest import create_mock_trades, get_patched_freqtradebot, patch_get_signal, create_mock_trades_tags +from tests.conftest import create_mock_trades, get_patched_freqtradebot, patch_get_signal # Functions for recurrent object patching @@ -826,11 +826,7 @@ def test_performance_handle(default_conf, ticker, limit_buy_order, fee, assert len(res) == 1 assert res[0]['pair'] == 'ETH/BTC' assert res[0]['count'] == 1 - assert prec_satoshi(res[0]['profit'], 6.3) - - # TEST FOR TRADES WITH NO BUY TAG - # TEST TRADE WITH ONE BUY_TAG AND OTHER TWO TRADES WITH THE SAME TAG - # TEST THE SAME FOR A PAIR + assert prec_satoshi(res[0]['profit'], 6.2) def test_buy_tag_performance_handle(default_conf, ticker, limit_buy_order, fee, @@ -861,23 +857,22 @@ def test_buy_tag_performance_handle(default_conf, ticker, limit_buy_order, fee, trade.close_date = datetime.utcnow() trade.is_open = False res = rpc._rpc_buy_tag_performance(None) - print(str(res)) + assert len(res) == 1 assert res[0]['buy_tag'] == 'Other' assert res[0]['count'] == 1 assert prec_satoshi(res[0]['profit'], 6.2) - print(Trade.pair) trade.buy_tag = "TEST_TAG" res = rpc._rpc_buy_tag_performance(None) - print(str(res)) + assert len(res) == 1 assert res[0]['buy_tag'] == 'TEST_TAG' assert res[0]['count'] == 1 - assert prec_satoshi(res[0]['profit'], 6.3) + assert prec_satoshi(res[0]['profit'], 6.2) -def test_buy_tag_performance_handle2(mocker, default_conf, markets, fee): +def test_buy_tag_performance_handle_2(mocker, default_conf, markets, fee): mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -885,22 +880,25 @@ def test_buy_tag_performance_handle2(mocker, default_conf, markets, fee): ) freqtradebot = get_patched_freqtradebot(mocker, default_conf) - #create_mock_trades(fee) #this works - create_mock_trades_tags(fee) #this doesn't + create_mock_trades(fee) rpc = RPC(freqtradebot) - trades = Trade.query.all() + res = rpc._rpc_buy_tag_performance(None) - res = rpc._rpc_performance() - print(res) - assert len(trades) == 1 - assert trades[0]['buy_tag'] == 'TEST_TAG' - assert trades[0]['count'] == 1 - assert prec_satoshi(trades[0]['profit'], 6.3) + assert len(res) == 2 + assert res[0]['buy_tag'] == 'TEST1' + assert res[0]['count'] == 1 + assert prec_satoshi(res[0]['profit'], 0.5) + assert res[1]['buy_tag'] == 'Other' + assert res[1]['count'] == 1 + assert prec_satoshi(res[1]['profit'], 1.0) - # TEST FOR TRADES WITH NO SELL REASON - # TEST TRADE WITH ONE SELL REASON AND OTHER TWO TRADES WITH THE SAME reason - # TEST THE SAME FOR A PAIR + # Test for a specific pair + res = rpc._rpc_buy_tag_performance('ETC/BTC') + assert len(res) == 1 + assert res[0]['count'] == 1 + assert res[0]['buy_tag'] == 'TEST1' + assert prec_satoshi(res[0]['profit'], 0.5) def test_sell_reason_performance_handle(default_conf, ticker, limit_buy_order, fee, @@ -931,14 +929,48 @@ def test_sell_reason_performance_handle(default_conf, ticker, limit_buy_order, f trade.close_date = datetime.utcnow() trade.is_open = False res = rpc._rpc_sell_reason_performance(None) - assert len(res) == 1 - # assert res[0]['pair'] == 'ETH/BTC' - # assert res[0]['count'] == 1 - # assert prec_satoshi(res[0]['profit'], 6.2) - # TEST FOR TRADES WITH NO TAGS - # TEST TRADE WITH ONE TAG MIX AND OTHER TWO TRADES WITH THE SAME TAG MIX - # TEST THE SAME FOR A PAIR + assert len(res) == 1 + assert res[0]['sell_reason'] == 'Other' + assert res[0]['count'] == 1 + assert prec_satoshi(res[0]['profit'], 6.2) + + trade.sell_reason = "TEST1" + res = rpc._rpc_sell_reason_performance(None) + + assert len(res) == 1 + assert res[0]['sell_reason'] == 'TEST1' + assert res[0]['count'] == 1 + assert prec_satoshi(res[0]['profit'], 6.2) + + +def test_sell_reason_performance_handle_2(mocker, default_conf, markets, fee): + mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) + mocker.patch.multiple( + 'freqtrade.exchange.Exchange', + markets=PropertyMock(return_value=markets) + ) + + freqtradebot = get_patched_freqtradebot(mocker, default_conf) + create_mock_trades(fee) + rpc = RPC(freqtradebot) + + res = rpc._rpc_sell_reason_performance(None) + + assert len(res) == 2 + assert res[0]['sell_reason'] == 'sell_signal' + assert res[0]['count'] == 1 + assert prec_satoshi(res[0]['profit'], 0.5) + assert res[1]['sell_reason'] == 'roi' + assert res[1]['count'] == 1 + assert prec_satoshi(res[1]['profit'], 1.0) + + # Test for a specific pair + res = rpc._rpc_sell_reason_performance('ETC/BTC') + assert len(res) == 1 + assert res[0]['count'] == 1 + assert res[0]['sell_reason'] == 'sell_signal' + assert prec_satoshi(res[0]['profit'], 0.5) def test_mix_tag_performance_handle(default_conf, ticker, limit_buy_order, fee, @@ -969,10 +1001,50 @@ def test_mix_tag_performance_handle(default_conf, ticker, limit_buy_order, fee, trade.close_date = datetime.utcnow() trade.is_open = False res = rpc._rpc_mix_tag_performance(None) + assert len(res) == 1 - # assert res[0]['pair'] == 'ETH/BTC' - # assert res[0]['count'] == 1 - # assert prec_satoshi(res[0]['profit'], 6.2) + assert res[0]['mix_tag'] == 'Other Other' + assert res[0]['count'] == 1 + assert prec_satoshi(res[0]['profit'], 6.2) + + trade.buy_tag = "TESTBUY" + trade.sell_reason = "TESTSELL" + res = rpc._rpc_mix_tag_performance(None) + + assert len(res) == 1 + assert res[0]['mix_tag'] == 'TESTBUY TESTSELL' + assert res[0]['count'] == 1 + assert prec_satoshi(res[0]['profit'], 6.2) + + +def test_mix_tag_performance_handle_2(mocker, default_conf, markets, fee): + mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) + mocker.patch.multiple( + 'freqtrade.exchange.Exchange', + markets=PropertyMock(return_value=markets) + ) + + freqtradebot = get_patched_freqtradebot(mocker, default_conf) + create_mock_trades(fee) + rpc = RPC(freqtradebot) + + res = rpc._rpc_mix_tag_performance(None) + + assert len(res) == 2 + assert res[0]['mix_tag'] == 'TEST1 sell_signal' + assert res[0]['count'] == 1 + assert prec_satoshi(res[0]['profit'], 0.5) + assert res[1]['mix_tag'] == 'Other roi' + assert res[1]['count'] == 1 + assert prec_satoshi(res[1]['profit'], 1.0) + + # Test for a specific pair + res = rpc._rpc_mix_tag_performance('ETC/BTC') + + assert len(res) == 1 + assert res[0]['count'] == 1 + assert res[0]['mix_tag'] == 'TEST1 sell_signal' + assert prec_satoshi(res[0]['profit'], 0.5) def test_rpc_count(mocker, default_conf, ticker, fee) -> None: diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index 306181eae..f669e9411 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -978,10 +978,6 @@ def test_performance_handle(default_conf, update, ticker, fee, assert 'Performance' in msg_mock.call_args_list[0][0][0] assert 'ETH/BTC\t0.00006217 BTC (6.20%) (1)' in msg_mock.call_args_list[0][0][0] - # TEST FOR TRADES WITH NO BUY TAG - # TEST TRADE WITH ONE BUY_TAG AND OTHER TWO TRADES WITH THE SAME TAG - # TEST THE SAME FOR A PAIR - def test_buy_tag_performance_handle(default_conf, update, ticker, fee, limit_buy_order, limit_sell_order, mocker) -> None: @@ -1001,19 +997,17 @@ def test_buy_tag_performance_handle(default_conf, update, ticker, fee, # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) + trade.buy_tag = "TESTBUY" # Simulate fulfilled LIMIT_SELL order for trade trade.update(limit_sell_order) trade.close_date = datetime.utcnow() trade.is_open = False + telegram._buy_tag_performance(update=update, context=MagicMock()) assert msg_mock.call_count == 1 - assert 'Performance' in msg_mock.call_args_list[0][0][0] - assert 'ETH/BTC\t0.00006217 BTC (6.20%) (1)' in msg_mock.call_args_list[0][0][0] - - # TEST FOR TRADES WITH NO SELL REASON - # TEST TRADE WITH ONE SELL REASON AND OTHER TWO TRADES WITH THE SAME reason - # TEST THE SAME FOR A PAIR + assert 'Buy Tag Performance' in msg_mock.call_args_list[0][0][0] + assert 'TESTBUY\t0.00006217 BTC (6.20%) (1)' in msg_mock.call_args_list[0][0][0] def test_sell_reason_performance_handle(default_conf, update, ticker, fee, @@ -1034,19 +1028,17 @@ def test_sell_reason_performance_handle(default_conf, update, ticker, fee, # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) + trade.sell_reason = 'TESTSELL' # Simulate fulfilled LIMIT_SELL order for trade trade.update(limit_sell_order) trade.close_date = datetime.utcnow() trade.is_open = False + telegram._sell_reason_performance(update=update, context=MagicMock()) assert msg_mock.call_count == 1 - assert 'Performance' in msg_mock.call_args_list[0][0][0] - assert 'ETH/BTC\t0.00006217 BTC (6.20%) (1)' in msg_mock.call_args_list[0][0][0] - - # TEST FOR TRADES WITH NO TAGS - # TEST TRADE WITH ONE TAG MIX AND OTHER TWO TRADES WITH THE SAME TAG MIX - # TEST THE SAME FOR A PAIR + assert 'Sell Reason Performance' in msg_mock.call_args_list[0][0][0] + assert 'TESTSELL\t0.00006217 BTC (6.20%) (1)' in msg_mock.call_args_list[0][0][0] def test_mix_tag_performance_handle(default_conf, update, ticker, fee, @@ -1067,15 +1059,19 @@ def test_mix_tag_performance_handle(default_conf, update, ticker, fee, # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) + trade.buy_tag = "TESTBUY" + trade.sell_reason = "TESTSELL" + # Simulate fulfilled LIMIT_SELL order for trade trade.update(limit_sell_order) trade.close_date = datetime.utcnow() trade.is_open = False + telegram._mix_tag_performance(update=update, context=MagicMock()) assert msg_mock.call_count == 1 - assert 'Performance' in msg_mock.call_args_list[0][0][0] - assert 'ETH/BTC\t0.00006217 BTC (6.20%) (1)' in msg_mock.call_args_list[0][0][0] + assert 'Mix Tag Performance' in msg_mock.call_args_list[0][0][0] + assert 'TESTBUY TESTSELL\t0.00006217 BTC (6.20%) (1)' in msg_mock.call_args_list[0][0][0] def test_count_handle(default_conf, update, ticker, fee, mocker) -> None: