diff --git a/freqtrade/tests/test_analyze.py b/freqtrade/tests/test_analyze.py index 413390a31..48c46822f 100644 --- a/freqtrade/tests/test_analyze.py +++ b/freqtrade/tests/test_analyze.py @@ -1,6 +1,4 @@ # pragma pylint: disable=missing-docstring -from unittest.mock import patch - import pytest import arrow from pandas import DataFrame @@ -39,10 +37,11 @@ def test_populates_buy_trend(result): assert 'buy' in dataframe.columns assert 'buy_price' in dataframe.columns -def test_returns_latest_buy_signal(): +def test_returns_latest_buy_signal(mocker): buydf = DataFrame([{'buy': 1, 'date': arrow.utcnow()}]) - with patch('freqtrade.analyze.analyze_ticker', return_value=buydf): - assert get_buy_signal('BTC-ETH') == True + mocker.patch('freqtrade.analyze.analyze_ticker', return_value=buydf) + assert get_buy_signal('BTC-ETH') == True + buydf = DataFrame([{'buy': 0, 'date': arrow.utcnow()}]) - with patch('freqtrade.analyze.analyze_ticker', return_value=buydf): - assert get_buy_signal('BTC-ETH') == False + mocker.patch('freqtrade.analyze.analyze_ticker', return_value=buydf) + assert get_buy_signal('BTC-ETH') == False diff --git a/freqtrade/tests/test_backtesting.py b/freqtrade/tests/test_backtesting.py index fe69104ff..dcb572157 100644 --- a/freqtrade/tests/test_backtesting.py +++ b/freqtrade/tests/test_backtesting.py @@ -2,7 +2,6 @@ import json import logging import os -from unittest.mock import patch import pytest import arrow @@ -41,30 +40,30 @@ def conf(): @pytest.mark.skipif(not os.environ.get('BACKTEST', False), reason="BACKTEST not set") -def test_backtest(conf, pairs): +def test_backtest(conf, pairs, mocker): trades = [] - with patch.dict('freqtrade.main._CONF', conf): - for pair in pairs: - with open('tests/testdata/'+pair+'.json') as data_file: - data = json.load(data_file) + mocker.patch.dict('freqtrade.main._CONF', conf) + for pair in pairs: + with open('tests/testdata/'+pair+'.json') as data_file: + data = json.load(data_file) - with patch('freqtrade.analyze.get_ticker', return_value=data): - with patch('arrow.utcnow', return_value=arrow.get('2017-08-20T14:50:00')): - ticker = analyze_ticker(pair) - # for each buy point - for index, row in ticker[ticker.buy == 1].iterrows(): - trade = Trade( - open_rate=row['close'], - open_date=arrow.get(row['date']).datetime, - amount=1, - ) - # calculate win/lose forwards from buy point - for index2, row2 in ticker[index:].iterrows(): - if should_sell(trade, row2['close'], arrow.get(row2['date']).datetime): - current_profit = (row2['close'] - trade.open_rate) / trade.open_rate + mocker.patch('freqtrade.analyze.get_ticker', return_value=data) + mocker.patch('arrow.utcnow', return_value=arrow.get('2017-08-20T14:50:00')) + ticker = analyze_ticker(pair) + # for each buy point + for index, row in ticker[ticker.buy == 1].iterrows(): + trade = Trade( + open_rate=row['close'], + open_date=arrow.get(row['date']).datetime, + amount=1, + ) + # calculate win/lose forwards from buy point + for index2, row2 in ticker[index:].iterrows(): + if should_sell(trade, row2['close'], arrow.get(row2['date']).datetime): + current_profit = (row2['close'] - trade.open_rate) / trade.open_rate - trades.append((pair, current_profit, index2 - index)) - break + trades.append((pair, current_profit, index2 - index)) + break labels = ['currency', 'profit', 'duration'] results = DataFrame.from_records(trades, columns=labels) diff --git a/freqtrade/tests/test_main.py b/freqtrade/tests/test_main.py index 7e2b41932..8c881c9c8 100644 --- a/freqtrade/tests/test_main.py +++ b/freqtrade/tests/test_main.py @@ -1,5 +1,5 @@ import copy -from unittest.mock import patch, MagicMock, call +from unittest.mock import MagicMock, call import pytest from jsonschema import validate @@ -46,77 +46,77 @@ def conf(): validate(configuration, CONF_SCHEMA) return configuration -def test_create_trade(conf): - with patch.dict('freqtrade.main._CONF', conf): - with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) as buy_signal: - with patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.07256061, - 'ask': 0.072661, - 'last': 0.07256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - # Save state of current whitelist - whitelist = copy.deepcopy(conf['bittrex']['pair_whitelist']) +def test_create_trade(conf, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + buy_signal = mocker.patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) + mocker.patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()) + mocker.patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.07256061, + 'ask': 0.072661, + 'last': 0.07256061 + }), + buy=MagicMock(return_value='mocked_order_id')) + # Save state of current whitelist + whitelist = copy.deepcopy(conf['bittrex']['pair_whitelist']) - init(conf, 'sqlite://') - for pair in ['BTC_ETH', 'BTC_TKN', 'BTC_TRST', 'BTC_SWT']: - trade = create_trade(15.0, exchange.Exchange.BITTREX) - Trade.session.add(trade) - Trade.session.flush() - assert trade is not None - assert trade.open_rate == 0.072661 - assert trade.pair == pair - assert trade.exchange == exchange.Exchange.BITTREX - assert trade.amount == 206.43811673387373 - assert trade.stake_amount == 15.0 - assert trade.is_open == True - assert trade.open_date is not None - assert whitelist == conf['bittrex']['pair_whitelist'] + init(conf, 'sqlite://') + for pair in ['BTC_ETH', 'BTC_TKN', 'BTC_TRST', 'BTC_SWT']: + trade = create_trade(15.0, exchange.Exchange.BITTREX) + Trade.session.add(trade) + Trade.session.flush() + assert trade is not None + assert trade.open_rate == 0.072661 + assert trade.pair == pair + assert trade.exchange == exchange.Exchange.BITTREX + assert trade.amount == 206.43811673387373 + assert trade.stake_amount == 15.0 + assert trade.is_open == True + assert trade.open_date is not None + assert whitelist == conf['bittrex']['pair_whitelist'] - buy_signal.assert_has_calls( - [call('BTC_ETH'), call('BTC_TKN'), call('BTC_TRST'), call('BTC_SWT')] - ) + buy_signal.assert_has_calls( + [call('BTC_ETH'), call('BTC_TKN'), call('BTC_TRST'), call('BTC_SWT')] + ) -def test_handle_trade(conf): - with patch.dict('freqtrade.main._CONF', conf): - with patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.17256061, - 'ask': 0.172661, - 'last': 0.17256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - trade = Trade.query.filter(Trade.is_open.is_(True)).first() - assert trade - handle_trade(trade) - assert trade.close_rate == 0.17256061 - assert trade.close_profit == 137.4872490056564 - assert trade.close_date is not None - assert trade.open_order_id == 'dry_run' +def test_handle_trade(conf, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + mocker.patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()) + mocker.patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.17256061, + 'ask': 0.172661, + 'last': 0.17256061 + }), + buy=MagicMock(return_value='mocked_order_id')) + trade = Trade.query.filter(Trade.is_open.is_(True)).first() + assert trade + handle_trade(trade) + assert trade.close_rate == 0.17256061 + assert trade.close_profit == 137.4872490056564 + assert trade.close_date is not None + assert trade.open_order_id == 'dry_run' -def test_close_trade(conf): - with patch.dict('freqtrade.main._CONF', conf): - trade = Trade.query.filter(Trade.is_open.is_(True)).first() - assert trade +def test_close_trade(conf, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + trade = Trade.query.filter(Trade.is_open.is_(True)).first() + assert trade - # Simulate that there is no open order - trade.open_order_id = None + # Simulate that there is no open order + trade.open_order_id = None - closed = close_trade_if_fulfilled(trade) - assert closed - assert trade.is_open == False + closed = close_trade_if_fulfilled(trade) + assert closed + assert trade.is_open == False -def test_balance_fully_ask_side(): - with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 0.0}}): - assert get_target_bid({'ask': 20, 'last': 10}) == 20 +def test_balance_fully_ask_side(mocker): + mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 0.0}}) + assert get_target_bid({'ask': 20, 'last': 10}) == 20 -def test_balance_fully_last_side(): - with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}): - assert get_target_bid({'ask': 20, 'last': 10}) == 10 +def test_balance_fully_last_side(mocker): + mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}) + assert get_target_bid({'ask': 20, 'last': 10}) == 10 -def test_balance_when_last_bigger_than_ask(): - with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}): - assert get_target_bid({'ask': 5, 'last': 10}) == 5 +def test_balance_when_last_bigger_than_ask(mocker): + mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}) + assert get_target_bid({'ask': 5, 'last': 10}) == 5 diff --git a/freqtrade/tests/test_persistence.py b/freqtrade/tests/test_persistence.py index 19ff4df10..6015fe858 100644 --- a/freqtrade/tests/test_persistence.py +++ b/freqtrade/tests/test_persistence.py @@ -1,22 +1,20 @@ -from unittest.mock import patch - from freqtrade.exchange import Exchange from freqtrade.persistence import Trade -def test_exec_sell_order(): - with patch('freqtrade.main.exchange.sell', side_effect='mocked_order_id') as api_mock: - trade = Trade( - pair='BTC_ETH', - stake_amount=1.00, - open_rate=0.50, - amount=10.00, - exchange=Exchange.BITTREX, - open_order_id='mocked' - ) - profit = trade.exec_sell_order(1.00, 10.00) - api_mock.assert_called_once_with('BTC_ETH', 1.0, 10.0) - assert profit == 100.0 - assert trade.close_rate == 1.0 - assert trade.close_profit == profit - assert trade.close_date is not None +def test_exec_sell_order(mocker): + api_mock = mocker.patch('freqtrade.main.exchange.sell', side_effect='mocked_order_id') + trade = Trade( + pair='BTC_ETH', + stake_amount=1.00, + open_rate=0.50, + amount=10.00, + exchange=Exchange.BITTREX, + open_order_id='mocked' + ) + profit = trade.exec_sell_order(1.00, 10.00) + api_mock.assert_called_once_with('BTC_ETH', 1.0, 10.0) + assert profit == 100.0 + assert trade.close_rate == 1.0 + assert trade.close_profit == profit + assert trade.close_date is not None diff --git a/freqtrade/tests/test_telegram.py b/freqtrade/tests/test_telegram.py index ef7b76868..c054b8994 100644 --- a/freqtrade/tests/test_telegram.py +++ b/freqtrade/tests/test_telegram.py @@ -1,5 +1,5 @@ from datetime import datetime -from unittest.mock import patch, MagicMock +from unittest.mock import MagicMock import pytest from jsonschema import validate @@ -56,137 +56,137 @@ class MagicBot(MagicMock, Bot): pass -def test_status_handle(conf, update): - with patch.dict('freqtrade.main._CONF', conf): - with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.07256061, - 'ask': 0.072661, - 'last': 0.07256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - init(conf, 'sqlite://') +def test_status_handle(conf, update, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + mocker.patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) + msg_mock = MagicMock() + mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock) + mocker.patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.07256061, + 'ask': 0.072661, + 'last': 0.07256061 + }), + buy=MagicMock(return_value='mocked_order_id')) + init(conf, 'sqlite://') - # Create some test data - trade = create_trade(15.0, exchange.Exchange.BITTREX) - assert trade - Trade.session.add(trade) - Trade.session.flush() + # Create some test data + trade = create_trade(15.0, exchange.Exchange.BITTREX) + assert trade + Trade.session.add(trade) + Trade.session.flush() - _status(bot=MagicBot(), update=update) - assert msg_mock.call_count == 2 - assert '[BTC_ETH]' in msg_mock.call_args_list[-1][0][0] + _status(bot=MagicBot(), update=update) + assert msg_mock.call_count == 2 + assert '[BTC_ETH]' in msg_mock.call_args_list[-1][0][0] -def test_profit_handle(conf, update): - with patch.dict('freqtrade.main._CONF', conf): - with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.07256061, - 'ask': 0.072661, - 'last': 0.07256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - init(conf, 'sqlite://') +def test_profit_handle(conf, update, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + mocker.patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) + msg_mock = MagicMock() + mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock) + mocker.patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.07256061, + 'ask': 0.072661, + 'last': 0.07256061 + }), + buy=MagicMock(return_value='mocked_order_id')) + init(conf, 'sqlite://') - # Create some test data - trade = create_trade(15.0, exchange.Exchange.BITTREX) - assert trade - trade.close_rate = 0.07256061 - trade.close_profit = 100.00 - trade.close_date = datetime.utcnow() - trade.open_order_id = None - trade.is_open = False - Trade.session.add(trade) - Trade.session.flush() + # Create some test data + trade = create_trade(15.0, exchange.Exchange.BITTREX) + assert trade + trade.close_rate = 0.07256061 + trade.close_profit = 100.00 + trade.close_date = datetime.utcnow() + trade.open_order_id = None + trade.is_open = False + Trade.session.add(trade) + Trade.session.flush() - _profit(bot=MagicBot(), update=update) - assert msg_mock.call_count == 2 - assert '(100.00%)' in msg_mock.call_args_list[-1][0][0] + _profit(bot=MagicBot(), update=update) + assert msg_mock.call_count == 2 + assert '(100.00%)' in msg_mock.call_args_list[-1][0][0] -def test_forcesell_handle(conf, update): - with patch.dict('freqtrade.main._CONF', conf): - with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.07256061, - 'ask': 0.072661, - 'last': 0.07256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - init(conf, 'sqlite://') +def test_forcesell_handle(conf, update, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + mocker.patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) + msg_mock = MagicMock() + mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock) + mocker.patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.07256061, + 'ask': 0.072661, + 'last': 0.07256061 + }), + buy=MagicMock(return_value='mocked_order_id')) + init(conf, 'sqlite://') - # Create some test data - trade = create_trade(15.0, exchange.Exchange.BITTREX) - assert trade - Trade.session.add(trade) - Trade.session.flush() + # Create some test data + trade = create_trade(15.0, exchange.Exchange.BITTREX) + assert trade + Trade.session.add(trade) + Trade.session.flush() - update.message.text = '/forcesell 1' - _forcesell(bot=MagicBot(), update=update) + update.message.text = '/forcesell 1' + _forcesell(bot=MagicBot(), update=update) - assert msg_mock.call_count == 2 - assert 'Selling [BTC/ETH]' in msg_mock.call_args_list[-1][0][0] - assert '0.072561' in msg_mock.call_args_list[-1][0][0] + assert msg_mock.call_count == 2 + assert 'Selling [BTC/ETH]' in msg_mock.call_args_list[-1][0][0] + assert '0.072561' in msg_mock.call_args_list[-1][0][0] -def test_performance_handle(conf, update): - with patch.dict('freqtrade.main._CONF', conf): - with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.07256061, - 'ask': 0.072661, - 'last': 0.07256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - init(conf, 'sqlite://') +def test_performance_handle(conf, update, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + mocker.patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) + msg_mock = MagicMock() + mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock) + mocker.patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.07256061, + 'ask': 0.072661, + 'last': 0.07256061 + }), + buy=MagicMock(return_value='mocked_order_id')) + init(conf, 'sqlite://') - # Create some test data - trade = create_trade(15.0, exchange.Exchange.BITTREX) - assert trade - trade.close_rate = 0.07256061 - trade.close_profit = 100.00 - trade.close_date = datetime.utcnow() - trade.open_order_id = None - trade.is_open = False - Trade.session.add(trade) - Trade.session.flush() + # Create some test data + trade = create_trade(15.0, exchange.Exchange.BITTREX) + assert trade + trade.close_rate = 0.07256061 + trade.close_profit = 100.00 + trade.close_date = datetime.utcnow() + trade.open_order_id = None + trade.is_open = False + Trade.session.add(trade) + Trade.session.flush() - _performance(bot=MagicBot(), update=update) - assert msg_mock.call_count == 2 - assert 'Performance' in msg_mock.call_args_list[-1][0][0] - assert 'BTC_ETH 100.00%' in msg_mock.call_args_list[-1][0][0] + _performance(bot=MagicBot(), update=update) + assert msg_mock.call_count == 2 + assert 'Performance' in msg_mock.call_args_list[-1][0][0] + assert 'BTC_ETH 100.00%' in msg_mock.call_args_list[-1][0][0] -def test_start_handle(conf, update): - with patch.dict('freqtrade.main._CONF', conf): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): - init(conf, 'sqlite://') +def test_start_handle(conf, update, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + msg_mock = MagicMock() + mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock) + init(conf, 'sqlite://') - update_state(State.STOPPED) - assert get_state() == State.STOPPED - _start(bot=MagicBot(), update=update) - assert get_state() == State.RUNNING - assert msg_mock.call_count == 0 + update_state(State.STOPPED) + assert get_state() == State.STOPPED + _start(bot=MagicBot(), update=update) + assert get_state() == State.RUNNING + assert msg_mock.call_count == 0 -def test_stop_handle(conf, update): - with patch.dict('freqtrade.main._CONF', conf): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): - init(conf, 'sqlite://') +def test_stop_handle(conf, update, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + msg_mock = MagicMock() + mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock) + init(conf, 'sqlite://') - update_state(State.RUNNING) - assert get_state() == State.RUNNING - _stop(bot=MagicBot(), update=update) - assert get_state() == State.STOPPED - assert msg_mock.call_count == 1 - assert 'Stopping trader' in msg_mock.call_args_list[0][0][0] + update_state(State.RUNNING) + assert get_state() == State.RUNNING + _stop(bot=MagicBot(), update=update) + assert get_state() == State.STOPPED + assert msg_mock.call_count == 1 + assert 'Stopping trader' in msg_mock.call_args_list[0][0][0]