Merge branch 'develop' into partial_sell2
This commit is contained in:
@@ -826,8 +826,9 @@ def test_download_data_trades(mocker, caplog):
|
||||
]
|
||||
with pytest.raises(OperationalException,
|
||||
match="Trade download not supported for futures."):
|
||||
|
||||
start_download_data(get_args(args))
|
||||
pargs = get_args(args)
|
||||
pargs['config'] = None
|
||||
start_download_data(pargs)
|
||||
|
||||
|
||||
def test_start_convert_trades(mocker, caplog):
|
||||
|
||||
@@ -87,7 +87,7 @@ def get_mock_coro(return_value):
|
||||
|
||||
def patched_configuration_load_config_file(mocker, config) -> None:
|
||||
mocker.patch(
|
||||
'freqtrade.configuration.configuration.load_config_file',
|
||||
'freqtrade.configuration.load_config.load_config_file',
|
||||
lambda *args, **kwargs: config
|
||||
)
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ from freqtrade.persistence.models import Order, Trade
|
||||
MOCK_TRADE_COUNT = 6
|
||||
|
||||
|
||||
def enter_side(is_short: bool):
|
||||
def entry_side(is_short: bool):
|
||||
return "sell" if is_short else "buy"
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ def mock_order_1(is_short: bool):
|
||||
'id': f'1234_{direc(is_short)}',
|
||||
'symbol': 'ETH/BTC',
|
||||
'status': 'closed',
|
||||
'side': enter_side(is_short),
|
||||
'side': entry_side(is_short),
|
||||
'type': 'limit',
|
||||
'price': 0.123,
|
||||
'average': 0.123,
|
||||
@@ -50,7 +50,7 @@ def mock_trade_1(fee, is_short: bool):
|
||||
timeframe=5,
|
||||
is_short=is_short
|
||||
)
|
||||
o = Order.parse_from_ccxt_object(mock_order_1(is_short), 'ETH/BTC', enter_side(is_short))
|
||||
o = Order.parse_from_ccxt_object(mock_order_1(is_short), 'ETH/BTC', entry_side(is_short))
|
||||
trade.orders.append(o)
|
||||
return trade
|
||||
|
||||
@@ -60,7 +60,7 @@ def mock_order_2(is_short: bool):
|
||||
'id': f'1235_{direc(is_short)}',
|
||||
'symbol': 'ETC/BTC',
|
||||
'status': 'closed',
|
||||
'side': enter_side(is_short),
|
||||
'side': entry_side(is_short),
|
||||
'type': 'limit',
|
||||
'price': 0.123,
|
||||
'amount': 123.0,
|
||||
@@ -109,7 +109,7 @@ def mock_trade_2(fee, is_short: bool):
|
||||
close_date=datetime.now(tz=timezone.utc) - timedelta(minutes=2),
|
||||
is_short=is_short
|
||||
)
|
||||
o = Order.parse_from_ccxt_object(mock_order_2(is_short), 'ETC/BTC', enter_side(is_short))
|
||||
o = Order.parse_from_ccxt_object(mock_order_2(is_short), 'ETC/BTC', entry_side(is_short))
|
||||
trade.orders.append(o)
|
||||
o = Order.parse_from_ccxt_object(mock_order_2_sell(is_short), 'ETC/BTC', exit_side(is_short))
|
||||
trade.orders.append(o)
|
||||
@@ -121,7 +121,7 @@ def mock_order_3(is_short: bool):
|
||||
'id': f'41231a12a_{direc(is_short)}',
|
||||
'symbol': 'XRP/BTC',
|
||||
'status': 'closed',
|
||||
'side': enter_side(is_short),
|
||||
'side': entry_side(is_short),
|
||||
'type': 'limit',
|
||||
'price': 0.05,
|
||||
'amount': 123.0,
|
||||
@@ -169,7 +169,7 @@ def mock_trade_3(fee, is_short: bool):
|
||||
close_date=datetime.now(tz=timezone.utc),
|
||||
is_short=is_short
|
||||
)
|
||||
o = Order.parse_from_ccxt_object(mock_order_3(is_short), 'XRP/BTC', enter_side(is_short))
|
||||
o = Order.parse_from_ccxt_object(mock_order_3(is_short), 'XRP/BTC', entry_side(is_short))
|
||||
trade.orders.append(o)
|
||||
o = Order.parse_from_ccxt_object(mock_order_3_sell(is_short), 'XRP/BTC', exit_side(is_short))
|
||||
trade.orders.append(o)
|
||||
@@ -181,7 +181,7 @@ def mock_order_4(is_short: bool):
|
||||
'id': f'prod_buy_{direc(is_short)}_12345',
|
||||
'symbol': 'ETC/BTC',
|
||||
'status': 'open',
|
||||
'side': enter_side(is_short),
|
||||
'side': entry_side(is_short),
|
||||
'type': 'limit',
|
||||
'price': 0.123,
|
||||
'amount': 123.0,
|
||||
@@ -210,7 +210,7 @@ def mock_trade_4(fee, is_short: bool):
|
||||
timeframe=5,
|
||||
is_short=is_short
|
||||
)
|
||||
o = Order.parse_from_ccxt_object(mock_order_4(is_short), 'ETC/BTC', enter_side(is_short))
|
||||
o = Order.parse_from_ccxt_object(mock_order_4(is_short), 'ETC/BTC', entry_side(is_short))
|
||||
trade.orders.append(o)
|
||||
return trade
|
||||
|
||||
@@ -220,7 +220,7 @@ def mock_order_5(is_short: bool):
|
||||
'id': f'prod_buy_{direc(is_short)}_3455',
|
||||
'symbol': 'XRP/BTC',
|
||||
'status': 'closed',
|
||||
'side': enter_side(is_short),
|
||||
'side': entry_side(is_short),
|
||||
'type': 'limit',
|
||||
'price': 0.123,
|
||||
'amount': 123.0,
|
||||
@@ -264,7 +264,7 @@ def mock_trade_5(fee, is_short: bool):
|
||||
timeframe=5,
|
||||
is_short=is_short
|
||||
)
|
||||
o = Order.parse_from_ccxt_object(mock_order_5(is_short), 'XRP/BTC', enter_side(is_short))
|
||||
o = Order.parse_from_ccxt_object(mock_order_5(is_short), 'XRP/BTC', entry_side(is_short))
|
||||
trade.orders.append(o)
|
||||
o = Order.parse_from_ccxt_object(mock_order_5_stoploss(is_short), 'XRP/BTC', 'stoploss')
|
||||
trade.orders.append(o)
|
||||
@@ -276,7 +276,7 @@ def mock_order_6(is_short: bool):
|
||||
'id': f'prod_buy_{direc(is_short)}_6',
|
||||
'symbol': 'LTC/BTC',
|
||||
'status': 'closed',
|
||||
'side': enter_side(is_short),
|
||||
'side': entry_side(is_short),
|
||||
'type': 'limit',
|
||||
'price': 0.15,
|
||||
'amount': 2.0,
|
||||
@@ -320,7 +320,7 @@ def mock_trade_6(fee, is_short: bool):
|
||||
timeframe=5,
|
||||
is_short=is_short
|
||||
)
|
||||
o = Order.parse_from_ccxt_object(mock_order_6(is_short), 'LTC/BTC', enter_side(is_short))
|
||||
o = Order.parse_from_ccxt_object(mock_order_6(is_short), 'LTC/BTC', entry_side(is_short))
|
||||
trade.orders.append(o)
|
||||
o = Order.parse_from_ccxt_object(mock_order_6_sell(is_short), 'LTC/BTC', exit_side(is_short))
|
||||
trade.orders.append(o)
|
||||
|
||||
@@ -821,7 +821,7 @@ def test_backtest_results(default_conf, fee, mocker, caplog, data: BTContainer)
|
||||
if data.trailing_stop_positive is not None:
|
||||
default_conf["trailing_stop_positive"] = data.trailing_stop_positive
|
||||
default_conf["trailing_stop_positive_offset"] = data.trailing_stop_positive_offset
|
||||
default_conf["use_sell_signal"] = data.use_exit_signal
|
||||
default_conf["use_exit_signal"] = data.use_exit_signal
|
||||
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_fee", return_value=0.0)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
|
||||
@@ -504,7 +504,7 @@ def test_backtesting_pairlist_list(default_conf, mocker, caplog, testdatadir, ti
|
||||
|
||||
|
||||
def test_backtest__enter_trade(default_conf, fee, mocker) -> None:
|
||||
default_conf['use_sell_signal'] = False
|
||||
default_conf['use_exit_signal'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
@@ -563,7 +563,7 @@ def test_backtest__enter_trade(default_conf, fee, mocker) -> None:
|
||||
|
||||
|
||||
def test_backtest__enter_trade_futures(default_conf_usdt, fee, mocker) -> None:
|
||||
default_conf_usdt['use_sell_signal'] = False
|
||||
default_conf_usdt['use_exit_signal'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
@@ -645,7 +645,7 @@ def test_backtest__enter_trade_futures(default_conf_usdt, fee, mocker) -> None:
|
||||
|
||||
|
||||
def test_backtest__get_sell_trade_entry(default_conf, fee, mocker) -> None:
|
||||
default_conf['use_sell_signal'] = False
|
||||
default_conf['use_exit_signal'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
@@ -741,7 +741,7 @@ def test_backtest__get_sell_trade_entry(default_conf, fee, mocker) -> None:
|
||||
|
||||
|
||||
def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None:
|
||||
default_conf['use_sell_signal'] = False
|
||||
default_conf['use_exit_signal'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
@@ -808,7 +808,7 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None:
|
||||
|
||||
|
||||
def test_backtest_1min_timeframe(default_conf, fee, mocker, testdatadir) -> None:
|
||||
default_conf['use_sell_signal'] = False
|
||||
default_conf['use_exit_signal'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
@@ -834,7 +834,7 @@ def test_backtest_1min_timeframe(default_conf, fee, mocker, testdatadir) -> None
|
||||
|
||||
|
||||
def test_backtest_trim_no_data_left(default_conf, fee, mocker, testdatadir) -> None:
|
||||
default_conf['use_sell_signal'] = False
|
||||
default_conf['use_exit_signal'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
@@ -879,7 +879,7 @@ def test_processed(default_conf, mocker, testdatadir) -> None:
|
||||
|
||||
|
||||
def test_backtest_dataprovider_analyzed_df(default_conf, fee, mocker, testdatadir) -> None:
|
||||
default_conf['use_sell_signal'] = False
|
||||
default_conf['use_exit_signal'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=100000)
|
||||
@@ -1152,10 +1152,10 @@ def test_backtest_start_timerange(default_conf, mocker, caplog, testdatadir):
|
||||
def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir):
|
||||
|
||||
default_conf.update({
|
||||
"use_sell_signal": True,
|
||||
"sell_profit_only": False,
|
||||
"sell_profit_offset": 0.0,
|
||||
"ignore_roi_if_buy_signal": False,
|
||||
"use_exit_signal": True,
|
||||
"exit_profit_only": False,
|
||||
"exit_profit_offset": 0.0,
|
||||
"ignore_roi_if_entry_signal": False,
|
||||
})
|
||||
patch_exchange(mocker)
|
||||
backtestmock = MagicMock(return_value={
|
||||
@@ -1229,10 +1229,10 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir):
|
||||
@pytest.mark.filterwarnings("ignore:deprecated")
|
||||
def test_backtest_start_multi_strat_nomock(default_conf, mocker, caplog, testdatadir, capsys):
|
||||
default_conf.update({
|
||||
"use_sell_signal": True,
|
||||
"sell_profit_only": False,
|
||||
"sell_profit_offset": 0.0,
|
||||
"ignore_roi_if_buy_signal": False,
|
||||
"use_exit_signal": True,
|
||||
"exit_profit_only": False,
|
||||
"exit_profit_offset": 0.0,
|
||||
"ignore_roi_if_entry_signal": False,
|
||||
})
|
||||
patch_exchange(mocker)
|
||||
result1 = pd.DataFrame({'pair': ['XRP/BTC', 'LTC/BTC'],
|
||||
@@ -1347,10 +1347,10 @@ def test_backtest_start_nomock_futures(default_conf_usdt, mocker,
|
||||
default_conf_usdt.update({
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"use_sell_signal": True,
|
||||
"sell_profit_only": False,
|
||||
"sell_profit_offset": 0.0,
|
||||
"ignore_roi_if_buy_signal": False,
|
||||
"use_exit_signal": True,
|
||||
"exit_profit_only": False,
|
||||
"exit_profit_offset": 0.0,
|
||||
"ignore_roi_if_entry_signal": False,
|
||||
"strategy": CURRENT_TEST_STRATEGY,
|
||||
})
|
||||
patch_exchange(mocker)
|
||||
@@ -1451,10 +1451,10 @@ def test_backtest_start_multi_strat_nomock_detail(default_conf, mocker,
|
||||
caplog, testdatadir, capsys):
|
||||
# Tests detail-data loading
|
||||
default_conf.update({
|
||||
"use_sell_signal": True,
|
||||
"sell_profit_only": False,
|
||||
"sell_profit_offset": 0.0,
|
||||
"ignore_roi_if_buy_signal": False,
|
||||
"use_exit_signal": True,
|
||||
"exit_profit_only": False,
|
||||
"exit_profit_offset": 0.0,
|
||||
"ignore_roi_if_entry_signal": False,
|
||||
})
|
||||
patch_exchange(mocker)
|
||||
result1 = pd.DataFrame({'pair': ['XRP/BTC', 'LTC/BTC'],
|
||||
@@ -1558,10 +1558,10 @@ def test_backtest_start_multi_strat_nomock_detail(default_conf, mocker,
|
||||
def test_backtest_start_multi_strat_caching(default_conf, mocker, caplog, testdatadir, run_id,
|
||||
start_delta, cache):
|
||||
default_conf.update({
|
||||
"use_sell_signal": True,
|
||||
"sell_profit_only": False,
|
||||
"sell_profit_offset": 0.0,
|
||||
"ignore_roi_if_buy_signal": False,
|
||||
"use_exit_signal": True,
|
||||
"exit_profit_only": False,
|
||||
"exit_profit_offset": 0.0,
|
||||
"ignore_roi_if_entry_signal": False,
|
||||
})
|
||||
patch_exchange(mocker)
|
||||
backtestmock = MagicMock(return_value={
|
||||
|
||||
@@ -14,7 +14,7 @@ from tests.conftest import patch_exchange
|
||||
|
||||
|
||||
def test_backtest_position_adjustment(default_conf, fee, mocker, testdatadir) -> None:
|
||||
default_conf['use_sell_signal'] = False
|
||||
default_conf['use_exit_signal'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
|
||||
@@ -779,7 +779,7 @@ def test_rpc_stopbuy(mocker, default_conf) -> None:
|
||||
assert freqtradebot.config['max_open_trades'] == 0
|
||||
|
||||
|
||||
def test_rpc_forceexit(default_conf, ticker, fee, mocker) -> None:
|
||||
def test_rpc_force_exit(default_conf, ticker, fee, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
|
||||
cancel_order_mock = MagicMock()
|
||||
@@ -806,29 +806,29 @@ def test_rpc_forceexit(default_conf, ticker, fee, mocker) -> None:
|
||||
|
||||
freqtradebot.state = State.STOPPED
|
||||
with pytest.raises(RPCException, match=r'.*trader is not running*'):
|
||||
rpc._rpc_forceexit(None)
|
||||
rpc._rpc_force_exit(None)
|
||||
|
||||
freqtradebot.state = State.RUNNING
|
||||
with pytest.raises(RPCException, match=r'.*invalid argument*'):
|
||||
rpc._rpc_forceexit(None)
|
||||
rpc._rpc_force_exit(None)
|
||||
|
||||
msg = rpc._rpc_forceexit('all')
|
||||
msg = rpc._rpc_force_exit('all')
|
||||
assert msg == {'result': 'Created sell orders for all open trades.'}
|
||||
|
||||
freqtradebot.enter_positions()
|
||||
msg = rpc._rpc_forceexit('all')
|
||||
msg = rpc._rpc_force_exit('all')
|
||||
assert msg == {'result': 'Created sell orders for all open trades.'}
|
||||
|
||||
freqtradebot.enter_positions()
|
||||
msg = rpc._rpc_forceexit('2')
|
||||
msg = rpc._rpc_force_exit('2')
|
||||
assert msg == {'result': 'Created sell order for trade 2.'}
|
||||
|
||||
freqtradebot.state = State.STOPPED
|
||||
with pytest.raises(RPCException, match=r'.*trader is not running*'):
|
||||
rpc._rpc_forceexit(None)
|
||||
rpc._rpc_force_exit(None)
|
||||
|
||||
with pytest.raises(RPCException, match=r'.*trader is not running*'):
|
||||
rpc._rpc_forceexit('all')
|
||||
rpc._rpc_force_exit('all')
|
||||
|
||||
freqtradebot.state = State.RUNNING
|
||||
assert cancel_order_mock.call_count == 0
|
||||
@@ -857,7 +857,7 @@ def test_rpc_forceexit(default_conf, ticker, fee, mocker) -> None:
|
||||
)
|
||||
# check that the trade is called, which is done by ensuring exchange.cancel_order is called
|
||||
# and trade amount is updated
|
||||
rpc._rpc_forceexit('3')
|
||||
rpc._rpc_force_exit('3')
|
||||
assert cancel_order_mock.call_count == 1
|
||||
assert trade.amount == filled_amount
|
||||
|
||||
@@ -885,7 +885,7 @@ def test_rpc_forceexit(default_conf, ticker, fee, mocker) -> None:
|
||||
}
|
||||
)
|
||||
# check that the trade is called, which is done by ensuring exchange.cancel_order is called
|
||||
msg = rpc._rpc_forceexit('4')
|
||||
msg = rpc._rpc_force_exit('4')
|
||||
assert msg == {'result': 'Created sell order for trade 4.'}
|
||||
assert cancel_order_mock.call_count == 2
|
||||
assert trade.amount == amount
|
||||
@@ -903,7 +903,7 @@ def test_rpc_forceexit(default_conf, ticker, fee, mocker) -> None:
|
||||
'id': trade.orders[0].order_id
|
||||
}
|
||||
)
|
||||
msg = rpc._rpc_forceexit('3')
|
||||
msg = rpc._rpc_force_exit('3')
|
||||
assert msg == {'result': 'Created sell order for trade 3.'}
|
||||
# status quo, no exchange calls
|
||||
assert cancel_order_mock.call_count == 3
|
||||
@@ -1195,8 +1195,8 @@ def test_rpc_count(mocker, default_conf, ticker, fee) -> None:
|
||||
assert counts["current"] == 1
|
||||
|
||||
|
||||
def test_rpc_forceentry(mocker, default_conf, ticker, fee, limit_buy_order_open) -> None:
|
||||
default_conf['forcebuy_enable'] = True
|
||||
def test_rpc_force_entry(mocker, default_conf, ticker, fee, limit_buy_order_open) -> None:
|
||||
default_conf['force_entry_enable'] = True
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
buy_mm = MagicMock(return_value=limit_buy_order_open)
|
||||
mocker.patch.multiple(
|
||||
@@ -1234,7 +1234,7 @@ def test_rpc_forceentry(mocker, default_conf, ticker, fee, limit_buy_order_open)
|
||||
pair = 'LTC/BTC'
|
||||
trade = rpc._rpc_force_entry(pair, 0.0001, order_type='limit', stake_amount=0.05)
|
||||
assert trade.stake_amount == 0.05
|
||||
assert trade.buy_tag == 'forceentry'
|
||||
assert trade.buy_tag == 'force_entry'
|
||||
|
||||
# Test not buying
|
||||
pair = 'XRP/BTC'
|
||||
@@ -1243,12 +1243,12 @@ def test_rpc_forceentry(mocker, default_conf, ticker, fee, limit_buy_order_open)
|
||||
patch_get_signal(freqtradebot)
|
||||
rpc = RPC(freqtradebot)
|
||||
pair = 'TKN/BTC'
|
||||
trade = rpc._rpc_force_entry(pair, None)
|
||||
assert trade is None
|
||||
with pytest.raises(RPCException, match=r"Failed to enter position for TKN/BTC."):
|
||||
trade = rpc._rpc_force_entry(pair, None)
|
||||
|
||||
|
||||
def test_rpc_forceentry_stopped(mocker, default_conf) -> None:
|
||||
default_conf['forcebuy_enable'] = True
|
||||
def test_rpc_force_entry_stopped(mocker, default_conf) -> None:
|
||||
default_conf['force_entry_enable'] = True
|
||||
default_conf['initial_state'] = 'stopped'
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
|
||||
@@ -1260,19 +1260,19 @@ def test_rpc_forceentry_stopped(mocker, default_conf) -> None:
|
||||
rpc._rpc_force_entry(pair, None)
|
||||
|
||||
|
||||
def test_rpc_forceentry_disabled(mocker, default_conf) -> None:
|
||||
def test_rpc_force_entry_disabled(mocker, default_conf) -> None:
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
|
||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||
patch_get_signal(freqtradebot)
|
||||
rpc = RPC(freqtradebot)
|
||||
pair = 'ETH/BTC'
|
||||
with pytest.raises(RPCException, match=r'Forceentry not enabled.'):
|
||||
with pytest.raises(RPCException, match=r'Force_entry not enabled.'):
|
||||
rpc._rpc_force_entry(pair, None)
|
||||
|
||||
|
||||
def test_rpc_forceentry_wrong_mode(mocker, default_conf) -> None:
|
||||
default_conf['forcebuy_enable'] = True
|
||||
def test_rpc_force_entry_wrong_mode(mocker, default_conf) -> None:
|
||||
default_conf['force_entry_enable'] = True
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
|
||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||
|
||||
@@ -1077,16 +1077,16 @@ def test_api_whitelist(botclient):
|
||||
'forcebuy',
|
||||
'forceenter',
|
||||
])
|
||||
def test_api_forceentry(botclient, mocker, fee, endpoint):
|
||||
def test_api_force_entry(botclient, mocker, fee, endpoint):
|
||||
ftbot, client = botclient
|
||||
|
||||
rc = client_post(client, f"{BASE_URI}/{endpoint}",
|
||||
data='{"pair": "ETH/BTC"}')
|
||||
assert_response(rc, 502)
|
||||
assert rc.json() == {"error": f"Error querying /api/v1/{endpoint}: Forceentry not enabled."}
|
||||
assert rc.json() == {"error": f"Error querying /api/v1/{endpoint}: Force_entry not enabled."}
|
||||
|
||||
# enable forcebuy
|
||||
ftbot.config['forcebuy_enable'] = True
|
||||
ftbot.config['force_entry_enable'] = True
|
||||
|
||||
fbuy_mock = MagicMock(return_value=None)
|
||||
mocker.patch("freqtrade.rpc.RPC._rpc_force_entry", fbuy_mock)
|
||||
|
||||
@@ -95,7 +95,7 @@ def test_telegram_init(default_conf, mocker, caplog) -> None:
|
||||
|
||||
message_str = ("rpc.telegram is listening for following commands: [['status'], ['profit'], "
|
||||
"['balance'], ['start'], ['stop'], "
|
||||
"['forcesell', 'forceexit'], ['forcebuy', 'forcelong'], ['forceshort'], "
|
||||
"['forcesell', 'forceexit', 'fx'], ['forcebuy', 'forcelong'], ['forceshort'], "
|
||||
"['trades'], ['delete'], ['performance'], "
|
||||
"['buys', 'entries'], ['sells', 'exits'], ['mix_tags'], "
|
||||
"['stats'], ['daily'], ['weekly'], ['monthly'], "
|
||||
@@ -1047,7 +1047,7 @@ def test_telegram_forcesell_handle(default_conf, update, ticker, fee,
|
||||
# /forcesell 1
|
||||
context = MagicMock()
|
||||
context.args = ["1"]
|
||||
telegram._forceexit(update=update, context=context)
|
||||
telegram._force_exit(update=update, context=context)
|
||||
|
||||
assert msg_mock.call_count == 4
|
||||
last_msg = msg_mock.call_args_list[-2][0][0]
|
||||
@@ -1117,7 +1117,7 @@ def test_telegram_forcesell_down_handle(default_conf, update, ticker, fee,
|
||||
# /forcesell 1
|
||||
context = MagicMock()
|
||||
context.args = ["1"]
|
||||
telegram._forceexit(update=update, context=context)
|
||||
telegram._force_exit(update=update, context=context)
|
||||
|
||||
assert msg_mock.call_count == 4
|
||||
|
||||
@@ -1178,7 +1178,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None
|
||||
# /forcesell all
|
||||
context = MagicMock()
|
||||
context.args = ["all"]
|
||||
telegram._forceexit(update=update, context=context)
|
||||
telegram._force_exit(update=update, context=context)
|
||||
|
||||
# Called for each trade 2 times
|
||||
assert msg_mock.call_count == 8
|
||||
@@ -1225,7 +1225,7 @@ def test_forcesell_handle_invalid(default_conf, update, mocker) -> None:
|
||||
# /forcesell 1
|
||||
context = MagicMock()
|
||||
context.args = ["1"]
|
||||
telegram._forceexit(update=update, context=context)
|
||||
telegram._force_exit(update=update, context=context)
|
||||
assert msg_mock.call_count == 1
|
||||
assert 'not running' in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
@@ -1234,7 +1234,7 @@ def test_forcesell_handle_invalid(default_conf, update, mocker) -> None:
|
||||
freqtradebot.state = State.RUNNING
|
||||
context = MagicMock()
|
||||
context.args = []
|
||||
telegram._forceexit(update=update, context=context)
|
||||
telegram._force_exit(update=update, context=context)
|
||||
assert msg_mock.call_count == 1
|
||||
assert "You must specify a trade-id or 'all'." in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
@@ -1244,12 +1244,12 @@ def test_forcesell_handle_invalid(default_conf, update, mocker) -> None:
|
||||
# /forcesell 123456
|
||||
context = MagicMock()
|
||||
context.args = ["123456"]
|
||||
telegram._forceexit(update=update, context=context)
|
||||
telegram._force_exit(update=update, context=context)
|
||||
assert msg_mock.call_count == 1
|
||||
assert 'invalid argument' in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
|
||||
def test_forceenter_handle(default_conf, update, mocker) -> None:
|
||||
def test_force_enter_handle(default_conf, update, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||
|
||||
fbuy_mock = MagicMock(return_value=None)
|
||||
@@ -1261,7 +1261,7 @@ def test_forceenter_handle(default_conf, update, mocker) -> None:
|
||||
# /forcelong ETH/BTC
|
||||
context = MagicMock()
|
||||
context.args = ["ETH/BTC"]
|
||||
telegram._forceenter(update=update, context=context, order_side=SignalDirection.LONG)
|
||||
telegram._force_enter(update=update, context=context, order_side=SignalDirection.LONG)
|
||||
|
||||
assert fbuy_mock.call_count == 1
|
||||
assert fbuy_mock.call_args_list[0][0][0] == 'ETH/BTC'
|
||||
@@ -1274,7 +1274,7 @@ def test_forceenter_handle(default_conf, update, mocker) -> None:
|
||||
# /forcelong ETH/BTC 0.055
|
||||
context = MagicMock()
|
||||
context.args = ["ETH/BTC", "0.055"]
|
||||
telegram._forceenter(update=update, context=context, order_side=SignalDirection.LONG)
|
||||
telegram._force_enter(update=update, context=context, order_side=SignalDirection.LONG)
|
||||
|
||||
assert fbuy_mock.call_count == 1
|
||||
assert fbuy_mock.call_args_list[0][0][0] == 'ETH/BTC'
|
||||
@@ -1282,20 +1282,20 @@ def test_forceenter_handle(default_conf, update, mocker) -> None:
|
||||
assert fbuy_mock.call_args_list[0][0][1] == 0.055
|
||||
|
||||
|
||||
def test_forceenter_handle_exception(default_conf, update, mocker) -> None:
|
||||
def test_force_enter_handle_exception(default_conf, update, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||
|
||||
telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
patch_get_signal(freqtradebot)
|
||||
|
||||
update.message.text = '/forcebuy ETH/Nonepair'
|
||||
telegram._forceenter(update=update, context=MagicMock(), order_side=SignalDirection.LONG)
|
||||
telegram._force_enter(update=update, context=MagicMock(), order_side=SignalDirection.LONG)
|
||||
|
||||
assert msg_mock.call_count == 1
|
||||
assert msg_mock.call_args_list[0][0][0] == 'Forceentry not enabled.'
|
||||
assert msg_mock.call_args_list[0][0][0] == 'Force_entry not enabled.'
|
||||
|
||||
|
||||
def test_forceenter_no_pair(default_conf, update, mocker) -> None:
|
||||
def test_force_enter_no_pair(default_conf, update, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||
|
||||
fbuy_mock = MagicMock(return_value=None)
|
||||
@@ -1307,7 +1307,7 @@ def test_forceenter_no_pair(default_conf, update, mocker) -> None:
|
||||
|
||||
context = MagicMock()
|
||||
context.args = []
|
||||
telegram._forceenter(update=update, context=context, order_side=SignalDirection.LONG)
|
||||
telegram._force_enter(update=update, context=context, order_side=SignalDirection.LONG)
|
||||
|
||||
assert fbuy_mock.call_count == 0
|
||||
assert msg_mock.call_count == 1
|
||||
@@ -1319,7 +1319,7 @@ def test_forceenter_no_pair(default_conf, update, mocker) -> None:
|
||||
update = MagicMock()
|
||||
update.callback_query = MagicMock()
|
||||
update.callback_query.data = 'XRP/USDT_||_long'
|
||||
telegram._forceenter_inline(update, None)
|
||||
telegram._force_enter_inline(update, None)
|
||||
assert fbuy_mock.call_count == 1
|
||||
|
||||
|
||||
|
||||
@@ -50,6 +50,8 @@ class StrategyTestV2(IStrategy):
|
||||
'entry': 'gtc',
|
||||
'exit': 'gtc',
|
||||
}
|
||||
# Test legacy use_sell_signal definition
|
||||
use_sell_signal = False
|
||||
|
||||
# By default this strategy does not use Position Adjustments
|
||||
position_adjustment_enable = False
|
||||
|
||||
@@ -183,7 +183,7 @@ class StrategyTestV3(IStrategy):
|
||||
current_profit: float, min_stake: float, max_stake: float, **kwargs):
|
||||
|
||||
if current_profit < -0.0075:
|
||||
orders = trade.select_filled_orders(trade.enter_side)
|
||||
orders = trade.select_filled_orders(trade.entry_side)
|
||||
return round(orders[0].cost, 0)
|
||||
|
||||
return None
|
||||
|
||||
@@ -143,16 +143,6 @@ def test_strategy_can_short(caplog, default_conf):
|
||||
assert isinstance(strat, IStrategy)
|
||||
|
||||
|
||||
def test_strategy_implements_populate_entry(caplog, default_conf):
|
||||
caplog.set_level(logging.INFO)
|
||||
default_conf.update({
|
||||
'strategy': "StrategyTestV2",
|
||||
})
|
||||
default_conf['trading_mode'] = 'futures'
|
||||
with pytest.raises(OperationalException, match="`populate_entry_trend` must be implemented."):
|
||||
StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
|
||||
def test_strategy_override_minimal_roi(caplog, default_conf):
|
||||
caplog.set_level(logging.INFO)
|
||||
default_conf.update({
|
||||
@@ -310,50 +300,50 @@ def test_strategy_override_order_tif(caplog, default_conf):
|
||||
StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
|
||||
def test_strategy_override_use_sell_signal(caplog, default_conf):
|
||||
def test_strategy_override_use_exit_signal(caplog, default_conf):
|
||||
caplog.set_level(logging.INFO)
|
||||
default_conf.update({
|
||||
'strategy': CURRENT_TEST_STRATEGY,
|
||||
})
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
assert strategy.use_sell_signal
|
||||
assert isinstance(strategy.use_sell_signal, bool)
|
||||
assert strategy.use_exit_signal
|
||||
assert isinstance(strategy.use_exit_signal, bool)
|
||||
# must be inserted to configuration
|
||||
assert 'use_sell_signal' in default_conf
|
||||
assert default_conf['use_sell_signal']
|
||||
assert 'use_exit_signal' in default_conf
|
||||
assert default_conf['use_exit_signal']
|
||||
|
||||
default_conf.update({
|
||||
'strategy': CURRENT_TEST_STRATEGY,
|
||||
'use_sell_signal': False,
|
||||
'use_exit_signal': False,
|
||||
})
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
assert not strategy.use_sell_signal
|
||||
assert isinstance(strategy.use_sell_signal, bool)
|
||||
assert log_has("Override strategy 'use_sell_signal' with value in config file: False.", caplog)
|
||||
assert not strategy.use_exit_signal
|
||||
assert isinstance(strategy.use_exit_signal, bool)
|
||||
assert log_has("Override strategy 'use_exit_signal' with value in config file: False.", caplog)
|
||||
|
||||
|
||||
def test_strategy_override_use_sell_profit_only(caplog, default_conf):
|
||||
def test_strategy_override_use_exit_profit_only(caplog, default_conf):
|
||||
caplog.set_level(logging.INFO)
|
||||
default_conf.update({
|
||||
'strategy': CURRENT_TEST_STRATEGY,
|
||||
})
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
assert not strategy.sell_profit_only
|
||||
assert isinstance(strategy.sell_profit_only, bool)
|
||||
assert not strategy.exit_profit_only
|
||||
assert isinstance(strategy.exit_profit_only, bool)
|
||||
# must be inserted to configuration
|
||||
assert 'sell_profit_only' in default_conf
|
||||
assert not default_conf['sell_profit_only']
|
||||
assert 'exit_profit_only' in default_conf
|
||||
assert not default_conf['exit_profit_only']
|
||||
|
||||
default_conf.update({
|
||||
'strategy': CURRENT_TEST_STRATEGY,
|
||||
'sell_profit_only': True,
|
||||
'exit_profit_only': True,
|
||||
})
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
assert strategy.sell_profit_only
|
||||
assert isinstance(strategy.sell_profit_only, bool)
|
||||
assert log_has("Override strategy 'sell_profit_only' with value in config file: True.", caplog)
|
||||
assert strategy.exit_profit_only
|
||||
assert isinstance(strategy.exit_profit_only, bool)
|
||||
assert log_has("Override strategy 'exit_profit_only' with value in config file: True.", caplog)
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("ignore:deprecated")
|
||||
@@ -391,7 +381,22 @@ def test_deprecate_populate_indicators(result, default_conf):
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("ignore:deprecated")
|
||||
def test_missing_implements(default_conf):
|
||||
def test_missing_implements(default_conf, caplog):
|
||||
|
||||
default_location = Path(__file__).parent / "strats"
|
||||
default_conf.update({'strategy': 'StrategyTestV2',
|
||||
'strategy_path': default_location})
|
||||
StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
log_has_re(r"DEPRECATED: .*use_sell_signal.*use_exit_signal.", caplog)
|
||||
|
||||
default_conf['trading_mode'] = 'futures'
|
||||
with pytest.raises(OperationalException,
|
||||
match=r"DEPRECATED: .*use_sell_signal.*use_exit_signal."):
|
||||
StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
default_conf['trading_mode'] = 'spot'
|
||||
|
||||
default_location = Path(__file__).parent / "strats/broken_strats"
|
||||
default_conf.update({'strategy': 'TestStrategyNoImplements',
|
||||
'strategy_path': default_location})
|
||||
|
||||
@@ -160,7 +160,7 @@ def test_load_config_combine_dicts(default_conf, mocker, caplog) -> None:
|
||||
|
||||
configsmock = MagicMock(side_effect=config_files)
|
||||
mocker.patch(
|
||||
'freqtrade.configuration.configuration.load_config_file',
|
||||
'freqtrade.configuration.load_config.load_config_file',
|
||||
configsmock
|
||||
)
|
||||
|
||||
@@ -191,7 +191,7 @@ def test_from_config(default_conf, mocker, caplog) -> None:
|
||||
mocker.patch('freqtrade.configuration.configuration.create_datadir', lambda c, x: x)
|
||||
|
||||
configsmock = MagicMock(side_effect=config_files)
|
||||
mocker.patch('freqtrade.configuration.configuration.load_config_file', configsmock)
|
||||
mocker.patch('freqtrade.configuration.load_config.load_config_file', configsmock)
|
||||
|
||||
validated_conf = Configuration.from_files(['test_conf.json', 'test2_conf.json'])
|
||||
|
||||
@@ -214,7 +214,7 @@ def test_print_config(default_conf, mocker, caplog) -> None:
|
||||
|
||||
configsmock = MagicMock(side_effect=config_files)
|
||||
mocker.patch('freqtrade.configuration.configuration.create_datadir', lambda c, x: x)
|
||||
mocker.patch('freqtrade.configuration.configuration.load_config_file', configsmock)
|
||||
mocker.patch('freqtrade.configuration.configuration.load_from_files', configsmock)
|
||||
|
||||
validated_conf = Configuration.from_files(['test_conf.json'])
|
||||
|
||||
@@ -772,15 +772,15 @@ def test_set_logfile(default_conf, mocker, tmpdir):
|
||||
|
||||
|
||||
def test_load_config_warn_forcebuy(default_conf, mocker, caplog) -> None:
|
||||
default_conf['forcebuy_enable'] = True
|
||||
default_conf['force_entry_enable'] = True
|
||||
patched_configuration_load_config_file(mocker, default_conf)
|
||||
|
||||
args = Arguments(['trade']).get_parsed_arg()
|
||||
configuration = Configuration(args)
|
||||
validated_conf = configuration.load_config()
|
||||
|
||||
assert validated_conf.get('forcebuy_enable')
|
||||
assert log_has('`forcebuy` RPC message enabled.', caplog)
|
||||
assert validated_conf.get('force_entry_enable')
|
||||
assert log_has('`force_entry_enable` RPC message enabled.', caplog)
|
||||
|
||||
|
||||
def test_validate_default_conf(default_conf) -> None:
|
||||
@@ -868,15 +868,15 @@ def test_validate_tsl(default_conf):
|
||||
|
||||
def test_validate_edge2(edge_conf):
|
||||
edge_conf.update({
|
||||
"use_sell_signal": True,
|
||||
"use_exit_signal": True,
|
||||
})
|
||||
# Passes test
|
||||
validate_config_consistency(edge_conf)
|
||||
|
||||
edge_conf.update({
|
||||
"use_sell_signal": False,
|
||||
"use_exit_signal": False,
|
||||
})
|
||||
with pytest.raises(OperationalException, match="Edge requires `use_sell_signal` to be True, "
|
||||
with pytest.raises(OperationalException, match="Edge requires `use_exit_signal` to be True, "
|
||||
"otherwise no sells will happen."):
|
||||
validate_config_consistency(edge_conf)
|
||||
|
||||
@@ -977,7 +977,7 @@ def test__validate_order_types(default_conf, caplog) -> None:
|
||||
assert log_has_re(r"DEPRECATED: Using 'buy' and 'sell' for order_types is.*", caplog)
|
||||
assert conf['order_types']['entry'] == 'limit'
|
||||
assert conf['order_types']['exit'] == 'market'
|
||||
assert conf['order_types']['forceentry'] == 'limit'
|
||||
assert conf['order_types']['force_entry'] == 'limit'
|
||||
assert 'buy' not in conf['order_types']
|
||||
assert 'sell' not in conf['order_types']
|
||||
assert 'forcebuy' not in conf['order_types']
|
||||
@@ -1238,14 +1238,8 @@ def test_pairlist_resolving_fallback(mocker):
|
||||
|
||||
|
||||
@pytest.mark.parametrize("setting", [
|
||||
("ask_strategy", "use_sell_signal", True,
|
||||
None, "use_sell_signal", False),
|
||||
("ask_strategy", "sell_profit_only", True,
|
||||
None, "sell_profit_only", False),
|
||||
("ask_strategy", "sell_profit_offset", 0.1,
|
||||
None, "sell_profit_offset", 0.01),
|
||||
("ask_strategy", "ignore_roi_if_buy_signal", True,
|
||||
None, "ignore_roi_if_buy_signal", False),
|
||||
("webhook", "webhookbuy", 'testWEbhook',
|
||||
"webhook", "webhookentry", 'testWEbhook'),
|
||||
("ask_strategy", "ignore_buying_expired_candle_after", 5,
|
||||
None, "ignore_buying_expired_candle_after", 6),
|
||||
])
|
||||
|
||||
@@ -24,7 +24,7 @@ from freqtrade.worker import Worker
|
||||
from tests.conftest import (create_mock_trades, get_patched_freqtradebot, get_patched_worker,
|
||||
log_has, log_has_re, patch_edge, patch_exchange, patch_get_signal,
|
||||
patch_wallet, patch_whitelist)
|
||||
from tests.conftest_trades import (MOCK_TRADE_COUNT, enter_side, exit_side, mock_order_1,
|
||||
from tests.conftest_trades import (MOCK_TRADE_COUNT, entry_side, exit_side, mock_order_1,
|
||||
mock_order_2, mock_order_2_sell, mock_order_3, mock_order_3_sell,
|
||||
mock_order_4, mock_order_5_stoploss, mock_order_6_sell)
|
||||
|
||||
@@ -304,7 +304,7 @@ def test_create_trade(default_conf_usdt, ticker_usdt, limit_order,
|
||||
|
||||
# Simulate fulfilled LIMIT_BUY order for trade
|
||||
oobj = Order.parse_from_ccxt_object(
|
||||
limit_order[enter_side(is_short)], 'ADA/USDT', enter_side(is_short))
|
||||
limit_order[entry_side(is_short)], 'ADA/USDT', entry_side(is_short))
|
||||
trade.update_trade(oobj)
|
||||
|
||||
assert trade.open_rate == open_rate
|
||||
@@ -342,7 +342,7 @@ def test_create_trade_minimal_amount(
|
||||
) -> None:
|
||||
patch_RPCManager(mocker)
|
||||
patch_exchange(mocker)
|
||||
enter_mock = MagicMock(return_value=limit_order_open[enter_side(is_short)])
|
||||
enter_mock = MagicMock(return_value=limit_order_open[entry_side(is_short)])
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
fetch_ticker=ticker_usdt,
|
||||
@@ -538,8 +538,8 @@ def test_process_trade_creation(default_conf_usdt, ticker_usdt, limit_order, lim
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
fetch_ticker=ticker_usdt,
|
||||
create_order=MagicMock(return_value=limit_order_open[enter_side(is_short)]),
|
||||
fetch_order=MagicMock(return_value=limit_order[enter_side(is_short)]),
|
||||
create_order=MagicMock(return_value=limit_order_open[entry_side(is_short)]),
|
||||
fetch_order=MagicMock(return_value=limit_order[entry_side(is_short)]),
|
||||
get_fee=fee,
|
||||
)
|
||||
freqtrade = FreqtradeBot(default_conf_usdt)
|
||||
@@ -752,8 +752,8 @@ def test_execute_entry(mocker, default_conf_usdt, fee, limit_order,
|
||||
(10 - (2 / 1)) / (1 - (0.01 + 0.0006)) = 8.085708510208207
|
||||
"""
|
||||
# TODO: Split this test into multiple tests to improve readability
|
||||
open_order = limit_order_open[enter_side(is_short)]
|
||||
order = limit_order[enter_side(is_short)]
|
||||
open_order = limit_order_open[entry_side(is_short)]
|
||||
order = limit_order[entry_side(is_short)]
|
||||
default_conf_usdt['trading_mode'] = trading_mode
|
||||
default_conf_usdt['liquidation_buffer'] = liq_buffer
|
||||
leverage = 1.0 if trading_mode == 'spot' else 5.0
|
||||
@@ -976,7 +976,7 @@ def test_execute_entry_confirm_error(mocker, default_conf_usdt, fee, limit_order
|
||||
'ask': 2.2,
|
||||
'last': 1.9
|
||||
}),
|
||||
create_order=MagicMock(return_value=limit_order[enter_side(is_short)]),
|
||||
create_order=MagicMock(return_value=limit_order[entry_side(is_short)]),
|
||||
get_rate=MagicMock(return_value=0.11),
|
||||
get_min_pair_stake_amount=MagicMock(return_value=1),
|
||||
get_fee=fee,
|
||||
@@ -987,11 +987,11 @@ def test_execute_entry_confirm_error(mocker, default_conf_usdt, fee, limit_order
|
||||
freqtrade.strategy.confirm_trade_entry = MagicMock(side_effect=ValueError)
|
||||
assert freqtrade.execute_entry(pair, stake_amount)
|
||||
|
||||
limit_order[enter_side(is_short)]['id'] = '222'
|
||||
limit_order[entry_side(is_short)]['id'] = '222'
|
||||
freqtrade.strategy.confirm_trade_entry = MagicMock(side_effect=Exception)
|
||||
assert freqtrade.execute_entry(pair, stake_amount)
|
||||
|
||||
limit_order[enter_side(is_short)]['id'] = '2223'
|
||||
limit_order[entry_side(is_short)]['id'] = '2223'
|
||||
freqtrade.strategy.confirm_trade_entry = MagicMock(return_value=True)
|
||||
assert freqtrade.execute_entry(pair, stake_amount)
|
||||
|
||||
@@ -1011,7 +1011,7 @@ def test_execute_entry_min_leverage(mocker, default_conf_usdt, fee, limit_order,
|
||||
'ask': 2.2,
|
||||
'last': 1.9
|
||||
}),
|
||||
create_order=MagicMock(return_value=limit_order[enter_side(is_short)]),
|
||||
create_order=MagicMock(return_value=limit_order[entry_side(is_short)]),
|
||||
get_rate=MagicMock(return_value=0.11),
|
||||
# Minimum stake-amount is ~5$
|
||||
get_maintenance_ratio_and_amt=MagicMock(return_value=(0.0, 0.0)),
|
||||
@@ -1033,7 +1033,7 @@ def test_execute_entry_min_leverage(mocker, default_conf_usdt, fee, limit_order,
|
||||
def test_add_stoploss_on_exchange(mocker, default_conf_usdt, limit_order, is_short) -> None:
|
||||
patch_RPCManager(mocker)
|
||||
patch_exchange(mocker)
|
||||
order = limit_order[enter_side(is_short)]
|
||||
order = limit_order[entry_side(is_short)]
|
||||
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_trade', MagicMock(return_value=True))
|
||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order', return_value=order)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[])
|
||||
@@ -1063,7 +1063,7 @@ def test_add_stoploss_on_exchange(mocker, default_conf_usdt, limit_order, is_sho
|
||||
def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog, is_short,
|
||||
limit_order) -> None:
|
||||
stoploss = MagicMock(return_value={'id': 13434334})
|
||||
enter_order = limit_order[enter_side(is_short)]
|
||||
enter_order = limit_order[entry_side(is_short)]
|
||||
exit_order = limit_order[exit_side(is_short)]
|
||||
patch_RPCManager(mocker)
|
||||
patch_exchange(mocker)
|
||||
@@ -1219,7 +1219,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog, is_
|
||||
def test_handle_sle_cancel_cant_recreate(mocker, default_conf_usdt, fee, caplog, is_short,
|
||||
limit_order) -> None:
|
||||
# Sixth case: stoploss order was cancelled but couldn't create new one
|
||||
enter_order = limit_order[enter_side(is_short)]
|
||||
enter_order = limit_order[entry_side(is_short)]
|
||||
exit_order = limit_order[exit_side(is_short)]
|
||||
patch_RPCManager(mocker)
|
||||
patch_exchange(mocker)
|
||||
@@ -1262,7 +1262,7 @@ def test_handle_sle_cancel_cant_recreate(mocker, default_conf_usdt, fee, caplog,
|
||||
def test_create_stoploss_order_invalid_order(
|
||||
mocker, default_conf_usdt, caplog, fee, is_short, limit_order, limit_order_open
|
||||
):
|
||||
open_order = limit_order_open[enter_side(is_short)]
|
||||
open_order = limit_order_open[entry_side(is_short)]
|
||||
order = limit_order[exit_side(is_short)]
|
||||
rpc_mock = patch_RPCManager(mocker)
|
||||
patch_exchange(mocker)
|
||||
@@ -1327,7 +1327,7 @@ def test_create_stoploss_order_insufficient_funds(
|
||||
'last': 1.9
|
||||
}),
|
||||
create_order=MagicMock(side_effect=[
|
||||
limit_order[enter_side(is_short)],
|
||||
limit_order[entry_side(is_short)],
|
||||
exit_order,
|
||||
]),
|
||||
get_fee=fee,
|
||||
@@ -1366,7 +1366,7 @@ def test_handle_stoploss_on_exchange_trailing(
|
||||
mocker, default_conf_usdt, fee, is_short, bid, ask, limit_order, stop_price, amt, hang_price
|
||||
) -> None:
|
||||
# When trailing stoploss is set
|
||||
enter_order = limit_order[enter_side(is_short)]
|
||||
enter_order = limit_order[entry_side(is_short)]
|
||||
exit_order = limit_order[exit_side(is_short)]
|
||||
stoploss = MagicMock(return_value={'id': 13434334})
|
||||
patch_RPCManager(mocker)
|
||||
@@ -1487,7 +1487,7 @@ def test_handle_stoploss_on_exchange_trailing(
|
||||
def test_handle_stoploss_on_exchange_trailing_error(
|
||||
mocker, default_conf_usdt, fee, caplog, limit_order, is_short
|
||||
) -> None:
|
||||
enter_order = limit_order[enter_side(is_short)]
|
||||
enter_order = limit_order[entry_side(is_short)]
|
||||
exit_order = limit_order[exit_side(is_short)]
|
||||
# When trailing stoploss is set
|
||||
stoploss = MagicMock(return_value={'id': 13434334})
|
||||
@@ -1595,7 +1595,7 @@ def test_stoploss_on_exchange_price_rounding(
|
||||
def test_handle_stoploss_on_exchange_custom_stop(
|
||||
mocker, default_conf_usdt, fee, is_short, limit_order
|
||||
) -> None:
|
||||
enter_order = limit_order[enter_side(is_short)]
|
||||
enter_order = limit_order[entry_side(is_short)]
|
||||
exit_order = limit_order[exit_side(is_short)]
|
||||
# When trailing stoploss is set
|
||||
stoploss = MagicMock(return_value={'id': 13434334})
|
||||
@@ -1862,10 +1862,10 @@ def test_exit_positions(mocker, default_conf_usdt, limit_order, is_short, caplog
|
||||
|
||||
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_trade', MagicMock(return_value=True))
|
||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order',
|
||||
return_value=limit_order[enter_side(is_short)])
|
||||
return_value=limit_order[entry_side(is_short)])
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[])
|
||||
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount',
|
||||
return_value=limit_order[enter_side(is_short)]['amount'])
|
||||
return_value=limit_order[entry_side(is_short)]['amount'])
|
||||
|
||||
trade = MagicMock()
|
||||
trade.is_short = is_short
|
||||
@@ -1888,7 +1888,7 @@ def test_exit_positions(mocker, default_conf_usdt, limit_order, is_short, caplog
|
||||
@pytest.mark.parametrize("is_short", [False, True])
|
||||
def test_exit_positions_exception(mocker, default_conf_usdt, limit_order, caplog, is_short) -> None:
|
||||
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
|
||||
order = limit_order[enter_side(is_short)]
|
||||
order = limit_order[entry_side(is_short)]
|
||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order', return_value=order)
|
||||
|
||||
trade = MagicMock()
|
||||
@@ -1911,7 +1911,7 @@ def test_exit_positions_exception(mocker, default_conf_usdt, limit_order, caplog
|
||||
@pytest.mark.parametrize("is_short", [False, True])
|
||||
def test_update_trade_state(mocker, default_conf_usdt, limit_order, is_short, caplog) -> None:
|
||||
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
|
||||
order = limit_order[enter_side(is_short)]
|
||||
order = limit_order[entry_side(is_short)]
|
||||
|
||||
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_trade', MagicMock(return_value=True))
|
||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order', return_value=order)
|
||||
@@ -1932,7 +1932,7 @@ def test_update_trade_state(mocker, default_conf_usdt, limit_order, is_short, ca
|
||||
leverage=1,
|
||||
)
|
||||
trade.orders.append(Order(
|
||||
ft_order_side=enter_side(is_short),
|
||||
ft_order_side=entry_side(is_short),
|
||||
price=0.01,
|
||||
order_id=order_id,
|
||||
|
||||
@@ -1982,7 +1982,7 @@ def test_update_trade_state_withorderdict(
|
||||
default_conf_usdt, trades_for_order, limit_order, fee, mocker, initial_amount,
|
||||
has_rounding_fee, is_short, caplog
|
||||
):
|
||||
order = limit_order[enter_side(is_short)]
|
||||
order = limit_order[entry_side(is_short)]
|
||||
trades_for_order[0]['amount'] = initial_amount
|
||||
order_id = "oid_123456"
|
||||
order['id'] = order_id
|
||||
@@ -2008,7 +2008,7 @@ def test_update_trade_state_withorderdict(
|
||||
)
|
||||
trade.orders.append(
|
||||
Order(
|
||||
ft_order_side=enter_side(is_short),
|
||||
ft_order_side=entry_side(is_short),
|
||||
ft_pair=trade.pair,
|
||||
ft_is_open=True,
|
||||
order_id=order_id,
|
||||
@@ -2028,7 +2028,7 @@ def test_update_trade_state_withorderdict(
|
||||
@pytest.mark.parametrize("is_short", [False, True])
|
||||
def test_update_trade_state_exception(mocker, default_conf_usdt, is_short, limit_order,
|
||||
caplog) -> None:
|
||||
order = limit_order[enter_side(is_short)]
|
||||
order = limit_order[entry_side(is_short)]
|
||||
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
|
||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order', return_value=order)
|
||||
|
||||
@@ -2109,7 +2109,7 @@ def test_handle_trade(
|
||||
default_conf_usdt, limit_order_open, limit_order, fee, mocker, is_short, close_profit
|
||||
) -> None:
|
||||
open_order = limit_order_open[exit_side(is_short)]
|
||||
enter_order = limit_order[enter_side(is_short)]
|
||||
enter_order = limit_order[entry_side(is_short)]
|
||||
exit_order = limit_order[exit_side(is_short)]
|
||||
patch_RPCManager(mocker)
|
||||
patch_exchange(mocker)
|
||||
@@ -2136,7 +2136,7 @@ def test_handle_trade(
|
||||
assert trade
|
||||
|
||||
time.sleep(0.01) # Race condition fix
|
||||
oobj = Order.parse_from_ccxt_object(enter_order, enter_order['symbol'], enter_side(is_short))
|
||||
oobj = Order.parse_from_ccxt_object(enter_order, enter_order['symbol'], entry_side(is_short))
|
||||
trade.update_trade(oobj)
|
||||
assert trade.is_open is True
|
||||
freqtrade.wallets.update()
|
||||
@@ -2237,7 +2237,7 @@ def test_handle_overlapping_signals(
|
||||
def test_handle_trade_roi(default_conf_usdt, ticker_usdt, limit_order_open, fee, mocker, caplog,
|
||||
is_short) -> None:
|
||||
|
||||
open_order = limit_order_open[enter_side(is_short)]
|
||||
open_order = limit_order_open[entry_side(is_short)]
|
||||
|
||||
caplog.set_level(logging.DEBUG)
|
||||
|
||||
@@ -2275,14 +2275,14 @@ def test_handle_trade_roi(default_conf_usdt, ticker_usdt, limit_order_open, fee,
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_short", [False, True])
|
||||
def test_handle_trade_use_sell_signal(
|
||||
def test_handle_trade_use_exit_signal(
|
||||
default_conf_usdt, ticker_usdt, limit_order_open, fee, mocker, caplog, is_short
|
||||
) -> None:
|
||||
|
||||
enter_open_order = limit_order_open[exit_side(is_short)]
|
||||
exit_open_order = limit_order_open[enter_side(is_short)]
|
||||
exit_open_order = limit_order_open[entry_side(is_short)]
|
||||
|
||||
# use_sell_signal is True buy default
|
||||
# use_exit_signal is True buy default
|
||||
caplog.set_level(logging.DEBUG)
|
||||
patch_RPCManager(mocker)
|
||||
mocker.patch.multiple(
|
||||
@@ -2322,7 +2322,7 @@ def test_close_trade(
|
||||
) -> None:
|
||||
open_order = limit_order_open[exit_side(is_short)]
|
||||
enter_order = limit_order[exit_side(is_short)]
|
||||
exit_order = limit_order[enter_side(is_short)]
|
||||
exit_order = limit_order[entry_side(is_short)]
|
||||
patch_RPCManager(mocker)
|
||||
patch_exchange(mocker)
|
||||
mocker.patch.multiple(
|
||||
@@ -2772,7 +2772,7 @@ def test_check_handle_timedout_partial_fee(
|
||||
assert trades[0].amount == (limit_buy_order_old_partial['amount'] -
|
||||
limit_buy_order_old_partial['remaining']) - 0.023
|
||||
assert trades[0].open_order_id is None
|
||||
assert trades[0].fee_updated(open_trade.enter_side)
|
||||
assert trades[0].fee_updated(open_trade.entry_side)
|
||||
assert pytest.approx(trades[0].fee_open) == 0.001
|
||||
|
||||
|
||||
@@ -2859,8 +2859,8 @@ def test_check_handle_timedout_exception(default_conf_usdt, ticker_usdt, open_tr
|
||||
def test_handle_cancel_enter(mocker, caplog, default_conf_usdt, limit_order, is_short) -> None:
|
||||
patch_RPCManager(mocker)
|
||||
patch_exchange(mocker)
|
||||
l_order = limit_order[enter_side(is_short)]
|
||||
cancel_buy_order = deepcopy(limit_order[enter_side(is_short)])
|
||||
l_order = limit_order[entry_side(is_short)]
|
||||
cancel_buy_order = deepcopy(limit_order[entry_side(is_short)])
|
||||
cancel_buy_order['status'] = 'canceled'
|
||||
del cancel_buy_order['filled']
|
||||
|
||||
@@ -2874,7 +2874,7 @@ def test_handle_cancel_enter(mocker, caplog, default_conf_usdt, limit_order, is_
|
||||
trade.pair = 'LTC/USDT'
|
||||
trade.open_rate = 200
|
||||
trade.is_short = False
|
||||
trade.enter_side = "buy"
|
||||
trade.entry_side = "buy"
|
||||
l_order['filled'] = 0.0
|
||||
l_order['status'] = 'open'
|
||||
reason = CANCEL_REASON['TIMEOUT']
|
||||
@@ -2902,7 +2902,7 @@ def test_handle_cancel_enter(mocker, caplog, default_conf_usdt, limit_order, is_
|
||||
assert log_has_re(r"Order .* for .* not cancelled.", caplog)
|
||||
# min_pair_stake empty should not crash
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_min_pair_stake_amount', return_value=None)
|
||||
assert not freqtrade.handle_cancel_enter(trade, limit_order[enter_side(is_short)], reason)
|
||||
assert not freqtrade.handle_cancel_enter(trade, limit_order[entry_side(is_short)], reason)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_short", [False, True])
|
||||
@@ -2921,11 +2921,11 @@ def test_handle_cancel_enter_exchanges(mocker, caplog, default_conf_usdt, is_sho
|
||||
reason = CANCEL_REASON['TIMEOUT']
|
||||
trade = MagicMock()
|
||||
trade.pair = 'LTC/ETH'
|
||||
trade.enter_side = "sell" if is_short else "buy"
|
||||
trade.entry_side = "sell" if is_short else "buy"
|
||||
assert freqtrade.handle_cancel_enter(trade, limit_buy_order_canceled_empty, reason)
|
||||
assert cancel_order_mock.call_count == 0
|
||||
assert log_has_re(
|
||||
f'{trade.enter_side.capitalize()} order fully cancelled. '
|
||||
f'{trade.entry_side.capitalize()} order fully cancelled. '
|
||||
r'Removing .* from database\.',
|
||||
caplog
|
||||
)
|
||||
@@ -2943,7 +2943,7 @@ def test_handle_cancel_enter_corder_empty(mocker, default_conf_usdt, limit_order
|
||||
cancelorder) -> None:
|
||||
patch_RPCManager(mocker)
|
||||
patch_exchange(mocker)
|
||||
l_order = limit_order[enter_side(is_short)]
|
||||
l_order = limit_order[entry_side(is_short)]
|
||||
cancel_order_mock = MagicMock(return_value=cancelorder)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
@@ -2955,9 +2955,9 @@ def test_handle_cancel_enter_corder_empty(mocker, default_conf_usdt, limit_order
|
||||
|
||||
trade = MagicMock()
|
||||
trade.pair = 'LTC/USDT'
|
||||
trade.enter_side = "buy"
|
||||
trade.entry_side = "buy"
|
||||
trade.open_rate = 200
|
||||
trade.enter_side = "buy"
|
||||
trade.entry_side = "buy"
|
||||
l_order['filled'] = 0.0
|
||||
l_order['status'] = 'open'
|
||||
reason = CANCEL_REASON['TIMEOUT']
|
||||
@@ -3654,12 +3654,12 @@ def test_execute_trade_exit_insufficient_funds_error(default_conf_usdt, ticker_u
|
||||
(False, 0.10, 0.22, True, False, ExitType.EXIT_SIGNAL.value, False),
|
||||
(False, 0.10, 0.22, True, False, ExitType.EXIT_SIGNAL.value, True),
|
||||
])
|
||||
def test_sell_profit_only(
|
||||
def test_exit_profit_only(
|
||||
default_conf_usdt, limit_order, limit_order_open, is_short,
|
||||
fee, mocker, profit_only, bid, ask, handle_first, handle_second, exit_type) -> None:
|
||||
patch_RPCManager(mocker)
|
||||
patch_exchange(mocker)
|
||||
eside = enter_side(is_short)
|
||||
eside = entry_side(is_short)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
fetch_ticker=MagicMock(return_value={
|
||||
@@ -3674,9 +3674,9 @@ def test_sell_profit_only(
|
||||
get_fee=fee,
|
||||
)
|
||||
default_conf_usdt.update({
|
||||
'use_sell_signal': True,
|
||||
'sell_profit_only': profit_only,
|
||||
'sell_profit_offset': 0.1,
|
||||
'use_exit_signal': True,
|
||||
'exit_profit_only': profit_only,
|
||||
'exit_profit_offset': 0.1,
|
||||
})
|
||||
freqtrade = FreqtradeBot(default_conf_usdt)
|
||||
patch_get_signal(freqtrade, enter_short=is_short, enter_long=not is_short)
|
||||
@@ -3696,7 +3696,7 @@ def test_sell_profit_only(
|
||||
assert freqtrade.handle_trade(trade) is handle_first
|
||||
|
||||
if handle_second:
|
||||
freqtrade.strategy.sell_profit_offset = 0.0
|
||||
freqtrade.strategy.exit_profit_offset = 0.0
|
||||
assert freqtrade.handle_trade(trade) is True
|
||||
|
||||
|
||||
@@ -3816,11 +3816,11 @@ def test_locked_pairs(default_conf_usdt, ticker_usdt, fee,
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_short", [False, True])
|
||||
def test_ignore_roi_if_buy_signal(default_conf_usdt, limit_order, limit_order_open, is_short,
|
||||
fee, mocker) -> None:
|
||||
def test_ignore_roi_if_entry_signal(default_conf_usdt, limit_order, limit_order_open, is_short,
|
||||
fee, mocker) -> None:
|
||||
patch_RPCManager(mocker)
|
||||
patch_exchange(mocker)
|
||||
eside = enter_side(is_short)
|
||||
eside = entry_side(is_short)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
fetch_ticker=MagicMock(return_value={
|
||||
@@ -3834,7 +3834,7 @@ def test_ignore_roi_if_buy_signal(default_conf_usdt, limit_order, limit_order_op
|
||||
]),
|
||||
get_fee=fee,
|
||||
)
|
||||
default_conf_usdt['ignore_roi_if_buy_signal'] = True
|
||||
default_conf_usdt['ignore_roi_if_entry_signal'] = True
|
||||
|
||||
freqtrade = FreqtradeBot(default_conf_usdt)
|
||||
patch_get_signal(freqtrade, enter_short=is_short, enter_long=not is_short)
|
||||
@@ -3880,7 +3880,7 @@ def test_trailing_stop_loss(default_conf_usdt, limit_order_open,
|
||||
'last': 2.0
|
||||
}),
|
||||
create_order=MagicMock(side_effect=[
|
||||
limit_order_open[enter_side(is_short)],
|
||||
limit_order_open[entry_side(is_short)],
|
||||
{'id': 1234553382},
|
||||
]),
|
||||
get_fee=fee,
|
||||
@@ -3938,10 +3938,10 @@ def test_trailing_stop_loss_positive(
|
||||
default_conf_usdt, limit_order, limit_order_open,
|
||||
offset, fee, caplog, mocker, trail_if_reached, second_sl, is_short
|
||||
) -> None:
|
||||
enter_price = limit_order[enter_side(is_short)]['price']
|
||||
enter_price = limit_order[entry_side(is_short)]['price']
|
||||
patch_RPCManager(mocker)
|
||||
patch_exchange(mocker)
|
||||
eside = enter_side(is_short)
|
||||
eside = entry_side(is_short)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
fetch_ticker=MagicMock(return_value={
|
||||
@@ -4033,11 +4033,11 @@ def test_trailing_stop_loss_positive(
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_short", [False, True])
|
||||
def test_disable_ignore_roi_if_buy_signal(default_conf_usdt, limit_order, limit_order_open,
|
||||
is_short, fee, mocker) -> None:
|
||||
def test_disable_ignore_roi_if_entry_signal(default_conf_usdt, limit_order, limit_order_open,
|
||||
is_short, fee, mocker) -> None:
|
||||
patch_RPCManager(mocker)
|
||||
patch_exchange(mocker)
|
||||
eside = enter_side(is_short)
|
||||
eside = entry_side(is_short)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
fetch_ticker=MagicMock(return_value={
|
||||
@@ -4054,7 +4054,7 @@ def test_disable_ignore_roi_if_buy_signal(default_conf_usdt, limit_order, limit_
|
||||
_is_dry_limit_order_filled=MagicMock(return_value=False),
|
||||
)
|
||||
default_conf_usdt['exit_pricing'] = {
|
||||
'ignore_roi_if_buy_signal': False
|
||||
'ignore_roi_if_entry_signal': False
|
||||
}
|
||||
freqtrade = FreqtradeBot(default_conf_usdt)
|
||||
patch_get_signal(freqtrade, enter_short=is_short, enter_long=not is_short)
|
||||
@@ -4441,7 +4441,7 @@ def test_order_book_depth_of_market(
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
fetch_ticker=ticker_usdt,
|
||||
create_order=MagicMock(return_value=limit_order_open[enter_side(is_short)]),
|
||||
create_order=MagicMock(return_value=limit_order_open[entry_side(is_short)]),
|
||||
get_fee=fee,
|
||||
)
|
||||
|
||||
@@ -4466,7 +4466,7 @@ def test_order_book_depth_of_market(
|
||||
|
||||
# Simulate fulfilled LIMIT_BUY order for trade
|
||||
oobj = Order.parse_from_ccxt_object(
|
||||
limit_order_open[enter_side(is_short)], 'ADA/USDT', enter_side(is_short))
|
||||
limit_order_open[entry_side(is_short)], 'ADA/USDT', entry_side(is_short))
|
||||
trade.update_trade(oobj)
|
||||
|
||||
assert trade.open_rate == ticker_usdt.return_value[ticker_side]
|
||||
@@ -4657,7 +4657,7 @@ def test_cancel_all_open_orders(mocker, default_conf_usdt, fee, limit_order, lim
|
||||
side_effect=[
|
||||
ExchangeError(),
|
||||
limit_order[exit_side(is_short)],
|
||||
limit_order_open[enter_side(is_short)],
|
||||
limit_order_open[entry_side(is_short)],
|
||||
limit_order_open[exit_side(is_short)],
|
||||
]
|
||||
)
|
||||
@@ -4770,7 +4770,7 @@ def test_update_closed_trades_without_assigned_fees(mocker, default_conf_usdt, f
|
||||
for trade in trades:
|
||||
if trade.is_open:
|
||||
# Exclude Trade 4 - as the order is still open.
|
||||
if trade.select_order(enter_side(is_short), False):
|
||||
if trade.select_order(entry_side(is_short), False):
|
||||
assert trade.fee_open_cost is not None
|
||||
assert trade.fee_open_currency is not None
|
||||
else:
|
||||
@@ -5027,7 +5027,7 @@ def test_update_funding_fees(
|
||||
# SETUP
|
||||
time_machine.move_to("2021-09-01 00:00:00 +00:00")
|
||||
|
||||
open_order = limit_order_open[enter_side(is_short)]
|
||||
open_order = limit_order_open[entry_side(is_short)]
|
||||
open_exit_order = limit_order_open[exit_side(is_short)]
|
||||
bid = 0.11
|
||||
enter_rate_mock = MagicMock(return_value=bid)
|
||||
|
||||
@@ -139,7 +139,7 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, mocker, balance_rati
|
||||
one trade was sold at a loss.
|
||||
"""
|
||||
default_conf['max_open_trades'] = 5
|
||||
default_conf['forcebuy_enable'] = True
|
||||
default_conf['force_entry_enable'] = True
|
||||
default_conf['stake_amount'] = 'unlimited'
|
||||
default_conf['tradable_balance_ratio'] = balance_ratio
|
||||
default_conf['dry_run_wallet'] = 1000
|
||||
|
||||
@@ -76,7 +76,7 @@ def test_init_dryrun_db(default_conf, tmpdir):
|
||||
@pytest.mark.parametrize('is_short', [False, True])
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
def test_enter_exit_side(fee, is_short):
|
||||
enter_side, exit_side = ("sell", "buy") if is_short else ("buy", "sell")
|
||||
entry_side, exit_side = ("sell", "buy") if is_short else ("buy", "sell")
|
||||
trade = Trade(
|
||||
id=2,
|
||||
pair='ADA/USDT',
|
||||
@@ -92,7 +92,7 @@ def test_enter_exit_side(fee, is_short):
|
||||
leverage=2.0,
|
||||
trading_mode=margin
|
||||
)
|
||||
assert trade.enter_side == enter_side
|
||||
assert trade.entry_side == entry_side
|
||||
assert trade.exit_side == exit_side
|
||||
assert trade.trade_direction == 'short' if is_short else 'long'
|
||||
|
||||
@@ -456,7 +456,7 @@ def test_update_limit_order(fee, caplog, limit_buy_order_usdt, limit_sell_order_
|
||||
|
||||
enter_order = limit_sell_order_usdt if is_short else limit_buy_order_usdt
|
||||
exit_order = limit_buy_order_usdt if is_short else limit_sell_order_usdt
|
||||
enter_side, exit_side = ("sell", "buy") if is_short else ("buy", "sell")
|
||||
entry_side, exit_side = ("sell", "buy") if is_short else ("buy", "sell")
|
||||
|
||||
trade = Trade(
|
||||
id=2,
|
||||
@@ -479,13 +479,13 @@ def test_update_limit_order(fee, caplog, limit_buy_order_usdt, limit_sell_order_
|
||||
assert trade.close_date is None
|
||||
|
||||
trade.open_order_id = enter_order['id']
|
||||
oobj = Order.parse_from_ccxt_object(enter_order, 'ADA/USDT', enter_side)
|
||||
oobj = Order.parse_from_ccxt_object(enter_order, 'ADA/USDT', entry_side)
|
||||
trade.update_trade(oobj)
|
||||
assert trade.open_order_id is None
|
||||
assert trade.open_rate == open_rate
|
||||
assert trade.close_profit is None
|
||||
assert trade.close_date is None
|
||||
assert log_has_re(f"LIMIT_{enter_side.upper()} has been fulfilled for "
|
||||
assert log_has_re(f"LIMIT_{entry_side.upper()} has been fulfilled for "
|
||||
r"Trade\(id=2, pair=ADA/USDT, amount=30.00000000, "
|
||||
f"is_short={is_short}, leverage={lev}, open_rate={open_rate}0000000, "
|
||||
r"open_since=.*\).",
|
||||
@@ -2137,19 +2137,19 @@ def test_select_order(fee, is_short):
|
||||
trades = Trade.get_trades().all()
|
||||
|
||||
# Open buy order, no sell order
|
||||
order = trades[0].select_order(trades[0].enter_side, True)
|
||||
order = trades[0].select_order(trades[0].entry_side, True)
|
||||
assert order is None
|
||||
order = trades[0].select_order(trades[0].enter_side, False)
|
||||
order = trades[0].select_order(trades[0].entry_side, False)
|
||||
assert order is not None
|
||||
order = trades[0].select_order(trades[0].exit_side, None)
|
||||
assert order is None
|
||||
|
||||
# closed buy order, and open sell order
|
||||
order = trades[1].select_order(trades[1].enter_side, True)
|
||||
order = trades[1].select_order(trades[1].entry_side, True)
|
||||
assert order is None
|
||||
order = trades[1].select_order(trades[1].enter_side, False)
|
||||
order = trades[1].select_order(trades[1].entry_side, False)
|
||||
assert order is not None
|
||||
order = trades[1].select_order(trades[1].enter_side, None)
|
||||
order = trades[1].select_order(trades[1].entry_side, None)
|
||||
assert order is not None
|
||||
order = trades[1].select_order(trades[1].exit_side, True)
|
||||
assert order is None
|
||||
@@ -2157,15 +2157,15 @@ def test_select_order(fee, is_short):
|
||||
assert order is not None
|
||||
|
||||
# Has open buy order
|
||||
order = trades[3].select_order(trades[3].enter_side, True)
|
||||
order = trades[3].select_order(trades[3].entry_side, True)
|
||||
assert order is not None
|
||||
order = trades[3].select_order(trades[3].enter_side, False)
|
||||
order = trades[3].select_order(trades[3].entry_side, False)
|
||||
assert order is None
|
||||
|
||||
# Open sell order
|
||||
order = trades[4].select_order(trades[4].enter_side, True)
|
||||
order = trades[4].select_order(trades[4].entry_side, True)
|
||||
assert order is None
|
||||
order = trades[4].select_order(trades[4].enter_side, False)
|
||||
order = trades[4].select_order(trades[4].entry_side, False)
|
||||
assert order is not None
|
||||
|
||||
trades[4].orders[1].ft_order_side = trades[4].exit_side
|
||||
@@ -2389,7 +2389,7 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee, is_short):
|
||||
o1_cost = o1_amount * o1_rate
|
||||
o1_fee_cost = o1_cost * fee.return_value
|
||||
o1_trade_val = o1_cost - o1_fee_cost if is_short else o1_cost + o1_fee_cost
|
||||
enter_side = "sell" if is_short else "buy"
|
||||
entry_side = "sell" if is_short else "buy"
|
||||
exit_side = "buy" if is_short else "sell"
|
||||
|
||||
trade = Trade(
|
||||
@@ -2405,16 +2405,16 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee, is_short):
|
||||
is_short=is_short,
|
||||
leverage=1.0,
|
||||
)
|
||||
trade.update_fee(o1_fee_cost, 'BNB', fee.return_value, enter_side)
|
||||
trade.update_fee(o1_fee_cost, 'BNB', fee.return_value, entry_side)
|
||||
# Check with 1 order
|
||||
order1 = Order(
|
||||
ft_order_side=enter_side,
|
||||
ft_order_side=entry_side,
|
||||
ft_pair=trade.pair,
|
||||
ft_is_open=False,
|
||||
status="closed",
|
||||
symbol=trade.pair,
|
||||
order_type="market",
|
||||
side=enter_side,
|
||||
side=entry_side,
|
||||
price=o1_rate,
|
||||
average=o1_rate,
|
||||
filled=o1_amount,
|
||||
@@ -2435,13 +2435,13 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee, is_short):
|
||||
assert trade.nr_of_successful_entries == 1
|
||||
|
||||
order2 = Order(
|
||||
ft_order_side=enter_side,
|
||||
ft_order_side=entry_side,
|
||||
ft_pair=trade.pair,
|
||||
ft_is_open=True,
|
||||
status="open",
|
||||
symbol=trade.pair,
|
||||
order_type="market",
|
||||
side=enter_side,
|
||||
side=entry_side,
|
||||
price=o1_rate,
|
||||
average=o1_rate,
|
||||
filled=o1_amount,
|
||||
@@ -2463,13 +2463,13 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee, is_short):
|
||||
|
||||
# Let's try with some other orders
|
||||
order3 = Order(
|
||||
ft_order_side=enter_side,
|
||||
ft_order_side=entry_side,
|
||||
ft_pair=trade.pair,
|
||||
ft_is_open=False,
|
||||
status="cancelled",
|
||||
symbol=trade.pair,
|
||||
order_type="market",
|
||||
side=enter_side,
|
||||
side=entry_side,
|
||||
price=1,
|
||||
average=2,
|
||||
filled=0,
|
||||
@@ -2490,13 +2490,13 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee, is_short):
|
||||
assert trade.nr_of_successful_entries == 1
|
||||
|
||||
order4 = Order(
|
||||
ft_order_side=enter_side,
|
||||
ft_order_side=entry_side,
|
||||
ft_pair=trade.pair,
|
||||
ft_is_open=False,
|
||||
status="closed",
|
||||
symbol=trade.pair,
|
||||
order_type="market",
|
||||
side=enter_side,
|
||||
side=entry_side,
|
||||
price=o1_rate,
|
||||
average=o1_rate,
|
||||
filled=o1_amount,
|
||||
@@ -2545,13 +2545,13 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee, is_short):
|
||||
|
||||
# Check with 1 order
|
||||
order_noavg = Order(
|
||||
ft_order_side=enter_side,
|
||||
ft_order_side=entry_side,
|
||||
ft_pair=trade.pair,
|
||||
ft_is_open=False,
|
||||
status="closed",
|
||||
symbol=trade.pair,
|
||||
order_type="market",
|
||||
side=enter_side,
|
||||
side=entry_side,
|
||||
price=o1_rate,
|
||||
average=None,
|
||||
filled=o1_amount,
|
||||
|
||||
File diff suppressed because one or more lines are too long
2
tests/testdata/backtest-result_new.json
vendored
2
tests/testdata/backtest-result_new.json
vendored
File diff suppressed because one or more lines are too long
10
tests/testdata/strategy_SampleStrategy.fthypt
vendored
10
tests/testdata/strategy_SampleStrategy.fthypt
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user