Merge pull request #8040 from xmatthias/mypy_fixes

Enable mypy defaults for Optional typechecking
This commit is contained in:
Matthias 2023-01-22 11:18:53 +01:00 committed by GitHub
commit 95987663f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 90 additions and 75 deletions

View File

@ -28,7 +28,7 @@ class Configuration:
Reuse this class for the bot, backtesting, hyperopt and every script that required configuration Reuse this class for the bot, backtesting, hyperopt and every script that required configuration
""" """
def __init__(self, args: Dict[str, Any], runmode: RunMode = None) -> None: def __init__(self, args: Dict[str, Any], runmode: Optional[RunMode] = None) -> None:
self.args = args self.args = args
self.config: Optional[Config] = None self.config: Optional[Config] = None
self.runmode = runmode self.runmode = runmode

View File

@ -6,7 +6,7 @@ import re
import sys import sys
from copy import deepcopy from copy import deepcopy
from pathlib import Path from pathlib import Path
from typing import Any, Dict, List from typing import Any, Dict, List, Optional
import rapidjson import rapidjson
@ -75,7 +75,8 @@ def load_config_file(path: str) -> Dict[str, Any]:
return config return config
def load_from_files(files: List[str], base_path: Path = None, level: int = 0) -> Dict[str, Any]: def load_from_files(
files: List[str], base_path: Optional[Path] = None, level: int = 0) -> Dict[str, Any]:
""" """
Recursively load configuration files if specified. Recursively load configuration files if specified.
Sub-files are assumed to be relative to the initial config. Sub-files are assumed to be relative to the initial config.

View File

@ -90,7 +90,8 @@ def get_latest_hyperopt_filename(directory: Union[Path, str]) -> str:
return 'hyperopt_results.pickle' return 'hyperopt_results.pickle'
def get_latest_hyperopt_file(directory: Union[Path, str], predef_filename: str = None) -> Path: def get_latest_hyperopt_file(
directory: Union[Path, str], predef_filename: Optional[str] = None) -> Path:
""" """
Get latest hyperopt export based on '.last_result.json'. Get latest hyperopt export based on '.last_result.json'.
:param directory: Directory to search for last result :param directory: Directory to search for last result
@ -193,7 +194,7 @@ def get_backtest_resultlist(dirname: Path):
def find_existing_backtest_stats(dirname: Union[Path, str], run_ids: Dict[str, str], def find_existing_backtest_stats(dirname: Union[Path, str], run_ids: Dict[str, str],
min_backtest_date: datetime = None) -> Dict[str, Any]: min_backtest_date: Optional[datetime] = None) -> Dict[str, Any]:
""" """
Find existing backtest stats that match specified run IDs and load them. Find existing backtest stats that match specified run IDs and load them.
:param dirname: pathlib.Path object, or string pointing to the file. :param dirname: pathlib.Path object, or string pointing to the file.

View File

@ -281,7 +281,7 @@ class DataProvider:
def historic_ohlcv( def historic_ohlcv(
self, self,
pair: str, pair: str,
timeframe: str = None, timeframe: Optional[str] = None,
candle_type: str = '' candle_type: str = ''
) -> DataFrame: ) -> DataFrame:
""" """
@ -333,7 +333,7 @@ class DataProvider:
def get_pair_dataframe( def get_pair_dataframe(
self, self,
pair: str, pair: str,
timeframe: str = None, timeframe: Optional[str] = None,
candle_type: str = '' candle_type: str = ''
) -> DataFrame: ) -> DataFrame:
""" """
@ -415,7 +415,7 @@ class DataProvider:
def refresh(self, def refresh(self,
pairlist: ListPairsWithTimeframes, pairlist: ListPairsWithTimeframes,
helping_pairs: ListPairsWithTimeframes = None) -> None: helping_pairs: Optional[ListPairsWithTimeframes] = None) -> None:
""" """
Refresh data, called with each cycle Refresh data, called with each cycle
""" """
@ -439,7 +439,7 @@ class DataProvider:
def ohlcv( def ohlcv(
self, self,
pair: str, pair: str,
timeframe: str = None, timeframe: Optional[str] = None,
copy: bool = True, copy: bool = True,
candle_type: str = '' candle_type: str = ''
) -> DataFrame: ) -> DataFrame:

View File

@ -28,8 +28,8 @@ def load_pair_history(pair: str,
fill_up_missing: bool = True, fill_up_missing: bool = True,
drop_incomplete: bool = False, drop_incomplete: bool = False,
startup_candles: int = 0, startup_candles: int = 0,
data_format: str = None, data_format: Optional[str] = None,
data_handler: IDataHandler = None, data_handler: Optional[IDataHandler] = None,
candle_type: CandleType = CandleType.SPOT candle_type: CandleType = CandleType.SPOT
) -> DataFrame: ) -> DataFrame:
""" """
@ -69,7 +69,7 @@ def load_data(datadir: Path,
fail_without_data: bool = False, fail_without_data: bool = False,
data_format: str = 'json', data_format: str = 'json',
candle_type: CandleType = CandleType.SPOT, candle_type: CandleType = CandleType.SPOT,
user_futures_funding_rate: int = None, user_futures_funding_rate: Optional[int] = None,
) -> Dict[str, DataFrame]: ) -> Dict[str, DataFrame]:
""" """
Load ohlcv history data for a list of pairs. Load ohlcv history data for a list of pairs.
@ -116,7 +116,7 @@ def refresh_data(*, datadir: Path,
timeframe: str, timeframe: str,
pairs: List[str], pairs: List[str],
exchange: Exchange, exchange: Exchange,
data_format: str = None, data_format: Optional[str] = None,
timerange: Optional[TimeRange] = None, timerange: Optional[TimeRange] = None,
candle_type: CandleType, candle_type: CandleType,
) -> None: ) -> None:
@ -189,7 +189,7 @@ def _download_pair_history(pair: str, *,
timeframe: str = '5m', timeframe: str = '5m',
process: str = '', process: str = '',
new_pairs_days: int = 30, new_pairs_days: int = 30,
data_handler: IDataHandler = None, data_handler: Optional[IDataHandler] = None,
timerange: Optional[TimeRange] = None, timerange: Optional[TimeRange] = None,
candle_type: CandleType, candle_type: CandleType,
erase: bool = False, erase: bool = False,
@ -272,7 +272,7 @@ def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes
datadir: Path, trading_mode: str, datadir: Path, trading_mode: str,
timerange: Optional[TimeRange] = None, timerange: Optional[TimeRange] = None,
new_pairs_days: int = 30, erase: bool = False, new_pairs_days: int = 30, erase: bool = False,
data_format: str = None, data_format: Optional[str] = None,
prepend: bool = False, prepend: bool = False,
) -> List[str]: ) -> List[str]:
""" """

View File

@ -418,8 +418,8 @@ def get_datahandlerclass(datatype: str) -> Type[IDataHandler]:
raise ValueError(f"No datahandler for datatype {datatype} available.") raise ValueError(f"No datahandler for datatype {datatype} available.")
def get_datahandler(datadir: Path, data_format: str = None, def get_datahandler(datadir: Path, data_format: Optional[str] = None,
data_handler: IDataHandler = None) -> IDataHandler: data_handler: Optional[IDataHandler] = None) -> IDataHandler:
""" """
:param datadir: Folder to save data :param datadir: Folder to save data
:param data_format: dataformat to use :param data_format: dataformat to use

View File

@ -675,7 +675,7 @@ class Exchange:
f"Freqtrade does not support {mm_value} {trading_mode.value} on {self.name}" f"Freqtrade does not support {mm_value} {trading_mode.value} on {self.name}"
) )
def get_option(self, param: str, default: Any = None) -> Any: def get_option(self, param: str, default: Optional[Any] = None) -> Any:
""" """
Get parameter value from _ft_has Get parameter value from _ft_has
""" """
@ -1350,7 +1350,7 @@ class Exchange:
raise OperationalException(e) from e raise OperationalException(e) from e
@retrier @retrier
def fetch_positions(self, pair: str = None) -> List[Dict]: def fetch_positions(self, pair: Optional[str] = None) -> List[Dict]:
""" """
Fetch positions from the exchange. Fetch positions from the exchange.
If no pair is given, all positions are returned. If no pair is given, all positions are returned.
@ -1794,7 +1794,7 @@ class Exchange:
def get_historic_ohlcv(self, pair: str, timeframe: str, def get_historic_ohlcv(self, pair: str, timeframe: str,
since_ms: int, candle_type: CandleType, since_ms: int, candle_type: CandleType,
is_new_pair: bool = False, is_new_pair: bool = False,
until_ms: int = None) -> List: until_ms: Optional[int] = None) -> List:
""" """
Get candle history using asyncio and returns the list of candles. Get candle history using asyncio and returns the list of candles.
Handles all async work for this. Handles all async work for this.

View File

@ -15,18 +15,19 @@ from freqtrade.util import FtPrecise
CcxtModuleType = Any CcxtModuleType = Any
def is_exchange_known_ccxt(exchange_name: str, ccxt_module: CcxtModuleType = None) -> bool: def is_exchange_known_ccxt(
exchange_name: str, ccxt_module: Optional[CcxtModuleType] = None) -> bool:
return exchange_name in ccxt_exchanges(ccxt_module) return exchange_name in ccxt_exchanges(ccxt_module)
def ccxt_exchanges(ccxt_module: CcxtModuleType = None) -> List[str]: def ccxt_exchanges(ccxt_module: Optional[CcxtModuleType] = None) -> List[str]:
""" """
Return the list of all exchanges known to ccxt Return the list of all exchanges known to ccxt
""" """
return ccxt_module.exchanges if ccxt_module is not None else ccxt.exchanges return ccxt_module.exchanges if ccxt_module is not None else ccxt.exchanges
def available_exchanges(ccxt_module: CcxtModuleType = None) -> List[str]: def available_exchanges(ccxt_module: Optional[CcxtModuleType] = None) -> List[str]:
""" """
Return exchanges available to the bot, i.e. non-bad exchanges in the ccxt list Return exchanges available to the bot, i.e. non-bad exchanges in the ccxt list
""" """
@ -86,7 +87,7 @@ def timeframe_to_msecs(timeframe: str) -> int:
return ccxt.Exchange.parse_timeframe(timeframe) * 1000 return ccxt.Exchange.parse_timeframe(timeframe) * 1000
def timeframe_to_prev_date(timeframe: str, date: datetime = None) -> datetime: def timeframe_to_prev_date(timeframe: str, date: Optional[datetime] = None) -> datetime:
""" """
Use Timeframe and determine the candle start date for this date. Use Timeframe and determine the candle start date for this date.
Does not round when given a candle start date. Does not round when given a candle start date.
@ -102,7 +103,7 @@ def timeframe_to_prev_date(timeframe: str, date: datetime = None) -> datetime:
return datetime.fromtimestamp(new_timestamp, tz=timezone.utc) return datetime.fromtimestamp(new_timestamp, tz=timezone.utc)
def timeframe_to_next_date(timeframe: str, date: datetime = None) -> datetime: def timeframe_to_next_date(timeframe: str, date: Optional[datetime] = None) -> datetime:
""" """
Use Timeframe and determine next candle. Use Timeframe and determine next candle.
:param timeframe: timeframe in string format (e.g. "5m") :param timeframe: timeframe in string format (e.g. "5m")

View File

@ -5,7 +5,7 @@ import shutil
from datetime import datetime, timezone from datetime import datetime, timezone
from math import cos, sin from math import cos, sin
from pathlib import Path from pathlib import Path
from typing import Any, Dict, List, Tuple from typing import Any, Dict, List, Optional, Tuple
import numpy as np import numpy as np
import numpy.typing as npt import numpy.typing as npt
@ -112,7 +112,7 @@ class FreqaiDataKitchen:
def set_paths( def set_paths(
self, self,
pair: str, pair: str,
trained_timestamp: int = None, trained_timestamp: Optional[int] = None,
) -> None: ) -> None:
""" """
Set the paths to the data for the present coin/botloop Set the paths to the data for the present coin/botloop

View File

@ -1522,7 +1522,7 @@ class FreqtradeBot(LoggingMixin):
*, *,
exit_tag: Optional[str] = None, exit_tag: Optional[str] = None,
ordertype: Optional[str] = None, ordertype: Optional[str] = None,
sub_trade_amt: float = None, sub_trade_amt: Optional[float] = None,
) -> bool: ) -> bool:
""" """
Executes a trade exit for the given trade and limit Executes a trade exit for the given trade and limit
@ -1616,7 +1616,7 @@ class FreqtradeBot(LoggingMixin):
return True return True
def _notify_exit(self, trade: Trade, order_type: str, fill: bool = False, def _notify_exit(self, trade: Trade, order_type: str, fill: bool = False,
sub_trade: bool = False, order: Order = None) -> None: sub_trade: bool = False, order: Optional[Order] = None) -> None:
""" """
Sends rpc notification when a sell occurred. Sends rpc notification when a sell occurred.
""" """
@ -1729,8 +1729,9 @@ class FreqtradeBot(LoggingMixin):
# Common update trade state methods # Common update trade state methods
# #
def update_trade_state(self, trade: Trade, order_id: str, action_order: Dict[str, Any] = None, def update_trade_state(
stoploss_order: bool = False, send_msg: bool = True) -> bool: self, trade: Trade, order_id: str, action_order: Optional[Dict[str, Any]] = None,
stoploss_order: bool = False, send_msg: bool = True) -> bool:
""" """
Checks trades with open orders and updates the amount if necessary Checks trades with open orders and updates the amount if necessary
Handles closing both buy and sell orders. Handles closing both buy and sell orders.

View File

@ -5,7 +5,7 @@ Read the documentation to know what cli arguments you need.
""" """
import logging import logging
import sys import sys
from typing import Any, List from typing import Any, List, Optional
from freqtrade.util.gc_setup import gc_set_threshold from freqtrade.util.gc_setup import gc_set_threshold
@ -23,7 +23,7 @@ from freqtrade.loggers import setup_logging_pre
logger = logging.getLogger('freqtrade') logger = logging.getLogger('freqtrade')
def main(sysargv: List[str] = None) -> None: def main(sysargv: Optional[List[str]] = None) -> None:
""" """
This function will initiate the bot and start the trading loop. This function will initiate the bot and start the trading loop.
:return: None :return: None

View File

@ -6,7 +6,7 @@ import logging
import re import re
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from typing import Any, Dict, Iterator, List, Mapping, Union from typing import Any, Dict, Iterator, List, Mapping, Optional, Union
from typing.io import IO from typing.io import IO
from urllib.parse import urlparse from urllib.parse import urlparse
@ -205,7 +205,7 @@ def safe_value_fallback2(dict1: dictMap, dict2: dictMap, key1: str, key2: str, d
return default_value return default_value
def plural(num: float, singular: str, plural: str = None) -> str: def plural(num: float, singular: str, plural: Optional[str] = None) -> str:
return singular if (num == 1 or num == -1) else plural or singular + 's' return singular if (num == 1 or num == -1) else plural or singular + 's'

View File

@ -644,7 +644,7 @@ class Backtesting:
return None return None
def _exit_trade(self, trade: LocalTrade, sell_row: Tuple, def _exit_trade(self, trade: LocalTrade, sell_row: Tuple,
close_rate: float, amount: float = None) -> Optional[LocalTrade]: close_rate: float, amount: Optional[float] = None) -> Optional[LocalTrade]:
self.order_id_counter += 1 self.order_id_counter += 1
exit_candle_time = sell_row[DATE_IDX].to_pydatetime() exit_candle_time = sell_row[DATE_IDX].to_pydatetime()
order_type = self.strategy.order_types['exit'] order_type = self.strategy.order_types['exit']

View File

@ -170,7 +170,7 @@ class HyperoptTools():
@staticmethod @staticmethod
def show_epoch_details(results, total_epochs: int, print_json: bool, def show_epoch_details(results, total_epochs: int, print_json: bool,
no_header: bool = False, header_str: str = None) -> None: no_header: bool = False, header_str: Optional[str] = None) -> None:
""" """
Display details of the hyperopt result Display details of the hyperopt result
""" """
@ -264,7 +264,7 @@ class HyperoptTools():
print(result) print(result)
@staticmethod @staticmethod
def _space_params(params, space: str, r: int = None) -> Dict: def _space_params(params, space: str, r: Optional[int] = None) -> Dict:
d = params.get(space) d = params.get(space)
if d: if d:
# Round floats to `r` digits after the decimal point if requested # Round floats to `r` digits after the decimal point if requested

View File

@ -30,8 +30,8 @@ class PairLocks():
PairLocks.locks = [] PairLocks.locks = []
@staticmethod @staticmethod
def lock_pair(pair: str, until: datetime, reason: str = None, *, def lock_pair(pair: str, until: datetime, reason: Optional[str] = None, *,
now: datetime = None, side: str = '*') -> PairLock: now: Optional[datetime] = None, side: str = '*') -> PairLock:
""" """
Create PairLock from now to "until". Create PairLock from now to "until".
Uses database by default, unless PairLocks.use_db is set to False, Uses database by default, unless PairLocks.use_db is set to False,

View File

@ -799,7 +799,7 @@ class LocalTrade():
else: else:
return close_trade - fees return close_trade - fees
def calc_close_trade_value(self, rate: float, amount: float = None) -> float: def calc_close_trade_value(self, rate: float, amount: Optional[float] = None) -> float:
""" """
Calculate the Trade's close value including fees Calculate the Trade's close value including fees
:param rate: rate to compare with. :param rate: rate to compare with.
@ -837,7 +837,8 @@ class LocalTrade():
raise OperationalException( raise OperationalException(
f"{self.trading_mode.value} trading is not yet available using freqtrade") f"{self.trading_mode.value} trading is not yet available using freqtrade")
def calc_profit(self, rate: float, amount: float = None, open_rate: float = None) -> float: def calc_profit(self, rate: float, amount: Optional[float] = None,
open_rate: Optional[float] = None) -> float:
""" """
Calculate the absolute profit in stake currency between Close and Open trade Calculate the absolute profit in stake currency between Close and Open trade
:param rate: close rate to compare with. :param rate: close rate to compare with.
@ -858,7 +859,8 @@ class LocalTrade():
return float(f"{profit:.8f}") return float(f"{profit:.8f}")
def calc_profit_ratio( def calc_profit_ratio(
self, rate: float, amount: float = None, open_rate: float = None) -> float: self, rate: float, amount: Optional[float] = None,
open_rate: Optional[float] = None) -> float:
""" """
Calculates the profit as ratio (including fee). Calculates the profit as ratio (including fee).
:param rate: rate to compare with. :param rate: rate to compare with.
@ -1059,8 +1061,9 @@ class LocalTrade():
return self.exit_reason return self.exit_reason
@staticmethod @staticmethod
def get_trades_proxy(*, pair: str = None, is_open: bool = None, def get_trades_proxy(*, pair: Optional[str] = None, is_open: Optional[bool] = None,
open_date: datetime = None, close_date: datetime = None, open_date: Optional[datetime] = None,
close_date: Optional[datetime] = None,
) -> List['LocalTrade']: ) -> List['LocalTrade']:
""" """
Helper function to query Trades. Helper function to query Trades.
@ -1257,8 +1260,9 @@ class Trade(_DECL_BASE, LocalTrade):
Trade.query.session.rollback() Trade.query.session.rollback()
@staticmethod @staticmethod
def get_trades_proxy(*, pair: str = None, is_open: bool = None, def get_trades_proxy(*, pair: Optional[str] = None, is_open: Optional[bool] = None,
open_date: datetime = None, close_date: datetime = None, open_date: Optional[datetime] = None,
close_date: Optional[datetime] = None,
) -> List['LocalTrade']: ) -> List['LocalTrade']:
""" """
Helper function to query Trades.j Helper function to query Trades.j

View File

@ -436,11 +436,11 @@ def create_scatter(
return None return None
def generate_candlestick_graph(pair: str, data: pd.DataFrame, trades: pd.DataFrame = None, *, def generate_candlestick_graph(
indicators1: List[str] = [], pair: str, data: pd.DataFrame, trades: Optional[pd.DataFrame] = None, *,
indicators2: List[str] = [], indicators1: List[str] = [], indicators2: List[str] = [],
plot_config: Dict[str, Dict] = {}, plot_config: Dict[str, Dict] = {},
) -> go.Figure: ) -> go.Figure:
""" """
Generate the graph from the data generated by Backtesting or from DB Generate the graph from the data generated by Backtesting or from DB
Volume will always be ploted in row2, so Row 1 and 3 are to our disposal for custom indicators Volume will always be ploted in row2, so Row 1 and 3 are to our disposal for custom indicators

View File

@ -23,7 +23,8 @@ logger = logging.getLogger(__name__)
class PairListManager(LoggingMixin): class PairListManager(LoggingMixin):
def __init__(self, exchange, config: Config, dataprovider: DataProvider = None) -> None: def __init__(
self, exchange, config: Config, dataprovider: Optional[DataProvider] = None) -> None:
self._exchange = exchange self._exchange = exchange
self._config = config self._config = config
self._whitelist = self._config['exchange'].get('pair_whitelist') self._whitelist = self._config['exchange'].get('pair_whitelist')
@ -153,7 +154,8 @@ class PairListManager(LoggingMixin):
return [] return []
return whitelist return whitelist
def create_pair_list(self, pairs: List[str], timeframe: str = None) -> ListPairsWithTimeframes: def create_pair_list(
self, pairs: List[str], timeframe: Optional[str] = None) -> ListPairsWithTimeframes:
""" """
Create list of pair tuples with (pair, timeframe) Create list of pair tuples with (pair, timeframe)
""" """

View File

@ -33,7 +33,7 @@ class StrategyResolver(IResolver):
extra_path = "strategy_path" extra_path = "strategy_path"
@staticmethod @staticmethod
def load_strategy(config: Config = None) -> IStrategy: def load_strategy(config: Optional[Config] = None) -> IStrategy:
""" """
Load the custom class from config parameter Load the custom class from config parameter
:param config: configuration dictionary or None :param config: configuration dictionary or None

View File

@ -945,7 +945,7 @@ class RPC:
resp['errors'] = errors resp['errors'] = errors
return resp return resp
def _rpc_blacklist(self, add: List[str] = None) -> Dict: def _rpc_blacklist(self, add: Optional[List[str]] = None) -> Dict:
""" Returns the currently active blacklist""" """ Returns the currently active blacklist"""
errors = {} errors = {}
if add: if add:

View File

@ -1605,7 +1605,7 @@ class Telegram(RPCHandler):
def _send_msg(self, msg: str, parse_mode: str = ParseMode.MARKDOWN, def _send_msg(self, msg: str, parse_mode: str = ParseMode.MARKDOWN,
disable_notification: bool = False, disable_notification: bool = False,
keyboard: List[List[InlineKeyboardButton]] = None, keyboard: Optional[List[List[InlineKeyboardButton]]] = None,
callback_path: str = "", callback_path: str = "",
reload_able: bool = False, reload_able: bool = False,
query: Optional[CallbackQuery] = None) -> None: query: Optional[CallbackQuery] = None) -> None:

View File

@ -4,7 +4,7 @@ This module defines a base class for auto-hyperoptable strategies.
""" """
import logging import logging
from pathlib import Path from pathlib import Path
from typing import Any, Dict, Iterator, List, Tuple, Type, Union from typing import Any, Dict, Iterator, List, Optional, Tuple, Type, Union
from freqtrade.constants import Config from freqtrade.constants import Config
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
@ -36,7 +36,8 @@ class HyperStrategyMixin:
self._ft_params_from_file = params self._ft_params_from_file = params
# Init/loading of parameters is done as part of ft_bot_start(). # Init/loading of parameters is done as part of ft_bot_start().
def enumerate_parameters(self, category: str = None) -> Iterator[Tuple[str, BaseParameter]]: def enumerate_parameters(
self, category: Optional[str] = None) -> Iterator[Tuple[str, BaseParameter]]:
""" """
Find all optimizable parameters and return (name, attr) iterator. Find all optimizable parameters and return (name, attr) iterator.
:param category: :param category:

View File

@ -598,7 +598,7 @@ class IStrategy(ABC, HyperStrategyMixin):
return None return None
def populate_any_indicators(self, pair: str, df: DataFrame, tf: str, def populate_any_indicators(self, pair: str, df: DataFrame, tf: str,
informative: DataFrame = None, informative: Optional[DataFrame] = None,
set_generalized_indicators: bool = False) -> DataFrame: set_generalized_indicators: bool = False) -> DataFrame:
""" """
DEPRECATED - USE FEATURE ENGINEERING FUNCTIONS INSTEAD DEPRECATED - USE FEATURE ENGINEERING FUNCTIONS INSTEAD
@ -759,7 +759,8 @@ class IStrategy(ABC, HyperStrategyMixin):
""" """
return self.__class__.__name__ return self.__class__.__name__
def lock_pair(self, pair: str, until: datetime, reason: str = None, side: str = '*') -> None: def lock_pair(self, pair: str, until: datetime,
reason: Optional[str] = None, side: str = '*') -> None:
""" """
Locks pair until a given timestamp happens. Locks pair until a given timestamp happens.
Locked pairs are not analyzed, and are prevented from opening new trades. Locked pairs are not analyzed, and are prevented from opening new trades.
@ -791,7 +792,8 @@ class IStrategy(ABC, HyperStrategyMixin):
""" """
PairLocks.unlock_reason(reason, datetime.now(timezone.utc)) PairLocks.unlock_reason(reason, datetime.now(timezone.utc))
def is_pair_locked(self, pair: str, *, candle_date: datetime = None, side: str = '*') -> bool: def is_pair_locked(self, pair: str, *, candle_date: Optional[datetime] = None,
side: str = '*') -> bool:
""" """
Checks if a pair is currently locked Checks if a pair is currently locked
The 2nd, optional parameter ensures that locks are applied until the new candle arrives, The 2nd, optional parameter ensures that locks are applied until the new candle arrives,
@ -962,7 +964,7 @@ class IStrategy(ABC, HyperStrategyMixin):
pair: str, pair: str,
timeframe: str, timeframe: str,
dataframe: DataFrame, dataframe: DataFrame,
is_short: bool = None is_short: Optional[bool] = None
) -> Tuple[bool, bool, Optional[str]]: ) -> Tuple[bool, bool, Optional[str]]:
""" """
Calculates current exit signal based based on the dataframe Calculates current exit signal based based on the dataframe
@ -1061,7 +1063,7 @@ class IStrategy(ABC, HyperStrategyMixin):
def should_exit(self, trade: Trade, rate: float, current_time: datetime, *, def should_exit(self, trade: Trade, rate: float, current_time: datetime, *,
enter: bool, exit_: bool, enter: bool, exit_: bool,
low: float = None, high: float = None, low: Optional[float] = None, high: Optional[float] = None,
force_stoploss: float = 0) -> List[ExitCheckTuple]: force_stoploss: float = 0) -> List[ExitCheckTuple]:
""" """
This function evaluates if one of the conditions required to trigger an exit order This function evaluates if one of the conditions required to trigger an exit order
@ -1149,8 +1151,8 @@ class IStrategy(ABC, HyperStrategyMixin):
def stop_loss_reached(self, current_rate: float, trade: Trade, def stop_loss_reached(self, current_rate: float, trade: Trade,
current_time: datetime, current_profit: float, current_time: datetime, current_profit: float,
force_stoploss: float, low: float = None, force_stoploss: float, low: Optional[float] = None,
high: float = None) -> ExitCheckTuple: high: Optional[float] = None) -> ExitCheckTuple:
""" """
Based on current profit of the trade and configured (trailing) stoploss, Based on current profit of the trade and configured (trailing) stoploss,
decides to exit or not decides to exit or not

View File

@ -26,7 +26,7 @@ class Worker:
Freqtradebot worker class Freqtradebot worker class
""" """
def __init__(self, args: Dict[str, Any], config: Config = None) -> None: def __init__(self, args: Dict[str, Any], config: Optional[Config] = None) -> None:
""" """
Init all variables and objects the bot needs to work Init all variables and objects the bot needs to work
""" """

View File

@ -31,7 +31,6 @@ asyncio_mode = "auto"
[tool.mypy] [tool.mypy]
ignore_missing_imports = true ignore_missing_imports = true
namespace_packages = false namespace_packages = false
implicit_optional = true
warn_unused_ignores = true warn_unused_ignores = true
exclude = [ exclude = [
'^build_helpers\.py$' '^build_helpers\.py$'
@ -41,6 +40,11 @@ exclude = [
module = "tests.*" module = "tests.*"
ignore_errors = true ignore_errors = true
[[tool.mypy.overrides]]
# Telegram does not use implicit_optional = false in the current version.
module = "telegram.*"
implicit_optional = true
[build-system] [build-system]
requires = ["setuptools >= 46.4.0", "wheel"] requires = ["setuptools >= 46.4.0", "wheel"]
build-backend = "setuptools.build_meta" build-backend = "setuptools.build_meta"
@ -52,6 +56,3 @@ exclude = [
"build_helpers/*.py", "build_helpers/*.py",
] ]
ignore = ["freqtrade/vendor/**"] ignore = ["freqtrade/vendor/**"]
# Align pyright to mypy config
strictParameterNoneValue = false

View File

@ -14,6 +14,7 @@ import logging
import re import re
import sys import sys
from pathlib import Path from pathlib import Path
from typing import Optional
from urllib.parse import urlencode, urlparse, urlunparse from urllib.parse import urlencode, urlparse, urlunparse
import rapidjson import rapidjson
@ -36,7 +37,7 @@ class FtRestClient():
self._session = requests.Session() self._session = requests.Session()
self._session.auth = (username, password) self._session.auth = (username, password)
def _call(self, method, apipath, params: dict = None, data=None, files=None): def _call(self, method, apipath, params: Optional[dict] = None, data=None, files=None):
if str(method).upper() not in ('GET', 'POST', 'PUT', 'DELETE'): if str(method).upper() not in ('GET', 'POST', 'PUT', 'DELETE'):
raise ValueError(f'invalid method <{method}>') raise ValueError(f'invalid method <{method}>')
@ -60,13 +61,13 @@ class FtRestClient():
except ConnectionError: except ConnectionError:
logger.warning("Connection error") logger.warning("Connection error")
def _get(self, apipath, params: dict = None): def _get(self, apipath, params: Optional[dict] = None):
return self._call("GET", apipath, params=params) return self._call("GET", apipath, params=params)
def _delete(self, apipath, params: dict = None): def _delete(self, apipath, params: Optional[dict] = None):
return self._call("DELETE", apipath, params=params) return self._call("DELETE", apipath, params=params)
def _post(self, apipath, params: dict = None, data: dict = None): def _post(self, apipath, params: Optional[dict] = None, data: Optional[dict] = None):
return self._call("POST", apipath, params=params, data=data) return self._call("POST", apipath, params=params, data=data)
def start(self): def start(self):