chore: update plugins to modern typing syntax

This commit is contained in:
Matthias
2024-10-04 07:02:20 +02:00
parent e9a6ba03f9
commit d8e41fa8b1
24 changed files with 116 additions and 122 deletions

View File

@@ -1,7 +1,7 @@
import logging
from datetime import datetime, timezone
from pathlib import Path
from typing import Dict, List, Optional
from typing import Optional
import pandas as pd
@@ -43,7 +43,7 @@ except ImportError:
exit(1)
def init_plotscript(config, markets: List, startup_candles: int = 0):
def init_plotscript(config, markets: list, startup_candles: int = 0):
"""
Initialize objects needed for plotting
:return: Dict with candle (OHLCV) data, trades and pairs
@@ -103,7 +103,7 @@ def init_plotscript(config, markets: List, startup_candles: int = 0):
}
def add_indicators(fig, row, indicators: Dict[str, Dict], data: pd.DataFrame) -> make_subplots:
def add_indicators(fig, row, indicators: dict[str, dict], data: pd.DataFrame) -> make_subplots:
"""
Generate all the indicators selected by the user for a specific row, based on the configuration
:param fig: Plot figure to append to
@@ -301,8 +301,8 @@ def plot_trades(fig, trades: pd.DataFrame) -> make_subplots:
def create_plotconfig(
indicators1: List[str], indicators2: List[str], plot_config: Dict[str, Dict]
) -> Dict[str, Dict]:
indicators1: list[str], indicators2: list[str], plot_config: dict[str, dict]
) -> dict[str, dict]:
"""
Combines indicators 1 and indicators 2 into plot_config if necessary
:param indicators1: List containing Main plot indicators
@@ -434,9 +434,9 @@ def generate_candlestick_graph(
data: pd.DataFrame,
trades: Optional[pd.DataFrame] = None,
*,
indicators1: Optional[List[str]] = None,
indicators2: Optional[List[str]] = None,
plot_config: Optional[Dict[str, Dict]] = None,
indicators1: Optional[list[str]] = None,
indicators2: Optional[list[str]] = None,
plot_config: Optional[dict[str, dict]] = None,
) -> go.Figure:
"""
Generate the graph from the data generated by Backtesting or from DB
@@ -521,7 +521,7 @@ def generate_candlestick_graph(
def generate_profit_graph(
pairs: str,
data: Dict[str, pd.DataFrame],
data: dict[str, pd.DataFrame],
trades: pd.DataFrame,
timeframe: str,
stake_currency: str,

View File

@@ -5,7 +5,7 @@ Minimum age (days listed) pair list filter
import logging
from copy import deepcopy
from datetime import timedelta
from typing import Dict, List, Optional
from typing import Optional
from pandas import DataFrame
@@ -27,7 +27,7 @@ class AgeFilter(IPairList):
super().__init__(*args, **kwargs)
# Checked symbols cache (dictionary of ticker symbol => timestamp)
self._symbolsChecked: Dict[str, int] = {}
self._symbolsChecked: dict[str, int] = {}
self._symbolsCheckFailed = PeriodicCache(maxsize=1000, ttl=86_400)
self._min_days_listed = self._pairlistconfig.get("min_days_listed", 10)
@@ -78,7 +78,7 @@ class AgeFilter(IPairList):
return "Filter pairs by age (days listed)."
@staticmethod
def available_parameters() -> Dict[str, PairlistParameter]:
def available_parameters() -> dict[str, PairlistParameter]:
return {
"min_days_listed": {
"type": "number",
@@ -94,7 +94,7 @@ class AgeFilter(IPairList):
},
}
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
def filter_pairlist(self, pairlist: list[str], tickers: Tickers) -> list[str]:
"""
:param pairlist: pairlist to filter or sort
:param tickers: Tickers (from exchange.get_tickers). May be cached.

View File

@@ -3,7 +3,6 @@ Full trade slots pair list filter
"""
import logging
from typing import List
from freqtrade.exchange.exchange_types import Tickers
from freqtrade.persistence import Trade
@@ -35,7 +34,7 @@ class FullTradesFilter(IPairList):
def description() -> str:
return "Shrink whitelist when trade slots are full."
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
def filter_pairlist(self, pairlist: list[str], tickers: Tickers) -> list[str]:
"""
Filters and sorts pairlist and returns the allowlist again.
Called on each bot iteration - please use internal caching if necessary

View File

@@ -6,7 +6,7 @@ import logging
from abc import ABC, abstractmethod
from copy import deepcopy
from enum import Enum
from typing import Any, Dict, List, Literal, Optional, TypedDict, Union
from typing import Any, Literal, Optional, TypedDict, Union
from freqtrade.constants import Config
from freqtrade.exceptions import OperationalException
@@ -36,12 +36,12 @@ class __StringPairlistParameter(__PairlistParameterBase):
class __OptionPairlistParameter(__PairlistParameterBase):
type: Literal["option"]
default: Union[str, None]
options: List[str]
options: list[str]
class __ListPairListParamenter(__PairlistParameterBase):
type: Literal["list"]
default: Union[List[str], None]
default: Union[list[str], None]
class __BoolPairlistParameter(__PairlistParameterBase):
@@ -78,7 +78,7 @@ class IPairList(LoggingMixin, ABC):
exchange: Exchange,
pairlistmanager,
config: Config,
pairlistconfig: Dict[str, Any],
pairlistconfig: dict[str, Any],
pairlist_pos: int,
) -> None:
"""
@@ -126,7 +126,7 @@ class IPairList(LoggingMixin, ABC):
return ""
@staticmethod
def available_parameters() -> Dict[str, PairlistParameter]:
def available_parameters() -> dict[str, PairlistParameter]:
"""
Return parameters used by this Pairlist Handler, and their type
contains a dictionary with the parameter name as key, and a dictionary
@@ -136,7 +136,7 @@ class IPairList(LoggingMixin, ABC):
return {}
@staticmethod
def refresh_period_parameter() -> Dict[str, PairlistParameter]:
def refresh_period_parameter() -> dict[str, PairlistParameter]:
return {
"refresh_period": {
"type": "number",
@@ -166,7 +166,7 @@ class IPairList(LoggingMixin, ABC):
"""
raise NotImplementedError()
def gen_pairlist(self, tickers: Tickers) -> List[str]:
def gen_pairlist(self, tickers: Tickers) -> list[str]:
"""
Generate the pairlist.
@@ -185,7 +185,7 @@ class IPairList(LoggingMixin, ABC):
"at the first position in the list of Pairlist Handlers."
)
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
def filter_pairlist(self, pairlist: list[str], tickers: Tickers) -> list[str]:
"""
Filters and sorts pairlist and returns the whitelist again.
@@ -209,7 +209,7 @@ class IPairList(LoggingMixin, ABC):
return pairlist
def verify_blacklist(self, pairlist: List[str], logmethod) -> List[str]:
def verify_blacklist(self, pairlist: list[str], logmethod) -> list[str]:
"""
Proxy method to verify_blacklist for easy access for child classes.
:param pairlist: Pairlist to validate
@@ -219,8 +219,8 @@ class IPairList(LoggingMixin, ABC):
return self._pairlistmanager.verify_blacklist(pairlist, logmethod)
def verify_whitelist(
self, pairlist: List[str], logmethod, keep_invalid: bool = False
) -> List[str]:
self, pairlist: list[str], logmethod, keep_invalid: bool = False
) -> list[str]:
"""
Proxy method to verify_whitelist for easy access for child classes.
:param pairlist: Pairlist to validate
@@ -230,7 +230,7 @@ class IPairList(LoggingMixin, ABC):
"""
return self._pairlistmanager.verify_whitelist(pairlist, logmethod, keep_invalid)
def _whitelist_for_active_markets(self, pairlist: List[str]) -> List[str]:
def _whitelist_for_active_markets(self, pairlist: list[str]) -> list[str]:
"""
Check available markets and remove pair from whitelist if necessary
:param pairlist: the sorted list of pairs the user might want to trade
@@ -243,7 +243,7 @@ class IPairList(LoggingMixin, ABC):
"Markets not loaded. Make sure that exchange is initialized correctly."
)
sanitized_whitelist: List[str] = []
sanitized_whitelist: list[str] = []
for pair in pairlist:
# pair is not in the generated dynamic market or has the wrong stake currency
if pair not in markets:

View File

@@ -5,7 +5,6 @@ Provides dynamic pair list based on Market Cap
"""
import logging
from typing import Dict, List
from cachetools import TTLCache
@@ -83,7 +82,7 @@ class MarketCapPairList(IPairList):
return "Provides pair list based on CoinGecko's market cap rank."
@staticmethod
def available_parameters() -> Dict[str, PairlistParameter]:
def available_parameters() -> dict[str, PairlistParameter]:
return {
"number_assets": {
"type": "number",
@@ -114,7 +113,7 @@ class MarketCapPairList(IPairList):
},
}
def gen_pairlist(self, tickers: Tickers) -> List[str]:
def gen_pairlist(self, tickers: Tickers) -> list[str]:
"""
Generate the pairlist
:param tickers: Tickers (from exchange.get_tickers). May be cached.
@@ -143,7 +142,7 @@ class MarketCapPairList(IPairList):
return pairlist
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
def filter_pairlist(self, pairlist: list[str], tickers: dict) -> list[str]:
"""
Filters and sorts pairlist and returns the whitelist again.
Called on each bot iteration - please use internal caching if necessary

View File

@@ -3,7 +3,6 @@ Offset pair list filter
"""
import logging
from typing import Dict, List
from freqtrade.exceptions import OperationalException
from freqtrade.exchange.exchange_types import Tickers
@@ -47,7 +46,7 @@ class OffsetFilter(IPairList):
return "Offset pair list filter."
@staticmethod
def available_parameters() -> Dict[str, PairlistParameter]:
def available_parameters() -> dict[str, PairlistParameter]:
return {
"offset": {
"type": "number",
@@ -63,7 +62,7 @@ class OffsetFilter(IPairList):
},
}
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
def filter_pairlist(self, pairlist: list[str], tickers: Tickers) -> list[str]:
"""
Filters and sorts pairlist and returns the whitelist again.
Called on each bot iteration - please use internal caching if necessary

View File

@@ -8,7 +8,7 @@ defined period or as coming from ticker
import logging
from datetime import timedelta
from typing import Any, Dict, List, Optional
from typing import Any, Optional
from cachetools import TTLCache
from pandas import DataFrame
@@ -115,7 +115,7 @@ class PercentChangePairList(IPairList):
return "Provides dynamic pair list based on percentage change."
@staticmethod
def available_parameters() -> Dict[str, PairlistParameter]:
def available_parameters() -> dict[str, PairlistParameter]:
return {
"number_assets": {
"type": "number",
@@ -163,7 +163,7 @@ class PercentChangePairList(IPairList):
},
}
def gen_pairlist(self, tickers: Tickers) -> List[str]:
def gen_pairlist(self, tickers: Tickers) -> list[str]:
"""
Generate the pairlist
:param tickers: Tickers (from exchange.get_tickers). May be cached.
@@ -204,7 +204,7 @@ class PercentChangePairList(IPairList):
return pairlist
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
def filter_pairlist(self, pairlist: list[str], tickers: dict) -> list[str]:
"""
Filters and sorts pairlist and returns the whitelist again.
Called on each bot iteration - please use internal caching if necessary
@@ -212,7 +212,7 @@ class PercentChangePairList(IPairList):
:param tickers: Tickers (from exchange.get_tickers). May be cached.
:return: new whitelist
"""
filtered_tickers: List[Dict[str, Any]] = [{"symbol": k} for k in pairlist]
filtered_tickers: list[dict[str, Any]] = [{"symbol": k} for k in pairlist]
if self._use_range:
# calculating using lookback_period
self.fetch_percent_change_from_lookback_period(filtered_tickers)
@@ -240,8 +240,8 @@ class PercentChangePairList(IPairList):
return pairs
def fetch_candles_for_lookback_period(
self, filtered_tickers: List[Dict[str, str]]
) -> Dict[PairWithTimeframe, DataFrame]:
self, filtered_tickers: list[dict[str, str]]
) -> dict[PairWithTimeframe, DataFrame]:
since_ms = (
int(
timeframe_to_prev_date(
@@ -277,7 +277,7 @@ class PercentChangePairList(IPairList):
candles = self._exchange.refresh_ohlcv_with_cache(needed_pairs, since_ms)
return candles
def fetch_percent_change_from_lookback_period(self, filtered_tickers: List[Dict[str, Any]]):
def fetch_percent_change_from_lookback_period(self, filtered_tickers: list[dict[str, Any]]):
# get lookback period in ms, for exchange ohlcv fetch
candles = self.fetch_candles_for_lookback_period(filtered_tickers)
@@ -301,7 +301,7 @@ class PercentChangePairList(IPairList):
else:
filtered_tickers[i]["percentage"] = 0
def fetch_percent_change_from_tickers(self, filtered_tickers: List[Dict[str, Any]], tickers):
def fetch_percent_change_from_tickers(self, filtered_tickers: list[dict[str, Any]], tickers):
for i, p in enumerate(filtered_tickers):
# Filter out assets
if not self._validate_pair(

View File

@@ -3,7 +3,6 @@ Performance pair list filter
"""
import logging
from typing import Dict, List
import pandas as pd
@@ -44,7 +43,7 @@ class PerformanceFilter(IPairList):
return "Filter pairs by performance."
@staticmethod
def available_parameters() -> Dict[str, PairlistParameter]:
def available_parameters() -> dict[str, PairlistParameter]:
return {
"minutes": {
"type": "number",
@@ -60,7 +59,7 @@ class PerformanceFilter(IPairList):
},
}
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
def filter_pairlist(self, pairlist: list[str], tickers: Tickers) -> list[str]:
"""
Filters and sorts pairlist and returns the allowlist again.
Called on each bot iteration - please use internal caching if necessary

View File

@@ -3,7 +3,7 @@ Price pair list filter
"""
import logging
from typing import Dict, Optional
from typing import Optional
from freqtrade.exceptions import OperationalException
from freqtrade.exchange.exchange_types import Ticker
@@ -71,7 +71,7 @@ class PriceFilter(IPairList):
return "Filter pairs by price."
@staticmethod
def available_parameters() -> Dict[str, PairlistParameter]:
def available_parameters() -> dict[str, PairlistParameter]:
return {
"low_price_ratio": {
"type": "number",

View File

@@ -5,7 +5,7 @@ Provides pair list from Leader data
"""
import logging
from typing import Dict, List, Optional
from typing import Optional
from freqtrade.exceptions import OperationalException
from freqtrade.exchange.exchange_types import Tickers
@@ -64,7 +64,7 @@ class ProducerPairList(IPairList):
return "Get a pairlist from an upstream bot."
@staticmethod
def available_parameters() -> Dict[str, PairlistParameter]:
def available_parameters() -> dict[str, PairlistParameter]:
return {
"number_assets": {
"type": "number",
@@ -83,7 +83,7 @@ class ProducerPairList(IPairList):
},
}
def _filter_pairlist(self, pairlist: Optional[List[str]]):
def _filter_pairlist(self, pairlist: Optional[list[str]]):
upstream_pairlist = self._pairlistmanager._dataprovider.get_producer_pairs(
self._producer_name
)
@@ -97,7 +97,7 @@ class ProducerPairList(IPairList):
return pairs
def gen_pairlist(self, tickers: Tickers) -> List[str]:
def gen_pairlist(self, tickers: Tickers) -> list[str]:
"""
Generate the pairlist
:param tickers: Tickers (from exchange.get_tickers). May be cached.
@@ -108,7 +108,7 @@ class ProducerPairList(IPairList):
pairs = self._whitelist_for_active_markets(self.verify_whitelist(pairs, logger.info))
return pairs
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
def filter_pairlist(self, pairlist: list[str], tickers: Tickers) -> list[str]:
"""
Filters and sorts pairlist and returns the whitelist again.
Called on each bot iteration - please use internal caching if necessary

View File

@@ -6,7 +6,7 @@ Provides pair list fetched from a remote source
import logging
from pathlib import Path
from typing import Any, Dict, List, Tuple
from typing import Any
import rapidjson
import requests
@@ -54,7 +54,7 @@ class RemotePairList(IPairList):
self._bearer_token = self._pairlistconfig.get("bearer_token", "")
self._init_done = False
self._save_to_file = self._pairlistconfig.get("save_to_file", None)
self._last_pairlist: List[Any] = list()
self._last_pairlist: list[Any] = list()
if self._mode not in ["whitelist", "blacklist"]:
raise OperationalException(
@@ -93,7 +93,7 @@ class RemotePairList(IPairList):
return "Retrieve pairs from a remote API or local file."
@staticmethod
def available_parameters() -> Dict[str, PairlistParameter]:
def available_parameters() -> dict[str, PairlistParameter]:
return {
"pairlist_url": {
"type": "string",
@@ -148,7 +148,7 @@ class RemotePairList(IPairList):
},
}
def process_json(self, jsonparse) -> List[str]:
def process_json(self, jsonparse) -> list[str]:
pairlist = jsonparse.get("pairs", [])
remote_refresh_period = int(jsonparse.get("refresh_period", self._refresh_period))
@@ -166,7 +166,7 @@ class RemotePairList(IPairList):
return pairlist
def return_last_pairlist(self) -> List[str]:
def return_last_pairlist(self) -> list[str]:
if self._keep_pairlist_on_failure:
pairlist = self._last_pairlist
self.log_once("Keeping last fetched pairlist", logger.info)
@@ -175,7 +175,7 @@ class RemotePairList(IPairList):
return pairlist
def fetch_pairlist(self) -> Tuple[List[str], float]:
def fetch_pairlist(self) -> tuple[list[str], float]:
headers = {"User-Agent": "Freqtrade/" + __version__ + " Remotepairlist"}
if self._bearer_token:
@@ -207,14 +207,14 @@ class RemotePairList(IPairList):
return pairlist, time_elapsed
def _handle_error(self, error: str) -> List[str]:
def _handle_error(self, error: str) -> list[str]:
if self._init_done:
self.log_once("Error: " + error, logger.info)
return self.return_last_pairlist()
else:
raise OperationalException(error)
def gen_pairlist(self, tickers: Tickers) -> List[str]:
def gen_pairlist(self, tickers: Tickers) -> list[str]:
"""
Generate the pairlist
:param tickers: Tickers (from exchange.get_tickers). May be cached.
@@ -278,7 +278,7 @@ class RemotePairList(IPairList):
return pairlist
def save_pairlist(self, pairlist: List[str], filename: str) -> None:
def save_pairlist(self, pairlist: list[str], filename: str) -> None:
pairlist_data = {"pairs": pairlist}
try:
file_path = Path(filename)
@@ -288,7 +288,7 @@ class RemotePairList(IPairList):
except Exception as e:
logger.error(f"Error saving processed pairlist to {filename}: {e}")
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
def filter_pairlist(self, pairlist: list[str], tickers: dict) -> list[str]:
"""
Filters and sorts pairlist and returns the whitelist again.
Called on each bot iteration - please use internal caching if necessary

View File

@@ -4,7 +4,7 @@ Shuffle pair list filter
import logging
import random
from typing import Dict, List, Literal
from typing import Literal
from freqtrade.enums import RunMode
from freqtrade.exchange import timeframe_to_seconds
@@ -61,7 +61,7 @@ class ShuffleFilter(IPairList):
return "Randomize pairlist order."
@staticmethod
def available_parameters() -> Dict[str, PairlistParameter]:
def available_parameters() -> dict[str, PairlistParameter]:
return {
"shuffle_frequency": {
"type": "option",
@@ -78,7 +78,7 @@ class ShuffleFilter(IPairList):
},
}
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
def filter_pairlist(self, pairlist: list[str], tickers: Tickers) -> list[str]:
"""
Filters and sorts pairlist and returns the whitelist again.
Called on each bot iteration - please use internal caching if necessary

View File

@@ -3,7 +3,7 @@ Spread pair list filter
"""
import logging
from typing import Dict, Optional
from typing import Optional
from freqtrade.exceptions import OperationalException
from freqtrade.exchange.exchange_types import Ticker
@@ -51,7 +51,7 @@ class SpreadFilter(IPairList):
return "Filter by bid/ask difference."
@staticmethod
def available_parameters() -> Dict[str, PairlistParameter]:
def available_parameters() -> dict[str, PairlistParameter]:
return {
"max_spread_ratio": {
"type": "number",

View File

@@ -6,7 +6,6 @@ Provides pair white list as it configured in config
import logging
from copy import deepcopy
from typing import Dict, List
from freqtrade.exchange.exchange_types import Tickers
from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting
@@ -45,7 +44,7 @@ class StaticPairList(IPairList):
return "Use pairlist as configured in config."
@staticmethod
def available_parameters() -> Dict[str, PairlistParameter]:
def available_parameters() -> dict[str, PairlistParameter]:
return {
"allow_inactive": {
"type": "boolean",
@@ -55,7 +54,7 @@ class StaticPairList(IPairList):
},
}
def gen_pairlist(self, tickers: Tickers) -> List[str]:
def gen_pairlist(self, tickers: Tickers) -> list[str]:
"""
Generate the pairlist
:param tickers: Tickers (from exchange.get_tickers). May be cached.
@@ -71,7 +70,7 @@ class StaticPairList(IPairList):
# proper warnings in the log
return self._whitelist_for_active_markets(wl)
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
def filter_pairlist(self, pairlist: list[str], tickers: Tickers) -> list[str]:
"""
Filters and sorts pairlist and returns the whitelist again.
Called on each bot iteration - please use internal caching if necessary

View File

@@ -5,7 +5,7 @@ Volatility pairlist filter
import logging
import sys
from datetime import timedelta
from typing import Dict, List, Optional
from typing import Optional
import numpy as np
from cachetools import TTLCache
@@ -79,7 +79,7 @@ class VolatilityFilter(IPairList):
return "Filter pairs by their recent volatility."
@staticmethod
def available_parameters() -> Dict[str, PairlistParameter]:
def available_parameters() -> dict[str, PairlistParameter]:
return {
"lookback_days": {
"type": "number",
@@ -109,7 +109,7 @@ class VolatilityFilter(IPairList):
**IPairList.refresh_period_parameter(),
}
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
def filter_pairlist(self, pairlist: list[str], tickers: Tickers) -> list[str]:
"""
Validate trading range
:param pairlist: pairlist to filter or sort
@@ -123,8 +123,8 @@ class VolatilityFilter(IPairList):
since_ms = dt_ts(dt_floor_day(dt_now()) - timedelta(days=self._days))
candles = self._exchange.refresh_ohlcv_with_cache(needed_pairs, since_ms=since_ms)
resulting_pairlist: List[str] = []
volatilitys: Dict[str, float] = {}
resulting_pairlist: list[str] = []
volatilitys: dict[str, float] = {}
for p in pairlist:
daily_candles = candles.get((p, "1d", self._def_candletype), None)

View File

@@ -6,7 +6,7 @@ Provides dynamic pair list based on trade volumes
import logging
from datetime import timedelta
from typing import Any, Dict, List, Literal
from typing import Any, Literal
from cachetools import TTLCache
@@ -122,7 +122,7 @@ class VolumePairList(IPairList):
return "Provides dynamic pair list based on trade volumes."
@staticmethod
def available_parameters() -> Dict[str, PairlistParameter]:
def available_parameters() -> dict[str, PairlistParameter]:
return {
"number_assets": {
"type": "number",
@@ -170,7 +170,7 @@ class VolumePairList(IPairList):
},
}
def gen_pairlist(self, tickers: Tickers) -> List[str]:
def gen_pairlist(self, tickers: Tickers) -> list[str]:
"""
Generate the pairlist
:param tickers: Tickers (from exchange.get_tickers). May be cached.
@@ -212,7 +212,7 @@ class VolumePairList(IPairList):
return pairlist
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
def filter_pairlist(self, pairlist: list[str], tickers: dict) -> list[str]:
"""
Filters and sorts pairlist and returns the whitelist again.
Called on each bot iteration - please use internal caching if necessary
@@ -222,7 +222,7 @@ class VolumePairList(IPairList):
"""
if self._use_range:
# Create bare minimum from tickers structure.
filtered_tickers: List[Dict[str, Any]] = [{"symbol": k} for k in pairlist]
filtered_tickers: list[dict[str, Any]] = [{"symbol": k} for k in pairlist]
# get lookback period in ms, for exchange ohlcv fetch
since_ms = (

View File

@@ -1,12 +1,11 @@
import re
from typing import List
from freqtrade.constants import Config
def expand_pairlist(
wildcardpl: List[str], available_pairs: List[str], keep_invalid: bool = False
) -> List[str]:
wildcardpl: list[str], available_pairs: list[str], keep_invalid: bool = False
) -> list[str]:
"""
Expand pairlist potentially containing wildcards based on available markets.
This will implicitly filter all pairs in the wildcard-list which are not in available_pairs.
@@ -41,7 +40,7 @@ def expand_pairlist(
return result
def dynamic_expand_pairlist(config: Config, markets: List[str]) -> List[str]:
def dynamic_expand_pairlist(config: Config, markets: list[str]) -> list[str]:
expanded_pairs = expand_pairlist(config["pairs"], markets)
if config.get("freqai", {}).get("enabled", False):
corr_pairlist = config["freqai"]["feature_parameters"]["include_corr_pairlist"]

View File

@@ -4,7 +4,7 @@ Rate of change pairlist filter
import logging
from datetime import timedelta
from typing import Dict, List, Optional
from typing import Optional
from cachetools import TTLCache
from pandas import DataFrame
@@ -76,7 +76,7 @@ class RangeStabilityFilter(IPairList):
return "Filters pairs by their rate of change."
@staticmethod
def available_parameters() -> Dict[str, PairlistParameter]:
def available_parameters() -> dict[str, PairlistParameter]:
return {
"lookback_days": {
"type": "number",
@@ -106,7 +106,7 @@ class RangeStabilityFilter(IPairList):
**IPairList.refresh_period_parameter(),
}
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
def filter_pairlist(self, pairlist: list[str], tickers: Tickers) -> list[str]:
"""
Validate trading range
:param pairlist: pairlist to filter or sort
@@ -120,8 +120,8 @@ class RangeStabilityFilter(IPairList):
since_ms = dt_ts(dt_floor_day(dt_now()) - timedelta(days=self._days + 1))
candles = self._exchange.refresh_ohlcv_with_cache(needed_pairs, since_ms=since_ms)
resulting_pairlist: List[str] = []
pct_changes: Dict[str, float] = {}
resulting_pairlist: list[str] = []
pct_changes: dict[str, float] = {}
for p in pairlist:
daily_candles = candles.get((p, "1d", self._def_candletype), None)

View File

@@ -4,7 +4,7 @@ PairList manager class
import logging
from functools import partial
from typing import Dict, List, Optional
from typing import Optional
from cachetools import TTLCache, cached
@@ -31,7 +31,7 @@ class PairListManager(LoggingMixin):
self._config = config
self._whitelist = self._config["exchange"].get("pair_whitelist")
self._blacklist = self._config["exchange"].get("pair_blacklist", [])
self._pairlist_handlers: List[IPairList] = []
self._pairlist_handlers: list[IPairList] = []
self._tickers_needed = False
self._dataprovider: Optional[DataProvider] = dataprovider
for pairlist_handler_config in self._config.get("pairlists", []):
@@ -67,9 +67,9 @@ class PairListManager(LoggingMixin):
if self._config["runmode"] not in (RunMode.BACKTEST, RunMode.EDGE, RunMode.HYPEROPT):
return
pairlist_errors: List[str] = []
noaction_pairlists: List[str] = []
biased_pairlists: List[str] = []
pairlist_errors: list[str] = []
noaction_pairlists: list[str] = []
biased_pairlists: list[str] = []
for pairlist_handler in self._pairlist_handlers:
if pairlist_handler.supports_backtesting == SupportsBacktesting.NO:
pairlist_errors.append(pairlist_handler.name)
@@ -97,12 +97,12 @@ class PairListManager(LoggingMixin):
)
@property
def whitelist(self) -> List[str]:
def whitelist(self) -> list[str]:
"""The current whitelist"""
return self._whitelist
@property
def blacklist(self) -> List[str]:
def blacklist(self) -> list[str]:
"""
The current blacklist
-> no need to overwrite in subclasses
@@ -110,16 +110,16 @@ class PairListManager(LoggingMixin):
return self._blacklist
@property
def expanded_blacklist(self) -> List[str]:
def expanded_blacklist(self) -> list[str]:
"""The expanded blacklist (including wildcard expansion)"""
return expand_pairlist(self._blacklist, self._exchange.get_markets().keys())
@property
def name_list(self) -> List[str]:
def name_list(self) -> list[str]:
"""Get list of loaded Pairlist Handler names"""
return [p.name for p in self._pairlist_handlers]
def short_desc(self) -> List[Dict]:
def short_desc(self) -> list[dict]:
"""List of short_desc for each Pairlist Handler"""
return [{p.name: p.short_desc()} for p in self._pairlist_handlers]
@@ -130,7 +130,7 @@ class PairListManager(LoggingMixin):
def refresh_pairlist(self) -> None:
"""Run pairlist through all configured Pairlist Handlers."""
# Tickers should be cached to avoid calling the exchange on each call.
tickers: Dict = {}
tickers: dict = {}
if self._tickers_needed:
tickers = self._get_cached_tickers()
@@ -150,7 +150,7 @@ class PairListManager(LoggingMixin):
self._whitelist = pairlist
def verify_blacklist(self, pairlist: List[str], logmethod) -> List[str]:
def verify_blacklist(self, pairlist: list[str], logmethod) -> list[str]:
"""
Verify and remove items from pairlist - returning a filtered pairlist.
Logs a warning or info depending on `aswarning`.
@@ -173,8 +173,8 @@ class PairListManager(LoggingMixin):
return pairlist
def verify_whitelist(
self, pairlist: List[str], logmethod, keep_invalid: bool = False
) -> List[str]:
self, pairlist: list[str], logmethod, keep_invalid: bool = False
) -> list[str]:
"""
Verify and remove items from pairlist - returning a filtered pairlist.
Logs a warning or info depending on `aswarning`.
@@ -193,7 +193,7 @@ class PairListManager(LoggingMixin):
return whitelist
def create_pair_list(
self, pairs: List[str], timeframe: Optional[str] = None
self, pairs: list[str], timeframe: Optional[str] = None
) -> ListPairsWithTimeframes:
"""
Create list of pair tuples with (pair, timeframe)

View File

@@ -4,7 +4,7 @@ Protection manager class
import logging
from datetime import datetime, timezone
from typing import Any, Dict, List, Optional
from typing import Any, Optional
from freqtrade.constants import Config, LongShort
from freqtrade.exceptions import ConfigurationError
@@ -18,10 +18,10 @@ logger = logging.getLogger(__name__)
class ProtectionManager:
def __init__(self, config: Config, protections: List) -> None:
def __init__(self, config: Config, protections: list) -> None:
self._config = config
self._protection_handlers: List[IProtection] = []
self._protection_handlers: list[IProtection] = []
self.validate_protections(protections)
for protection_handler_config in protections:
protection_handler = ProtectionResolver.load_protection(
@@ -35,13 +35,13 @@ class ProtectionManager:
logger.info("No protection Handlers defined.")
@property
def name_list(self) -> List[str]:
def name_list(self) -> list[str]:
"""
Get list of loaded Protection Handler names
"""
return [p.name for p in self._protection_handlers]
def short_desc(self) -> List[Dict]:
def short_desc(self) -> list[dict]:
"""
List of short_desc for each Pairlist Handler
"""
@@ -80,7 +80,7 @@ class ProtectionManager:
return result
@staticmethod
def validate_protections(protections: List[Dict[str, Any]]) -> None:
def validate_protections(protections: list[dict[str, Any]]) -> None:
"""
Validate protection setup validity
"""

View File

@@ -2,7 +2,7 @@ import logging
from abc import ABC, abstractmethod
from dataclasses import dataclass
from datetime import datetime, timedelta, timezone
from typing import Any, Dict, List, Optional
from typing import Any, Optional
from freqtrade.constants import Config, LongShort
from freqtrade.exchange import timeframe_to_minutes
@@ -28,7 +28,7 @@ class IProtection(LoggingMixin, ABC):
# Can stop trading for one pair
has_local_stop: bool = False
def __init__(self, config: Config, protection_config: Dict[str, Any]) -> None:
def __init__(self, config: Config, protection_config: dict[str, Any]) -> None:
self._config = config
self._protection_config = protection_config
self._stop_duration_candles: Optional[int] = None
@@ -119,7 +119,7 @@ class IProtection(LoggingMixin, ABC):
If true, this pair will be locked with <reason> until <until>
"""
def calculate_lock_end(self, trades: List[LocalTrade]) -> datetime:
def calculate_lock_end(self, trades: list[LocalTrade]) -> datetime:
"""
Get lock end time
Implicitly uses `self._stop_duration` or `self._unlock_at` depending on the configuration.

View File

@@ -1,6 +1,6 @@
import logging
from datetime import datetime, timedelta
from typing import Any, Dict, Optional
from typing import Any, Optional
from freqtrade.constants import Config, LongShort
from freqtrade.persistence import Trade
@@ -14,7 +14,7 @@ class LowProfitPairs(IProtection):
has_global_stop: bool = False
has_local_stop: bool = True
def __init__(self, config: Config, protection_config: Dict[str, Any]) -> None:
def __init__(self, config: Config, protection_config: dict[str, Any]) -> None:
super().__init__(config, protection_config)
self._trade_limit = protection_config.get("trade_limit", 1)

View File

@@ -1,6 +1,6 @@
import logging
from datetime import datetime, timedelta
from typing import Any, Dict, Optional
from typing import Any, Optional
import pandas as pd
@@ -17,7 +17,7 @@ class MaxDrawdown(IProtection):
has_global_stop: bool = True
has_local_stop: bool = False
def __init__(self, config: Config, protection_config: Dict[str, Any]) -> None:
def __init__(self, config: Config, protection_config: dict[str, Any]) -> None:
super().__init__(config, protection_config)
self._trade_limit = protection_config.get("trade_limit", 1)

View File

@@ -1,6 +1,6 @@
import logging
from datetime import datetime, timedelta
from typing import Any, Dict, Optional
from typing import Any, Optional
from freqtrade.constants import Config, LongShort
from freqtrade.enums import ExitType
@@ -15,7 +15,7 @@ class StoplossGuard(IProtection):
has_global_stop: bool = True
has_local_stop: bool = True
def __init__(self, config: Config, protection_config: Dict[str, Any]) -> None:
def __init__(self, config: Config, protection_config: dict[str, Any]) -> None:
super().__init__(config, protection_config)
self._trade_limit = protection_config.get("trade_limit", 10)