Merge branch 'freqtrade:develop' into develop
This commit is contained in:
@@ -3489,6 +3489,27 @@ def test_stoploss_order_unsupported_exchange(default_conf, mocker):
|
||||
exchange.stoploss_adjust(1, {}, side="sell")
|
||||
|
||||
|
||||
@pytest.mark.parametrize('side,ratio,expected', [
|
||||
('sell', 0.99, 99.0), # Default
|
||||
('sell', 0.999, 99.9),
|
||||
('sell', 1, 100),
|
||||
('sell', 1.1, InvalidOrderException),
|
||||
('buy', 0.99, 101.0), # Default
|
||||
('buy', 0.999, 100.1),
|
||||
('buy', 1, 100),
|
||||
('buy', 1.1, InvalidOrderException),
|
||||
])
|
||||
def test__get_stop_limit_rate(default_conf_usdt, mocker, side, ratio, expected):
|
||||
exchange = get_patched_exchange(mocker, default_conf_usdt, id='binance')
|
||||
|
||||
order_types = {'stoploss_on_exchange_limit_ratio': ratio}
|
||||
if isinstance(expected, type) and issubclass(expected, Exception):
|
||||
with pytest.raises(expected):
|
||||
exchange._get_stop_limit_rate(100, order_types, side)
|
||||
else:
|
||||
assert exchange._get_stop_limit_rate(100, order_types, side) == expected
|
||||
|
||||
|
||||
def test_merge_ft_has_dict(default_conf, mocker):
|
||||
mocker.patch.multiple(EXMS,
|
||||
_init_ccxt=MagicMock(return_value=MagicMock()),
|
||||
|
||||
@@ -1657,6 +1657,122 @@ def test_api_freqaimodels(botclient, tmpdir, mocker):
|
||||
]}
|
||||
|
||||
|
||||
def test_api_pairlists_available(botclient, tmpdir):
|
||||
ftbot, client = botclient
|
||||
ftbot.config['user_data_dir'] = Path(tmpdir)
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/pairlists/available")
|
||||
|
||||
assert_response(rc, 503)
|
||||
assert rc.json()['detail'] == 'Bot is not in the correct state.'
|
||||
|
||||
ftbot.config['runmode'] = RunMode.WEBSERVER
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/pairlists/available")
|
||||
assert_response(rc)
|
||||
response = rc.json()
|
||||
assert isinstance(response['pairlists'], list)
|
||||
assert len(response['pairlists']) > 0
|
||||
|
||||
assert len([r for r in response['pairlists'] if r['name'] == 'AgeFilter']) == 1
|
||||
assert len([r for r in response['pairlists'] if r['name'] == 'VolumePairList']) == 1
|
||||
assert len([r for r in response['pairlists'] if r['name'] == 'StaticPairList']) == 1
|
||||
|
||||
volumepl = [r for r in response['pairlists'] if r['name'] == 'VolumePairList'][0]
|
||||
assert volumepl['is_pairlist_generator'] is True
|
||||
assert len(volumepl['params']) > 1
|
||||
age_pl = [r for r in response['pairlists'] if r['name'] == 'AgeFilter'][0]
|
||||
assert age_pl['is_pairlist_generator'] is False
|
||||
assert len(volumepl['params']) > 2
|
||||
|
||||
|
||||
def test_api_pairlists_evaluate(botclient, tmpdir, mocker):
|
||||
ftbot, client = botclient
|
||||
ftbot.config['user_data_dir'] = Path(tmpdir)
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/pairlists/evaluate/randomJob")
|
||||
|
||||
assert_response(rc, 503)
|
||||
assert rc.json()['detail'] == 'Bot is not in the correct state.'
|
||||
|
||||
ftbot.config['runmode'] = RunMode.WEBSERVER
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/pairlists/evaluate/randomJob")
|
||||
assert_response(rc, 404)
|
||||
assert rc.json()['detail'] == 'Job not found.'
|
||||
|
||||
body = {
|
||||
"pairlists": [
|
||||
{"method": "StaticPairList", },
|
||||
],
|
||||
"blacklist": [
|
||||
],
|
||||
"stake_currency": "BTC"
|
||||
}
|
||||
# Fail, already running
|
||||
ApiBG.pairlist_running = True
|
||||
rc = client_post(client, f"{BASE_URI}/pairlists/evaluate", body)
|
||||
assert_response(rc, 400)
|
||||
assert rc.json()['detail'] == 'Pairlist evaluation is already running.'
|
||||
|
||||
# should start the run
|
||||
ApiBG.pairlist_running = False
|
||||
rc = client_post(client, f"{BASE_URI}/pairlists/evaluate", body)
|
||||
assert_response(rc)
|
||||
assert rc.json()['status'] == 'Pairlist evaluation started in background.'
|
||||
job_id = rc.json()['job_id']
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/background/RandomJob")
|
||||
assert_response(rc, 404)
|
||||
assert rc.json()['detail'] == 'Job not found.'
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/background/{job_id}")
|
||||
assert_response(rc)
|
||||
response = rc.json()
|
||||
assert response['job_id'] == job_id
|
||||
assert response['job_category'] == 'pairlist'
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/pairlists/evaluate/{job_id}")
|
||||
assert_response(rc)
|
||||
response = rc.json()
|
||||
assert response['result']['whitelist'] == ['ETH/BTC', 'LTC/BTC', 'XRP/BTC', 'NEO/BTC',]
|
||||
assert response['result']['length'] == 4
|
||||
|
||||
# Restart with additional filter, reducing the list to 2
|
||||
body['pairlists'].append({"method": "OffsetFilter", "number_assets": 2})
|
||||
rc = client_post(client, f"{BASE_URI}/pairlists/evaluate", body)
|
||||
assert_response(rc)
|
||||
assert rc.json()['status'] == 'Pairlist evaluation started in background.'
|
||||
job_id = rc.json()['job_id']
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/pairlists/evaluate/{job_id}")
|
||||
assert_response(rc)
|
||||
response = rc.json()
|
||||
assert response['result']['whitelist'] == ['ETH/BTC', 'LTC/BTC', ]
|
||||
assert response['result']['length'] == 2
|
||||
# Patch __run_pairlists
|
||||
plm = mocker.patch('freqtrade.rpc.api_server.api_background_tasks.__run_pairlist',
|
||||
return_value=None)
|
||||
body = {
|
||||
"pairlists": [
|
||||
{"method": "StaticPairList", },
|
||||
],
|
||||
"blacklist": [
|
||||
],
|
||||
"stake_currency": "BTC",
|
||||
"exchange": "randomExchange",
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
}
|
||||
rc = client_post(client, f"{BASE_URI}/pairlists/evaluate", body)
|
||||
assert_response(rc)
|
||||
assert plm.call_count == 1
|
||||
call_config = plm.call_args_list[0][0][1]
|
||||
assert call_config['exchange']['name'] == 'randomExchange'
|
||||
assert call_config['trading_mode'] == 'futures'
|
||||
assert call_config['margin_mode'] == 'isolated'
|
||||
|
||||
|
||||
def test_list_available_pairs(botclient):
|
||||
ftbot, client = botclient
|
||||
|
||||
|
||||
Reference in New Issue
Block a user