Update tests to test DCA for shorts

This commit is contained in:
Matthias 2022-02-13 16:01:44 +01:00
parent eed516a5c6
commit f0f5a50975
4 changed files with 80 additions and 5 deletions

View File

@ -593,7 +593,7 @@ Additional orders also result in additional fees and those orders don't count to
This callback is **not** called when there is an open order (either buy or sell) waiting for execution, or when you have reached the maximum amount of extra buys that you have set on `max_entry_position_adjustment`.
`adjust_trade_position()` is called very frequently for the duration of a trade, so you must keep your implementation as performant as possible.
Position adjustments will always be applied in the direction of the trade, so a positive value will always increase your position, no matter if it's a long or short trade.
Position adjustments will always be applied in the direction of the trade, so a positive value will always increase your position, no matter if it's a long or short trade.
!!! Note "About stake size"
Using fixed stake size means it will be the amount used for the first order, just like without position adjustment.

View File

@ -533,7 +533,7 @@ class FreqtradeBot(LoggingMixin):
if stake_amount is not None and stake_amount > 0.0:
# We should increase our position
self.execute_entry(trade.pair, stake_amount, trade=trade)
self.execute_entry(trade.pair, stake_amount, trade=trade, is_short=trade.is_short)
if stake_amount is not None and stake_amount < 0.0:
# We should decrease our position

View File

@ -183,7 +183,7 @@ class StrategyTestV3(IStrategy):
current_profit: float, min_stake: float, max_stake: float, **kwargs):
if current_profit < -0.0075:
orders = trade.select_filled_orders('buy')
orders = trade.select_filled_orders(trade.enter_side)
return round(orders[0].cost, 0)
return None

View File

@ -214,6 +214,7 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, mocker, balance_rati
def test_dca_buying(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
# TODO-lev: this should also check with different leverages per entry order!
default_conf_usdt['position_adjustment_enable'] = True
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
@ -231,13 +232,13 @@ def test_dca_buying(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
assert len(Trade.get_trades().all()) == 1
trade = Trade.get_trades().first()
assert len(trade.orders) == 1
assert trade.stake_amount == 60
assert pytest.approx(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
assert pytest.approx(trade.stake_amount) == 60
# Reduce bid amount
ticker_usdt_modif = ticker_usdt.return_value
@ -266,6 +267,7 @@ def test_dca_buying(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
assert trade.amount == trade.orders[0].amount + trade.orders[1].amount
assert trade.nr_of_successful_buys == 2
assert trade.nr_of_successful_entries == 2
# Sell
patch_get_signal(freqtrade, enter_long=False, exit_long=True)
@ -280,3 +282,76 @@ def test_dca_buying(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
assert trade.orders[2].amount == trade.amount
assert trade.nr_of_successful_buys == 2
assert trade.nr_of_successful_entries == 2
def test_dca_short(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
# TODO-lev: this should also check with different leverages per entry order!
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, enter_long=False, enter_short=True)
freqtrade.enter_positions()
assert len(Trade.get_trades().all()) == 1
trade = Trade.get_trades().first()
assert len(trade.orders) == 1
assert pytest.approx(trade.stake_amount) == 60
assert trade.open_rate == 2.02
# No adjustment
freqtrade.process()
trade = Trade.get_trades().first()
assert len(trade.orders) == 1
assert pytest.approx(trade.stake_amount) == 60
# Reduce bid amount
ticker_usdt_modif = ticker_usdt.return_value
ticker_usdt_modif['ask'] = ticker_usdt_modif['ask'] * 1.015
ticker_usdt_modif['bid'] = ticker_usdt_modif['bid'] * 1.0125
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
for o in trade.orders:
assert o.status == "closed"
assert pytest.approx(trade.stake_amount) == 120
# Open-rate averaged between 2.0 and 2.0 * 1.015
assert trade.open_rate >= 2.02
assert trade.open_rate < 2.02 * 1.015
# 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 pytest.approx(trade.stake_amount) == 120
# assert trade.orders[0].amount == 30
assert trade.orders[1].amount == 60 / ticker_usdt_modif['ask']
assert trade.amount == trade.orders[0].amount + trade.orders[1].amount
assert trade.nr_of_successful_entries == 2
# Buy
patch_get_signal(freqtrade, enter_long=False, exit_short=True)
freqtrade.process()
trade = Trade.get_trades().first()
assert trade.is_open is False
# assert trade.orders[0].amount == 30
assert trade.orders[0].side == 'sell'
assert trade.orders[1].amount == 60 / ticker_usdt_modif['ask']
# Sold everything
assert trade.orders[-1].side == 'buy'
assert trade.orders[2].amount == trade.amount
assert trade.nr_of_successful_entries == 2
assert trade.nr_of_successful_exits == 1