Skip to content

Commit 33ec55f

Browse files
committed
test: add test for funding fee DCA entry
1 parent 890f30e commit 33ec55f

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

tests/freqtradebot/test_freqtradebot.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5297,6 +5297,91 @@ def test_update_funding_fees_error(mocker, default_conf, caplog):
52975297
log_has("Could not update funding fees for open trades.", caplog)
52985298

52995299

5300+
def test_execute_entry_funding_fees_dca(mocker, default_conf_usdt, fee) -> None:
5301+
"""
5302+
On a position adjustment (DCA), funding fees must be calculated on the existing
5303+
position size (trade.amount) - not on the combined existing + newly added amount,
5304+
as the newly added amount hasn't accrued any funding fees yet.
5305+
"""
5306+
patch_wallet(mocker, free=10000)
5307+
default_conf_usdt.update(
5308+
{
5309+
"position_adjustment_enable": True,
5310+
"trading_mode": "futures",
5311+
"margin_mode": "isolated",
5312+
"dry_run": False,
5313+
"stake_amount": 10.0,
5314+
"dry_run_wallet": 1000.0,
5315+
}
5316+
)
5317+
bid = 11
5318+
stake_amount = 10
5319+
get_funding_fees = MagicMock(return_value=0)
5320+
mocker.patch.multiple(
5321+
EXMS,
5322+
get_rate=MagicMock(return_value=bid),
5323+
fetch_ticker=MagicMock(return_value={"bid": 10, "ask": 12, "last": 11}),
5324+
get_min_pair_stake_amount=MagicMock(return_value=1),
5325+
get_fee=fee,
5326+
get_funding_fees=get_funding_fees,
5327+
get_maintenance_ratio_and_amt=MagicMock(return_value=(0.01, 0.01)),
5328+
get_max_leverage=MagicMock(return_value=10),
5329+
)
5330+
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
5331+
pair = "ETH/USDT"
5332+
5333+
# Initial buy - creates a trade with amount == 30
5334+
closed_buy_order = {
5335+
"pair": pair,
5336+
"ft_pair": pair,
5337+
"ft_order_side": "buy",
5338+
"side": "buy",
5339+
"type": "limit",
5340+
"status": "closed",
5341+
"price": bid,
5342+
"average": bid,
5343+
"cost": bid * 30,
5344+
"amount": 30,
5345+
"filled": 30,
5346+
"ft_is_open": False,
5347+
"id": "650",
5348+
"order_id": "650",
5349+
}
5350+
mocker.patch(f"{EXMS}.create_order", return_value=closed_buy_order)
5351+
mocker.patch(f"{EXMS}.fetch_order_or_stoploss_order", return_value=closed_buy_order)
5352+
assert freqtrade.execute_entry(pair, stake_amount)
5353+
5354+
trade = Trade.session.scalars(select(Trade)).first()
5355+
assert trade
5356+
assert trade.amount == 30
5357+
5358+
# Position adjustment (DCA) - adds 12 to the position
5359+
get_funding_fees.reset_mock()
5360+
closed_dca_order = {
5361+
"pair": pair,
5362+
"ft_pair": pair,
5363+
"ft_order_side": "buy",
5364+
"side": "buy",
5365+
"type": "limit",
5366+
"status": "closed",
5367+
"price": 9,
5368+
"average": 9,
5369+
"cost": 108,
5370+
"amount": 12,
5371+
"filled": 12,
5372+
"ft_is_open": False,
5373+
"id": "651",
5374+
"order_id": "651",
5375+
}
5376+
mocker.patch(f"{EXMS}.create_order", return_value=closed_dca_order)
5377+
mocker.patch(f"{EXMS}.fetch_order_or_stoploss_order", return_value=closed_dca_order)
5378+
assert freqtrade.execute_entry(pair, stake_amount, trade=trade)
5379+
5380+
# Funding fees must be calculated on the existing amount (30), not 30 + 12
5381+
assert get_funding_fees.call_count == 1
5382+
assert get_funding_fees.call_args[1]["amount"] == 30
5383+
5384+
53005385
def test_position_adjust(mocker, default_conf_usdt, fee) -> None:
53015386
patch_RPCManager(mocker)
53025387
patch_exchange(mocker)

0 commit comments

Comments
 (0)