diff --git a/build_helpers/freqtrade_client_version_align.py b/build_helpers/freqtrade_client_version_align.py index f86bee98c..91d708b54 100755 --- a/build_helpers/freqtrade_client_version_align.py +++ b/build_helpers/freqtrade_client_version_align.py @@ -1,11 +1,12 @@ #!/usr/bin/env python3 -from freqtrade import __version__ as ft_version from freqtrade_client import __version__ as client_version +from freqtrade import __version__ as ft_version + def main(): if ft_version != client_version: - print(f"Versions do not match: \n" f"ft: {ft_version} \n" f"client: {client_version}") + print(f"Versions do not match: \nft: {ft_version} \nclient: {client_version}") exit(1) print(f"Versions match: ft: {ft_version}, client: {client_version}") exit(0) diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index eb272ea3c..4313ba11f 100755 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -369,7 +369,7 @@ AVAILABLE_CLI_OPTIONS = { "list_pairs_all": Arg( "-a", "--all", - help="Print all pairs or market symbols. By default only active " "ones are shown.", + help="Print all pairs or market symbols. By default only active ones are shown.", action="store_true", ), "print_list": Arg( @@ -490,7 +490,7 @@ AVAILABLE_CLI_OPTIONS = { "timeframes": Arg( "-t", "--timeframes", - help="Specify which tickers to download. Space-separated list. " "Default: `1m 5m`.", + help="Specify which tickers to download. Space-separated list. Default: `1m 5m`.", nargs="+", ), "prepend_data": Arg( diff --git a/freqtrade/commands/deploy_commands.py b/freqtrade/commands/deploy_commands.py index a562c8400..3a784bda9 100644 --- a/freqtrade/commands/deploy_commands.py +++ b/freqtrade/commands/deploy_commands.py @@ -89,7 +89,7 @@ def start_new_strategy(args: Dict[str, Any]) -> None: if new_path.exists(): raise OperationalException( - f"`{new_path}` already exists. " "Please choose another Strategy Name." + f"`{new_path}` already exists. Please choose another Strategy Name." ) deploy_new_strategy(args["strategy"], new_path, args["template"]) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index eb9922fcb..9b834fccf 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -218,7 +218,7 @@ class Configuration: self._args_to_config( config, argname="timeframe", - logstring="Parameter -i/--timeframe detected ... " "Using timeframe: {} ...", + logstring="Parameter -i/--timeframe detected ... Using timeframe: {} ...", ) self._args_to_config( @@ -240,7 +240,7 @@ class Configuration: elif "max_open_trades" in self.args and self.args["max_open_trades"]: config.update({"max_open_trades": self.args["max_open_trades"]}) logger.info( - "Parameter --max-open-trades detected, " "overriding max_open_trades to: %s ...", + "Parameter --max-open-trades detected, overriding max_open_trades to: %s ...", config.get("max_open_trades"), ) elif config["runmode"] in NON_UTIL_MODES: @@ -417,7 +417,7 @@ class Configuration: self._args_to_config( config, argname="dry_run", - logstring="Parameter --dry-run detected, " "overriding dry_run to: {} ...", + logstring="Parameter --dry-run detected, overriding dry_run to: {} ...", ) if not self.runmode: diff --git a/freqtrade/configuration/load_config.py b/freqtrade/configuration/load_config.py index 277dd3bc6..c11f6b37e 100644 --- a/freqtrade/configuration/load_config.py +++ b/freqtrade/configuration/load_config.py @@ -69,7 +69,7 @@ def load_config_file(path: str) -> Dict[str, Any]: except rapidjson.JSONDecodeError as e: err_range = log_config_error_range(path, str(e)) raise ConfigurationError( - f"{e}\n" f"Please verify the following segment of your configuration:\n{err_range}" + f"{e}\nPlease verify the following segment of your configuration:\n{err_range}" if err_range else "Please verify your configuration file for syntax errors." ) diff --git a/freqtrade/data/converter/converter.py b/freqtrade/data/converter/converter.py index 33a507740..0475ddee2 100644 --- a/freqtrade/data/converter/converter.py +++ b/freqtrade/data/converter/converter.py @@ -98,7 +98,7 @@ def clean_ohlcv_dataframe( def ohlcv_fill_up_missing_data(dataframe: DataFrame, timeframe: str, pair: str) -> DataFrame: """ Fills up missing data with 0 volume rows, - using the previous close as price for "open", "high" "low" and "close", volume is set to 0 + using the previous close as price for "open", "high", "low" and "close", volume is set to 0 """ from freqtrade.exchange import timeframe_to_resample_freq @@ -175,7 +175,7 @@ def trim_dataframes( processed[pair] = trimed_df else: logger.warning( - f"{pair} has no data left after adjusting for startup candles, " f"skipping." + f"{pair} has no data left after adjusting for startup candles, skipping." ) return processed @@ -285,7 +285,7 @@ def reduce_dataframe_footprint(df: DataFrame) -> DataFrame: :return: Dataframe converted to float/int 32s """ - logger.debug(f"Memory usage of dataframe is " f"{df.memory_usage().sum() / 1024**2:.2f} MB") + logger.debug(f"Memory usage of dataframe is {df.memory_usage().sum() / 1024**2:.2f} MB") df_dtypes = df.dtypes for column, dtype in df_dtypes.items(): @@ -297,8 +297,6 @@ def reduce_dataframe_footprint(df: DataFrame) -> DataFrame: df_dtypes[column] = np.int32 df = df.astype(df_dtypes) - logger.debug( - f"Memory usage after optimization is: " f"{df.memory_usage().sum() / 1024**2:.2f} MB" - ) + logger.debug(f"Memory usage after optimization is: {df.memory_usage().sum() / 1024**2:.2f} MB") return df diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index be0a2ad72..a31f7f7e8 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -849,7 +849,7 @@ class Exchange: if max_stake_amount is None: # * Should never be executed raise OperationalException( - f"{self.name}.get_max_pair_stake_amount should" "never set max_stake_amount to None" + f"{self.name}.get_max_pair_stake_amount should never set max_stake_amount to None" ) return max_stake_amount @@ -1375,7 +1375,7 @@ class Exchange: raise DDosProtection(e) from e except (ccxt.OperationFailed, ccxt.ExchangeError) as e: raise TemporaryError( - f"Could not place stoploss order due to {e.__class__.__name__}. " f"Message: {e}" + f"Could not place stoploss order due to {e.__class__.__name__}. Message: {e}" ) from e except ccxt.BaseError as e: raise OperationalException(e) from e @@ -1800,7 +1800,7 @@ class Exchange: return self._api.fetch_l2_order_book(pair, limit1) except ccxt.NotSupported as e: raise OperationalException( - f"Exchange {self._api.name} does not support fetching order book." f"Message: {e}" + f"Exchange {self._api.name} does not support fetching order book. Message: {e}" ) from e except ccxt.DDoSProtection as e: raise DDosProtection(e) from e @@ -2498,7 +2498,7 @@ class Exchange: ) from e except ccxt.BaseError as e: raise OperationalException( - f"Could not fetch historical candle (OHLCV) data " f"for pair {pair}. Message: {e}" + f"Could not fetch historical candle (OHLCV) data for pair {pair}. Message: {e}" ) from e async def _fetch_funding_rate_history( @@ -2555,7 +2555,7 @@ class Exchange: raise DDosProtection(e) from e except (ccxt.OperationFailed, ccxt.ExchangeError) as e: raise TemporaryError( - f"Could not load trade history due to {e.__class__.__name__}. " f"Message: {e}" + f"Could not load trade history due to {e.__class__.__name__}. Message: {e}" ) from e except ccxt.BaseError as e: raise OperationalException(f"Could not fetch trade data. Msg: {e}") from e @@ -2701,7 +2701,7 @@ class Exchange: ) else: raise OperationalException( - f"Exchange {self.name} does use neither time, " f"nor id based pagination" + f"Exchange {self.name} does use neither time, nor id based pagination" ) def get_historic_trades( diff --git a/freqtrade/freqai/RL/BaseReinforcementLearningModel.py b/freqtrade/freqai/RL/BaseReinforcementLearningModel.py index 8908e33ac..e52470b41 100644 --- a/freqtrade/freqai/RL/BaseReinforcementLearningModel.py +++ b/freqtrade/freqai/RL/BaseReinforcementLearningModel.py @@ -105,7 +105,7 @@ class BaseReinforcementLearningModel(IFreqaiModel): :model: Trained model which can be used to inference (self.predict) """ - logger.info("--------------------Starting training " f"{pair} --------------------") + logger.info(f"--------------------Starting training {pair} --------------------") features_filtered, labels_filtered = dk.filter_features( unfiltered_df, @@ -430,7 +430,7 @@ class BaseReinforcementLearningModel(IFreqaiModel): # you can use feature values from dataframe rsi_now = self.raw_features[ - f"%-rsi-period-10_shift-1_{self.pair}_" f"{self.config['timeframe']}" + f"%-rsi-period-10_shift-1_{self.pair}_{self.config['timeframe']}" ].iloc[self._current_tick] # reward agent for entering trades diff --git a/freqtrade/freqai/base_models/BasePyTorchClassifier.py b/freqtrade/freqai/base_models/BasePyTorchClassifier.py index f726ba603..86eadb7bd 100644 --- a/freqtrade/freqai/base_models/BasePyTorchClassifier.py +++ b/freqtrade/freqai/base_models/BasePyTorchClassifier.py @@ -59,7 +59,7 @@ class BasePyTorchClassifier(BasePyTorchModel): class_names = self.model.model_meta_data.get("class_names", None) if not class_names: raise ValueError( - "Missing class names. " "self.model.model_meta_data['class_names'] is None." + "Missing class names. self.model.model_meta_data['class_names'] is None." ) if not self.class_name_to_index: diff --git a/freqtrade/freqai/base_models/FreqaiMultiOutputClassifier.py b/freqtrade/freqai/base_models/FreqaiMultiOutputClassifier.py index 5252c7e87..c83a19bb5 100644 --- a/freqtrade/freqai/base_models/FreqaiMultiOutputClassifier.py +++ b/freqtrade/freqai/base_models/FreqaiMultiOutputClassifier.py @@ -63,7 +63,7 @@ class FreqaiMultiOutputClassifier(MultiOutputClassifier): self.classes_.extend(estimator.classes_) if len(set(self.classes_)) != len(self.classes_): raise OperationalException( - f"Class labels must be unique across targets: " f"{self.classes_}" + f"Class labels must be unique across targets: {self.classes_}" ) if hasattr(self.estimators_[0], "n_features_in_"): diff --git a/freqtrade/freqai/data_drawer.py b/freqtrade/freqai/data_drawer.py index 8e80efcf2..37780a945 100644 --- a/freqtrade/freqai/data_drawer.py +++ b/freqtrade/freqai/data_drawer.py @@ -618,7 +618,7 @@ class FreqaiDataDrawer: if not model: raise OperationalException( - f"Unable to load model, ensure model exists at " f"{dk.data_path} " + f"Unable to load model, ensure model exists at {dk.data_path} " ) # load it into ram if it was loaded from disk diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index 974618691..c6a358c57 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -763,7 +763,7 @@ class IFreqaiModel(ABC): """ current_pairlist = self.config.get("exchange", {}).get("pair_whitelist") if not self.dd.pair_dict: - logger.info("Set fresh train queue from whitelist. " f"Queue: {current_pairlist}") + logger.info("Set fresh train queue from whitelist. Queue: {current_pairlist}") return deque(current_pairlist) best_queue = deque() @@ -779,7 +779,7 @@ class IFreqaiModel(ABC): best_queue.appendleft(pair) logger.info( - "Set existing queue from trained timestamps. " f"Best approximation queue: {best_queue}" + "Set existing queue from trained timestamps. Best approximation queue: {best_queue}" ) return best_queue diff --git a/freqtrade/freqai/prediction_models/ReinforcementLearner.py b/freqtrade/freqai/prediction_models/ReinforcementLearner.py index d76b352fd..7c2ad35ca 100644 --- a/freqtrade/freqai/prediction_models/ReinforcementLearner.py +++ b/freqtrade/freqai/prediction_models/ReinforcementLearner.py @@ -73,7 +73,7 @@ class ReinforcementLearner(BaseReinforcementLearningModel): ) else: logger.info( - "Continual training activated - starting training from previously " "trained agent." + "Continual training activated - starting training from previously trained agent." ) model = self.dd.model_dictionary[dk.pair] model.set_env(self.train_env) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 5e5793039..387007b19 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1015,9 +1015,7 @@ class FreqtradeBot(LoggingMixin): # First cancelling stoploss on exchange ... for oslo in trade.open_sl_orders: try: - logger.info( - f"Cancelling stoploss on exchange for {trade} order: {oslo.order_id}" - ) + logger.info(f"Cancelling stoploss on exchange for {trade} order: {oslo.order_id}") co = self.exchange.cancel_stoploss_order_with_result( oslo.order_id, trade.pair, trade.amount ) @@ -2285,7 +2283,7 @@ class FreqtradeBot(LoggingMixin): if fee_abs != 0 and self.wallets.get_free(trade_base_currency) >= amount_: # Eat into dust if we own more than base currency logger.info( - f"Fee amount for {trade} was in base currency - " f"Eating Fee {fee_abs} into dust." + f"Fee amount for {trade} was in base currency - Eating Fee {fee_abs} into dust." ) elif fee_abs != 0: logger.info(f"Applying fee on amount for {trade}, fee={fee_abs}.") diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 95ad1b821..73633eeb4 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -215,7 +215,7 @@ class Backtesting: def _validate_pairlists_for_backtesting(self): if "VolumePairList" in self.pairlists.name_list: raise OperationalException( - "VolumePairList not allowed for backtesting. " "Please use StaticPairList instead." + "VolumePairList not allowed for backtesting. Please use StaticPairList instead." ) if "PerformanceFilter" in self.pairlists.name_list: raise OperationalException("PerformanceFilter not allowed for backtesting.") diff --git a/freqtrade/optimize/optimize_reports/bt_output.py b/freqtrade/optimize/optimize_reports/bt_output.py index 4a634f83b..061d509ab 100644 --- a/freqtrade/optimize/optimize_reports/bt_output.py +++ b/freqtrade/optimize/optimize_reports/bt_output.py @@ -316,7 +316,7 @@ def text_table_add_metrics(strat_results: Dict) -> str: f"{strat_results['worst_pair']['profit_total']:.2%}", ), ("Best trade", f"{best_trade['pair']} {best_trade['profit_ratio']:.2%}"), - ("Worst trade", f"{worst_trade['pair']} " f"{worst_trade['profit_ratio']:.2%}"), + ("Worst trade", f"{worst_trade['pair']} {worst_trade['profit_ratio']:.2%}"), ( "Best day", fmt_coin(strat_results["backtest_best_day_abs"], strat_results["stake_currency"]), diff --git a/freqtrade/persistence/migrations.py b/freqtrade/persistence/migrations.py index a2e4ec681..5988e1b7e 100644 --- a/freqtrade/persistence/migrations.py +++ b/freqtrade/persistence/migrations.py @@ -361,9 +361,7 @@ def check_migrate(engine, decl_base, previous_tables) -> None: if not has_column(cols_pairlocks, "side"): migrating = True - logger.info( - f"Running database migration for pairlocks - " f"backup: {pairlock_table_bak_name}" - ) + logger.info(f"Running database migration for pairlocks - backup: {pairlock_table_bak_name}") migrate_pairlocks_table( decl_base, inspector, engine, pairlock_table_bak_name, cols_pairlocks diff --git a/freqtrade/plugins/pairlist/AgeFilter.py b/freqtrade/plugins/pairlist/AgeFilter.py index 48ea7cc2c..0be04d7b8 100644 --- a/freqtrade/plugins/pairlist/AgeFilter.py +++ b/freqtrade/plugins/pairlist/AgeFilter.py @@ -73,7 +73,7 @@ class AgeFilter(IPairList): f"{self.name} - Filtering pairs with age less than " f"{self._min_days_listed} {plural(self._min_days_listed, 'day')}" ) + ( - (" or more than " f"{self._max_days_listed} {plural(self._max_days_listed, 'day')}") + (" or more than {self._max_days_listed} {plural(self._max_days_listed, 'day')}") if self._max_days_listed else "" ) diff --git a/freqtrade/plugins/pairlist/IPairList.py b/freqtrade/plugins/pairlist/IPairList.py index f58df718f..0db38ff2f 100644 --- a/freqtrade/plugins/pairlist/IPairList.py +++ b/freqtrade/plugins/pairlist/IPairList.py @@ -236,7 +236,7 @@ class IPairList(LoggingMixin, ABC): if not self._exchange.market_is_tradable(markets[pair]): self.log_once( - f"Pair {pair} is not tradable with Freqtrade." "Removing it from whitelist..", + f"Pair {pair} is not tradable with Freqtrade. Removing it from whitelist..", logger.warning, ) continue diff --git a/freqtrade/plugins/pairlist/PriceFilter.py b/freqtrade/plugins/pairlist/PriceFilter.py index 38dc97457..81dbdfc33 100644 --- a/freqtrade/plugins/pairlist/PriceFilter.py +++ b/freqtrade/plugins/pairlist/PriceFilter.py @@ -84,7 +84,7 @@ class PriceFilter(IPairList): "default": 0, "description": "Low price ratio", "help": ( - "Remove pairs where a price move of 1 price unit (pip) " "is above this ratio." + "Remove pairs where a price move of 1 price unit (pip) is above this ratio." ), }, "min_price": { @@ -130,7 +130,7 @@ class PriceFilter(IPairList): changeperc = compare / price if changeperc > self._low_price_ratio: self.log_once( - f"Removed {pair} from whitelist, " f"because 1 unit is {changeperc:.3%}", + f"Removed {pair} from whitelist, because 1 unit is {changeperc:.3%}", logger.info, ) return False diff --git a/freqtrade/plugins/pairlist/RemotePairList.py b/freqtrade/plugins/pairlist/RemotePairList.py index e980e61e0..b15cfa96e 100644 --- a/freqtrade/plugins/pairlist/RemotePairList.py +++ b/freqtrade/plugins/pairlist/RemotePairList.py @@ -201,12 +201,12 @@ class RemotePairList(IPairList): pairlist = self._handle_error(f"Failed processing JSON data: {type(e)}") else: pairlist = self._handle_error( - f"RemotePairList is not of type JSON." f" {self._pairlist_url}" + f"RemotePairList is not of type JSON. {self._pairlist_url}" ) except requests.exceptions.RequestException: pairlist = self._handle_error( - f"Was not able to fetch pairlist from:" f" {self._pairlist_url}" + f"Was not able to fetch pairlist from: {self._pairlist_url}" ) time_elapsed = 0 diff --git a/freqtrade/plugins/protections/iprotection.py b/freqtrade/plugins/protections/iprotection.py index 91d591c48..204a8b827 100644 --- a/freqtrade/plugins/protections/iprotection.py +++ b/freqtrade/plugins/protections/iprotection.py @@ -65,7 +65,7 @@ class IProtection(LoggingMixin, ABC): f"{plural(self._stop_duration_candles, 'candle', 'candles')}" ) else: - return f"{self._stop_duration} " f"{plural(self._stop_duration, 'minute', 'minutes')}" + return f"{self._stop_duration} {plural(self._stop_duration, 'minute', 'minutes')}" @property def lookback_period_str(self) -> str: @@ -78,9 +78,7 @@ class IProtection(LoggingMixin, ABC): f"{plural(self._lookback_period_candles, 'candle', 'candles')}" ) else: - return ( - f"{self._lookback_period} " f"{plural(self._lookback_period, 'minute', 'minutes')}" - ) + return f"{self._lookback_period} {plural(self._lookback_period, 'minute', 'minutes')}" @abstractmethod def short_desc(self) -> str: diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index 883b36abc..72b1db034 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -44,7 +44,7 @@ class StrategyResolver(IResolver): if not config.get("strategy"): raise OperationalException( - "No strategy set. Please use `--strategy` to specify " "the strategy class to use." + "No strategy set. Please use `--strategy` to specify the strategy class to use." ) strategy_name = config["strategy"] diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index ef8013ff7..dcc6465f0 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -219,7 +219,7 @@ class Telegram(RPCHandler): raise OperationalException(err_msg) else: self._keyboard = cust_keyboard - logger.info("using custom keyboard from " f"config.json: {self._keyboard}") + logger.info("using custom keyboard from config.json: {self._keyboard}") def _init_telegram_app(self): return Application.builder().token(self._config["telegram"]["token"]).build() @@ -1749,9 +1749,7 @@ class Telegram(RPCHandler): for chunk in chunks(edge_pairs, 25): edge_pairs_tab = tabulate(chunk, headers="keys", tablefmt="simple") - message = ( - f"Edge only validated following pairs:\n" f"
{edge_pairs_tab}
" - ) + message = f"Edge only validated following pairs:\n
{edge_pairs_tab}
" await self._send_msg(message, parse_mode=ParseMode.HTML) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index e9152579b..bed216faf 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -1201,7 +1201,7 @@ class IStrategy(ABC, HyperStrategyMixin): # Tags can be None, which does not resolve to False. exit_tag = exit_tag if isinstance(exit_tag, str) and exit_tag != "nan" else None - logger.debug(f"exit-trigger: {latest['date']} (pair={pair}) " f"enter={enter} exit={exit_}") + logger.debug(f"exit-trigger: {latest['date']} (pair={pair}) enter={enter} exit={exit_}") return enter, exit_, exit_tag diff --git a/freqtrade/strategy/strategy_wrapper.py b/freqtrade/strategy/strategy_wrapper.py index eaeb6aa7e..a6f74f1c0 100644 --- a/freqtrade/strategy/strategy_wrapper.py +++ b/freqtrade/strategy/strategy_wrapper.py @@ -27,12 +27,12 @@ def strategy_safe_wrapper(f: F, message: str = "", default_retval=None, supress_ kwargs["trade"] = deepcopy(kwargs["trade"]) return f(*args, **kwargs) except ValueError as error: - logger.warning(f"{message}" f"Strategy caused the following exception: {error}" f"{f}") + logger.warning(f"{message}Strategy caused the following exception: {error}{f}") if default_retval is None and not supress_error: raise StrategyError(str(error)) from error return default_retval except Exception as error: - logger.exception(f"{message}" f"Unexpected error {error} calling {f}") + logger.exception(f"{message}Unexpected error {error} calling {f}") if default_retval is None and not supress_error: raise StrategyError(str(error)) from error return default_retval diff --git a/freqtrade/vendor/qtpylib/indicators.py b/freqtrade/vendor/qtpylib/indicators.py index a4d92eed3..9c92b2f8e 100644 --- a/freqtrade/vendor/qtpylib/indicators.py +++ b/freqtrade/vendor/qtpylib/indicators.py @@ -42,7 +42,7 @@ def numpy_rolling_series(func): new_series = np.empty(len(series)) * np.nan calculated = func(series, window) - new_series[-len(calculated):] = calculated + new_series[-len(calculated) :] = calculated if as_source and isinstance(data, pd.Series): return pd.Series(index=data.index, data=new_series) @@ -65,97 +65,103 @@ def numpy_rolling_std(data, window, as_source=False): # --------------------------------------------- -def session(df, start='17:00', end='16:00'): - """ remove previous globex day from df """ +def session(df, start="17:00", end="16:00"): + """remove previous globex day from df""" if df.empty: return df # get start/end/now as decimals - int_start = list(map(int, start.split(':'))) + int_start = list(map(int, start.split(":"))) int_start = (int_start[0] + int_start[1] - 1 / 100) - 0.0001 - int_end = list(map(int, end.split(':'))) + int_end = list(map(int, end.split(":"))) int_end = int_end[0] + int_end[1] / 100 - int_now = (df[-1:].index.hour[0] + (df[:1].index.minute[0]) / 100) + int_now = df[-1:].index.hour[0] + (df[:1].index.minute[0]) / 100 # same-dat session? is_same_day = int_end > int_start # set pointers - curr = prev = df[-1:].index[0].strftime('%Y-%m-%d') + curr = prev = df[-1:].index[0].strftime("%Y-%m-%d") # globex/forex session if not is_same_day: - prev = (datetime.strptime(curr, '%Y-%m-%d') - - timedelta(1)).strftime('%Y-%m-%d') + prev = (datetime.strptime(curr, "%Y-%m-%d") - timedelta(1)).strftime("%Y-%m-%d") # slice if int_now >= int_start: - df = df[df.index >= curr + ' ' + start] + df = df[df.index >= curr + " " + start] else: - df = df[df.index >= prev + ' ' + start] + df = df[df.index >= prev + " " + start] return df.copy() + # --------------------------------------------- def heikinashi(bars): bars = bars.copy() - bars['ha_close'] = (bars['open'] + bars['high'] + - bars['low'] + bars['close']) / 4 + bars["ha_close"] = (bars["open"] + bars["high"] + bars["low"] + bars["close"]) / 4 # ha open - bars.at[0, 'ha_open'] = (bars.at[0, 'open'] + bars.at[0, 'close']) / 2 + bars.at[0, "ha_open"] = (bars.at[0, "open"] + bars.at[0, "close"]) / 2 for i in range(1, len(bars)): - bars.at[i, 'ha_open'] = (bars.at[i - 1, 'ha_open'] + bars.at[i - 1, 'ha_close']) / 2 + bars.at[i, "ha_open"] = (bars.at[i - 1, "ha_open"] + bars.at[i - 1, "ha_close"]) / 2 - bars['ha_high'] = bars.loc[:, ['high', 'ha_open', 'ha_close']].max(axis=1) - bars['ha_low'] = bars.loc[:, ['low', 'ha_open', 'ha_close']].min(axis=1) + bars["ha_high"] = bars.loc[:, ["high", "ha_open", "ha_close"]].max(axis=1) + bars["ha_low"] = bars.loc[:, ["low", "ha_open", "ha_close"]].min(axis=1) + + return pd.DataFrame( + index=bars.index, + data={ + "open": bars["ha_open"], + "high": bars["ha_high"], + "low": bars["ha_low"], + "close": bars["ha_close"], + }, + ) - return pd.DataFrame(index=bars.index, - data={'open': bars['ha_open'], - 'high': bars['ha_high'], - 'low': bars['ha_low'], - 'close': bars['ha_close']}) # --------------------------------------------- -def tdi(series, rsi_lookback=13, rsi_smooth_len=2, - rsi_signal_len=7, bb_lookback=34, bb_std=1.6185): - +def tdi(series, rsi_lookback=13, rsi_smooth_len=2, rsi_signal_len=7, bb_lookback=34, bb_std=1.6185): rsi_data = rsi(series, rsi_lookback) rsi_smooth = sma(rsi_data, rsi_smooth_len) rsi_signal = sma(rsi_data, rsi_signal_len) bb_series = bollinger_bands(rsi_data, bb_lookback, bb_std) - return pd.DataFrame(index=series.index, data={ - "rsi": rsi_data, - "rsi_signal": rsi_signal, - "rsi_smooth": rsi_smooth, - "rsi_bb_upper": bb_series['upper'], - "rsi_bb_lower": bb_series['lower'], - "rsi_bb_mid": bb_series['mid'] - }) + return pd.DataFrame( + index=series.index, + data={ + "rsi": rsi_data, + "rsi_signal": rsi_signal, + "rsi_smooth": rsi_smooth, + "rsi_bb_upper": bb_series["upper"], + "rsi_bb_lower": bb_series["lower"], + "rsi_bb_mid": bb_series["mid"], + }, + ) + # --------------------------------------------- def awesome_oscillator(df, weighted=False, fast=5, slow=34): - midprice = (df['high'] + df['low']) / 2 + midprice = (df["high"] + df["low"]) / 2 if weighted: ao = (midprice.ewm(fast).mean() - midprice.ewm(slow).mean()).values else: - ao = numpy_rolling_mean(midprice, fast) - \ - numpy_rolling_mean(midprice, slow) + ao = numpy_rolling_mean(midprice, fast) - numpy_rolling_mean(midprice, slow) return pd.Series(index=df.index, data=ao) # --------------------------------------------- + def nans(length=1): mtx = np.empty(length) mtx[:] = np.nan @@ -164,39 +170,45 @@ def nans(length=1): # --------------------------------------------- + def typical_price(bars): - res = (bars['high'] + bars['low'] + bars['close']) / 3. + res = (bars["high"] + bars["low"] + bars["close"]) / 3.0 return pd.Series(index=bars.index, data=res) # --------------------------------------------- + def mid_price(bars): - res = (bars['high'] + bars['low']) / 2. + res = (bars["high"] + bars["low"]) / 2.0 return pd.Series(index=bars.index, data=res) # --------------------------------------------- + def ibs(bars): - """ Internal bar strength """ - res = np.round((bars['close'] - bars['low']) / - (bars['high'] - bars['low']), 2) + """Internal bar strength""" + res = np.round((bars["close"] - bars["low"]) / (bars["high"] - bars["low"]), 2) return pd.Series(index=bars.index, data=res) # --------------------------------------------- + def true_range(bars): - return pd.DataFrame({ - "hl": bars['high'] - bars['low'], - "hc": abs(bars['high'] - bars['close'].shift(1)), - "lc": abs(bars['low'] - bars['close'].shift(1)) - }).max(axis=1) + return pd.DataFrame( + { + "hl": bars["high"] - bars["low"], + "hc": abs(bars["high"] - bars["close"].shift(1)), + "lc": abs(bars["low"] - bars["close"].shift(1)), + } + ).max(axis=1) # --------------------------------------------- + def atr(bars, window=14, exp=False): tr = true_range(bars) @@ -210,6 +222,7 @@ def atr(bars, window=14, exp=False): # --------------------------------------------- + def crossed(series1, series2, direction=None): if isinstance(series1, np.ndarray): series1 = pd.Series(series1) @@ -218,12 +231,10 @@ def crossed(series1, series2, direction=None): series2 = pd.Series(index=series1.index, data=series2) if direction is None or direction == "above": - above = pd.Series((series1 > series2) & ( - series1.shift(1) <= series2.shift(1))) + above = pd.Series((series1 > series2) & (series1.shift(1) <= series2.shift(1))) if direction is None or direction == "below": - below = pd.Series((series1 < series2) & ( - series1.shift(1) >= series2.shift(1))) + below = pd.Series((series1 < series2) & (series1.shift(1) >= series2.shift(1))) if direction is None: return above | below @@ -238,6 +249,7 @@ def crossed_above(series1, series2): def crossed_below(series1, series2): return crossed(series1, series2, "below") + # --------------------------------------------- @@ -251,6 +263,7 @@ def rolling_std(series, window=200, min_periods=None): except Exception as e: # noqa: F841 return pd.Series(series).rolling(window=window, min_periods=min_periods).std() + # --------------------------------------------- @@ -264,6 +277,7 @@ def rolling_mean(series, window=200, min_periods=None): except Exception as e: # noqa: F841 return pd.Series(series).rolling(window=window, min_periods=min_periods).mean() + # --------------------------------------------- @@ -277,6 +291,7 @@ def rolling_min(series, window=14, min_periods=None): # --------------------------------------------- + def rolling_max(series, window=14, min_periods=None): min_periods = window if min_periods is None else min_periods try: @@ -287,6 +302,7 @@ def rolling_max(series, window=14, min_periods=None): # --------------------------------------------- + def rolling_weighted_mean(series, window=200, min_periods=None): min_periods = window if min_periods is None else min_periods try: @@ -297,41 +313,49 @@ def rolling_weighted_mean(series, window=200, min_periods=None): # --------------------------------------------- + def hull_moving_average(series, window=200, min_periods=None): min_periods = window if min_periods is None else min_periods - ma = (2 * rolling_weighted_mean(series, window / 2, min_periods)) - \ - rolling_weighted_mean(series, window, min_periods) + ma = (2 * rolling_weighted_mean(series, window / 2, min_periods)) - rolling_weighted_mean( + series, window, min_periods + ) return rolling_weighted_mean(ma, np.sqrt(window), min_periods) # --------------------------------------------- + def sma(series, window=200, min_periods=None): return rolling_mean(series, window=window, min_periods=min_periods) # --------------------------------------------- + def wma(series, window=200, min_periods=None): return rolling_weighted_mean(series, window=window, min_periods=min_periods) # --------------------------------------------- + def hma(series, window=200, min_periods=None): return hull_moving_average(series, window=window, min_periods=min_periods) # --------------------------------------------- + def vwap(bars): """ calculate vwap of entire time series (input can be pandas series or numpy array) bars are usually mid [ (h+l)/2 ] or typical [ (h+l+c)/3 ] """ - raise ValueError("using `qtpylib.vwap` facilitates lookahead bias. Please use " - "`qtpylib.rolling_vwap` instead, which calculates vwap in a rolling manner.") + raise ValueError( + "using `qtpylib.vwap` facilitates lookahead bias. Please use " + "`qtpylib.rolling_vwap` instead, which calculates vwap in a rolling manner." + ) # typical = ((bars['high'] + bars['low'] + bars['close']) / 3).values # volume = bars['volume'].values @@ -341,6 +365,7 @@ def vwap(bars): # --------------------------------------------- + def rolling_vwap(bars, window=200, min_periods=None): """ calculate vwap using moving window @@ -349,19 +374,22 @@ def rolling_vwap(bars, window=200, min_periods=None): """ min_periods = window if min_periods is None else min_periods - typical = ((bars['high'] + bars['low'] + bars['close']) / 3) - volume = bars['volume'] + typical = (bars["high"] + bars["low"] + bars["close"]) / 3 + volume = bars["volume"] - left = (volume * typical).rolling(window=window, - min_periods=min_periods).sum() + left = (volume * typical).rolling(window=window, min_periods=min_periods).sum() right = volume.rolling(window=window, min_periods=min_periods).sum() - return pd.Series(index=bars.index, data=(left / right) - ).replace([np.inf, -np.inf], float('NaN')).ffill() + return ( + pd.Series(index=bars.index, data=(left / right)) + .replace([np.inf, -np.inf], float("NaN")) + .ffill() + ) # --------------------------------------------- + def rsi(series, window=14): """ compute the n period relative strength indicator @@ -369,13 +397,13 @@ def rsi(series, window=14): # 100-(100/relative_strength) deltas = np.diff(series) - seed = deltas[:window + 1] + seed = deltas[: window + 1] # default values ups = seed[seed > 0].sum() / window downs = -seed[seed < 0].sum() / window rsival = np.zeros_like(series) - rsival[:window] = 100. - 100. / (1. + ups / downs) + rsival[:window] = 100.0 - 100.0 / (1.0 + ups / downs) # period values for i in range(window, len(series)): @@ -388,8 +416,8 @@ def rsi(series, window=14): downval = -delta ups = (ups * (window - 1) + upval) / window - downs = (downs * (window - 1.) + downval) / window - rsival[i] = 100. - 100. / (1. + ups / downs) + downs = (downs * (window - 1.0) + downval) / window + rsival[i] = 100.0 - 100.0 / (1.0 + ups / downs) # return rsival return pd.Series(index=series.index, data=rsival) @@ -397,60 +425,57 @@ def rsi(series, window=14): # --------------------------------------------- + def macd(series, fast=3, slow=10, smooth=16): """ compute the MACD (Moving Average Convergence/Divergence) using a fast and slow exponential moving avg' return value is emaslow, emafast, macd which are len(x) arrays """ - macd_line = rolling_weighted_mean(series, window=fast) - \ - rolling_weighted_mean(series, window=slow) + macd_line = rolling_weighted_mean(series, window=fast) - rolling_weighted_mean( + series, window=slow + ) signal = rolling_weighted_mean(macd_line, window=smooth) histogram = macd_line - signal # return macd_line, signal, histogram - return pd.DataFrame(index=series.index, data={ - 'macd': macd_line.values, - 'signal': signal.values, - 'histogram': histogram.values - }) + return pd.DataFrame( + index=series.index, + data={"macd": macd_line.values, "signal": signal.values, "histogram": histogram.values}, + ) # --------------------------------------------- + def bollinger_bands(series, window=20, stds=2): ma = rolling_mean(series, window=window, min_periods=1) std = rolling_std(series, window=window, min_periods=1) upper = ma + std * stds lower = ma - std * stds - return pd.DataFrame(index=series.index, data={ - 'upper': upper, - 'mid': ma, - 'lower': lower - }) + return pd.DataFrame(index=series.index, data={"upper": upper, "mid": ma, "lower": lower}) # --------------------------------------------- + def weighted_bollinger_bands(series, window=20, stds=2): ema = rolling_weighted_mean(series, window=window) std = rolling_std(series, window=window) upper = ema + std * stds lower = ema - std * stds - return pd.DataFrame(index=series.index, data={ - 'upper': upper.values, - 'mid': ema.values, - 'lower': lower.values - }) + return pd.DataFrame( + index=series.index, data={"upper": upper.values, "mid": ema.values, "lower": lower.values} + ) # --------------------------------------------- + def returns(series): try: - res = (series / series.shift(1) - - 1).replace([np.inf, -np.inf], float('NaN')) + res = (series / series.shift(1) - 1).replace([np.inf, -np.inf], float("NaN")) except Exception as e: # noqa: F841 res = nans(len(series)) @@ -459,10 +484,10 @@ def returns(series): # --------------------------------------------- + def log_returns(series): try: - res = np.log(series / series.shift(1) - ).replace([np.inf, -np.inf], float('NaN')) + res = np.log(series / series.shift(1)).replace([np.inf, -np.inf], float("NaN")) except Exception as e: # noqa: F841 res = nans(len(series)) @@ -471,10 +496,10 @@ def log_returns(series): # --------------------------------------------- + def implied_volatility(series, window=252): try: - logret = np.log(series / series.shift(1) - ).replace([np.inf, -np.inf], float('NaN')) + logret = np.log(series / series.shift(1)).replace([np.inf, -np.inf], float("NaN")) res = numpy_rolling_std(logret, window) * np.sqrt(window) except Exception as e: # noqa: F841 res = nans(len(series)) @@ -484,6 +509,7 @@ def implied_volatility(series, window=252): # --------------------------------------------- + def keltner_channel(bars, window=14, atrs=2): typical_mean = rolling_mean(typical_price(bars), window) atrval = atr(bars, window) * atrs @@ -491,15 +517,15 @@ def keltner_channel(bars, window=14, atrs=2): upper = typical_mean + atrval lower = typical_mean - atrval - return pd.DataFrame(index=bars.index, data={ - 'upper': upper.values, - 'mid': typical_mean.values, - 'lower': lower.values - }) + return pd.DataFrame( + index=bars.index, + data={"upper": upper.values, "mid": typical_mean.values, "lower": lower.values}, + ) # --------------------------------------------- + def roc(series, window=14): """ compute rate of change @@ -510,18 +536,20 @@ def roc(series, window=14): # --------------------------------------------- + def cci(series, window=14): """ compute commodity channel index """ price = typical_price(series) typical_mean = rolling_mean(price, window) - res = (price - typical_mean) / (.015 * np.std(typical_mean)) + res = (price - typical_mean) / (0.015 * np.std(typical_mean)) return pd.Series(index=series.index, data=res) # --------------------------------------------- + def stoch(df, window=14, d=3, k=3, fast=False): """ compute the n period relative strength indicator @@ -530,22 +558,22 @@ def stoch(df, window=14, d=3, k=3, fast=False): my_df = pd.DataFrame(index=df.index) - my_df['rolling_max'] = df['high'].rolling(window).max() - my_df['rolling_min'] = df['low'].rolling(window).min() + my_df["rolling_max"] = df["high"].rolling(window).max() + my_df["rolling_min"] = df["low"].rolling(window).min() - my_df['fast_k'] = ( - 100 * (df['close'] - my_df['rolling_min']) / - (my_df['rolling_max'] - my_df['rolling_min']) + my_df["fast_k"] = ( + 100 * (df["close"] - my_df["rolling_min"]) / (my_df["rolling_max"] - my_df["rolling_min"]) ) - my_df['fast_d'] = my_df['fast_k'].rolling(d).mean() + my_df["fast_d"] = my_df["fast_k"].rolling(d).mean() if fast: - return my_df.loc[:, ['fast_k', 'fast_d']] + return my_df.loc[:, ["fast_k", "fast_d"]] - my_df['slow_k'] = my_df['fast_k'].rolling(k).mean() - my_df['slow_d'] = my_df['slow_k'].rolling(d).mean() + my_df["slow_k"] = my_df["fast_k"].rolling(k).mean() + my_df["slow_d"] = my_df["slow_k"].rolling(d).mean() + + return my_df.loc[:, ["slow_k", "slow_d"]] - return my_df.loc[:, ['slow_k', 'slow_d']] # --------------------------------------------- @@ -559,7 +587,7 @@ def zlma(series, window=20, min_periods=None, kind="ema"): lag = (window - 1) // 2 series = 2 * series - series.shift(lag) - if kind in ['ewm', 'ema']: + if kind in ["ewm", "ema"]: return wma(series, lag, min_periods) elif kind == "hma": return hma(series, lag, min_periods) @@ -577,29 +605,30 @@ def zlsma(series, window, min_periods=None): def zlhma(series, window, min_periods=None): return zlma(series, window, min_periods, kind="hma") + # --------------------------------------------- -def zscore(bars, window=20, stds=1, col='close'): - """ get zscore of price """ +def zscore(bars, window=20, stds=1, col="close"): + """get zscore of price""" std = numpy_rolling_std(bars[col], window) mean = numpy_rolling_mean(bars[col], window) return (bars[col] - mean) / (std * stds) + # --------------------------------------------- def pvt(bars): - """ Price Volume Trend """ - trend = ((bars['close'] - bars['close'].shift(1)) / - bars['close'].shift(1)) * bars['volume'] + """Price Volume Trend""" + trend = ((bars["close"] - bars["close"].shift(1)) / bars["close"].shift(1)) * bars["volume"] return trend.cumsum() def chopiness(bars, window=14): atrsum = true_range(bars).rolling(window).sum() - highs = bars['high'].rolling(window).max() - lows = bars['low'].rolling(window).min() + highs = bars["high"].rolling(window).max() + lows = bars["low"].rolling(window).min() return 100 * np.log10(atrsum / (highs - lows)) / np.log10(window) diff --git a/freqtrade/worker.py b/freqtrade/worker.py index 63ff71277..4c8fee356 100644 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -131,7 +131,7 @@ class Worker: if strategy_version is not None: version += ", strategy_version: " + strategy_version logger.info( - f"Bot heartbeat. PID={getpid()}, " f"version='{version}', state='{state.name}'" + f"Bot heartbeat. PID={getpid()}, version='{version}', state='{state.name}'" ) self._heartbeat_msg = now diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 82d3d3246..77cabc51b 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -186,7 +186,7 @@ def test_list_timeframes(mocker, capsys): start_list_timeframes(get_args(args)) captured = capsys.readouterr() assert re.match( - "Timeframes available for the exchange `Bybit`: " "1m, 5m, 30m, 1h, 1d", captured.out + "Timeframes available for the exchange `Bybit`: 1m, 5m, 30m, 1h, 1d", captured.out ) # Test with --exchange bybit @@ -198,7 +198,7 @@ def test_list_timeframes(mocker, capsys): start_list_timeframes(get_args(args)) captured = capsys.readouterr() assert re.match( - "Timeframes available for the exchange `Bybit`: " "1m, 5m, 30m, 1h, 1d", captured.out + "Timeframes available for the exchange `Bybit`: 1m, 5m, 30m, 1h, 1d", captured.out ) api_mock.timeframes = { @@ -222,7 +222,7 @@ def test_list_timeframes(mocker, capsys): start_list_timeframes(get_args(args)) captured = capsys.readouterr() assert re.match( - "Timeframes available for the exchange `Binance`: " "1m, 5m, 15m, 30m, 1h, 6h, 12h, 1d, 3d", + "Timeframes available for the exchange `Binance`: 1m, 5m, 15m, 30m, 1h, 6h, 12h, 1d, 3d", captured.out, ) diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 2fe82ea25..29ac89337 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -415,7 +415,7 @@ def test_load_partial_missing(testdatadir, caplog) -> None: assert td != len(data["UNITTEST/BTC"]) start_real = data["UNITTEST/BTC"].iloc[0, 0] assert log_has( - f"UNITTEST/BTC, spot, 5m, " f"data starts at {start_real.strftime(DATETIME_PRINT_FORMAT)}", + f"UNITTEST/BTC, spot, 5m, data starts at {start_real.strftime(DATETIME_PRINT_FORMAT)}", caplog, ) # Make sure we start fresh - test missing data at end @@ -435,7 +435,7 @@ def test_load_partial_missing(testdatadir, caplog) -> None: # Shift endtime with +5 end_real = data["UNITTEST/BTC"].iloc[-1, 0].to_pydatetime() assert log_has( - f"UNITTEST/BTC, spot, 5m, " f"data ends at {end_real.strftime(DATETIME_PRINT_FORMAT)}", + f"UNITTEST/BTC, spot, 5m, data ends at {end_real.strftime(DATETIME_PRINT_FORMAT)}", caplog, ) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index ff7ee0aa3..1d7e6e356 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -645,7 +645,7 @@ def test_validate_stakecurrency_error(default_conf, mocker, caplog): mocker.patch(f"{EXMS}._load_async_markets") with pytest.raises( ConfigurationError, - match=r"XRP is not available as stake on .*" "Available currencies are: BTC, ETH, USDT", + match=r"XRP is not available as stake on .*Available currencies are: BTC, ETH, USDT", ): Exchange(default_conf) @@ -2328,7 +2328,7 @@ def test_refresh_latest_ohlcv(mocker, default_conf, caplog, candle_type) -> None assert exchange._api_async.fetch_ohlcv.call_count == 0 assert log_has( - f"Using cached candle (OHLCV) data for {pairs[0][0]}, " f"{pairs[0][1]}, {candle_type} ...", + f"Using cached candle (OHLCV) data for {pairs[0][0]}, {pairs[0][1]}, {candle_type} ...", caplog, ) caplog.clear() diff --git a/tests/freqtradebot/test_freqtradebot.py b/tests/freqtradebot/test_freqtradebot.py index 32773fd1f..cbcc78f11 100644 --- a/tests/freqtradebot/test_freqtradebot.py +++ b/tests/freqtradebot/test_freqtradebot.py @@ -3771,7 +3771,7 @@ def test_get_real_amount_quote_dust( assert freqtrade.get_real_amount(trade, buy_order_fee, order_obj) is None assert walletmock.call_count == 1 assert log_has_re( - r"Fee amount for Trade.* was in base currency " "- Eating Fee 0.008 into dust", caplog + r"Fee amount for Trade.* was in base currency - Eating Fee 0.008 into dust", caplog ) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index ce9f3e51a..5576b312f 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -393,9 +393,7 @@ def test_backtesting_start(default_conf, mocker, caplog) -> None: backtesting.strategy.bot_start = MagicMock() backtesting.start() # check the logs, that will contain the backtest result - exists = [ - "Backtesting with data from 2017-11-14 21:17:00 " "up to 2017-11-14 22:59:00 (0 days)." - ] + exists = ["Backtesting with data from 2017-11-14 21:17:00 up to 2017-11-14 22:59:00 (0 days)."] for line in exists: assert log_has(line, caplog) assert backtesting.strategy.dp._pairlists is not None @@ -1574,8 +1572,8 @@ def test_backtest_start_timerange(default_conf, mocker, caplog, testdatadir): "Ignoring max_open_trades (--disable-max-market-positions was used) ...", "Parameter --timerange detected: 1510694220-1510700340 ...", f"Using data directory: {testdatadir} ...", - "Loading data from 2017-11-14 20:57:00 " "up to 2017-11-14 22:59:00 (0 days).", - "Backtesting with data from 2017-11-14 21:17:00 " "up to 2017-11-14 22:59:00 (0 days).", + "Loading data from 2017-11-14 20:57:00 up to 2017-11-14 22:59:00 (0 days).", + "Backtesting with data from 2017-11-14 21:17:00 up to 2017-11-14 22:59:00 (0 days).", "Parameter --enable-position-stacking detected ...", ] @@ -1665,8 +1663,8 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir): "Ignoring max_open_trades (--disable-max-market-positions was used) ...", "Parameter --timerange detected: 1510694220-1510700340 ...", f"Using data directory: {testdatadir} ...", - "Loading data from 2017-11-14 20:57:00 " "up to 2017-11-14 22:59:00 (0 days).", - "Backtesting with data from 2017-11-14 21:17:00 " "up to 2017-11-14 22:59:00 (0 days).", + "Loading data from 2017-11-14 20:57:00 up to 2017-11-14 22:59:00 (0 days).", + "Backtesting with data from 2017-11-14 21:17:00 up to 2017-11-14 22:59:00 (0 days).", "Parameter --enable-position-stacking detected ...", f"Running backtesting for Strategy {CURRENT_TEST_STRATEGY}", "Running backtesting for Strategy StrategyTestV2", @@ -1799,8 +1797,8 @@ def test_backtest_start_multi_strat_nomock(default_conf, mocker, caplog, testdat "Ignoring max_open_trades (--disable-max-market-positions was used) ...", "Parameter --timerange detected: 1510694220-1510700340 ...", f"Using data directory: {testdatadir} ...", - "Loading data from 2017-11-14 20:57:00 " "up to 2017-11-14 22:59:00 (0 days).", - "Backtesting with data from 2017-11-14 21:17:00 " "up to 2017-11-14 22:59:00 (0 days).", + "Loading data from 2017-11-14 20:57:00 up to 2017-11-14 22:59:00 (0 days).", + "Backtesting with data from 2017-11-14 21:17:00 up to 2017-11-14 22:59:00 (0 days).", "Parameter --enable-position-stacking detected ...", f"Running backtesting for Strategy {CURRENT_TEST_STRATEGY}", "Running backtesting for Strategy StrategyTestV2", @@ -1975,8 +1973,8 @@ def test_backtest_start_nomock_futures(default_conf_usdt, mocker, caplog, testda exists = [ "Parameter -i/--timeframe detected ... Using timeframe: 1h ...", f"Using data directory: {testdatadir} ...", - "Loading data from 2021-11-17 01:00:00 " "up to 2021-11-21 04:00:00 (4 days).", - "Backtesting with data from 2021-11-17 21:00:00 " "up to 2021-11-21 04:00:00 (3 days).", + "Loading data from 2021-11-17 01:00:00 up to 2021-11-21 04:00:00 (4 days).", + "Backtesting with data from 2021-11-17 21:00:00 up to 2021-11-21 04:00:00 (3 days).", "XRP/USDT:USDT, funding_rate, 8h, data starts at 2021-11-18 00:00:00", "XRP/USDT:USDT, mark, 8h, data starts at 2021-11-18 00:00:00", f"Running backtesting for Strategy {CURRENT_TEST_STRATEGY}", @@ -2112,8 +2110,8 @@ def test_backtest_start_multi_strat_nomock_detail( "Parameter -i/--timeframe detected ... Using timeframe: 5m ...", "Parameter --timeframe-detail detected, using 1m for intra-candle backtesting ...", f"Using data directory: {testdatadir} ...", - "Loading data from 2019-10-11 00:00:00 " "up to 2019-10-13 11:15:00 (2 days).", - "Backtesting with data from 2019-10-11 01:40:00 " "up to 2019-10-13 11:15:00 (2 days).", + "Loading data from 2019-10-11 00:00:00 up to 2019-10-13 11:15:00 (2 days).", + "Backtesting with data from 2019-10-11 01:40:00 up to 2019-10-13 11:15:00 (2 days).", f"Running backtesting for Strategy {CURRENT_TEST_STRATEGY}", ] diff --git a/tests/strategy/test_strategy_loading.py b/tests/strategy/test_strategy_loading.py index 523bd4a77..9b143ace6 100644 --- a/tests/strategy/test_strategy_loading.py +++ b/tests/strategy/test_strategy_loading.py @@ -111,7 +111,7 @@ def test_load_strategy_noname(default_conf): default_conf["strategy"] = "" with pytest.raises( OperationalException, - match="No strategy set. Please use `--strategy` to specify " "the strategy class to use.", + match="No strategy set. Please use `--strategy` to specify the strategy class to use.", ): StrategyResolver.load_strategy(default_conf) diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 104987b99..7faa35c4a 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -664,7 +664,7 @@ def test_validate_max_open_trades(default_conf): default_conf["stake_amount"] = "unlimited" with pytest.raises( OperationalException, - match="`max_open_trades` and `stake_amount` " "cannot both be unlimited.", + match="`max_open_trades` and `stake_amount` cannot both be unlimited.", ): validate_config_consistency(default_conf) @@ -767,7 +767,7 @@ def test_validate_edge2(edge_conf): ) with pytest.raises( OperationalException, - match="Edge requires `use_exit_signal` to be True, " "otherwise no sells will happen.", + match="Edge requires `use_exit_signal` to be True, otherwise no sells will happen.", ): validate_config_consistency(edge_conf)