diff --git a/TODO b/TODO index c89e7ddf0..26dcda682 100644 --- a/TODO +++ b/TODO @@ -10,37 +10,6 @@ Files to edit freqtrade/strategy freqtrade/constants.py -Tests - tests/test_persistence.pys - init with - lev & bor - lev - bor - neither lev nor bor - adjust_stop_loss - short - leverage - is_opening_trade - short - long - shortBuy - longSell - is_closing_trade - short - long - shortBuy - longSell - update, close, update fee - possible to test? - calc_profit - * * create a few shorts, a few leveraged longs test correct ratio - calc_profit_ratio - * create a few shorts, a few leveraged longs test correct ratio - get_open_trades - * create a short, check if exists - - tests/test_freqtradebot.py - later freqtrade/commands/build_config_commands.py freqtrade/commands/cli_options.py @@ -56,6 +25,3 @@ Did not look at these files freqtrade/resolvers/strategy_resolver.py freqtrade/rpc -Already Edited - freqtrade/persistence/migrations.py - freqtrade/persistence/models.py \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py index a19dbac2b..256204263 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -204,7 +204,30 @@ def create_mock_trades(fee, use_db: bool = True): add_trade(trade) trade = mock_trade_6(fee) add_trade(trade) - # TODO: margin trades + + +def create_mock_trades_with_leverage(fee, use_db: bool = True): + """ + Create some fake trades ... + """ + 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_1(fee) + add_trade(trade) + trade = mock_trade_2(fee) + add_trade(trade) + trade = mock_trade_3(fee) + add_trade(trade) + trade = mock_trade_4(fee) + add_trade(trade) + trade = mock_trade_5(fee) + add_trade(trade) + trade = mock_trade_6(fee) + add_trade(trade) trade = short_trade(fee) add_trade(trade) trade = leverage_trade(fee) diff --git a/tests/conftest_trades.py b/tests/conftest_trades.py index 9bf334b48..bc728dd44 100644 --- a/tests/conftest_trades.py +++ b/tests/conftest_trades.py @@ -310,7 +310,7 @@ def mock_trade_6(fee): def short_order(): return { - 'id': '1235', + 'id': '1236', 'symbol': 'ETC/BTC', 'status': 'closed', 'side': 'sell', @@ -324,7 +324,7 @@ def short_order(): def exit_short_order(): return { - 'id': '12366', + 'id': '12367', 'symbol': 'ETC/BTC', 'status': 'closed', 'side': 'buy', @@ -397,7 +397,7 @@ def short_trade(fee): def leverage_order(): return { - 'id': '1235', + 'id': '1237', 'symbol': 'ETC/BTC', 'status': 'closed', 'side': 'buy', @@ -412,7 +412,7 @@ def leverage_order(): def leverage_order_sell(): return { - 'id': '12366', + 'id': '12368', 'symbol': 'ETC/BTC', 'status': 'closed', 'side': 'sell', diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 6709a526f..febfd5c2a 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -907,7 +907,7 @@ def test_get_open(fee, use_db): Trade.reset_trades() create_mock_trades(fee, use_db) - assert len(Trade.get_open_trades()) == 5 + assert len(Trade.get_open_trades()) == 4 Trade.use_db = True diff --git a/tests/test_persistence_short.py b/tests/test_persistence_short.py index 782782118..58a2f1e13 100644 --- a/tests/test_persistence_short.py +++ b/tests/test_persistence_short.py @@ -10,7 +10,7 @@ from sqlalchemy import create_engine, inspect, text from freqtrade import constants from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.persistence import LocalTrade, Order, Trade, clean_dry_run_db, init_db -from tests.conftest import create_mock_trades, log_has, log_has_re +from tests.conftest import create_mock_trades_with_leverage, log_has, log_has_re @pytest.mark.usefixtures("init_persistence") @@ -655,21 +655,19 @@ def test_adjust_stop_loss(fee): assert trade.stop_loss_pct == 0.1 # TODO-mg: Do a test with a trade that has a liquidation price -# TODO-mg: I don't know how to do this test, but it should be tested for shorts - @pytest.mark.usefixtures("init_persistence") @pytest.mark.parametrize('use_db', [True, False]) def test_get_open(fee, use_db): Trade.use_db = use_db Trade.reset_trades() - create_mock_trades(fee, use_db) + create_mock_trades_with_leverage(fee, use_db) assert len(Trade.get_open_trades()) == 5 Trade.use_db = True def test_stoploss_reinitialization(default_conf, fee): - # TODO-mg: I don't understand this at all, I was going in the opposite direction as the matching function form test_persistance.py + # TODO-mg: I don't understand this at all, I was just going in the opposite direction as the matching function form test_persistance.py init_db(default_conf['db_url']) trade = Trade( pair='ETH/BTC', @@ -721,83 +719,26 @@ def test_stoploss_reinitialization(default_conf, fee): assert trade_adj.initial_stop_loss == 1.04 assert trade_adj.initial_stop_loss_pct == 0.04 -# @pytest.mark.usefixtures("init_persistence") -# @pytest.mark.parametrize('use_db', [True, False]) -# def test_total_open_trades_stakes(fee, use_db): -# Trade.use_db = use_db -# Trade.reset_trades() -# res = Trade.total_open_trades_stakes() -# assert res == 0 -# create_mock_trades(fee, use_db) -# res = Trade.total_open_trades_stakes() -# assert res == 0.004 -# Trade.use_db = True -# @pytest.mark.usefixtures("init_persistence") -# def test_get_overall_performance(fee): -# create_mock_trades(fee) -# res = Trade.get_overall_performance() -# assert len(res) == 2 -# assert 'pair' in res[0] -# assert 'profit' in res[0] -# assert 'count' in res[0] +@pytest.mark.usefixtures("init_persistence") +@pytest.mark.parametrize('use_db', [True, False]) +def test_total_open_trades_stakes(fee, use_db): + Trade.use_db = use_db + Trade.reset_trades() + res = Trade.total_open_trades_stakes() + assert res == 0 + create_mock_trades_with_leverage(fee, use_db) + res = Trade.total_open_trades_stakes() + assert res == 15.133 + Trade.use_db = True -# @pytest.mark.usefixtures("init_persistence") -# def test_get_best_pair(fee): -# res = Trade.get_best_pair() -# assert res is None -# create_mock_trades(fee) -# res = Trade.get_best_pair() -# assert len(res) == 2 -# assert res[0] == 'XRP/BTC' -# assert res[1] == 0.01 -# @pytest.mark.usefixtures("init_persistence") -# def test_update_order_from_ccxt(caplog): -# # Most basic order return (only has orderid) -# o = Order.parse_from_ccxt_object({'id': '1234'}, 'ETH/BTC', 'buy') -# assert isinstance(o, Order) -# assert o.ft_pair == 'ETH/BTC' -# assert o.ft_order_side == 'buy' -# assert o.order_id == '1234' -# assert o.ft_is_open -# ccxt_order = { -# 'id': '1234', -# 'side': 'buy', -# 'symbol': 'ETH/BTC', -# 'type': 'limit', -# 'price': 1234.5, -# 'amount': 20.0, -# 'filled': 9, -# 'remaining': 11, -# 'status': 'open', -# 'timestamp': 1599394315123 -# } -# o = Order.parse_from_ccxt_object(ccxt_order, 'ETH/BTC', 'buy') -# assert isinstance(o, Order) -# assert o.ft_pair == 'ETH/BTC' -# assert o.ft_order_side == 'buy' -# assert o.order_id == '1234' -# assert o.order_type == 'limit' -# assert o.price == 1234.5 -# assert o.filled == 9 -# assert o.remaining == 11 -# assert o.order_date is not None -# assert o.ft_is_open -# assert o.order_filled_date is None -# # Order has been closed -# ccxt_order.update({'filled': 20.0, 'remaining': 0.0, 'status': 'closed'}) -# o.update_from_ccxt_object(ccxt_order) -# assert o.filled == 20.0 -# assert o.remaining == 0.0 -# assert not o.ft_is_open -# assert o.order_filled_date is not None -# ccxt_order.update({'id': 'somethingelse'}) -# with pytest.raises(DependencyException, match=r"Order-id's don't match"): -# o.update_from_ccxt_object(ccxt_order) -# message = "aaaa is not a valid response object." -# assert not log_has(message, caplog) -# Order.update_orders([o], 'aaaa') -# assert log_has(message, caplog) -# # Call regular update - shouldn't fail. -# Order.update_orders([o], {'id': '1234'}) +@pytest.mark.usefixtures("init_persistence") +def test_get_best_pair(fee): + res = Trade.get_best_pair() + assert res is None + create_mock_trades_with_leverage(fee) + res = Trade.get_best_pair() + assert len(res) == 2 + assert res[0] == 'ETC/BTC' + assert res[1] == 0.22626016260162551