From a98fcee4f950448495f160324738e929705929bf Mon Sep 17 00:00:00 2001 From: Pan Long Date: Fri, 25 May 2018 22:29:06 +0800 Subject: [PATCH] Sell filled amount or an open limit buy order in forcesell. Currently forcesell only cancels an open limit buy order and doesn't sell the filled amount. After this change, forcesell will also update trade's amount to filled amount and sell the filled amount. --- freqtrade/rpc/rpc.py | 6 ++++-- freqtrade/tests/rpc/test_rpc.py | 34 ++++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index dd3eed001..f972e64cc 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -316,8 +316,10 @@ class RPC(object): and order['side'] == 'buy': exchange.cancel_order(trade.open_order_id, trade.pair) trade.close(order.get('price') or trade.open_rate) - # TODO: sell amount which has been bought already - return + # Do the best effort, if we don't know 'filled' amount, don't try selling + if order['filled'] is None: + return + trade.amount = order['filled'] # Ignore trades with an attached LIMIT_SELL order if order and order['status'] == 'open' \ diff --git a/freqtrade/tests/rpc/test_rpc.py b/freqtrade/tests/rpc/test_rpc.py index 1d1b3b39c..1cf374b6b 100644 --- a/freqtrade/tests/rpc/test_rpc.py +++ b/freqtrade/tests/rpc/test_rpc.py @@ -449,20 +449,44 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker) -> None: freqtradebot.state = State.RUNNING assert cancel_order_mock.call_count == 0 # make an limit-buy open trade + trade = Trade.query.filter(Trade.id == '1').first() + filled_amount = trade.amount / 2 mocker.patch( 'freqtrade.freqtradebot.exchange.get_order', return_value={ 'status': 'open', 'type': 'limit', - 'side': 'buy' + 'side': 'buy', + 'filled': filled_amount } ) - # check that the trade is called, which is done - # by ensuring exchange.cancel_order is called + # check that the trade is called, which is done by ensuring exchange.cancel_order is called + # and trade amount is updated (error, res) = rpc.rpc_forcesell('1') assert not error assert res == '' assert cancel_order_mock.call_count == 1 + assert trade.amount == filled_amount + + freqtradebot.create_trade() + trade = Trade.query.filter(Trade.id == '2').first() + amount = trade.amount + # make an limit-buy open trade, if there is no 'filled', don't sell it + mocker.patch( + 'freqtrade.freqtradebot.exchange.get_order', + return_value={ + 'status': 'open', + 'type': 'limit', + 'side': 'buy', + 'filled': None + } + ) + # check that the trade is called, which is done by ensuring exchange.cancel_order is called + (error, res) = rpc.rpc_forcesell('2') + assert not error + assert res == '' + assert cancel_order_mock.call_count == 2 + assert trade.amount == amount freqtradebot.create_trade() # make an limit-sell open trade @@ -474,11 +498,11 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker) -> None: 'side': 'sell' } ) - (error, res) = rpc.rpc_forcesell('2') + (error, res) = rpc.rpc_forcesell('3') assert not error assert res == '' # status quo, no exchange calls - assert cancel_order_mock.call_count == 1 + assert cancel_order_mock.call_count == 2 def test_performance_handle(default_conf, ticker, limit_buy_order, fee,