diff --git a/.github/workflows/binance-lev-tier-update.yml b/.github/workflows/binance-lev-tier-update.yml index f06251cca89..2e0a3d3b285 100644 --- a/.github/workflows/binance-lev-tier-update.yml +++ b/.github/workflows/binance-lev-tier-update.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install ccxt run: pip install ccxt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4d5ee5c5fde..7bc2ac1f5e7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -334,7 +334,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: pre-commit dependencies run: | @@ -348,7 +348,7 @@ jobs: - uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - uses: pre-commit/action@v3.0.1 docs-check: @@ -363,7 +363,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Documentation build run: | @@ -389,7 +389,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Cache_dependencies uses: actions/cache@v4 @@ -471,7 +471,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Build distribution run: | @@ -542,7 +542,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Extract branch name id: extract-branch diff --git a/.github/workflows/pre-commit-update.yml b/.github/workflows/pre-commit-update.yml index 69f5dbb4eba..e451e5a53db 100644 --- a/.github/workflows/pre-commit-update.yml +++ b/.github/workflows/pre-commit-update.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install pre-commit diff --git a/build_helpers/pyarrow-16.0.0-cp311-cp311-linux_armv7l.whl b/build_helpers/pyarrow-16.1.0-cp311-cp311-linux_armv7l.whl similarity index 66% rename from build_helpers/pyarrow-16.0.0-cp311-cp311-linux_armv7l.whl rename to build_helpers/pyarrow-16.1.0-cp311-cp311-linux_armv7l.whl index f8022ffbf01..345f2dd6309 100644 Binary files a/build_helpers/pyarrow-16.0.0-cp311-cp311-linux_armv7l.whl and b/build_helpers/pyarrow-16.1.0-cp311-cp311-linux_armv7l.whl differ diff --git a/build_helpers/pyarrow-16.0.0-cp39-cp39-linux_armv7l.whl b/build_helpers/pyarrow-16.1.0-cp39-cp39-linux_armv7l.whl similarity index 66% rename from build_helpers/pyarrow-16.0.0-cp39-cp39-linux_armv7l.whl rename to build_helpers/pyarrow-16.1.0-cp39-cp39-linux_armv7l.whl index c1cbf19de29..ffbe09bf488 100644 Binary files a/build_helpers/pyarrow-16.0.0-cp39-cp39-linux_armv7l.whl and b/build_helpers/pyarrow-16.1.0-cp39-cp39-linux_armv7l.whl differ diff --git a/docs/data-download.md b/docs/data-download.md index 890a89b6029..2a51edb0bf7 100644 --- a/docs/data-download.md +++ b/docs/data-download.md @@ -24,10 +24,10 @@ usage: freqtrade download-data [-h] [-v] [--logfile FILE] [-V] [-c PATH] [--days INT] [--new-pairs-days INT] [--include-inactive-pairs] [--timerange TIMERANGE] [--dl-trades] - [--exchange EXCHANGE] + [--convert] [--exchange EXCHANGE] [-t TIMEFRAMES [TIMEFRAMES ...]] [--erase] [--data-format-ohlcv {json,jsongz,hdf5,feather,parquet}] - [--data-format-trades {json,jsongz,hdf5,feather}] + [--data-format-trades {json,jsongz,hdf5,feather,parquet}] [--trading-mode {spot,margin,futures}] [--prepend] @@ -48,6 +48,11 @@ options: --dl-trades Download trades instead of OHLCV data. The bot will resample trades to the desired timeframe as specified as --timeframes/-t. + --convert Convert downloaded trades to OHLCV data. Only + applicable in combination with `--dl-trades`. Will be + automatic for exchanges which don't have historic + OHLCV (e.g. Kraken). If not provided, use `trades-to- + ohlcv` to convert trades data to OHLCV data. --exchange EXCHANGE Exchange name. Only valid if no config is provided. -t TIMEFRAMES [TIMEFRAMES ...], --timeframes TIMEFRAMES [TIMEFRAMES ...] Specify which tickers to download. Space-separated @@ -57,7 +62,7 @@ options: --data-format-ohlcv {json,jsongz,hdf5,feather,parquet} Storage format for downloaded candle (OHLCV) data. (default: `feather`). - --data-format-trades {json,jsongz,hdf5,feather} + --data-format-trades {json,jsongz,hdf5,feather,parquet} Storage format for downloaded trades data. (default: `feather`). --trading-mode {spot,margin,futures}, --tradingmode {spot,margin,futures} @@ -471,15 +476,20 @@ ETH/USDT 5m, 15m, 30m, 1h, 2h, 4h ## Trades (tick) data -By default, `download-data` sub-command downloads Candles (OHLCV) data. Some exchanges also provide historic trade-data via their API. +By default, `download-data` sub-command downloads Candles (OHLCV) data. Most exchanges also provide historic trade-data via their API. This data can be useful if you need many different timeframes, since it is only downloaded once, and then resampled locally to the desired timeframes. -Since this data is large by default, the files use the feather fileformat by default. They are stored in your data-directory with the naming convention of `-trades.feather` (`ETH_BTC-trades.feather`). Incremental mode is also supported, as for historic OHLCV data, so downloading the data once per week with `--days 8` will create an incremental data-repository. +Since this data is large by default, the files use the feather file format by default. They are stored in your data-directory with the naming convention of `-trades.feather` (`ETH_BTC-trades.feather`). Incremental mode is also supported, as for historic OHLCV data, so downloading the data once per week with `--days 8` will create an incremental data-repository. + +To use this mode, simply add `--dl-trades` to your call. This will swap the download method to download trades. +If `--convert` is also provided, the resample step will happen automatically and overwrite eventually existing OHLCV data for the given pair/timeframe combinations. -To use this mode, simply add `--dl-trades` to your call. This will swap the download method to download trades, and resamples the data locally. +!!! Warning "Do not use" + You should not use this unless you're a kraken user (Kraken does not provide historic OHLCV data). + Most other exchanges provide OHLCV data with sufficient history, so downloading multiple timeframes through that method will still proof to be a lot faster than downloading trades data. -!!! Warning "do not use" - You should not use this unless you're a kraken user. Most other exchanges provide OHLCV data with sufficient history. +!!! Note "Kraken user" + Kraken users should read [this](exchanges.md#historic-kraken-data) before starting to download data. Example call: @@ -490,12 +500,6 @@ freqtrade download-data --exchange kraken --pairs XRP/EUR ETH/EUR --days 20 --dl !!! Note While this method uses async calls, it will be slow, since it requires the result of the previous call to generate the next request to the exchange. -!!! Warning - The historic trades are not available during Freqtrade dry-run and live trade modes because all exchanges tested provide this data with a delay of few 100 candles, so it's not suitable for real-time trading. - -!!! Note "Kraken user" - Kraken users should read [this](exchanges.md#historic-kraken-data) before starting to download data. - ## Next step -Great, you now have backtest data downloaded, so you can now start [backtesting](backtesting.md) your strategy. +Great, you now have some data downloaded, so you can now start [backtesting](backtesting.md) your strategy. diff --git a/docs/installation.md b/docs/installation.md index 189f45cfae8..f86043fb388 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -286,7 +286,7 @@ cd freqtrade #### Freqtrade install: Conda Environment ```bash -conda create --name freqtrade python=3.11 +conda create --name freqtrade python=3.12 ``` !!! Note "Creating Conda Environment" diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index a333447c2d6..956d2288c33 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,6 +1,6 @@ markdown==3.6 mkdocs==1.6.0 -mkdocs-material==9.5.22 +mkdocs-material==9.5.23 mdx_truly_sane_lists==1.3 pymdown-extensions==10.8.1 jinja2==3.1.4 diff --git a/docs/windows_installation.md b/docs/windows_installation.md index cd9007d985e..d513c0af5b6 100644 --- a/docs/windows_installation.md +++ b/docs/windows_installation.md @@ -24,7 +24,7 @@ git clone https://github.com/freqtrade/freqtrade.git Install ta-lib according to the [ta-lib documentation](https://github.com/TA-Lib/ta-lib-python#windows). -As compiling from source on windows has heavy dependencies (requires a partial visual studio installation), Freqtrade provides these dependencies (in the binary wheel format) for the latest 3 Python versions (3.9, 3.10 and 3.11) and for 64bit Windows. +As compiling from source on windows has heavy dependencies (requires a partial visual studio installation), Freqtrade provides these dependencies (in the binary wheel format) for the latest 3 Python versions (3.9, 3.10, 3.11 and 3.12) and for 64bit Windows. These Wheels are also used by CI running on windows, and are therefore tested together with freqtrade. Other versions must be downloaded from the above link. diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 98281e9f0bf..c527a80d630 100755 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -142,6 +142,7 @@ "include_inactive", "timerange", "download_trades", + "convert_trades", "exchange", "timeframes", "erase", diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index b7aaf7812f8..b9236a0ab42 100755 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -450,6 +450,14 @@ def __init__(self, *args, **kwargs): "desired timeframe as specified as --timeframes/-t.", action="store_true", ), + "convert_trades": Arg( + "--convert", + help="Convert downloaded trades to OHLCV data. Only applicable in combination with " + "`--dl-trades`. " + "Will be automatic for exchanges which don't have historic OHLCV (e.g. Kraken). " + "If not provided, use `trades-to-ohlcv` to convert trades data to OHLCV data.", + action="store_true", + ), "format_from_trades": Arg( "--format-from", help="Source format for data conversion.", diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 99ec4452526..cc8b5407e41 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -370,6 +370,7 @@ def _process_plot_options(self, config: Config) -> None: ("days", "Detected --days: {}"), ("include_inactive", "Detected --include-inactive-pairs: {}"), ("download_trades", "Detected --dl-trades: {}"), + ("convert_trades", "Detected --convert: {} - Converting Trade data to OHCV {}"), ("dataformat_ohlcv", 'Using "{}" to store OHLCV data.'), ("dataformat_trades", 'Using "{}" to store trades data.'), ("show_timerange", "Detected --show-timerange"), diff --git a/freqtrade/data/history/history_utils.py b/freqtrade/data/history/history_utils.py index 50dfcdc44bd..bdca599c663 100644 --- a/freqtrade/data/history/history_utils.py +++ b/freqtrade/data/history/history_utils.py @@ -629,17 +629,20 @@ def download_data_main(config: Config) -> None: trading_mode=config.get("trading_mode", TradingMode.SPOT), ) - # Convert downloaded trade data to different timeframes - convert_trades_to_ohlcv( - pairs=expanded_pairs, - timeframes=config["timeframes"], - datadir=config["datadir"], - timerange=timerange, - erase=bool(config.get("erase")), - data_format_ohlcv=config["dataformat_ohlcv"], - data_format_trades=config["dataformat_trades"], - candle_type=config.get("candle_type_def", CandleType.SPOT), - ) + if config.get("convert_trades") or not exchange.get_option("ohlcv_has_history", True): + # Convert downloaded trade data to different timeframes + # Only auto-convert for exchanges without historic klines + + convert_trades_to_ohlcv( + pairs=expanded_pairs, + timeframes=config["timeframes"], + datadir=config["datadir"], + timerange=timerange, + erase=bool(config.get("erase")), + data_format_ohlcv=config["dataformat_ohlcv"], + data_format_trades=config["dataformat_trades"], + candle_type=config.get("candle_type_def", CandleType.SPOT), + ) else: if not exchange.get_option("ohlcv_has_history", True): raise OperationalException( diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 3623a9845d5..95698846774 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -206,7 +206,6 @@ def dry_run_liquidation_price( "Freqtrade only supports isolated futures for leverage trading" ) - @retrier def load_leverage_tiers(self) -> Dict[str, List[Dict]]: if self.trading_mode == TradingMode.FUTURES: if self._config["dry_run"]: @@ -214,16 +213,6 @@ def load_leverage_tiers(self) -> Dict[str, List[Dict]]: with leverage_tiers_path.open() as json_file: return json_load(json_file) else: - try: - return self._api.fetch_leverage_tiers() - except ccxt.DDoSProtection as e: - raise DDosProtection(e) from e - except (ccxt.OperationFailed, ccxt.ExchangeError) as e: - raise TemporaryError( - f"Could not fetch leverage amounts due to" - f"{e.__class__.__name__}. Message: {e}" - ) from e - except ccxt.BaseError as e: - raise OperationalException(e) from e + return self.get_leverage_tiers() else: return {} diff --git a/freqtrade/exchange/bingx.py b/freqtrade/exchange/bingx.py index 7ee08273c97..4efd621e830 100644 --- a/freqtrade/exchange/bingx.py +++ b/freqtrade/exchange/bingx.py @@ -17,4 +17,6 @@ class Bingx(Exchange): _ft_has: Dict = { "ohlcv_candle_limit": 1000, + "stoploss_on_exchange": False, + "stoploss_order_types": {"limit": "limit", "market": "market"}, } diff --git a/freqtrade/exchange/bybit.py b/freqtrade/exchange/bybit.py index 1f810cf1fef..c8b05d1de4f 100644 --- a/freqtrade/exchange/bybit.py +++ b/freqtrade/exchange/bybit.py @@ -250,38 +250,19 @@ def fetch_order(self, order_id: str, pair: str, params: Optional[Dict] = None) - @retrier def get_leverage_tiers(self) -> Dict[str, List[Dict]]: """ - Temporary workaround for https://github.com/freqtrade/freqtrade/issues/10196 - should be removed or updated once https://github.com/ccxt/ccxt/issues/22448 is fixed. + Cache leverage tiers for 1 day, since they are not expected to change often, and + bybit requires pagination to fetch all tiers. """ # Load cached tiers - tiers_cached = self.load_cached_leverage_tiers(self._config["stake_currency"]) + tiers_cached = self.load_cached_leverage_tiers( + self._config["stake_currency"], timedelta(days=1) + ) if tiers_cached: - tiers = tiers_cached - return tiers + return tiers_cached # Fetch tiers from exchange - - symbols = self._api.market_symbols([]) - - def parse_resp(response): - result = self._api.safe_dict(response, "result", {}) - data = self._api.safe_list(result, "list", []) - return self._api.parse_leverage_tiers(data, symbols, "symbol") - - params = { - "category": "linear", - } - tiers = {} - # 20 pairs ... should be sufficient assuming 30 pairs per page - # Aimed to avoid a potential infinite loop - for _ in range(20): - # Fetch from private endpoint - response = self._api.publicGetV5MarketRiskLimit(params) - tiers = tiers | parse_resp(response) - if (cursor := response["result"]["nextPageCursor"]) == "": - break - params.update({"cursor": cursor}) + tiers = super().get_leverage_tiers() self.cache_leverage_tiers(tiers, self._config["stake_currency"]) return tiers diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index a31f7f7e88e..9d7c4eabbe6 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -2868,7 +2868,16 @@ def cache_leverage_tiers(self, tiers: Dict[str, List[Dict]], stake_currency: str } file_dump_json(filename, data) - def load_cached_leverage_tiers(self, stake_currency: str) -> Optional[Dict[str, List[Dict]]]: + def load_cached_leverage_tiers( + self, stake_currency: str, cache_time: Optional[timedelta] = None + ) -> Optional[Dict[str, List[Dict]]]: + """ + Load cached leverage tiers from disk + :param cache_time: The maximum age of the cache before it is considered outdated + """ + if not cache_time: + # Default to 4 weeks + cache_time = timedelta(weeks=4) filename = self._config["datadir"] / "futures" / f"leverage_tiers_{stake_currency}.json" if filename.is_file(): try: @@ -2876,7 +2885,7 @@ def load_cached_leverage_tiers(self, stake_currency: str) -> Optional[Dict[str, updated = tiers.get("updated") if updated: updated_dt = parser.parse(updated) - if updated_dt < datetime.now(timezone.utc) - timedelta(weeks=4): + if updated_dt < datetime.now(timezone.utc) - cache_time: logger.info("Cached leverage tiers are outdated. Will update.") return None return tiers["data"] diff --git a/freqtrade/freqai/prediction_models/CatboostClassifier.py b/freqtrade/freqai/prediction_models/CatboostClassifier.py index 9dd1a4107d1..1761397702a 100644 --- a/freqtrade/freqai/prediction_models/CatboostClassifier.py +++ b/freqtrade/freqai/prediction_models/CatboostClassifier.py @@ -1,5 +1,4 @@ import logging -import sys from pathlib import Path from typing import Any, Dict @@ -57,8 +56,6 @@ def fit(self, data_dictionary: Dict, dk: FreqaiDataKitchen, **kwargs) -> Any: X=train_data, eval_set=test_data, init_model=init_model, - log_cout=sys.stdout, - log_cerr=sys.stderr, ) return cbr diff --git a/freqtrade/freqai/prediction_models/CatboostClassifierMultiTarget.py b/freqtrade/freqai/prediction_models/CatboostClassifierMultiTarget.py index de93a47512f..02cb91f5a40 100644 --- a/freqtrade/freqai/prediction_models/CatboostClassifierMultiTarget.py +++ b/freqtrade/freqai/prediction_models/CatboostClassifierMultiTarget.py @@ -1,5 +1,4 @@ import logging -import sys from pathlib import Path from typing import Any, Dict @@ -68,8 +67,6 @@ def fit(self, data_dictionary: Dict, dk: FreqaiDataKitchen, **kwargs) -> Any: { "eval_set": eval_sets[i], "init_model": init_models[i], - "log_cout": sys.stdout, - "log_cerr": sys.stderr, } ) diff --git a/freqtrade/freqai/prediction_models/CatboostRegressor.py b/freqtrade/freqai/prediction_models/CatboostRegressor.py index f0bb5e99908..5401a808bcb 100644 --- a/freqtrade/freqai/prediction_models/CatboostRegressor.py +++ b/freqtrade/freqai/prediction_models/CatboostRegressor.py @@ -1,5 +1,4 @@ import logging -import sys from pathlib import Path from typing import Any, Dict @@ -56,8 +55,6 @@ def fit(self, data_dictionary: Dict, dk: FreqaiDataKitchen, **kwargs) -> Any: X=train_data, eval_set=test_data, init_model=init_model, - log_cout=sys.stdout, - log_cerr=sys.stderr, ) return model diff --git a/freqtrade/freqai/prediction_models/CatboostRegressorMultiTarget.py b/freqtrade/freqai/prediction_models/CatboostRegressorMultiTarget.py index 1300fbfe2da..c2a5344e332 100644 --- a/freqtrade/freqai/prediction_models/CatboostRegressorMultiTarget.py +++ b/freqtrade/freqai/prediction_models/CatboostRegressorMultiTarget.py @@ -1,5 +1,4 @@ import logging -import sys from pathlib import Path from typing import Any, Dict @@ -67,8 +66,6 @@ def fit(self, data_dictionary: Dict, dk: FreqaiDataKitchen, **kwargs) -> Any: { "eval_set": eval_sets[i], "init_model": init_models[i], - "log_cout": sys.stdout, - "log_cerr": sys.stderr, } ) diff --git a/freqtrade/optimize/hyperopt_loss/hyperopt_loss_profit_drawdown.py b/freqtrade/optimize/hyperopt_loss/hyperopt_loss_profit_drawdown.py index 26dad9c9e96..e5ec6075ee6 100644 --- a/freqtrade/optimize/hyperopt_loss/hyperopt_loss_profit_drawdown.py +++ b/freqtrade/optimize/hyperopt_loss/hyperopt_loss_profit_drawdown.py @@ -10,23 +10,26 @@ from pandas import DataFrame +from freqtrade.constants import Config from freqtrade.data.metrics import calculate_max_drawdown from freqtrade.optimize.hyperopt import IHyperOptLoss -# higher numbers penalize drawdowns more severely -DRAWDOWN_MULT = 0.5 +# smaller numbers penalize drawdowns more severely +DRAWDOWN_MULT = 0.075 class ProfitDrawDownHyperOptLoss(IHyperOptLoss): @staticmethod - def hyperopt_loss_function(results: DataFrame, trade_count: int, *args, **kwargs) -> float: + def hyperopt_loss_function(results: DataFrame, config: Config, *args, **kwargs) -> float: total_profit = results["profit_abs"].sum() try: - drawdown = calculate_max_drawdown(results, value_col="profit_abs") + drawdown = calculate_max_drawdown( + results, starting_balance=config["dry_run_wallet"], value_col="profit_abs" + ) relative_account_drawdown = drawdown.relative_account_drawdown except ValueError: relative_account_drawdown = 0 - return -1 * (total_profit * (1 - relative_account_drawdown * DRAWDOWN_MULT)) + return -1 * (total_profit - (relative_account_drawdown * total_profit) / DRAWDOWN_MULT) diff --git a/freqtrade/optimize/hyperopt_tools.py b/freqtrade/optimize/hyperopt_tools.py index a4c32bf69d0..1f444d53340 100644 --- a/freqtrade/optimize/hyperopt_tools.py +++ b/freqtrade/optimize/hyperopt_tools.py @@ -359,14 +359,15 @@ def _format_explanation_string(results, total_epochs) -> str: ) @staticmethod - def prepare_trials_columns(trials: pd.DataFrame, has_drawdown: bool) -> pd.DataFrame: + def prepare_trials_columns(trials: pd.DataFrame) -> pd.DataFrame: trials["Best"] = "" if "results_metrics.winsdrawslosses" not in trials.columns: # Ensure compatibility with older versions of hyperopt results trials["results_metrics.winsdrawslosses"] = "N/A" - if not has_drawdown: + has_account_drawdown = "results_metrics.max_drawdown_account" in trials.columns + if not has_account_drawdown: # Ensure compatibility with older versions of hyperopt results trials["results_metrics.max_drawdown_account"] = None if "is_random" not in trials.columns: @@ -390,7 +391,6 @@ def prepare_trials_columns(trials: pd.DataFrame, has_drawdown: bool) -> pd.DataF "results_metrics.profit_total_abs", "results_metrics.profit_total", "results_metrics.holding_avg", - "results_metrics.max_drawdown", "results_metrics.max_drawdown_account", "results_metrics.max_drawdown_abs", "loss", @@ -410,7 +410,6 @@ def prepare_trials_columns(trials: pd.DataFrame, has_drawdown: bool) -> pd.DataF "Total profit", "Profit", "Avg duration", - "max_drawdown", "max_drawdown_account", "max_drawdown_abs", "Objective", @@ -440,9 +439,7 @@ def get_result_table( tabulate.PRESERVE_WHITESPACE = True trials = json_normalize(results, max_level=1) - has_account_drawdown = "results_metrics.max_drawdown_account" in trials.columns - - trials = HyperoptTools.prepare_trials_columns(trials, has_account_drawdown) + trials = HyperoptTools.prepare_trials_columns(trials) trials["is_profit"] = False trials.loc[trials["is_initial_point"] | trials["is_random"], "Best"] = "* " @@ -475,22 +472,19 @@ def get_result_table( stake_currency = config["stake_currency"] trials["Expectancy Ratio"] = trials["Expectancy Ratio"].apply(lambda x: f"{x:6.3f}") - - trials[f"Max Drawdown{' (Acct)' if has_account_drawdown else ''}"] = trials.apply( - lambda x: "{} {}".format( - fmt_coin(x["max_drawdown_abs"], stake_currency, keep_trailing_zeros=True), - ( - f"({x['max_drawdown_account']:,.2%})" - if has_account_drawdown - else f"({x['max_drawdown']:,.2%})" - ).rjust(7, " "), - ).rjust(20 + len(stake_currency)) - if x["max_drawdown"] != 0.0 or x["max_drawdown_account"] != 0.0 - else "--".rjust(20 + len(stake_currency)), + trials["Max Drawdown (Acct)"] = trials.apply( + lambda x: ( + "{} {}".format( + fmt_coin(x["max_drawdown_abs"], stake_currency, keep_trailing_zeros=True), + (f"({x['max_drawdown_account']:,.2%})").rjust(10, " "), + ).rjust(25 + len(stake_currency)) + if x["max_drawdown_account"] != 0.0 + else "--".rjust(25 + len(stake_currency)) + ), axis=1, ) - trials = trials.drop(columns=["max_drawdown_abs", "max_drawdown", "max_drawdown_account"]) + trials = trials.drop(columns=["max_drawdown_abs", "max_drawdown_account"]) trials["Profit"] = trials.apply( lambda x: "{} {}".format( diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index 26c55c3565b..74e8ce14539 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -498,7 +498,6 @@ def generate_strategy_stats( } try: - max_drawdown_legacy = calculate_max_drawdown(results, value_col="profit_ratio") drawdown = calculate_max_drawdown( results, value_col="profit_abs", starting_balance=start_balance ) @@ -509,7 +508,6 @@ def generate_strategy_stats( strat_stats.update( { - "max_drawdown": max_drawdown_legacy.drawdown_abs, # Deprecated - do not use "max_drawdown_account": drawdown.relative_account_drawdown, "max_relative_drawdown": underwater.relative_account_drawdown, "max_drawdown_abs": drawdown.drawdown_abs, @@ -528,7 +526,6 @@ def generate_strategy_stats( except ValueError: strat_stats.update( { - "max_drawdown": 0.0, "max_drawdown_account": 0.0, "max_relative_drawdown": 0.0, "max_drawdown_abs": 0.0, diff --git a/ft_client/requirements.txt b/ft_client/requirements.txt index 56def405997..a1eb259aa2a 100644 --- a/ft_client/requirements.txt +++ b/ft_client/requirements.txt @@ -1,3 +1,3 @@ # Requirements for freqtrade client library requests==2.31.0 -python-rapidjson==1.16 +python-rapidjson==1.17 diff --git a/mkdocs.yml b/mkdocs.yml index 4350a1cabd4..ef8b7181b17 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -48,9 +48,9 @@ nav: - Advanced Strategy: strategy-advanced.md - Advanced Hyperopt: advanced-hyperopt.md - Producer/Consumer mode: producer-consumer.md + - SQL Cheat-sheet: sql_cheatsheet.md - Edge Positioning: edge.md - FAQ: faq.md - - SQL Cheat-sheet: sql_cheatsheet.md - Strategy migration: strategy_migration.md - Updating Freqtrade: updating.md - Deprecated Features: deprecated.md diff --git a/requirements-dev.txt b/requirements-dev.txt index 38392cc0342..745773abb0d 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,12 +6,12 @@ # -r requirements-freqai-rl.txt -r docs/requirements-docs.txt -coveralls==4.0.0 +coveralls==4.0.1 ruff==0.4.4 mypy==1.10.0 pre-commit==3.7.1 -pytest==8.2.0 -pytest-asyncio==0.23.6 +pytest==8.2.1 +pytest-asyncio==0.23.7 pytest-cov==5.0.0 pytest-mock==3.14.0 pytest-random-order==1.1.1 diff --git a/requirements.txt b/requirements.txt index 898519ffd99..de3df458474 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ pandas-ta==0.3.14b finta>=1.3 ta>=0.10.1 -ccxt==4.3.23 +ccxt==4.3.27 cryptography==42.0.7 aiohttp==3.9.5 SQLAlchemy==2.0.30 @@ -24,13 +24,13 @@ jinja2==3.1.4 tables==3.9.1 joblib==1.4.2 rich==13.7.1 -pyarrow==16.0.0; platform_machine != 'armv7l' +pyarrow==16.1.0; platform_machine != 'armv7l' # find first, C search in arrays py_find_1st==1.1.6 # Load ticker files 30% faster -python-rapidjson==1.16 +python-rapidjson==1.17 # Properly format api responses orjson==3.10.3 diff --git a/setup.py b/setup.py index 7a7fc99df6e..8865f46be9f 100644 --- a/setup.py +++ b/setup.py @@ -69,7 +69,7 @@ ], install_requires=[ # from requirements.txt - "ccxt>=4.2.47", + "ccxt>=4.3.24", "SQLAlchemy>=2.0.6", "python-telegram-bot>=20.1", "humanize>=4.0.0", diff --git a/setup.sh b/setup.sh index 68374a689d0..18f7682d86c 100755 --- a/setup.sh +++ b/setup.sh @@ -25,7 +25,7 @@ function check_installed_python() { exit 2 fi - for v in 11 10 9 + for v in 12 11 10 9 do PYTHON="python3.${v}" which $PYTHON @@ -277,7 +277,7 @@ function install() { install_redhat else echo "This script does not support your OS." - echo "If you have Python version 3.9 - 3.11, pip, virtualenv, ta-lib you can continue." + echo "If you have Python version 3.9 - 3.12, pip, virtualenv, ta-lib you can continue." echo "Wait 10 seconds to continue the next install steps or use ctrl+c to interrupt this shell." sleep 10 fi diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 77cabc51bc7..c98c6302ec1 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -54,6 +54,7 @@ patch_exchange, patched_configuration_load_config_file, ) +from tests.conftest_hyperopt import hyperopt_test_result from tests.conftest_trades import MOCK_TRADE_COUNT @@ -1137,7 +1138,8 @@ def test_start_test_pairlist(mocker, caplog, tickers, default_conf, capsys): pytest.fail(f"Expected well formed JSON, but failed to parse: {captured.out}") -def test_hyperopt_list(mocker, capsys, caplog, saved_hyperopt_results, tmp_path): +def test_hyperopt_list(mocker, capsys, caplog, tmp_path): + saved_hyperopt_results = hyperopt_test_result() csv_file = tmp_path / "test.csv" mocker.patch( "freqtrade.optimize.hyperopt_tools.HyperoptTools._test_hyperopt_results_exist", @@ -1507,7 +1509,8 @@ def fake_iterator(*args, **kwargs): csv_file.unlink() -def test_hyperopt_show(mocker, capsys, saved_hyperopt_results): +def test_hyperopt_show(mocker, capsys): + saved_hyperopt_results = hyperopt_test_result() mocker.patch( "freqtrade.optimize.hyperopt_tools.HyperoptTools._test_hyperopt_results_exist", return_value=True, diff --git a/tests/conftest.py b/tests/conftest.py index c2e4f672576..944f78e22b1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2707,1004 +2707,6 @@ def open_trade_usdt(): return trade -@pytest.fixture -def saved_hyperopt_results(): - hyperopt_res = [ - { - "loss": 0.4366182531161519, - "params_dict": { - "mfi-value": 15, - "fastd-value": 20, - "adx-value": 25, - "rsi-value": 28, - "mfi-enabled": False, - "fastd-enabled": True, - "adx-enabled": True, - "rsi-enabled": True, - "trigger": "macd_cross_signal", - "sell-mfi-value": 88, - "sell-fastd-value": 97, - "sell-adx-value": 51, - "sell-rsi-value": 67, - "sell-mfi-enabled": False, - "sell-fastd-enabled": False, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-bb_upper", - "roi_t1": 1190, - "roi_t2": 541, - "roi_t3": 408, - "roi_p1": 0.026035863879169705, - "roi_p2": 0.12508730043628782, - "roi_p3": 0.27766427921605896, - "stoploss": -0.2562930402099556, - }, # noqa: E501 - "params_details": { - "buy": { - "mfi-value": 15, - "fastd-value": 20, - "adx-value": 25, - "rsi-value": 28, - "mfi-enabled": False, - "fastd-enabled": True, - "adx-enabled": True, - "rsi-enabled": True, - "trigger": "macd_cross_signal", - }, - "sell": { - "sell-mfi-value": 88, - "sell-fastd-value": 97, - "sell-adx-value": 51, - "sell-rsi-value": 67, - "sell-mfi-enabled": False, - "sell-fastd-enabled": False, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-bb_upper", - }, - "roi": { - 0: 0.4287874435315165, - 408: 0.15112316431545753, - 949: 0.026035863879169705, - 2139: 0, - }, - "stoploss": {"stoploss": -0.2562930402099556}, - }, # noqa: E501 - "results_metrics": { - "total_trades": 2, - "trade_count_long": 2, - "trade_count_short": 0, - "wins": 0, - "draws": 0, - "losses": 2, - "profit_mean": -0.01254995, - "profit_median": -0.012222, - "profit_total": -0.00125625, - "profit_total_abs": -2.50999, - "max_drawdown": 0.23, - "max_drawdown_abs": -0.00125625, - "holding_avg": timedelta(minutes=3930.0), - "stake_currency": "BTC", - "strategy_name": "SampleStrategy", - }, # noqa: E501 - "results_explanation": " 2 trades. Avg profit -1.25%. Total profit -0.00125625 BTC ( -2.51Σ%). Avg duration 3930.0 min.", # noqa: E501 - "total_profit": -0.00125625, - "current_epoch": 1, - "is_initial_point": True, - "is_random": False, - "is_best": True, - }, - { - "loss": 20.0, - "params_dict": { - "mfi-value": 17, - "fastd-value": 38, - "adx-value": 48, - "rsi-value": 22, - "mfi-enabled": True, - "fastd-enabled": False, - "adx-enabled": True, - "rsi-enabled": True, - "trigger": "macd_cross_signal", - "sell-mfi-value": 96, - "sell-fastd-value": 68, - "sell-adx-value": 63, - "sell-rsi-value": 81, - "sell-mfi-enabled": False, - "sell-fastd-enabled": True, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-sar_reversal", - "roi_t1": 334, - "roi_t2": 683, - "roi_t3": 140, - "roi_p1": 0.06403981740598495, - "roi_p2": 0.055519840060645045, - "roi_p3": 0.3253712811342459, - "stoploss": -0.338070047333259, - }, # noqa: E501 - "params_details": { - "buy": { - "mfi-value": 17, - "fastd-value": 38, - "adx-value": 48, - "rsi-value": 22, - "mfi-enabled": True, - "fastd-enabled": False, - "adx-enabled": True, - "rsi-enabled": True, - "trigger": "macd_cross_signal", - }, # noqa: E501 - "sell": { - "sell-mfi-value": 96, - "sell-fastd-value": 68, - "sell-adx-value": 63, - "sell-rsi-value": 81, - "sell-mfi-enabled": False, - "sell-fastd-enabled": True, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-sar_reversal", - }, # noqa: E501 - "roi": { - 0: 0.4449309386008759, - 140: 0.11955965746663, - 823: 0.06403981740598495, - 1157: 0, - }, # noqa: E501 - "stoploss": {"stoploss": -0.338070047333259}, - }, - "results_metrics": { - "total_trades": 1, - "trade_count_long": 1, - "trade_count_short": 0, - "wins": 0, - "draws": 0, - "losses": 1, - "profit_mean": 0.012357, - "profit_median": -0.012222, - "profit_total": 6.185e-05, - "profit_total_abs": 0.12357, - "max_drawdown": 0.23, - "max_drawdown_abs": -0.00125625, - "holding_avg": timedelta(minutes=1200.0), - }, # noqa: E501 - "results_explanation": " 1 trades. Avg profit 0.12%. Total profit 0.00006185 BTC ( 0.12Σ%). Avg duration 1200.0 min.", # noqa: E501 - "total_profit": 6.185e-05, - "current_epoch": 2, - "is_initial_point": True, - "is_random": False, - "is_best": False, - }, - { - "loss": 14.241196856510731, - "params_dict": { - "mfi-value": 25, - "fastd-value": 16, - "adx-value": 29, - "rsi-value": 20, - "mfi-enabled": False, - "fastd-enabled": False, - "adx-enabled": False, - "rsi-enabled": False, - "trigger": "macd_cross_signal", - "sell-mfi-value": 98, - "sell-fastd-value": 72, - "sell-adx-value": 51, - "sell-rsi-value": 82, - "sell-mfi-enabled": True, - "sell-fastd-enabled": True, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-macd_cross_signal", - "roi_t1": 889, - "roi_t2": 533, - "roi_t3": 263, - "roi_p1": 0.04759065393663096, - "roi_p2": 0.1488819964638463, - "roi_p3": 0.4102801822104605, - "stoploss": -0.05394588767607611, - }, # noqa: E501 - "params_details": { - "buy": { - "mfi-value": 25, - "fastd-value": 16, - "adx-value": 29, - "rsi-value": 20, - "mfi-enabled": False, - "fastd-enabled": False, - "adx-enabled": False, - "rsi-enabled": False, - "trigger": "macd_cross_signal", - }, - "sell": { - "sell-mfi-value": 98, - "sell-fastd-value": 72, - "sell-adx-value": 51, - "sell-rsi-value": 82, - "sell-mfi-enabled": True, - "sell-fastd-enabled": True, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-macd_cross_signal", - }, - "roi": { - 0: 0.6067528326109377, - 263: 0.19647265040047726, - 796: 0.04759065393663096, - 1685: 0, - }, - "stoploss": {"stoploss": -0.05394588767607611}, - }, # noqa: E501 - "results_metrics": { - "total_trades": 621, - "trade_count_long": 621, - "trade_count_short": 0, - "wins": 320, - "draws": 0, - "losses": 301, - "profit_mean": -0.043883302093397747, - "profit_median": -0.012222, - "profit_total": -0.13639474, - "profit_total_abs": -272.515306, - "max_drawdown": 0.25, - "max_drawdown_abs": -272.515306, - "holding_avg": timedelta(minutes=1691.207729468599), - }, # noqa: E501 - "results_explanation": " 621 trades. Avg profit -0.44%. Total profit -0.13639474 BTC (-272.52Σ%). Avg duration 1691.2 min.", # noqa: E501 - "total_profit": -0.13639474, - "current_epoch": 3, - "is_initial_point": True, - "is_random": False, - "is_best": False, - }, - { - "loss": 100000, - "params_dict": { - "mfi-value": 13, - "fastd-value": 35, - "adx-value": 39, - "rsi-value": 29, - "mfi-enabled": True, - "fastd-enabled": False, - "adx-enabled": False, - "rsi-enabled": True, - "trigger": "macd_cross_signal", - "sell-mfi-value": 87, - "sell-fastd-value": 54, - "sell-adx-value": 63, - "sell-rsi-value": 93, - "sell-mfi-enabled": False, - "sell-fastd-enabled": True, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-bb_upper", - "roi_t1": 1402, - "roi_t2": 676, - "roi_t3": 215, - "roi_p1": 0.06264755784937427, - "roi_p2": 0.14258587851894644, - "roi_p3": 0.20671291201040828, - "stoploss": -0.11818343570194478, - }, # noqa: E501 - "params_details": { - "buy": { - "mfi-value": 13, - "fastd-value": 35, - "adx-value": 39, - "rsi-value": 29, - "mfi-enabled": True, - "fastd-enabled": False, - "adx-enabled": False, - "rsi-enabled": True, - "trigger": "macd_cross_signal", - }, - "sell": { - "sell-mfi-value": 87, - "sell-fastd-value": 54, - "sell-adx-value": 63, - "sell-rsi-value": 93, - "sell-mfi-enabled": False, - "sell-fastd-enabled": True, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-bb_upper", - }, - "roi": { - 0: 0.411946348378729, - 215: 0.2052334363683207, - 891: 0.06264755784937427, - 2293: 0, - }, - "stoploss": {"stoploss": -0.11818343570194478}, - }, # noqa: E501 - "results_metrics": { - "total_trades": 0, - "trade_count_long": 0, - "trade_count_short": 0, - "wins": 0, - "draws": 0, - "losses": 0, - "profit_mean": None, - "profit_median": None, - "profit_total": 0, - "profit": 0.0, - "holding_avg": timedelta(), - }, # noqa: E501 - "results_explanation": " 0 trades. Avg profit nan%. Total profit 0.00000000 BTC ( 0.00Σ%). Avg duration nan min.", # noqa: E501 - "total_profit": 0, - "current_epoch": 4, - "is_initial_point": True, - "is_random": False, - "is_best": False, # noqa: E501 - }, - { - "loss": 0.22195522184191518, - "params_dict": { - "mfi-value": 17, - "fastd-value": 21, - "adx-value": 38, - "rsi-value": 33, - "mfi-enabled": True, - "fastd-enabled": False, - "adx-enabled": True, - "rsi-enabled": False, - "trigger": "macd_cross_signal", - "sell-mfi-value": 87, - "sell-fastd-value": 82, - "sell-adx-value": 78, - "sell-rsi-value": 69, - "sell-mfi-enabled": True, - "sell-fastd-enabled": False, - "sell-adx-enabled": True, - "sell-rsi-enabled": False, - "sell-trigger": "sell-macd_cross_signal", - "roi_t1": 1269, - "roi_t2": 601, - "roi_t3": 444, - "roi_p1": 0.07280999507931168, - "roi_p2": 0.08946698095898986, - "roi_p3": 0.1454876733325284, - "stoploss": -0.18181041180901014, - }, # noqa: E501 - "params_details": { - "buy": { - "mfi-value": 17, - "fastd-value": 21, - "adx-value": 38, - "rsi-value": 33, - "mfi-enabled": True, - "fastd-enabled": False, - "adx-enabled": True, - "rsi-enabled": False, - "trigger": "macd_cross_signal", - }, - "sell": { - "sell-mfi-value": 87, - "sell-fastd-value": 82, - "sell-adx-value": 78, - "sell-rsi-value": 69, - "sell-mfi-enabled": True, - "sell-fastd-enabled": False, - "sell-adx-enabled": True, - "sell-rsi-enabled": False, - "sell-trigger": "sell-macd_cross_signal", - }, - "roi": { - 0: 0.3077646493708299, - 444: 0.16227697603830155, - 1045: 0.07280999507931168, - 2314: 0, - }, - "stoploss": {"stoploss": -0.18181041180901014}, - }, # noqa: E501 - "results_metrics": { - "total_trades": 14, - "trade_count_long": 14, - "trade_count_short": 0, - "wins": 6, - "draws": 0, - "losses": 8, - "profit_mean": -0.003539515, - "profit_median": -0.012222, - "profit_total": -0.002480140000000001, - "profit_total_abs": -4.955321, - "max_drawdown": 0.34, - "max_drawdown_abs": -4.955321, - "holding_avg": timedelta(minutes=3402.8571428571427), - }, # noqa: E501 - "results_explanation": " 14 trades. Avg profit -0.35%. Total profit -0.00248014 BTC ( -4.96Σ%). Avg duration 3402.9 min.", # noqa: E501 - "total_profit": -0.002480140000000001, - "current_epoch": 5, - "is_initial_point": True, - "is_random": False, - "is_best": True, - }, - { - "loss": 0.545315889154162, - "params_dict": { - "mfi-value": 22, - "fastd-value": 43, - "adx-value": 46, - "rsi-value": 20, - "mfi-enabled": False, - "fastd-enabled": False, - "adx-enabled": True, - "rsi-enabled": True, - "trigger": "bb_lower", - "sell-mfi-value": 87, - "sell-fastd-value": 65, - "sell-adx-value": 94, - "sell-rsi-value": 63, - "sell-mfi-enabled": False, - "sell-fastd-enabled": True, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-macd_cross_signal", - "roi_t1": 319, - "roi_t2": 556, - "roi_t3": 216, - "roi_p1": 0.06251955472249589, - "roi_p2": 0.11659519602202795, - "roi_p3": 0.0953744132197762, - "stoploss": -0.024551752215582423, - }, # noqa: E501 - "params_details": { - "buy": { - "mfi-value": 22, - "fastd-value": 43, - "adx-value": 46, - "rsi-value": 20, - "mfi-enabled": False, - "fastd-enabled": False, - "adx-enabled": True, - "rsi-enabled": True, - "trigger": "bb_lower", - }, - "sell": { - "sell-mfi-value": 87, - "sell-fastd-value": 65, - "sell-adx-value": 94, - "sell-rsi-value": 63, - "sell-mfi-enabled": False, - "sell-fastd-enabled": True, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-macd_cross_signal", - }, - "roi": { - 0: 0.2744891639643, - 216: 0.17911475074452382, - 772: 0.06251955472249589, - 1091: 0, - }, - "stoploss": {"stoploss": -0.024551752215582423}, - }, # noqa: E501 - "results_metrics": { - "total_trades": 39, - "trade_count_long": 39, - "trade_count_short": 0, - "wins": 20, - "draws": 0, - "losses": 19, - "profit_mean": -0.0021400679487179478, - "profit_median": -0.012222, - "profit_total": -0.0041773, - "profit_total_abs": -8.346264999999997, - "max_drawdown": 0.45, - "max_drawdown_abs": -4.955321, - "holding_avg": timedelta(minutes=636.9230769230769), - }, # noqa: E501 - "results_explanation": " 39 trades. Avg profit -0.21%. Total profit -0.00417730 BTC ( -8.35Σ%). Avg duration 636.9 min.", # noqa: E501 - "total_profit": -0.0041773, - "current_epoch": 6, - "is_initial_point": True, - "is_random": False, - "is_best": False, - }, - { - "loss": 4.713497421432944, - "params_dict": { - "mfi-value": 13, - "fastd-value": 41, - "adx-value": 21, - "rsi-value": 29, - "mfi-enabled": False, - "fastd-enabled": True, - "adx-enabled": False, - "rsi-enabled": False, - "trigger": "bb_lower", - "sell-mfi-value": 99, - "sell-fastd-value": 60, - "sell-adx-value": 81, - "sell-rsi-value": 69, - "sell-mfi-enabled": True, - "sell-fastd-enabled": True, - "sell-adx-enabled": True, - "sell-rsi-enabled": False, - "sell-trigger": "sell-macd_cross_signal", - "roi_t1": 771, - "roi_t2": 620, - "roi_t3": 145, - "roi_p1": 0.0586919200378493, - "roi_p2": 0.04984118697312542, - "roi_p3": 0.37521058680247044, - "stoploss": -0.14613268022709905, - }, # noqa: E501 - "params_details": { - "buy": { - "mfi-value": 13, - "fastd-value": 41, - "adx-value": 21, - "rsi-value": 29, - "mfi-enabled": False, - "fastd-enabled": True, - "adx-enabled": False, - "rsi-enabled": False, - "trigger": "bb_lower", - }, - "sell": { - "sell-mfi-value": 99, - "sell-fastd-value": 60, - "sell-adx-value": 81, - "sell-rsi-value": 69, - "sell-mfi-enabled": True, - "sell-fastd-enabled": True, - "sell-adx-enabled": True, - "sell-rsi-enabled": False, - "sell-trigger": "sell-macd_cross_signal", - }, - "roi": { - 0: 0.4837436938134452, - 145: 0.10853310701097472, - 765: 0.0586919200378493, - 1536: 0, - }, # noqa: E501 - "stoploss": {"stoploss": -0.14613268022709905}, - }, # noqa: E501 - "results_metrics": { - "total_trades": 318, - "trade_count_long": 318, - "trade_count_short": 0, - "wins": 100, - "draws": 0, - "losses": 218, - "profit_mean": -0.0039833954716981146, - "profit_median": -0.012222, - "profit_total": -0.06339929, - "profit_total_abs": -126.67197600000004, - "max_drawdown": 0.50, - "max_drawdown_abs": -200.955321, - "holding_avg": timedelta(minutes=3140.377358490566), - }, # noqa: E501 - "results_explanation": " 318 trades. Avg profit -0.40%. Total profit -0.06339929 BTC (-126.67Σ%). Avg duration 3140.4 min.", # noqa: E501 - "total_profit": -0.06339929, - "current_epoch": 7, - "is_initial_point": True, - "is_random": False, - "is_best": False, - }, - { - "loss": 20.0, # noqa: E501 - "params_dict": { - "mfi-value": 24, - "fastd-value": 43, - "adx-value": 33, - "rsi-value": 20, - "mfi-enabled": False, - "fastd-enabled": True, - "adx-enabled": True, - "rsi-enabled": True, - "trigger": "sar_reversal", - "sell-mfi-value": 89, - "sell-fastd-value": 74, - "sell-adx-value": 70, - "sell-rsi-value": 70, - "sell-mfi-enabled": False, - "sell-fastd-enabled": False, - "sell-adx-enabled": False, - "sell-rsi-enabled": True, - "sell-trigger": "sell-sar_reversal", - "roi_t1": 1149, - "roi_t2": 375, - "roi_t3": 289, - "roi_p1": 0.05571820757172588, - "roi_p2": 0.0606240398618907, - "roi_p3": 0.1729012220156157, - "stoploss": -0.1588514289110401, - }, # noqa: E501 - "params_details": { - "buy": { - "mfi-value": 24, - "fastd-value": 43, - "adx-value": 33, - "rsi-value": 20, - "mfi-enabled": False, - "fastd-enabled": True, - "adx-enabled": True, - "rsi-enabled": True, - "trigger": "sar_reversal", - }, - "sell": { - "sell-mfi-value": 89, - "sell-fastd-value": 74, - "sell-adx-value": 70, - "sell-rsi-value": 70, - "sell-mfi-enabled": False, - "sell-fastd-enabled": False, - "sell-adx-enabled": False, - "sell-rsi-enabled": True, - "sell-trigger": "sell-sar_reversal", - }, - "roi": { - 0: 0.2892434694492323, - 289: 0.11634224743361658, - 664: 0.05571820757172588, - 1813: 0, - }, - "stoploss": {"stoploss": -0.1588514289110401}, - }, # noqa: E501 - "results_metrics": { - "total_trades": 1, - "trade_count_long": 1, - "trade_count_short": 0, - "wins": 0, - "draws": 1, - "losses": 0, - "profit_mean": 0.0, - "profit_median": 0.0, - "profit_total": 0.0, - "profit_total_abs": 0.0, - "max_drawdown": 0.0, - "max_drawdown_abs": 0.52, - "holding_avg": timedelta(minutes=5340.0), - }, # noqa: E501 - "results_explanation": " 1 trades. Avg profit 0.00%. Total profit 0.00000000 BTC ( 0.00Σ%). Avg duration 5340.0 min.", # noqa: E501 - "total_profit": 0.0, - "current_epoch": 8, - "is_initial_point": True, - "is_random": False, - "is_best": False, - }, - { - "loss": 2.4731817780991223, - "params_dict": { - "mfi-value": 22, - "fastd-value": 20, - "adx-value": 29, - "rsi-value": 40, - "mfi-enabled": False, - "fastd-enabled": False, - "adx-enabled": False, - "rsi-enabled": False, - "trigger": "sar_reversal", - "sell-mfi-value": 97, - "sell-fastd-value": 65, - "sell-adx-value": 81, - "sell-rsi-value": 64, - "sell-mfi-enabled": True, - "sell-fastd-enabled": True, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-bb_upper", - "roi_t1": 1012, - "roi_t2": 584, - "roi_t3": 422, - "roi_p1": 0.036764323603472565, - "roi_p2": 0.10335480573205287, - "roi_p3": 0.10322347377503042, - "stoploss": -0.2780610808108503, - }, # noqa: E501 - "params_details": { - "buy": { - "mfi-value": 22, - "fastd-value": 20, - "adx-value": 29, - "rsi-value": 40, - "mfi-enabled": False, - "fastd-enabled": False, - "adx-enabled": False, - "rsi-enabled": False, - "trigger": "sar_reversal", - }, - "sell": { - "sell-mfi-value": 97, - "sell-fastd-value": 65, - "sell-adx-value": 81, - "sell-rsi-value": 64, - "sell-mfi-enabled": True, - "sell-fastd-enabled": True, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-bb_upper", - }, - "roi": { - 0: 0.2433426031105559, - 422: 0.14011912933552545, - 1006: 0.036764323603472565, - 2018: 0, - }, - "stoploss": {"stoploss": -0.2780610808108503}, - }, # noqa: E501 - "results_metrics": { - "total_trades": 229, - "trade_count_long": 229, - "trade_count_short": 0, - "wins": 150, - "draws": 0, - "losses": 79, - "profit_mean": -0.0038433433624454144, - "profit_median": -0.012222, - "profit_total": -0.044050070000000004, - "profit_total_abs": -88.01256299999999, - "max_drawdown": 0.41, - "max_drawdown_abs": -150.955321, - "holding_avg": timedelta(minutes=6505.676855895196), - }, # noqa: E501 - "results_explanation": " 229 trades. Avg profit -0.38%. Total profit -0.04405007 BTC ( -88.01Σ%). Avg duration 6505.7 min.", # noqa: E501 - "total_profit": -0.044050070000000004, # noqa: E501 - "current_epoch": 9, - "is_initial_point": True, - "is_random": False, - "is_best": False, - }, - { - "loss": -0.2604606005845212, # noqa: E501 - "params_dict": { - "mfi-value": 23, - "fastd-value": 24, - "adx-value": 22, - "rsi-value": 24, - "mfi-enabled": False, - "fastd-enabled": False, - "adx-enabled": False, - "rsi-enabled": True, - "trigger": "macd_cross_signal", - "sell-mfi-value": 97, - "sell-fastd-value": 70, - "sell-adx-value": 64, - "sell-rsi-value": 80, - "sell-mfi-enabled": False, - "sell-fastd-enabled": True, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-sar_reversal", - "roi_t1": 792, - "roi_t2": 464, - "roi_t3": 215, - "roi_p1": 0.04594053535385903, - "roi_p2": 0.09623192684243963, - "roi_p3": 0.04428219070850663, - "stoploss": -0.16992287161634415, - }, # noqa: E501 - "params_details": { - "buy": { - "mfi-value": 23, - "fastd-value": 24, - "adx-value": 22, - "rsi-value": 24, - "mfi-enabled": False, - "fastd-enabled": False, - "adx-enabled": False, - "rsi-enabled": True, - "trigger": "macd_cross_signal", - }, - "sell": { - "sell-mfi-value": 97, - "sell-fastd-value": 70, - "sell-adx-value": 64, - "sell-rsi-value": 80, - "sell-mfi-enabled": False, - "sell-fastd-enabled": True, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-sar_reversal", - }, - "roi": { - 0: 0.18645465290480528, - 215: 0.14217246219629864, - 679: 0.04594053535385903, - 1471: 0, - }, - "stoploss": {"stoploss": -0.16992287161634415}, - }, # noqa: E501 - "results_metrics": { - "total_trades": 4, - "trade_count_long": 4, - "trade_count_short": 0, - "wins": 0, - "draws": 0, - "losses": 4, - "profit_mean": 0.001080385, - "profit_median": -0.012222, - "profit_total": 0.00021629, - "profit_total_abs": 0.432154, - "max_drawdown": 0.13, - "max_drawdown_abs": -4.955321, - "holding_avg": timedelta(minutes=2850.0), - }, # noqa: E501 - "results_explanation": " 4 trades. Avg profit 0.11%. Total profit 0.00021629 BTC ( 0.43Σ%). Avg duration 2850.0 min.", # noqa: E501 - "total_profit": 0.00021629, - "current_epoch": 10, - "is_initial_point": True, - "is_random": False, - "is_best": True, - }, - { - "loss": 4.876465945994304, # noqa: E501 - "params_dict": { - "mfi-value": 20, - "fastd-value": 32, - "adx-value": 49, - "rsi-value": 23, - "mfi-enabled": True, - "fastd-enabled": True, - "adx-enabled": False, - "rsi-enabled": False, - "trigger": "bb_lower", - "sell-mfi-value": 75, - "sell-fastd-value": 56, - "sell-adx-value": 61, - "sell-rsi-value": 62, - "sell-mfi-enabled": False, - "sell-fastd-enabled": False, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-macd_cross_signal", - "roi_t1": 579, - "roi_t2": 614, - "roi_t3": 273, - "roi_p1": 0.05307643172744114, - "roi_p2": 0.1352282078262871, - "roi_p3": 0.1913307406325751, - "stoploss": -0.25728526022513887, - }, # noqa: E501 - "params_details": { - "buy": { - "mfi-value": 20, - "fastd-value": 32, - "adx-value": 49, - "rsi-value": 23, - "mfi-enabled": True, - "fastd-enabled": True, - "adx-enabled": False, - "rsi-enabled": False, - "trigger": "bb_lower", - }, - "sell": { - "sell-mfi-value": 75, - "sell-fastd-value": 56, - "sell-adx-value": 61, - "sell-rsi-value": 62, - "sell-mfi-enabled": False, - "sell-fastd-enabled": False, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-macd_cross_signal", - }, - "roi": { - 0: 0.3796353801863034, - 273: 0.18830463955372825, - 887: 0.05307643172744114, - 1466: 0, - }, - "stoploss": {"stoploss": -0.25728526022513887}, - }, # noqa: E501 - # New Hyperopt mode! - "results_metrics": { - "total_trades": 117, - "trade_count_long": 117, - "trade_count_short": 0, - "wins": 67, - "draws": 0, - "losses": 50, - "profit_mean": -0.012698609145299145, - "profit_median": -0.012222, - "profit_total": -0.07436117, - "profit_total_abs": -148.573727, - "max_drawdown": 0.52, - "max_drawdown_abs": -224.955321, - "holding_avg": timedelta(minutes=4282.5641025641025), - }, # noqa: E501 - "results_explanation": " 117 trades. Avg profit -1.27%. Total profit -0.07436117 BTC (-148.57Σ%). Avg duration 4282.6 min.", # noqa: E501 - "total_profit": -0.07436117, - "current_epoch": 11, - "is_initial_point": True, - "is_random": False, - "is_best": False, - }, - { - "loss": 100000, - "params_dict": { - "mfi-value": 10, - "fastd-value": 36, - "adx-value": 31, - "rsi-value": 22, - "mfi-enabled": True, - "fastd-enabled": True, - "adx-enabled": True, - "rsi-enabled": False, - "trigger": "sar_reversal", - "sell-mfi-value": 80, - "sell-fastd-value": 71, - "sell-adx-value": 60, - "sell-rsi-value": 85, - "sell-mfi-enabled": False, - "sell-fastd-enabled": False, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-bb_upper", - "roi_t1": 1156, - "roi_t2": 581, - "roi_t3": 408, - "roi_p1": 0.06860454019988212, - "roi_p2": 0.12473718444931989, - "roi_p3": 0.2896360635226823, - "stoploss": -0.30889015124682806, - }, # noqa: E501 - "params_details": { - "buy": { - "mfi-value": 10, - "fastd-value": 36, - "adx-value": 31, - "rsi-value": 22, - "mfi-enabled": True, - "fastd-enabled": True, - "adx-enabled": True, - "rsi-enabled": False, - "trigger": "sar_reversal", - }, - "sell": { - "sell-mfi-value": 80, - "sell-fastd-value": 71, - "sell-adx-value": 60, - "sell-rsi-value": 85, - "sell-mfi-enabled": False, - "sell-fastd-enabled": False, - "sell-adx-enabled": True, - "sell-rsi-enabled": True, - "sell-trigger": "sell-bb_upper", - }, - "roi": { - 0: 0.4829777881718843, - 408: 0.19334172464920202, - 989: 0.06860454019988212, - 2145: 0, - }, - "stoploss": {"stoploss": -0.30889015124682806}, - }, # noqa: E501 - "results_metrics": { - "total_trades": 0, - "trade_count_long": 0, - "trade_count_short": 0, - "wins": 0, - "draws": 0, - "losses": 0, - "profit_mean": None, - "profit_median": None, - "profit_total": 0, - "profit_total_abs": 0.0, - "max_drawdown": 0.0, - "max_drawdown_abs": 0.0, - "holding_avg": timedelta(), - }, # noqa: E501 - "results_explanation": " 0 trades. Avg profit nan%. Total profit 0.00000000 BTC ( 0.00Σ%). Avg duration nan min.", # noqa: E501 - "total_profit": 0, - "current_epoch": 12, - "is_initial_point": True, - "is_random": False, - "is_best": False, - }, - ] - - for res in hyperopt_res: - res["results_metrics"]["holding_avg_s"] = res["results_metrics"][ - "holding_avg" - ].total_seconds() - - return hyperopt_res - - @pytest.fixture(scope="function") def limit_buy_order_usdt_open(): return { diff --git a/tests/conftest_hyperopt.py b/tests/conftest_hyperopt.py new file mode 100644 index 00000000000..af4039a3cdc --- /dev/null +++ b/tests/conftest_hyperopt.py @@ -0,0 +1,1000 @@ +from datetime import timedelta + + +def hyperopt_test_result(): + """ + Sample hyperopt test result, used for some tests. + """ + hyperopt_res = [ + { + "loss": 0.4366182531161519, + "params_dict": { + "mfi-value": 15, + "fastd-value": 20, + "adx-value": 25, + "rsi-value": 28, + "mfi-enabled": False, + "fastd-enabled": True, + "adx-enabled": True, + "rsi-enabled": True, + "trigger": "macd_cross_signal", + "sell-mfi-value": 88, + "sell-fastd-value": 97, + "sell-adx-value": 51, + "sell-rsi-value": 67, + "sell-mfi-enabled": False, + "sell-fastd-enabled": False, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-bb_upper", + "roi_t1": 1190, + "roi_t2": 541, + "roi_t3": 408, + "roi_p1": 0.026035863879169705, + "roi_p2": 0.12508730043628782, + "roi_p3": 0.27766427921605896, + "stoploss": -0.2562930402099556, + }, # noqa: E501 + "params_details": { + "buy": { + "mfi-value": 15, + "fastd-value": 20, + "adx-value": 25, + "rsi-value": 28, + "mfi-enabled": False, + "fastd-enabled": True, + "adx-enabled": True, + "rsi-enabled": True, + "trigger": "macd_cross_signal", + }, + "sell": { + "sell-mfi-value": 88, + "sell-fastd-value": 97, + "sell-adx-value": 51, + "sell-rsi-value": 67, + "sell-mfi-enabled": False, + "sell-fastd-enabled": False, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-bb_upper", + }, + "roi": { + 0: 0.4287874435315165, + 408: 0.15112316431545753, + 949: 0.026035863879169705, + 2139: 0, + }, + "stoploss": {"stoploss": -0.2562930402099556}, + }, # noqa: E501 + "results_metrics": { + "total_trades": 2, + "trade_count_long": 2, + "trade_count_short": 0, + "wins": 0, + "draws": 0, + "losses": 2, + "profit_mean": -0.01254995, + "profit_median": -0.012222, + "profit_total": -0.00125625, + "profit_total_abs": -2.50999, + "max_drawdown_account": 0.23, + "max_drawdown_abs": -0.00125625, + "holding_avg": timedelta(minutes=3930.0), + "stake_currency": "BTC", + "strategy_name": "SampleStrategy", + }, # noqa: E501 + "results_explanation": " 2 trades. Avg profit -1.25%. Total profit -0.00125625 BTC ( -2.51Σ%). Avg duration 3930.0 min.", # noqa: E501 + "total_profit": -0.00125625, + "current_epoch": 1, + "is_initial_point": True, + "is_random": False, + "is_best": True, + }, + { + "loss": 20.0, + "params_dict": { + "mfi-value": 17, + "fastd-value": 38, + "adx-value": 48, + "rsi-value": 22, + "mfi-enabled": True, + "fastd-enabled": False, + "adx-enabled": True, + "rsi-enabled": True, + "trigger": "macd_cross_signal", + "sell-mfi-value": 96, + "sell-fastd-value": 68, + "sell-adx-value": 63, + "sell-rsi-value": 81, + "sell-mfi-enabled": False, + "sell-fastd-enabled": True, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-sar_reversal", + "roi_t1": 334, + "roi_t2": 683, + "roi_t3": 140, + "roi_p1": 0.06403981740598495, + "roi_p2": 0.055519840060645045, + "roi_p3": 0.3253712811342459, + "stoploss": -0.338070047333259, + }, # noqa: E501 + "params_details": { + "buy": { + "mfi-value": 17, + "fastd-value": 38, + "adx-value": 48, + "rsi-value": 22, + "mfi-enabled": True, + "fastd-enabled": False, + "adx-enabled": True, + "rsi-enabled": True, + "trigger": "macd_cross_signal", + }, # noqa: E501 + "sell": { + "sell-mfi-value": 96, + "sell-fastd-value": 68, + "sell-adx-value": 63, + "sell-rsi-value": 81, + "sell-mfi-enabled": False, + "sell-fastd-enabled": True, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-sar_reversal", + }, # noqa: E501 + "roi": { + 0: 0.4449309386008759, + 140: 0.11955965746663, + 823: 0.06403981740598495, + 1157: 0, + }, # noqa: E501 + "stoploss": {"stoploss": -0.338070047333259}, + }, + "results_metrics": { + "total_trades": 1, + "trade_count_long": 1, + "trade_count_short": 0, + "wins": 0, + "draws": 0, + "losses": 1, + "profit_mean": 0.012357, + "profit_median": -0.012222, + "profit_total": 6.185e-05, + "profit_total_abs": 0.12357, + "max_drawdown_account": 0.23, + "max_drawdown_abs": -0.00125625, + "holding_avg": timedelta(minutes=1200.0), + }, # noqa: E501 + "results_explanation": " 1 trades. Avg profit 0.12%. Total profit 0.00006185 BTC ( 0.12Σ%). Avg duration 1200.0 min.", # noqa: E501 + "total_profit": 6.185e-05, + "current_epoch": 2, + "is_initial_point": True, + "is_random": False, + "is_best": False, + }, + { + "loss": 14.241196856510731, + "params_dict": { + "mfi-value": 25, + "fastd-value": 16, + "adx-value": 29, + "rsi-value": 20, + "mfi-enabled": False, + "fastd-enabled": False, + "adx-enabled": False, + "rsi-enabled": False, + "trigger": "macd_cross_signal", + "sell-mfi-value": 98, + "sell-fastd-value": 72, + "sell-adx-value": 51, + "sell-rsi-value": 82, + "sell-mfi-enabled": True, + "sell-fastd-enabled": True, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-macd_cross_signal", + "roi_t1": 889, + "roi_t2": 533, + "roi_t3": 263, + "roi_p1": 0.04759065393663096, + "roi_p2": 0.1488819964638463, + "roi_p3": 0.4102801822104605, + "stoploss": -0.05394588767607611, + }, # noqa: E501 + "params_details": { + "buy": { + "mfi-value": 25, + "fastd-value": 16, + "adx-value": 29, + "rsi-value": 20, + "mfi-enabled": False, + "fastd-enabled": False, + "adx-enabled": False, + "rsi-enabled": False, + "trigger": "macd_cross_signal", + }, + "sell": { + "sell-mfi-value": 98, + "sell-fastd-value": 72, + "sell-adx-value": 51, + "sell-rsi-value": 82, + "sell-mfi-enabled": True, + "sell-fastd-enabled": True, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-macd_cross_signal", + }, + "roi": { + 0: 0.6067528326109377, + 263: 0.19647265040047726, + 796: 0.04759065393663096, + 1685: 0, + }, + "stoploss": {"stoploss": -0.05394588767607611}, + }, # noqa: E501 + "results_metrics": { + "total_trades": 621, + "trade_count_long": 621, + "trade_count_short": 0, + "wins": 320, + "draws": 0, + "losses": 301, + "profit_mean": -0.043883302093397747, + "profit_median": -0.012222, + "profit_total": -0.13639474, + "profit_total_abs": -272.515306, + "max_drawdown_account": 0.25, + "max_drawdown_abs": -272.515306, + "holding_avg": timedelta(minutes=1691.207729468599), + }, # noqa: E501 + "results_explanation": " 621 trades. Avg profit -0.44%. Total profit -0.13639474 BTC (-272.52Σ%). Avg duration 1691.2 min.", # noqa: E501 + "total_profit": -0.13639474, + "current_epoch": 3, + "is_initial_point": True, + "is_random": False, + "is_best": False, + }, + { + "loss": 100000, + "params_dict": { + "mfi-value": 13, + "fastd-value": 35, + "adx-value": 39, + "rsi-value": 29, + "mfi-enabled": True, + "fastd-enabled": False, + "adx-enabled": False, + "rsi-enabled": True, + "trigger": "macd_cross_signal", + "sell-mfi-value": 87, + "sell-fastd-value": 54, + "sell-adx-value": 63, + "sell-rsi-value": 93, + "sell-mfi-enabled": False, + "sell-fastd-enabled": True, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-bb_upper", + "roi_t1": 1402, + "roi_t2": 676, + "roi_t3": 215, + "roi_p1": 0.06264755784937427, + "roi_p2": 0.14258587851894644, + "roi_p3": 0.20671291201040828, + "stoploss": -0.11818343570194478, + }, # noqa: E501 + "params_details": { + "buy": { + "mfi-value": 13, + "fastd-value": 35, + "adx-value": 39, + "rsi-value": 29, + "mfi-enabled": True, + "fastd-enabled": False, + "adx-enabled": False, + "rsi-enabled": True, + "trigger": "macd_cross_signal", + }, + "sell": { + "sell-mfi-value": 87, + "sell-fastd-value": 54, + "sell-adx-value": 63, + "sell-rsi-value": 93, + "sell-mfi-enabled": False, + "sell-fastd-enabled": True, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-bb_upper", + }, + "roi": { + 0: 0.411946348378729, + 215: 0.2052334363683207, + 891: 0.06264755784937427, + 2293: 0, + }, + "stoploss": {"stoploss": -0.11818343570194478}, + }, # noqa: E501 + "results_metrics": { + "total_trades": 0, + "trade_count_long": 0, + "trade_count_short": 0, + "wins": 0, + "draws": 0, + "losses": 0, + "profit_mean": None, + "profit_median": None, + "profit_total": 0, + "profit": 0.0, + "holding_avg": timedelta(), + }, # noqa: E501 + "results_explanation": " 0 trades. Avg profit nan%. Total profit 0.00000000 BTC ( 0.00Σ%). Avg duration nan min.", # noqa: E501 + "total_profit": 0, + "current_epoch": 4, + "is_initial_point": True, + "is_random": False, + "is_best": False, # noqa: E501 + }, + { + "loss": 0.22195522184191518, + "params_dict": { + "mfi-value": 17, + "fastd-value": 21, + "adx-value": 38, + "rsi-value": 33, + "mfi-enabled": True, + "fastd-enabled": False, + "adx-enabled": True, + "rsi-enabled": False, + "trigger": "macd_cross_signal", + "sell-mfi-value": 87, + "sell-fastd-value": 82, + "sell-adx-value": 78, + "sell-rsi-value": 69, + "sell-mfi-enabled": True, + "sell-fastd-enabled": False, + "sell-adx-enabled": True, + "sell-rsi-enabled": False, + "sell-trigger": "sell-macd_cross_signal", + "roi_t1": 1269, + "roi_t2": 601, + "roi_t3": 444, + "roi_p1": 0.07280999507931168, + "roi_p2": 0.08946698095898986, + "roi_p3": 0.1454876733325284, + "stoploss": -0.18181041180901014, + }, # noqa: E501 + "params_details": { + "buy": { + "mfi-value": 17, + "fastd-value": 21, + "adx-value": 38, + "rsi-value": 33, + "mfi-enabled": True, + "fastd-enabled": False, + "adx-enabled": True, + "rsi-enabled": False, + "trigger": "macd_cross_signal", + }, + "sell": { + "sell-mfi-value": 87, + "sell-fastd-value": 82, + "sell-adx-value": 78, + "sell-rsi-value": 69, + "sell-mfi-enabled": True, + "sell-fastd-enabled": False, + "sell-adx-enabled": True, + "sell-rsi-enabled": False, + "sell-trigger": "sell-macd_cross_signal", + }, + "roi": { + 0: 0.3077646493708299, + 444: 0.16227697603830155, + 1045: 0.07280999507931168, + 2314: 0, + }, + "stoploss": {"stoploss": -0.18181041180901014}, + }, # noqa: E501 + "results_metrics": { + "total_trades": 14, + "trade_count_long": 14, + "trade_count_short": 0, + "wins": 6, + "draws": 0, + "losses": 8, + "profit_mean": -0.003539515, + "profit_median": -0.012222, + "profit_total": -0.002480140000000001, + "profit_total_abs": -4.955321, + "max_drawdown_account": 0.34, + "max_drawdown_abs": -4.955321, + "holding_avg": timedelta(minutes=3402.8571428571427), + }, # noqa: E501 + "results_explanation": " 14 trades. Avg profit -0.35%. Total profit -0.00248014 BTC ( -4.96Σ%). Avg duration 3402.9 min.", # noqa: E501 + "total_profit": -0.002480140000000001, + "current_epoch": 5, + "is_initial_point": True, + "is_random": False, + "is_best": True, + }, + { + "loss": 0.545315889154162, + "params_dict": { + "mfi-value": 22, + "fastd-value": 43, + "adx-value": 46, + "rsi-value": 20, + "mfi-enabled": False, + "fastd-enabled": False, + "adx-enabled": True, + "rsi-enabled": True, + "trigger": "bb_lower", + "sell-mfi-value": 87, + "sell-fastd-value": 65, + "sell-adx-value": 94, + "sell-rsi-value": 63, + "sell-mfi-enabled": False, + "sell-fastd-enabled": True, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-macd_cross_signal", + "roi_t1": 319, + "roi_t2": 556, + "roi_t3": 216, + "roi_p1": 0.06251955472249589, + "roi_p2": 0.11659519602202795, + "roi_p3": 0.0953744132197762, + "stoploss": -0.024551752215582423, + }, # noqa: E501 + "params_details": { + "buy": { + "mfi-value": 22, + "fastd-value": 43, + "adx-value": 46, + "rsi-value": 20, + "mfi-enabled": False, + "fastd-enabled": False, + "adx-enabled": True, + "rsi-enabled": True, + "trigger": "bb_lower", + }, + "sell": { + "sell-mfi-value": 87, + "sell-fastd-value": 65, + "sell-adx-value": 94, + "sell-rsi-value": 63, + "sell-mfi-enabled": False, + "sell-fastd-enabled": True, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-macd_cross_signal", + }, + "roi": { + 0: 0.2744891639643, + 216: 0.17911475074452382, + 772: 0.06251955472249589, + 1091: 0, + }, + "stoploss": {"stoploss": -0.024551752215582423}, + }, # noqa: E501 + "results_metrics": { + "total_trades": 39, + "trade_count_long": 39, + "trade_count_short": 0, + "wins": 20, + "draws": 0, + "losses": 19, + "profit_mean": -0.0021400679487179478, + "profit_median": -0.012222, + "profit_total": -0.0041773, + "profit_total_abs": -8.346264999999997, + "max_drawdown_account": 0.45, + "max_drawdown_abs": -4.955321, + "holding_avg": timedelta(minutes=636.9230769230769), + }, # noqa: E501 + "results_explanation": " 39 trades. Avg profit -0.21%. Total profit -0.00417730 BTC ( -8.35Σ%). Avg duration 636.9 min.", # noqa: E501 + "total_profit": -0.0041773, + "current_epoch": 6, + "is_initial_point": True, + "is_random": False, + "is_best": False, + }, + { + "loss": 4.713497421432944, + "params_dict": { + "mfi-value": 13, + "fastd-value": 41, + "adx-value": 21, + "rsi-value": 29, + "mfi-enabled": False, + "fastd-enabled": True, + "adx-enabled": False, + "rsi-enabled": False, + "trigger": "bb_lower", + "sell-mfi-value": 99, + "sell-fastd-value": 60, + "sell-adx-value": 81, + "sell-rsi-value": 69, + "sell-mfi-enabled": True, + "sell-fastd-enabled": True, + "sell-adx-enabled": True, + "sell-rsi-enabled": False, + "sell-trigger": "sell-macd_cross_signal", + "roi_t1": 771, + "roi_t2": 620, + "roi_t3": 145, + "roi_p1": 0.0586919200378493, + "roi_p2": 0.04984118697312542, + "roi_p3": 0.37521058680247044, + "stoploss": -0.14613268022709905, + }, # noqa: E501 + "params_details": { + "buy": { + "mfi-value": 13, + "fastd-value": 41, + "adx-value": 21, + "rsi-value": 29, + "mfi-enabled": False, + "fastd-enabled": True, + "adx-enabled": False, + "rsi-enabled": False, + "trigger": "bb_lower", + }, + "sell": { + "sell-mfi-value": 99, + "sell-fastd-value": 60, + "sell-adx-value": 81, + "sell-rsi-value": 69, + "sell-mfi-enabled": True, + "sell-fastd-enabled": True, + "sell-adx-enabled": True, + "sell-rsi-enabled": False, + "sell-trigger": "sell-macd_cross_signal", + }, + "roi": { + 0: 0.4837436938134452, + 145: 0.10853310701097472, + 765: 0.0586919200378493, + 1536: 0, + }, # noqa: E501 + "stoploss": {"stoploss": -0.14613268022709905}, + }, # noqa: E501 + "results_metrics": { + "total_trades": 318, + "trade_count_long": 318, + "trade_count_short": 0, + "wins": 100, + "draws": 0, + "losses": 218, + "profit_mean": -0.0039833954716981146, + "profit_median": -0.012222, + "profit_total": -0.06339929, + "profit_total_abs": -126.67197600000004, + "max_drawdown_account": 0.50, + "max_drawdown_abs": -200.955321, + "holding_avg": timedelta(minutes=3140.377358490566), + }, # noqa: E501 + "results_explanation": " 318 trades. Avg profit -0.40%. Total profit -0.06339929 BTC (-126.67Σ%). Avg duration 3140.4 min.", # noqa: E501 + "total_profit": -0.06339929, + "current_epoch": 7, + "is_initial_point": True, + "is_random": False, + "is_best": False, + }, + { + "loss": 20.0, # noqa: E501 + "params_dict": { + "mfi-value": 24, + "fastd-value": 43, + "adx-value": 33, + "rsi-value": 20, + "mfi-enabled": False, + "fastd-enabled": True, + "adx-enabled": True, + "rsi-enabled": True, + "trigger": "sar_reversal", + "sell-mfi-value": 89, + "sell-fastd-value": 74, + "sell-adx-value": 70, + "sell-rsi-value": 70, + "sell-mfi-enabled": False, + "sell-fastd-enabled": False, + "sell-adx-enabled": False, + "sell-rsi-enabled": True, + "sell-trigger": "sell-sar_reversal", + "roi_t1": 1149, + "roi_t2": 375, + "roi_t3": 289, + "roi_p1": 0.05571820757172588, + "roi_p2": 0.0606240398618907, + "roi_p3": 0.1729012220156157, + "stoploss": -0.1588514289110401, + }, # noqa: E501 + "params_details": { + "buy": { + "mfi-value": 24, + "fastd-value": 43, + "adx-value": 33, + "rsi-value": 20, + "mfi-enabled": False, + "fastd-enabled": True, + "adx-enabled": True, + "rsi-enabled": True, + "trigger": "sar_reversal", + }, + "sell": { + "sell-mfi-value": 89, + "sell-fastd-value": 74, + "sell-adx-value": 70, + "sell-rsi-value": 70, + "sell-mfi-enabled": False, + "sell-fastd-enabled": False, + "sell-adx-enabled": False, + "sell-rsi-enabled": True, + "sell-trigger": "sell-sar_reversal", + }, + "roi": { + 0: 0.2892434694492323, + 289: 0.11634224743361658, + 664: 0.05571820757172588, + 1813: 0, + }, + "stoploss": {"stoploss": -0.1588514289110401}, + }, # noqa: E501 + "results_metrics": { + "total_trades": 1, + "trade_count_long": 1, + "trade_count_short": 0, + "wins": 0, + "draws": 1, + "losses": 0, + "profit_mean": 0.0, + "profit_median": 0.0, + "profit_total": 0.0, + "profit_total_abs": 0.0, + "max_drawdown_account": 0.0, + "max_drawdown_abs": 0.52, + "holding_avg": timedelta(minutes=5340.0), + }, # noqa: E501 + "results_explanation": " 1 trades. Avg profit 0.00%. Total profit 0.00000000 BTC ( 0.00Σ%). Avg duration 5340.0 min.", # noqa: E501 + "total_profit": 0.0, + "current_epoch": 8, + "is_initial_point": True, + "is_random": False, + "is_best": False, + }, + { + "loss": 2.4731817780991223, + "params_dict": { + "mfi-value": 22, + "fastd-value": 20, + "adx-value": 29, + "rsi-value": 40, + "mfi-enabled": False, + "fastd-enabled": False, + "adx-enabled": False, + "rsi-enabled": False, + "trigger": "sar_reversal", + "sell-mfi-value": 97, + "sell-fastd-value": 65, + "sell-adx-value": 81, + "sell-rsi-value": 64, + "sell-mfi-enabled": True, + "sell-fastd-enabled": True, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-bb_upper", + "roi_t1": 1012, + "roi_t2": 584, + "roi_t3": 422, + "roi_p1": 0.036764323603472565, + "roi_p2": 0.10335480573205287, + "roi_p3": 0.10322347377503042, + "stoploss": -0.2780610808108503, + }, # noqa: E501 + "params_details": { + "buy": { + "mfi-value": 22, + "fastd-value": 20, + "adx-value": 29, + "rsi-value": 40, + "mfi-enabled": False, + "fastd-enabled": False, + "adx-enabled": False, + "rsi-enabled": False, + "trigger": "sar_reversal", + }, + "sell": { + "sell-mfi-value": 97, + "sell-fastd-value": 65, + "sell-adx-value": 81, + "sell-rsi-value": 64, + "sell-mfi-enabled": True, + "sell-fastd-enabled": True, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-bb_upper", + }, + "roi": { + 0: 0.2433426031105559, + 422: 0.14011912933552545, + 1006: 0.036764323603472565, + 2018: 0, + }, + "stoploss": {"stoploss": -0.2780610808108503}, + }, # noqa: E501 + "results_metrics": { + "total_trades": 229, + "trade_count_long": 229, + "trade_count_short": 0, + "wins": 150, + "draws": 0, + "losses": 79, + "profit_mean": -0.0038433433624454144, + "profit_median": -0.012222, + "profit_total": -0.044050070000000004, + "profit_total_abs": -88.01256299999999, + "max_drawdown_account": 0.41, + "max_drawdown_abs": -150.955321, + "holding_avg": timedelta(minutes=6505.676855895196), + }, # noqa: E501 + "results_explanation": " 229 trades. Avg profit -0.38%. Total profit -0.04405007 BTC ( -88.01Σ%). Avg duration 6505.7 min.", # noqa: E501 + "total_profit": -0.044050070000000004, # noqa: E501 + "current_epoch": 9, + "is_initial_point": True, + "is_random": False, + "is_best": False, + }, + { + "loss": -0.2604606005845212, # noqa: E501 + "params_dict": { + "mfi-value": 23, + "fastd-value": 24, + "adx-value": 22, + "rsi-value": 24, + "mfi-enabled": False, + "fastd-enabled": False, + "adx-enabled": False, + "rsi-enabled": True, + "trigger": "macd_cross_signal", + "sell-mfi-value": 97, + "sell-fastd-value": 70, + "sell-adx-value": 64, + "sell-rsi-value": 80, + "sell-mfi-enabled": False, + "sell-fastd-enabled": True, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-sar_reversal", + "roi_t1": 792, + "roi_t2": 464, + "roi_t3": 215, + "roi_p1": 0.04594053535385903, + "roi_p2": 0.09623192684243963, + "roi_p3": 0.04428219070850663, + "stoploss": -0.16992287161634415, + }, # noqa: E501 + "params_details": { + "buy": { + "mfi-value": 23, + "fastd-value": 24, + "adx-value": 22, + "rsi-value": 24, + "mfi-enabled": False, + "fastd-enabled": False, + "adx-enabled": False, + "rsi-enabled": True, + "trigger": "macd_cross_signal", + }, + "sell": { + "sell-mfi-value": 97, + "sell-fastd-value": 70, + "sell-adx-value": 64, + "sell-rsi-value": 80, + "sell-mfi-enabled": False, + "sell-fastd-enabled": True, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-sar_reversal", + }, + "roi": { + 0: 0.18645465290480528, + 215: 0.14217246219629864, + 679: 0.04594053535385903, + 1471: 0, + }, + "stoploss": {"stoploss": -0.16992287161634415}, + }, # noqa: E501 + "results_metrics": { + "total_trades": 4, + "trade_count_long": 4, + "trade_count_short": 0, + "wins": 0, + "draws": 0, + "losses": 4, + "profit_mean": 0.001080385, + "profit_median": -0.012222, + "profit_total": 0.00021629, + "profit_total_abs": 0.432154, + "max_drawdown_account": 0.13, + "max_drawdown_abs": -4.955321, + "holding_avg": timedelta(minutes=2850.0), + }, # noqa: E501 + "results_explanation": " 4 trades. Avg profit 0.11%. Total profit 0.00021629 BTC ( 0.43Σ%). Avg duration 2850.0 min.", # noqa: E501 + "total_profit": 0.00021629, + "current_epoch": 10, + "is_initial_point": True, + "is_random": False, + "is_best": True, + }, + { + "loss": 4.876465945994304, # noqa: E501 + "params_dict": { + "mfi-value": 20, + "fastd-value": 32, + "adx-value": 49, + "rsi-value": 23, + "mfi-enabled": True, + "fastd-enabled": True, + "adx-enabled": False, + "rsi-enabled": False, + "trigger": "bb_lower", + "sell-mfi-value": 75, + "sell-fastd-value": 56, + "sell-adx-value": 61, + "sell-rsi-value": 62, + "sell-mfi-enabled": False, + "sell-fastd-enabled": False, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-macd_cross_signal", + "roi_t1": 579, + "roi_t2": 614, + "roi_t3": 273, + "roi_p1": 0.05307643172744114, + "roi_p2": 0.1352282078262871, + "roi_p3": 0.1913307406325751, + "stoploss": -0.25728526022513887, + }, # noqa: E501 + "params_details": { + "buy": { + "mfi-value": 20, + "fastd-value": 32, + "adx-value": 49, + "rsi-value": 23, + "mfi-enabled": True, + "fastd-enabled": True, + "adx-enabled": False, + "rsi-enabled": False, + "trigger": "bb_lower", + }, + "sell": { + "sell-mfi-value": 75, + "sell-fastd-value": 56, + "sell-adx-value": 61, + "sell-rsi-value": 62, + "sell-mfi-enabled": False, + "sell-fastd-enabled": False, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-macd_cross_signal", + }, + "roi": { + 0: 0.3796353801863034, + 273: 0.18830463955372825, + 887: 0.05307643172744114, + 1466: 0, + }, + "stoploss": {"stoploss": -0.25728526022513887}, + }, # noqa: E501 + # New Hyperopt mode! + "results_metrics": { + "total_trades": 117, + "trade_count_long": 117, + "trade_count_short": 0, + "wins": 67, + "draws": 0, + "losses": 50, + "profit_mean": -0.012698609145299145, + "profit_median": -0.012222, + "profit_total": -0.07436117, + "profit_total_abs": -148.573727, + "max_drawdown_account": 0.52, + "max_drawdown_abs": -224.955321, + "holding_avg": timedelta(minutes=4282.5641025641025), + }, # noqa: E501 + "results_explanation": " 117 trades. Avg profit -1.27%. Total profit -0.07436117 BTC (-148.57Σ%). Avg duration 4282.6 min.", # noqa: E501 + "total_profit": -0.07436117, + "current_epoch": 11, + "is_initial_point": True, + "is_random": False, + "is_best": False, + }, + { + "loss": 100000, + "params_dict": { + "mfi-value": 10, + "fastd-value": 36, + "adx-value": 31, + "rsi-value": 22, + "mfi-enabled": True, + "fastd-enabled": True, + "adx-enabled": True, + "rsi-enabled": False, + "trigger": "sar_reversal", + "sell-mfi-value": 80, + "sell-fastd-value": 71, + "sell-adx-value": 60, + "sell-rsi-value": 85, + "sell-mfi-enabled": False, + "sell-fastd-enabled": False, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-bb_upper", + "roi_t1": 1156, + "roi_t2": 581, + "roi_t3": 408, + "roi_p1": 0.06860454019988212, + "roi_p2": 0.12473718444931989, + "roi_p3": 0.2896360635226823, + "stoploss": -0.30889015124682806, + }, # noqa: E501 + "params_details": { + "buy": { + "mfi-value": 10, + "fastd-value": 36, + "adx-value": 31, + "rsi-value": 22, + "mfi-enabled": True, + "fastd-enabled": True, + "adx-enabled": True, + "rsi-enabled": False, + "trigger": "sar_reversal", + }, + "sell": { + "sell-mfi-value": 80, + "sell-fastd-value": 71, + "sell-adx-value": 60, + "sell-rsi-value": 85, + "sell-mfi-enabled": False, + "sell-fastd-enabled": False, + "sell-adx-enabled": True, + "sell-rsi-enabled": True, + "sell-trigger": "sell-bb_upper", + }, + "roi": { + 0: 0.4829777881718843, + 408: 0.19334172464920202, + 989: 0.06860454019988212, + 2145: 0, + }, + "stoploss": {"stoploss": -0.30889015124682806}, + }, # noqa: E501 + "results_metrics": { + "total_trades": 0, + "trade_count_long": 0, + "trade_count_short": 0, + "wins": 0, + "draws": 0, + "losses": 0, + "profit_mean": None, + "profit_median": None, + "profit_total": 0, + "profit_total_abs": 0.0, + "max_drawdown_account": 0.0, + "max_drawdown_abs": 0.0, + "holding_avg": timedelta(), + }, # noqa: E501 + "results_explanation": " 0 trades. Avg profit nan%. Total profit 0.00000000 BTC ( 0.00Σ%). Avg duration nan min.", # noqa: E501 + "total_profit": 0, + "current_epoch": 12, + "is_initial_point": True, + "is_random": False, + "is_best": False, + }, + ] + + for res in hyperopt_res: + res["results_metrics"]["holding_avg_s"] = res["results_metrics"][ + "holding_avg" + ].total_seconds() + return hyperopt_res diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index d5dc8fc1e25..b9dee6d59d1 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -507,7 +507,9 @@ def test_calculate_max_drawdown2(): # sort by profit and reset index df = df.sort_values("profit").reset_index(drop=True) df1 = df.copy() - drawdown = calculate_max_drawdown(df, date_col="open_date", value_col="profit") + drawdown = calculate_max_drawdown( + df, date_col="open_date", starting_balance=0.2, value_col="profit" + ) # Ensure df has not been altered. assert df.equals(df1) @@ -518,6 +520,7 @@ def test_calculate_max_drawdown2(): # High value must be higher than low value assert drawdown.high_value > drawdown.low_value assert drawdown.drawdown_abs == 0.091755 + assert pytest.approx(drawdown.relative_account_drawdown) == 0.32129575 df = DataFrame(zip(values[:5], dates[:5]), columns=["profit", "open_date"]) with pytest.raises(ValueError, match="No losing trade, therefore no drawdown."): diff --git a/tests/data/test_download_data.py b/tests/data/test_download_data.py index cd7f4ab8f74..4922a213f51 100644 --- a/tests/data/test_download_data.py +++ b/tests/data/test_download_data.py @@ -69,13 +69,19 @@ def test_download_data_main_trades(mocker): assert dl_mock.call_args[1]["timerange"].starttype == "date" assert dl_mock.call_count == 1 - assert convert_mock.call_count == 1 + assert convert_mock.call_count == 0 + dl_mock.reset_mock() + config.update( { - "download_trades": True, - "trading_mode": "futures", + "convert_trades": True, } ) + download_data_main(config) + + assert dl_mock.call_args[1]["timerange"].starttype == "date" + assert dl_mock.call_count == 1 + assert convert_mock.call_count == 1 def test_download_data_main_data_invalid(mocker): diff --git a/tests/exchange_online/conftest.py b/tests/exchange_online/conftest.py index ad1bdb8702d..ee1e8a74108 100644 --- a/tests/exchange_online/conftest.py +++ b/tests/exchange_online/conftest.py @@ -200,6 +200,24 @@ "rebated_fee_currency": "USDT", }, ], + "sample_my_trades": [ + { + "id": "123412341234", + "create_time": "167997798", + "create_time_ms": "167997798825.566200", + "currency_pair": "ETH_USDT", + "side": "sell", + "role": "taker", + "amount": "0.0115", + "price": "1712.63", + "order_id": "1234123412", + "fee": "0.0", + "fee_currency": "USDT", + "point_fee": "0.03939049", + "gt_fee": "0.0", + "amend_text": "-", + } + ], }, "okx": { "pair": "BTC/USDT", diff --git a/tests/exchange_online/test_ccxt_compat.py b/tests/exchange_online/test_ccxt_compat.py index b764f8f756a..6eb9f002311 100644 --- a/tests/exchange_online/test_ccxt_compat.py +++ b/tests/exchange_online/test_ccxt_compat.py @@ -86,6 +86,33 @@ def test_ccxt_order_parse(self, exchange: EXCHANGE_FIXTURE_TYPE): else: pytest.skip(f"No sample order available for exchange {exchange_name}") + def test_ccxt_my_trades_parse(self, exchange: EXCHANGE_FIXTURE_TYPE): + exch, exchange_name = exchange + if trades := EXCHANGES[exchange_name].get("sample_my_trades"): + pair = "SOL/USDT" + for trade in trades: + market = exch._api.markets[pair] + po = exch._api.parse_trade(trade) + (trade, market) + assert isinstance(po["id"], str) + assert isinstance(po["side"], str) + assert isinstance(po["amount"], float) + assert isinstance(po["price"], float) + assert isinstance(po["datetime"], str) + assert isinstance(po["timestamp"], int) + + if fees := po.get("fees"): + assert isinstance(fees, list) + for fee in fees: + assert isinstance(fee, dict) + assert isinstance(fee["cost"], str) + # TODO: this should be a float! + # assert isinstance(fee["cost"], float) + assert isinstance(fee["currency"], str) + + else: + pytest.skip(f"No sample Trades available for exchange {exchange_name}") + def test_ccxt_fetch_tickers(self, exchange: EXCHANGE_FIXTURE_TYPE): exch, exchangename = exchange pair = EXCHANGES[exchangename]["pair"] diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 08f0408ed98..4d2f9ae36b1 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -47,7 +47,7 @@ def generate_result_metrics(): "profit_total_abs": 0.001, "profit_total": 0.01, "holding_avg": timedelta(minutes=20), - "max_drawdown": 0.001, + "max_drawdown_account": 0.001, "max_drawdown_abs": 0.001, "loss": 0.001, "is_initial_point": 0.001, diff --git a/tests/strategy/strats/hyperoptable_strategy.py b/tests/strategy/strats/hyperoptable_strategy.py index bc71ed3ae2f..3a2b210bee0 100644 --- a/tests/strategy/strats/hyperoptable_strategy.py +++ b/tests/strategy/strats/hyperoptable_strategy.py @@ -52,7 +52,7 @@ def protections(self): bot_loop_started = False bot_started = False - def bot_loop_start(self): + def bot_loop_start(self, **kwargs): self.bot_loop_started = True def bot_start(self, **kwargs) -> None: diff --git a/tests/strategy/strats/hyperoptable_strategy_v2.py b/tests/strategy/strats/hyperoptable_strategy_v2.py index 650c587f539..40e139e1fa0 100644 --- a/tests/strategy/strats/hyperoptable_strategy_v2.py +++ b/tests/strategy/strats/hyperoptable_strategy_v2.py @@ -48,7 +48,7 @@ def protections(self): bot_loop_started = False - def bot_loop_start(self): + def bot_loop_start(self, **kwargs): self.bot_loop_started = True def bot_start(self, **kwargs) -> None: