Merge branch 'develop' into spreadfilter

This commit is contained in:
hroff-1902
2020-02-04 16:54:46 +03:00
committed by GitHub
49 changed files with 523 additions and 257 deletions

View File

@@ -163,8 +163,8 @@ def test_edge_results(edge_conf, mocker, caplog, data) -> None:
for c, trade in enumerate(data.trades):
res = results.iloc[c]
assert res.exit_type == trade.sell_reason
assert arrow.get(res.open_time) == _get_frame_time_from_offset(trade.open_tick)
assert arrow.get(res.close_time) == _get_frame_time_from_offset(trade.close_tick)
assert res.open_time == np.datetime64(_get_frame_time_from_offset(trade.open_tick))
assert res.close_time == np.datetime64(_get_frame_time_from_offset(trade.close_tick))
def test_adjust(mocker, edge_conf):

View File

@@ -9,7 +9,7 @@ from freqtrade.exceptions import (DependencyException, InvalidOrderException,
from tests.conftest import get_patched_exchange
def test_stoploss_limit_order(default_conf, mocker):
def test_stoploss_order_binance(default_conf, mocker):
api_mock = MagicMock()
order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6))
order_type = 'stop_loss_limit'
@@ -28,46 +28,47 @@ def test_stoploss_limit_order(default_conf, mocker):
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance')
with pytest.raises(OperationalException):
order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=190, rate=200)
order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=190,
order_types={'stoploss_on_exchange_limit_ratio': 1.05})
api_mock.create_order.reset_mock()
order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200)
order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={})
assert 'id' in order
assert 'info' in order
assert order['id'] == order_id
assert api_mock.create_order.call_args[0][0] == 'ETH/BTC'
assert api_mock.create_order.call_args[0][1] == order_type
assert api_mock.create_order.call_args[0][2] == 'sell'
assert api_mock.create_order.call_args[0][3] == 1
assert api_mock.create_order.call_args[0][4] == 200
assert api_mock.create_order.call_args[0][5] == {'stopPrice': 220}
assert api_mock.create_order.call_args_list[0][1]['symbol'] == 'ETH/BTC'
assert api_mock.create_order.call_args_list[0][1]['type'] == order_type
assert api_mock.create_order.call_args_list[0][1]['side'] == 'sell'
assert api_mock.create_order.call_args_list[0][1]['amount'] == 1
assert api_mock.create_order.call_args_list[0][1]['price'] == 220
assert api_mock.create_order.call_args_list[0][1]['params'] == {'stopPrice': 220}
# test exception handling
with pytest.raises(DependencyException):
api_mock.create_order = MagicMock(side_effect=ccxt.InsufficientFunds("0 balance"))
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance')
exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200)
exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={})
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)
exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={})
with pytest.raises(TemporaryError):
api_mock.create_order = MagicMock(side_effect=ccxt.NetworkError("No connection"))
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance')
exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200)
exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={})
with pytest.raises(OperationalException, match=r".*DeadBeef.*"):
api_mock.create_order = MagicMock(side_effect=ccxt.BaseError("DeadBeef"))
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance')
exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200)
exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={})
def test_stoploss_limit_order_dry_run(default_conf, mocker):
def test_stoploss_order_dry_run_binance(default_conf, mocker):
api_mock = MagicMock()
order_type = 'stop_loss_limit'
default_conf['dry_run'] = True
@@ -77,11 +78,12 @@ def test_stoploss_limit_order_dry_run(default_conf, mocker):
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance')
with pytest.raises(OperationalException):
order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=190, rate=200)
order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=190,
order_types={'stoploss_on_exchange_limit_ratio': 1.05})
api_mock.create_order.reset_mock()
order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200)
order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={})
assert 'id' in order
assert 'info' in order
@@ -90,3 +92,17 @@ def test_stoploss_limit_order_dry_run(default_conf, mocker):
assert order['type'] == order_type
assert order['price'] == 220
assert order['amount'] == 1
def test_stoploss_adjust_binance(mocker, default_conf):
exchange = get_patched_exchange(mocker, default_conf, id='binance')
order = {
'type': 'stop_loss_limit',
'price': 1500,
'info': {'stopPrice': 1500},
}
assert exchange.stoploss_adjust(1501, order)
assert not exchange.stoploss_adjust(1499, order)
# Test with invalid order case
order['type'] = 'stop_loss'
assert not exchange.stoploss_adjust(1501, order)

View File

@@ -76,9 +76,11 @@ def test_init_ccxt_kwargs(default_conf, mocker, caplog):
mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency')
caplog.set_level(logging.INFO)
conf = copy.deepcopy(default_conf)
conf['exchange']['ccxt_async_config'] = {'aiohttp_trust_env': True}
conf['exchange']['ccxt_async_config'] = {'aiohttp_trust_env': True, 'asyncio_loop': True}
ex = Exchange(conf)
assert log_has("Applying additional ccxt config: {'aiohttp_trust_env': True}", caplog)
assert log_has(
"Applying additional ccxt config: {'aiohttp_trust_env': True, 'asyncio_loop': True}",
caplog)
assert ex._api_async.aiohttp_trust_env
assert not ex._api.aiohttp_trust_env
@@ -86,6 +88,8 @@ def test_init_ccxt_kwargs(default_conf, mocker, caplog):
caplog.clear()
conf = copy.deepcopy(default_conf)
conf['exchange']['ccxt_config'] = {'TestKWARG': 11}
conf['exchange']['ccxt_async_config'] = {'asyncio_loop': True}
ex = Exchange(conf)
assert not log_has("Applying additional ccxt config: {'aiohttp_trust_env': True}", caplog)
assert not ex._api_async.aiohttp_trust_env
@@ -1758,10 +1762,13 @@ def test_get_fee(default_conf, mocker, exchange_name):
'get_fee', 'calculate_fee', symbol="ETH/BTC")
def test_stoploss_limit_order_unsupported_exchange(default_conf, mocker):
def test_stoploss_order_unsupported_exchange(default_conf, mocker):
exchange = get_patched_exchange(mocker, default_conf, 'bittrex')
with pytest.raises(OperationalException, match=r"stoploss_limit is not implemented .*"):
exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200)
with pytest.raises(OperationalException, match=r"stoploss is not implemented .*"):
exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={})
with pytest.raises(OperationalException, match=r"stoploss is not implemented .*"):
exchange.stoploss_adjust(1, {})
def test_merge_ft_has_dict(default_conf, mocker):

View File

@@ -3,6 +3,11 @@
from random import randint
from unittest.mock import MagicMock
import ccxt
import pytest
from freqtrade.exceptions import (DependencyException, InvalidOrderException,
OperationalException, TemporaryError)
from tests.conftest import get_patched_exchange
from tests.exchange.test_exchange import ccxt_exceptionhandlers
@@ -149,3 +154,98 @@ def test_get_balances_prod(default_conf, mocker):
assert balances['4ST']['used'] == 0.0
ccxt_exceptionhandlers(mocker, default_conf, api_mock, "kraken",
"get_balances", "fetch_balance")
def test_stoploss_order_kraken(default_conf, mocker):
api_mock = MagicMock()
order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6))
order_type = 'stop-loss'
api_mock.create_order = MagicMock(return_value={
'id': order_id,
'info': {
'foo': 'bar'
}
})
default_conf['dry_run'] = False
mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y)
mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y)
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken')
# stoploss_on_exchange_limit_ratio is irrelevant for kraken market orders
order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=190,
order_types={'stoploss_on_exchange_limit_ratio': 1.05})
assert api_mock.create_order.call_count == 1
api_mock.create_order.reset_mock()
order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={})
assert 'id' in order
assert 'info' in order
assert order['id'] == order_id
assert api_mock.create_order.call_args_list[0][1]['symbol'] == 'ETH/BTC'
assert api_mock.create_order.call_args_list[0][1]['type'] == order_type
assert api_mock.create_order.call_args_list[0][1]['side'] == 'sell'
assert api_mock.create_order.call_args_list[0][1]['amount'] == 1
assert api_mock.create_order.call_args_list[0][1]['price'] == 220
assert api_mock.create_order.call_args_list[0][1]['params'] == {'trading_agreement': 'agree'}
# test exception handling
with pytest.raises(DependencyException):
api_mock.create_order = MagicMock(side_effect=ccxt.InsufficientFunds("0 balance"))
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken')
exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={})
with pytest.raises(InvalidOrderException):
api_mock.create_order = MagicMock(
side_effect=ccxt.InvalidOrder("kraken Order would trigger immediately."))
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken')
exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={})
with pytest.raises(TemporaryError):
api_mock.create_order = MagicMock(side_effect=ccxt.NetworkError("No connection"))
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken')
exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={})
with pytest.raises(OperationalException, match=r".*DeadBeef.*"):
api_mock.create_order = MagicMock(side_effect=ccxt.BaseError("DeadBeef"))
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken')
exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={})
def test_stoploss_order_dry_run_kraken(default_conf, mocker):
api_mock = MagicMock()
order_type = 'stop-loss'
default_conf['dry_run'] = True
mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y)
mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y)
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken')
api_mock.create_order.reset_mock()
order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={})
assert 'id' in order
assert 'info' in order
assert 'type' in order
assert order['type'] == order_type
assert order['price'] == 220
assert order['amount'] == 1
def test_stoploss_adjust_kraken(mocker, default_conf):
exchange = get_patched_exchange(mocker, default_conf, id='kraken')
order = {
'type': 'stop-loss',
'price': 1500,
}
assert exchange.stoploss_adjust(1501, order)
assert not exchange.stoploss_adjust(1499, order)
# Test with invalid order case ...
order['type'] = 'stop_loss_limit'
assert not exchange.stoploss_adjust(1501, order)

View File

@@ -21,14 +21,14 @@ def test_generate_text_table(default_conf, mocker):
)
result_str = (
'| pair | buy count | avg profit % | cum profit % | '
'tot profit BTC | tot profit % | avg duration | profit | loss |\n'
'|:--------|------------:|---------------:|---------------:|'
'-----------------:|---------------:|:---------------|---------:|-------:|\n'
'| ETH/BTC | 2 | 15.00 | 30.00 | '
'0.60000000 | 15.00 | 0:20:00 | 2 | 0 |\n'
'| TOTAL | 2 | 15.00 | 30.00 | '
'0.60000000 | 15.00 | 0:20:00 | 2 | 0 |'
'| Pair | Buy Count | Avg Profit % | Cum Profit % | Tot Profit BTC '
'| Tot Profit % | Avg Duration | Wins | Losses |\n'
'|:--------|------------:|---------------:|---------------:|-----------------:'
'|---------------:|:---------------|-------:|---------:|\n'
'| ETH/BTC | 2 | 15.00 | 30.00 | 0.60000000 '
'| 15.00 | 0:20:00 | 2 | 0 |\n'
'| TOTAL | 2 | 15.00 | 30.00 | 0.60000000 '
'| 15.00 | 0:20:00 | 2 | 0 |'
)
assert generate_text_table(data={'ETH/BTC': {}},
stake_currency='BTC', max_open_trades=2,
@@ -50,13 +50,19 @@ def test_generate_text_table_sell_reason(default_conf, mocker):
)
result_str = (
'| Sell Reason | Count | Profit | Loss | Profit % |\n'
'|:--------------|--------:|---------:|-------:|-----------:|\n'
'| roi | 2 | 2 | 0 | 15 |\n'
'| stop_loss | 1 | 0 | 1 | -10 |'
'| Sell Reason | Sell Count | Wins | Losses | Avg Profit % |'
' Cum Profit % | Tot Profit BTC | Tot Profit % |\n'
'|:--------------|-------------:|-------:|---------:|---------------:|'
'---------------:|-----------------:|---------------:|\n'
'| roi | 2 | 2 | 0 | 15 |'
' 30 | 0.6 | 15 |\n'
'| stop_loss | 1 | 0 | 1 | -10 |'
' -10 | -0.2 | -5 |'
)
assert generate_text_table_sell_reason(
data={'ETH/BTC': {}}, results=results) == result_str
data={'ETH/BTC': {}},
stake_currency='BTC', max_open_trades=2,
results=results) == result_str
def test_generate_text_table_strategy(default_conf, mocker):

View File

@@ -1023,8 +1023,8 @@ def test_add_stoploss_on_exchange(mocker, default_conf, limit_buy_order) -> None
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount',
return_value=limit_buy_order['amount'])
stoploss_limit = MagicMock(return_value={'id': 13434334})
mocker.patch('freqtrade.exchange.Exchange.stoploss_limit', stoploss_limit)
stoploss = MagicMock(return_value={'id': 13434334})
mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss)
freqtrade = FreqtradeBot(default_conf)
freqtrade.strategy.order_types['stoploss_on_exchange'] = True
@@ -1037,13 +1037,13 @@ def test_add_stoploss_on_exchange(mocker, default_conf, limit_buy_order) -> None
freqtrade.exit_positions(trades)
assert trade.stoploss_order_id == '13434334'
assert stoploss_limit.call_count == 1
assert stoploss.call_count == 1
assert trade.is_open is True
def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog,
limit_buy_order, limit_sell_order) -> None:
stoploss_limit = MagicMock(return_value={'id': 13434334})
stoploss = MagicMock(return_value={'id': 13434334})
patch_RPCManager(mocker)
patch_exchange(mocker)
mocker.patch.multiple(
@@ -1056,7 +1056,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog,
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
sell=MagicMock(return_value={'id': limit_sell_order['id']}),
get_fee=fee,
stoploss_limit=stoploss_limit
stoploss=stoploss
)
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)
@@ -1070,7 +1070,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog,
trade.stoploss_order_id = None
assert freqtrade.handle_stoploss_on_exchange(trade) is False
assert stoploss_limit.call_count == 1
assert stoploss.call_count == 1
assert trade.stoploss_order_id == "13434334"
# Second case: when stoploss is set but it is not yet hit
@@ -1094,10 +1094,10 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog,
canceled_stoploss_order = MagicMock(return_value={'status': 'canceled'})
mocker.patch('freqtrade.exchange.Exchange.get_order', canceled_stoploss_order)
stoploss_limit.reset_mock()
stoploss.reset_mock()
assert freqtrade.handle_stoploss_on_exchange(trade) is False
assert stoploss_limit.call_count == 1
assert stoploss.call_count == 1
assert trade.stoploss_order_id == "13434334"
# Fourth case: when stoploss is set and it is hit
@@ -1124,9 +1124,10 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog,
assert trade.is_open is False
mocker.patch(
'freqtrade.exchange.Exchange.stoploss_limit',
'freqtrade.exchange.Exchange.stoploss',
side_effect=DependencyException()
)
trade.is_open = True
freqtrade.handle_stoploss_on_exchange(trade)
assert log_has('Unable to place a stoploss order on exchange.', caplog)
assert trade.stoploss_order_id is None
@@ -1134,11 +1135,21 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog,
# Fifth case: get_order returns InvalidOrder
# It should try to add stoploss order
trade.stoploss_order_id = 100
stoploss_limit.reset_mock()
stoploss.reset_mock()
mocker.patch('freqtrade.exchange.Exchange.get_order', side_effect=InvalidOrderException())
mocker.patch('freqtrade.exchange.Exchange.stoploss_limit', stoploss_limit)
mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss)
freqtrade.handle_stoploss_on_exchange(trade)
assert stoploss_limit.call_count == 1
assert stoploss.call_count == 1
# Sixth case: Closed Trade
# Should not create new order
trade.stoploss_order_id = None
trade.is_open = False
stoploss.reset_mock()
mocker.patch('freqtrade.exchange.Exchange.get_order')
mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss)
assert freqtrade.handle_stoploss_on_exchange(trade) is False
assert stoploss.call_count == 0
def test_handle_sle_cancel_cant_recreate(mocker, default_conf, fee, caplog,
@@ -1157,7 +1168,7 @@ def test_handle_sle_cancel_cant_recreate(mocker, default_conf, fee, caplog,
sell=MagicMock(return_value={'id': limit_sell_order['id']}),
get_fee=fee,
get_order=MagicMock(return_value={'status': 'canceled'}),
stoploss_limit=MagicMock(side_effect=DependencyException()),
stoploss=MagicMock(side_effect=DependencyException()),
)
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)
@@ -1165,7 +1176,7 @@ def test_handle_sle_cancel_cant_recreate(mocker, default_conf, fee, caplog,
freqtrade.enter_positions()
trade = Trade.query.first()
trade.is_open = True
trade.open_order_id = '12345'
trade.open_order_id = None
trade.stoploss_order_id = 100
assert trade
@@ -1191,7 +1202,7 @@ def test_create_stoploss_order_invalid_order(mocker, default_conf, caplog, fee,
sell=sell_mock,
get_fee=fee,
get_order=MagicMock(return_value={'status': 'canceled'}),
stoploss_limit=MagicMock(side_effect=InvalidOrderException()),
stoploss=MagicMock(side_effect=InvalidOrderException()),
)
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)
@@ -1221,7 +1232,7 @@ def test_create_stoploss_order_invalid_order(mocker, default_conf, caplog, fee,
def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog,
limit_buy_order, limit_sell_order) -> None:
# When trailing stoploss is set
stoploss_limit = MagicMock(return_value={'id': 13434334})
stoploss = MagicMock(return_value={'id': 13434334})
patch_RPCManager(mocker)
mocker.patch.multiple(
'freqtrade.exchange.Exchange',
@@ -1233,7 +1244,8 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog,
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
sell=MagicMock(return_value={'id': limit_sell_order['id']}),
get_fee=fee,
stoploss_limit=stoploss_limit
stoploss=stoploss,
stoploss_adjust=MagicMock(return_value=True),
)
# enabling TSL
@@ -1288,7 +1300,7 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog,
cancel_order_mock = MagicMock()
stoploss_order_mock = MagicMock()
mocker.patch('freqtrade.exchange.Exchange.cancel_order', cancel_order_mock)
mocker.patch('freqtrade.exchange.Exchange.stoploss_limit', stoploss_order_mock)
mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss_order_mock)
# stoploss should not be updated as the interval is 60 seconds
assert freqtrade.handle_trade(trade) is False
@@ -1307,7 +1319,7 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog,
cancel_order_mock.assert_called_once_with(100, 'ETH/BTC')
stoploss_order_mock.assert_called_once_with(amount=85.25149190110828,
pair='ETH/BTC',
rate=0.00002344 * 0.95 * 0.99,
order_types=freqtrade.strategy.order_types,
stop_price=0.00002344 * 0.95)
# price fell below stoploss, so dry-run sells trade.
@@ -1322,7 +1334,7 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog,
def test_handle_stoploss_on_exchange_trailing_error(mocker, default_conf, fee, caplog,
limit_buy_order, limit_sell_order) -> None:
# When trailing stoploss is set
stoploss_limit = MagicMock(return_value={'id': 13434334})
stoploss = MagicMock(return_value={'id': 13434334})
patch_exchange(mocker)
mocker.patch.multiple(
@@ -1335,7 +1347,8 @@ def test_handle_stoploss_on_exchange_trailing_error(mocker, default_conf, fee, c
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
sell=MagicMock(return_value={'id': limit_sell_order['id']}),
get_fee=fee,
stoploss_limit=stoploss_limit
stoploss=stoploss,
stoploss_adjust=MagicMock(return_value=True),
)
# enabling TSL
@@ -1375,12 +1388,12 @@ def test_handle_stoploss_on_exchange_trailing_error(mocker, default_conf, fee, c
assert log_has_re(r"Could not cancel stoploss order abcd for pair ETH/BTC.*", caplog)
# Still try to create order
assert stoploss_limit.call_count == 1
assert stoploss.call_count == 1
# Fail creating stoploss order
caplog.clear()
cancel_mock = mocker.patch("freqtrade.exchange.Exchange.cancel_order", MagicMock())
mocker.patch("freqtrade.exchange.Exchange.stoploss_limit", side_effect=DependencyException())
mocker.patch("freqtrade.exchange.Exchange.stoploss", side_effect=DependencyException())
freqtrade.handle_trailing_stoploss_on_exchange(trade, stoploss_order_hanging)
assert cancel_mock.call_count == 1
assert log_has_re(r"Could not create trailing stoploss order for pair ETH/BTC\..*", caplog)
@@ -1390,12 +1403,13 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,
limit_buy_order, limit_sell_order) -> None:
# When trailing stoploss is set
stoploss_limit = MagicMock(return_value={'id': 13434334})
stoploss = MagicMock(return_value={'id': 13434334})
patch_RPCManager(mocker)
patch_exchange(mocker)
patch_edge(mocker)
edge_conf['max_open_trades'] = float('inf')
edge_conf['dry_run_wallet'] = 999.9
edge_conf['exchange']['name'] = 'binance'
mocker.patch.multiple(
'freqtrade.exchange.Exchange',
fetch_ticker=MagicMock(return_value={
@@ -1406,7 +1420,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
sell=MagicMock(return_value={'id': limit_sell_order['id']}),
get_fee=fee,
stoploss_limit=stoploss_limit
stoploss=stoploss,
)
# enabling TSL
@@ -1459,7 +1473,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,
cancel_order_mock = MagicMock()
stoploss_order_mock = MagicMock()
mocker.patch('freqtrade.exchange.Exchange.cancel_order', cancel_order_mock)
mocker.patch('freqtrade.exchange.Exchange.stoploss_limit', stoploss_order_mock)
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss_order_mock)
# price goes down 5%
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={
@@ -1492,7 +1506,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,
cancel_order_mock.assert_called_once_with(100, 'NEO/BTC')
stoploss_order_mock.assert_called_once_with(amount=2131074.168797954,
pair='NEO/BTC',
rate=0.00002344 * 0.99 * 0.99,
order_types=freqtrade.strategy.order_types,
stop_price=0.00002344 * 0.99)
@@ -2423,7 +2437,7 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke
default_conf['exchange']['name'] = 'binance'
rpc_mock = patch_RPCManager(mocker)
patch_exchange(mocker)
stoploss_limit = MagicMock(return_value={
stoploss = MagicMock(return_value={
'id': 123,
'info': {
'foo': 'bar'
@@ -2437,7 +2451,7 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke
get_fee=fee,
amount_to_precision=lambda s, x, y: y,
price_to_precision=lambda s, x, y: y,
stoploss_limit=stoploss_limit,
stoploss=stoploss,
cancel_order=cancel_order,
)
@@ -2482,14 +2496,14 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f
price_to_precision=lambda s, x, y: y,
)
stoploss_limit = MagicMock(return_value={
stoploss = MagicMock(return_value={
'id': 123,
'info': {
'foo': 'bar'
}
})
mocker.patch('freqtrade.exchange.Binance.stoploss_limit', stoploss_limit)
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss)
freqtrade = FreqtradeBot(default_conf)
freqtrade.strategy.order_types['stoploss_on_exchange'] = True
@@ -2507,7 +2521,7 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f
# Assuming stoploss on exchnage is hit
# stoploss_order_id should become None
# and trade should be sold at the price of stoploss
stoploss_limit_executed = MagicMock(return_value={
stoploss_executed = MagicMock(return_value={
"id": "123",
"timestamp": 1542707426845,
"datetime": "2018-11-20T09:50:26.845Z",
@@ -2525,7 +2539,7 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f
"fee": None,
"trades": None
})
mocker.patch('freqtrade.exchange.Exchange.get_order', stoploss_limit_executed)
mocker.patch('freqtrade.exchange.Exchange.get_order', stoploss_executed)
freqtrade.exit_positions(trades)
assert trade.stoploss_order_id is None

View File

@@ -20,7 +20,7 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee,
default_conf['max_open_trades'] = 3
default_conf['exchange']['name'] = 'binance'
stoploss_limit = {
stoploss = {
'id': 123,
'info': {}
}
@@ -53,7 +53,7 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee,
SellCheckTuple(sell_flag=True, sell_type=SellType.SELL_SIGNAL)]
)
cancel_order_mock = MagicMock()
mocker.patch('freqtrade.exchange.Binance.stoploss_limit', stoploss_limit)
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss)
mocker.patch.multiple(
'freqtrade.exchange.Exchange',
fetch_ticker=ticker,