diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index ba7d79f97..7e276d538 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -2371,12 +2371,12 @@ class Exchange: # Must fetch the leverage tiers for each market separately # * This is slow(~45s) on Okx, makes ~90 api calls to load all linear swap markets markets = self.markets - symbols = [] - for symbol, market in markets.items(): + symbols = [ + symbol for symbol, market in markets.items() if (self.market_is_future(market) - and market['quote'] == self._config['stake_currency']): - symbols.append(symbol) + and market['quote'] == self._config['stake_currency']) + ] tiers: Dict[str, List[Dict]] = {} @@ -2396,25 +2396,26 @@ class Exchange: else: logger.info("Using cached leverage_tiers.") - async def gather_results(): + async def gather_results(input_coro): return await asyncio.gather(*input_coro, return_exceptions=True) for input_coro in chunks(coros, 100): with self._loop_lock: - results = self.loop.run_until_complete(gather_results()) + results = self.loop.run_until_complete(gather_results(input_coro)) - for symbol, res in results: - tiers[symbol] = res + for res in results: + if isinstance(res, Exception): + logger.warning(f"Leverage tier exception: {repr(res)}") + continue + symbol, tier = res + tiers[symbol] = tier if len(coros) > 0: self.cache_leverage_tiers(tiers, self._config['stake_currency']) logger.info(f"Done initializing {len(symbols)} markets.") return tiers - else: - return {} - else: - return {} + return {} def cache_leverage_tiers(self, tiers: Dict[str, List[Dict]], stake_currency: str) -> None: @@ -2430,14 +2431,17 @@ class Exchange: def load_cached_leverage_tiers(self, stake_currency: str) -> Optional[Dict[str, List[Dict]]]: filename = self._config['datadir'] / "futures" / f"leverage_tiers_{stake_currency}.json" if filename.is_file(): - tiers = file_load_json(filename) - updated = tiers.get('updated') - if updated: - updated_dt = parser.parse(updated) - if updated_dt < datetime.now(timezone.utc) - timedelta(weeks=4): - logger.info("Cached leverage tiers are outdated. Will update.") - return None - return tiers['data'] + try: + tiers = file_load_json(filename) + updated = tiers.get('updated') + if updated: + updated_dt = parser.parse(updated) + if updated_dt < datetime.now(timezone.utc) - timedelta(weeks=4): + logger.info("Cached leverage tiers are outdated. Will update.") + return None + return tiers['data'] + except Exception: + logger.exception("Error loading cached leverage tiers. Refreshing.") return None def fill_leverage_tiers(self) -> None: diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index b4925770d..cbae6aede 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -273,7 +273,8 @@ def _get_resample_from_period(period: str) -> str: if period == 'day': return '1d' if period == 'week': - return '1w' + # Weekly defaulting to Monday. + return '1W-MON' if period == 'month': return '1M' raise ValueError(f"Period {period} is not supported.") diff --git a/pyproject.toml b/pyproject.toml index baf707c68..28de6a1d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,6 +68,9 @@ target-version = "py38" extend-select = [ "C90", # mccabe # "N", # pep8-naming + "F", # pyflakes + "E", # pycodestyle + "W", # pycodestyle "UP", # pyupgrade "TID", # flake8-tidy-imports # "EXE", # flake8-executable diff --git a/requirements.txt b/requirements.txt index 07ddde148..7db852961 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ numpy==1.24.2 pandas==1.5.3 pandas-ta==0.3.14b -ccxt==3.0.59 +ccxt==3.0.69 cryptography==40.0.2 aiohttp==3.8.4 SQLAlchemy==2.0.9 diff --git a/tests/exchange/test_okx.py b/tests/exchange/test_okx.py index 7a3fa22f0..3824eddb7 100644 --- a/tests/exchange/test_okx.py +++ b/tests/exchange/test_okx.py @@ -1,14 +1,14 @@ from datetime import datetime, timedelta, timezone from pathlib import Path -from unittest.mock import MagicMock, PropertyMock +from unittest.mock import AsyncMock, MagicMock, PropertyMock import ccxt import pytest from freqtrade.enums import CandleType, MarginMode, TradingMode -from freqtrade.exceptions import RetryableOrderError +from freqtrade.exceptions import RetryableOrderError, TemporaryError from freqtrade.exchange.exchange import timeframe_to_minutes -from tests.conftest import EXMS, get_mock_coro, get_patched_exchange, log_has +from tests.conftest import EXMS, get_patched_exchange, log_has from tests.exchange.test_exchange import ccxt_exceptionhandlers @@ -278,7 +278,7 @@ def test_load_leverage_tiers_okx(default_conf, mocker, markets, tmpdir, caplog, 'fetchLeverageTiers': False, 'fetchMarketLeverageTiers': True, }) - api_mock.fetch_market_leverage_tiers = get_mock_coro(side_effect=[ + api_mock.fetch_market_leverage_tiers = AsyncMock(side_effect=[ [ { 'tier': 1, @@ -341,6 +341,7 @@ def test_load_leverage_tiers_okx(default_conf, mocker, markets, tmpdir, caplog, } }, ], + TemporaryError("this Failed"), [ { 'tier': 1, diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 0cc32baaf..9fdd0d61e 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -465,7 +465,7 @@ def test_generate_periodic_breakdown_stats(testdatadir): def test__get_resample_from_period(): assert _get_resample_from_period('day') == '1d' - assert _get_resample_from_period('week') == '1w' + assert _get_resample_from_period('week') == '1W-MON' assert _get_resample_from_period('month') == '1M' with pytest.raises(ValueError, match=r"Period noooo is not supported."): _get_resample_from_period('noooo')