use requested - remaining amount - not the requested amount!

This commit is contained in:
Matthias 2019-10-18 09:04:05 +02:00
parent 2588990f4b
commit 9d739f98ac
2 changed files with 49 additions and 7 deletions

View File

@ -466,11 +466,12 @@ class FreqtradeBot:
if result: if result:
self.wallets.update() self.wallets.update()
def get_real_amount(self, trade: Trade, order: Dict) -> float: def get_real_amount(self, trade: Trade, order: Dict, order_amount: float = None) -> float:
""" """
Get real amount for the trade Get real amount for the trade
Necessary for exchanges which charge fees in base currency (e.g. binance) Necessary for exchanges which charge fees in base currency (e.g. binance)
""" """
if order_amount is None:
order_amount = order['amount'] order_amount = order['amount']
# Only run for closed orders # Only run for closed orders
if trade.fee_open == 0 or order['status'] == 'open': if trade.fee_open == 0 or order['status'] == 'open':
@ -819,7 +820,7 @@ class FreqtradeBot:
trade.stake_amount = trade.amount * trade.open_rate trade.stake_amount = trade.amount * trade.open_rate
# verify if fees were taken from amount to avoid problems during selling # verify if fees were taken from amount to avoid problems during selling
try: try:
new_amount = self.get_real_amount(trade, corder) new_amount = self.get_real_amount(trade, corder, trade.amount)
if not isclose(order['amount'], new_amount, abs_tol=constants.MATH_CLOSE_PREC): if not isclose(order['amount'], new_amount, abs_tol=constants.MATH_CLOSE_PREC):
trade.amount = new_amount trade.amount = new_amount
# Fee was applied, so set to 0 # Fee was applied, so set to 0

View File

@ -2076,7 +2076,7 @@ def test_check_handle_timedout_partial(default_conf, ticker, limit_buy_order_old
assert trades[0].stake_amount == open_trade.open_rate * trades[0].amount assert trades[0].stake_amount == open_trade.open_rate * trades[0].amount
def test_check_handle_timedout_partial_fee(default_conf, ticker, open_trade, caplog, def test_check_handle_timedout_partial_fee(default_conf, ticker, open_trade, caplog, fee,
limit_buy_order_old_partial, trades_for_order, limit_buy_order_old_partial, trades_for_order,
limit_buy_order_old_partial_canceled, mocker) -> None: limit_buy_order_old_partial_canceled, mocker) -> None:
rpc_mock = patch_RPCManager(mocker) rpc_mock = patch_RPCManager(mocker)
@ -2093,8 +2093,8 @@ def test_check_handle_timedout_partial_fee(default_conf, ticker, open_trade, cap
assert open_trade.amount == limit_buy_order_old_partial['amount'] assert open_trade.amount == limit_buy_order_old_partial['amount']
open_trade.fee_open = 0.0025 open_trade.fee_open = fee()
open_trade.fee_close = 0.0025 open_trade.fee_close = fee()
Trade.session.add(open_trade) Trade.session.add(open_trade)
# cancelling a half-filled order should update the amount to the bought amount # cancelling a half-filled order should update the amount to the bought amount
# and apply fees if necessary. # and apply fees if necessary.
@ -2107,11 +2107,52 @@ def test_check_handle_timedout_partial_fee(default_conf, ticker, open_trade, cap
trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all() trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all()
assert len(trades) == 1 assert len(trades) == 1
# Verify that tradehas been updated # Verify that tradehas been updated
assert trades[0].amount == limit_buy_order_old_partial['amount'] - 0.0001 assert trades[0].amount == (limit_buy_order_old_partial['amount'] -
limit_buy_order_old_partial['remaining']) - 0.0001
assert trades[0].open_order_id is None assert trades[0].open_order_id is None
assert trades[0].fee_open == 0 assert trades[0].fee_open == 0
def test_check_handle_timedout_partial_except(default_conf, ticker, open_trade, caplog, fee,
limit_buy_order_old_partial, trades_for_order,
limit_buy_order_old_partial_canceled, mocker) -> None:
rpc_mock = patch_RPCManager(mocker)
cancel_order_mock = MagicMock(return_value=limit_buy_order_old_partial_canceled)
patch_exchange(mocker)
mocker.patch.multiple(
'freqtrade.exchange.Exchange',
get_ticker=ticker,
get_order=MagicMock(return_value=limit_buy_order_old_partial),
cancel_order=cancel_order_mock,
get_trades_for_order=MagicMock(return_value=trades_for_order),
)
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount',
MagicMock(side_effect=DependencyException))
freqtrade = FreqtradeBot(default_conf)
assert open_trade.amount == limit_buy_order_old_partial['amount']
open_trade.fee_open = fee()
open_trade.fee_close = fee()
Trade.session.add(open_trade)
# cancelling a half-filled order should update the amount to the bought amount
# and apply fees if necessary.
freqtrade.check_handle_timedout()
assert log_has_re(r"Could not update trade amount: .*", caplog)
assert cancel_order_mock.call_count == 1
assert rpc_mock.call_count == 1
trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all()
assert len(trades) == 1
# Verify that tradehas been updated
assert trades[0].amount == (limit_buy_order_old_partial['amount'] -
limit_buy_order_old_partial['remaining'])
assert trades[0].open_order_id is None
assert trades[0].fee_open == fee()
def test_check_handle_timedout_exception(default_conf, ticker, open_trade, mocker, caplog) -> None: def test_check_handle_timedout_exception(default_conf, ticker, open_trade, mocker, caplog) -> None:
patch_RPCManager(mocker) patch_RPCManager(mocker)
patch_exchange(mocker) patch_exchange(mocker)