refacotr: default to stop on 404
This commit is contained in:
@@ -177,7 +177,6 @@ class Binance(Exchange):
|
|||||||
timeframe=timeframe,
|
timeframe=timeframe,
|
||||||
since_ms=since_ms,
|
since_ms=since_ms,
|
||||||
until_ms=until_ms,
|
until_ms=until_ms,
|
||||||
stop_on_404=False,
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if df.empty:
|
if df.empty:
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ from freqtrade.util.datetime_helpers import dt_from_ts, dt_now
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Http404(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BadHttpStatus(Exception):
|
class BadHttpStatus(Exception):
|
||||||
"""Not 200/404"""
|
"""Not 200/404"""
|
||||||
|
|
||||||
@@ -32,7 +36,7 @@ async def fetch_ohlcv(
|
|||||||
timeframe: str,
|
timeframe: str,
|
||||||
since_ms: int,
|
since_ms: int,
|
||||||
until_ms: int | None,
|
until_ms: int | None,
|
||||||
stop_on_404: bool = False,
|
stop_on_404: bool = True,
|
||||||
) -> DataFrame:
|
) -> DataFrame:
|
||||||
"""
|
"""
|
||||||
Fetch OHLCV data from https://data.binance.vision/
|
Fetch OHLCV data from https://data.binance.vision/
|
||||||
@@ -103,6 +107,7 @@ async def _fetch_ohlcv(
|
|||||||
stop_on_404: bool,
|
stop_on_404: bool,
|
||||||
) -> DataFrame:
|
) -> DataFrame:
|
||||||
dfs: list[DataFrame | None] = []
|
dfs: list[DataFrame | None] = []
|
||||||
|
current_day = 0
|
||||||
|
|
||||||
connector = aiohttp.TCPConnector(limit=100)
|
connector = aiohttp.TCPConnector(limit=100)
|
||||||
async with aiohttp.ClientSession(connector=connector) as session:
|
async with aiohttp.ClientSession(connector=connector) as session:
|
||||||
@@ -112,14 +117,27 @@ async def _fetch_ohlcv(
|
|||||||
*(get_daily_ohlcv(asset_type, symbol, timeframe, date, session) for date in dates)
|
*(get_daily_ohlcv(asset_type, symbol, timeframe, date, session) for date in dates)
|
||||||
)
|
)
|
||||||
for result in results:
|
for result in results:
|
||||||
if isinstance(result, BaseException):
|
current_day += 1
|
||||||
|
if isinstance(result, Http404):
|
||||||
|
if stop_on_404:
|
||||||
|
if current_day == 1:
|
||||||
|
# https://github.com/freqtrade/freqtrade/blob/acc53065e5fa7ab5197073276306dc9dc3adbfa3/tests/exchange_online/test_binance_compare_ohlcv.py#L7
|
||||||
|
logger.warning(
|
||||||
|
"Failed to use fast download, fall back to rest API download, this "
|
||||||
|
"can take more time. If you're downloading BTC/USDT:USDT, "
|
||||||
|
"ETH/USDT:USDT, BCH/USDT:USDT, please first download "
|
||||||
|
"data before 2020 (using `--timerange yyyymmdd-20200101`), and "
|
||||||
|
"then download the full data you need."
|
||||||
|
)
|
||||||
|
logger.debug("Abort downloading from data.binance.vision due to 404")
|
||||||
|
return concat(dfs)
|
||||||
|
else:
|
||||||
|
dfs.append(None)
|
||||||
|
elif isinstance(result, BaseException):
|
||||||
logger.warning(f"An exception raised: : {result}")
|
logger.warning(f"An exception raised: : {result}")
|
||||||
# Directly return the existing data, do not allow the gap
|
# Directly return the existing data, do not allow the gap
|
||||||
# between the data
|
# between the data
|
||||||
return concat(dfs)
|
return concat(dfs)
|
||||||
elif result is None and stop_on_404:
|
|
||||||
logger.debug("Abort downloading from data.binance.vision due to 404")
|
|
||||||
return concat(dfs)
|
|
||||||
else:
|
else:
|
||||||
dfs.append(result)
|
dfs.append(result)
|
||||||
return concat(dfs)
|
return concat(dfs)
|
||||||
@@ -160,6 +178,7 @@ async def get_daily_ohlcv(
|
|||||||
date: datetime.date,
|
date: datetime.date,
|
||||||
session: aiohttp.ClientSession,
|
session: aiohttp.ClientSession,
|
||||||
retry_count: int = 3,
|
retry_count: int = 3,
|
||||||
|
retry_delay: float = 0.0,
|
||||||
) -> DataFrame | None | Exception:
|
) -> DataFrame | None | Exception:
|
||||||
"""
|
"""
|
||||||
Get daily OHLCV from https://data.binance.vision
|
Get daily OHLCV from https://data.binance.vision
|
||||||
@@ -176,7 +195,7 @@ async def get_daily_ohlcv(
|
|||||||
retry = 0
|
retry = 0
|
||||||
while True:
|
while True:
|
||||||
if retry > 0:
|
if retry > 0:
|
||||||
sleep_secs = retry * 0.5
|
sleep_secs = retry * retry_delay
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"[{retry}/{retry_count}] retry to download {url} after {sleep_secs} seconds"
|
f"[{retry}/{retry_count}] retry to download {url} after {sleep_secs} seconds"
|
||||||
)
|
)
|
||||||
@@ -206,7 +225,7 @@ async def get_daily_ohlcv(
|
|||||||
return df
|
return df
|
||||||
elif resp.status == 404:
|
elif resp.status == 404:
|
||||||
logger.debug(f"No data available for {symbol} in {format_date(date)}")
|
logger.debug(f"No data available for {symbol} in {format_date(date)}")
|
||||||
return None
|
raise Http404
|
||||||
else:
|
else:
|
||||||
raise BadHttpStatus(f"{resp.status} - {resp.reason}")
|
raise BadHttpStatus(f"{resp.status} - {resp.reason}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import pytest
|
|||||||
from freqtrade.enums import CandleType
|
from freqtrade.enums import CandleType
|
||||||
from freqtrade.exchange.binance_public_data import (
|
from freqtrade.exchange.binance_public_data import (
|
||||||
BadHttpStatus,
|
BadHttpStatus,
|
||||||
|
Http404,
|
||||||
fetch_ohlcv,
|
fetch_ohlcv,
|
||||||
get_daily_ohlcv,
|
get_daily_ohlcv,
|
||||||
symbol_ccxt_to_binance,
|
symbol_ccxt_to_binance,
|
||||||
@@ -256,8 +257,8 @@ async def test_get_daily_ohlcv(mocker, testdatadir):
|
|||||||
assert df["date"].iloc[-1] == last_date
|
assert df["date"].iloc[-1] == last_date
|
||||||
|
|
||||||
mocker.patch("aiohttp.ClientSession.get", return_value=MockResponse(b"", 404))
|
mocker.patch("aiohttp.ClientSession.get", return_value=MockResponse(b"", 404))
|
||||||
df = await get_daily_ohlcv("spot", symbol, timeframe, date, session)
|
df = await get_daily_ohlcv("spot", symbol, timeframe, date, session, retry_delay=0)
|
||||||
assert df is None
|
assert isinstance(df, Http404)
|
||||||
|
|
||||||
mocker.patch("aiohttp.ClientSession.get", return_value=MockResponse(b"", 500))
|
mocker.patch("aiohttp.ClientSession.get", return_value=MockResponse(b"", 500))
|
||||||
mocker.patch("asyncio.sleep")
|
mocker.patch("asyncio.sleep")
|
||||||
|
|||||||
Reference in New Issue
Block a user