Fix the dca order not being counted bug.
This commit is contained in:
parent
d9f5694965
commit
f6d36ce56b
@ -292,8 +292,8 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
for trade in trades:
|
for trade in trades:
|
||||||
if trade.is_open and not trade.fee_updated('buy'):
|
if trade.is_open and not trade.fee_updated('buy'):
|
||||||
order = trade.select_order('buy', False)
|
order = trade.select_order('buy', False)
|
||||||
if order:
|
open_order = trade.select_order('buy', True)
|
||||||
logger.info(f"Updating buy-fee on trade {trade} for order {order.order_id}.")
|
if order and open_order is None:
|
||||||
self.update_trade_state(trade, order.order_id, send_msg=False)
|
self.update_trade_state(trade, order.order_id, send_msg=False)
|
||||||
|
|
||||||
def handle_insufficient_funds(self, trade: Trade):
|
def handle_insufficient_funds(self, trade: Trade):
|
||||||
|
@ -4310,10 +4310,17 @@ def test_get_valid_price(mocker, default_conf_usdt) -> None:
|
|||||||
assert valid_price_at_min_alwd > custom_price_under_min_alwd
|
assert valid_price_at_min_alwd > custom_price_under_min_alwd
|
||||||
assert valid_price_at_min_alwd < proposed_price
|
assert valid_price_at_min_alwd < proposed_price
|
||||||
|
|
||||||
def test_position_adjust(mocker, default_conf_usdt, fee, limit_buy_order_usdt,
|
|
||||||
limit_buy_order_usdt_open) -> None:
|
def test_position_adjust(mocker, default_conf_usdt, fee) -> None:
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
|
patch_wallet(mocker, free=10000)
|
||||||
|
default_conf_usdt.update({
|
||||||
|
"position_adjustment_enable": True,
|
||||||
|
"dry_run": False,
|
||||||
|
"stake_amount": 10.0,
|
||||||
|
"dry_run_wallet": 1000.0,
|
||||||
|
})
|
||||||
freqtrade = FreqtradeBot(default_conf_usdt)
|
freqtrade = FreqtradeBot(default_conf_usdt)
|
||||||
freqtrade.strategy.confirm_trade_entry = MagicMock(return_value=True)
|
freqtrade.strategy.confirm_trade_entry = MagicMock(return_value=True)
|
||||||
bid = 11
|
bid = 11
|
||||||
@ -4333,23 +4340,26 @@ def test_position_adjust(mocker, default_conf_usdt, fee, limit_buy_order_usdt,
|
|||||||
pair = 'ETH/USDT'
|
pair = 'ETH/USDT'
|
||||||
|
|
||||||
# Initial buy
|
# Initial buy
|
||||||
limit_buy_order_usdt['status'] = 'closed'
|
closed_successful_buy_order = {
|
||||||
limit_buy_order_usdt['pair'] = pair
|
'pair': pair,
|
||||||
limit_buy_order_usdt['ft_pair'] = pair
|
'ft_pair': pair,
|
||||||
limit_buy_order_usdt['ft_order_side'] = 'buy'
|
'ft_order_side': 'buy',
|
||||||
limit_buy_order_usdt['side'] = 'buy'
|
'side': 'buy',
|
||||||
limit_buy_order_usdt['price'] = bid
|
'type': 'limit',
|
||||||
limit_buy_order_usdt['average'] = bid
|
'status': 'closed',
|
||||||
limit_buy_order_usdt['cost'] = bid * stake_amount
|
'price': bid,
|
||||||
limit_buy_order_usdt['amount'] = stake_amount
|
'average': bid,
|
||||||
limit_buy_order_usdt['filled'] = stake_amount
|
'cost': bid * stake_amount,
|
||||||
limit_buy_order_usdt['ft_is_open'] = False
|
'amount': stake_amount,
|
||||||
limit_buy_order_usdt['id'] = '650'
|
'filled': stake_amount,
|
||||||
limit_buy_order_usdt['order_id'] = '650'
|
'ft_is_open': False,
|
||||||
|
'id': '650',
|
||||||
|
'order_id': '650'
|
||||||
|
}
|
||||||
mocker.patch('freqtrade.exchange.Exchange.create_order',
|
mocker.patch('freqtrade.exchange.Exchange.create_order',
|
||||||
MagicMock(return_value=limit_buy_order_usdt))
|
MagicMock(return_value=closed_successful_buy_order))
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order_or_stoploss_order',
|
mocker.patch('freqtrade.exchange.Exchange.fetch_order_or_stoploss_order',
|
||||||
MagicMock(return_value=limit_buy_order_usdt))
|
MagicMock(return_value=closed_successful_buy_order))
|
||||||
assert freqtrade.execute_entry(pair, stake_amount)
|
assert freqtrade.execute_entry(pair, stake_amount)
|
||||||
# Should create an closed trade with an no open order id
|
# Should create an closed trade with an no open order id
|
||||||
# Order is filled and trade is open
|
# Order is filled and trade is open
|
||||||
@ -4363,7 +4373,7 @@ def test_position_adjust(mocker, default_conf_usdt, fee, limit_buy_order_usdt,
|
|||||||
assert trade.open_rate == 11
|
assert trade.open_rate == 11
|
||||||
assert trade.stake_amount == 110
|
assert trade.stake_amount == 110
|
||||||
|
|
||||||
# Assume it does nothing since trade is still open and no new orders
|
# Assume it does nothing since order is closed and trade is open
|
||||||
freqtrade.update_closed_trades_without_assigned_fees()
|
freqtrade.update_closed_trades_without_assigned_fees()
|
||||||
|
|
||||||
trade = Trade.query.first()
|
trade = Trade.query.first()
|
||||||
@ -4372,22 +4382,36 @@ def test_position_adjust(mocker, default_conf_usdt, fee, limit_buy_order_usdt,
|
|||||||
assert trade.open_order_id is None
|
assert trade.open_order_id is None
|
||||||
assert trade.open_rate == 11
|
assert trade.open_rate == 11
|
||||||
assert trade.stake_amount == 110
|
assert trade.stake_amount == 110
|
||||||
|
assert not trade.fee_updated('buy')
|
||||||
|
|
||||||
|
freqtrade.check_handle_timedout()
|
||||||
|
|
||||||
|
trade = Trade.query.first()
|
||||||
|
assert trade
|
||||||
|
assert trade.is_open is True
|
||||||
|
assert trade.open_order_id is None
|
||||||
|
assert trade.open_rate == 11
|
||||||
|
assert trade.stake_amount == 110
|
||||||
|
assert not trade.fee_updated('buy')
|
||||||
|
|
||||||
# First position adjustment buy.
|
# First position adjustment buy.
|
||||||
limit_buy_order_usdt_open['ft_pair'] = pair
|
open_dca_order_1 = {
|
||||||
limit_buy_order_usdt_open['ft_order_side'] = 'buy'
|
'ft_pair': pair,
|
||||||
limit_buy_order_usdt_open['side'] = 'buy'
|
'ft_order_side': 'buy',
|
||||||
limit_buy_order_usdt_open['status'] = None
|
'side': 'buy',
|
||||||
limit_buy_order_usdt_open['price'] = 9
|
'type': 'limit',
|
||||||
limit_buy_order_usdt_open['amount'] = 12
|
'status': None,
|
||||||
limit_buy_order_usdt_open['cost'] = 100
|
'price': 9,
|
||||||
limit_buy_order_usdt_open['ft_is_open'] = True
|
'amount': 12,
|
||||||
limit_buy_order_usdt_open['id'] = 651
|
'cost': 100,
|
||||||
limit_buy_order_usdt_open['order_id'] = 651
|
'ft_is_open': True,
|
||||||
|
'id': '651',
|
||||||
|
'order_id': '651'
|
||||||
|
}
|
||||||
mocker.patch('freqtrade.exchange.Exchange.create_order',
|
mocker.patch('freqtrade.exchange.Exchange.create_order',
|
||||||
MagicMock(return_value=limit_buy_order_usdt_open))
|
MagicMock(return_value=open_dca_order_1))
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order_or_stoploss_order',
|
mocker.patch('freqtrade.exchange.Exchange.fetch_order_or_stoploss_order',
|
||||||
MagicMock(return_value=limit_buy_order_usdt_open))
|
MagicMock(return_value=open_dca_order_1))
|
||||||
assert freqtrade.execute_entry(pair, stake_amount, trade=trade)
|
assert freqtrade.execute_entry(pair, stake_amount, trade=trade)
|
||||||
|
|
||||||
orders = Order.query.all()
|
orders = Order.query.all()
|
||||||
@ -4399,10 +4423,28 @@ def test_position_adjust(mocker, default_conf_usdt, fee, limit_buy_order_usdt,
|
|||||||
assert trade.open_rate == 11
|
assert trade.open_rate == 11
|
||||||
assert trade.amount == 10
|
assert trade.amount == 10
|
||||||
assert trade.stake_amount == 110
|
assert trade.stake_amount == 110
|
||||||
|
assert not trade.fee_updated('buy')
|
||||||
|
trades: List[Trade] = Trade.get_open_trades_without_assigned_fees()
|
||||||
|
assert len(trades) == 1
|
||||||
|
assert trade.is_open
|
||||||
|
assert not trade.fee_updated('buy')
|
||||||
|
order = trade.select_order('buy', False)
|
||||||
|
assert order
|
||||||
|
assert order.order_id == '650'
|
||||||
|
|
||||||
# Assume it does nothing since trade is still open
|
def make_sure_its_651(*apos, **kwargs):
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order_or_stoploss_order',
|
|
||||||
MagicMock(return_value=limit_buy_order_usdt_open))
|
if apos[0] == '650':
|
||||||
|
return closed_successful_buy_order
|
||||||
|
if apos[0] == '651':
|
||||||
|
return open_dca_order_1
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Assume it does nothing since order is still open
|
||||||
|
fetch_order_mm = MagicMock(side_effect=make_sure_its_651)
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.create_order', fetch_order_mm)
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.fetch_order', fetch_order_mm)
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.fetch_order_or_stoploss_order', fetch_order_mm)
|
||||||
freqtrade.update_closed_trades_without_assigned_fees()
|
freqtrade.update_closed_trades_without_assigned_fees()
|
||||||
|
|
||||||
orders = Order.query.all()
|
orders = Order.query.all()
|
||||||
@ -4418,27 +4460,35 @@ def test_position_adjust(mocker, default_conf_usdt, fee, limit_buy_order_usdt,
|
|||||||
assert trade.open_rate == 11
|
assert trade.open_rate == 11
|
||||||
assert trade.amount == 10
|
assert trade.amount == 10
|
||||||
assert trade.stake_amount == 110
|
assert trade.stake_amount == 110
|
||||||
assert trade.fee_updated('buy') is False
|
assert not trade.fee_updated('buy')
|
||||||
|
|
||||||
# Make sure the closed order is found as the first order.
|
# Make sure the closed order is found as the first order.
|
||||||
order = trade.select_order('buy', False)
|
order = trade.select_order('buy', False)
|
||||||
assert order.order_id == '650'
|
assert order.order_id == '650'
|
||||||
|
|
||||||
# Now close the order so it should update.
|
# Now close the order so it should update.
|
||||||
limit_buy_order_usdt_open['ft_pair'] = pair
|
closed_dca_order_1 = {
|
||||||
limit_buy_order_usdt_open['status'] = 'closed'
|
'ft_pair': pair,
|
||||||
limit_buy_order_usdt_open['ft_order_side'] = 'buy'
|
'ft_order_side': 'buy',
|
||||||
limit_buy_order_usdt_open['side'] = 'buy'
|
'side': 'buy',
|
||||||
limit_buy_order_usdt_open['price'] = 9
|
'type': 'limit',
|
||||||
limit_buy_order_usdt_open['average'] = 9
|
'status': 'closed',
|
||||||
limit_buy_order_usdt_open['amount'] = 12
|
'price': 9,
|
||||||
limit_buy_order_usdt_open['filled'] = 12
|
'average': 9,
|
||||||
limit_buy_order_usdt_open['cost'] = 108
|
'amount': 12,
|
||||||
limit_buy_order_usdt_open['ft_is_open'] = False
|
'filled': 12,
|
||||||
limit_buy_order_usdt_open['id'] = '651'
|
'cost': 108,
|
||||||
limit_buy_order_usdt_open['order_id'] = '651'
|
'ft_is_open': False,
|
||||||
|
'id': '651',
|
||||||
|
'order_id': '651'
|
||||||
|
}
|
||||||
|
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.create_order',
|
||||||
|
MagicMock(return_value=closed_dca_order_1))
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order',
|
mocker.patch('freqtrade.exchange.Exchange.fetch_order',
|
||||||
MagicMock(return_value=limit_buy_order_usdt_open))
|
MagicMock(return_value=closed_dca_order_1))
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.fetch_order_or_stoploss_order',
|
||||||
|
MagicMock(return_value=closed_dca_order_1))
|
||||||
freqtrade.check_handle_timedout()
|
freqtrade.check_handle_timedout()
|
||||||
|
|
||||||
# Assert trade is as expected (averaged dca)
|
# Assert trade is as expected (averaged dca)
|
||||||
@ -4461,3 +4511,42 @@ def test_position_adjust(mocker, default_conf_usdt, fee, limit_buy_order_usdt,
|
|||||||
trades: List[Trade] = Trade.get_open_trades_without_assigned_fees()
|
trades: List[Trade] = Trade.get_open_trades_without_assigned_fees()
|
||||||
assert len(trades) == 1
|
assert len(trades) == 1
|
||||||
|
|
||||||
|
# Add a second DCA
|
||||||
|
closed_dca_order_2 = {
|
||||||
|
'ft_pair': pair,
|
||||||
|
'status': 'closed',
|
||||||
|
'ft_order_side': 'buy',
|
||||||
|
'side': 'buy',
|
||||||
|
'type': 'limit',
|
||||||
|
'price': 7,
|
||||||
|
'average': 7,
|
||||||
|
'amount': 15,
|
||||||
|
'filled': 15,
|
||||||
|
'cost': 105,
|
||||||
|
'ft_is_open': False,
|
||||||
|
'id': '652',
|
||||||
|
'order_id': '652'
|
||||||
|
}
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.create_order',
|
||||||
|
MagicMock(return_value=closed_dca_order_2))
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.fetch_order',
|
||||||
|
MagicMock(return_value=closed_dca_order_2))
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.fetch_order_or_stoploss_order',
|
||||||
|
MagicMock(return_value=closed_dca_order_2))
|
||||||
|
assert freqtrade.execute_entry(pair, stake_amount, trade=trade)
|
||||||
|
|
||||||
|
# Assert trade is as expected (averaged dca)
|
||||||
|
trade = Trade.query.first()
|
||||||
|
assert trade
|
||||||
|
assert trade.open_order_id is None
|
||||||
|
assert pytest.approx(trade.open_rate) == 8.729729729729
|
||||||
|
assert trade.amount == 37
|
||||||
|
assert trade.stake_amount == 323
|
||||||
|
|
||||||
|
orders = Order.query.all()
|
||||||
|
assert orders
|
||||||
|
assert len(orders) == 3
|
||||||
|
|
||||||
|
# Make sure the closed order is found as the second order.
|
||||||
|
order = trade.select_order('buy', False)
|
||||||
|
assert order.order_id == '652'
|
||||||
|
Loading…
Reference in New Issue
Block a user