2023-08-10 19:25:50 +00:00
|
|
|
"""
|
|
|
|
Tests in this file do NOT mock network calls, so they are expected to be fluky at times.
|
|
|
|
|
|
|
|
However, these tests aim to test ccxt compatibility, specifically regarding websockets.
|
|
|
|
"""
|
|
|
|
|
|
|
|
import logging
|
|
|
|
from datetime import timedelta
|
2023-11-21 05:23:26 +00:00
|
|
|
from time import sleep
|
2023-08-10 19:25:50 +00:00
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
from freqtrade.enums import CandleType
|
2023-11-24 05:55:02 +00:00
|
|
|
from freqtrade.exchange.exchange_utils import timeframe_to_prev_date
|
2023-11-21 05:23:26 +00:00
|
|
|
from freqtrade.loggers.set_log_levels import set_loggers
|
2023-08-10 19:25:50 +00:00
|
|
|
from freqtrade.util.datetime_helpers import dt_now
|
|
|
|
from tests.conftest import log_has_re
|
2023-11-24 05:55:02 +00:00
|
|
|
from tests.exchange_online.conftest import EXCHANGE_WS_FIXTURE_TYPE
|
2023-08-10 19:25:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.longrun
|
2024-06-03 18:57:15 +00:00
|
|
|
@pytest.mark.timeout(3 * 60)
|
2023-08-10 19:25:50 +00:00
|
|
|
class TestCCXTExchangeWs:
|
2024-07-04 15:43:50 +00:00
|
|
|
def test_ccxt_watch_ohlcv(self, exchange_ws: EXCHANGE_WS_FIXTURE_TYPE, caplog, mocker):
|
2024-07-05 06:18:16 +00:00
|
|
|
exch, _exchangename, pair = exchange_ws
|
2023-08-10 19:25:50 +00:00
|
|
|
|
|
|
|
assert exch._ws_async is not None
|
2024-05-14 04:35:49 +00:00
|
|
|
timeframe = "1m"
|
2023-08-10 19:25:50 +00:00
|
|
|
pair_tf = (pair, timeframe, CandleType.SPOT)
|
2024-05-14 04:35:49 +00:00
|
|
|
m_hist = mocker.spy(exch, "_async_get_historic_ohlcv")
|
|
|
|
m_cand = mocker.spy(exch, "_async_get_candle_history")
|
2023-08-10 19:25:50 +00:00
|
|
|
|
2024-08-01 18:37:26 +00:00
|
|
|
while True:
|
|
|
|
# Don't start the test if we are too close to the end of the minute.
|
2024-08-20 04:45:09 +00:00
|
|
|
if dt_now().second < 50 and dt_now().second > 1:
|
2024-08-01 18:37:26 +00:00
|
|
|
break
|
|
|
|
sleep(1)
|
|
|
|
|
2023-08-10 19:25:50 +00:00
|
|
|
res = exch.refresh_latest_ohlcv([pair_tf])
|
2023-11-21 05:23:26 +00:00
|
|
|
assert m_cand.call_count == 1
|
|
|
|
|
|
|
|
# Currently open candle
|
|
|
|
next_candle = timeframe_to_prev_date(timeframe, dt_now())
|
|
|
|
now = next_candle - timedelta(seconds=1)
|
2023-08-10 19:25:50 +00:00
|
|
|
# Currently closed candle
|
|
|
|
curr_candle = timeframe_to_prev_date(timeframe, now)
|
2023-11-21 05:23:26 +00:00
|
|
|
|
2023-08-10 19:25:50 +00:00
|
|
|
assert pair_tf in exch._exchange_ws._klines_watching
|
|
|
|
assert pair_tf in exch._exchange_ws._klines_scheduled
|
|
|
|
assert res[pair_tf] is not None
|
|
|
|
df1 = res[pair_tf]
|
|
|
|
caplog.set_level(logging.DEBUG)
|
2023-11-21 05:23:26 +00:00
|
|
|
set_loggers(1)
|
2024-05-14 04:35:49 +00:00
|
|
|
assert df1.iloc[-1]["date"] == curr_candle
|
2023-08-10 19:25:50 +00:00
|
|
|
|
|
|
|
# Wait until the next candle (might be up to 1 minute).
|
|
|
|
while True:
|
|
|
|
caplog.clear()
|
|
|
|
res = exch.refresh_latest_ohlcv([pair_tf])
|
|
|
|
df2 = res[pair_tf]
|
|
|
|
assert df2 is not None
|
2024-05-14 04:35:49 +00:00
|
|
|
if df2.iloc[-1]["date"] == next_candle:
|
2023-08-10 19:25:50 +00:00
|
|
|
break
|
2024-05-14 04:35:49 +00:00
|
|
|
assert df2.iloc[-1]["date"] == curr_candle
|
2023-11-21 05:23:26 +00:00
|
|
|
sleep(1)
|
2023-08-10 19:25:50 +00:00
|
|
|
|
2023-11-21 05:23:26 +00:00
|
|
|
assert m_hist.call_count == 0
|
2023-11-24 05:40:58 +00:00
|
|
|
# shouldn't have tried fetch_ohlcv a second time.
|
2023-11-21 05:23:26 +00:00
|
|
|
assert m_cand.call_count == 1
|
2023-08-10 19:25:50 +00:00
|
|
|
assert log_has_re(r"watch result.*", caplog)
|