diff --git a/docs/strategy-callbacks.md b/docs/strategy-callbacks.md index 129e15b32..55db40b7b 100644 --- a/docs/strategy-callbacks.md +++ b/docs/strategy-callbacks.md @@ -639,7 +639,6 @@ class DigDeeperStrategy(IStrategy): return None count_of_buys = 0 - initial_order_stake = for order in trade.orders: if order.ft_order_side == 'buy' and order.status == "closed": count_of_buys += 1 diff --git a/freqtrade/wallets.py b/freqtrade/wallets.py index 90672c315..98a39ea2d 100644 --- a/freqtrade/wallets.py +++ b/freqtrade/wallets.py @@ -184,7 +184,6 @@ class Wallets: return 0 possible_stake = (available_amount + val_tied_up) / self._config['max_open_trades'] - # Theoretical amount can be above available amount - therefore limit to available amount! return min(possible_stake, available_amount) diff --git a/tests/test_integration.py b/tests/test_integration.py index a3484d438..21b01126f 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -127,8 +127,7 @@ def test_may_execute_exit_stoploss_on_exchange_multi(default_conf, ticker, fee, (1, 200), (0.99, 198), ]) -def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, mocker, balance_ratio, - result1) -> None: +def test_forcebuy_last_unlimited(default_conf, ticker, fee, mocker, balance_ratio, result1) -> None: """ Tests workflow unlimited stake-amount Buy 4 trades, forcebuy a 5th trade @@ -207,3 +206,67 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc assert len(bals2) == 5 assert 'LTC' in bals assert 'LTC' not in bals2 + + +def test_dca_buying(default_conf_usdt, ticker_usdt, fee, mocker) -> None: + default_conf_usdt['position_adjustment_enable'] = True + + freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt) + mocker.patch.multiple( + 'freqtrade.exchange.Exchange', + fetch_ticker=ticker_usdt, + get_fee=fee, + amount_to_precision=lambda s, x, y: y, + price_to_precision=lambda s, x, y: y, + ) + + patch_get_signal(freqtrade) + freqtrade.enter_positions() + + assert len(Trade.get_trades().all()) == 1 + trade = Trade.get_trades().first() + assert len(trade.orders) == 1 + assert trade.stake_amount == 60 + assert trade.open_rate == 2.0 + # No adjustment + freqtrade.process() + trade = Trade.get_trades().first() + assert len(trade.orders) == 1 + assert trade.stake_amount == 60 + + # Reduce bid amount + ticker_usdt_modif = ticker_usdt.return_value + ticker_usdt_modif['bid'] = ticker_usdt_modif['bid'] * 0.995 + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', return_value=ticker_usdt_modif) + + # additional buy order + freqtrade.process() + trade = Trade.get_trades().first() + assert len(trade.orders) == 2 + assert trade.stake_amount == 120 + + # Open-rate averaged between 2.0 and 2.0 * 0.995 + assert trade.open_rate < 2.0 + assert trade.open_rate > 2.0 * 0.995 + + # No action - profit raised above 1% (the bar set in the strategy). + freqtrade.process() + trade = Trade.get_trades().first() + assert len(trade.orders) == 2 + assert trade.stake_amount == 120 + assert trade.orders[0].amount == 30 + assert trade.orders[1].amount == 60 / ticker_usdt_modif['bid'] + + assert trade.amount == trade.orders[0].amount + trade.orders[1].amount + + # Sell + patch_get_signal(freqtrade, value=(False, True, None, None)) + freqtrade.process() + trade = Trade.get_trades().first() + assert trade.is_open is False + assert trade.orders[0].amount == 30 + assert trade.orders[0].side == 'buy' + assert trade.orders[1].amount == 60 / ticker_usdt_modif['bid'] + # Sold everything + assert trade.orders[-1].side == 'sell' + assert trade.orders[2].amount == trade.amount