diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 114814b58..3188283b7 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -5782,12 +5782,11 @@ def test_position_adjust3(mocker, default_conf_usdt, fee, data) -> None: get_fee=fee, ) pair = 'ETH/USDT' - # Initial buy closed_successful_order = { 'pair': pair, 'ft_pair': pair, - 'ft_order_side': 'buy', - 'side': 'buy', + 'ft_order_side': order[0], + 'side': order[0], 'type': 'limit', 'status': 'closed', 'price': price, diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 832ea316b..a32b40786 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -2692,3 +2692,91 @@ def test_order_to_ccxt(limit_buy_order_open): del raw_order['info'] del limit_buy_order_open['datetime'] assert raw_order == limit_buy_order_open + + +@pytest.mark.usefixtures("init_persistence") +@pytest.mark.parametrize('data', [ + ( + # tuple 1 - side, amount, price + # tuple 2 - amount, open_rate, stake_amount, cumulative_profit, realized_profit + (('buy', 100, 10), (100.0, 10.0, 1000.0, 0.0, None)), + (('buy', 100, 15), (200.0, 12.5, 2500.0, 0.0, None)), + (('sell', 50, 12), (150.0, 12.5, 1875.0, -28.0625, -28.0625)), + (('sell', 100, 20), (50.0, 12.5, 625.0, 713.8125, 741.875)), + (('sell', 50, 5), (50.0, 12.5, 625.0, 713.8125, 336.625)), + ), + ( + (('buy', 100, 3), (100.0, 3.0, 300.0, 0.0, None)), + (('buy', 100, 7), (200.0, 5.0, 1000.0, 0.0, None)), + (('sell', 100, 11), (100.0, 5.0, 500.0, 596.0, 596.0)), + (('buy', 150, 15), (250.0, 11.0, 2750.0, 596.0, 596.0)), + (('sell', 100, 19), (150.0, 11.0, 1650.0, 1388.5, 792.5)), + (('sell', 150, 23), (150.0, 11.0, 1650.0, 1388.5, 3175.75)), + ) +]) +def test_recalc_trade_from_orders_dca(fee, data) -> None: + + pair = 'ETH/USDT' + trade = Trade( + id=2, + pair=pair, + stake_amount=1000, + open_rate=data[0][0][2], + amount=data[0][0][1], + is_open=True, + open_date=arrow.utcnow().datetime, + fee_open=fee.return_value, + fee_close=fee.return_value, + exchange='binance', + is_short=False, + leverage=1.0, + trading_mode=TradingMode.SPOT + ) + Trade.query.session.add(trade) + + for idx, (order, result) in enumerate(data): + amount = order[1] + price = order[2] + + order_obj = Order( + ft_order_side=order[0], + ft_pair=trade.pair, + order_id=f"order_{order[0]}_{idx}", + ft_is_open=False, + status="closed", + symbol=trade.pair, + order_type="market", + side=order[0], + price=price, + average=price, + filled=amount, + remaining=0, + cost=amount * price, + order_date=arrow.utcnow().shift(hours=-10 + idx).datetime, + order_filled_date=arrow.utcnow().shift(hours=-10 + idx).datetime, + ) + trade.orders.append(order_obj) + if order[0] == 'sell' and idx != len(data) - 1: + trade.process_exit_sub_trade(order_obj, True) + trade.recalc_trade_from_orders() + Trade.commit() + + orders1 = Order.query.all() + assert orders1 + assert len(orders1) == idx + 1 + + trade = Trade.query.first() + assert trade + assert len(trade.orders) == idx + 1 + if idx < len(data) - 1: + assert trade.is_open is True + assert trade.open_order_id is None + assert trade.amount == result[0] + assert trade.open_rate == result[1] + assert trade.stake_amount == result[2] + assert pytest.approx(trade.realized_profit) == result[3] + # assert pytest.approx(trade.close_profit_abs) == result[4] + + trade = Trade.query.first() + assert trade + assert trade.open_order_id is None