tests: further test cleanup
This commit is contained in:
@@ -253,92 +253,6 @@ def test_check_available_stake_amount(
|
|||||||
freqtrade.wallets.get_trade_stake_amount("ETH/USDT", 1)
|
freqtrade.wallets.get_trade_stake_amount("ETH/USDT", 1)
|
||||||
|
|
||||||
|
|
||||||
def test_edge_called_in_process(mocker, edge_conf) -> None:
|
|
||||||
patch_RPCManager(mocker)
|
|
||||||
patch_edge(mocker)
|
|
||||||
|
|
||||||
patch_exchange(mocker)
|
|
||||||
freqtrade = FreqtradeBot(edge_conf)
|
|
||||||
patch_get_signal(freqtrade)
|
|
||||||
freqtrade.process()
|
|
||||||
assert freqtrade.active_pair_whitelist == ["NEO/BTC", "LTC/BTC"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_edge_overrides_stake_amount(mocker, edge_conf) -> None:
|
|
||||||
patch_RPCManager(mocker)
|
|
||||||
patch_exchange(mocker)
|
|
||||||
patch_edge(mocker)
|
|
||||||
edge_conf["dry_run_wallet"] = 999.9
|
|
||||||
freqtrade = FreqtradeBot(edge_conf)
|
|
||||||
|
|
||||||
assert (
|
|
||||||
freqtrade.wallets.get_trade_stake_amount("NEO/BTC", 1, freqtrade.edge)
|
|
||||||
== (999.9 * 0.5 * 0.01) / 0.20
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
freqtrade.wallets.get_trade_stake_amount("LTC/BTC", 1, freqtrade.edge)
|
|
||||||
== (999.9 * 0.5 * 0.01) / 0.21
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"buy_price_mult,ignore_strat_sl",
|
|
||||||
[
|
|
||||||
(0.79, False), # Override stoploss
|
|
||||||
(0.85, True), # Override strategy stoploss
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_edge_overrides_stoploss(
|
|
||||||
limit_order, fee, caplog, mocker, buy_price_mult, ignore_strat_sl, edge_conf
|
|
||||||
) -> None:
|
|
||||||
patch_RPCManager(mocker)
|
|
||||||
patch_exchange(mocker)
|
|
||||||
patch_edge(mocker)
|
|
||||||
edge_conf["max_open_trades"] = float("inf")
|
|
||||||
|
|
||||||
# Strategy stoploss is -0.1 but Edge imposes a stoploss at -0.2
|
|
||||||
# Thus, if price falls 21%, stoploss should be triggered
|
|
||||||
#
|
|
||||||
# mocking the ticker: price is falling ...
|
|
||||||
enter_price = limit_order["buy"]["price"]
|
|
||||||
ticker_val = {
|
|
||||||
"bid": enter_price,
|
|
||||||
"ask": enter_price,
|
|
||||||
"last": enter_price,
|
|
||||||
}
|
|
||||||
mocker.patch.multiple(
|
|
||||||
EXMS,
|
|
||||||
fetch_ticker=MagicMock(return_value=ticker_val),
|
|
||||||
get_fee=fee,
|
|
||||||
)
|
|
||||||
#############################################
|
|
||||||
|
|
||||||
# Create a trade with "limit_buy_order_usdt" price
|
|
||||||
freqtrade = FreqtradeBot(edge_conf)
|
|
||||||
freqtrade.active_pair_whitelist = ["NEO/BTC"]
|
|
||||||
patch_get_signal(freqtrade)
|
|
||||||
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
|
|
||||||
freqtrade.enter_positions()
|
|
||||||
trade = Trade.session.scalars(select(Trade)).first()
|
|
||||||
caplog.clear()
|
|
||||||
#############################################
|
|
||||||
ticker_val.update(
|
|
||||||
{
|
|
||||||
"bid": enter_price * buy_price_mult,
|
|
||||||
"ask": enter_price * buy_price_mult,
|
|
||||||
"last": enter_price * buy_price_mult,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
# stoploss should be hit
|
|
||||||
assert freqtrade.handle_trade(trade) is not ignore_strat_sl
|
|
||||||
if not ignore_strat_sl:
|
|
||||||
assert log_has_re("Exit for NEO/BTC detected. Reason: stop_loss.*", caplog)
|
|
||||||
assert trade.exit_reason == ExitType.STOP_LOSS.value
|
|
||||||
# Test compatibility ...
|
|
||||||
assert trade.sell_reason == ExitType.STOP_LOSS.value
|
|
||||||
|
|
||||||
|
|
||||||
def test_total_open_trades_stakes(mocker, default_conf_usdt, ticker_usdt, fee) -> None:
|
def test_total_open_trades_stakes(mocker, default_conf_usdt, ticker_usdt, fee) -> None:
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
@@ -483,7 +397,7 @@ def test_create_trade_minimal_amount(
|
|||||||
if not max_open_trades:
|
if not max_open_trades:
|
||||||
assert (
|
assert (
|
||||||
freqtrade.wallets.get_trade_stake_amount(
|
freqtrade.wallets.get_trade_stake_amount(
|
||||||
"ETH/USDT", default_conf_usdt["max_open_trades"], freqtrade.edge
|
"ETH/USDT", default_conf_usdt["max_open_trades"]
|
||||||
)
|
)
|
||||||
== 0
|
== 0
|
||||||
)
|
)
|
||||||
@@ -4479,7 +4393,7 @@ def test_startup_state(default_conf_usdt, mocker):
|
|||||||
assert worker.freqtrade.state is State.RUNNING
|
assert worker.freqtrade.state is State.RUNNING
|
||||||
|
|
||||||
|
|
||||||
def test_startup_trade_reinit(default_conf_usdt, edge_conf, mocker):
|
def test_startup_trade_reinit(default_conf_usdt, mocker):
|
||||||
mocker.patch(f"{EXMS}.exchange_has", MagicMock(return_value=True))
|
mocker.patch(f"{EXMS}.exchange_has", MagicMock(return_value=True))
|
||||||
reinit_mock = MagicMock()
|
reinit_mock = MagicMock()
|
||||||
mocker.patch("freqtrade.persistence.Trade.stoploss_reinitialization", reinit_mock)
|
mocker.patch("freqtrade.persistence.Trade.stoploss_reinitialization", reinit_mock)
|
||||||
@@ -4488,12 +4402,6 @@ def test_startup_trade_reinit(default_conf_usdt, edge_conf, mocker):
|
|||||||
ftbot.startup()
|
ftbot.startup()
|
||||||
assert reinit_mock.call_count == 1
|
assert reinit_mock.call_count == 1
|
||||||
|
|
||||||
reinit_mock.reset_mock()
|
|
||||||
|
|
||||||
ftbot = get_patched_freqtradebot(mocker, edge_conf)
|
|
||||||
ftbot.startup()
|
|
||||||
assert reinit_mock.call_count == 0
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("init_persistence")
|
@pytest.mark.usefixtures("init_persistence")
|
||||||
def test_sync_wallet_dry_run(
|
def test_sync_wallet_dry_run(
|
||||||
|
|||||||
@@ -971,128 +971,6 @@ def test_handle_stoploss_on_exchange_custom_stop(
|
|||||||
assert freqtrade.handle_trade(trade) is True
|
assert freqtrade.handle_trade(trade) is True
|
||||||
|
|
||||||
|
|
||||||
def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, limit_order) -> None:
|
|
||||||
enter_order = limit_order["buy"]
|
|
||||||
exit_order = limit_order["sell"]
|
|
||||||
enter_order["average"] = 2.19
|
|
||||||
# When trailing stoploss is set
|
|
||||||
stoploss = MagicMock(return_value={"id": "13434334", "status": "open"})
|
|
||||||
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(
|
|
||||||
EXMS,
|
|
||||||
fetch_ticker=MagicMock(return_value={"bid": 2.19, "ask": 2.2, "last": 2.19}),
|
|
||||||
create_order=MagicMock(
|
|
||||||
side_effect=[
|
|
||||||
enter_order,
|
|
||||||
exit_order,
|
|
||||||
]
|
|
||||||
),
|
|
||||||
get_fee=fee,
|
|
||||||
create_stoploss=stoploss,
|
|
||||||
)
|
|
||||||
|
|
||||||
# enabling TSL
|
|
||||||
edge_conf["trailing_stop"] = True
|
|
||||||
edge_conf["trailing_stop_positive"] = 0.01
|
|
||||||
edge_conf["trailing_stop_positive_offset"] = 0.011
|
|
||||||
|
|
||||||
# disabling ROI
|
|
||||||
edge_conf["minimal_roi"]["0"] = 999999999
|
|
||||||
|
|
||||||
freqtrade = FreqtradeBot(edge_conf)
|
|
||||||
|
|
||||||
# enabling stoploss on exchange
|
|
||||||
freqtrade.strategy.order_types["stoploss_on_exchange"] = True
|
|
||||||
|
|
||||||
# setting stoploss
|
|
||||||
freqtrade.strategy.stoploss = -0.02
|
|
||||||
|
|
||||||
# setting stoploss_on_exchange_interval to 0 seconds
|
|
||||||
freqtrade.strategy.order_types["stoploss_on_exchange_interval"] = 0
|
|
||||||
|
|
||||||
patch_get_signal(freqtrade)
|
|
||||||
|
|
||||||
freqtrade.active_pair_whitelist = freqtrade.edge.adjust(freqtrade.active_pair_whitelist)
|
|
||||||
|
|
||||||
freqtrade.enter_positions()
|
|
||||||
trade = Trade.session.scalars(select(Trade)).first()
|
|
||||||
trade.is_open = True
|
|
||||||
|
|
||||||
trade.stoploss_last_update = dt_now()
|
|
||||||
trade.orders.append(
|
|
||||||
Order(
|
|
||||||
ft_order_side="stoploss",
|
|
||||||
ft_pair=trade.pair,
|
|
||||||
ft_is_open=True,
|
|
||||||
ft_amount=trade.amount,
|
|
||||||
ft_price=trade.stop_loss,
|
|
||||||
order_id="100",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
stoploss_order_hanging = MagicMock(
|
|
||||||
return_value={
|
|
||||||
"id": "100",
|
|
||||||
"status": "open",
|
|
||||||
"type": "stop_loss_limit",
|
|
||||||
"price": 3,
|
|
||||||
"average": 2,
|
|
||||||
"stopPrice": "2.178",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
mocker.patch(f"{EXMS}.fetch_stoploss_order", stoploss_order_hanging)
|
|
||||||
|
|
||||||
# stoploss initially at 20% as edge dictated it.
|
|
||||||
assert freqtrade.handle_trade(trade) is False
|
|
||||||
assert freqtrade.handle_stoploss_on_exchange(trade) is False
|
|
||||||
assert pytest.approx(trade.stop_loss) == 1.76
|
|
||||||
|
|
||||||
cancel_order_mock = MagicMock()
|
|
||||||
stoploss_order_mock = MagicMock()
|
|
||||||
mocker.patch(f"{EXMS}.cancel_stoploss_order", cancel_order_mock)
|
|
||||||
mocker.patch(f"{EXMS}.create_stoploss", stoploss_order_mock)
|
|
||||||
|
|
||||||
# price goes down 5%
|
|
||||||
mocker.patch(
|
|
||||||
f"{EXMS}.fetch_ticker",
|
|
||||||
MagicMock(return_value={"bid": 2.19 * 0.95, "ask": 2.2 * 0.95, "last": 2.19 * 0.95}),
|
|
||||||
)
|
|
||||||
assert freqtrade.handle_trade(trade) is False
|
|
||||||
assert freqtrade.handle_stoploss_on_exchange(trade) is False
|
|
||||||
|
|
||||||
# stoploss should remain the same
|
|
||||||
assert pytest.approx(trade.stop_loss) == 1.76
|
|
||||||
|
|
||||||
# stoploss on exchange should not be canceled
|
|
||||||
cancel_order_mock.assert_not_called()
|
|
||||||
|
|
||||||
# price jumped 2x
|
|
||||||
mocker.patch(
|
|
||||||
f"{EXMS}.fetch_ticker", MagicMock(return_value={"bid": 4.38, "ask": 4.4, "last": 4.38})
|
|
||||||
)
|
|
||||||
|
|
||||||
assert freqtrade.handle_trade(trade) is False
|
|
||||||
assert freqtrade.handle_stoploss_on_exchange(trade) is False
|
|
||||||
|
|
||||||
# stoploss should be set to 1% as trailing is on
|
|
||||||
assert trade.stop_loss == 4.4 * 0.99
|
|
||||||
cancel_order_mock.assert_called_once_with("100", "NEO/BTC")
|
|
||||||
stoploss_order_mock.assert_called_once_with(
|
|
||||||
amount=30,
|
|
||||||
pair="NEO/BTC",
|
|
||||||
order_types=freqtrade.strategy.order_types,
|
|
||||||
stop_price=4.4 * 0.99,
|
|
||||||
side="sell",
|
|
||||||
leverage=1.0,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("is_short", [False, True])
|
@pytest.mark.parametrize("is_short", [False, True])
|
||||||
def test_execute_trade_exit_down_stoploss_on_exchange_dry_run(
|
def test_execute_trade_exit_down_stoploss_on_exchange_dry_run(
|
||||||
default_conf_usdt,
|
default_conf_usdt,
|
||||||
|
|||||||
@@ -1,133 +0,0 @@
|
|||||||
# pragma pylint: disable=missing-docstring, C0103, C0330
|
|
||||||
# pragma pylint: disable=protected-access, too-many-lines, invalid-name, too-many-arguments
|
|
||||||
|
|
||||||
from unittest.mock import MagicMock
|
|
||||||
|
|
||||||
from freqtrade.commands.optimize_commands import setup_optimize_configuration, start_edge
|
|
||||||
from freqtrade.enums import RunMode
|
|
||||||
from freqtrade.optimize.edge_cli import EdgeCli
|
|
||||||
from tests.conftest import (
|
|
||||||
CURRENT_TEST_STRATEGY,
|
|
||||||
EXMS,
|
|
||||||
get_args,
|
|
||||||
log_has,
|
|
||||||
patch_exchange,
|
|
||||||
patched_configuration_load_config_file,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_setup_optimize_configuration_without_arguments(mocker, default_conf, caplog) -> None:
|
|
||||||
patched_configuration_load_config_file(mocker, default_conf)
|
|
||||||
|
|
||||||
args = [
|
|
||||||
"edge",
|
|
||||||
"--config",
|
|
||||||
"config.json",
|
|
||||||
"--strategy",
|
|
||||||
CURRENT_TEST_STRATEGY,
|
|
||||||
]
|
|
||||||
|
|
||||||
config = setup_optimize_configuration(get_args(args), RunMode.EDGE)
|
|
||||||
assert config["runmode"] == RunMode.EDGE
|
|
||||||
|
|
||||||
assert "max_open_trades" in config
|
|
||||||
assert "stake_currency" in config
|
|
||||||
assert "stake_amount" in config
|
|
||||||
assert "exchange" in config
|
|
||||||
assert "pair_whitelist" in config["exchange"]
|
|
||||||
assert "datadir" in config
|
|
||||||
assert log_has("Using data directory: {} ...".format(config["datadir"]), caplog)
|
|
||||||
assert "timeframe" in config
|
|
||||||
|
|
||||||
assert "timerange" not in config
|
|
||||||
assert "stoploss_range" not in config
|
|
||||||
|
|
||||||
|
|
||||||
def test_setup_edge_configuration_with_arguments(mocker, edge_conf, caplog) -> None:
|
|
||||||
patched_configuration_load_config_file(mocker, edge_conf)
|
|
||||||
mocker.patch("freqtrade.configuration.configuration.create_datadir", lambda c, x: x)
|
|
||||||
|
|
||||||
args = [
|
|
||||||
"edge",
|
|
||||||
"--config",
|
|
||||||
"config.json",
|
|
||||||
"--strategy",
|
|
||||||
CURRENT_TEST_STRATEGY,
|
|
||||||
"--datadir",
|
|
||||||
"/foo/bar",
|
|
||||||
"--timeframe",
|
|
||||||
"1m",
|
|
||||||
"--timerange",
|
|
||||||
":100",
|
|
||||||
"--stoplosses=-0.01,-0.10,-0.001",
|
|
||||||
]
|
|
||||||
|
|
||||||
config = setup_optimize_configuration(get_args(args), RunMode.EDGE)
|
|
||||||
assert "max_open_trades" in config
|
|
||||||
assert "stake_currency" in config
|
|
||||||
assert "stake_amount" in config
|
|
||||||
assert "exchange" in config
|
|
||||||
assert "pair_whitelist" in config["exchange"]
|
|
||||||
assert "datadir" in config
|
|
||||||
assert config["runmode"] == RunMode.EDGE
|
|
||||||
assert log_has("Using data directory: {} ...".format(config["datadir"]), caplog)
|
|
||||||
assert "timeframe" in config
|
|
||||||
assert log_has("Parameter -i/--timeframe detected ... Using timeframe: 1m ...", caplog)
|
|
||||||
|
|
||||||
assert "timerange" in config
|
|
||||||
assert log_has("Parameter --timerange detected: {} ...".format(config["timerange"]), caplog)
|
|
||||||
|
|
||||||
|
|
||||||
def test_start(mocker, fee, edge_conf, caplog) -> None:
|
|
||||||
start_mock = MagicMock()
|
|
||||||
mocker.patch(f"{EXMS}.get_fee", fee)
|
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch("freqtrade.optimize.edge_cli.EdgeCli.start", start_mock)
|
|
||||||
patched_configuration_load_config_file(mocker, edge_conf)
|
|
||||||
|
|
||||||
args = [
|
|
||||||
"edge",
|
|
||||||
"--config",
|
|
||||||
"config.json",
|
|
||||||
"--strategy",
|
|
||||||
CURRENT_TEST_STRATEGY,
|
|
||||||
]
|
|
||||||
pargs = get_args(args)
|
|
||||||
start_edge(pargs)
|
|
||||||
assert log_has("Starting freqtrade in Edge mode", caplog)
|
|
||||||
assert start_mock.call_count == 1
|
|
||||||
|
|
||||||
|
|
||||||
def test_edge_init(mocker, edge_conf) -> None:
|
|
||||||
patch_exchange(mocker)
|
|
||||||
edge_conf["stake_amount"] = 20
|
|
||||||
edge_cli = EdgeCli(edge_conf)
|
|
||||||
assert edge_cli.config == edge_conf
|
|
||||||
assert edge_cli.config["stake_amount"] == "unlimited"
|
|
||||||
assert callable(edge_cli.edge.calculate)
|
|
||||||
assert edge_cli.strategy.bot_started is True
|
|
||||||
|
|
||||||
|
|
||||||
def test_edge_init_fee(mocker, edge_conf) -> None:
|
|
||||||
patch_exchange(mocker)
|
|
||||||
edge_conf["fee"] = 0.01234
|
|
||||||
edge_conf["stake_amount"] = 20
|
|
||||||
fee_mock = mocker.patch(f"{EXMS}.get_fee", return_value=0.5)
|
|
||||||
edge_cli = EdgeCli(edge_conf)
|
|
||||||
assert edge_cli.edge.fee == 0.01234
|
|
||||||
assert fee_mock.call_count == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_edge_start(mocker, edge_conf) -> None:
|
|
||||||
mock_calculate = mocker.patch(
|
|
||||||
"freqtrade.edge.edge_positioning.Edge.calculate", return_value=True
|
|
||||||
)
|
|
||||||
table_mock = mocker.patch("freqtrade.optimize.edge_cli.generate_edge_table")
|
|
||||||
|
|
||||||
patch_exchange(mocker)
|
|
||||||
edge_conf["stake_amount"] = 20
|
|
||||||
|
|
||||||
edge_cli = EdgeCli(edge_conf)
|
|
||||||
edge_cli.start()
|
|
||||||
assert mock_calculate.call_count == 1
|
|
||||||
assert table_mock.call_count == 1
|
|
||||||
Reference in New Issue
Block a user