Merge pull request #2206 from freqtrade/sloe_handling

Improve stoploss on exchange handling
This commit is contained in:
hroff-1902
2019-09-04 10:00:53 +03:00
committed by GitHub
9 changed files with 133 additions and 72 deletions

View File

@@ -4,7 +4,8 @@ from unittest.mock import MagicMock
import ccxt
import pytest
from freqtrade import DependencyException, OperationalException, TemporaryError
from freqtrade import (DependencyException, InvalidOrderException,
OperationalException, TemporaryError)
from freqtrade.tests.conftest import get_patched_exchange
@@ -49,8 +50,9 @@ def test_stoploss_limit_order(default_conf, mocker):
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance')
exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200)
with pytest.raises(DependencyException):
api_mock.create_order = MagicMock(side_effect=ccxt.InvalidOrder("Order not found"))
with pytest.raises(InvalidOrderException):
api_mock.create_order = MagicMock(
side_effect=ccxt.InvalidOrder("binance Order would trigger immediately."))
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance')
exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200)

View File

@@ -1152,7 +1152,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog,
side_effect=DependencyException()
)
freqtrade.handle_stoploss_on_exchange(trade)
assert log_has('Unable to place a stoploss order on exchange: ', caplog)
assert log_has('Unable to place a stoploss order on exchange.', caplog)
assert trade.stoploss_order_id is None
# Fifth case: get_order returns InvalidOrder
@@ -1200,6 +1200,50 @@ def test_handle_sle_cancel_cant_recreate(mocker, default_conf, fee, caplog,
assert trade.is_open is True
def test_create_stoploss_order_invalid_order(mocker, default_conf, caplog, fee,
markets, limit_buy_order, limit_sell_order):
rpc_mock = patch_RPCManager(mocker)
patch_exchange(mocker)
sell_mock = MagicMock(return_value={'id': limit_sell_order['id']})
mocker.patch.multiple(
'freqtrade.exchange.Exchange',
get_ticker=MagicMock(return_value={
'bid': 0.00001172,
'ask': 0.00001173,
'last': 0.00001172
}),
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
sell=sell_mock,
get_fee=fee,
markets=PropertyMock(return_value=markets),
get_order=MagicMock(return_value={'status': 'canceled'}),
stoploss_limit=MagicMock(side_effect=InvalidOrderException()),
)
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)
freqtrade.strategy.order_types['stoploss_on_exchange'] = True
freqtrade.create_trades()
trade = Trade.query.first()
caplog.clear()
freqtrade.create_stoploss_order(trade, 200, 199)
assert trade.stoploss_order_id is None
assert trade.sell_reason == SellType.EMERGENCY_SELL.value
assert log_has("Unable to place a stoploss order on exchange. ", caplog)
assert log_has("Selling the trade forcefully", caplog)
# Should call a market sell
assert sell_mock.call_count == 1
assert sell_mock.call_args[1]['ordertype'] == 'market'
assert sell_mock.call_args[1]['pair'] == trade.pair
assert sell_mock.call_args[1]['amount'] == trade.amount
# Rpc is sending first buy, then sell
assert rpc_mock.call_count == 2
assert rpc_mock.call_args_list[1][0][0]['sell_reason'] == SellType.EMERGENCY_SELL.value
assert rpc_mock.call_args_list[1][0][0]['order_type'] == 'market'
def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog,
markets, limit_buy_order, limit_sell_order) -> None:
# When trailing stoploss is set