Merge pull request #10143 from freqtrade/feat/pairhistory_advanced

RPC: Advanced pairhistory endpoint
This commit is contained in:
Matthias
2024-04-28 20:07:24 +02:00
committed by GitHub
4 changed files with 210 additions and 88 deletions
+141 -72
View File
@@ -1511,6 +1511,7 @@ def test_api_pair_candles(botclient, ohlcv_history):
assert 'data_stop_ts' in rc.json()
assert len(rc.json()['data']) == 0
ohlcv_history['sma'] = ohlcv_history['close'].rolling(2).mean()
ohlcv_history['sma2'] = ohlcv_history['close'].rolling(2).mean()
ohlcv_history['enter_long'] = 0
ohlcv_history.loc[1, 'enter_long'] = 1
ohlcv_history['exit_long'] = 0
@@ -1518,44 +1519,83 @@ def test_api_pair_candles(botclient, ohlcv_history):
ohlcv_history['exit_short'] = 0
ftbot.dataprovider._set_cached_df("XRP/BTC", timeframe, ohlcv_history, CandleType.SPOT)
for call in ('get', 'post'):
if call == 'get':
rc = client_get(
client,
f"{BASE_URI}/pair_candles?limit={amount}&pair=XRP%2FBTC&timeframe={timeframe}")
else:
rc = client_post(
client,
f"{BASE_URI}/pair_candles",
data={
"pair": "XRP/BTC",
"timeframe": timeframe,
"limit": amount,
"columns": ['sma'],
}
)
assert_response(rc)
resp = rc.json()
assert 'strategy' in resp
assert resp['strategy'] == CURRENT_TEST_STRATEGY
assert 'columns' in resp
assert 'data_start_ts' in resp
assert 'data_start' in resp
assert 'data_stop' in resp
assert 'data_stop_ts' in resp
assert resp['data_start'] == '2017-11-26 08:50:00+00:00'
assert resp['data_start_ts'] == 1511686200000
assert resp['data_stop'] == '2017-11-26 09:00:00+00:00'
assert resp['data_stop_ts'] == 1511686800000
assert isinstance(resp['columns'], list)
base_cols = {
'date', 'open', 'high', 'low', 'close', 'volume',
'sma', 'enter_long', 'exit_long', 'enter_short', 'exit_short', '__date_ts',
'_enter_long_signal_close', '_exit_long_signal_close',
'_enter_short_signal_close', '_exit_short_signal_close'
}
if call == 'get':
assert set(resp['columns']) == base_cols.union({'sma2'})
else:
assert set(resp['columns']) == base_cols
rc = client_get(client,
f"{BASE_URI}/pair_candles?limit={amount}&pair=XRP%2FBTC&timeframe={timeframe}")
assert_response(rc)
assert 'strategy' in rc.json()
assert rc.json()['strategy'] == CURRENT_TEST_STRATEGY
assert 'columns' in rc.json()
assert 'data_start_ts' in rc.json()
assert 'data_start' in rc.json()
assert 'data_stop' in rc.json()
assert 'data_stop_ts' in rc.json()
assert rc.json()['data_start'] == '2017-11-26 08:50:00+00:00'
assert rc.json()['data_start_ts'] == 1511686200000
assert rc.json()['data_stop'] == '2017-11-26 09:00:00+00:00'
assert rc.json()['data_stop_ts'] == 1511686800000
assert isinstance(rc.json()['columns'], list)
assert set(rc.json()['columns']) == {
'date', 'open', 'high', 'low', 'close', 'volume',
'sma', 'enter_long', 'exit_long', 'enter_short', 'exit_short', '__date_ts',
'_enter_long_signal_close', '_exit_long_signal_close',
'_enter_short_signal_close', '_exit_short_signal_close'
}
assert 'pair' in rc.json()
assert rc.json()['pair'] == 'XRP/BTC'
# All columns doesn't include the internal columns
assert set(resp['all_columns']) == {
'date', 'open', 'high', 'low', 'close', 'volume',
'sma', 'sma2', 'enter_long', 'exit_long', 'enter_short', 'exit_short'
}
assert 'pair' in resp
assert resp['pair'] == 'XRP/BTC'
assert 'data' in rc.json()
assert len(rc.json()['data']) == amount
assert 'data' in resp
assert len(resp['data']) == amount
if call == 'get':
assert len(resp['data'][0]) == 17
assert resp['data'] == [
['2017-11-26T08:50:00Z', 8.794e-05, 8.948e-05, 8.794e-05, 8.88e-05,
0.0877869, None, None, 0, 0, 0, 0, 1511686200000, None, None, None, None],
['2017-11-26T08:55:00Z', 8.88e-05, 8.942e-05, 8.88e-05, 8.893e-05, 0.05874751,
8.886500000000001e-05, 8.886500000000001e-05, 1, 0, 0, 0, 1511686500000,
8.893e-05, None, None, None],
['2017-11-26T09:00:00Z', 8.891e-05, 8.893e-05, 8.875e-05, 8.877e-05,
0.7039405, 8.885e-05, 8.885e-05, 0, 0, 0, 0, 1511686800000, None, None, None, None
]
]
else:
assert len(resp['data'][0]) == 16
assert resp['data'] == [
['2017-11-26T08:50:00Z', 8.794e-05, 8.948e-05, 8.794e-05, 8.88e-05,
0.0877869, None, 0, 0, 0, 0, 1511686200000, None, None, None, None],
['2017-11-26T08:55:00Z', 8.88e-05, 8.942e-05, 8.88e-05, 8.893e-05, 0.05874751,
8.886500000000001e-05, 1, 0, 0, 0, 1511686500000,
8.893e-05, None, None, None],
['2017-11-26T09:00:00Z', 8.891e-05, 8.893e-05, 8.875e-05, 8.877e-05,
0.7039405, 8.885e-05, 0, 0, 0, 0, 1511686800000, None, None, None, None
]
]
assert (rc.json()['data'] ==
[['2017-11-26T08:50:00Z', 8.794e-05, 8.948e-05, 8.794e-05, 8.88e-05, 0.0877869,
None, 0, 0, 0, 0, 1511686200000, None, None, None, None],
['2017-11-26T08:55:00Z', 8.88e-05, 8.942e-05, 8.88e-05,
8.893e-05, 0.05874751, 8.886500000000001e-05, 1, 0, 0, 0, 1511686500000, 8.893e-05,
None, None, None],
['2017-11-26T09:00:00Z', 8.891e-05, 8.893e-05, 8.875e-05, 8.877e-05,
0.7039405, 8.885e-05, 0, 0, 0, 0, 1511686800000, None, None, None, None]
])
# prep for next test
ohlcv_history['exit_long'] = ohlcv_history['exit_long'].astype('float64')
ohlcv_history.at[0, 'exit_long'] = float('inf')
ohlcv_history['date1'] = ohlcv_history['date']
@@ -1567,13 +1607,13 @@ def test_api_pair_candles(botclient, ohlcv_history):
assert_response(rc)
assert (rc.json()['data'] ==
[['2017-11-26T08:50:00Z', 8.794e-05, 8.948e-05, 8.794e-05, 8.88e-05, 0.0877869,
None, 0, None, 0, 0, None, 1511686200000, None, None, None, None],
None, None, 0, None, 0, 0, None, 1511686200000, None, None, None, None],
['2017-11-26T08:55:00Z', 8.88e-05, 8.942e-05, 8.88e-05,
8.893e-05, 0.05874751, 8.886500000000001e-05, 1, 0.0, 0, 0, '2017-11-26T08:55:00Z',
1511686500000, 8.893e-05, None, None, None],
8.893e-05, 0.05874751, 8.886500000000001e-05, 8.886500000000001e-05, 1, 0.0, 0,
0, '2017-11-26T08:55:00Z', 1511686500000, 8.893e-05, None, None, None],
['2017-11-26T09:00:00Z', 8.891e-05, 8.893e-05, 8.875e-05, 8.877e-05,
0.7039405, 8.885e-05, 0, 0.0, 0, 0, '2017-11-26T09:00:00Z', 1511686800000,
None, None, None, None]
0.7039405, 8.885e-05, 8.885e-05, 0, 0.0, 0, 0, '2017-11-26T09:00:00Z',
1511686800000, None, None, None, None]
])
@@ -1614,40 +1654,69 @@ def test_api_pair_history(botclient, tmp_path, mocker):
assert_response(rc, 502)
# Working
rc = client_get(client,
f"{BASE_URI}/pair_history?pair=UNITTEST%2FBTC&timeframe={timeframe}"
f"&timerange=20180111-20180112&strategy={CURRENT_TEST_STRATEGY}")
assert_response(rc, 200)
result = rc.json()
assert result['length'] == 289
assert len(result['data']) == result['length']
assert 'columns' in result
assert 'data' in result
data = result['data']
assert len(data) == 289
# analyzed DF has 30 columns
assert len(result['columns']) == 30
assert len(data[0]) == 30
date_col_idx = [idx for idx, c in enumerate(result['columns']) if c == 'date'][0]
rsi_col_idx = [idx for idx, c in enumerate(result['columns']) if c == 'rsi'][0]
for call in ('get', 'post'):
if call == 'get':
rc = client_get(client,
f"{BASE_URI}/pair_history?pair=UNITTEST%2FBTC&timeframe={timeframe}"
f"&timerange=20180111-20180112&strategy={CURRENT_TEST_STRATEGY}")
else:
rc = client_post(
client,
f"{BASE_URI}/pair_history",
data={
"pair": "UNITTEST/BTC",
"timeframe": timeframe,
"timerange": "20180111-20180112",
"strategy": CURRENT_TEST_STRATEGY,
"columns": ['rsi', 'fastd', 'fastk'],
})
assert data[0][date_col_idx] == '2018-01-11T00:00:00Z'
assert data[0][rsi_col_idx] is not None
assert data[0][rsi_col_idx] > 0
assert lfm.call_count == 1
assert result['pair'] == 'UNITTEST/BTC'
assert result['strategy'] == CURRENT_TEST_STRATEGY
assert result['data_start'] == '2018-01-11 00:00:00+00:00'
assert result['data_start_ts'] == 1515628800000
assert result['data_stop'] == '2018-01-12 00:00:00+00:00'
assert result['data_stop_ts'] == 1515715200000
assert_response(rc, 200)
result = rc.json()
assert result['length'] == 289
assert len(result['data']) == result['length']
assert 'columns' in result
assert 'data' in result
data = result['data']
assert len(data) == 289
col_count = 30 if call == 'get' else 18
# analyzed DF has 30 columns
assert len(result['columns']) == col_count
assert len(result['all_columns']) == 25
assert len(data[0]) == col_count
date_col_idx = [idx for idx, c in enumerate(result['columns']) if c == 'date'][0]
rsi_col_idx = [idx for idx, c in enumerate(result['columns']) if c == 'rsi'][0]
# No data found
rc = client_get(client,
f"{BASE_URI}/pair_history?pair=UNITTEST%2FBTC&timeframe={timeframe}"
f"&timerange=20200111-20200112&strategy={CURRENT_TEST_STRATEGY}")
assert_response(rc, 502)
assert rc.json()['detail'] == ("No data for UNITTEST/BTC, 5m in 20200111-20200112 found.")
assert data[0][date_col_idx] == '2018-01-11T00:00:00Z'
assert data[0][rsi_col_idx] is not None
assert data[0][rsi_col_idx] > 0
assert lfm.call_count == 1
assert result['pair'] == 'UNITTEST/BTC'
assert result['strategy'] == CURRENT_TEST_STRATEGY
assert result['data_start'] == '2018-01-11 00:00:00+00:00'
assert result['data_start_ts'] == 1515628800000
assert result['data_stop'] == '2018-01-12 00:00:00+00:00'
assert result['data_stop_ts'] == 1515715200000
lfm.reset_mock()
# No data found
if call == 'get':
rc = client_get(client,
f"{BASE_URI}/pair_history?pair=UNITTEST%2FBTC&timeframe={timeframe}"
f"&timerange=20200111-20200112&strategy={CURRENT_TEST_STRATEGY}")
else:
rc = client_post(
client,
f"{BASE_URI}/pair_history",
data={
"pair": "UNITTEST/BTC",
"timeframe": timeframe,
"timerange": "20200111-20200112",
"strategy": CURRENT_TEST_STRATEGY,
"columns": ['rsi', 'fastd', 'fastk'],
})
assert_response(rc, 502)
assert rc.json()['detail'] == ("No data for UNITTEST/BTC, 5m in 20200111-20200112 found.")
def test_api_plot_config(botclient, mocker, tmp_path):