From 6f58e01f8ea96bfc95ddbd2d685c2126e95e4afb Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 22 Mar 2025 20:11:20 +0100 Subject: [PATCH 01/34] chore: drop support for macos x64 PyTorch --- docs/freqai-configuration.md | 2 ++ requirements-freqai-rl.txt | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/freqai-configuration.md b/docs/freqai-configuration.md index 7ae2535f6..5ab7b2602 100644 --- a/docs/freqai-configuration.md +++ b/docs/freqai-configuration.md @@ -258,6 +258,8 @@ freqtrade trade --config config_examples/config_freqai.example.json --strategy F We do provide an explicit docker-compose file for this in `docker/docker-compose-freqai.yml` - which can be used via `docker compose -f docker/docker-compose-freqai.yml run ...` - or can be copied to replace the original docker file. This docker-compose file also contains a (disabled) section to enable GPU resources within docker containers. This obviously assumes the system has GPU resources available. + PyTorch dropped support for macOS x64 (intel based Apple devices) in version 2.3. Subsequently, freqtrade also dropped support for PyTorch on this platform. + ### Structure #### Model diff --git a/requirements-freqai-rl.txt b/requirements-freqai-rl.txt index 413feec8f..b170da518 100644 --- a/requirements-freqai-rl.txt +++ b/requirements-freqai-rl.txt @@ -2,7 +2,6 @@ -r requirements-freqai.txt # Required for freqai-rl -torch==2.2.2; sys_platform == 'darwin' and platform_machine == 'x86_64' torch==2.6.0; sys_platform != 'darwin' or platform_machine != 'x86_64' gymnasium==0.29.1 # SB3 >=2.5.0 depends on torch 2.3.0 - which implies it dropped support x86 macos From 23b10161d519ec60114030ada279b20e8d29bf2a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Mar 2025 15:42:38 +0100 Subject: [PATCH 02/34] test: improve test resiliance --- tests/conftest.py | 1 + tests/optimize/test_optimize_reports.py | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index b7e766b3e..06dd23f79 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -652,6 +652,7 @@ def get_default_conf(testdatadir): "trading_mode": "spot", "margin_mode": "", "candle_type_def": CandleType.SPOT, + "original_config": {}, } return configuration diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index d0c970b33..c69761fe0 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -253,8 +253,9 @@ def test_store_backtest_results(testdatadir, mocker): dump_mock = mocker.patch("freqtrade.optimize.optimize_reports.bt_storage.file_dump_json") zip_mock = mocker.patch("freqtrade.optimize.optimize_reports.bt_storage.ZipFile") data = {"metadata": {}, "strategy": {}, "strategy_comparison": []} - - store_backtest_results({"exportfilename": testdatadir}, data, "2022_01_01_15_05_13") + store_backtest_results( + {"exportfilename": testdatadir, "original_config": {}}, data, "2022_01_01_15_05_13" + ) assert dump_mock.call_count == 2 assert zip_mock.call_count == 1 @@ -264,7 +265,9 @@ def test_store_backtest_results(testdatadir, mocker): dump_mock.reset_mock() zip_mock.reset_mock() filename = testdatadir / "testresult.json" - store_backtest_results({"exportfilename": filename}, data, "2022_01_01_15_05_13") + store_backtest_results( + {"exportfilename": filename, "original_config": {}}, data, "2022_01_01_15_05_13" + ) assert dump_mock.call_count == 2 assert zip_mock.call_count == 1 assert isinstance(dump_mock.call_args_list[0][0][0], Path) @@ -274,7 +277,11 @@ def test_store_backtest_results(testdatadir, mocker): def test_store_backtest_results_real(tmp_path): data = {"metadata": {}, "strategy": {}, "strategy_comparison": []} - store_backtest_results({"exportfilename": tmp_path}, data, "2022_01_01_15_05_13") + config = { + "exportfilename": tmp_path, + "original_config": {}, + } + store_backtest_results(config, data, "2022_01_01_15_05_13") zip_file = tmp_path / "backtest-result-2022_01_01_15_05_13.zip" assert zip_file.is_file() @@ -287,9 +294,7 @@ def test_store_backtest_results_real(tmp_path): fn = get_latest_backtest_filename(tmp_path) assert fn == "backtest-result-2022_01_01_15_05_13.zip" - store_backtest_results( - {"exportfilename": tmp_path}, data, "2024_01_01_15_05_25", market_change_data=pd.DataFrame() - ) + store_backtest_results(config, data, "2024_01_01_15_05_25", market_change_data=pd.DataFrame()) zip_file = tmp_path / "backtest-result-2024_01_01_15_05_25.zip" assert zip_file.is_file() assert (tmp_path / "backtest-result-2024_01_01_15_05_25.meta.json").is_file() @@ -313,6 +318,7 @@ def test_write_read_backtest_candles(tmp_path): "exportfilename": tmp_path, "export": "signals", "runmode": "backtest", + "original_config": {}, } # test directory exporting sample_date = "2022_01_01_15_05_13" From 9fa3a15e245a2214bd0a226495a8432ad3a5b882 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Mar 2025 15:44:55 +0100 Subject: [PATCH 03/34] feat: store (sanitized) configuration --- freqtrade/optimize/optimize_reports/bt_storage.py | 5 +++++ tests/optimize/test_optimize_reports.py | 2 ++ 2 files changed, 7 insertions(+) diff --git a/freqtrade/optimize/optimize_reports/bt_storage.py b/freqtrade/optimize/optimize_reports/bt_storage.py index d0c5d7fb7..00c8c1913 100644 --- a/freqtrade/optimize/optimize_reports/bt_storage.py +++ b/freqtrade/optimize/optimize_reports/bt_storage.py @@ -6,6 +6,7 @@ from zipfile import ZIP_DEFLATED, ZipFile from pandas import DataFrame +from freqtrade.configuration import sanitize_config from freqtrade.constants import LAST_BT_RESULT_FN from freqtrade.enums.runmode import RunMode from freqtrade.ft_types import BacktestResultType @@ -85,6 +86,10 @@ def store_backtest_results( dump_json_to_file(stats_buf, stats_copy) zipf.writestr(json_filename.name, stats_buf.getvalue()) + config_buf = StringIO() + dump_json_to_file(config_buf, sanitize_config(config["original_config"])) + zipf.writestr(f"{base_filename.stem}_config.json", config_buf.getvalue()) + # Add market change data if present if market_change_data is not None: market_change_name = f"{base_filename.stem}_market_change.feather" diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index c69761fe0..838dcb14f 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -303,6 +303,8 @@ def test_store_backtest_results_real(tmp_path): with ZipFile(zip_file, "r") as zipf: assert "backtest-result-2024_01_01_15_05_25.json" in zipf.namelist() assert "backtest-result-2024_01_01_15_05_25_market_change.feather" in zipf.namelist() + assert "backtest-result-2024_01_01_15_05_25_config.json" in zipf.namelist() + assert (tmp_path / LAST_BT_RESULT_FN).is_file() # Last file reference should be updated From 04a28b25508d76d71465b93d226dac88dcce9756 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Mar 2025 15:51:48 +0100 Subject: [PATCH 04/34] fix: backtestResulttype - simplify --- freqtrade/ft_types/backtest_result_type.py | 13 ++++++++----- .../optimize/optimize_reports/optimize_reports.py | 8 ++------ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/freqtrade/ft_types/backtest_result_type.py b/freqtrade/ft_types/backtest_result_type.py index 27cdb6126..4cd8f2a58 100644 --- a/freqtrade/ft_types/backtest_result_type.py +++ b/freqtrade/ft_types/backtest_result_type.py @@ -1,3 +1,4 @@ +from copy import deepcopy from typing import Any from typing_extensions import TypedDict @@ -15,11 +16,13 @@ class BacktestResultType(TypedDict): def get_BacktestResultType_default() -> BacktestResultType: - return { - "metadata": {}, - "strategy": {}, - "strategy_comparison": [], - } + return deepcopy( + { + "metadata": {}, + "strategy": {}, + "strategy_comparison": [], + } + ) class BacktestHistoryEntryType(BacktestMetadataType): diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index c0188673a..e5b526779 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -18,7 +18,7 @@ from freqtrade.data.metrics import ( calculate_sortino, calculate_sqn, ) -from freqtrade.ft_types import BacktestResultType +from freqtrade.ft_types import BacktestResultType, get_BacktestResultType_default from freqtrade.util import decimals_per_coin, fmt_coin, get_dry_run_wallet @@ -587,11 +587,7 @@ def generate_backtest_stats( :param max_date: Backtest end date :return: Dictionary containing results per strategy and a strategy summary. """ - result: BacktestResultType = { - "metadata": {}, - "strategy": {}, - "strategy_comparison": [], - } + result: BacktestResultType = get_BacktestResultType_default() market_change = calculate_market_change(btdata, "close") metadata = {} pairlist = list(btdata.keys()) From 85fc9364319b03d2fc75c714f3855349dc0e107d Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Mar 2025 17:22:50 +0100 Subject: [PATCH 05/34] feat: add Strategy and parameter file to backtest zip file --- freqtrade/optimize/backtesting.py | 1 + .../optimize/optimize_reports/bt_storage.py | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index d2efc78b5..9a5e58c92 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -1792,6 +1792,7 @@ class Backtesting: dt_appendix, market_change_data=combined_res, analysis_results=self.analysis_results, + strategy_files={s.get_strategy_name(): s.__file__ for s in self.strategylist}, ) # Results may be mixed up now. Sort them so they follow --strategy-list order. diff --git a/freqtrade/optimize/optimize_reports/bt_storage.py b/freqtrade/optimize/optimize_reports/bt_storage.py index 00c8c1913..202db7c21 100644 --- a/freqtrade/optimize/optimize_reports/bt_storage.py +++ b/freqtrade/optimize/optimize_reports/bt_storage.py @@ -53,6 +53,7 @@ def store_backtest_results( *, market_change_data: DataFrame | None = None, analysis_results: dict[str, dict[str, DataFrame]] | None = None, + strategy_files: dict[str, str] | None = None, ) -> Path: """ Stores backtest results and analysis data in a zip file, with metadata stored separately @@ -90,6 +91,25 @@ def store_backtest_results( dump_json_to_file(config_buf, sanitize_config(config["original_config"])) zipf.writestr(f"{base_filename.stem}_config.json", config_buf.getvalue()) + for strategy_name, strategy_file in (strategy_files or {}).items(): + # Store the strategy file and its parameters + strategy_buf = BytesIO() + strategy_path = Path(strategy_file) + with strategy_path.open("rb") as strategy_file_obj: + strategy_buf.write(strategy_file_obj.read()) + strategy_buf.seek(0) + zipf.writestr(f"{base_filename.stem}_{strategy_name}.py", strategy_buf.getvalue()) + strategy_params = strategy_path.with_suffix(".json") + if strategy_params.is_file(): + strategy_params_buf = BytesIO() + with strategy_params.open("rb") as strategy_params_obj: + strategy_params_buf.write(strategy_params_obj.read()) + strategy_params_buf.seek(0) + zipf.writestr( + f"{base_filename.stem}_{strategy_name}.json", + strategy_params_buf.getvalue(), + ) + # Add market change data if present if market_change_data is not None: market_change_name = f"{base_filename.stem}_market_change.feather" From 5b0b44069aad729bbb6f3f61d35032672cd6b779 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Mar 2025 17:23:05 +0100 Subject: [PATCH 06/34] test: Ensure strategy file is added to the test file. --- tests/optimize/test_optimize_reports.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 838dcb14f..3e00e4d85 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -294,7 +294,15 @@ def test_store_backtest_results_real(tmp_path): fn = get_latest_backtest_filename(tmp_path) assert fn == "backtest-result-2022_01_01_15_05_13.zip" - store_backtest_results(config, data, "2024_01_01_15_05_25", market_change_data=pd.DataFrame()) + strategy_test_dir = Path(__file__).parent.parent / "strategy" / "strats" + + store_backtest_results( + config, + data, + "2024_01_01_15_05_25", + market_change_data=pd.DataFrame(), + strategy_files={"DefStrat": str(strategy_test_dir / "strategy_test_v3.py")}, + ) zip_file = tmp_path / "backtest-result-2024_01_01_15_05_25.zip" assert zip_file.is_file() assert (tmp_path / "backtest-result-2024_01_01_15_05_25.meta.json").is_file() @@ -304,6 +312,14 @@ def test_store_backtest_results_real(tmp_path): assert "backtest-result-2024_01_01_15_05_25.json" in zipf.namelist() assert "backtest-result-2024_01_01_15_05_25_market_change.feather" in zipf.namelist() assert "backtest-result-2024_01_01_15_05_25_config.json" in zipf.namelist() + # strategy file is copied to the zip file + assert "backtest-result-2024_01_01_15_05_25_DefStrat.py" in zipf.namelist() + # compare the content of the strategy file + with zipf.open("backtest-result-2024_01_01_15_05_25_DefStrat.py") as strategy_file: + strategy_content = strategy_file.read() + with (strategy_test_dir / "strategy_test_v3.py").open("rb") as original_file: + original_content = original_file.read() + assert strategy_content == original_content assert (tmp_path / LAST_BT_RESULT_FN).is_file() From 7b44dd17aef21f2b9d7c55ebb6b945946389e76b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Mar 2025 17:24:00 +0100 Subject: [PATCH 07/34] feat: strategy-file saving for api backtest --- freqtrade/rpc/api_server/api_backtest.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/freqtrade/rpc/api_server/api_backtest.py b/freqtrade/rpc/api_server/api_backtest.py index 278922b7d..5d06e8a48 100644 --- a/freqtrade/rpc/api_server/api_backtest.py +++ b/freqtrade/rpc/api_server/api_backtest.py @@ -108,6 +108,9 @@ def __run_backtest_bg(btconfig: Config): ApiBG.bt["bt"].results, datetime.now().strftime("%Y-%m-%d_%H-%M-%S"), market_change_data=combined_res, + strategy_files={ + s.get_strategy_name(): s.__file__ for s in ApiBG.bt["bt"].strategylist + }, ) ApiBG.bt["bt"].results["metadata"][strategy_name]["filename"] = str(fn.stem) ApiBG.bt["bt"].results["metadata"][strategy_name]["strategy"] = strategy_name From 3ffc69ad024df680fb88d9e73817d02207c7d6ae Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Mar 2025 19:09:11 +0100 Subject: [PATCH 08/34] chore: fix typing errors --- freqtrade/ft_types/backtest_result_type.py | 17 ++++++++++------- freqtrade/strategy/interface.py | 1 + 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/freqtrade/ft_types/backtest_result_type.py b/freqtrade/ft_types/backtest_result_type.py index 4cd8f2a58..b8ddbb4b6 100644 --- a/freqtrade/ft_types/backtest_result_type.py +++ b/freqtrade/ft_types/backtest_result_type.py @@ -1,5 +1,5 @@ from copy import deepcopy -from typing import Any +from typing import Any, cast from typing_extensions import TypedDict @@ -16,12 +16,15 @@ class BacktestResultType(TypedDict): def get_BacktestResultType_default() -> BacktestResultType: - return deepcopy( - { - "metadata": {}, - "strategy": {}, - "strategy_comparison": [], - } + return cast( + BacktestResultType, + deepcopy( + { + "metadata": {}, + "strategy": {}, + "strategy_comparison": [], + } + ), ) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 98e02cdd6..5cd873f23 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -132,6 +132,7 @@ class IStrategy(ABC, HyperStrategyMixin): stake_currency: str # container variable for strategy source code __source__: str = "" + __file__: str = "" # Definition of plot_config. See plotting documentation for more details. plot_config: dict = {} From 286371c1e482fa85eb61dc09c9ec769c67db0de6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Mar 2025 19:35:02 +0100 Subject: [PATCH 09/34] docs: add documentation for output zip file format --- docs/backtesting.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/backtesting.md b/docs/backtesting.md index 981f889a2..4d91b3ca6 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -435,6 +435,20 @@ To save time, by default backtest will reuse a cached result from within the las To further analyze your backtest results, freqtrade will export the trades to file by default. You can then load the trades to perform further analysis as shown in the [data analysis](strategy_analysis_example.md#load-backtest-results-to-pandas-dataframe) backtesting section. +### Backtest output file + +The output file freqtrade produces is a zip file containing the following files: + +- The backtest report in json format +- the market change data in feather format +- a copy of the strategy file +- a copy of the strategy parameters (if a parameter file was used) +- a sanitized copy of the config file + +This will ensure results are reproducible - under the assumption that the same data is available. + +Only the strategy file and the config file are included in the zip file, eventual dependencies are not included. + ## Assumptions made by backtesting Since backtesting lacks some detailed information about what happens within a candle, it needs to take a few assumptions: From 1fdce89806b6f638cf88146fb4bf8ca0851df7ce Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 24 Mar 2025 06:41:58 +0100 Subject: [PATCH 10/34] chore: Implement safeguard against non-existing strategy files --- freqtrade/optimize/optimize_reports/bt_storage.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/freqtrade/optimize/optimize_reports/bt_storage.py b/freqtrade/optimize/optimize_reports/bt_storage.py index 202db7c21..1e6a67e81 100644 --- a/freqtrade/optimize/optimize_reports/bt_storage.py +++ b/freqtrade/optimize/optimize_reports/bt_storage.py @@ -95,6 +95,9 @@ def store_backtest_results( # Store the strategy file and its parameters strategy_buf = BytesIO() strategy_path = Path(strategy_file) + if not strategy_path.is_file(): + logger.warning(f"Strategy file '{strategy_path}' does not exist. Skipping.") + continue with strategy_path.open("rb") as strategy_file_obj: strategy_buf.write(strategy_file_obj.read()) strategy_buf.seek(0) From 799ce4e1f2ec3096744b6925bbbe2dd04e0d0ee1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 24 Mar 2025 07:10:43 +0100 Subject: [PATCH 11/34] test: Enhance test to also cover params file saving --- tests/optimize/test_optimize_reports.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 3e00e4d85..9fb5ccae9 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -1,5 +1,6 @@ import json import re +import shutil from datetime import timedelta from pathlib import Path from shutil import copyfile @@ -41,7 +42,7 @@ from freqtrade.optimize.optimize_reports.optimize_reports import ( from freqtrade.resolvers.strategy_resolver import StrategyResolver from freqtrade.util import dt_ts from freqtrade.util.datetime_helpers import dt_from_ts, dt_utc -from tests.conftest import CURRENT_TEST_STRATEGY +from tests.conftest import CURRENT_TEST_STRATEGY, log_has_re from tests.data.test_history import _clean_test_file @@ -275,13 +276,16 @@ def test_store_backtest_results(testdatadir, mocker): assert str(dump_mock.call_args_list[0][0][0]).startswith(str(testdatadir / "testresult")) -def test_store_backtest_results_real(tmp_path): +def test_store_backtest_results_real(tmp_path, caplog): data = {"metadata": {}, "strategy": {}, "strategy_comparison": []} config = { "exportfilename": tmp_path, "original_config": {}, } - store_backtest_results(config, data, "2022_01_01_15_05_13") + store_backtest_results( + config, data, "2022_01_01_15_05_13", strategy_files={"DefStrat": "NoFile"} + ) + assert log_has_re(r"Strategy file .* does not exist\. Skipping\.", caplog) zip_file = tmp_path / "backtest-result-2022_01_01_15_05_13.zip" assert zip_file.is_file() @@ -296,12 +300,17 @@ def test_store_backtest_results_real(tmp_path): strategy_test_dir = Path(__file__).parent.parent / "strategy" / "strats" + shutil.copy(strategy_test_dir / "strategy_test_v3.py", tmp_path) + params_file = tmp_path / "strategy_test_v3.json" + with params_file.open("w") as f: + f.write("""{"strategy_name": "TurtleStrategyX5","params":{}}""") + store_backtest_results( config, data, "2024_01_01_15_05_25", market_change_data=pd.DataFrame(), - strategy_files={"DefStrat": str(strategy_test_dir / "strategy_test_v3.py")}, + strategy_files={"DefStrat": str(tmp_path / "strategy_test_v3.py")}, ) zip_file = tmp_path / "backtest-result-2024_01_01_15_05_25.zip" assert zip_file.is_file() @@ -320,6 +329,12 @@ def test_store_backtest_results_real(tmp_path): with (strategy_test_dir / "strategy_test_v3.py").open("rb") as original_file: original_content = original_file.read() assert strategy_content == original_content + assert "backtest-result-2024_01_01_15_05_25_DefStrat.py" in zipf.namelist() + with zipf.open("backtest-result-2024_01_01_15_05_25_DefStrat.json") as pf: + params_content = pf.read() + with params_file.open("rb") as original_file: + original_content = original_file.read() + assert params_content == original_content assert (tmp_path / LAST_BT_RESULT_FN).is_file() From f242110957f1fbf67c28020edacdae827ab29bf9 Mon Sep 17 00:00:00 2001 From: Freqtrade Bot <154552126+freqtrade-bot@users.noreply.github.com> Date: Thu, 27 Mar 2025 03:13:26 +0000 Subject: [PATCH 12/34] chore: update pre-commit hooks --- .../exchange/binance_leverage_tiers.json | 1499 ++++++++++++++++- 1 file changed, 1449 insertions(+), 50 deletions(-) diff --git a/freqtrade/exchange/binance_leverage_tiers.json b/freqtrade/exchange/binance_leverage_tiers.json index f71f2a002..4eb970b2c 100644 --- a/freqtrade/exchange/binance_leverage_tiers.json +++ b/freqtrade/exchange/binance_leverage_tiers.json @@ -8279,10 +8279,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "50", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.015", @@ -8296,10 +8296,10 @@ "minNotional": 5000.0, "maxNotional": 20000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "2", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "20000", "notionalFloor": "5000", "maintMarginRatio": "0.02", @@ -8313,10 +8313,10 @@ "minNotional": 20000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "3", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "30000", "notionalFloor": "20000", "maintMarginRatio": "0.025", @@ -8330,10 +8330,10 @@ "minNotional": 30000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "4", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "300000", "notionalFloor": "30000", "maintMarginRatio": "0.05", @@ -10133,6 +10133,127 @@ } } ], + "BANANAS31/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "BANANAS31/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.02", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "BANANAS31/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "2", + "initialLeverage": "20", + "notionalCap": "25000", + "notionalFloor": "5000", + "maintMarginRatio": "0.025", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "BANANAS31/USDT:USDT", + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "650.0" + } + }, + { + "tier": 4.0, + "symbol": "BANANAS31/USDT:USDT", + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "500000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "10650.0" + } + }, + { + "tier": 5.0, + "symbol": "BANANAS31/USDT:USDT", + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "5", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "500000", + "maintMarginRatio": "0.125", + "cum": "23150.0" + } + }, + { + "tier": 6.0, + "symbol": "BANANAS31/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "6", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "116900.0" + } + }, + { + "tier": 7.0, + "symbol": "BANANAS31/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "491900.0" + } + } + ], "BAND/USDT:USDT": [ { "tier": 1.0, @@ -11477,6 +11598,127 @@ } } ], + "BID/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "BID/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.02", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "BID/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "2", + "initialLeverage": "20", + "notionalCap": "25000", + "notionalFloor": "5000", + "maintMarginRatio": "0.025", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "BID/USDT:USDT", + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "650.0" + } + }, + { + "tier": 4.0, + "symbol": "BID/USDT:USDT", + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "500000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "10650.0" + } + }, + { + "tier": 5.0, + "symbol": "BID/USDT:USDT", + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "5", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "500000", + "maintMarginRatio": "0.125", + "cum": "23150.0" + } + }, + { + "tier": 6.0, + "symbol": "BID/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "6", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "116900.0" + } + }, + { + "tier": 7.0, + "symbol": "BID/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "491900.0" + } + } + ], "BIGTIME/USDT:USDT": [ { "tier": 1.0, @@ -13116,6 +13358,127 @@ } } ], + "BR/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "BR/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.02", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "BR/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "2", + "initialLeverage": "20", + "notionalCap": "25000", + "notionalFloor": "5000", + "maintMarginRatio": "0.025", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "BR/USDT:USDT", + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "650.0" + } + }, + { + "tier": 4.0, + "symbol": "BR/USDT:USDT", + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "500000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "10650.0" + } + }, + { + "tier": 5.0, + "symbol": "BR/USDT:USDT", + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "5", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "500000", + "maintMarginRatio": "0.125", + "cum": "23150.0" + } + }, + { + "tier": 6.0, + "symbol": "BR/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "6", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "116900.0" + } + }, + { + "tier": 7.0, + "symbol": "BR/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "491900.0" + } + } + ], "BRETT/USDT:USDT": [ { "tier": 1.0, @@ -13271,6 +13634,248 @@ } } ], + "BROCCOLI714/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "BROCCOLI714/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.02", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "BROCCOLI714/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "2", + "initialLeverage": "20", + "notionalCap": "25000", + "notionalFloor": "5000", + "maintMarginRatio": "0.025", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "BROCCOLI714/USDT:USDT", + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "650.0" + } + }, + { + "tier": 4.0, + "symbol": "BROCCOLI714/USDT:USDT", + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "500000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "10650.0" + } + }, + { + "tier": 5.0, + "symbol": "BROCCOLI714/USDT:USDT", + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "5", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "500000", + "maintMarginRatio": "0.125", + "cum": "23150.0" + } + }, + { + "tier": 6.0, + "symbol": "BROCCOLI714/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "6", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "116900.0" + } + }, + { + "tier": 7.0, + "symbol": "BROCCOLI714/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "491900.0" + } + } + ], + "BROCCOLIF3B/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "BROCCOLIF3B/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.02", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "BROCCOLIF3B/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "2", + "initialLeverage": "20", + "notionalCap": "25000", + "notionalFloor": "5000", + "maintMarginRatio": "0.025", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "BROCCOLIF3B/USDT:USDT", + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "650.0" + } + }, + { + "tier": 4.0, + "symbol": "BROCCOLIF3B/USDT:USDT", + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "500000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "10650.0" + } + }, + { + "tier": 5.0, + "symbol": "BROCCOLIF3B/USDT:USDT", + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "5", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "500000", + "maintMarginRatio": "0.125", + "cum": "23150.0" + } + }, + { + "tier": 6.0, + "symbol": "BROCCOLIF3B/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "6", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "116900.0" + } + }, + { + "tier": 7.0, + "symbol": "BROCCOLIF3B/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "491900.0" + } + } + ], "BSV/USDT:USDT": [ { "tier": 1.0, @@ -31199,6 +31804,127 @@ } } ], + "JELLYJELLY/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "JELLYJELLY/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.02", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "JELLYJELLY/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "2", + "initialLeverage": "20", + "notionalCap": "25000", + "notionalFloor": "5000", + "maintMarginRatio": "0.025", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "JELLYJELLY/USDT:USDT", + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "650.0" + } + }, + { + "tier": 4.0, + "symbol": "JELLYJELLY/USDT:USDT", + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "300000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "10650.0" + } + }, + { + "tier": 5.0, + "symbol": "JELLYJELLY/USDT:USDT", + "currency": "USDT", + "minNotional": 300000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "5", + "initialLeverage": "4", + "notionalCap": "400000", + "notionalFloor": "300000", + "maintMarginRatio": "0.125", + "cum": "18150.0" + } + }, + { + "tier": 6.0, + "symbol": "JELLYJELLY/USDT:USDT", + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "6", + "initialLeverage": "2", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.25", + "cum": "68150.0" + } + }, + { + "tier": 7.0, + "symbol": "JELLYJELLY/USDT:USDT", + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", + "initialLeverage": "1", + "notionalCap": "600000", + "notionalFloor": "500000", + "maintMarginRatio": "0.5", + "cum": "193150.0" + } + } + ], "JOE/USDT:USDT": [ { "tier": 1.0, @@ -36739,14 +37465,14 @@ "currency": "USDT", "minNotional": 0.0, "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 10.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "10", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.02", "cum": "0.0" } }, @@ -36757,14 +37483,14 @@ "minNotional": 5000.0, "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 8.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "8", + "initialLeverage": "20", "notionalCap": "25000", "notionalFloor": "5000", "maintMarginRatio": "0.025", - "cum": "50.0" + "cum": "25.0" } }, { @@ -36772,84 +37498,84 @@ "symbol": "MAVIA/USDT:USDT", "currency": "USDT", "minNotional": 25000.0, - "maxNotional": 100000.0, + "maxNotional": 200000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 6.0, + "maxLeverage": 10.0, "info": { "bracket": "3", - "initialLeverage": "6", - "notionalCap": "100000", + "initialLeverage": "10", + "notionalCap": "200000", "notionalFloor": "25000", "maintMarginRatio": "0.05", - "cum": "675.0" + "cum": "650.0" } }, { "tier": 4.0, "symbol": "MAVIA/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 200000.0, + "minNotional": 200000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "notionalCap": "200000", - "notionalFloor": "100000", + "notionalCap": "500000", + "notionalFloor": "200000", "maintMarginRatio": "0.1", - "cum": "5675.0" + "cum": "10650.0" } }, { "tier": 5.0, "symbol": "MAVIA/USDT:USDT", "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 500000.0, + "minNotional": 500000.0, + "maxNotional": 750000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "notionalCap": "500000", - "notionalFloor": "200000", + "notionalCap": "750000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", - "cum": "10675.0" + "cum": "23150.0" } }, { "tier": 6.0, "symbol": "MAVIA/USDT:USDT", "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 1000000.0, + "minNotional": 750000.0, + "maxNotional": 1500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "notionalCap": "1000000", - "notionalFloor": "500000", + "notionalCap": "1500000", + "notionalFloor": "750000", "maintMarginRatio": "0.25", - "cum": "73175.0" + "cum": "116900.0" } }, { "tier": 7.0, "symbol": "MAVIA/USDT:USDT", "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "minNotional": 1500000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "notionalCap": "2000000", - "notionalFloor": "1000000", + "notionalCap": "3000000", + "notionalFloor": "1500000", "maintMarginRatio": "0.5", - "cum": "323175.0" + "cum": "491900.0" } } ], @@ -40284,6 +41010,161 @@ } } ], + "NIL/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "NIL/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "NIL/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, + "info": { + "bracket": "2", + "initialLeverage": "50", + "notionalCap": "10000", + "notionalFloor": "5000", + "maintMarginRatio": "0.015", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "NIL/USDT:USDT", + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "symbol": "NIL/USDT:USDT", + "currency": "USDT", + "minNotional": 30000.0, + "maxNotional": 60000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "60000", + "notionalFloor": "30000", + "maintMarginRatio": "0.025", + "cum": "225.0" + } + }, + { + "tier": 5.0, + "symbol": "NIL/USDT:USDT", + "currency": "USDT", + "minNotional": 60000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "300000", + "notionalFloor": "60000", + "maintMarginRatio": "0.05", + "cum": "1725.0" + } + }, + { + "tier": 6.0, + "symbol": "NIL/USDT:USDT", + "currency": "USDT", + "minNotional": 300000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "600000", + "notionalFloor": "300000", + "maintMarginRatio": "0.1", + "cum": "16725.0" + } + }, + { + "tier": 7.0, + "symbol": "NIL/USDT:USDT", + "currency": "USDT", + "minNotional": 600000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "600000", + "maintMarginRatio": "0.125", + "cum": "31725.0" + } + }, + { + "tier": 8.0, + "symbol": "NIL/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "125475.0" + } + }, + { + "tier": 9.0, + "symbol": "NIL/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "500475.0" + } + } + ], "NKN/USDT:USDT": [ { "tier": 1.0, @@ -42415,10 +43296,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -42432,10 +43313,10 @@ "minNotional": 5000.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "10000", "notionalFloor": "5000", "maintMarginRatio": "0.015", @@ -42449,10 +43330,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 18.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "18", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.02", @@ -42466,10 +43347,10 @@ "minNotional": 30000.0, "maxNotional": 60000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 15.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "15", "notionalCap": "60000", "notionalFloor": "30000", "maintMarginRatio": "0.025", @@ -42549,13 +43430,13 @@ "symbol": "ORCA/USDT:USDT", "currency": "USDT", "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "3000000", + "notionalCap": "2000000", "notionalFloor": "1500000", "maintMarginRatio": "0.5", "cum": "500475.0" @@ -43027,6 +43908,161 @@ } } ], + "PARTI/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "PARTI/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "PARTI/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, + "info": { + "bracket": "2", + "initialLeverage": "50", + "notionalCap": "10000", + "notionalFloor": "5000", + "maintMarginRatio": "0.015", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "PARTI/USDT:USDT", + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "symbol": "PARTI/USDT:USDT", + "currency": "USDT", + "minNotional": 30000.0, + "maxNotional": 60000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "60000", + "notionalFloor": "30000", + "maintMarginRatio": "0.025", + "cum": "225.0" + } + }, + { + "tier": 5.0, + "symbol": "PARTI/USDT:USDT", + "currency": "USDT", + "minNotional": 60000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "300000", + "notionalFloor": "60000", + "maintMarginRatio": "0.05", + "cum": "1725.0" + } + }, + { + "tier": 6.0, + "symbol": "PARTI/USDT:USDT", + "currency": "USDT", + "minNotional": 300000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "600000", + "notionalFloor": "300000", + "maintMarginRatio": "0.1", + "cum": "16725.0" + } + }, + { + "tier": 7.0, + "symbol": "PARTI/USDT:USDT", + "currency": "USDT", + "minNotional": 600000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "600000", + "maintMarginRatio": "0.125", + "cum": "31725.0" + } + }, + { + "tier": 8.0, + "symbol": "PARTI/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "125475.0" + } + }, + { + "tier": 9.0, + "symbol": "PARTI/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "500475.0" + } + } + ], "PENDLE/USDT:USDT": [ { "tier": 1.0, @@ -44148,6 +45184,127 @@ } } ], + "PLUME/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "PLUME/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.02", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "PLUME/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "2", + "initialLeverage": "20", + "notionalCap": "25000", + "notionalFloor": "5000", + "maintMarginRatio": "0.025", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "PLUME/USDT:USDT", + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "650.0" + } + }, + { + "tier": 4.0, + "symbol": "PLUME/USDT:USDT", + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "500000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "10650.0" + } + }, + { + "tier": 5.0, + "symbol": "PLUME/USDT:USDT", + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "5", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "500000", + "maintMarginRatio": "0.125", + "cum": "23150.0" + } + }, + { + "tier": 6.0, + "symbol": "PLUME/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "6", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "116900.0" + } + }, + { + "tier": 7.0, + "symbol": "PLUME/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "491900.0" + } + } + ], "PNUT/USDC:USDC": [ { "tier": 1.0, @@ -50286,6 +51443,127 @@ } } ], + "SIREN/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "SIREN/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.02", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "SIREN/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "2", + "initialLeverage": "20", + "notionalCap": "25000", + "notionalFloor": "5000", + "maintMarginRatio": "0.025", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "SIREN/USDT:USDT", + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "650.0" + } + }, + { + "tier": 4.0, + "symbol": "SIREN/USDT:USDT", + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "500000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "10650.0" + } + }, + { + "tier": 5.0, + "symbol": "SIREN/USDT:USDT", + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "5", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "500000", + "maintMarginRatio": "0.125", + "cum": "23150.0" + } + }, + { + "tier": 6.0, + "symbol": "SIREN/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "6", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "116900.0" + } + }, + { + "tier": 7.0, + "symbol": "SIREN/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "491900.0" + } + } + ], "SKL/USDT:USDT": [ { "tier": 1.0, @@ -57199,6 +58477,127 @@ } } ], + "TUT/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "TUT/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.02", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "TUT/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "2", + "initialLeverage": "20", + "notionalCap": "25000", + "notionalFloor": "5000", + "maintMarginRatio": "0.025", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "TUT/USDT:USDT", + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "650.0" + } + }, + { + "tier": 4.0, + "symbol": "TUT/USDT:USDT", + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "500000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "10650.0" + } + }, + { + "tier": 5.0, + "symbol": "TUT/USDT:USDT", + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "5", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "500000", + "maintMarginRatio": "0.125", + "cum": "23150.0" + } + }, + { + "tier": 6.0, + "symbol": "TUT/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "6", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "116900.0" + } + }, + { + "tier": 7.0, + "symbol": "TUT/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "491900.0" + } + } + ], "TWT/USDT:USDT": [ { "tier": 1.0, From 583e20dc9db92c1449d8f03c6e62bd13fe8d7178 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 27 Mar 2025 07:10:46 +0100 Subject: [PATCH 13/34] chore: bump dev version to 2025.4-dev --- freqtrade/__init__.py | 2 +- ft_client/freqtrade_client/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/__init__.py b/freqtrade/__init__.py index 8ca2a3e67..8644f9eab 100644 --- a/freqtrade/__init__.py +++ b/freqtrade/__init__.py @@ -1,6 +1,6 @@ """Freqtrade bot""" -__version__ = "2025.3-dev" +__version__ = "2025.4-dev" if "dev" in __version__: from pathlib import Path diff --git a/ft_client/freqtrade_client/__init__.py b/ft_client/freqtrade_client/__init__.py index f9a9baf16..32e91f3a1 100644 --- a/ft_client/freqtrade_client/__init__.py +++ b/ft_client/freqtrade_client/__init__.py @@ -1,7 +1,7 @@ from freqtrade_client.ft_rest_client import FtRestClient -__version__ = "2025.3-dev" +__version__ = "2025.4-dev" if "dev" in __version__: from pathlib import Path From 3637d7a54c3d86b33e31f4466784467de8a7ccc0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 27 Mar 2025 18:14:36 +0100 Subject: [PATCH 14/34] chore(ci): run mypy only on the latest OS each --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cc0c8a5d7..0fdd76a79 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -139,6 +139,7 @@ jobs: ruff format --check - name: Mypy + if: ${{ matrix.os }} == 'ubuntu-24.04' run: | mypy freqtrade scripts tests @@ -264,6 +265,7 @@ jobs: ruff format --check - name: Mypy + if: ${{ matrix.os }} == 'macos-15' run: | mypy freqtrade scripts From 26ea4fdcc94a76e0a6b33a9154f6de0c8bf95800 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 27 Mar 2025 19:22:35 +0100 Subject: [PATCH 15/34] chore(ci): simplified syntax --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0fdd76a79..e90218b2c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -139,7 +139,7 @@ jobs: ruff format --check - name: Mypy - if: ${{ matrix.os }} == 'ubuntu-24.04' + if: matrix.os == 'ubuntu-24.04' run: | mypy freqtrade scripts tests @@ -265,7 +265,7 @@ jobs: ruff format --check - name: Mypy - if: ${{ matrix.os }} == 'macos-15' + if: matrix.os == 'macos-15' run: | mypy freqtrade scripts From 4632839fc525812ebe9a72420b6f3ae79be9ad29 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 27 Mar 2025 20:05:27 +0100 Subject: [PATCH 16/34] chore(ci): run coveralls on ubuntu 24.04 runner --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e90218b2c..e45f85481 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,17 +73,17 @@ jobs: python build_helpers/freqtrade_client_version_align.py - name: Tests - if: (!(runner.os == 'Linux' && matrix.python-version == '3.12' && matrix.os == 'ubuntu-22.04')) + if: (!(runner.os == 'Linux' && matrix.python-version == '3.12' && matrix.os == 'ubuntu-24.04')) run: | pytest --random-order - name: Tests with Coveralls - if: (runner.os == 'Linux' && matrix.python-version == '3.12' && matrix.os == 'ubuntu-22.04') + if: (runner.os == 'Linux' && matrix.python-version == '3.12' && matrix.os == 'ubuntu-24.04') run: | pytest --random-order --cov=freqtrade --cov=freqtrade_client --cov-config=.coveragerc - name: Coveralls - if: (runner.os == 'Linux' && matrix.python-version == '3.12' && matrix.os == 'ubuntu-22.04') + if: (runner.os == 'Linux' && matrix.python-version == '3.12' && matrix.os == 'ubuntu-24.04') env: # Coveralls token. Not used as secret due to github not providing secrets to forked repositories COVERALLS_REPO_TOKEN: 6D1m0xupS3FgutfuGao8keFf9Hc0FpIXu From b77739b5ca4d0d629232623b1b1225b0455a95ad Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 30 Mar 2025 15:22:11 +0200 Subject: [PATCH 17/34] docs: add exchange docs about hyperliquid historic data --- docs/exchanges.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/exchanges.md b/docs/exchanges.md index 953fb5f8c..f058ed86e 100644 --- a/docs/exchanges.md +++ b/docs/exchanges.md @@ -363,6 +363,10 @@ Hyperliquid handles deposits and withdrawals on the Arbitrum One chain, a Layer * Create a different software wallet, only transfer the funds you want to trade with to that wallet, and use that wallet to trade on Hyperliquid. * If you have funds you don't want to use for trading (after making a profit for example), transfer them back to your hardware wallet. +### Historic Hyperliquid data + +The Hyperliquid API does not provide historic data beyond the single call to fetch current data, so downloading data is not possible, as the downloaded data would not constitute proper historic data. + ## All exchanges Should you experience constant errors with Nonce (like `InvalidNonce`), it is best to regenerate the API keys. Resetting Nonce is difficult and it's usually easier to regenerate the API keys. From ac9b26cc57b19c7d4a7f9b6133f85ff57d7aa417 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 30 Mar 2025 19:33:53 +0200 Subject: [PATCH 18/34] fix: allow backtesting for specific exchanges --- freqtrade/exchange/exchange_types.py | 1 + freqtrade/exchange/hyperliquid.py | 1 + freqtrade/optimize/backtesting.py | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/freqtrade/exchange/exchange_types.py b/freqtrade/exchange/exchange_types.py index 9687057bd..ae84bb502 100644 --- a/freqtrade/exchange/exchange_types.py +++ b/freqtrade/exchange/exchange_types.py @@ -44,6 +44,7 @@ class FtHas(TypedDict, total=False): funding_fee_timeframe: str funding_fee_candle_limit: int floor_leverage: bool + uses_leverage_tiers: bool needs_trading_fees: bool order_props_in_contracts: list[Literal["amount", "cost", "filled", "remaining"]] diff --git a/freqtrade/exchange/hyperliquid.py b/freqtrade/exchange/hyperliquid.py index a75a77892..b6ec23942 100644 --- a/freqtrade/exchange/hyperliquid.py +++ b/freqtrade/exchange/hyperliquid.py @@ -35,6 +35,7 @@ class Hyperliquid(Exchange): "stop_price_prop": "stopPrice", "funding_fee_timeframe": "1h", "funding_fee_candle_limit": 500, + "uses_leverage_tiers": False, } _supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [ diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 9a5e58c92..5d83d4981 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -360,8 +360,9 @@ class Backtesting: ) # Combine data to avoid combining the data per trade. unavailable_pairs = [] + uses_leverage_tiers = self.exchange.get_option("uses_leverage_tiers", True) for pair in self.pairlists.whitelist: - if pair not in self.exchange._leverage_tiers: + if uses_leverage_tiers and pair not in self.exchange._leverage_tiers: unavailable_pairs.append(pair) continue From 6fca35adaeb95318f5201d9e0d9e63b6b40761e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 03:04:57 +0000 Subject: [PATCH 19/34] chore(deps-dev): bump pytest-asyncio in the pytest group Bumps the pytest group with 1 update: [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio). Updates `pytest-asyncio` from 0.25.3 to 0.26.0 - [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases) - [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.25.3...v0.26.0) --- updated-dependencies: - dependency-name: pytest-asyncio dependency-type: direct:development update-type: version-update:semver-minor dependency-group: pytest ... Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index aaa58632f..29fc2bee1 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -11,7 +11,7 @@ ruff==0.11.2 mypy==1.15.0 pre-commit==4.2.0 pytest==8.3.5 -pytest-asyncio==0.25.3 +pytest-asyncio==0.26.0 pytest-cov==6.0.0 pytest-mock==3.14.0 pytest-random-order==1.1.1 From 07fb94175804d655f983d8d88e5555320a0e7929 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 03:05:07 +0000 Subject: [PATCH 20/34] chore(deps): bump mkdocs-material in the mkdocs group Bumps the mkdocs group with 1 update: [mkdocs-material](https://github.com/squidfunk/mkdocs-material). Updates `mkdocs-material` from 9.6.9 to 9.6.10 - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.6.9...9.6.10) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:production update-type: version-update:semver-patch dependency-group: mkdocs ... Signed-off-by: dependabot[bot] --- docs/requirements-docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index c1c90d274..fb5578d26 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,6 +1,6 @@ markdown==3.7 mkdocs==1.6.1 -mkdocs-material==9.6.9 +mkdocs-material==9.6.10 mdx_truly_sane_lists==1.3 pymdown-extensions==10.14.3 jinja2==3.1.6 From 67e2d9c730ba6c2b1009c7bd1c3fdced9df48cd0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 03:05:12 +0000 Subject: [PATCH 21/34] chore(deps): bump pydantic from 2.10.6 to 2.11.1 Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.10.6 to 2.11.1. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v2.10.6...v2.11.1) --- updated-dependencies: - dependency-name: pydantic dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 928954c21..a66a3629d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -38,7 +38,7 @@ sdnotify==0.3.2 # API Server fastapi==0.115.12 -pydantic==2.10.6 +pydantic==2.11.1 uvicorn==0.34.0 pyjwt==2.10.1 aiofiles==24.1.0 From 22f109bab1ff0df03d8a605351f56d1b06d065bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 03:05:18 +0000 Subject: [PATCH 22/34] chore(deps): bump humanize from 4.12.1 to 4.12.2 Bumps [humanize](https://github.com/python-humanize/humanize) from 4.12.1 to 4.12.2. - [Release notes](https://github.com/python-humanize/humanize/releases) - [Commits](https://github.com/python-humanize/humanize/compare/4.12.1...4.12.2) --- updated-dependencies: - dependency-name: humanize dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 928954c21..ee4613a74 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ SQLAlchemy==2.0.39 python-telegram-bot==22.0 # can't be hard-pinned due to telegram-bot pinning httpx with ~ httpx>=0.24.1 -humanize==4.12.1 +humanize==4.12.2 cachetools==5.5.2 requests==2.32.3 urllib3==2.3.0 From dd388a51e0ce05858852811203114e3fba5416c4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 03:05:33 +0000 Subject: [PATCH 23/34] chore(deps): bump sqlalchemy from 2.0.39 to 2.0.40 Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.39 to 2.0.40. - [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases) - [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst) - [Commits](https://github.com/sqlalchemy/sqlalchemy/commits) --- updated-dependencies: - dependency-name: sqlalchemy dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 928954c21..1214141d5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ pandas-ta==0.3.14b ccxt==4.4.69 cryptography==44.0.2 aiohttp==3.9.5 -SQLAlchemy==2.0.39 +SQLAlchemy==2.0.40 python-telegram-bot==22.0 # can't be hard-pinned due to telegram-bot pinning httpx with ~ httpx>=0.24.1 From 63010bc5e9eb62d68b9e16cb09d8e20b3c9d1646 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 03:05:41 +0000 Subject: [PATCH 24/34] chore(deps): bump ccxt from 4.4.69 to 4.4.71 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.69 to 4.4.71. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/v4.4.69...v4.4.71) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 928954c21..9f55b7cd3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ bottleneck==1.4.2 numexpr==2.10.2 pandas-ta==0.3.14b -ccxt==4.4.69 +ccxt==4.4.71 cryptography==44.0.2 aiohttp==3.9.5 SQLAlchemy==2.0.39 From 98652bfd89179e301b640d33ca5218ffe4567562 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 03:05:45 +0000 Subject: [PATCH 25/34] chore(deps): bump rich from 13.9.4 to 14.0.0 Bumps [rich](https://github.com/Textualize/rich) from 13.9.4 to 14.0.0. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.9.4...v14.0.0) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 928954c21..f5ff71eb8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,7 +22,7 @@ tabulate==0.9.0 pycoingecko==3.2.0 jinja2==3.1.6 joblib==1.4.2 -rich==13.9.4 +rich==14.0.0 pyarrow==19.0.1; platform_machine != 'armv7l' # find first, C search in arrays From db647ab4d5966d2a53411dc00d03e2551a9d70b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 03:05:49 +0000 Subject: [PATCH 26/34] chore(deps): bump orjson from 3.10.15 to 3.10.16 Bumps [orjson](https://github.com/ijl/orjson) from 3.10.15 to 3.10.16. - [Release notes](https://github.com/ijl/orjson/releases) - [Changelog](https://github.com/ijl/orjson/blob/master/CHANGELOG.md) - [Commits](https://github.com/ijl/orjson/compare/3.10.15...3.10.16) --- updated-dependencies: - dependency-name: orjson dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 928954c21..6bb9e28d7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,7 +31,7 @@ py_find_1st==1.1.7 # Load ticker files 30% faster python-rapidjson==1.20 # Properly format api responses -orjson==3.10.15 +orjson==3.10.16 # Notify systemd sdnotify==0.3.2 From 937aa5c70e97aa4e58a392986a880cc0e6a6e4a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 03:05:55 +0000 Subject: [PATCH 27/34] chore(deps): bump pytz from 2025.1 to 2025.2 Bumps [pytz](https://github.com/stub42/pytz) from 2025.1 to 2025.2. - [Release notes](https://github.com/stub42/pytz/releases) - [Commits](https://github.com/stub42/pytz/compare/release_2025.1...release_2025.2) --- updated-dependencies: - dependency-name: pytz dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 928954c21..10287e588 100644 --- a/requirements.txt +++ b/requirements.txt @@ -49,7 +49,7 @@ questionary==2.1.0 prompt-toolkit==3.0.50 # Extensions to datetime library python-dateutil==2.9.0.post0 -pytz==2025.1 +pytz==2025.2 #Futures schedule==1.2.2 From e5268a0449874c122372806de1cdcb2be691f795 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 31 Mar 2025 06:28:40 +0200 Subject: [PATCH 28/34] chore: bump sqlalchemy in pre-commit config --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5d36ce602..f89cc7383 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: - types-requests==2.32.0.20250306 - types-tabulate==0.9.0.20241207 - types-python-dateutil==2.9.0.20241206 - - SQLAlchemy==2.0.39 + - SQLAlchemy==2.0.40 # stages: [push] - repo: https://github.com/pycqa/isort From 795a0b81eec3c401d511f6b0799e43a0b3b79ddd Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 31 Mar 2025 06:47:23 +0200 Subject: [PATCH 29/34] chore: remove workaround for Kraken ".F" workaround --- freqtrade/exchange/kraken.py | 2 +- tests/exchange/test_kraken.py | 2 +- tests/exchange_online/conftest.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index 03c97569a..d82725bbb 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -69,7 +69,7 @@ class Kraken(Exchange): consolidated: CcxtBalances = {} for currency, balance in balances.items(): base_currency = currency[:-2] if currency.endswith(".F") else currency - base_currency = self._api.commonCurrencies.get(base_currency, base_currency) + if base_currency in consolidated: consolidated[base_currency]["free"] += balance["free"] consolidated[base_currency]["used"] += balance["used"] diff --git a/tests/exchange/test_kraken.py b/tests/exchange/test_kraken.py index 5cfdac15f..fd36a359d 100644 --- a/tests/exchange/test_kraken.py +++ b/tests/exchange/test_kraken.py @@ -71,7 +71,7 @@ def test_get_balances_prod_kraken(default_conf, mocker): "4TH": balance_item.copy(), "EUR": balance_item.copy(), "BTC": {"free": 0.0, "total": 0.0, "used": 0.0}, - "XBT.F": balance_item.copy(), + "BTC.F": balance_item.copy(), "timestamp": 123123, } ) diff --git a/tests/exchange_online/conftest.py b/tests/exchange_online/conftest.py index 8eedcfb01..f7cf49aa4 100644 --- a/tests/exchange_online/conftest.py +++ b/tests/exchange_online/conftest.py @@ -156,7 +156,7 @@ EXCHANGES = { "ADA.F": {"free": 2.0, "total": 2.0, "used": 0.0}, "BTC": {"free": 0.0006, "total": 0.0006, "used": 0.0}, # XBT.F should be mapped to BTC.F - "XBT.F": {"free": 0.001, "total": 0.001, "used": 0.0}, + "BTC.F": {"free": 0.001, "total": 0.001, "used": 0.0}, }, }, }, From b2b15187085361793759db710d556cab50318d1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 07:04:07 +0000 Subject: [PATCH 30/34] chore(deps-dev): bump types-requests in the types group Bumps the types group with 1 update: [types-requests](https://github.com/python/typeshed). Updates `types-requests` from 2.32.0.20250306 to 2.32.0.20250328 - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-requests dependency-type: direct:development update-type: version-update:semver-patch dependency-group: types ... Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 29fc2bee1..e8450eb80 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -27,6 +27,6 @@ nbconvert==7.16.6 # mypy types types-cachetools==5.5.0.20240820 types-filelock==3.2.7 -types-requests==2.32.0.20250306 +types-requests==2.32.0.20250328 types-tabulate==0.9.0.20241207 types-python-dateutil==2.9.0.20241206 From 296c14afc0b156e2cb04dbbcbf306aa3dbca0a93 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 31 Mar 2025 09:06:26 +0200 Subject: [PATCH 31/34] chore: bump pre-commit types-requests --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f89cc7383..6f2430770 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: additional_dependencies: - types-cachetools==5.5.0.20240820 - types-filelock==3.2.7 - - types-requests==2.32.0.20250306 + - types-requests==2.32.0.20250328 - types-tabulate==0.9.0.20241207 - types-python-dateutil==2.9.0.20241206 - SQLAlchemy==2.0.40 From e9cd840f5bac0bc312aeff4b0ba634c949780c86 Mon Sep 17 00:00:00 2001 From: Freqtrade Bot <154552126+freqtrade-bot@users.noreply.github.com> Date: Tue, 1 Apr 2025 03:20:59 +0000 Subject: [PATCH 32/34] chore: update pre-commit hooks --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6f2430770..200f12818 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pycqa/flake8 - rev: "7.1.2" + rev: "7.2.0" hooks: - id: flake8 additional_dependencies: [Flake8-pyproject] From 68f32d76aeb1d0b356a0c228e441495eed5bea8c Mon Sep 17 00:00:00 2001 From: mrpabloyeah Date: Tue, 1 Apr 2025 20:54:03 +0200 Subject: [PATCH 33/34] Fix drawdown calculation when there are no winning trades --- freqtrade/data/metrics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/data/metrics.py b/freqtrade/data/metrics.py index d2ae2d64b..e15288802 100644 --- a/freqtrade/data/metrics.py +++ b/freqtrade/data/metrics.py @@ -118,7 +118,7 @@ def _calc_drawdown_series( ) -> pd.DataFrame: max_drawdown_df = pd.DataFrame() max_drawdown_df["cumulative"] = profit_results[value_col].cumsum() - max_drawdown_df["high_value"] = max_drawdown_df["cumulative"].cummax() + max_drawdown_df["high_value"] = np.maximum(0, max_drawdown_df["cumulative"].cummax()) max_drawdown_df["drawdown"] = max_drawdown_df["cumulative"] - max_drawdown_df["high_value"] max_drawdown_df["date"] = profit_results.loc[:, date_col] if starting_balance: From a3f23fd4fb2636402a7f2f023fac6bef8215b2bd Mon Sep 17 00:00:00 2001 From: mrpabloyeah Date: Tue, 1 Apr 2025 22:51:29 +0200 Subject: [PATCH 34/34] Also fix the expected result in the test --- tests/data/test_btanalysis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index eec3ac4e4..b0128dd25 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -569,7 +569,7 @@ def test_calculate_max_drawdown2(): df1.loc[:, "profit"] = df1["profit"] * -1 # No winning trade ... drawdown = calculate_max_drawdown(df1, date_col="open_date", value_col="profit") - assert drawdown.drawdown_abs == 0.043965 + assert drawdown.drawdown_abs == 0.055545 @pytest.mark.parametrize(