Merge branch 'freqtrade:develop' into strategy_utils

This commit is contained in:
hippocritical
2023-02-17 21:07:23 +01:00
committed by GitHub
39 changed files with 3620 additions and 1598 deletions

View File

@@ -139,7 +139,7 @@ def test_adjust(mocker, edge_conf):
assert (edge.adjust(pairs) == ['E/F', 'C/D'])
def test_stoploss(mocker, edge_conf):
def test_edge_get_stoploss(mocker, edge_conf):
freqtrade = get_patched_freqtradebot(mocker, edge_conf)
edge = Edge(edge_conf, freqtrade.exchange, freqtrade.strategy)
mocker.patch('freqtrade.edge.Edge._cached_pairs', mocker.PropertyMock(
@@ -150,10 +150,10 @@ def test_stoploss(mocker, edge_conf):
}
))
assert edge.stoploss('E/F') == -0.01
assert edge.get_stoploss('E/F') == -0.01
def test_nonexisting_stoploss(mocker, edge_conf):
def test_nonexisting_get_stoploss(mocker, edge_conf):
freqtrade = get_patched_freqtradebot(mocker, edge_conf)
edge = Edge(edge_conf, freqtrade.exchange, freqtrade.strategy)
mocker.patch('freqtrade.edge.Edge._cached_pairs', mocker.PropertyMock(
@@ -162,7 +162,7 @@ def test_nonexisting_stoploss(mocker, edge_conf):
}
))
assert edge.stoploss('N/O') == -0.1
assert edge.get_stoploss('N/O') == -0.1
def test_edge_stake_amount(mocker, edge_conf):

View File

@@ -20,7 +20,7 @@ from tests.exchange.test_exchange import ccxt_exceptionhandlers
(0.99, 220 * 1.01, "buy"),
(0.98, 220 * 1.02, "buy"),
])
def test_stoploss_order_binance(default_conf, mocker, limitratio, expected, side, trademode):
def test_create_stoploss_order_binance(default_conf, mocker, limitratio, expected, side, trademode):
api_mock = MagicMock()
order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6))
order_type = 'stop_loss_limit' if trademode == TradingMode.SPOT else 'stop'
@@ -40,7 +40,7 @@ def test_stoploss_order_binance(default_conf, mocker, limitratio, expected, side
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance')
with pytest.raises(OperationalException):
order = exchange.stoploss(
order = exchange.create_stoploss(
pair='ETH/BTC',
amount=1,
stop_price=190,
@@ -54,7 +54,7 @@ def test_stoploss_order_binance(default_conf, mocker, limitratio, expected, side
if limitratio is not None:
order_types.update({'stoploss_on_exchange_limit_ratio': limitratio})
order = exchange.stoploss(
order = exchange.create_stoploss(
pair='ETH/BTC',
amount=1,
stop_price=220,
@@ -82,7 +82,7 @@ def test_stoploss_order_binance(default_conf, mocker, limitratio, expected, side
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(
exchange.create_stoploss(
pair='ETH/BTC',
amount=1,
stop_price=220,
@@ -94,7 +94,7 @@ def test_stoploss_order_binance(default_conf, mocker, limitratio, expected, side
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(
exchange.create_stoploss(
pair='ETH/BTC',
amount=1,
stop_price=220,
@@ -104,12 +104,12 @@ def test_stoploss_order_binance(default_conf, mocker, limitratio, expected, side
)
ccxt_exceptionhandlers(mocker, default_conf, api_mock, "binance",
"stoploss", "create_order", retries=1,
"create_stoploss", "create_order", retries=1,
pair='ETH/BTC', amount=1, stop_price=220, order_types={},
side=side, leverage=1.0)
def test_stoploss_order_dry_run_binance(default_conf, mocker):
def test_create_stoploss_order_dry_run_binance(default_conf, mocker):
api_mock = MagicMock()
order_type = 'stop_loss_limit'
default_conf['dry_run'] = True
@@ -119,7 +119,7 @@ def test_stoploss_order_dry_run_binance(default_conf, mocker):
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance')
with pytest.raises(OperationalException):
order = exchange.stoploss(
order = exchange.create_stoploss(
pair='ETH/BTC',
amount=1,
stop_price=190,
@@ -130,7 +130,7 @@ def test_stoploss_order_dry_run_binance(default_conf, mocker):
api_mock.create_order.reset_mock()
order = exchange.stoploss(
order = exchange.create_stoploss(
pair='ETH/BTC',
amount=1,
stop_price=220,
@@ -495,7 +495,8 @@ def test_fill_leverage_tiers_binance_dryrun(default_conf, mocker, leverage_tiers
for key, value in leverage_tiers.items():
v = exchange._leverage_tiers[key]
assert isinstance(v, list)
assert len(v) == len(value)
# Assert if conftest leverage tiers have less or equal tiers than the exchange
assert len(v) >= len(value)
def test_additional_exchange_init_binance(default_conf, mocker):

View File

@@ -534,8 +534,7 @@ class TestCCXTExchange():
def test_ccxt__async_get_candle_history(self, exchange: EXCHANGE_FIXTURE_TYPE):
exc, exchangename = exchange
if exchangename in ('binanceus', 'bittrex'):
# TODO: reenable binanceus test once downtime "ages out" (2023-02-06)
if exchangename in ('bittrex'):
# For some weired reason, this test returns random lengths for bittrex.
pytest.skip("Exchange doesn't provide stable ohlcv history")

View File

@@ -1223,7 +1223,7 @@ def test_create_dry_run_order_fees(
'freqtrade.exchange.Exchange.get_fee',
side_effect=lambda symbol, taker_or_maker: 2.0 if taker_or_maker == 'taker' else 1.0
)
mocker.patch('freqtrade.exchange.Exchange._is_dry_limit_order_filled',
mocker.patch('freqtrade.exchange.Exchange._dry_is_price_crossed',
return_value=price_side == 'other')
exchange = get_patched_exchange(mocker, default_conf)
@@ -1241,25 +1241,27 @@ def test_create_dry_run_order_fees(
else:
assert order['fee'] is None
mocker.patch('freqtrade.exchange.Exchange._is_dry_limit_order_filled',
mocker.patch('freqtrade.exchange.Exchange._dry_is_price_crossed',
return_value=price_side != 'other')
order1 = exchange.fetch_dry_run_order(order['id'])
assert order1['fee']['rate'] == fee
@pytest.mark.parametrize("side,price,filled", [
@pytest.mark.parametrize("side,price,filled,converted", [
# order_book_l2_usd spread:
# best ask: 25.566
# best bid: 25.563
("buy", 25.563, False),
("buy", 25.566, True),
("sell", 25.566, False),
("sell", 25.563, True),
("buy", 25.563, False, False),
("buy", 25.566, True, False),
("sell", 25.566, False, False),
("sell", 25.563, True, False),
("buy", 29.563, True, True),
("sell", 21.563, True, True),
])
@pytest.mark.parametrize("exchange_name", EXCHANGES)
def test_create_dry_run_order_limit_fill(default_conf, mocker, side, price, filled,
exchange_name, order_book_l2_usd):
def test_create_dry_run_order_limit_fill(default_conf, mocker, side, price, filled, caplog,
exchange_name, order_book_l2_usd, converted):
default_conf['dry_run'] = True
exchange = get_patched_exchange(mocker, default_conf, id=exchange_name)
mocker.patch.multiple('freqtrade.exchange.Exchange',
@@ -1279,9 +1281,16 @@ def test_create_dry_run_order_limit_fill(default_conf, mocker, side, price, fill
assert 'id' in order
assert f'dry_run_{side}_' in order["id"]
assert order["side"] == side
assert order["type"] == "limit"
if not converted:
assert order["average"] == price
assert order["type"] == "limit"
else:
# Converted to market order
assert order["type"] == "market"
assert 25.5 < order["average"] < 25.6
assert log_has_re(r"Converted .* to market order.*", caplog)
assert order["symbol"] == "LTC/USDT"
assert order["average"] == price
assert order['status'] == 'open' if not filled else 'closed'
order_book_l2_usd.reset_mock()
@@ -3018,7 +3027,7 @@ def test_get_historic_trades_notsupported(default_conf, mocker, caplog, exchange
def test_cancel_order_dry_run(default_conf, mocker, exchange_name):
default_conf['dry_run'] = True
exchange = get_patched_exchange(mocker, default_conf, id=exchange_name)
mocker.patch('freqtrade.exchange.Exchange._is_dry_limit_order_filled', return_value=True)
mocker.patch('freqtrade.exchange.Exchange._dry_is_price_crossed', return_value=True)
assert exchange.cancel_order(order_id='123', pair='TKN/BTC') == {}
assert exchange.cancel_stoploss_order(order_id='123', pair='TKN/BTC') == {}
@@ -3380,7 +3389,7 @@ def test_get_fee(default_conf, mocker, exchange_name):
def test_stoploss_order_unsupported_exchange(default_conf, mocker):
exchange = get_patched_exchange(mocker, default_conf, id='bittrex')
with pytest.raises(OperationalException, match=r"stoploss is not implemented .*"):
exchange.stoploss(
exchange.create_stoploss(
pair='ETH/BTC',
amount=1,
stop_price=220,
@@ -5318,7 +5327,7 @@ def test_stoploss_contract_size(mocker, default_conf, contract_size, order_amoun
exchange.get_contract_size = MagicMock(return_value=contract_size)
api_mock.create_order.reset_mock()
order = exchange.stoploss(
order = exchange.create_stoploss(
pair='ETH/BTC',
amount=100,
stop_price=220,

View File

@@ -14,7 +14,7 @@ from tests.exchange.test_exchange import ccxt_exceptionhandlers
(0.99, 220 * 0.99, "sell"),
(0.98, 220 * 0.98, "sell"),
])
def test_stoploss_order_huobi(default_conf, mocker, limitratio, expected, side):
def test_create_stoploss_order_huobi(default_conf, mocker, limitratio, expected, side):
api_mock = MagicMock()
order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6))
order_type = 'stop-limit'
@@ -32,15 +32,15 @@ def test_stoploss_order_huobi(default_conf, mocker, limitratio, expected, side):
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'huobi')
with pytest.raises(OperationalException):
order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=190,
order_types={'stoploss_on_exchange_limit_ratio': 1.05},
side=side,
leverage=1.0)
order = exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=190,
order_types={'stoploss_on_exchange_limit_ratio': 1.05},
side=side,
leverage=1.0)
api_mock.create_order.reset_mock()
order_types = {} if limitratio is None else {'stoploss_on_exchange_limit_ratio': limitratio}
order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types=order_types,
side=side, leverage=1.0)
order = exchange.create_stoploss(
pair='ETH/BTC', amount=1, stop_price=220, order_types=order_types, side=side, leverage=1.0)
assert 'id' in order
assert 'info' in order
@@ -59,23 +59,23 @@ def test_stoploss_order_huobi(default_conf, mocker, limitratio, expected, side):
with pytest.raises(DependencyException):
api_mock.create_order = MagicMock(side_effect=ccxt.InsufficientFunds("0 balance"))
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'huobi')
exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220,
order_types={}, side=side, leverage=1.0)
exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=220,
order_types={}, side=side, leverage=1.0)
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(pair='ETH/BTC', amount=1, stop_price=220,
order_types={}, side=side, leverage=1.0)
exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=220,
order_types={}, side=side, leverage=1.0)
ccxt_exceptionhandlers(mocker, default_conf, api_mock, "huobi",
"stoploss", "create_order", retries=1,
"create_stoploss", "create_order", retries=1,
pair='ETH/BTC', amount=1, stop_price=220, order_types={},
side=side, leverage=1.0)
def test_stoploss_order_dry_run_huobi(default_conf, mocker):
def test_create_stoploss_order_dry_run_huobi(default_conf, mocker):
api_mock = MagicMock()
order_type = 'stop-limit'
default_conf['dry_run'] = True
@@ -85,14 +85,14 @@ def test_stoploss_order_dry_run_huobi(default_conf, mocker):
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'huobi')
with pytest.raises(OperationalException):
order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=190,
order_types={'stoploss_on_exchange_limit_ratio': 1.05},
side='sell', leverage=1.0)
order = exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=190,
order_types={'stoploss_on_exchange_limit_ratio': 1.05},
side='sell', leverage=1.0)
api_mock.create_order.reset_mock()
order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220,
order_types={}, side='sell', leverage=1.0)
order = exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=220,
order_types={}, side='sell', leverage=1.0)
assert 'id' in order
assert 'info' in order

View File

@@ -179,7 +179,7 @@ def test_get_balances_prod(default_conf, mocker):
("sell", 217.8),
("buy", 222.2),
])
def test_stoploss_order_kraken(default_conf, mocker, ordertype, side, adjustedprice):
def test_create_stoploss_order_kraken(default_conf, mocker, ordertype, side, adjustedprice):
api_mock = MagicMock()
order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6))
@@ -196,7 +196,7 @@ def test_stoploss_order_kraken(default_conf, mocker, ordertype, side, adjustedpr
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken')
order = exchange.stoploss(
order = exchange.create_stoploss(
pair='ETH/BTC',
amount=1,
stop_price=220,
@@ -230,7 +230,7 @@ def test_stoploss_order_kraken(default_conf, mocker, ordertype, side, adjustedpr
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(
exchange.create_stoploss(
pair='ETH/BTC',
amount=1,
stop_price=220,
@@ -243,7 +243,7 @@ def test_stoploss_order_kraken(default_conf, mocker, ordertype, side, adjustedpr
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(
exchange.create_stoploss(
pair='ETH/BTC',
amount=1,
stop_price=220,
@@ -253,13 +253,13 @@ def test_stoploss_order_kraken(default_conf, mocker, ordertype, side, adjustedpr
)
ccxt_exceptionhandlers(mocker, default_conf, api_mock, "kraken",
"stoploss", "create_order", retries=1,
"create_stoploss", "create_order", retries=1,
pair='ETH/BTC', amount=1, stop_price=220, order_types={},
side=side, leverage=1.0)
@pytest.mark.parametrize('side', ['buy', 'sell'])
def test_stoploss_order_dry_run_kraken(default_conf, mocker, side):
def test_create_stoploss_order_dry_run_kraken(default_conf, mocker, side):
api_mock = MagicMock()
default_conf['dry_run'] = True
mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y)
@@ -269,7 +269,7 @@ def test_stoploss_order_dry_run_kraken(default_conf, mocker, side):
api_mock.create_order.reset_mock()
order = exchange.stoploss(
order = exchange.create_stoploss(
pair='ETH/BTC',
amount=1,
stop_price=220,

View File

@@ -15,7 +15,7 @@ from tests.exchange.test_exchange import ccxt_exceptionhandlers
(0.99, 220 * 0.99, "sell"),
(0.98, 220 * 0.98, "sell"),
])
def test_stoploss_order_kucoin(default_conf, mocker, limitratio, expected, side, order_type):
def test_create_stoploss_order_kucoin(default_conf, mocker, limitratio, expected, side, order_type):
api_mock = MagicMock()
order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6))
@@ -32,18 +32,18 @@ def test_stoploss_order_kucoin(default_conf, mocker, limitratio, expected, side,
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kucoin')
if order_type == 'limit':
with pytest.raises(OperationalException):
order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=190,
order_types={
'stoploss': order_type,
'stoploss_on_exchange_limit_ratio': 1.05},
side=side, leverage=1.0)
order = exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=190,
order_types={
'stoploss': order_type,
'stoploss_on_exchange_limit_ratio': 1.05},
side=side, leverage=1.0)
api_mock.create_order.reset_mock()
order_types = {'stoploss': order_type}
if limitratio is not None:
order_types.update({'stoploss_on_exchange_limit_ratio': limitratio})
order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220,
order_types=order_types, side=side, leverage=1.0)
order = exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=220,
order_types=order_types, side=side, leverage=1.0)
assert 'id' in order
assert 'info' in order
@@ -67,18 +67,18 @@ def test_stoploss_order_kucoin(default_conf, mocker, limitratio, expected, side,
with pytest.raises(DependencyException):
api_mock.create_order = MagicMock(side_effect=ccxt.InsufficientFunds("0 balance"))
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kucoin')
exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220,
order_types={}, side=side, leverage=1.0)
exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=220,
order_types={}, side=side, leverage=1.0)
with pytest.raises(InvalidOrderException):
api_mock.create_order = MagicMock(
side_effect=ccxt.InvalidOrder("kucoin Order would trigger immediately."))
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kucoin')
exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220,
order_types={}, side=side, leverage=1.0)
exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=220,
order_types={}, side=side, leverage=1.0)
ccxt_exceptionhandlers(mocker, default_conf, api_mock, "kucoin",
"stoploss", "create_order", retries=1,
"create_stoploss", "create_order", retries=1,
pair='ETH/BTC', amount=1, stop_price=220, order_types={},
side=side, leverage=1.0)
@@ -93,15 +93,15 @@ def test_stoploss_order_dry_run_kucoin(default_conf, mocker):
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kucoin')
with pytest.raises(OperationalException):
order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=190,
order_types={'stoploss': 'limit',
'stoploss_on_exchange_limit_ratio': 1.05},
side='sell', leverage=1.0)
order = exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=190,
order_types={'stoploss': 'limit',
'stoploss_on_exchange_limit_ratio': 1.05},
side='sell', leverage=1.0)
api_mock.create_order.reset_mock()
order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220,
order_types={}, side='sell', leverage=1.0)
order = exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=220,
order_types={}, side='sell', leverage=1.0)
assert 'id' in order
assert 'info' in order

View File

@@ -112,7 +112,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
'freqtrade.exchange.Exchange',
fetch_ticker=ticker,
get_fee=fee,
_is_dry_limit_order_filled=MagicMock(side_effect=[False, True]),
_dry_is_price_crossed=MagicMock(side_effect=[False, True]),
)
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
@@ -226,7 +226,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
freqtradebot.state = State.RUNNING
with pytest.raises(RPCException, match=r'.*no active trade*'):
rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
mocker.patch('freqtrade.exchange.Exchange._is_dry_limit_order_filled', return_value=False)
mocker.patch('freqtrade.exchange.Exchange._dry_is_price_crossed', return_value=False)
freqtradebot.enter_positions()
result, headers, fiat_profit_sum = rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
@@ -237,7 +237,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
assert '0.00' == result[0][3]
assert isnan(fiat_profit_sum)
mocker.patch('freqtrade.exchange.Exchange._is_dry_limit_order_filled', return_value=True)
mocker.patch('freqtrade.exchange.Exchange._dry_is_price_crossed', return_value=True)
freqtradebot.process()
result, headers, fiat_profit_sum = rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
@@ -688,7 +688,7 @@ def test_rpc_force_exit(default_conf, ticker, fee, mocker) -> None:
'filled': 0.0,
}
),
_is_dry_limit_order_filled=MagicMock(return_value=True),
_dry_is_price_crossed=MagicMock(return_value=True),
get_fee=fee,
)
mocker.patch('freqtrade.wallets.Wallets.get_free', return_value=1000)
@@ -726,7 +726,7 @@ def test_rpc_force_exit(default_conf, ticker, fee, mocker) -> None:
freqtradebot.state = State.RUNNING
assert cancel_order_mock.call_count == 0
mocker.patch(
'freqtrade.exchange.Exchange._is_dry_limit_order_filled', MagicMock(return_value=False))
'freqtrade.exchange.Exchange._dry_is_price_crossed', MagicMock(return_value=False))
freqtradebot.enter_positions()
# make an limit-buy open trade
trade = Trade.query.filter(Trade.id == '3').first()

View File

@@ -1280,7 +1280,7 @@ def test_api_forceexit(botclient, mocker, ticker, fee, markets):
fetch_ticker=ticker,
get_fee=fee,
markets=PropertyMock(return_value=markets),
_is_dry_limit_order_filled=MagicMock(return_value=True),
_dry_is_price_crossed=MagicMock(return_value=True),
)
patch_get_signal(ftbot)

View File

@@ -313,7 +313,7 @@ def test_status_handle(default_conf, update, ticker, fee, mocker) -> None:
'freqtrade.exchange.Exchange',
fetch_ticker=ticker,
get_fee=fee,
_is_dry_limit_order_filled=MagicMock(return_value=True),
_dry_is_price_crossed=MagicMock(return_value=True),
)
status_table = MagicMock()
mocker.patch.multiple(
@@ -930,7 +930,7 @@ def test_telegram_forceexit_handle(default_conf, update, ticker, fee,
'freqtrade.exchange.Exchange',
fetch_ticker=ticker,
get_fee=fee,
_is_dry_limit_order_filled=MagicMock(return_value=True),
_dry_is_price_crossed=MagicMock(return_value=True),
)
freqtradebot = FreqtradeBot(default_conf)
@@ -999,7 +999,7 @@ def test_telegram_force_exit_down_handle(default_conf, update, ticker, fee,
'freqtrade.exchange.Exchange',
fetch_ticker=ticker,
get_fee=fee,
_is_dry_limit_order_filled=MagicMock(return_value=True),
_dry_is_price_crossed=MagicMock(return_value=True),
)
freqtradebot = FreqtradeBot(default_conf)
@@ -1070,7 +1070,7 @@ def test_forceexit_all_handle(default_conf, update, ticker, fee, mocker) -> None
'freqtrade.exchange.Exchange',
fetch_ticker=ticker,
get_fee=fee,
_is_dry_limit_order_filled=MagicMock(return_value=True),
_dry_is_price_crossed=MagicMock(return_value=True),
)
default_conf['max_open_trades'] = 4
freqtradebot = FreqtradeBot(default_conf)
@@ -1155,7 +1155,7 @@ def test_force_exit_no_pair(default_conf, update, ticker, fee, mocker) -> None:
'freqtrade.exchange.Exchange',
fetch_ticker=ticker,
get_fee=fee,
_is_dry_limit_order_filled=MagicMock(return_value=True),
_dry_is_price_crossed=MagicMock(return_value=True),
)
femock = mocker.patch('freqtrade.rpc.rpc.RPC._rpc_force_exit')
telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf)

View File

@@ -452,8 +452,8 @@ def test_min_roi_reached3(default_conf, fee) -> None:
(0.05, 0.9, ExitType.NONE, None, False, True, 0.09, 0.9, ExitType.NONE,
lambda **kwargs: None),
])
def test_stop_loss_reached(default_conf, fee, profit, adjusted, expected, liq, trailing, custom,
profit2, adjusted2, expected2, custom_stop) -> None:
def test_ft_stoploss_reached(default_conf, fee, profit, adjusted, expected, liq, trailing, custom,
profit2, adjusted2, expected2, custom_stop) -> None:
strategy = StrategyResolver.load_strategy(default_conf)
trade = Trade(
@@ -477,9 +477,9 @@ def test_stop_loss_reached(default_conf, fee, profit, adjusted, expected, liq, t
now = arrow.utcnow().datetime
current_rate = trade.open_rate * (1 + profit)
sl_flag = strategy.stop_loss_reached(current_rate=current_rate, trade=trade,
current_time=now, current_profit=profit,
force_stoploss=0, high=None)
sl_flag = strategy.ft_stoploss_reached(current_rate=current_rate, trade=trade,
current_time=now, current_profit=profit,
force_stoploss=0, high=None)
assert isinstance(sl_flag, ExitCheckTuple)
assert sl_flag.exit_type == expected
if expected == ExitType.NONE:
@@ -489,9 +489,9 @@ def test_stop_loss_reached(default_conf, fee, profit, adjusted, expected, liq, t
assert round(trade.stop_loss, 2) == adjusted
current_rate2 = trade.open_rate * (1 + profit2)
sl_flag = strategy.stop_loss_reached(current_rate=current_rate2, trade=trade,
current_time=now, current_profit=profit2,
force_stoploss=0, high=None)
sl_flag = strategy.ft_stoploss_reached(current_rate=current_rate2, trade=trade,
current_time=now, current_profit=profit2,
force_stoploss=0, high=None)
assert sl_flag.exit_type == expected2
if expected2 == ExitType.NONE:
assert sl_flag.exit_flag is False
@@ -579,7 +579,7 @@ def test_should_sell(default_conf, fee) -> None:
assert res == [ExitCheckTuple(exit_type=ExitType.ROI)]
strategy.min_roi_reached = MagicMock(return_value=True)
strategy.stop_loss_reached = MagicMock(
strategy.ft_stoploss_reached = MagicMock(
return_value=ExitCheckTuple(exit_type=ExitType.STOP_LOSS))
res = strategy.should_exit(trade, 1, now,
@@ -603,7 +603,7 @@ def test_should_sell(default_conf, fee) -> None:
ExitCheckTuple(exit_type=ExitType.ROI),
]
strategy.stop_loss_reached = MagicMock(
strategy.ft_stoploss_reached = MagicMock(
return_value=ExitCheckTuple(exit_type=ExitType.TRAILING_STOP_LOSS))
# Regular exit signal
res = strategy.should_exit(trade, 1, now,

View File

@@ -272,7 +272,7 @@ def test_total_open_trades_stakes(mocker, default_conf_usdt, ticker_usdt, fee) -
'freqtrade.exchange.Exchange',
fetch_ticker=ticker_usdt,
get_fee=fee,
_is_dry_limit_order_filled=MagicMock(return_value=False),
_dry_is_price_crossed=MagicMock(return_value=False),
)
freqtrade = FreqtradeBot(default_conf_usdt)
patch_get_signal(freqtrade)
@@ -307,7 +307,7 @@ def test_create_trade(default_conf_usdt, ticker_usdt, limit_order,
'freqtrade.exchange.Exchange',
fetch_ticker=ticker_usdt,
get_fee=fee,
_is_dry_limit_order_filled=MagicMock(return_value=False),
_dry_is_price_crossed=MagicMock(return_value=False),
)
# Save state of current whitelist
@@ -1070,7 +1070,7 @@ def test_add_stoploss_on_exchange(mocker, default_conf_usdt, limit_order, is_sho
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[])
stoploss = MagicMock(return_value={'id': 13434334})
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss)
mocker.patch('freqtrade.exchange.Binance.create_stoploss', stoploss)
freqtrade = FreqtradeBot(default_conf_usdt)
freqtrade.strategy.order_types['stoploss_on_exchange'] = True
@@ -1109,7 +1109,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog, is_
exit_order,
]),
get_fee=fee,
stoploss=stoploss
create_stoploss=stoploss
)
freqtrade = FreqtradeBot(default_conf_usdt)
patch_get_signal(freqtrade, enter_short=is_short, enter_long=not is_short)
@@ -1191,7 +1191,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog, is_
caplog.clear()
mocker.patch(
'freqtrade.exchange.Exchange.stoploss',
'freqtrade.exchange.Exchange.create_stoploss',
side_effect=ExchangeError()
)
trade.is_open = True
@@ -1205,7 +1205,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog, is_
stoploss.reset_mock()
mocker.patch('freqtrade.exchange.Exchange.fetch_stoploss_order',
side_effect=InvalidOrderException())
mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss)
mocker.patch('freqtrade.exchange.Exchange.create_stoploss', stoploss)
freqtrade.handle_stoploss_on_exchange(trade)
assert stoploss.call_count == 1
@@ -1215,7 +1215,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog, is_
trade.is_open = False
stoploss.reset_mock()
mocker.patch('freqtrade.exchange.Exchange.fetch_order')
mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss)
mocker.patch('freqtrade.exchange.Exchange.create_stoploss', stoploss)
assert freqtrade.handle_stoploss_on_exchange(trade) is False
assert stoploss.call_count == 0
@@ -1240,7 +1240,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog, is_
mocker.patch('freqtrade.exchange.Exchange.cancel_stoploss_order_with_result',
side_effect=InvalidOrderException())
mocker.patch('freqtrade.exchange.Exchange.fetch_stoploss_order', stoploss_order_cancelled)
mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss)
mocker.patch('freqtrade.exchange.Exchange.create_stoploss', stoploss)
assert freqtrade.handle_stoploss_on_exchange(trade) is False
assert trade.stoploss_order_id is None
assert trade.is_open is False
@@ -1271,7 +1271,7 @@ def test_handle_sle_cancel_cant_recreate(mocker, default_conf_usdt, fee, caplog,
mocker.patch.multiple(
'freqtrade.exchange.Binance',
fetch_stoploss_order=MagicMock(return_value={'status': 'canceled', 'id': 100}),
stoploss=MagicMock(side_effect=ExchangeError()),
create_stoploss=MagicMock(side_effect=ExchangeError()),
)
freqtrade = FreqtradeBot(default_conf_usdt)
patch_get_signal(freqtrade, enter_short=is_short, enter_long=not is_short)
@@ -1315,7 +1315,7 @@ def test_create_stoploss_order_invalid_order(
mocker.patch.multiple(
'freqtrade.exchange.Binance',
fetch_order=MagicMock(return_value={'status': 'canceled'}),
stoploss=MagicMock(side_effect=InvalidOrderException()),
create_stoploss=MagicMock(side_effect=InvalidOrderException()),
)
freqtrade = FreqtradeBot(default_conf_usdt)
patch_get_signal(freqtrade, enter_short=is_short, enter_long=not is_short)
@@ -1367,7 +1367,7 @@ def test_create_stoploss_order_insufficient_funds(
)
mocker.patch.multiple(
'freqtrade.exchange.Binance',
stoploss=MagicMock(side_effect=InsufficientFundsError()),
create_stoploss=MagicMock(side_effect=InsufficientFundsError()),
)
patch_get_signal(freqtrade, enter_short=is_short, enter_long=not is_short)
freqtrade.strategy.order_types['stoploss_on_exchange'] = True
@@ -1417,7 +1417,7 @@ def test_handle_stoploss_on_exchange_trailing(
)
mocker.patch.multiple(
'freqtrade.exchange.Binance',
stoploss=stoploss,
create_stoploss=stoploss,
stoploss_adjust=MagicMock(return_value=True),
)
@@ -1478,7 +1478,7 @@ def test_handle_stoploss_on_exchange_trailing(
cancel_order_mock = MagicMock()
stoploss_order_mock = MagicMock(return_value={'id': 'so1'})
mocker.patch('freqtrade.exchange.Binance.cancel_stoploss_order', cancel_order_mock)
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss_order_mock)
mocker.patch('freqtrade.exchange.Binance.create_stoploss', stoploss_order_mock)
# stoploss should not be updated as the interval is 60 seconds
assert freqtrade.handle_trade(trade) is False
@@ -1542,7 +1542,7 @@ def test_handle_stoploss_on_exchange_trailing_error(
)
mocker.patch.multiple(
'freqtrade.exchange.Binance',
stoploss=stoploss,
create_stoploss=stoploss,
stoploss_adjust=MagicMock(return_value=True),
)
@@ -1593,7 +1593,7 @@ def test_handle_stoploss_on_exchange_trailing_error(
trade.stoploss_last_update = arrow.utcnow().shift(minutes=-601).datetime
caplog.clear()
cancel_mock = mocker.patch("freqtrade.exchange.Binance.cancel_stoploss_order", MagicMock())
mocker.patch("freqtrade.exchange.Binance.stoploss", side_effect=ExchangeError())
mocker.patch("freqtrade.exchange.Binance.create_stoploss", side_effect=ExchangeError())
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/USDT\..*", caplog)
@@ -1611,7 +1611,7 @@ def test_stoploss_on_exchange_price_rounding(
adjust_mock = MagicMock(return_value=False)
mocker.patch.multiple(
'freqtrade.exchange.Binance',
stoploss=stoploss_mock,
create_stoploss=stoploss_mock,
stoploss_adjust=adjust_mock,
price_to_precision=price_mock,
)
@@ -1650,7 +1650,7 @@ def test_handle_stoploss_on_exchange_custom_stop(
)
mocker.patch.multiple(
'freqtrade.exchange.Binance',
stoploss=stoploss,
create_stoploss=stoploss,
stoploss_adjust=MagicMock(return_value=True),
)
@@ -1710,7 +1710,7 @@ def test_handle_stoploss_on_exchange_custom_stop(
cancel_order_mock = MagicMock()
stoploss_order_mock = MagicMock(return_value={'id': 'so1'})
mocker.patch('freqtrade.exchange.Binance.cancel_stoploss_order', cancel_order_mock)
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss_order_mock)
mocker.patch('freqtrade.exchange.Binance.create_stoploss', stoploss_order_mock)
# stoploss should not be updated as the interval is 60 seconds
assert freqtrade.handle_trade(trade) is False
@@ -1775,7 +1775,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, limit_orde
{'id': exit_order['id']},
]),
get_fee=fee,
stoploss=stoploss,
create_stoploss=stoploss,
)
# enabling TSL
@@ -1827,7 +1827,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, limit_orde
cancel_order_mock = MagicMock()
stoploss_order_mock = MagicMock()
mocker.patch('freqtrade.exchange.Exchange.cancel_stoploss_order', cancel_order_mock)
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss_order_mock)
mocker.patch('freqtrade.exchange.Binance.create_stoploss', stoploss_order_mock)
# price goes down 5%
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={
@@ -3257,7 +3257,7 @@ def test_execute_trade_exit_up(default_conf_usdt, ticker_usdt, fee, ticker_usdt_
'freqtrade.exchange.Exchange',
fetch_ticker=ticker_usdt,
get_fee=fee,
_is_dry_limit_order_filled=MagicMock(return_value=False),
_dry_is_price_crossed=MagicMock(return_value=False),
)
patch_whitelist(mocker, default_conf_usdt)
freqtrade = FreqtradeBot(default_conf_usdt)
@@ -3340,7 +3340,7 @@ def test_execute_trade_exit_down(default_conf_usdt, ticker_usdt, fee, ticker_usd
'freqtrade.exchange.Exchange',
fetch_ticker=ticker_usdt,
get_fee=fee,
_is_dry_limit_order_filled=MagicMock(return_value=False),
_dry_is_price_crossed=MagicMock(return_value=False),
)
patch_whitelist(mocker, default_conf_usdt)
freqtrade = FreqtradeBot(default_conf_usdt)
@@ -3409,7 +3409,7 @@ def test_execute_trade_exit_custom_exit_price(
'freqtrade.exchange.Exchange',
fetch_ticker=ticker_usdt,
get_fee=fee,
_is_dry_limit_order_filled=MagicMock(return_value=False),
_dry_is_price_crossed=MagicMock(return_value=False),
)
config = deepcopy(default_conf_usdt)
config['custom_price_max_distance_ratio'] = 0.1
@@ -3490,7 +3490,7 @@ def test_execute_trade_exit_down_stoploss_on_exchange_dry_run(
'freqtrade.exchange.Exchange',
fetch_ticker=ticker_usdt,
get_fee=fee,
_is_dry_limit_order_filled=MagicMock(return_value=False),
_dry_is_price_crossed=MagicMock(return_value=False),
)
patch_whitelist(mocker, default_conf_usdt)
freqtrade = FreqtradeBot(default_conf_usdt)
@@ -3607,9 +3607,9 @@ def test_execute_trade_exit_with_stoploss_on_exchange(
get_fee=fee,
amount_to_precision=lambda s, x, y: y,
price_to_precision=lambda s, x, y: y,
stoploss=stoploss,
create_stoploss=stoploss,
cancel_stoploss_order=cancel_order,
_is_dry_limit_order_filled=MagicMock(side_effect=[True, False]),
_dry_is_price_crossed=MagicMock(side_effect=[True, False]),
)
freqtrade = FreqtradeBot(default_conf_usdt)
@@ -3658,7 +3658,7 @@ def test_may_execute_trade_exit_after_stoploss_on_exchange_hit(
get_fee=fee,
amount_to_precision=lambda s, x, y: y,
price_to_precision=lambda s, x, y: y,
_is_dry_limit_order_filled=MagicMock(side_effect=[False, True]),
_dry_is_price_crossed=MagicMock(side_effect=[False, True]),
)
stoploss = MagicMock(return_value={
@@ -3668,7 +3668,7 @@ def test_may_execute_trade_exit_after_stoploss_on_exchange_hit(
}
})
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss)
mocker.patch('freqtrade.exchange.Binance.create_stoploss', stoploss)
freqtrade = FreqtradeBot(default_conf_usdt)
freqtrade.strategy.order_types['stoploss_on_exchange'] = True
@@ -3753,7 +3753,7 @@ def test_execute_trade_exit_market_order(
'freqtrade.exchange.Exchange',
fetch_ticker=ticker_usdt,
get_fee=fee,
_is_dry_limit_order_filled=MagicMock(return_value=True),
_dry_is_price_crossed=MagicMock(return_value=True),
get_funding_fees=MagicMock(side_effect=ExchangeError()),
)
patch_whitelist(mocker, default_conf_usdt)
@@ -3771,7 +3771,7 @@ def test_execute_trade_exit_market_order(
mocker.patch.multiple(
'freqtrade.exchange.Exchange',
fetch_ticker=ticker_usdt_sell_up,
_is_dry_limit_order_filled=MagicMock(return_value=False),
_dry_is_price_crossed=MagicMock(return_value=False),
)
freqtrade.config['order_types']['exit'] = 'market'
@@ -3902,7 +3902,7 @@ def test_exit_profit_only(
if exit_type == ExitType.EXIT_SIGNAL.value:
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
else:
freqtrade.strategy.stop_loss_reached = MagicMock(return_value=ExitCheckTuple(
freqtrade.strategy.ft_stoploss_reached = MagicMock(return_value=ExitCheckTuple(
exit_type=ExitType.NONE))
freqtrade.enter_positions()
@@ -4283,7 +4283,7 @@ def test_disable_ignore_roi_if_entry_signal(default_conf_usdt, limit_order, limi
{'id': 1234553383}
]),
get_fee=fee,
_is_dry_limit_order_filled=MagicMock(return_value=False),
_dry_is_price_crossed=MagicMock(return_value=False),
)
default_conf_usdt['exit_pricing'] = {
'ignore_roi_if_entry_signal': False

View File

@@ -56,7 +56,7 @@ def test_may_execute_exit_stoploss_on_exchange_multi(default_conf, ticker, fee,
[ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL)]]
)
cancel_order_mock = MagicMock()
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss)
mocker.patch('freqtrade.exchange.Binance.create_stoploss', stoploss)
mocker.patch.multiple(
'freqtrade.exchange.Exchange',
fetch_ticker=ticker,
@@ -367,7 +367,7 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker)
amount_to_precision=lambda s, x, y: y,
price_to_precision=lambda s, x, y: y,
)
mocker.patch('freqtrade.exchange.Exchange._is_dry_limit_order_filled', return_value=False)
mocker.patch('freqtrade.exchange.Exchange._dry_is_price_crossed', return_value=False)
mocker.patch("freqtrade.exchange.Exchange.get_max_leverage", return_value=10)
mocker.patch("freqtrade.exchange.Exchange.get_funding_fees", return_value=0)
mocker.patch("freqtrade.exchange.Exchange.get_maintenance_ratio_and_amt", return_value=(0, 0))
@@ -413,7 +413,7 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker)
assert trade.initial_stop_loss_pct is None
# Fill order
mocker.patch('freqtrade.exchange.Exchange._is_dry_limit_order_filled', return_value=True)
mocker.patch('freqtrade.exchange.Exchange._dry_is_price_crossed', return_value=True)
freqtrade.process()
trade = Trade.get_trades().first()
assert len(trade.orders) == 2
@@ -428,7 +428,7 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker)
# 2nd order - not filling
freqtrade.strategy.adjust_trade_position = MagicMock(return_value=120)
mocker.patch('freqtrade.exchange.Exchange._is_dry_limit_order_filled', return_value=False)
mocker.patch('freqtrade.exchange.Exchange._dry_is_price_crossed', return_value=False)
freqtrade.process()
trade = Trade.get_trades().first()
@@ -452,7 +452,7 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker)
# Fill DCA order
freqtrade.strategy.adjust_trade_position = MagicMock(return_value=None)
mocker.patch('freqtrade.exchange.Exchange._is_dry_limit_order_filled', return_value=True)
mocker.patch('freqtrade.exchange.Exchange._dry_is_price_crossed', return_value=True)
freqtrade.strategy.adjust_entry_price = MagicMock(side_effect=ValueError)
freqtrade.process()