mirror of
https://github.com/freqtrade/freqtrade.git
synced 2026-01-28 18:00:23 +00:00
chore: update plugins to modern typing syntax
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 = (
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user