From f3c84d6a3cde70b780b06fe22d5b7045d51932d8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Apr 2026 16:01:26 +0200 Subject: [PATCH 01/49] feat: calculate sharpe-ratio from historic balance snapshots --- freqtrade/data/metrics.py | 47 ++++++++++++++++++- .../optimize/optimize_reports/bt_output.py | 7 +++ .../optimize_reports/optimize_reports.py | 3 ++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/freqtrade/data/metrics.py b/freqtrade/data/metrics.py index a9d3963d2..00101c5ea 100644 --- a/freqtrade/data/metrics.py +++ b/freqtrade/data/metrics.py @@ -390,10 +390,55 @@ def calculate_sharpe( # Define high (negative) sharpe ratio to be clear that this is NOT optimal. sharp_ratio = -100 - # print(expected_returns_mean, up_stdev, sharp_ratio) return sharp_ratio +def calculate_sharpe_from_balance( + balance_history: pd.DataFrame, + date_col: str = "date", + balance_col: str = "total_quote", +) -> float: + """ + Calculate sharpe ratio from historical balance snapshots. + + :param balance_history: DataFrame containing at least date and balance columns + :param date_col: Column containing timestamps + :param balance_col: Column containing historical balance values + :return: sharpe + """ + if ( + len(balance_history) == 0 + or date_col not in balance_history + or balance_col not in balance_history + ): + return 0.0 + + wallet = balance_history.loc[:, [date_col, balance_col]].copy() + wallet[date_col] = pd.to_datetime(wallet[date_col], utc=True, errors="coerce") + wallet = wallet.dropna(subset=[date_col, balance_col]).sort_values(date_col) + + if len(wallet) < 2: + return 0.0 + + # Sample balance to daily end-of-day values to normalize variable snapshot frequency. + daily_balance = wallet.set_index(date_col)[balance_col].resample("1D").last().dropna() + daily_returns = daily_balance.pct_change().dropna() + + if len(daily_returns) == 0: + return 0.0 + + expected_returns_mean = daily_returns.mean() + up_stdev = daily_returns.std(ddof=0) + + if up_stdev != 0 and not np.isnan(up_stdev): + sharp_ratio = expected_returns_mean / up_stdev * np.sqrt(365) + else: + # Define high (negative) sharpe ratio to be clear that this is NOT optimal. + sharp_ratio = -100 + + return float(sharp_ratio) + + def calculate_calmar( trades: pd.DataFrame, min_date: datetime | None, diff --git a/freqtrade/optimize/optimize_reports/bt_output.py b/freqtrade/optimize/optimize_reports/bt_output.py index 23963038c..149f886a2 100644 --- a/freqtrade/optimize/optimize_reports/bt_output.py +++ b/freqtrade/optimize/optimize_reports/bt_output.py @@ -308,6 +308,13 @@ def text_table_add_metrics(strat_results: dict) -> None: ), ] ) + if "sharpe" in wallet_stats: + wallet_metrics.append( + ( + "Sharpe ratio balance", + f"{wallet_stats['sharpe']:.2f}", + ) + ) # Newly added fields should be ignored if they are missing in strat_results. hyperopt-show # command stores these results and newer version of freqtrade must be able to handle old diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index ba84d8834..24c683482 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -15,6 +15,7 @@ from freqtrade.data.metrics import ( calculate_market_change, calculate_max_drawdown, calculate_sharpe, + calculate_sharpe_from_balance, calculate_sortino, calculate_sqn, ) @@ -59,11 +60,13 @@ def generate_wallet_stats(wallet_df: DataFrame, stake_currency: str) -> dict[str low_balance = total_quote.loc[low_idx] low_date = wallet.loc[low_idx, "date"] high_date = wallet.loc[high_idx, "date"] + sharpe = calculate_sharpe_from_balance(wallet) return { "start_balance": start_balance, "end_balance": end_balance, "high_balance": high_balance, "low_balance": low_balance, + "sharpe": sharpe, "low_date": low_date.strftime(DATETIME_PRINT_FORMAT), "low_ts": int(low_date.timestamp() * 1000), "high_date": high_date.strftime(DATETIME_PRINT_FORMAT), From 97badd0d3b7b9763632441e5368acd468ba49235 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Apr 2026 16:01:42 +0200 Subject: [PATCH 02/49] test: add tests for sharpe based on balance --- tests/data/test_metrics.py | 43 +++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/tests/data/test_metrics.py b/tests/data/test_metrics.py index d19d9e328..38ce57aff 100644 --- a/tests/data/test_metrics.py +++ b/tests/data/test_metrics.py @@ -1,7 +1,8 @@ from datetime import UTC, datetime, timedelta +import numpy as np import pytest -from pandas import DataFrame, DateOffset, Timestamp +from pandas import DataFrame, DateOffset, Timestamp, to_datetime from freqtrade.configuration import TimeRange from freqtrade.data.btanalysis import ( @@ -16,6 +17,7 @@ from freqtrade.data.metrics import ( calculate_market_change, calculate_max_drawdown, calculate_sharpe, + calculate_sharpe_from_balance, calculate_sortino, calculate_sqn, calculate_underwater, @@ -217,6 +219,45 @@ def test_calculate_sharpe(testdatadir): assert pytest.approx(sharpe) == 44.5078669 +def test_calculate_sharpe_from_balance(): + balance_history = DataFrame( + { + "date": to_datetime( + [ + "2025-01-01 00:00:00+00:00", + "2025-01-02 00:00:00+00:00", + "2025-01-03 00:00:00+00:00", + "2025-01-04 00:00:00+00:00", + ], + utc=True, + ), + "total_quote": [100.0, 110.0, 104.5, 125.4], + } + ) + + sharpe = calculate_sharpe_from_balance(balance_history) + expected_returns = np.array([0.1, -0.05, 0.2]) + expected_sharpe = expected_returns.mean() / expected_returns.std() * np.sqrt(365) + + assert isinstance(sharpe, float) + assert pytest.approx(sharpe) == expected_sharpe + + +def test_calculate_sharpe_from_balance_empty_or_flat(): + assert calculate_sharpe_from_balance(DataFrame()) == 0.0 + + flat_balance_history = DataFrame( + { + "date": to_datetime( + ["2025-01-01 00:00:00+00:00", "2025-01-02 00:00:00+00:00"], + utc=True, + ), + "total_quote": [100.0, 100.0], + } + ) + assert calculate_sharpe_from_balance(flat_balance_history) == -100 + + def test_calculate_calmar(testdatadir): filename = testdatadir / "backtest_results/backtest-result.json" bt_data = load_backtest_data(filename) From 017df564ce367d1c7d2304374621cc61273e8a6f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Apr 2026 16:05:21 +0200 Subject: [PATCH 03/49] refactor: extract annualizated ratio calculation --- freqtrade/data/metrics.py | 54 +++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/freqtrade/data/metrics.py b/freqtrade/data/metrics.py index 00101c5ea..5538b72e5 100644 --- a/freqtrade/data/metrics.py +++ b/freqtrade/data/metrics.py @@ -333,6 +333,25 @@ def calculate_expectancy(trades: pd.DataFrame) -> tuple[float, float]: return expectancy, expectancy_ratio +def _calculate_annualized_ratio( + expected_returns_mean: float, + denominator: float, + annualization_factor: int = 365, +) -> float: + """ + Helper function to calculate annualized ratios like Sharpe and Sortino. + :param expected_returns_mean: Mean of the returns (expected returns) + :param denominator: Denominator of the ratio (e.g. standard deviation for Sharpe) + :param annualization_factor: Factor to annualize the ratio (default is 365 for daily returns) + :return: Annualized ratio, or -100.0 if denominator is zero or NaN to indicate this is + not optimal. + """ + if denominator != 0 and not np.isnan(denominator): + return float(expected_returns_mean / denominator * np.sqrt(annualization_factor)) + + # Define high (negative) ratio to be clear that this is NOT optimal. + return -100.0 + def calculate_sortino( trades: pd.DataFrame, min_date: datetime | None, @@ -354,14 +373,7 @@ def calculate_sortino( down_stdev = np.std(trades.loc[trades["profit_abs"] < 0, "profit_abs"] / starting_balance) - if down_stdev != 0 and not np.isnan(down_stdev): - sortino_ratio = expected_returns_mean / down_stdev * np.sqrt(365) - else: - # Define high (negative) sortino ratio to be clear that this is NOT optimal. - sortino_ratio = -100 - - # print(expected_returns_mean, down_stdev, sortino_ratio) - return sortino_ratio + return _calculate_annualized_ratio(expected_returns_mean, down_stdev) def calculate_sharpe( @@ -384,13 +396,7 @@ def calculate_sharpe( expected_returns_mean = total_profit.sum() / days_period up_stdev = np.std(total_profit) - if up_stdev != 0: - sharp_ratio = expected_returns_mean / up_stdev * np.sqrt(365) - else: - # Define high (negative) sharpe ratio to be clear that this is NOT optimal. - sharp_ratio = -100 - - return sharp_ratio + return _calculate_annualized_ratio(expected_returns_mean, up_stdev) def calculate_sharpe_from_balance( @@ -429,14 +435,7 @@ def calculate_sharpe_from_balance( expected_returns_mean = daily_returns.mean() up_stdev = daily_returns.std(ddof=0) - - if up_stdev != 0 and not np.isnan(up_stdev): - sharp_ratio = expected_returns_mean / up_stdev * np.sqrt(365) - else: - # Define high (negative) sharpe ratio to be clear that this is NOT optimal. - sharp_ratio = -100 - - return float(sharp_ratio) + return _calculate_annualized_ratio(expected_returns_mean, up_stdev) def calculate_calmar( @@ -469,14 +468,7 @@ def calculate_calmar( except ValueError: max_drawdown = 0 - if max_drawdown != 0: - calmar_ratio = expected_returns_mean / max_drawdown * math.sqrt(365) - else: - # Define high (negative) calmar ratio to be clear that this is NOT optimal. - calmar_ratio = -100 - - # print(expected_returns_mean, max_drawdown, calmar_ratio) - return calmar_ratio + return _calculate_annualized_ratio(expected_returns_mean, max_drawdown) def calculate_sqn(trades: pd.DataFrame, starting_balance: float) -> float: From c2b95090f7d3187e2ae99feb196476c288c4e170 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Apr 2026 16:07:55 +0200 Subject: [PATCH 04/49] refactor: reusable "daily_returns_from_balance" method --- freqtrade/data/metrics.py | 42 +++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/freqtrade/data/metrics.py b/freqtrade/data/metrics.py index 5538b72e5..b766f461d 100644 --- a/freqtrade/data/metrics.py +++ b/freqtrade/data/metrics.py @@ -352,6 +352,30 @@ def _calculate_annualized_ratio( # Define high (negative) ratio to be clear that this is NOT optimal. return -100.0 + +def _calculate_daily_returns_from_balance( + balance_history: pd.DataFrame, + date_col: str, + balance_col: str, +) -> pd.Series: + if ( + len(balance_history) == 0 + or date_col not in balance_history + or balance_col not in balance_history + ): + return pd.Series(dtype=float) + + wallet = balance_history.loc[:, [date_col, balance_col]].copy() + wallet = wallet.dropna(subset=[date_col, balance_col]).sort_values(date_col) + + if len(wallet) < 2: + return pd.Series(dtype=float) + + # Sample balance to daily end-of-day values to normalize variable snapshot frequency. + daily_balance = wallet.set_index(date_col)[balance_col].resample("1D").last().dropna() + return daily_balance.pct_change().dropna() + + def calculate_sortino( trades: pd.DataFrame, min_date: datetime | None, @@ -412,23 +436,7 @@ def calculate_sharpe_from_balance( :param balance_col: Column containing historical balance values :return: sharpe """ - if ( - len(balance_history) == 0 - or date_col not in balance_history - or balance_col not in balance_history - ): - return 0.0 - - wallet = balance_history.loc[:, [date_col, balance_col]].copy() - wallet[date_col] = pd.to_datetime(wallet[date_col], utc=True, errors="coerce") - wallet = wallet.dropna(subset=[date_col, balance_col]).sort_values(date_col) - - if len(wallet) < 2: - return 0.0 - - # Sample balance to daily end-of-day values to normalize variable snapshot frequency. - daily_balance = wallet.set_index(date_col)[balance_col].resample("1D").last().dropna() - daily_returns = daily_balance.pct_change().dropna() + daily_returns = _calculate_daily_returns_from_balance(balance_history, date_col, balance_col) if len(daily_returns) == 0: return 0.0 From 6210927bdb984670844df99e18cf0affc50281ea Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Apr 2026 16:37:37 +0200 Subject: [PATCH 05/49] feat: add sortino_from_balance calculation --- freqtrade/data/metrics.py | 24 +++++++++++++++++++ tests/data/test_metrics.py | 48 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/freqtrade/data/metrics.py b/freqtrade/data/metrics.py index b766f461d..e4e618d1c 100644 --- a/freqtrade/data/metrics.py +++ b/freqtrade/data/metrics.py @@ -400,6 +400,30 @@ def calculate_sortino( return _calculate_annualized_ratio(expected_returns_mean, down_stdev) +def calculate_sortino_from_balance( + balance_history: pd.DataFrame, + date_col: str = "date", + balance_col: str = "total_quote", +) -> float: + """ + Calculate sortino ratio from historical balance snapshots. + + :param balance_history: DataFrame containing at least date and balance columns + :param date_col: Column containing timestamps + :param balance_col: Column containing historical balance values + :return: sortino + """ + daily_returns = _calculate_daily_returns_from_balance(balance_history, date_col, balance_col) + + if len(daily_returns) == 0: + return 0.0 + + expected_returns_mean = daily_returns.mean() + downside_returns = daily_returns[daily_returns < 0] + down_stdev = downside_returns.std(ddof=0) + return _calculate_annualized_ratio(expected_returns_mean, down_stdev) + + def calculate_sharpe( trades: pd.DataFrame, min_date: datetime | None, diff --git a/tests/data/test_metrics.py b/tests/data/test_metrics.py index 38ce57aff..53f8ef0be 100644 --- a/tests/data/test_metrics.py +++ b/tests/data/test_metrics.py @@ -19,6 +19,7 @@ from freqtrade.data.metrics import ( calculate_sharpe, calculate_sharpe_from_balance, calculate_sortino, + calculate_sortino_from_balance, calculate_sqn, calculate_underwater, combine_dataframes_with_mean, @@ -202,6 +203,53 @@ def test_calculate_sortino(testdatadir): assert pytest.approx(sortino) == 35.17722 +def test_calculate_sortino_from_balance(): + balance_history = DataFrame( + { + "date": to_datetime( + [ + "2025-01-01 00:00:00+00:00", + "2025-01-02 00:00:00+00:00", + "2025-01-03 00:00:00+00:00", + "2025-01-04 00:00:00+00:00", + "2025-01-05 00:00:00+00:00", + ], + utc=True, + ), + "total_quote": [100.0, 110.0, 104.5, 125.4, 112.86], + } + ) + + sortino = calculate_sortino_from_balance(balance_history) + expected_returns = np.array([0.1, -0.05, 0.2, -0.1]) + expected_sortino = expected_returns.mean() / np.std(expected_returns[expected_returns < 0]) + expected_sortino *= np.sqrt(365) + + assert isinstance(sortino, float) + assert pytest.approx(sortino) == expected_sortino + # Explicit assert + assert pytest.approx(sortino) == 28.6574597 + + +def test_calculate_sortino_from_balance_empty_or_no_downside(): + assert calculate_sortino_from_balance(DataFrame()) == 0.0 + + positive_balance_history = DataFrame( + { + "date": to_datetime( + [ + "2025-01-01 00:00:00+00:00", + "2025-01-02 00:00:00+00:00", + "2025-01-03 00:00:00+00:00", + ], + utc=True, + ), + "total_quote": [100.0, 110.0, 121.0], + } + ) + assert calculate_sortino_from_balance(positive_balance_history) == -100 + + def test_calculate_sharpe(testdatadir): filename = testdatadir / "backtest_results/backtest-result.json" bt_data = load_backtest_data(filename) From fba843cb61a0edd2636e79d7db5cf57caf8c1eb7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Apr 2026 17:05:55 +0200 Subject: [PATCH 06/49] refactor: extract balance df checks for future reuse --- freqtrade/data/metrics.py | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/freqtrade/data/metrics.py b/freqtrade/data/metrics.py index e4e618d1c..8573505c7 100644 --- a/freqtrade/data/metrics.py +++ b/freqtrade/data/metrics.py @@ -358,22 +358,45 @@ def _calculate_daily_returns_from_balance( date_col: str, balance_col: str, ) -> pd.Series: + wallet = _prepare_balance_history(balance_history, date_col, balance_col) + if len(wallet) == 0: + return pd.DataFrame(columns=[date_col, balance_col]) + + # Sample balance to daily end-of-day values to normalize variable snapshot frequency. + daily_balance = ( + wallet.set_index(date_col)[balance_col].resample("1D").last().dropna().rename(balance_col) + ) + daily_balance = daily_balance.reset_index() + + if len(daily_balance) < 2: + return pd.Series(dtype=float) + + return daily_balance[balance_col].pct_change().dropna() + + +def _prepare_balance_history( + balance_history: pd.DataFrame, + date_col: str, + balance_col: str, +) -> pd.DataFrame: + """ + Prepare balance history for calculations by filtering out rows with + missing date or balance values. + """ if ( len(balance_history) == 0 or date_col not in balance_history or balance_col not in balance_history ): - return pd.Series(dtype=float) + return pd.DataFrame(columns=[date_col, balance_col]) wallet = balance_history.loc[:, [date_col, balance_col]].copy() wallet = wallet.dropna(subset=[date_col, balance_col]).sort_values(date_col) - if len(wallet) < 2: - return pd.Series(dtype=float) + if len(wallet) == 0: + return pd.DataFrame(columns=[date_col, balance_col]) - # Sample balance to daily end-of-day values to normalize variable snapshot frequency. - daily_balance = wallet.set_index(date_col)[balance_col].resample("1D").last().dropna() - return daily_balance.pct_change().dropna() + return wallet def calculate_sortino( From bcd9023a8d32a6af702ee25c3038950b356f088a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Apr 2026 17:09:37 +0200 Subject: [PATCH 07/49] feat: add max-drawdown from wallet balance --- freqtrade/data/metrics.py | 37 ++++++++++++++++++++++++++++++++ tests/data/test_metrics.py | 43 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/freqtrade/data/metrics.py b/freqtrade/data/metrics.py index 8573505c7..5aaf6fac2 100644 --- a/freqtrade/data/metrics.py +++ b/freqtrade/data/metrics.py @@ -493,6 +493,43 @@ def calculate_sharpe_from_balance( return _calculate_annualized_ratio(expected_returns_mean, up_stdev) +def calculate_max_drawdown_from_balance( + balance_history: pd.DataFrame, + date_col: str = "date", + balance_col: str = "total_quote", + relative: bool = False, +) -> DrawDownResult: + """ + Calculate max drawdown from historical balance snapshots. + + :param balance_history: DataFrame containing at least date and balance columns + :param date_col: Column containing timestamps + :param balance_col: Column containing historical balance values + :param relative: If True, use relative drawdown for max calculation instead of absolute + :return: DrawDownResult object + :raise: ValueError if balance-history dataframe was found empty. + """ + wallet = _prepare_balance_history( + balance_history=balance_history, + date_col=date_col, + balance_col=balance_col, + ) + + if len(wallet) < 2: + raise ValueError("Balance-history dataframe empty.") + + starting_balance = float(wallet[balance_col].iloc[0]) + wallet.loc[:, "total_balance"] = wallet[balance_col].diff().fillna(0.0) + + return calculate_max_drawdown( + wallet, + date_col=date_col, + value_col="total_balance", + starting_balance=starting_balance, + relative=relative, + ) + + def calculate_calmar( trades: pd.DataFrame, min_date: datetime | None, diff --git a/tests/data/test_metrics.py b/tests/data/test_metrics.py index 53f8ef0be..610cbd8ee 100644 --- a/tests/data/test_metrics.py +++ b/tests/data/test_metrics.py @@ -16,6 +16,7 @@ from freqtrade.data.metrics import ( calculate_expectancy, calculate_market_change, calculate_max_drawdown, + calculate_max_drawdown_from_balance, calculate_sharpe, calculate_sharpe_from_balance, calculate_sortino, @@ -145,6 +146,48 @@ def test_calculate_max_drawdown(testdatadir): calculate_underwater(DataFrame()) +def test_calculate_max_drawdown_from_balance(): + balance_history = DataFrame( + { + "date": to_datetime( + [ + "2025-01-01 00:00:00+00:00", + "2025-01-01 12:00:00+00:00", + "2025-01-01 18:00:00+00:00", + "2025-01-04 00:00:00+00:00", + ], + utc=True, + ), + "total_quote": [100.0, 120.0, 80.0, 110.0], + } + ) + + drawdown = calculate_max_drawdown_from_balance(balance_history) + assert isinstance(drawdown.relative_account_drawdown, float) + assert pytest.approx(drawdown.relative_account_drawdown) == 1 / 3 + assert pytest.approx(drawdown.drawdown_abs) == 40 + assert pytest.approx(drawdown.current_high_value) == 20 + assert pytest.approx(drawdown.low_value) == -20 + assert pytest.approx(drawdown.high_value) == 20 + + assert drawdown.high_date == Timestamp("2025-01-01 12:00:00", tz="UTC") + assert drawdown.low_date == Timestamp("2025-01-01 18:00:00", tz="UTC") + + +def test_calculate_max_drawdown_from_balance_empty_or_short(): + with pytest.raises(ValueError, match=r"Balance-history dataframe empty\."): + calculate_max_drawdown_from_balance(DataFrame()) + + one_point = DataFrame( + { + "date": to_datetime(["2025-01-01 00:00:00+00:00"], utc=True), + "total_quote": [100.0], + } + ) + with pytest.raises(ValueError, match=r"Balance-history dataframe empty\."): + calculate_max_drawdown_from_balance(one_point) + + def test_calculate_csum(testdatadir): filename = testdatadir / "backtest_results/backtest-result.json" bt_data = load_backtest_data(filename) From 624be0c469c0f06fab999412d37e3794acd51bbb Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Apr 2026 17:10:05 +0200 Subject: [PATCH 08/49] feat: add calmar_from_balance --- freqtrade/data/metrics.py | 48 +++++++++++++++++++++++++++++++++++--- tests/data/test_metrics.py | 40 +++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 3 deletions(-) diff --git a/freqtrade/data/metrics.py b/freqtrade/data/metrics.py index 5aaf6fac2..4d66104ea 100644 --- a/freqtrade/data/metrics.py +++ b/freqtrade/data/metrics.py @@ -537,12 +537,12 @@ def calculate_calmar( starting_balance: float, ) -> float: """ - Calculate calmar + Calculate calmar from trades data. :param trades: DataFrame containing trades (requires columns close_date and profit_abs) :return: calmar """ if (len(trades) == 0) or (min_date is None) or (max_date is None) or (min_date == max_date): - return 0 + return 0.0 total_profit = trades["profit_abs"].sum() / starting_balance days_period = max(1, (max_date - min_date).days) @@ -558,7 +558,49 @@ def calculate_calmar( ) max_drawdown = drawdown.relative_account_drawdown except ValueError: - max_drawdown = 0 + return 0.0 + + return _calculate_annualized_ratio(expected_returns_mean, max_drawdown) + + +def calculate_calmar_from_balance( + balance_history: pd.DataFrame, + date_col: str = "date", + balance_col: str = "total_quote", +) -> float: + """ + Calculate calmar ratio from historical balance snapshots. + + :param balance_history: DataFrame containing at least date and balance columns + :param date_col: Column containing timestamps + :param balance_col: Column containing historical balance values + :return: calmar + """ + wallet = _prepare_balance_history( + balance_history=balance_history, + date_col=date_col, + balance_col=balance_col, + ) + + if len(wallet) < 2: + return 0.0 + + starting_balance = float(wallet[balance_col].iloc[0]) + final_balance = float(wallet[balance_col].iloc[-1]) + days_period = max(1, (wallet[date_col].iloc[-1] - wallet[date_col].iloc[0]).days) + + total_profit = (final_balance - starting_balance) / starting_balance + expected_returns_mean = total_profit / days_period * 100 + + try: + drawdown = calculate_max_drawdown_from_balance( + wallet, + date_col=date_col, + balance_col=balance_col, + ) + max_drawdown = drawdown.relative_account_drawdown + except ValueError: + return 0.0 return _calculate_annualized_ratio(expected_returns_mean, max_drawdown) diff --git a/tests/data/test_metrics.py b/tests/data/test_metrics.py index 610cbd8ee..242700eef 100644 --- a/tests/data/test_metrics.py +++ b/tests/data/test_metrics.py @@ -12,6 +12,7 @@ from freqtrade.data.history import load_data, load_pair_history from freqtrade.data.metrics import ( calculate_cagr, calculate_calmar, + calculate_calmar_from_balance, calculate_csum, calculate_expectancy, calculate_market_change, @@ -366,6 +367,45 @@ def test_calculate_calmar(testdatadir): assert pytest.approx(calmar) == 559.040508 +def test_calculate_calmar_from_balance(): + balance_history = DataFrame( + { + "date": to_datetime( + [ + "2025-01-01 00:00:00+00:00", + "2025-01-01 12:00:00+00:00", + "2025-01-01 18:00:00+00:00", + "2025-01-04 00:00:00+00:00", + ], + utc=True, + ), + "total_quote": [100.0, 120.0, 80.0, 110.0], + } + ) + + calmar = calculate_calmar_from_balance(balance_history) + expected_returns_mean = ((110.0 - 100.0) / 100.0) / 3 * 100 + expected_calmar = expected_returns_mean / (1 / 3) * np.sqrt(365) + + assert isinstance(calmar, float) + assert pytest.approx(calmar) == expected_calmar + + +def test_calculate_calmar_from_balance_empty_or_flat(): + assert calculate_calmar_from_balance(DataFrame()) == 0.0 + + flat_balance_history = DataFrame( + { + "date": to_datetime( + ["2025-01-01 00:00:00+00:00", "2025-01-02 00:00:00+00:00"], + utc=True, + ), + "total_quote": [100.0, 100.0], + } + ) + assert calculate_calmar_from_balance(flat_balance_history) == -100 + + def test_calculate_sqn(testdatadir): filename = testdatadir / "backtest_results/backtest-result.json" bt_data = load_backtest_data(filename) From bc0c8ffb712d97c2f3f33a0bfe5815b1fc152d78 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Apr 2026 17:25:45 +0200 Subject: [PATCH 09/49] feat: add wallet based metrics to backtest output --- .../optimize/optimize_reports/bt_output.py | 32 ++++++++++++----- .../optimize_reports/optimize_reports.py | 34 +++++++++++++++++++ 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/freqtrade/optimize/optimize_reports/bt_output.py b/freqtrade/optimize/optimize_reports/bt_output.py index 149f886a2..c8b4b50db 100644 --- a/freqtrade/optimize/optimize_reports/bt_output.py +++ b/freqtrade/optimize/optimize_reports/bt_output.py @@ -289,7 +289,7 @@ def text_table_add_metrics(strat_results: dict) -> None: ) wallet_metrics: list[tuple[str, str]] = [ ( - "Min/Max balance realized", + "Min/Max balance (realized)", f"{fmt_coin(strat_results['csum_min'], stake)} / " f"{fmt_coin(strat_results['csum_max'], stake)}", ), @@ -298,22 +298,38 @@ def text_table_add_metrics(strat_results: dict) -> None: wallet_metrics.extend( [ ( - "Min/Max balance unrealized", + "Min/Max balance (unrealized)", f"{fmt_coin(wallet_stats['low_balance'], stake)} / " f"{fmt_coin(wallet_stats['high_balance'], stake)}", ), ( - "Min/Max balance dates", + "Min/Max balance dates (unrealized)", f"{wallet_stats['low_date']} / {wallet_stats['high_date']}", ), ] ) if "sharpe" in wallet_stats: - wallet_metrics.append( - ( - "Sharpe ratio balance", - f"{wallet_stats['sharpe']:.2f}", - ) + # Assume that if sharpe is there, all others are there as well. + wallet_metrics.extend( + [ + ( + "Sharpe (unrealized)", + f"{wallet_stats['sharpe']:.2f}", + ), + ( + "Sortino (unrealized)", + f"{wallet_stats['sortino']:.2f}", + ), + ( + "Calmar (unrealized)", + f"{wallet_stats['calmar']:.2f}", + ), + ( + "Max drawdown (unrealized)", + f"{fmt_coin(wallet_stats['max_drawdown_abs'], stake)} " + f"({wallet_stats['max_drawdown_account']:.2%})", + ), + ] ) # Newly added fields should be ignored if they are missing in strat_results. hyperopt-show diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index 24c683482..a17d92b59 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -10,13 +10,16 @@ from freqtrade.constants import BACKTEST_BREAKDOWNS, DATETIME_PRINT_FORMAT from freqtrade.data.metrics import ( calculate_cagr, calculate_calmar, + calculate_calmar_from_balance, calculate_csum, calculate_expectancy, calculate_market_change, calculate_max_drawdown, + calculate_max_drawdown_from_balance, calculate_sharpe, calculate_sharpe_from_balance, calculate_sortino, + calculate_sortino_from_balance, calculate_sqn, ) from freqtrade.ft_types import ( @@ -61,12 +64,43 @@ def generate_wallet_stats(wallet_df: DataFrame, stake_currency: str) -> dict[str low_date = wallet.loc[low_idx, "date"] high_date = wallet.loc[high_idx, "date"] sharpe = calculate_sharpe_from_balance(wallet) + sortino = calculate_sortino_from_balance(wallet) + calmar = calculate_calmar_from_balance(wallet) + try: + drawdown = calculate_max_drawdown_from_balance(wallet) + except ValueError: + drawdown = None + return { "start_balance": start_balance, "end_balance": end_balance, "high_balance": high_balance, "low_balance": low_balance, "sharpe": sharpe, + "sortino": sortino, + "calmar": calmar, + "max_drawdown_account": drawdown.relative_account_drawdown if drawdown else 0.0, + "max_drawdown_abs": drawdown.drawdown_abs if drawdown else 0.0, + "drawdown_start": ( + drawdown.high_date.strftime(DATETIME_PRINT_FORMAT) + if drawdown and drawdown.high_date is not None + else None + ), + "drawdown_start_ts": ( + int(drawdown.high_date.timestamp() * 1000) + if drawdown and drawdown.high_date is not None + else None + ), + "drawdown_end": ( + drawdown.low_date.strftime(DATETIME_PRINT_FORMAT) + if drawdown and drawdown.low_date is not None + else None + ), + "drawdown_end_ts": ( + int(drawdown.low_date.timestamp() * 1000) + if drawdown and drawdown.low_date is not None + else None + ), "low_date": low_date.strftime(DATETIME_PRINT_FORMAT), "low_ts": int(low_date.timestamp() * 1000), "high_date": high_date.strftime(DATETIME_PRINT_FORMAT), From 64ceb028ac60f642a864786e9c5c58b9f201e45e Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Apr 2026 17:25:58 +0200 Subject: [PATCH 10/49] test: add test for wallet based output --- tests/optimize/test_optimize_reports.py | 54 +++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index b37080f43..2d82be360 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -28,6 +28,7 @@ from freqtrade.optimize.optimize_reports import ( generate_trading_stats, show_sorted_pairlist, store_backtest_results, + text_table_add_metrics, text_table_bt_results, text_table_strategy, ) @@ -36,6 +37,7 @@ from freqtrade.optimize.optimize_reports.optimize_reports import ( _get_resample_from_period, calc_streak, generate_tag_metrics, + generate_wallet_stats, ) from freqtrade.resolvers.strategy_resolver import StrategyResolver from freqtrade.util import dt_ts, format_duration @@ -616,6 +618,58 @@ def test_text_table_strategy(testdatadir, capsys): ) +def test_generate_wallet_stats_extended_metrics(): + wallet_df = pd.DataFrame( + { + "date": [ + dt_utc(2025, 1, 1, 0, 0, 0), + dt_utc(2025, 1, 1, 12, 0, 0), + dt_utc(2025, 1, 1, 18, 0, 0), + dt_utc(2025, 1, 3, 0, 0, 0), + ], + "currency": ["BTC", "BTC", "BTC", "BTC"], + "rate": [1.0, 1.0, 1.0, 1.0], + "balance": [100.0, 120.0, 80.0, 110.0], + } + ) + + stats = generate_wallet_stats(wallet_df, "BTC") + + assert "sharpe" in stats + assert "sortino" in stats + assert "calmar" in stats + assert "max_drawdown_account" in stats + assert "max_drawdown_abs" in stats + assert pytest.approx(stats["max_drawdown_account"]) == 1 / 3 + assert stats["drawdown_start"] == "2025-01-01 12:00:00" + assert stats["drawdown_end"] == "2025-01-01 18:00:00" + + +def test_text_table_add_metrics_shows_wallet_ratios(testdatadir, capsys): + filename = testdatadir / "backtest_results/backtest-result.json" + bt_data = load_backtest_stats(filename) + strat_results = next(iter(bt_data["strategy"].values())) + strat_results["wallet_stats"] = { + "low_balance": 0.95, + "high_balance": 1.12, + "low_date": "2025-01-01 18:00:00", + "high_date": "2025-01-01 12:00:00", + "sharpe": 1.23, + "sortino": 2.34, + "calmar": 3.45, + "max_drawdown_account": 0.12, + "max_drawdown_abs": 0.05, + } + + text_table_add_metrics(strat_results) + text = capsys.readouterr().out + + assert "Sharpe ratio balance" in text + assert "Sortino ratio balance" in text + assert "Calmar ratio balance" in text + assert "Max drawdown balance" in text + + def test_generate_periodic_breakdown_stats(testdatadir): filename = testdatadir / "backtest_results/backtest-result.json" bt_data = load_backtest_data(filename).to_dict(orient="records") From 5e0eb5da1079595a8e11ceab59631b25485796ed Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Apr 2026 18:15:36 +0200 Subject: [PATCH 11/49] chore: improved backtest-output ordering --- .../optimize/optimize_reports/bt_output.py | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/freqtrade/optimize/optimize_reports/bt_output.py b/freqtrade/optimize/optimize_reports/bt_output.py index c8b4b50db..148583ed7 100644 --- a/freqtrade/optimize/optimize_reports/bt_output.py +++ b/freqtrade/optimize/optimize_reports/bt_output.py @@ -294,7 +294,8 @@ def text_table_add_metrics(strat_results: dict) -> None: f"{fmt_coin(strat_results['csum_max'], stake)}", ), ] - if wallet_stats := strat_results.get("wallet_stats"): + wallet_stats = strat_results.get("wallet_stats", {}) + if wallet_stats: wallet_metrics.extend( [ ( @@ -308,24 +309,12 @@ def text_table_add_metrics(strat_results: dict) -> None: ), ] ) - if "sharpe" in wallet_stats: + if "max_drawdown_abs" in wallet_stats: # Assume that if sharpe is there, all others are there as well. - wallet_metrics.extend( + drawdown_metrics.extend( [ ( - "Sharpe (unrealized)", - f"{wallet_stats['sharpe']:.2f}", - ), - ( - "Sortino (unrealized)", - f"{wallet_stats['sortino']:.2f}", - ), - ( - "Calmar (unrealized)", - f"{wallet_stats['calmar']:.2f}", - ), - ( - "Max drawdown (unrealized)", + "Absolute drawdown (unrealized)", f"{fmt_coin(wallet_stats['max_drawdown_abs'], stake)} " f"({wallet_stats['max_drawdown_account']:.2%})", ), @@ -359,9 +348,27 @@ def text_table_add_metrics(strat_results: dict) -> None: ), ("Total profit %", f"{strat_results['profit_total']:.2%}"), ("CAGR %", f"{strat_results['cagr']:.2%}" if "cagr" in strat_results else "N/A"), - ("Sortino", f"{strat_results['sortino']:.2f}" if "sortino" in strat_results else "N/A"), ("Sharpe", f"{strat_results['sharpe']:.2f}" if "sharpe" in strat_results else "N/A"), + ( + "Sharpe (unrealized)", + f"{wallet_stats['sharpe']:.2f}" + if wallet_stats and "sharpe" in wallet_stats + else "N/A", + ), + ("Sortino", f"{strat_results['sortino']:.2f}" if "sortino" in strat_results else "N/A"), + ( + "Sortino (unrealized)", + f"{wallet_stats['sortino']:.2f}" + if wallet_stats and "sortino" in wallet_stats + else "N/A", + ), ("Calmar", f"{strat_results['calmar']:.2f}" if "calmar" in strat_results else "N/A"), + ( + "Calmar (unrealized)", + f"{wallet_stats['calmar']:.2f}" + if wallet_stats and "calmar" in wallet_stats + else "N/A", + ), ("SQN", f"{strat_results['sqn']:.2f}" if "sqn" in strat_results else "N/A"), ( "Profit factor", From dfa2db8575b7fdf3ad5b76414aeceaabf763b22c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 08:34:22 +0200 Subject: [PATCH 12/49] docs: add new fields to the docs --- docs/backtesting.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index 12455b367..eaf3d1581 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -394,9 +394,12 @@ It contains key metrics about the performance of your strategy on backtesting da - `Absolute profit`: Profit made in stake currency. - `Total profit %`: Total profit. Aligned to the `TOTAL` row's `Tot Profit %` from the first table. Calculated as `(End capital − Starting capital) / Starting capital`. - `CAGR %`: Compound annual growth rate. -- `Sortino`: Annualized Sortino ratio. -- `Sharpe`: Annualized Sharpe ratio. -- `Calmar`: Annualized Calmar ratio. +- `Sharpe (closed trades)`: Annualized Sharpe ratio including only closed trades (ignoring open trades with profits or losses). +- `Sharpe (wallet balance)` Annualized Sharpe ratio calculation but including unrealized profits. +- `Sortino (closed trades)`: Annualized Sortino ratio including only closed trades (ignoring open trades with profits or losses). +- `Sortino (wallet balance)` Annualized Sortino ratio calculation but including unrealized profits. +- `Calmar (closed trades)`: Annualized Calmar ratio including only closed trades (ignoring open trades with profits or losses). +- `Calmar (wallet balance)` Annualized Calmar ratio calculation but including unrealized profits. - `SQN`: System Quality Number (SQN) - by Van Tharp. - `Profit factor`: Sum of the profits of all winning trades divided by the sum of the losses of all losing trades. - `Expectancy (Ratio)`: Expectancy ratio, which is the average profit or loss per trade. A negative expectancy ratio means that your strategy is not profitable. @@ -415,11 +418,12 @@ It contains key metrics about the performance of your strategy on backtesting da - `Max Consecutive Wins / Loss`: Maximum consecutive wins/losses in a row. - `Rejected Entry signals`: Trade entry signals that could not be acted upon due to `max_open_trades` being reached. - `Entry/Exit Timeouts`: Entry/exit orders which did not fill (only applicable if custom pricing is used). -- `Min/Max balance realized`: Lowest and Highest Wallet balance during the backtest period based on closed trades trades. -- `Min/Max balance unrealized`: Lowest and Highest Wallet balance during the backtest period - including capital tied in open trades. -- `Min/Max balance dates`: Dates when the minimum and maximum unrealized balance occurred. +- `Min/Max balance (closed trades)`: Lowest and Highest Wallet balance during the backtest period based on closed trades trades. +- `Min/Max balance (wallet balance)`: Lowest and Highest Wallet balance during the backtest period - including capital tied in open trades. +- `Min/Max balance dates (wallet balance)`: Dates when the minimum and maximum unrealized balance occurred. - `Max % of account underwater`: Maximum percentage your account has decreased from the top since the simulation started. Calculated as the maximum of `(Max Balance - Current Balance) / (Max Balance)`. - `Absolute drawdown`: Maximum absolute drawdown experienced, including percentage relative to the account calculated as `(Absolute Drawdown) / (DrawdownHigh + startingBalance)`.. +- `Absolute drawdown (wallet balance)`: Maximum absolute drawdown experienced based on the unrealized balance, including percentage relative to the account calculated as `(Absolute Drawdown) / (DrawdownHigh + startingBalance)`. - `Drawdown duration`: Duration of the largest drawdown period. - `Profit at drawdown start` / `Profit at drawdown end`: Profit at the beginning and end of the largest drawdown period. - `Drawdown start` / `Drawdown end`: Start and end datetime for the largest drawdown (can also be visualized via the `plot-dataframe` sub-command). From 173c75c08c15232e177b1855387c0b982d55b72f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 09:00:14 +0200 Subject: [PATCH 13/49] feat: improve wording on metrics --- .../optimize/optimize_reports/bt_output.py | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/freqtrade/optimize/optimize_reports/bt_output.py b/freqtrade/optimize/optimize_reports/bt_output.py index 148583ed7..4f8143420 100644 --- a/freqtrade/optimize/optimize_reports/bt_output.py +++ b/freqtrade/optimize/optimize_reports/bt_output.py @@ -289,7 +289,7 @@ def text_table_add_metrics(strat_results: dict) -> None: ) wallet_metrics: list[tuple[str, str]] = [ ( - "Min/Max balance (realized)", + "Min/Max balance (closed trades)", f"{fmt_coin(strat_results['csum_min'], stake)} / " f"{fmt_coin(strat_results['csum_max'], stake)}", ), @@ -299,26 +299,25 @@ def text_table_add_metrics(strat_results: dict) -> None: wallet_metrics.extend( [ ( - "Min/Max balance (unrealized)", + "Min/Max balance (wallet balance)", f"{fmt_coin(wallet_stats['low_balance'], stake)} / " f"{fmt_coin(wallet_stats['high_balance'], stake)}", ), ( - "Min/Max balance dates (unrealized)", + "Min/Max balance dates (wallet balance)", f"{wallet_stats['low_date']} / {wallet_stats['high_date']}", ), ] ) if "max_drawdown_abs" in wallet_stats: # Assume that if sharpe is there, all others are there as well. - drawdown_metrics.extend( - [ - ( - "Absolute drawdown (unrealized)", - f"{fmt_coin(wallet_stats['max_drawdown_abs'], stake)} " - f"({wallet_stats['max_drawdown_account']:.2%})", - ), - ] + drawdown_metrics.insert( + 2, + ( + "Absolute drawdown (wallet balance)", + f"{fmt_coin(wallet_stats['max_drawdown_abs'], stake)} " + f"({wallet_stats['max_drawdown_account']:.2%})", + ), ) # Newly added fields should be ignored if they are missing in strat_results. hyperopt-show @@ -348,23 +347,32 @@ def text_table_add_metrics(strat_results: dict) -> None: ), ("Total profit %", f"{strat_results['profit_total']:.2%}"), ("CAGR %", f"{strat_results['cagr']:.2%}" if "cagr" in strat_results else "N/A"), - ("Sharpe", f"{strat_results['sharpe']:.2f}" if "sharpe" in strat_results else "N/A"), ( - "Sharpe (unrealized)", + "Sharpe (closed trades)", + f"{strat_results['sharpe']:.2f}" if "sharpe" in strat_results else "N/A", + ), + ( + "Sharpe (daily wallet balance)", f"{wallet_stats['sharpe']:.2f}" if wallet_stats and "sharpe" in wallet_stats else "N/A", ), - ("Sortino", f"{strat_results['sortino']:.2f}" if "sortino" in strat_results else "N/A"), ( - "Sortino (unrealized)", + "Sortino (closed trades)", + f"{strat_results['sortino']:.2f}" if "sortino" in strat_results else "N/A", + ), + ( + "Sortino (daily wallet balance)", f"{wallet_stats['sortino']:.2f}" if wallet_stats and "sortino" in wallet_stats else "N/A", ), - ("Calmar", f"{strat_results['calmar']:.2f}" if "calmar" in strat_results else "N/A"), ( - "Calmar (unrealized)", + "Calmar (closed trades)", + f"{strat_results['calmar']:.2f}" if "calmar" in strat_results else "N/A", + ), + ( + "Calmar (daily wallet balance)", f"{wallet_stats['calmar']:.2f}" if wallet_stats and "calmar" in wallet_stats else "N/A", From 76c09299a9bdf2c529073f4c8a573f1711ef05ea Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 09:18:37 +0200 Subject: [PATCH 14/49] feat: calculate complete drawdown metrics from wallet (incl. underwater) --- .../optimize_reports/optimize_reports.py | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index a17d92b59..1648db860 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -68,9 +68,16 @@ def generate_wallet_stats(wallet_df: DataFrame, stake_currency: str) -> dict[str calmar = calculate_calmar_from_balance(wallet) try: drawdown = calculate_max_drawdown_from_balance(wallet) + # max_relative_drawdown = Underwater + drawdown_duration = drawdown.low_date - drawdown.high_date + except ValueError: drawdown = None - + drawdown_duration = timedelta() + try: + underwater = calculate_max_drawdown_from_balance(wallet, relative=True) + except ValueError: + underwater = None return { "start_balance": start_balance, "end_balance": end_balance, @@ -79,7 +86,13 @@ def generate_wallet_stats(wallet_df: DataFrame, stake_currency: str) -> dict[str "sharpe": sharpe, "sortino": sortino, "calmar": calmar, + "low_date": low_date.strftime(DATETIME_PRINT_FORMAT), + "low_ts": int(low_date.timestamp() * 1000), + "high_date": high_date.strftime(DATETIME_PRINT_FORMAT), + "high_ts": int(high_date.timestamp() * 1000), + # Drawdown metrics "max_drawdown_account": drawdown.relative_account_drawdown if drawdown else 0.0, + "max_relative_drawdown": underwater.relative_account_drawdown, "max_drawdown_abs": drawdown.drawdown_abs if drawdown else 0.0, "drawdown_start": ( drawdown.high_date.strftime(DATETIME_PRINT_FORMAT) @@ -101,10 +114,10 @@ def generate_wallet_stats(wallet_df: DataFrame, stake_currency: str) -> dict[str if drawdown and drawdown.low_date is not None else None ), - "low_date": low_date.strftime(DATETIME_PRINT_FORMAT), - "low_ts": int(low_date.timestamp() * 1000), - "high_date": high_date.strftime(DATETIME_PRINT_FORMAT), - "high_ts": int(high_date.timestamp() * 1000), + "drawdown_duration": drawdown_duration, + "drawdown_duration_s": drawdown_duration.total_seconds(), + "max_drawdown_low": drawdown.low_value, + "max_drawdown_high": drawdown.high_value, } From a28545a67a7702502606ba72e2ac627d882c1854 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 09:18:46 +0200 Subject: [PATCH 15/49] feat: improved backtst output --- .../optimize/optimize_reports/bt_output.py | 49 ++++++++++++++----- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/freqtrade/optimize/optimize_reports/bt_output.py b/freqtrade/optimize/optimize_reports/bt_output.py index 4f8143420..5834d890d 100644 --- a/freqtrade/optimize/optimize_reports/bt_output.py +++ b/freqtrade/optimize/optimize_reports/bt_output.py @@ -9,6 +9,8 @@ from freqtrade.util import decimals_per_coin, fmt_coin, print_rich_table logger = logging.getLogger(__name__) +__EMPTY_LINE = ("", "") + def _get_line_floatfmt(stake_currency: str) -> list[str]: """ @@ -201,7 +203,7 @@ def text_table_add_metrics(strat_results: dict) -> None: short_metrics = ( [ - ("", ""), # Empty line to improve readability + __EMPTY_LINE, # Empty line to improve readability ( "Long / Short trades", f"{strat_results.get('trade_count_long', 'total_trades')} / " @@ -311,13 +313,35 @@ def text_table_add_metrics(strat_results: dict) -> None: ) if "max_drawdown_abs" in wallet_stats: # Assume that if sharpe is there, all others are there as well. - drawdown_metrics.insert( - 2, - ( - "Absolute drawdown (wallet balance)", - f"{fmt_coin(wallet_stats['max_drawdown_abs'], stake)} " - f"({wallet_stats['max_drawdown_account']:.2%})", - ), + drawdown_metrics.extend( + [ + __EMPTY_LINE, # Empty line to improve readability + ( + "Max % of account underwater (balance)", + f"{wallet_stats['max_relative_drawdown']:.2%}", + ), + ( + "Absolute drawdown (wallet balance)", + f"{fmt_coin(wallet_stats['max_drawdown_abs'], stake)} " + f"({wallet_stats['max_drawdown_account']:.2%})", + ), + ( + "Drawdown duration", + wallet_stats["drawdown_duration"] + if "drawdown_duration" in wallet_stats + else "N/A", + ), + ( + "Profit at drawdown start", + fmt_coin(wallet_stats["max_drawdown_high"], stake), + ), + ( + "Profit at drawdown end", + fmt_coin(wallet_stats["max_drawdown_low"], stake), + ), + ("Drawdown start", wallet_stats["drawdown_start"]), + ("Drawdown end", wallet_stats["drawdown_end"]), + ] ) # Newly added fields should be ignored if they are missing in strat_results. hyperopt-show @@ -328,7 +352,7 @@ def text_table_add_metrics(strat_results: dict) -> None: ("Backtesting to", strat_results["backtest_end"]), *trading_mode, ("Max open trades", strat_results["max_open_trades"]), - ("", ""), # Empty line to improve readability + __EMPTY_LINE, # Empty line to improve readability ( "Total/Daily Avg Trades", f"{strat_results['total_trades']} / {strat_results['trades_per_day']}", @@ -405,12 +429,13 @@ def text_table_add_metrics(strat_results: dict) -> None: "Avg. stake amount", fmt_coin(strat_results["avg_stake_amount"], stake), ), + ("Market change", f"{strat_results['market_change']:.2%}"), ( "Total trade volume", fmt_coin(strat_results["total_volume"], stake), ), *short_metrics, - ("", ""), # Empty line to improve readability + __EMPTY_LINE, # Empty line to improve readability ( "Best Pair", f"{strat_results['best_pair']['key']} " @@ -466,10 +491,10 @@ def text_table_add_metrics(strat_results: dict) -> None: f"{strat_results.get('timedout_exit_orders', 'N/A')}", ), *entry_adjustment_metrics, - ("", ""), # Empty line to improve readability + __EMPTY_LINE, # Empty line to improve readability *wallet_metrics, + __EMPTY_LINE, # Empty line to improve readability *drawdown_metrics, - ("Market change", f"{strat_results['market_change']:.2%}"), ] print_rich_table(metrics, ["Metric", "Value"], summary="SUMMARY METRICS", justify="left") From 44919adae461707ed4dbdec2fc279af9440f78ed Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 09:27:47 +0200 Subject: [PATCH 16/49] feat: improve backtest-output --- .../optimize/optimize_reports/bt_output.py | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/freqtrade/optimize/optimize_reports/bt_output.py b/freqtrade/optimize/optimize_reports/bt_output.py index 5834d890d..dbb3eff82 100644 --- a/freqtrade/optimize/optimize_reports/bt_output.py +++ b/freqtrade/optimize/optimize_reports/bt_output.py @@ -1,6 +1,8 @@ import logging from typing import Any, Literal +from rich.text import Text + from freqtrade.constants import UNLIMITED_STAKE_AMOUNT, Config from freqtrade.ft_types import BacktestResultType from freqtrade.optimize.optimize_reports.optimize_reports import generate_periodic_breakdown_stats @@ -316,6 +318,7 @@ def text_table_add_metrics(strat_results: dict) -> None: drawdown_metrics.extend( [ __EMPTY_LINE, # Empty line to improve readability + (Text("Wallet based Metrics", style="bold"), ""), ( "Max % of account underwater (balance)", f"{wallet_stats['max_relative_drawdown']:.2%}", @@ -341,6 +344,24 @@ def text_table_add_metrics(strat_results: dict) -> None: ), ("Drawdown start", wallet_stats["drawdown_start"]), ("Drawdown end", wallet_stats["drawdown_end"]), + ( + "Sharpe (daily wallet balance)", + f"{wallet_stats['sharpe']:.2f}" + if wallet_stats and "sharpe" in wallet_stats + else "N/A", + ), + ( + "Sortino (daily wallet balance)", + f"{wallet_stats['sortino']:.2f}" + if wallet_stats and "sortino" in wallet_stats + else "N/A", + ), + ( + "Calmar (daily wallet balance)", + f"{wallet_stats['calmar']:.2f}" + if wallet_stats and "calmar" in wallet_stats + else "N/A", + ), ] ) @@ -375,32 +396,14 @@ def text_table_add_metrics(strat_results: dict) -> None: "Sharpe (closed trades)", f"{strat_results['sharpe']:.2f}" if "sharpe" in strat_results else "N/A", ), - ( - "Sharpe (daily wallet balance)", - f"{wallet_stats['sharpe']:.2f}" - if wallet_stats and "sharpe" in wallet_stats - else "N/A", - ), ( "Sortino (closed trades)", f"{strat_results['sortino']:.2f}" if "sortino" in strat_results else "N/A", ), - ( - "Sortino (daily wallet balance)", - f"{wallet_stats['sortino']:.2f}" - if wallet_stats and "sortino" in wallet_stats - else "N/A", - ), ( "Calmar (closed trades)", f"{strat_results['calmar']:.2f}" if "calmar" in strat_results else "N/A", ), - ( - "Calmar (daily wallet balance)", - f"{wallet_stats['calmar']:.2f}" - if wallet_stats and "calmar" in wallet_stats - else "N/A", - ), ("SQN", f"{strat_results['sqn']:.2f}" if "sqn" in strat_results else "N/A"), ( "Profit factor", From 2d930f1fff27b711cf14db391fa26a7ddb4bdf72 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 09:33:39 +0200 Subject: [PATCH 17/49] chore: improved wallet stat drawdown safety --- freqtrade/optimize/optimize_reports/optimize_reports.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index 1648db860..a5d38b850 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -92,7 +92,7 @@ def generate_wallet_stats(wallet_df: DataFrame, stake_currency: str) -> dict[str "high_ts": int(high_date.timestamp() * 1000), # Drawdown metrics "max_drawdown_account": drawdown.relative_account_drawdown if drawdown else 0.0, - "max_relative_drawdown": underwater.relative_account_drawdown, + "max_relative_drawdown": underwater.relative_account_drawdown if underwater else 0.0, "max_drawdown_abs": drawdown.drawdown_abs if drawdown else 0.0, "drawdown_start": ( drawdown.high_date.strftime(DATETIME_PRINT_FORMAT) @@ -116,8 +116,8 @@ def generate_wallet_stats(wallet_df: DataFrame, stake_currency: str) -> dict[str ), "drawdown_duration": drawdown_duration, "drawdown_duration_s": drawdown_duration.total_seconds(), - "max_drawdown_low": drawdown.low_value, - "max_drawdown_high": drawdown.high_value, + "max_drawdown_low": drawdown.low_value if drawdown else 0.0, + "max_drawdown_high": drawdown.high_value if drawdown else 0.0, } From 22707d6c042f1c3fc8c288f0a6f33971f7d886f3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 09:51:54 +0200 Subject: [PATCH 18/49] test: update test with new metrics --- tests/optimize/test_optimize_reports.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 2d82be360..c54dea689 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -658,16 +658,21 @@ def test_text_table_add_metrics_shows_wallet_ratios(testdatadir, capsys): "sortino": 2.34, "calmar": 3.45, "max_drawdown_account": 0.12, + "max_relative_drawdown": 0.15, "max_drawdown_abs": 0.05, + "drawdown_start": "2025-01-01 12:00:00", + "drawdown_end": "2025-01-01 18:00:00", + "max_drawdown_high": 1.12, + "max_drawdown_low": 0.95, } text_table_add_metrics(strat_results) text = capsys.readouterr().out - assert "Sharpe ratio balance" in text - assert "Sortino ratio balance" in text - assert "Calmar ratio balance" in text - assert "Max drawdown balance" in text + assert "Sharpe (daily wallet balance)" in text + assert "Sortino (daily wallet balance)" in text + assert "Calmar (daily wallet balance)" in text + assert "Max % of account underwater (balance)" in text def test_generate_periodic_breakdown_stats(testdatadir): From da9f592d3dd06bce867f910d4730934757874129 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 10:00:16 +0200 Subject: [PATCH 19/49] docs: update backtesting docs --- docs/backtesting.md | 352 ++++++++++++++++++++++++-------------------- 1 file changed, 189 insertions(+), 163 deletions(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index eaf3d1581..5c758880b 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -160,118 +160,131 @@ The most important in the backtesting is to understand the result. A backtesting result will look like that: ``` - BACKTESTING REPORT -┏━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ -┃ Pair ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ -┡━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ -│ LTC/USDT:USDT │ 16 │ 1.0 │ 56.176 │ 5.62 │ 16:16:00 │ 16 0 0 100 │ -│ ETC/USDT:USDT │ 12 │ 0.72 │ 30.936 │ 3.09 │ 9:55:00 │ 11 0 1 91.7 │ -│ ETH/USDT:USDT │ 8 │ 0.66 │ 17.864 │ 1.79 │ 1 day, 13:55:00 │ 7 0 1 87.5 │ -│ XLM/USDT:USDT │ 10 │ 0.31 │ 11.054 │ 1.11 │ 12:08:00 │ 9 0 1 90.0 │ -│ BTC/USDT:USDT │ 8 │ 0.21 │ 7.289 │ 0.73 │ 3 days, 1:24:00 │ 6 0 2 75.0 │ -│ XRP/USDT:USDT │ 9 │ -0.14 │ -7.261 │ -0.73 │ 21:18:00 │ 8 0 1 88.9 │ -│ DOT/USDT:USDT │ 6 │ -0.4 │ -9.187 │ -0.92 │ 5:35:00 │ 4 0 2 66.7 │ -│ ADA/USDT:USDT │ 8 │ -1.76 │ -52.098 │ -5.21 │ 11:38:00 │ 6 0 2 75.0 │ -│ TOTAL │ 77 │ 0.22 │ 54.774 │ 5.48 │ 22:12:00 │ 67 0 10 87.0 │ -└───────────────┴────────┴──────────────┴─────────────────┴──────────────┴─────────────────┴────────────────────────┘ - LEFT OPEN TRADES REPORT -┏━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ -┃ Pair ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ -┡━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ -│ BTC/USDT:USDT │ 1 │ -4.14 │ -9.930 │ -0.99 │ 17 days, 8:00:00 │ 0 0 1 0 │ -│ ETC/USDT:USDT │ 1 │ -4.24 │ -15.365 │ -1.54 │ 10:40:00 │ 0 0 1 0 │ -│ DOT/USDT:USDT │ 1 │ -5.29 │ -19.125 │ -1.91 │ 11:30:00 │ 0 0 1 0 │ -│ TOTAL │ 3 │ -4.56 │ -44.420 │ -4.44 │ 6 days, 2:03:00 │ 0 0 3 0 │ -└───────────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┘ - ENTER TAG STATS -┏━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ -┃ Enter Tag ┃ Entries ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ -┡━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ -│ OTHER │ 77 │ 0.22 │ 54.774 │ 5.48 │ 22:12:00 │ 67 0 10 87.0 │ -│ TOTAL │ 77 │ 0.22 │ 54.774 │ 5.48 │ 22:12:00 │ 67 0 10 87.0 │ -└───────────┴─────────┴──────────────┴─────────────────┴──────────────┴──────────────┴────────────────────────┘ - EXIT REASON STATS -┏━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ -┃ Exit Reason ┃ Exits ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ -┡━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ -│ roi │ 67 │ 1.05 │ 242.179 │ 24.22 │ 15:49:00 │ 67 0 0 100 │ -│ exit_signal │ 4 │ -2.23 │ -31.217 │ -3.12 │ 1 day, 8:38:00 │ 0 0 4 0 │ -│ force_exit │ 3 │ -4.56 │ -44.420 │ -4.44 │ 6 days, 2:03:00 │ 0 0 3 0 │ -│ stop_loss │ 3 │ -10.14 │ -111.768 │ -11.18 │ 1 day, 3:05:00 │ 0 0 3 0 │ -│ TOTAL │ 77 │ 0.22 │ 54.774 │ 5.48 │ 22:12:00 │ 67 0 10 87.0 │ -└─────────────┴───────┴──────────────┴─────────────────┴──────────────┴─────────────────┴────────────────────────┘ - MIXED TAG STATS -┏━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ -┃ Enter Tag ┃ Exit Reason ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ -┡━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ -│ │ roi │ 67 │ 1.05 │ 242.179 │ 24.22 │ 15:49:00 │ 67 0 0 100 │ -│ │ exit_signal │ 4 │ -2.23 │ -31.217 │ -3.12 │ 1 day, 8:38:00 │ 0 0 4 0 │ -│ │ force_exit │ 3 │ -4.56 │ -44.420 │ -4.44 │ 6 days, 2:03:00 │ 0 0 3 0 │ -│ │ stop_loss │ 3 │ -10.14 │ -111.768 │ -11.18 │ 1 day, 3:05:00 │ 0 0 3 0 │ -│ TOTAL │ │ 77 │ 0.22 │ 54.774 │ 5.48 │ 22:12:00 │ 67 0 10 87.0 │ -└───────────┴─────────────┴────────┴──────────────┴─────────────────┴──────────────┴─────────────────┴────────────────────────┘ - SUMMARY METRICS -┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -┃ Metric ┃ Value ┃ -┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ -│ Backtesting from │ 2025-07-01 00:00:00 │ -│ Backtesting to │ 2025-08-01 00:00:00 │ -│ Trading Mode │ Isolated Futures │ -│ Max open trades │ 3 │ -│ │ │ -│ Total/Daily Avg Trades │ 77 / 2.48 │ -│ Starting balance │ 1000 USDT │ -│ Final balance │ 1054.669 USDT │ -│ Absolute profit │ 54.669 USDT │ -│ Total profit % │ 5.47% │ -│ CAGR % │ 87.14% │ -│ Sortino │ 2.46 │ -│ Sharpe │ 3.73 │ -│ Calmar │ 40.81 │ -│ SQN │ 0.69 │ -│ Profit factor │ 1.29 │ -│ Expectancy (Ratio) │ 0.71 (0.04) │ -│ Avg. daily profit │ 1.764 USDT │ -│ Avg. stake amount │ 345.251 USDT │ -│ Total trade volume │ 53352.96 USDT │ -│ │ │ -│ Long / Short trades │ 67 / 10 │ -│ Long / Short profit % │ 8.93% / -3.46% │ -│ Long / Short profit USDT │ 89.262 / -34.593 │ -│ │ │ -│ Best Pair │ LTC/USDT:USDT 5.62% │ -│ Worst Pair │ ADA/USDT:USDT -5.21% │ -│ Best trade │ ETC/USDT:USDT 2.00% │ -│ Worst trade │ ADA/USDT:USDT -10.17% │ -│ Best day │ 26.931 USDT │ -│ Worst day │ -47.741 USDT │ -│ Days win/draw/lose │ 20 / 6 / 5 │ -│ Min/Max/Avg. Duration Winners │ 0d 00:35 / 5d 18:15 / 0d 15:49 │ -│ Min/Max/Avg. Duration Losers │ 0d 10:40 / 17d 08:00 / 2d 17:00 │ -│ Max Consecutive Wins / Loss │ 36 / 3 │ -│ Rejected Entry signals │ 258 │ -│ Entry/Exit Timeouts │ 0 / 0 │ -│ │ │ -│ Min/Max balance realized │ 1003.168 USDT / 1149.577 USDT │ -│ Min/Max balance unrealized │ 1000 USDT / 1149.577 USDT │ -│ Min/Max balance dates │ 2025-07-01 00:05:00 / 2025-07-22 15:15:00 │ -│ Max % of account underwater │ 8.26% │ -│ Absolute drawdown │ 94.908 USDT (8.26%) │ -│ Drawdown duration │ 9 days 08:50:00 │ -│ Profit at drawdown start │ 149.577 USDT │ -│ Profit at drawdown end │ 54.669 USDT │ -│ Drawdown start │ 2025-07-22 15:10:00 │ -│ Drawdown end │ 2025-08-01 00:00:00 │ -│ Market change │ 30.51% │ -└───────────────────────────────┴───────────────────────────────────────────┘ + BACKTESTING REPORT +┏━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Pair ┃ Trades ┃ Avg Profit % ┃ Tot Profit ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ +┡━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ LTC/USDT:USDT │ 16 │ 1.01 │ 56.882 │ 5.69 │ 16:16:00 │ 16 0 0 100 │ +│ ETC/USDT:USDT │ 12 │ 0.73 │ 31.513 │ 3.15 │ 9:55:00 │ 11 0 1 91.7 │ +│ ETH/USDT:USDT │ 8 │ 0.69 │ 18.659 │ 1.87 │ 1 day, 13:55:00 │ 7 0 1 87.5 │ +│ XLM/USDT:USDT │ 10 │ 0.3 │ 10.694 │ 1.07 │ 12:08:00 │ 9 0 1 90.0 │ +│ BTC/USDT:USDT │ 8 │ 0.22 │ 7.502 │ 0.75 │ 3 days, 1:24:00 │ 6 0 2 75.0 │ +│ XRP/USDT:USDT │ 9 │ -0.13 │ -6.837 │ -0.68 │ 21:18:00 │ 8 0 1 88.9 │ +│ DOT/USDT:USDT │ 6 │ -0.39 │ -9.169 │ -0.92 │ 5:35:00 │ 4 0 2 66.7 │ +│ ADA/USDT:USDT │ 8 │ -1.75 │ -52.089 │ -5.21 │ 11:38:00 │ 6 0 2 75.0 │ +│ TOTAL │ 77 │ 0.23 │ 57.157 │ 5.72 │ 22:12:00 │ 67 0 10 87.0 │ +└───────────────┴────────┴──────────────┴─────────────┴──────────────┴─────────────────┴────────────────────────┘ + LEFT OPEN TRADES REPORT +┏━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Pair ┃ Trades ┃ Avg Profit % ┃ Tot Profit ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ +┡━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ BTC/USDT:USDT │ 1 │ -4.14 │ -9.930 │ -0.99 │ 17 days, 8:00:00 │ 0 0 1 0 │ +│ ETC/USDT:USDT │ 1 │ -4.24 │ -15.365 │ -1.54 │ 10:40:00 │ 0 0 1 0 │ +│ DOT/USDT:USDT │ 1 │ -5.29 │ -19.166 │ -1.92 │ 11:30:00 │ 0 0 1 0 │ +│ TOTAL │ 3 │ -4.56 │ -44.461 │ -4.45 │ 6 days, 2:03:00 │ 0 0 3 0 │ +└───────────────┴────────┴──────────────┴─────────────┴──────────────┴──────────────────┴────────────────────────┘ + ENTER TAG STATS +┏━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Enter Tag ┃ Entries ┃ Avg Profit % ┃ Tot Profit ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ +┡━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ OTHER │ 77 │ 0.23 │ 57.157 │ 5.72 │ 22:12:00 │ 67 0 10 87.0 │ +│ TOTAL │ 77 │ 0.23 │ 57.157 │ 5.72 │ 22:12:00 │ 67 0 10 87.0 │ +└───────────┴─────────┴──────────────┴─────────────┴──────────────┴──────────────┴────────────────────────┘ + EXIT REASON STATS +┏━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Exit Reason ┃ Exits ┃ Avg Profit % ┃ Tot Profit ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ +┡━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ roi │ 67 │ 1.06 │ 245.117 │ 24.51 │ 15:49:00 │ 67 0 0 100 │ +│ exit_signal │ 4 │ -2.23 │ -31.226 │ -3.12 │ 1 day, 8:38:00 │ 0 0 4 0 │ +│ force_exit │ 3 │ -4.56 │ -44.461 │ -4.45 │ 6 days, 2:03:00 │ 0 0 3 0 │ +│ stop_loss │ 3 │ -10.14 │ -112.273 │ -11.23 │ 1 day, 3:05:00 │ 0 0 3 0 │ +│ TOTAL │ 77 │ 0.23 │ 57.157 │ 5.72 │ 22:12:00 │ 67 0 10 87.0 │ +└─────────────┴───────┴──────────────┴─────────────┴──────────────┴─────────────────┴────────────────────────┘ + MIXED TAG STATS +┏━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Enter Tag ┃ Exit Reason ┃ Trades ┃ Avg Profit % ┃ Tot Profit ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ +┡━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ │ roi │ 67 │ 1.06 │ 245.117 │ 24.51 │ 15:49:00 │ 67 0 0 100 │ +│ │ exit_signal │ 4 │ -2.23 │ -31.226 │ -3.12 │ 1 day, 8:38:00 │ 0 0 4 0 │ +│ │ force_exit │ 3 │ -4.56 │ -44.461 │ -4.45 │ 6 days, 2:03:00 │ 0 0 3 0 │ +│ │ stop_loss │ 3 │ -10.14 │ -112.273 │ -11.23 │ 1 day, 3:05:00 │ 0 0 3 0 │ +│ TOTAL │ │ 77 │ 0.23 │ 57.157 │ 5.72 │ 22:12:00 │ 67 0 10 87.0 │ +└───────────┴─────────────┴────────┴──────────────┴─────────────┴──────────────┴─────────────────┴────────────────────────┘ + SUMMARY METRICS +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Metric ┃ Value ┃ +┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ Backtesting from │ 2025-07-01 00:00:00 │ +│ Backtesting to │ 2025-08-01 00:00:00 │ +│ Trading Mode │ Isolated Futures │ +│ Max open trades │ 3 │ +│ │ │ +│ Total/Daily Avg Trades │ 77 / 2.48 │ +│ Starting balance │ 1000 USDT │ +│ Final balance │ 1057.157 USDT │ +│ Absolute profit │ 57.157 USDT │ +│ Total profit % │ 5.72% │ +│ CAGR % │ 92.41% │ +│ Sharpe (closed trades) │ 3.89 │ +│ Sortino (closed trades) │ 2.57 │ +│ Calmar (closed trades) │ 43.03 │ +│ SQN │ 0.71 │ +│ Profit factor │ 1.30 │ +│ Expectancy (Ratio) │ 0.74 (0.04) │ +│ Avg. daily profit │ 1.844 USDT │ +│ Avg. stake amount │ 345.478 USDT │ +│ Market change │ 30.51% │ +│ Total trade volume │ 53390.788 USDT │ +│ │ │ +│ Long / Short trades │ 67 / 10 │ +│ Long / Short profit % │ 9.19% / -3.48% │ +│ Long / Short profit USDT │ 91.940 / -34.783 │ +│ │ │ +│ Best Pair │ LTC/USDT:USDT 5.69% │ +│ Worst Pair │ ADA/USDT:USDT -5.21% │ +│ Best trade │ XRP/USDT:USDT 2.00% │ +│ Worst trade │ ADA/USDT:USDT -10.17% │ +│ Best day │ 27.031 USDT │ +│ Worst day │ -47.826 USDT │ +│ Days win/draw/lose │ 20 / 6 / 5 │ +│ Min/Max/Avg. Duration Winners │ 0d 00:35 / 5d 18:15 / 0d 15:49 │ +│ Min/Max/Avg. Duration Losers │ 0d 10:40 / 17d 08:00 / 2d 17:00 │ +│ Max Consecutive Wins / Loss │ 36 / 3 │ +│ Rejected Entry signals │ 258 │ +│ Entry/Exit Timeouts │ 0 / 0 │ +│ │ │ +│ Min/Max balance (closed trades) │ 1003.205 USDT / 1151.425 USDT │ +│ Max % of account underwater │ 8.19% │ +│ Absolute drawdown │ 94.268 USDT (8.19%) │ +│ Drawdown duration │ 9 days 08:50:00 │ +│ Profit at drawdown start │ 151.425 USDT │ +│ Profit at drawdown end │ 57.157 USDT │ +│ Drawdown start │ 2025-07-22 15:10:00 │ +│ Drawdown end │ 2025-08-01 00:00:00 │ +│ │ │ +│ Wallet based Metrics │ │ +│ Min/Max balance (wallet balance) │ 1000 USDT / 1151.425 USDT │ +│ Min/Max balance dates (wallet balance) │ 2025-07-01 00:05:00 / 2025-07-22 15:15:00 │ +│ Max % of account underwater (balance) │ 5.01% │ +│ Absolute drawdown (wallet balance) │ 54.76 USDT (4.76%) │ +│ Drawdown duration │ 7 days 20:35:00 │ +│ Profit at drawdown start │ 151.425 USDT │ +│ Profit at drawdown end │ 96.664 USDT │ +│ Drawdown start │ 2025-07-22 15:15:00 │ +│ Drawdown end │ 2025-07-30 11:50:00 │ +│ Sharpe (daily wallet balance) │ 4.42 │ +│ Sortino (daily wallet balance) │ 4.35 │ +│ Calmar (daily wallet balance) │ 136.07 │ +└────────────────────────────────────────┴───────────────────────────────────────────┘ Backtested 2025-07-01 00:00:00 -> 2025-08-01 00:00:00 | Max open trades : 3 - STRATEGY SUMMARY -┏━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┓ -┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ Drawdown ┃ -┡━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━┩ -│ SampleStrategy │ 77 │ 0.22 │ 54.774 │ 5.48 │ 22:12:00 │ 67 0 10 87.0 │ 94.647 USDT 8.23% │ -└────────────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────┴────────────────────────┴────────────────────┘ + STRATEGY SUMMARY +┏━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ +┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ Drawdown ┃ +┡━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩ +│ SampleStrategy │ 77 │ 0.23 │ 57.157 │ 5.72 │ 22:12:00 │ 67 0 10 87.0 │ 94.268 8.19% │ +└────────────────┴────────┴──────────────┴─────────────┴──────────────┴──────────────┴────────────────────────┴────────────────┘ + ``` ### Backtesting report table @@ -330,59 +343,72 @@ The last element of the backtest report is the summary metrics table. It contains key metrics about the performance of your strategy on backtesting data. ``` -┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -┃ Metric ┃ Value ┃ -┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ -│ Backtesting from │ 2025-07-01 00:00:00 │ -│ Backtesting to │ 2025-08-01 00:00:00 │ -│ Trading Mode │ Isolated Futures │ -│ Max open trades │ 3 │ -│ │ │ -│ Total/Daily Avg Trades │ 77 / 2.48 │ -│ Starting balance │ 1000 USDT │ -│ Final balance │ 1054.669 USDT │ -│ Absolute profit │ 54.669 USDT │ -│ Total profit % │ 5.47% │ -│ CAGR % │ 87.14% │ -│ Sortino │ 2.46 │ -│ Sharpe │ 3.73 │ -│ Calmar │ 40.81 │ -│ SQN │ 0.69 │ -│ Profit factor │ 1.29 │ -│ Expectancy (Ratio) │ 0.71 (0.04) │ -│ Avg. daily profit │ 1.764 USDT │ -│ Avg. stake amount │ 345.251 USDT │ -│ Total trade volume │ 53352.96 USDT │ -│ │ │ -│ Long / Short trades │ 67 / 10 │ -│ Long / Short profit % │ 8.93% / -3.46% │ -│ Long / Short profit USDT │ 89.262 / -34.593 │ -│ │ │ -│ Best Pair │ LTC/USDT:USDT 5.62% │ -│ Worst Pair │ ADA/USDT:USDT -5.21% │ -│ Best trade │ ETC/USDT:USDT 2.00% │ -│ Worst trade │ ADA/USDT:USDT -10.17% │ -│ Best day │ 26.931 USDT │ -│ Worst day │ -47.741 USDT │ -│ Days win/draw/lose │ 20 / 6 / 5 │ -│ Min/Max/Avg. Duration Winners │ 0d 00:35 / 5d 18:15 / 0d 15:49 │ -│ Min/Max/Avg. Duration Losers │ 0d 10:40 / 17d 08:00 / 2d 17:00 │ -│ Max Consecutive Wins / Loss │ 36 / 3 │ -│ Rejected Entry signals │ 258 │ -│ Entry/Exit Timeouts │ 0 / 0 │ -│ │ │ -│ Min/Max balance realized │ 1003.168 USDT / 1149.577 USDT │ -│ Min/Max balance unrealized │ 1000 USDT / 1149.577 USDT │ -│ Min/Max balance dates │ 2025-07-01 00:05:00 / 2025-07-22 15:15:00 │ -│ Max % of account underwater │ 8.26% │ -│ Absolute drawdown │ 94.908 USDT (8.26%) │ -│ Drawdown duration │ 9 days 08:50:00 │ -│ Profit at drawdown start │ 149.577 USDT │ -│ Profit at drawdown end │ 54.669 USDT │ -│ Drawdown start │ 2025-07-22 15:10:00 │ -│ Drawdown end │ 2025-08-01 00:00:00 │ -│ Market change │ 30.51% │ -└───────────────────────────────┴───────────────────────────────────────────┘ + SUMMARY METRICS +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Metric ┃ Value ┃ +┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ Backtesting from │ 2025-07-01 00:00:00 │ +│ Backtesting to │ 2025-08-01 00:00:00 │ +│ Trading Mode │ Isolated Futures │ +│ Max open trades │ 3 │ +│ │ │ +│ Total/Daily Avg Trades │ 77 / 2.48 │ +│ Starting balance │ 1000 USDT │ +│ Final balance │ 1057.157 USDT │ +│ Absolute profit │ 57.157 USDT │ +│ Total profit % │ 5.72% │ +│ CAGR % │ 92.41% │ +│ Sharpe (closed trades) │ 3.89 │ +│ Sortino (closed trades) │ 2.57 │ +│ Calmar (closed trades) │ 43.03 │ +│ SQN │ 0.71 │ +│ Profit factor │ 1.30 │ +│ Expectancy (Ratio) │ 0.74 (0.04) │ +│ Avg. daily profit │ 1.844 USDT │ +│ Avg. stake amount │ 345.478 USDT │ +│ Market change │ 30.51% │ +│ Total trade volume │ 53390.788 USDT │ +│ │ │ +│ Long / Short trades │ 67 / 10 │ +│ Long / Short profit % │ 9.19% / -3.48% │ +│ Long / Short profit USDT │ 91.940 / -34.783 │ +│ │ │ +│ Best Pair │ LTC/USDT:USDT 5.69% │ +│ Worst Pair │ ADA/USDT:USDT -5.21% │ +│ Best trade │ XRP/USDT:USDT 2.00% │ +│ Worst trade │ ADA/USDT:USDT -10.17% │ +│ Best day │ 27.031 USDT │ +│ Worst day │ -47.826 USDT │ +│ Days win/draw/lose │ 20 / 6 / 5 │ +│ Min/Max/Avg. Duration Winners │ 0d 00:35 / 5d 18:15 / 0d 15:49 │ +│ Min/Max/Avg. Duration Losers │ 0d 10:40 / 17d 08:00 / 2d 17:00 │ +│ Max Consecutive Wins / Loss │ 36 / 3 │ +│ Rejected Entry signals │ 258 │ +│ Entry/Exit Timeouts │ 0 / 0 │ +│ │ │ +│ Min/Max balance (closed trades) │ 1003.205 USDT / 1151.425 USDT │ +│ Max % of account underwater │ 8.19% │ +│ Absolute drawdown │ 94.268 USDT (8.19%) │ +│ Drawdown duration │ 9 days 08:50:00 │ +│ Profit at drawdown start │ 151.425 USDT │ +│ Profit at drawdown end │ 57.157 USDT │ +│ Drawdown start │ 2025-07-22 15:10:00 │ +│ Drawdown end │ 2025-08-01 00:00:00 │ +│ │ │ +│ Wallet based Metrics │ │ +│ Min/Max balance (wallet balance) │ 1000 USDT / 1151.425 USDT │ +│ Min/Max balance dates (wallet balance) │ 2025-07-01 00:05:00 / 2025-07-22 15:15:00 │ +│ Max % of account underwater (balance) │ 5.01% │ +│ Absolute drawdown (wallet balance) │ 54.76 USDT (4.76%) │ +│ Drawdown duration │ 7 days 20:35:00 │ +│ Profit at drawdown start │ 151.425 USDT │ +│ Profit at drawdown end │ 96.664 USDT │ +│ Drawdown start │ 2025-07-22 15:15:00 │ +│ Drawdown end │ 2025-07-30 11:50:00 │ +│ Sharpe (daily wallet balance) │ 4.42 │ +│ Sortino (daily wallet balance) │ 4.35 │ +│ Calmar (daily wallet balance) │ 136.07 │ +└────────────────────────────────────────┴───────────────────────────────────────────┘ ``` - `Backtesting from` / `Backtesting to`: Backtesting range (usually defined with the `--timerange` option). From 09106ecbe09c4dc8d6fddf07209eac2e52b77a5c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 10:06:59 +0200 Subject: [PATCH 20/49] chore: further reorder backtest output --- freqtrade/optimize/optimize_reports/bt_output.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/freqtrade/optimize/optimize_reports/bt_output.py b/freqtrade/optimize/optimize_reports/bt_output.py index dbb3eff82..977d402e5 100644 --- a/freqtrade/optimize/optimize_reports/bt_output.py +++ b/freqtrade/optimize/optimize_reports/bt_output.py @@ -300,8 +300,10 @@ def text_table_add_metrics(strat_results: dict) -> None: ] wallet_stats = strat_results.get("wallet_stats", {}) if wallet_stats: - wallet_metrics.extend( + drawdown_metrics.extend( [ + __EMPTY_LINE, # Empty line to improve readability + (Text("Wallet based Metrics", style="bold"), ""), ( "Min/Max balance (wallet balance)", f"{fmt_coin(wallet_stats['low_balance'], stake)} / " @@ -317,8 +319,6 @@ def text_table_add_metrics(strat_results: dict) -> None: # Assume that if sharpe is there, all others are there as well. drawdown_metrics.extend( [ - __EMPTY_LINE, # Empty line to improve readability - (Text("Wallet based Metrics", style="bold"), ""), ( "Max % of account underwater (balance)", f"{wallet_stats['max_relative_drawdown']:.2%}", @@ -496,7 +496,6 @@ def text_table_add_metrics(strat_results: dict) -> None: *entry_adjustment_metrics, __EMPTY_LINE, # Empty line to improve readability *wallet_metrics, - __EMPTY_LINE, # Empty line to improve readability *drawdown_metrics, ] print_rich_table(metrics, ["Metric", "Value"], summary="SUMMARY METRICS", justify="left") From 45d4c5d036658c612cdcb74f654b34eba96981b3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 10:07:05 +0200 Subject: [PATCH 21/49] docs: update backtesting docs --- docs/backtesting.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index 5c758880b..00776ed66 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -421,16 +421,14 @@ It contains key metrics about the performance of your strategy on backtesting da - `Total profit %`: Total profit. Aligned to the `TOTAL` row's `Tot Profit %` from the first table. Calculated as `(End capital − Starting capital) / Starting capital`. - `CAGR %`: Compound annual growth rate. - `Sharpe (closed trades)`: Annualized Sharpe ratio including only closed trades (ignoring open trades with profits or losses). -- `Sharpe (wallet balance)` Annualized Sharpe ratio calculation but including unrealized profits. - `Sortino (closed trades)`: Annualized Sortino ratio including only closed trades (ignoring open trades with profits or losses). -- `Sortino (wallet balance)` Annualized Sortino ratio calculation but including unrealized profits. - `Calmar (closed trades)`: Annualized Calmar ratio including only closed trades (ignoring open trades with profits or losses). -- `Calmar (wallet balance)` Annualized Calmar ratio calculation but including unrealized profits. - `SQN`: System Quality Number (SQN) - by Van Tharp. - `Profit factor`: Sum of the profits of all winning trades divided by the sum of the losses of all losing trades. - `Expectancy (Ratio)`: Expectancy ratio, which is the average profit or loss per trade. A negative expectancy ratio means that your strategy is not profitable. - `Avg. daily profit`: Average profit per day, calculated as `(Total Profit / Backtest Days)`. - `Avg. stake amount`: Average stake amount, either `stake_amount` or the average when using dynamic stake amount. +- `Market change`: Change of the market during the backtest period. Calculated as the average of all pairs' changes from the first to the last candle using the "close" column. - `Total trade volume`: Volume generated on the exchange to reach the above profit. - `Long / Short trades`: Split long/short trade counts (only shown when short trades were made). - `Long / Short profit %`: Profit percentage for long and short trades (only shown when short trades were made). @@ -445,15 +443,20 @@ It contains key metrics about the performance of your strategy on backtesting da - `Rejected Entry signals`: Trade entry signals that could not be acted upon due to `max_open_trades` being reached. - `Entry/Exit Timeouts`: Entry/exit orders which did not fill (only applicable if custom pricing is used). - `Min/Max balance (closed trades)`: Lowest and Highest Wallet balance during the backtest period based on closed trades trades. -- `Min/Max balance (wallet balance)`: Lowest and Highest Wallet balance during the backtest period - including capital tied in open trades. -- `Min/Max balance dates (wallet balance)`: Dates when the minimum and maximum unrealized balance occurred. - `Max % of account underwater`: Maximum percentage your account has decreased from the top since the simulation started. Calculated as the maximum of `(Max Balance - Current Balance) / (Max Balance)`. - `Absolute drawdown`: Maximum absolute drawdown experienced, including percentage relative to the account calculated as `(Absolute Drawdown) / (DrawdownHigh + startingBalance)`.. - `Absolute drawdown (wallet balance)`: Maximum absolute drawdown experienced based on the unrealized balance, including percentage relative to the account calculated as `(Absolute Drawdown) / (DrawdownHigh + startingBalance)`. - `Drawdown duration`: Duration of the largest drawdown period. - `Profit at drawdown start` / `Profit at drawdown end`: Profit at the beginning and end of the largest drawdown period. - `Drawdown start` / `Drawdown end`: Start and end datetime for the largest drawdown (can also be visualized via the `plot-dataframe` sub-command). -- `Market change`: Change of the market during the backtest period. Calculated as the average of all pairs' changes from the first to the last candle using the "close" column. +- `Min/Max balance (wallet balance)`: Lowest and Highest Wallet balance during the backtest period - including capital tied in open trades. +- `Min/Max balance dates (wallet balance)`: Dates when the minimum and maximum unrealized balance occurred. +- `Sharpe (wallet balance)` Annualized Sharpe ratio calculation including unrealized profits. +- `Sortino (wallet balance)` Annualized Sortino ratio calculation including unrealized profits. +- `Calmar (wallet balance)` Annualized Calmar ratio calculation including unrealized profits. + +!!! Tip "Wallet based Metrics" + The metrics under the "Wallet based Metrics" section are calculated based on the unrealized balance, which includes the capital tied in open trades. This provides a more comprehensive view of the strategy's performance, as it accounts for both realized and unrealized profits and losses. ### Daily / Weekly / Monthly / Yearly breakdown From c60d96922db23057bdda67f33374ed09a73b4d47 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 10:38:44 +0200 Subject: [PATCH 22/49] chore: improve type safety --- freqtrade/optimize/optimize_reports/bt_output.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/optimize_reports/bt_output.py b/freqtrade/optimize/optimize_reports/bt_output.py index 977d402e5..f42054c65 100644 --- a/freqtrade/optimize/optimize_reports/bt_output.py +++ b/freqtrade/optimize/optimize_reports/bt_output.py @@ -226,7 +226,7 @@ def text_table_add_metrics(strat_results: dict) -> None: else [] ) - drawdown_metrics = [] + drawdown_metrics: list[tuple[str | Text, str | Text]] = [] if "max_relative_drawdown" in strat_results: # Compatibility to show old hyperopt results drawdown_metrics.append( From 33211c8eb1aa5437c63a2ccc3ee8d77db0cc21aa Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 13:02:51 +0200 Subject: [PATCH 23/49] chore: don't use deprecated resmapling frequency --- freqtrade/optimize/optimize_reports/optimize_reports.py | 6 +++--- tests/optimize/test_optimize_reports.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index a5d38b850..15d25a19c 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -340,7 +340,7 @@ def generate_strategy_comparison(bt_stats: dict) -> list[dict]: def _get_resample_from_period(period: str) -> str: if period == "day": - return "1d" + return "1D" if period == "week": # Weekly defaulting to Monday. return "1W-MON" @@ -530,8 +530,8 @@ def generate_daily_stats(results: DataFrame) -> dict[str, Any]: "losing_days": 0, "daily_profit_list": [], } - daily_profit_rel = results.resample("1d", on="close_date")["profit_ratio"].sum() - daily_profit = results.resample("1d", on="close_date")["profit_abs"].sum().round(10) + daily_profit_rel = results.resample("1D", on="close_date")["profit_ratio"].sum() + daily_profit = results.resample("1D", on="close_date")["profit_abs"].sum().round(10) worst_rel = min(daily_profit_rel) best_rel = max(daily_profit_rel) worst = min(daily_profit) diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index c54dea689..fcf5abffd 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -713,7 +713,7 @@ def test_generate_periodic_breakdown_stats(testdatadir): def test__get_resample_from_period(): - assert _get_resample_from_period("day") == "1d" + assert _get_resample_from_period("day") == "1D" assert _get_resample_from_period("week") == "1W-MON" assert _get_resample_from_period("month") == "1ME" assert _get_resample_from_period("weekday") == "weekday" From f6f0180fc1f7660ddf3d305b38cf365d265a7e53 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 13:12:09 +0200 Subject: [PATCH 24/49] fix: use more stable "date to ms" method --- freqtrade/data/btanalysis/bt_fileutils.py | 4 ++-- freqtrade/data/history/datahandlers/jsondatahandler.py | 4 ++-- freqtrade/rpc/rpc.py | 4 ++-- tests/conftest.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/freqtrade/data/btanalysis/bt_fileutils.py b/freqtrade/data/btanalysis/bt_fileutils.py index a97d5bef3..2e6b23662 100644 --- a/freqtrade/data/btanalysis/bt_fileutils.py +++ b/freqtrade/data/btanalysis/bt_fileutils.py @@ -308,7 +308,7 @@ def get_backtest_market_change(filename: Path, include_ts: bool = True) -> pd.Da else: df = pd.read_feather(filename) if include_ts: - df.loc[:, "__date_ts"] = df.loc[:, "date"].astype(np.int64) // 1000 // 1000 + df.loc[:, "__date_ts"] = df.loc[:, "date"].dt.as_unit("ms").astype(np.int64) return df @@ -326,7 +326,7 @@ def get_backtest_wallet_change(filename: Path, strategy_name: str) -> pd.DataFra data = load_file_from_zip(filename, f"{filename.stem}_{strategy_name}_wallet.feather") df = pd.read_feather(BytesIO(data)) - df.loc[:, "__date_ts"] = df.loc[:, "date"].astype(np.int64) // 1000 // 1000 + df.loc[:, "__date_ts"] = df.loc[:, "date"].dt.as_unit("ms").astype(np.int64) return df except ValueError: pass diff --git a/freqtrade/data/history/datahandlers/jsondatahandler.py b/freqtrade/data/history/datahandlers/jsondatahandler.py index 1a33b3e2f..e2ab5c408 100644 --- a/freqtrade/data/history/datahandlers/jsondatahandler.py +++ b/freqtrade/data/history/datahandlers/jsondatahandler.py @@ -35,8 +35,8 @@ class JsonDataHandler(IDataHandler): filename = self._pair_data_filename(self._datadir, pair, timeframe, candle_type) self.create_dir_if_needed(filename) _data = data.copy() - # Convert date to int - _data["date"] = _data["date"].astype(np.int64) // 1000 // 1000 + # Convert date to int (milliseconds) + _data["date"] = _data["date"].dt.as_unit("ms").astype(np.int64) # Reset index, select only appropriate columns and save as json _data.reset_index(drop=True).loc[:, self._columns].to_json( diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 63f00a22d..82c66de0c 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -794,7 +794,7 @@ class RPC: results = read_sql("wallet_history", con=Trade.session.bind, parse_dates=["timestamp"]) results = results.rename({"timestamp": "date"}, axis=1) - results.loc[:, "__date_ts"] = results.loc[:, "date"].astype("int64") // 1000 // 1000 + results.loc[:, "__date_ts"] = results.loc[:, "date"].dt.as_unit("ms").astype("int64") # Exclude non-bot managed for now results_filtered = results.loc[results["bot_managed"]] @@ -1536,7 +1536,7 @@ class RPC: df_cols = [col for col in dataframe_columns if col in cols_set] dataframe = dataframe.loc[:, df_cols] - dataframe.loc[:, "__date_ts"] = dataframe.loc[:, "date"].astype(int64) // 1000 // 1000 + dataframe.loc[:, "__date_ts"] = dataframe.loc[:, "date"].dt.as_unit("ms").astype(int64) # Move signal close to separate column when signal for easy plotting for sig_type in signals.keys(): if sig_type in dataframe.columns: diff --git a/tests/conftest.py b/tests/conftest.py index 93d34fe18..a92144659 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -207,7 +207,7 @@ def generate_test_data( def generate_test_data_raw(timeframe: str, size: int, start: str = "2020-07-05", random_seed=42): """Generates data in the ohlcv format used by ccxt""" df = generate_test_data(timeframe, size, start, random_seed) - df["date"] = df.loc[:, "date"].astype(np.int64) // 1000 // 1000 + df["date"] = df.loc[:, "date"].dt.as_unit("ms").astype(np.int64) return list(list(x) for x in zip(*(df[x].values.tolist() for x in df.columns), strict=False)) From 79ea1ba1d58372038db53182f87a3ac3c6cdd02b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 19:33:28 +0200 Subject: [PATCH 25/49] fix: use is_string_dtype to check for object/string types --- freqtrade/freqai/data_drawer.py | 2 +- freqtrade/freqai/data_kitchen.py | 6 +++--- freqtrade/freqai/freqai_interface.py | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/freqtrade/freqai/data_drawer.py b/freqtrade/freqai/data_drawer.py index 960c822b5..9e9381937 100644 --- a/freqtrade/freqai/data_drawer.py +++ b/freqtrade/freqai/data_drawer.py @@ -361,7 +361,7 @@ class FreqaiDataDrawer: label_loc = df.columns.get_loc(label) pred_label_loc = predictions.columns.get_loc(label) df.iloc[-1, label_loc] = predictions.iloc[-1, pred_label_loc] - if df[label].dtype == object: + if pd.api.types.is_string_dtype(df[label].dtype): continue label_mean_loc = df.columns.get_loc(f"{label}_mean") label_std_loc = df.columns.get_loc(f"{label}_std") diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index df7c827f9..9f04e0ca4 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -435,7 +435,7 @@ class FreqaiDataKitchen: for label in predictions.columns: append_dict[label] = predictions[label] - if predictions[label].dtype == object: + if pd.api.types.is_string_dtype(predictions[label].dtype): continue if "labels_mean" in self.data and label in self.data["labels_mean"]: append_dict[f"{label}_mean"] = self.data["labels_mean"][label] @@ -879,7 +879,7 @@ class FreqaiDataKitchen: self.data["labels_mean"], self.data["labels_std"] = {}, {} for label in self.data_dictionary["train_labels"].columns: - if self.data_dictionary["train_labels"][label].dtype == object: + if pd.api.types.is_string_dtype(self.data_dictionary["train_labels"][label].dtype): continue f = spy.stats.norm.fit(self.data_dictionary["train_labels"][label]) self.data["labels_mean"][label], self.data["labels_std"][label] = f[0], f[1] @@ -905,7 +905,7 @@ class FreqaiDataKitchen: self.find_labels(dataframe) for key in self.label_list: - if dataframe[key].dtype == object: + if pd.api.types.is_string_dtype(dataframe[key].dtype): self.unique_classes[key] = dataframe[key].dropna().unique() if self.unique_classes: diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index 1ba58d3e8..2e3e74400 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -676,7 +676,7 @@ class IFreqaiModel(ABC): self.set_start_dry_live_date(strat_df) for label in hist_preds_df.columns: - if hist_preds_df[label].dtype == object: + if pd.api.types.is_string_dtype(hist_preds_df[label].dtype): continue hist_preds_df[f"{label}_mean"] = 0 hist_preds_df[f"{label}_std"] = 0 @@ -706,7 +706,7 @@ class IFreqaiModel(ABC): num_candles = self.freqai_info.get("fit_live_predictions_candles", 100) dk.data["labels_mean"], dk.data["labels_std"] = {}, {} for label in full_labels: - if self.dd.historic_predictions[dk.pair][label].dtype == object: + if pd.api.types.is_string_dtype(self.dd.historic_predictions[dk.pair][label].dtype): continue f = spy.stats.norm.fit(self.dd.historic_predictions[dk.pair][label].tail(num_candles)) dk.data["labels_mean"][label], dk.data["labels_std"][label] = f[0], f[1] @@ -896,7 +896,7 @@ class IFreqaiModel(ABC): ] self.fit_live_predictions(self.dk, self.dk.pair) for label in label_columns: - if dk.full_df[label].dtype == object: + if pd.api.types.is_string_dtype(dk.full_df[label].dtype): continue if "labels_mean" in self.dk.data: dk.full_df.at[index, f"{label}_mean"] = self.dk.data["labels_mean"][ From 51d61bc6a8d2e2cd8013fae306883da1a0ea90ef Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 19:14:33 +0200 Subject: [PATCH 26/49] chore: don't use microsecond precision for --- freqtrade/util/__init__.py | 2 ++ freqtrade/util/datetime_helpers.py | 7 +++++++ tests/strategy/test_interface.py | 9 +++++---- tests/util/test_datetime_helpers.py | 8 ++++++-- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/freqtrade/util/__init__.py b/freqtrade/util/__init__.py index 06deb3ce0..0e9c1ac12 100644 --- a/freqtrade/util/__init__.py +++ b/freqtrade/util/__init__.py @@ -3,6 +3,7 @@ from freqtrade.util.datetime_helpers import ( dt_from_ts, dt_humanize_delta, dt_now, + dt_now_no_micro, dt_ts, dt_ts_def, dt_ts_none, @@ -39,6 +40,7 @@ __all__ = [ "dt_from_ts", "dt_humanize_delta", "dt_now", + "dt_now_no_micro", "dt_ts", "dt_ts_def", "dt_ts_none", diff --git a/freqtrade/util/datetime_helpers.py b/freqtrade/util/datetime_helpers.py index b6535db5d..55bf29419 100644 --- a/freqtrade/util/datetime_helpers.py +++ b/freqtrade/util/datetime_helpers.py @@ -12,6 +12,13 @@ def dt_now() -> datetime: return datetime.now(UTC) +def dt_now_no_micro() -> datetime: + """Return the current datetime in UTC without microseconds. + Should not be used outside of tests. + """ + return dt_now().replace(microsecond=0) + + def dt_utc( year: int, month: int, diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index f64c2c3cb..bdae9601c 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -22,6 +22,7 @@ from freqtrade.strategy.parameters import ( ) from freqtrade.strategy.strategy_validation import StrategyResultValidator from freqtrade.util import dt_now +from freqtrade.util.datetime_helpers import dt_now_no_micro from tests.conftest import CURRENT_TEST_STRATEGY, TRADE_SIDES, log_has, log_has_re from .strats.strategy_test_v3 import StrategyTestV3 @@ -33,7 +34,7 @@ _STRATEGY.dp = DataProvider({}, None, None) def test_returns_latest_signal(ohlcv_history): - ohlcv_history.loc[1, "date"] = dt_now() + ohlcv_history.loc[1, "date"] = dt_now_no_micro() # Take a copy to correctly modify the call mocked_history = ohlcv_history.copy() mocked_history["enter_long"] = 0 @@ -160,7 +161,7 @@ def test_get_signal_exception_valueerror(mocker, caplog, ohlcv_history): def test_get_signal_old_dataframe(default_conf, mocker, caplog, ohlcv_history): # default_conf defines a 5m interval. we check interval * 2 + 5m # this is necessary as the last candle is removed (partial candles) by default - ohlcv_history.loc[1, "date"] = dt_now() - timedelta(minutes=16) + ohlcv_history.loc[1, "date"] = dt_now_no_micro() - timedelta(minutes=16) # Take a copy to correctly modify the call mocked_history = ohlcv_history.copy() mocked_history["exit_long"] = 0 @@ -179,7 +180,7 @@ def test_get_signal_old_dataframe(default_conf, mocker, caplog, ohlcv_history): def test_get_signal_no_sell_column(default_conf, mocker, caplog, ohlcv_history): # default_conf defines a 5m interval. we check interval * 2 + 5m # this is necessary as the last candle is removed (partial candles) by default - ohlcv_history.loc[1, "date"] = dt_now() + ohlcv_history.loc[1, "date"] = dt_now_no_micro() # Take a copy to correctly modify the call mocked_history = ohlcv_history.copy() # Intentionally don't set sell column @@ -223,7 +224,7 @@ def test_ignore_expired_candle(default_conf): def test_assert_df_raise(mocker, caplog, ohlcv_history): - ohlcv_history.loc[1, "date"] = dt_now() - timedelta(minutes=16) + ohlcv_history.loc[1, "date"] = dt_now_no_micro() - timedelta(minutes=16) # Take a copy to correctly modify the call mocked_history = ohlcv_history.copy() mocked_history["sell"] = 0 diff --git a/tests/util/test_datetime_helpers.py b/tests/util/test_datetime_helpers.py index 9069b60c5..babe5b7b9 100644 --- a/tests/util/test_datetime_helpers.py +++ b/tests/util/test_datetime_helpers.py @@ -6,7 +6,9 @@ import time_machine from freqtrade.util import ( dt_floor_day, dt_from_ts, + dt_humanize_delta, dt_now, + dt_now_no_micro, dt_ts, dt_ts_def, dt_ts_none, @@ -16,15 +18,17 @@ from freqtrade.util import ( format_ms_time_det, shorten_date, ) -from freqtrade.util.datetime_helpers import dt_humanize_delta def test_dt_now(): - with time_machine.travel("2021-09-01 05:01:00 +00:00", tick=False) as t: + with time_machine.travel("2021-09-01 05:01:00.123 +00:00", tick=False) as t: now = datetime.now(UTC) assert dt_now() == now assert dt_ts() == int(now.timestamp() * 1000) assert dt_ts(now) == int(now.timestamp() * 1000) + assert dt_now().microsecond != 0.0 + assert dt_now_no_micro().microsecond == 0.0 + assert dt_now_no_micro() == now.replace(microsecond=0) t.shift(timedelta(hours=5)) assert dt_now() >= now From 12f37b757552e0034f3087f40634681a1e74e9fc Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2026 19:54:44 +0200 Subject: [PATCH 27/49] chore: more generic datetime selection --- freqtrade/rpc/rpc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 82c66de0c..37c097347 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -1546,7 +1546,7 @@ class RPC: # band-aid until this is fixed: # https://github.com/pandas-dev/pandas/issues/45836 - datetime_types = ["datetime", "datetime64", "datetime64[ns, UTC]"] + datetime_types = ["datetime", "datetime64", "datetimetz"] date_columns = dataframe.select_dtypes(include=datetime_types) for date_column in date_columns: # replace NaT with `None` From c9d4276c669db43413ebdbbbc8322facc2028ffa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 03:03:36 +0000 Subject: [PATCH 28/49] chore(deps-dev): bump ruff from 0.15.8 to 0.15.9 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.15.8 to 0.15.9. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.15.8...0.15.9) --- updated-dependencies: - dependency-name: ruff dependency-version: 0.15.9 dependency-type: direct:development update-type: version-update:semver-patch ... 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 8018da419..b3d6bdfc8 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,7 +6,7 @@ -r requirements-freqai-rl.txt -r docs/requirements-docs.txt -ruff==0.15.8 +ruff==0.15.9 mypy==1.20.0 pre-commit==4.5.1 pytest==9.0.2 From df9469d195aae457b077093f89d97db04b520eb4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 03:03:59 +0000 Subject: [PATCH 29/49] chore(deps): bump sqlalchemy from 2.0.48 to 2.0.49 Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.48 to 2.0.49. - [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-version: 2.0.49 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 f33fd73c2..5017203ef 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ technical==1.5.4 ccxt==4.5.47 cryptography==46.0.7 aiohttp==3.13.5 -SQLAlchemy==2.0.48 +SQLAlchemy==2.0.49 python-telegram-bot==22.7 # can't be hard-pinned due to telegram-bot pinning httpx with ~ httpx>=0.24.1 From 94e52f52414bff57071cdf45057e06237c145e0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 03:04:02 +0000 Subject: [PATCH 30/49] chore(deps): bump docker/login-action in the docker group Bumps the docker group with 1 update: [docker/login-action](https://github.com/docker/login-action). Updates `docker/login-action` from 4.0.0 to 4.1.0 - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/b45d80f862d83dbcd57f89517bcf500b2ab88fb2...4907a6ddec9925e35a0a9e82d7399ccc52663121) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: docker ... Signed-off-by: dependabot[bot] --- .github/workflows/devcontainer-build.yml | 2 +- .github/workflows/docker-build.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/devcontainer-build.yml b/.github/workflows/devcontainer-build.yml index 3cbc8ba6c..d29831375 100644 --- a/.github/workflows/devcontainer-build.yml +++ b/.github/workflows/devcontainer-build.yml @@ -31,7 +31,7 @@ jobs: with: persist-credentials: false - name: Login to GitHub Container Registry - uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: registry: ghcr.io username: ${{ github.actor }} diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 7dce79b6a..90cc7c629 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -59,7 +59,7 @@ jobs: uses: ./.github/actions/docker-tags - name: Login to Docker Hub - uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} @@ -183,13 +183,13 @@ jobs: uses: ./.github/actions/docker-tags - name: Login to Docker Hub - uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Login to github - uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: registry: ghcr.io username: ${{ github.actor }} From 2f8d82e0b09842c0d15f022c55bd9e1b93bb0a6a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 03:04:03 +0000 Subject: [PATCH 31/49] chore(deps): bump uvicorn from 0.42.0 to 0.43.0 Bumps [uvicorn](https://github.com/Kludex/uvicorn) from 0.42.0 to 0.43.0. - [Release notes](https://github.com/Kludex/uvicorn/releases) - [Changelog](https://github.com/Kludex/uvicorn/blob/main/docs/release-notes.md) - [Commits](https://github.com/Kludex/uvicorn/compare/0.42.0...0.43.0) --- updated-dependencies: - dependency-name: uvicorn dependency-version: 0.43.0 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 f33fd73c2..719156528 100644 --- a/requirements.txt +++ b/requirements.txt @@ -39,7 +39,7 @@ sdnotify==0.3.2 # API Server fastapi==0.135.3 pydantic==2.12.5 -uvicorn==0.42.0 +uvicorn==0.43.0 pyjwt==2.12.1 aiofiles==25.1.0 psutil==7.2.2 From 3da3290224138251953ab7f4215663f60b1cb1bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 03:04:11 +0000 Subject: [PATCH 32/49] chore(deps): bump technical from 1.5.4 to 1.6.0 Bumps [technical](https://github.com/freqtrade/technical) from 1.5.4 to 1.6.0. - [Release notes](https://github.com/freqtrade/technical/releases) - [Commits](https://github.com/freqtrade/technical/compare/1.5.4...1.6.0) --- updated-dependencies: - dependency-name: technical dependency-version: 1.6.0 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 f33fd73c2..66ec97438 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ numexpr==2.14.1 # Indicator libraries ft-pandas-ta==0.3.16 ta-lib==0.6.8 -technical==1.5.4 +technical==1.6.0 ccxt==4.5.47 cryptography==46.0.7 From a9b1fd219bea44f618e499cbd5f82715d31bde69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 03:04:23 +0000 Subject: [PATCH 33/49] chore(deps): bump ccxt from 4.5.47 to 4.5.48 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.5.47 to 4.5.48. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Commits](https://github.com/ccxt/ccxt/compare/v4.5.47...v4.5.48) --- updated-dependencies: - dependency-name: ccxt dependency-version: 4.5.48 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 f33fd73c2..d546be536 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ ft-pandas-ta==0.3.16 ta-lib==0.6.8 technical==1.5.4 -ccxt==4.5.47 +ccxt==4.5.48 cryptography==46.0.7 aiohttp==3.13.5 SQLAlchemy==2.0.48 From 895a9f351f6bea282bd61b4c49d0b81fb36b1e77 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 13 Apr 2026 06:32:28 +0200 Subject: [PATCH 34/49] 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 a32221ee3..f3f58d269 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,7 +26,7 @@ repos: - types-tabulate==0.10.0.20260308 - types-python-dateutil==2.9.0.20260402 - scipy-stubs==1.17.1.3 - - SQLAlchemy==2.0.48 + - SQLAlchemy==2.0.49 # stages: [push] - repo: https://github.com/charliermarsh/ruff-pre-commit From 187d06b5ba04fcb008f549022bd71ff2690d0139 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 13 Apr 2026 07:09:36 +0200 Subject: [PATCH 35/49] fix: use pd.notna to check for empty strings --- freqtrade/plot/plotting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 085a198ca..ed15c8e79 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -263,7 +263,7 @@ def plot_trades(fig, trades: pd.DataFrame) -> make_subplots: trades["desc"] = trades.apply( lambda row: ( f"{row['profit_ratio']:.2%}, " - + (f"{row['enter_tag']}, " if row["enter_tag"] is not None else "") + + (f"{row['enter_tag']}, " if pd.notna(row["enter_tag"]) else "") + f"{row['exit_reason']}, " + f"{row['trade_duration']} min" ), From 74ba9d76a216673996a560947745fe60ceb79735 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 13 Apr 2026 07:18:35 +0200 Subject: [PATCH 36/49] fix: use as_unit instead of int math --- freqtrade/rpc/rpc.py | 6 ++++-- tests/conftest.py | 2 +- tests/exchange/test_binance_public_data.py | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 37c097347..0b47ecf7c 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -11,7 +11,7 @@ from typing import TYPE_CHECKING, Any import psutil from dateutil.relativedelta import relativedelta from dateutil.tz import tzlocal -from numpy import inf, int64, isnan, mean, nan +from numpy import inf, isnan, mean, nan from pandas import DataFrame, NaT, read_sql from sqlalchemy import func, select @@ -1536,7 +1536,9 @@ class RPC: df_cols = [col for col in dataframe_columns if col in cols_set] dataframe = dataframe.loc[:, df_cols] - dataframe.loc[:, "__date_ts"] = dataframe.loc[:, "date"].dt.as_unit("ms").astype(int64) + dataframe.loc[:, "__date_ts"] = ( + dataframe.loc[:, "date"].dt.as_unit("ms").astype("int64") + ) # Move signal close to separate column when signal for easy plotting for sig_type in signals.keys(): if sig_type in dataframe.columns: diff --git a/tests/conftest.py b/tests/conftest.py index a92144659..46601ddfb 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -207,7 +207,7 @@ def generate_test_data( def generate_test_data_raw(timeframe: str, size: int, start: str = "2020-07-05", random_seed=42): """Generates data in the ohlcv format used by ccxt""" df = generate_test_data(timeframe, size, start, random_seed) - df["date"] = df.loc[:, "date"].dt.as_unit("ms").astype(np.int64) + df["date"] = df.loc[:, "date"].dt.as_unit("ms").astype("int64") return list(list(x) for x in zip(*(df[x].values.tolist() for x in df.columns), strict=False)) diff --git a/tests/exchange/test_binance_public_data.py b/tests/exchange/test_binance_public_data.py index ab299321b..98d3864d3 100644 --- a/tests/exchange/test_binance_public_data.py +++ b/tests/exchange/test_binance_public_data.py @@ -69,7 +69,7 @@ def make_response_from_url(start_date, end_date): "taker_buy_quote_volume,ignore" ) df = pd.DataFrame(columns=cols.split(","), dtype=float) - df["open_time"] = date_col.astype("int64") // 10**6 + df["open_time"] = date_col.as_unit("ms").astype("int64") df["open"] = df["high"] = df["low"] = df["close"] = df["volume"] = 1.0 return df From c19982dd36f8597094e2c80f5234b2064c9f5ac8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 13 Apr 2026 07:24:10 +0200 Subject: [PATCH 37/49] chore: use string aliases for astype calls --- freqtrade/data/btanalysis/bt_fileutils.py | 5 ++--- .../data/history/datahandlers/jsondatahandler.py | 3 +-- freqtrade/optimize/analysis/lookahead_helpers.py | 12 ++++++------ tests/exchange_online/test_ccxt_compat.py | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/freqtrade/data/btanalysis/bt_fileutils.py b/freqtrade/data/btanalysis/bt_fileutils.py index 2e6b23662..9328ba428 100644 --- a/freqtrade/data/btanalysis/bt_fileutils.py +++ b/freqtrade/data/btanalysis/bt_fileutils.py @@ -10,7 +10,6 @@ from io import BytesIO, StringIO from pathlib import Path from typing import Any, Literal -import numpy as np import pandas as pd from freqtrade.constants import LAST_BT_RESULT_FN @@ -308,7 +307,7 @@ def get_backtest_market_change(filename: Path, include_ts: bool = True) -> pd.Da else: df = pd.read_feather(filename) if include_ts: - df.loc[:, "__date_ts"] = df.loc[:, "date"].dt.as_unit("ms").astype(np.int64) + df.loc[:, "__date_ts"] = df.loc[:, "date"].dt.as_unit("ms").astype("int64") return df @@ -326,7 +325,7 @@ def get_backtest_wallet_change(filename: Path, strategy_name: str) -> pd.DataFra data = load_file_from_zip(filename, f"{filename.stem}_{strategy_name}_wallet.feather") df = pd.read_feather(BytesIO(data)) - df.loc[:, "__date_ts"] = df.loc[:, "date"].dt.as_unit("ms").astype(np.int64) + df.loc[:, "__date_ts"] = df.loc[:, "date"].dt.as_unit("ms").astype("int64") return df except ValueError: pass diff --git a/freqtrade/data/history/datahandlers/jsondatahandler.py b/freqtrade/data/history/datahandlers/jsondatahandler.py index e2ab5c408..332b687b4 100644 --- a/freqtrade/data/history/datahandlers/jsondatahandler.py +++ b/freqtrade/data/history/datahandlers/jsondatahandler.py @@ -1,6 +1,5 @@ import logging -import numpy as np from pandas import DataFrame, read_json, to_datetime from freqtrade import misc @@ -36,7 +35,7 @@ class JsonDataHandler(IDataHandler): self.create_dir_if_needed(filename) _data = data.copy() # Convert date to int (milliseconds) - _data["date"] = _data["date"].dt.as_unit("ms").astype(np.int64) + _data["date"] = _data["date"].dt.as_unit("ms").astype("int64") # Reset index, select only appropriate columns and save as json _data.reset_index(drop=True).loc[:, self._columns].to_json( diff --git a/freqtrade/optimize/analysis/lookahead_helpers.py b/freqtrade/optimize/analysis/lookahead_helpers.py index c9434c3d8..affa0c652 100644 --- a/freqtrade/optimize/analysis/lookahead_helpers.py +++ b/freqtrade/optimize/analysis/lookahead_helpers.py @@ -126,14 +126,14 @@ class LookaheadAnalysisSubFunctions: csv_df = add_or_update_row(csv_df, new_row_data) # Fill NaN values with a default value (e.g., 0) - csv_df["total_signals"] = csv_df["total_signals"].astype(int).fillna(0) - csv_df["biased_entry_signals"] = csv_df["biased_entry_signals"].astype(int).fillna(0) - csv_df["biased_exit_signals"] = csv_df["biased_exit_signals"].astype(int).fillna(0) + csv_df["total_signals"] = csv_df["total_signals"].astype("int64").fillna(0) + csv_df["biased_entry_signals"] = csv_df["biased_entry_signals"].astype("int64").fillna(0) + csv_df["biased_exit_signals"] = csv_df["biased_exit_signals"].astype("int64").fillna(0) # Convert columns to integers - csv_df["total_signals"] = csv_df["total_signals"].astype(int) - csv_df["biased_entry_signals"] = csv_df["biased_entry_signals"].astype(int) - csv_df["biased_exit_signals"] = csv_df["biased_exit_signals"].astype(int) + csv_df["total_signals"] = csv_df["total_signals"].astype("int64") + csv_df["biased_entry_signals"] = csv_df["biased_entry_signals"].astype("int64") + csv_df["biased_exit_signals"] = csv_df["biased_exit_signals"].astype("int64") logger.info(f"saving {config['lookahead_analysis_exportfilename']}") csv_df.to_csv(config["lookahead_analysis_exportfilename"], index=False) diff --git a/tests/exchange_online/test_ccxt_compat.py b/tests/exchange_online/test_ccxt_compat.py index c44bb216a..556d5edf6 100644 --- a/tests/exchange_online/test_ccxt_compat.py +++ b/tests/exchange_online/test_ccxt_compat.py @@ -287,7 +287,7 @@ class TestCCXTExchange: # Check if last-timeframe is within the last 2 intervals now = datetime.now(UTC) - timedelta(minutes=(timeframe_to_minutes(timeframe) * 2)) assert exch.klines(pair_tf).iloc[-1]["date"] >= timeframe_to_prev_date(timeframe, now) - assert exch.klines(pair_tf)["date"].astype(int).iloc[0] // 1e6 == since_ms + assert exch.klines(pair_tf)["date"].dt.as_unit("ms").astype("int64").iloc[0] == since_ms def _ccxt__async_get_candle_history( self, exchange, pair: str, timeframe: str, candle_type: CandleType, factor: float = 0.9 From 3a31337e43e49fe9df6d0c750c8f6fcb72c8653d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2026 02:29:25 +0000 Subject: [PATCH 38/49] chore(deps-dev): bump pytest from 9.0.2 to 9.0.3 Bumps [pytest](https://github.com/pytest-dev/pytest) from 9.0.2 to 9.0.3. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/9.0.2...9.0.3) --- updated-dependencies: - dependency-name: pytest dependency-version: 9.0.3 dependency-type: direct:development ... 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 b3d6bdfc8..d8f8c9719 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -9,7 +9,7 @@ ruff==0.15.9 mypy==1.20.0 pre-commit==4.5.1 -pytest==9.0.2 +pytest==9.0.3 pytest-asyncio==1.3.0 pytest-cov==7.1.0 pytest-mock==3.15.1 From 0568c7b945ea5427e3d9e64d639eb3500083b67b Mon Sep 17 00:00:00 2001 From: Freqtrade Bot <154552126+freqtrade-bot@users.noreply.github.com> Date: Tue, 14 Apr 2026 04:01:05 +0000 Subject: [PATCH 39/49] chore: update pre-commit hooks --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f3f58d269..aaf398201 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,7 +15,7 @@ repos: - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v1.20.0" + rev: "v1.20.1" hooks: - id: mypy exclude: build_helpers @@ -31,7 +31,7 @@ repos: - repo: https://github.com/charliermarsh/ruff-pre-commit # Ruff version. - rev: 'v0.15.9' + rev: 'v0.15.10' hooks: - id: ruff - id: ruff-format @@ -70,6 +70,6 @@ repos: # Ensure github actions remain safe - repo: https://github.com/woodruffw/zizmor-pre-commit - rev: v1.23.1 + rev: v1.24.1 hooks: - id: zizmor From ff7e6c373720eded7a316076e98c4cc422cfb4b9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Apr 2026 06:34:14 +0200 Subject: [PATCH 40/49] chore: allow pytest to be newer temporarily --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index b62878fad..c94348f4e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -223,6 +223,7 @@ exclude-newer = "1 week" [tool.uv.exclude-newer-package] ccxt = false cryptography = "1 days" +pytest = "5 days" [tool.ruff] line-length = 100 From 812dc64cd75f479b229813eac691bec1dbc1abaf Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Apr 2026 07:18:09 +0200 Subject: [PATCH 41/49] chore: bump cryptography exclusion to 6 days --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c94348f4e..bd0672cd2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -222,7 +222,7 @@ exclude-newer = "1 week" [tool.uv.exclude-newer-package] ccxt = false -cryptography = "1 days" +cryptography = "6 days" pytest = "5 days" [tool.ruff] From 7105279654aca2290386f22273f4a15f885bc8fc Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Apr 2026 20:41:18 +0200 Subject: [PATCH 42/49] fix(bitget): handle old and new stoploss order types --- freqtrade/exchange/bitget.py | 54 ++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/freqtrade/exchange/bitget.py b/freqtrade/exchange/bitget.py index 9691f72f8..d3cb1ad83 100644 --- a/freqtrade/exchange/bitget.py +++ b/freqtrade/exchange/bitget.py @@ -101,30 +101,36 @@ class Bitget(Exchange): return order def _fetch_stop_order_fallback(self, order_id: str, pair: str) -> CcxtOrder: - params2 = { - "stop": True, - } - for method in ( - self._api.fetch_open_orders, - self._api.fetch_canceled_and_closed_orders, - ): - try: - orders = method(pair, params=params2) - orders_f = [order for order in orders if order["id"] == order_id] - if orders_f: - order = orders_f[0] - self._log_exchange_response("get_stop_order_fallback", order) - return self._convert_stop_order(pair, order_id, order) - except (ccxt.OrderNotFound, ccxt.InvalidOrder): - pass - except ccxt.DDoSProtection as e: - raise DDosProtection(e) from e - except (ccxt.OperationFailed, ccxt.ExchangeError) as e: - raise TemporaryError( - f"Could not get order due to {e.__class__.__name__}. Message: {e}" - ) from e - except ccxt.BaseError as e: - raise OperationalException(e) from e + # old stoploss orders + paramsold = {"stop": True} + # new stoploss orders with stopLossPrice (used in futures starting 2026.4) + paramsnew = {"planType": "profit_loss"} + params_to_try = ( + (paramsnew, paramsold) if self.trading_mode == TradingMode.FUTURES else (paramsold,) + ) + + for params2 in params_to_try: + for method in ( + self._api.fetch_open_orders, + self._api.fetch_canceled_and_closed_orders, + ): + try: + orders = method(pair, params=params2) + orders_f = [order for order in orders if order["id"] == order_id] + if orders_f: + order = orders_f[0] + self._log_exchange_response("get_stop_order_fallback", order) + return self._convert_stop_order(pair, order_id, order) + except (ccxt.OrderNotFound, ccxt.InvalidOrder): + pass + except ccxt.DDoSProtection as e: + raise DDosProtection(e) from e + except (ccxt.OperationFailed, ccxt.ExchangeError) as e: + raise TemporaryError( + f"Could not get order due to {e.__class__.__name__}. Message: {e}" + ) from e + except ccxt.BaseError as e: + raise OperationalException(e) from e raise RetryableOrderError(f"StoplossOrder not found (pair: {pair} id: {order_id}).") @retrier(retries=API_RETRY_COUNT) From b71f91a15683b8c3d80f40b25666ad5fda507bde Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Apr 2026 21:07:16 +0200 Subject: [PATCH 43/49] test: attempted reduction of test flukes by resetting recwarn --- tests/strategy/test_interface.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index bdae9601c..4ddc35e88 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -1041,6 +1041,7 @@ def test_auto_hyperopt_interface_loadparams(default_conf, mocker, caplog): ], ) def test_pandas_warning_direct(ohlcv_history, function, raises, recwarn): + recwarn.clear() df = _STRATEGY.populate_indicators(ohlcv_history, {"pair": "ETH/BTC"}) if raises: assert len(recwarn) == 1 @@ -1054,6 +1055,7 @@ def test_pandas_warning_direct(ohlcv_history, function, raises, recwarn): def test_pandas_warning_through_analyze_pair(ohlcv_history, mocker, recwarn): + recwarn.clear() mocker.patch.object(_STRATEGY.dp, "ohlcv", return_value=ohlcv_history) _STRATEGY.analyze_pair("ETH/BTC") assert len(recwarn) == 0, f"warnings: {', '.join(str(w) for w in recwarn.list)}" From b1747fe9eaf730772655665867d1f9ff1b27711c Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Apr 2026 06:47:51 +0200 Subject: [PATCH 44/49] docs: clarify plot_config setup --- docs/plotting.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/plotting.md b/docs/plotting.md index ae480e78f..599a71dbc 100644 --- a/docs/plotting.md +++ b/docs/plotting.md @@ -111,10 +111,10 @@ It also allows multiple subplots to display both MACD and RSI at the same time. Plot type can be configured using `type` key. Possible types are: -* `scatter` corresponding to `plotly.graph_objects.Scatter` class (default). -* `bar` corresponding to `plotly.graph_objects.Bar` class. +* `scatter` corresponding a scatter plot. +* `bar` corresponding to a bar plot. -Extra parameters to `plotly.graph_objects.*` constructor can be specified in `plotly` dict. +Extra parameters to `plotly.graph_objects.*` constructor can be specified in `plotly` dict - these are only supported when using plotly as plotting library and will be ignored when using freq-ui. Sample configuration with inline comments explaining the process: @@ -163,7 +163,7 @@ def plot_config(self): ``` ??? Note "As attribute (former method)" - Assigning plot_config is also possible as Attribute (this used to be the default way). + Assigning `plot_config` is also possible as Attribute (this used to be the default way). This has the disadvantage that strategy parameters are not available, preventing certain configurations from working. ``` python From 63f2a8bb68d8d4348d26d311a5e5ddb423d25c29 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Apr 2026 06:51:32 +0200 Subject: [PATCH 45/49] chore: remove shorter install allows --- pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bd0672cd2..fd23460bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -222,8 +222,6 @@ exclude-newer = "1 week" [tool.uv.exclude-newer-package] ccxt = false -cryptography = "6 days" -pytest = "5 days" [tool.ruff] line-length = 100 From 0248c209994fa356c10f9daa59e8c1cfb3486feb Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Apr 2026 19:32:33 +0200 Subject: [PATCH 46/49] chore(ci): remove actions/python - uv can do this on it's own --- .github/workflows/binance-lev-tier-update.yml | 4 --- .github/workflows/ci.yml | 28 ++----------------- .github/workflows/deploy-docs.yml | 5 ---- .github/workflows/pre-commit-update.yml | 4 --- 4 files changed, 2 insertions(+), 39 deletions(-) diff --git a/.github/workflows/binance-lev-tier-update.yml b/.github/workflows/binance-lev-tier-update.yml index 01040534e..ed2c21005 100644 --- a/.github/workflows/binance-lev-tier-update.yml +++ b/.github/workflows/binance-lev-tier-update.yml @@ -24,10 +24,6 @@ jobs: with: persist-credentials: false - - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - python-version: "3.14" - - name: Install uv uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 16846d1ac..aa19fd8fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,11 +32,6 @@ jobs: with: persist-credentials: false - - name: Set up Python 🐍 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - python-version: ${{ matrix.python-version }} - - name: Install uv uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: @@ -177,11 +172,6 @@ jobs: with: persist-credentials: false - - name: Set up Python 🐍 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 #v6.2.0 - with: - python-version: "3.13" - - name: Install uv uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: @@ -201,7 +191,8 @@ jobs: with: persist-credentials: false - - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + - name: Set up Python 🐍 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.13" @@ -219,11 +210,6 @@ jobs: run: | ./tests/test_docs.sh - - name: Set up Python 🐍 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - python-version: "3.13" - - name: Install uv uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: @@ -256,11 +242,6 @@ jobs: with: persist-credentials: false - - name: Set up Python 🐍 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - python-version: "${{ matrix.python-version }}" - - name: Install uv uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: @@ -328,11 +309,6 @@ jobs: with: persist-credentials: false - - name: Set up Python 🐍 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - python-version: "${{ matrix.python-version }}" - - name: Install uv uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index bd3d0ee9b..fa710a5be 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -26,11 +26,6 @@ jobs: with: persist-credentials: true - - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - python-version: '3.13' - - name: Install uv uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: diff --git a/.github/workflows/pre-commit-update.yml b/.github/workflows/pre-commit-update.yml index 3d74af2c1..97cdd6e72 100644 --- a/.github/workflows/pre-commit-update.yml +++ b/.github/workflows/pre-commit-update.yml @@ -25,10 +25,6 @@ jobs: with: persist-credentials: false - - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - python-version: "3.13" - - name: Install uv uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: From f1828d72ac1889aa2cd2defda2a6d4ad39aecdcc Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Apr 2026 19:37:02 +0200 Subject: [PATCH 47/49] chore(ci): improved task naming --- .github/workflows/binance-lev-tier-update.yml | 2 +- .github/workflows/ci.yml | 10 +++++----- .github/workflows/deploy-docs.yml | 2 +- .github/workflows/pre-commit-update.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/binance-lev-tier-update.yml b/.github/workflows/binance-lev-tier-update.yml index ed2c21005..4354c233b 100644 --- a/.github/workflows/binance-lev-tier-update.yml +++ b/.github/workflows/binance-lev-tier-update.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - - name: Install uv + - name: Install uv and Python 🐍 uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: activate-environment: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aa19fd8fa..529f3d2cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,7 @@ jobs: with: persist-credentials: false - - name: Install uv + - name: Install uv and Python 🐍 uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: activate-environment: true @@ -172,7 +172,7 @@ jobs: with: persist-credentials: false - - name: Install uv + - name: Install uv and Python 🐍 uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: activate-environment: true @@ -210,7 +210,7 @@ jobs: run: | ./tests/test_docs.sh - - name: Install uv + - name: Install uv and Python 🐍 uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: activate-environment: true @@ -242,7 +242,7 @@ jobs: with: persist-credentials: false - - name: Install uv + - name: Install uv and Python 🐍 uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: activate-environment: true @@ -309,7 +309,7 @@ jobs: with: persist-credentials: false - - name: Install uv + - name: Install uv and Python 🐍 uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: activate-environment: true diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index fa710a5be..e30a0edae 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -26,7 +26,7 @@ jobs: with: persist-credentials: true - - name: Install uv + - name: Install uv and Python 🐍 uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: activate-environment: true diff --git a/.github/workflows/pre-commit-update.yml b/.github/workflows/pre-commit-update.yml index 97cdd6e72..61da3b15e 100644 --- a/.github/workflows/pre-commit-update.yml +++ b/.github/workflows/pre-commit-update.yml @@ -25,7 +25,7 @@ jobs: with: persist-credentials: false - - name: Install uv + - name: Install uv and Python 🐍 uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: activate-environment: true From 12ccd292b113f3f5701d5003e8d97e35db464644 Mon Sep 17 00:00:00 2001 From: Freqtrade Bot <154552126+freqtrade-bot@users.noreply.github.com> Date: Thu, 16 Apr 2026 04:28:50 +0000 Subject: [PATCH 48/49] chore: update binance leverage tiers --- .../exchange/binance_leverage_tiers.json | 3208 ++++++++--------- 1 file changed, 1537 insertions(+), 1671 deletions(-) diff --git a/freqtrade/exchange/binance_leverage_tiers.json b/freqtrade/exchange/binance_leverage_tiers.json index 58f8b3286..09b8e5791 100644 --- a/freqtrade/exchange/binance_leverage_tiers.json +++ b/freqtrade/exchange/binance_leverage_tiers.json @@ -5,13 +5,13 @@ "symbol": "0G/USDT:USDT", "currency": "USDT", "minNotional": 0.0, - "maxNotional": 20000.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, "maxLeverage": 75.0, "info": { "bracket": 1, "initialLeverage": 75, - "notionalCap": 20000, + "notionalCap": 5000, "notionalFloor": 0, "maintMarginRatio": 0.01, "cum": 0.0 @@ -21,136 +21,170 @@ "tier": 2.0, "symbol": "0G/USDT:USDT", "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 200000.0, + "minNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, "maxLeverage": 50.0, "info": { "bracket": 2, "initialLeverage": 50, - "notionalCap": 200000, - "notionalFloor": 20000, + "notionalCap": 10000, + "notionalFloor": 5000, "maintMarginRatio": 0.015, - "cum": 100.0 + "cum": 25.0 } }, { "tier": 3.0, "symbol": "0G/USDT:USDT", "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 1000000.0, + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": 3, "initialLeverage": 25, - "notionalCap": 1000000, - "notionalFloor": 200000, + "notionalCap": 50000, + "notionalFloor": 10000, "maintMarginRatio": 0.02, - "cum": 1100.0 + "cum": 75.0 } }, { "tier": 4.0, "symbol": "0G/USDT:USDT", "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "minNotional": 50000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": 4, "initialLeverage": 20, - "notionalCap": 2000000, - "notionalFloor": 1000000, + "notionalCap": 100000, + "notionalFloor": 50000, "maintMarginRatio": 0.025, - "cum": 6100.0 + "cum": 325.0 } }, { "tier": 5.0, "symbol": "0G/USDT:USDT", "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 100000.0, + "maxNotional": 175000.0, + "maintenanceMarginRate": 0.0333, + "maxLeverage": 15.0, "info": { "bracket": 5, - "initialLeverage": 10, - "notionalCap": 5000000, - "notionalFloor": 2000000, - "maintMarginRatio": 0.05, - "cum": 56100.0 + "initialLeverage": 15, + "notionalCap": 175000, + "notionalFloor": 100000, + "maintMarginRatio": 0.0333, + "cum": 1155.0 } }, { "tier": 6.0, "symbol": "0G/USDT:USDT", "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 7500000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 175000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 6, - "initialLeverage": 5, - "notionalCap": 7500000, - "notionalFloor": 5000000, - "maintMarginRatio": 0.1, - "cum": 306100.0 + "initialLeverage": 10, + "notionalCap": 250000, + "notionalFloor": 175000, + "maintMarginRatio": 0.05, + "cum": 4077.5 } }, { "tier": 7.0, "symbol": "0G/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 10000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 250000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 7, - "initialLeverage": 4, - "notionalCap": 10000000, - "notionalFloor": 7500000, - "maintMarginRatio": 0.125, - "cum": 493600.0 + "initialLeverage": 5, + "notionalCap": 750000, + "notionalFloor": 250000, + "maintMarginRatio": 0.1, + "cum": 16577.5 } }, { "tier": 8.0, "symbol": "0G/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 12500000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 8, - "initialLeverage": 2, - "notionalCap": 12500000, - "notionalFloor": 10000000, - "maintMarginRatio": 0.25, - "cum": 1743600.0 + "initialLeverage": 4, + "notionalCap": 1500000, + "notionalFloor": 750000, + "maintMarginRatio": 0.125, + "cum": 35327.5 } }, { "tier": 9.0, "symbol": "0G/USDT:USDT", "currency": "USDT", - "minNotional": 12500000.0, - "maxNotional": 15000000.0, + "minNotional": 1500000.0, + "maxNotional": 4500000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, + "info": { + "bracket": 9, + "initialLeverage": 3, + "notionalCap": 4500000, + "notionalFloor": 1500000, + "maintMarginRatio": 0.1667, + "cum": 97877.5 + } + }, + { + "tier": 10.0, + "symbol": "0G/USDT:USDT", + "currency": "USDT", + "minNotional": 4500000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": 10, + "initialLeverage": 2, + "notionalCap": 7500000, + "notionalFloor": 4500000, + "maintMarginRatio": 0.25, + "cum": 472727.5 + } + }, + { + "tier": 11.0, + "symbol": "0G/USDT:USDT", + "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 12500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 9, + "bracket": 11, "initialLeverage": 1, - "notionalCap": 15000000, - "notionalFloor": 12500000, + "notionalCap": 12500000, + "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 4868600.0 + "cum": 2347727.5 } } ], @@ -10126,15 +10160,15 @@ "symbol": "ARIA/USDT:USDT", "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxNotional": 6000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 1, - "initialLeverage": 50, - "notionalCap": 5000, + "initialLeverage": 10, + "notionalCap": 6000, "notionalFloor": 0, - "maintMarginRatio": 0.015, + "maintMarginRatio": 0.05, "cum": 0.0 } }, @@ -10142,119 +10176,85 @@ "tier": 2.0, "symbol": "ARIA/USDT:USDT", "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 10000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 6000.0, + "maxNotional": 50000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 2, - "initialLeverage": 20, - "notionalCap": 10000, - "notionalFloor": 5000, - "maintMarginRatio": 0.025, - "cum": 50.0 + "initialLeverage": 5, + "notionalCap": 50000, + "notionalFloor": 6000, + "maintMarginRatio": 0.1, + "cum": 300.0 } }, { "tier": 3.0, "symbol": "ARIA/USDT:USDT", "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 20000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 50000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 3, - "initialLeverage": 10, - "notionalCap": 20000, - "notionalFloor": 10000, - "maintMarginRatio": 0.05, - "cum": 300.0 + "initialLeverage": 4, + "notionalCap": 100000, + "notionalFloor": 50000, + "maintMarginRatio": 0.125, + "cum": 1550.0 } }, { "tier": 4.0, "symbol": "ARIA/USDT:USDT", "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 100000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, "info": { "bracket": 4, - "initialLeverage": 5, - "notionalCap": 50000, - "notionalFloor": 20000, - "maintMarginRatio": 0.1, - "cum": 1300.0 + "initialLeverage": 3, + "notionalCap": 300000, + "notionalFloor": 100000, + "maintMarginRatio": 0.1667, + "cum": 5720.0 } }, { "tier": 5.0, "symbol": "ARIA/USDT:USDT", "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 250000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 300000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, "info": { "bracket": 5, - "initialLeverage": 4, - "notionalCap": 250000, - "notionalFloor": 50000, - "maintMarginRatio": 0.125, - "cum": 2550.0 + "initialLeverage": 2, + "notionalCap": 1000000, + "notionalFloor": 300000, + "maintMarginRatio": 0.25, + "cum": 30710.0 } }, { "tier": 6.0, "symbol": "ARIA/USDT:USDT", "currency": "USDT", - "minNotional": 250000.0, - "maxNotional": 500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, - "info": { - "bracket": 6, - "initialLeverage": 3, - "notionalCap": 500000, - "notionalFloor": 250000, - "maintMarginRatio": 0.1667, - "cum": 12975.0 - } - }, - { - "tier": 7.0, - "symbol": "ARIA/USDT:USDT", - "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 7500000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, - "info": { - "bracket": 7, - "initialLeverage": 2, - "notionalCap": 7500000, - "notionalFloor": 500000, - "maintMarginRatio": 0.25, - "cum": 54625.0 - } - }, - { - "tier": 8.0, - "symbol": "ARIA/USDT:USDT", - "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 12500000.0, + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 8, + "bracket": 6, "initialLeverage": 1, - "notionalCap": 12500000, - "notionalFloor": 7500000, + "notionalCap": 2000000, + "notionalFloor": 1000000, "maintMarginRatio": 0.5, - "cum": 1929625.0 + "cum": 280710.0 } } ], @@ -11402,15 +11402,15 @@ "symbol": "ATH/USDT:USDT", "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": 1, - "initialLeverage": 75, - "notionalCap": 5000, + "initialLeverage": 50, + "notionalCap": 10000, "notionalFloor": 0, - "maintMarginRatio": 0.01, + "maintMarginRatio": 0.015, "cum": 0.0 } }, @@ -11418,38 +11418,21 @@ "tier": 2.0, "symbol": "ATH/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": "ATH/USDT:USDT", - "currency": "USDT", "minNotional": 10000.0, "maxNotional": 50000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { - "bracket": 3, + "bracket": 2, "initialLeverage": 25, "notionalCap": 50000, "notionalFloor": 10000, "maintMarginRatio": 0.02, - "cum": 75.0 + "cum": 50.0 } }, { - "tier": 4.0, + "tier": 3.0, "symbol": "ATH/USDT:USDT", "currency": "USDT", "minNotional": 50000.0, @@ -11457,50 +11440,50 @@ "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { - "bracket": 4, + "bracket": 3, "initialLeverage": 20, "notionalCap": 100000, "notionalFloor": 50000, "maintMarginRatio": 0.025, - "cum": 325.0 + "cum": 300.0 + } + }, + { + "tier": 4.0, + "symbol": "ATH/USDT:USDT", + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 125000.0, + "maintenanceMarginRate": 0.0333, + "maxLeverage": 15.0, + "info": { + "bracket": 4, + "initialLeverage": 15, + "notionalCap": 125000, + "notionalFloor": 100000, + "maintMarginRatio": 0.0333, + "cum": 1130.0 } }, { "tier": 5.0, "symbol": "ATH/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 175000.0, - "maintenanceMarginRate": 0.0333, - "maxLeverage": 15.0, - "info": { - "bracket": 5, - "initialLeverage": 15, - "notionalCap": 175000, - "notionalFloor": 100000, - "maintMarginRatio": 0.0333, - "cum": 1155.0 - } - }, - { - "tier": 6.0, - "symbol": "ATH/USDT:USDT", - "currency": "USDT", - "minNotional": 175000.0, + "minNotional": 125000.0, "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { - "bracket": 6, + "bracket": 5, "initialLeverage": 10, "notionalCap": 250000, - "notionalFloor": 175000, + "notionalFloor": 125000, "maintMarginRatio": 0.05, - "cum": 4077.5 + "cum": 3217.5 } }, { - "tier": 7.0, + "tier": 6.0, "symbol": "ATH/USDT:USDT", "currency": "USDT", "minNotional": 250000.0, @@ -11508,16 +11491,16 @@ "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { - "bracket": 7, + "bracket": 6, "initialLeverage": 5, "notionalCap": 750000, "notionalFloor": 250000, "maintMarginRatio": 0.1, - "cum": 16577.5 + "cum": 15717.5 } }, { - "tier": 8.0, + "tier": 7.0, "symbol": "ATH/USDT:USDT", "currency": "USDT", "minNotional": 750000.0, @@ -11525,63 +11508,63 @@ "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { - "bracket": 8, + "bracket": 7, "initialLeverage": 4, "notionalCap": 1500000, "notionalFloor": 750000, "maintMarginRatio": 0.125, - "cum": 35327.5 + "cum": 34467.5 + } + }, + { + "tier": 8.0, + "symbol": "ATH/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 2500000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, + "info": { + "bracket": 8, + "initialLeverage": 3, + "notionalCap": 2500000, + "notionalFloor": 1500000, + "maintMarginRatio": 0.1667, + "cum": 97017.5 } }, { "tier": 9.0, "symbol": "ATH/USDT:USDT", "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 4500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, + "minNotional": 2500000.0, + "maxNotional": 5000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, "info": { "bracket": 9, - "initialLeverage": 3, - "notionalCap": 4500000, - "notionalFloor": 1500000, - "maintMarginRatio": 0.1667, - "cum": 97877.5 + "initialLeverage": 2, + "notionalCap": 5000000, + "notionalFloor": 2500000, + "maintMarginRatio": 0.25, + "cum": 305267.5 } }, { "tier": 10.0, "symbol": "ATH/USDT:USDT", "currency": "USDT", - "minNotional": 4500000.0, + "minNotional": 5000000.0, "maxNotional": 7500000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, - "info": { - "bracket": 10, - "initialLeverage": 2, - "notionalCap": 7500000, - "notionalFloor": 4500000, - "maintMarginRatio": 0.25, - "cum": 472727.5 - } - }, - { - "tier": 11.0, - "symbol": "ATH/USDT:USDT", - "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 12500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 11, + "bracket": 10, "initialLeverage": 1, - "notionalCap": 12500000, - "notionalFloor": 7500000, + "notionalCap": 7500000, + "notionalFloor": 5000000, "maintMarginRatio": 0.5, - "cum": 2347727.5 + "cum": 1555267.5 } } ], @@ -16589,13 +16572,13 @@ "symbol": "BERA/USDT:USDT", "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 50000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": 3, "initialLeverage": 25, - "notionalCap": 50000, + "notionalCap": 25000, "notionalFloor": 10000, "maintMarginRatio": 0.02, "cum": 75.0 @@ -16605,51 +16588,51 @@ "tier": 4.0, "symbol": "BERA/USDT:USDT", "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, + "minNotional": 25000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": 4, "initialLeverage": 20, - "notionalCap": 100000, - "notionalFloor": 50000, + "notionalCap": 50000, + "notionalFloor": 25000, "maintMarginRatio": 0.025, - "cum": 325.0 + "cum": 200.0 } }, { "tier": 5.0, "symbol": "BERA/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 175000.0, - "maintenanceMarginRate": 0.0333, - "maxLeverage": 15.0, + "minNotional": 50000.0, + "maxNotional": 125000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 5, - "initialLeverage": 15, - "notionalCap": 175000, - "notionalFloor": 100000, - "maintMarginRatio": 0.0333, - "cum": 1155.0 + "initialLeverage": 10, + "notionalCap": 125000, + "notionalFloor": 50000, + "maintMarginRatio": 0.05, + "cum": 1450.0 } }, { "tier": 6.0, "symbol": "BERA/USDT:USDT", "currency": "USDT", - "minNotional": 175000.0, + "minNotional": 125000.0, "maxNotional": 250000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 6, - "initialLeverage": 10, + "initialLeverage": 5, "notionalCap": 250000, - "notionalFloor": 175000, - "maintMarginRatio": 0.05, - "cum": 4077.5 + "notionalFloor": 125000, + "maintMarginRatio": 0.1, + "cum": 7700.0 } }, { @@ -16657,71 +16640,54 @@ "symbol": "BERA/USDT:USDT", "currency": "USDT", "minNotional": 250000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 7, - "initialLeverage": 5, - "notionalCap": 750000, + "initialLeverage": 4, + "notionalCap": 500000, "notionalFloor": 250000, - "maintMarginRatio": 0.1, - "cum": 16577.5 + "maintMarginRatio": 0.125, + "cum": 13950.0 } }, { "tier": 8.0, "symbol": "BERA/USDT:USDT", "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, "info": { "bracket": 8, - "initialLeverage": 4, - "notionalCap": 1500000, - "notionalFloor": 750000, - "maintMarginRatio": 0.125, - "cum": 35327.5 + "initialLeverage": 3, + "notionalCap": 1000000, + "notionalFloor": 500000, + "maintMarginRatio": 0.1667, + "cum": 34800.0 } }, { "tier": 9.0, "symbol": "BERA/USDT:USDT", "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 4500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, - "info": { - "bracket": 9, - "initialLeverage": 3, - "notionalCap": 4500000, - "notionalFloor": 1500000, - "maintMarginRatio": 0.1667, - "cum": 97877.5 - } - }, - { - "tier": 10.0, - "symbol": "BERA/USDT:USDT", - "currency": "USDT", - "minNotional": 4500000.0, + "minNotional": 1000000.0, "maxNotional": 7500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": 10, + "bracket": 9, "initialLeverage": 2, "notionalCap": 7500000, - "notionalFloor": 4500000, + "notionalFloor": 1000000, "maintMarginRatio": 0.25, - "cum": 472727.5 + "cum": 118100.0 } }, { - "tier": 11.0, + "tier": 10.0, "symbol": "BERA/USDT:USDT", "currency": "USDT", "minNotional": 7500000.0, @@ -16729,12 +16695,12 @@ "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 11, + "bracket": 10, "initialLeverage": 1, "notionalCap": 12500000, "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 2347727.5 + "cum": 1993100.0 } } ], @@ -17348,14 +17314,14 @@ "currency": "USDT", "minNotional": 0.0, "maxNotional": 5000.0, - "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": 1, - "initialLeverage": 75, + "initialLeverage": 50, "notionalCap": 5000, "notionalFloor": 0, - "maintMarginRatio": 0.01, + "maintMarginRatio": 0.015, "cum": 0.0 } }, @@ -17365,14 +17331,14 @@ "currency": "USDT", "minNotional": 5000.0, "maxNotional": 10000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": 2, - "initialLeverage": 50, + "initialLeverage": 25, "notionalCap": 10000, "notionalFloor": 5000, - "maintMarginRatio": 0.015, + "maintMarginRatio": 0.02, "cum": 25.0 } }, @@ -17381,15 +17347,15 @@ "symbol": "BIO/USDT:USDT", "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": 3, - "initialLeverage": 25, - "notionalCap": 50000, + "initialLeverage": 20, + "notionalCap": 25000, "notionalFloor": 10000, - "maintMarginRatio": 0.02, + "maintMarginRatio": 0.025, "cum": 75.0 } }, @@ -17397,51 +17363,51 @@ "tier": 4.0, "symbol": "BIO/USDT:USDT", "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 25000.0, + "maxNotional": 62500.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 4, - "initialLeverage": 20, - "notionalCap": 100000, - "notionalFloor": 50000, - "maintMarginRatio": 0.025, - "cum": 325.0 + "initialLeverage": 10, + "notionalCap": 62500, + "notionalFloor": 25000, + "maintMarginRatio": 0.05, + "cum": 700.0 } }, { "tier": 5.0, "symbol": "BIO/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 175000.0, - "maintenanceMarginRate": 0.0333, - "maxLeverage": 15.0, + "minNotional": 62500.0, + "maxNotional": 125000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 5, - "initialLeverage": 15, - "notionalCap": 175000, - "notionalFloor": 100000, - "maintMarginRatio": 0.0333, - "cum": 1155.0 + "initialLeverage": 5, + "notionalCap": 125000, + "notionalFloor": 62500, + "maintMarginRatio": 0.1, + "cum": 3825.0 } }, { "tier": 6.0, "symbol": "BIO/USDT:USDT", "currency": "USDT", - "minNotional": 175000.0, + "minNotional": 125000.0, "maxNotional": 250000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 6, - "initialLeverage": 10, + "initialLeverage": 4, "notionalCap": 250000, - "notionalFloor": 175000, - "maintMarginRatio": 0.05, - "cum": 4077.5 + "notionalFloor": 125000, + "maintMarginRatio": 0.125, + "cum": 6950.0 } }, { @@ -17449,71 +17415,37 @@ "symbol": "BIO/USDT:USDT", "currency": "USDT", "minNotional": 250000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, "info": { "bracket": 7, - "initialLeverage": 5, - "notionalCap": 750000, + "initialLeverage": 3, + "notionalCap": 500000, "notionalFloor": 250000, - "maintMarginRatio": 0.1, - "cum": 16577.5 + "maintMarginRatio": 0.1667, + "cum": 17375.0 } }, { "tier": 8.0, "symbol": "BIO/USDT:USDT", "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, - "info": { - "bracket": 8, - "initialLeverage": 4, - "notionalCap": 1500000, - "notionalFloor": 750000, - "maintMarginRatio": 0.125, - "cum": 35327.5 - } - }, - { - "tier": 9.0, - "symbol": "BIO/USDT:USDT", - "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 4500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, - "info": { - "bracket": 9, - "initialLeverage": 3, - "notionalCap": 4500000, - "notionalFloor": 1500000, - "maintMarginRatio": 0.1667, - "cum": 97877.5 - } - }, - { - "tier": 10.0, - "symbol": "BIO/USDT:USDT", - "currency": "USDT", - "minNotional": 4500000.0, + "minNotional": 500000.0, "maxNotional": 7500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": 10, + "bracket": 8, "initialLeverage": 2, "notionalCap": 7500000, - "notionalFloor": 4500000, + "notionalFloor": 500000, "maintMarginRatio": 0.25, - "cum": 472727.5 + "cum": 59025.0 } }, { - "tier": 11.0, + "tier": 9.0, "symbol": "BIO/USDT:USDT", "currency": "USDT", "minNotional": 7500000.0, @@ -17521,12 +17453,12 @@ "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 11, + "bracket": 9, "initialLeverage": 1, "notionalCap": 12500000, "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 2347727.5 + "cum": 1934025.0 } } ], @@ -33401,14 +33333,14 @@ "currency": "USDT", "minNotional": 0.0, "maxNotional": 5000.0, - "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": 1, - "initialLeverage": 75, + "initialLeverage": 50, "notionalCap": 5000, "notionalFloor": 0, - "maintMarginRatio": 0.01, + "maintMarginRatio": 0.015, "cum": 0.0 } }, @@ -33418,14 +33350,14 @@ "currency": "USDT", "minNotional": 5000.0, "maxNotional": 10000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": 2, - "initialLeverage": 50, + "initialLeverage": 25, "notionalCap": 10000, "notionalFloor": 5000, - "maintMarginRatio": 0.015, + "maintMarginRatio": 0.02, "cum": 25.0 } }, @@ -33434,15 +33366,15 @@ "symbol": "ERA/USDT:USDT", "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": 3, - "initialLeverage": 25, - "notionalCap": 50000, + "initialLeverage": 20, + "notionalCap": 25000, "notionalFloor": 10000, - "maintMarginRatio": 0.02, + "maintMarginRatio": 0.025, "cum": 75.0 } }, @@ -33450,51 +33382,51 @@ "tier": 4.0, "symbol": "ERA/USDT:USDT", "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 25000.0, + "maxNotional": 62500.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 4, - "initialLeverage": 20, - "notionalCap": 100000, - "notionalFloor": 50000, - "maintMarginRatio": 0.025, - "cum": 325.0 + "initialLeverage": 10, + "notionalCap": 62500, + "notionalFloor": 25000, + "maintMarginRatio": 0.05, + "cum": 700.0 } }, { "tier": 5.0, "symbol": "ERA/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 175000.0, - "maintenanceMarginRate": 0.0333, - "maxLeverage": 15.0, + "minNotional": 62500.0, + "maxNotional": 125000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 5, - "initialLeverage": 15, - "notionalCap": 175000, - "notionalFloor": 100000, - "maintMarginRatio": 0.0333, - "cum": 1155.0 + "initialLeverage": 5, + "notionalCap": 125000, + "notionalFloor": 62500, + "maintMarginRatio": 0.1, + "cum": 3825.0 } }, { "tier": 6.0, "symbol": "ERA/USDT:USDT", "currency": "USDT", - "minNotional": 175000.0, + "minNotional": 125000.0, "maxNotional": 250000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 6, - "initialLeverage": 10, + "initialLeverage": 4, "notionalCap": 250000, - "notionalFloor": 175000, - "maintMarginRatio": 0.05, - "cum": 4077.5 + "notionalFloor": 125000, + "maintMarginRatio": 0.125, + "cum": 6950.0 } }, { @@ -33502,71 +33434,37 @@ "symbol": "ERA/USDT:USDT", "currency": "USDT", "minNotional": 250000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, "info": { "bracket": 7, - "initialLeverage": 5, - "notionalCap": 750000, + "initialLeverage": 3, + "notionalCap": 500000, "notionalFloor": 250000, - "maintMarginRatio": 0.1, - "cum": 16577.5 + "maintMarginRatio": 0.1667, + "cum": 17375.0 } }, { "tier": 8.0, "symbol": "ERA/USDT:USDT", "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, - "info": { - "bracket": 8, - "initialLeverage": 4, - "notionalCap": 1500000, - "notionalFloor": 750000, - "maintMarginRatio": 0.125, - "cum": 35327.5 - } - }, - { - "tier": 9.0, - "symbol": "ERA/USDT:USDT", - "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 4500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, - "info": { - "bracket": 9, - "initialLeverage": 3, - "notionalCap": 4500000, - "notionalFloor": 1500000, - "maintMarginRatio": 0.1667, - "cum": 97877.5 - } - }, - { - "tier": 10.0, - "symbol": "ERA/USDT:USDT", - "currency": "USDT", - "minNotional": 4500000.0, + "minNotional": 500000.0, "maxNotional": 7500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": 10, + "bracket": 8, "initialLeverage": 2, "notionalCap": 7500000, - "notionalFloor": 4500000, + "notionalFloor": 500000, "maintMarginRatio": 0.25, - "cum": 472727.5 + "cum": 59025.0 } }, { - "tier": 11.0, + "tier": 9.0, "symbol": "ERA/USDT:USDT", "currency": "USDT", "minNotional": 7500000.0, @@ -33574,12 +33472,12 @@ "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 11, + "bracket": 9, "initialLeverage": 1, "notionalCap": 12000000, "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 2347727.5 + "cum": 1934025.0 } } ], @@ -36500,13 +36398,13 @@ "symbol": "FF/USDT:USDT", "currency": "USDT", "minNotional": 0.0, - "maxNotional": 20000.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, "maxLeverage": 75.0, "info": { "bracket": 1, "initialLeverage": 75, - "notionalCap": 20000, + "notionalCap": 5000, "notionalFloor": 0, "maintMarginRatio": 0.01, "cum": 0.0 @@ -36516,136 +36414,170 @@ "tier": 2.0, "symbol": "FF/USDT:USDT", "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 200000.0, + "minNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, "maxLeverage": 50.0, "info": { "bracket": 2, "initialLeverage": 50, - "notionalCap": 200000, - "notionalFloor": 20000, + "notionalCap": 10000, + "notionalFloor": 5000, "maintMarginRatio": 0.015, - "cum": 100.0 + "cum": 25.0 } }, { "tier": 3.0, "symbol": "FF/USDT:USDT", "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 1000000.0, + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": 3, "initialLeverage": 25, - "notionalCap": 1000000, - "notionalFloor": 200000, + "notionalCap": 50000, + "notionalFloor": 10000, "maintMarginRatio": 0.02, - "cum": 1100.0 + "cum": 75.0 } }, { "tier": 4.0, "symbol": "FF/USDT:USDT", "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "minNotional": 50000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": 4, "initialLeverage": 20, - "notionalCap": 2000000, - "notionalFloor": 1000000, + "notionalCap": 100000, + "notionalFloor": 50000, "maintMarginRatio": 0.025, - "cum": 6100.0 + "cum": 325.0 } }, { "tier": 5.0, "symbol": "FF/USDT:USDT", "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 100000.0, + "maxNotional": 175000.0, + "maintenanceMarginRate": 0.0333, + "maxLeverage": 15.0, "info": { "bracket": 5, - "initialLeverage": 10, - "notionalCap": 5000000, - "notionalFloor": 2000000, - "maintMarginRatio": 0.05, - "cum": 56100.0 + "initialLeverage": 15, + "notionalCap": 175000, + "notionalFloor": 100000, + "maintMarginRatio": 0.0333, + "cum": 1155.0 } }, { "tier": 6.0, "symbol": "FF/USDT:USDT", "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 7500000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 175000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 6, - "initialLeverage": 5, - "notionalCap": 7500000, - "notionalFloor": 5000000, - "maintMarginRatio": 0.1, - "cum": 306100.0 + "initialLeverage": 10, + "notionalCap": 250000, + "notionalFloor": 175000, + "maintMarginRatio": 0.05, + "cum": 4077.5 } }, { "tier": 7.0, "symbol": "FF/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 10000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 250000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 7, - "initialLeverage": 4, - "notionalCap": 10000000, - "notionalFloor": 7500000, - "maintMarginRatio": 0.125, - "cum": 493600.0 + "initialLeverage": 5, + "notionalCap": 750000, + "notionalFloor": 250000, + "maintMarginRatio": 0.1, + "cum": 16577.5 } }, { "tier": 8.0, "symbol": "FF/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 12500000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 8, - "initialLeverage": 2, - "notionalCap": 12500000, - "notionalFloor": 10000000, - "maintMarginRatio": 0.25, - "cum": 1743600.0 + "initialLeverage": 4, + "notionalCap": 1500000, + "notionalFloor": 750000, + "maintMarginRatio": 0.125, + "cum": 35327.5 } }, { "tier": 9.0, "symbol": "FF/USDT:USDT", "currency": "USDT", - "minNotional": 12500000.0, - "maxNotional": 15000000.0, + "minNotional": 1500000.0, + "maxNotional": 4500000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, + "info": { + "bracket": 9, + "initialLeverage": 3, + "notionalCap": 4500000, + "notionalFloor": 1500000, + "maintMarginRatio": 0.1667, + "cum": 97877.5 + } + }, + { + "tier": 10.0, + "symbol": "FF/USDT:USDT", + "currency": "USDT", + "minNotional": 4500000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": 10, + "initialLeverage": 2, + "notionalCap": 7500000, + "notionalFloor": 4500000, + "maintMarginRatio": 0.25, + "cum": 472727.5 + } + }, + { + "tier": 11.0, + "symbol": "FF/USDT:USDT", + "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 12500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 9, + "bracket": 11, "initialLeverage": 1, - "notionalCap": 15000000, - "notionalFloor": 12500000, + "notionalCap": 12500000, + "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 4868600.0 + "cum": 2347727.5 } } ], @@ -40065,6 +39997,127 @@ } } ], + "GENIUS/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "GENIUS/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": 1, + "initialLeverage": 20, + "notionalCap": 5000, + "notionalFloor": 0, + "maintMarginRatio": 0.025, + "cum": 0.0 + } + }, + { + "tier": 2.0, + "symbol": "GENIUS/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": 2, + "initialLeverage": 10, + "notionalCap": 10000, + "notionalFloor": 5000, + "maintMarginRatio": 0.05, + "cum": 125.0 + } + }, + { + "tier": 3.0, + "symbol": "GENIUS/USDT:USDT", + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 50000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": 3, + "initialLeverage": 5, + "notionalCap": 50000, + "notionalFloor": 10000, + "maintMarginRatio": 0.1, + "cum": 625.0 + } + }, + { + "tier": 4.0, + "symbol": "GENIUS/USDT:USDT", + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": 4, + "initialLeverage": 4, + "notionalCap": 100000, + "notionalFloor": 50000, + "maintMarginRatio": 0.125, + "cum": 1875.0 + } + }, + { + "tier": 5.0, + "symbol": "GENIUS/USDT:USDT", + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, + "info": { + "bracket": 5, + "initialLeverage": 3, + "notionalCap": 250000, + "notionalFloor": 100000, + "maintMarginRatio": 0.1667, + "cum": 6045.0 + } + }, + { + "tier": 6.0, + "symbol": "GENIUS/USDT:USDT", + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": 6, + "initialLeverage": 2, + "notionalCap": 500000, + "notionalFloor": 250000, + "maintMarginRatio": 0.25, + "cum": 26870.0 + } + }, + { + "tier": 7.0, + "symbol": "GENIUS/USDT:USDT", + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 800000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": 7, + "initialLeverage": 1, + "notionalCap": 800000, + "notionalFloor": 500000, + "maintMarginRatio": 0.5, + "cum": 151870.0 + } + } + ], "GHST/USDT:USDT": [ { "tier": 1.0, @@ -49810,13 +49863,13 @@ "symbol": "KAITO/USDT:USDT", "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 50000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": 3, "initialLeverage": 25, - "notionalCap": 50000, + "notionalCap": 25000, "notionalFloor": 10000, "maintMarginRatio": 0.02, "cum": 75.0 @@ -49826,51 +49879,51 @@ "tier": 4.0, "symbol": "KAITO/USDT:USDT", "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, + "minNotional": 25000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": 4, "initialLeverage": 20, - "notionalCap": 100000, - "notionalFloor": 50000, + "notionalCap": 50000, + "notionalFloor": 25000, "maintMarginRatio": 0.025, - "cum": 325.0 + "cum": 200.0 } }, { "tier": 5.0, "symbol": "KAITO/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 175000.0, - "maintenanceMarginRate": 0.0333, - "maxLeverage": 15.0, + "minNotional": 50000.0, + "maxNotional": 125000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 5, - "initialLeverage": 15, - "notionalCap": 175000, - "notionalFloor": 100000, - "maintMarginRatio": 0.0333, - "cum": 1155.0 + "initialLeverage": 10, + "notionalCap": 125000, + "notionalFloor": 50000, + "maintMarginRatio": 0.05, + "cum": 1450.0 } }, { "tier": 6.0, "symbol": "KAITO/USDT:USDT", "currency": "USDT", - "minNotional": 175000.0, + "minNotional": 125000.0, "maxNotional": 250000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 6, - "initialLeverage": 10, + "initialLeverage": 5, "notionalCap": 250000, - "notionalFloor": 175000, - "maintMarginRatio": 0.05, - "cum": 4077.5 + "notionalFloor": 125000, + "maintMarginRatio": 0.1, + "cum": 7700.0 } }, { @@ -49878,71 +49931,54 @@ "symbol": "KAITO/USDT:USDT", "currency": "USDT", "minNotional": 250000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 7, - "initialLeverage": 5, - "notionalCap": 750000, + "initialLeverage": 4, + "notionalCap": 500000, "notionalFloor": 250000, - "maintMarginRatio": 0.1, - "cum": 16577.5 + "maintMarginRatio": 0.125, + "cum": 13950.0 } }, { "tier": 8.0, "symbol": "KAITO/USDT:USDT", "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, "info": { "bracket": 8, - "initialLeverage": 4, - "notionalCap": 1500000, - "notionalFloor": 750000, - "maintMarginRatio": 0.125, - "cum": 35327.5 + "initialLeverage": 3, + "notionalCap": 1000000, + "notionalFloor": 500000, + "maintMarginRatio": 0.1667, + "cum": 34800.0 } }, { "tier": 9.0, "symbol": "KAITO/USDT:USDT", "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 4500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, - "info": { - "bracket": 9, - "initialLeverage": 3, - "notionalCap": 4500000, - "notionalFloor": 1500000, - "maintMarginRatio": 0.1667, - "cum": 97877.5 - } - }, - { - "tier": 10.0, - "symbol": "KAITO/USDT:USDT", - "currency": "USDT", - "minNotional": 4500000.0, + "minNotional": 1000000.0, "maxNotional": 7500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": 10, + "bracket": 9, "initialLeverage": 2, "notionalCap": 7500000, - "notionalFloor": 4500000, + "notionalFloor": 1000000, "maintMarginRatio": 0.25, - "cum": 472727.5 + "cum": 118100.0 } }, { - "tier": 11.0, + "tier": 10.0, "symbol": "KAITO/USDT:USDT", "currency": "USDT", "minNotional": 7500000.0, @@ -49950,12 +49986,12 @@ "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 11, + "bracket": 10, "initialLeverage": 1, "notionalCap": 12500000, "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 2347727.5 + "cum": 1993100.0 } } ], @@ -52742,15 +52778,15 @@ "symbol": "LINEA/USDT:USDT", "currency": "USDT", "minNotional": 0.0, - "maxNotional": 7500.0, - "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": 1, - "initialLeverage": 75, - "notionalCap": 7500, + "initialLeverage": 50, + "notionalCap": 5000, "notionalFloor": 0, - "maintMarginRatio": 0.01, + "maintMarginRatio": 0.015, "cum": 0.0 } }, @@ -52758,170 +52794,136 @@ "tier": 2.0, "symbol": "LINEA/USDT:USDT", "currency": "USDT", - "minNotional": 7500.0, - "maxNotional": 15000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "minNotional": 5000.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": 2, - "initialLeverage": 50, - "notionalCap": 15000, - "notionalFloor": 7500, - "maintMarginRatio": 0.015, - "cum": 37.5 + "initialLeverage": 25, + "notionalCap": 10000, + "notionalFloor": 5000, + "maintMarginRatio": 0.02, + "cum": 25.0 } }, { "tier": 3.0, "symbol": "LINEA/USDT:USDT", "currency": "USDT", - "minNotional": 15000.0, - "maxNotional": 75000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "minNotional": 10000.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": 3, - "initialLeverage": 25, - "notionalCap": 75000, - "notionalFloor": 15000, - "maintMarginRatio": 0.02, - "cum": 112.5 + "initialLeverage": 20, + "notionalCap": 25000, + "notionalFloor": 10000, + "maintMarginRatio": 0.025, + "cum": 75.0 } }, { "tier": 4.0, "symbol": "LINEA/USDT:USDT", "currency": "USDT", - "minNotional": 75000.0, - "maxNotional": 200000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 25000.0, + "maxNotional": 62500.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 4, - "initialLeverage": 20, - "notionalCap": 200000, - "notionalFloor": 75000, - "maintMarginRatio": 0.025, - "cum": 487.5 + "initialLeverage": 10, + "notionalCap": 62500, + "notionalFloor": 25000, + "maintMarginRatio": 0.05, + "cum": 700.0 } }, { "tier": 5.0, "symbol": "LINEA/USDT:USDT", "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 350000.0, - "maintenanceMarginRate": 0.0333, - "maxLeverage": 15.0, + "minNotional": 62500.0, + "maxNotional": 125000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 5, - "initialLeverage": 15, - "notionalCap": 350000, - "notionalFloor": 200000, - "maintMarginRatio": 0.0333, - "cum": 2147.5 + "initialLeverage": 5, + "notionalCap": 125000, + "notionalFloor": 62500, + "maintMarginRatio": 0.1, + "cum": 3825.0 } }, { "tier": 6.0, "symbol": "LINEA/USDT:USDT", "currency": "USDT", - "minNotional": 350000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 125000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 6, - "initialLeverage": 10, - "notionalCap": 750000, - "notionalFloor": 350000, - "maintMarginRatio": 0.05, - "cum": 7992.5 + "initialLeverage": 4, + "notionalCap": 250000, + "notionalFloor": 125000, + "maintMarginRatio": 0.125, + "cum": 6950.0 } }, { "tier": 7.0, "symbol": "LINEA/USDT:USDT", "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 250000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, "info": { "bracket": 7, - "initialLeverage": 5, - "notionalCap": 3000000, - "notionalFloor": 750000, - "maintMarginRatio": 0.1, - "cum": 45492.5 + "initialLeverage": 3, + "notionalCap": 500000, + "notionalFloor": 250000, + "maintMarginRatio": 0.1667, + "cum": 17375.0 } }, { "tier": 8.0, "symbol": "LINEA/USDT:USDT", "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 4500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 500000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, "info": { "bracket": 8, - "initialLeverage": 4, - "notionalCap": 4500000, - "notionalFloor": 3000000, - "maintMarginRatio": 0.125, - "cum": 120492.5 + "initialLeverage": 2, + "notionalCap": 7500000, + "notionalFloor": 500000, + "maintMarginRatio": 0.25, + "cum": 59025.0 } }, { "tier": 9.0, "symbol": "LINEA/USDT:USDT", "currency": "USDT", - "minNotional": 4500000.0, - "maxNotional": 7500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, - "info": { - "bracket": 9, - "initialLeverage": 3, - "notionalCap": 7500000, - "notionalFloor": 4500000, - "maintMarginRatio": 0.1667, - "cum": 308142.5 - } - }, - { - "tier": 10.0, - "symbol": "LINEA/USDT:USDT", - "currency": "USDT", "minNotional": 7500000.0, - "maxNotional": 12000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, - "info": { - "bracket": 10, - "initialLeverage": 2, - "notionalCap": 12000000, - "notionalFloor": 7500000, - "maintMarginRatio": 0.25, - "cum": 932892.5 - } - }, - { - "tier": 11.0, - "symbol": "LINEA/USDT:USDT", - "currency": "USDT", - "minNotional": 12000000.0, - "maxNotional": 18000000.0, + "maxNotional": 12500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 11, + "bracket": 9, "initialLeverage": 1, - "notionalCap": 18000000, - "notionalFloor": 12000000, + "notionalCap": 12500000, + "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 3932892.5 + "cum": 1934025.0 } } ], @@ -59465,14 +59467,14 @@ "currency": "USDT", "minNotional": 0.0, "maxNotional": 5000.0, - "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": 1, - "initialLeverage": 75, + "initialLeverage": 50, "notionalCap": 5000, "notionalFloor": 0, - "maintMarginRatio": 0.01, + "maintMarginRatio": 0.015, "cum": 0.0 } }, @@ -59482,14 +59484,14 @@ "currency": "USDT", "minNotional": 5000.0, "maxNotional": 10000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": 2, - "initialLeverage": 50, + "initialLeverage": 25, "notionalCap": 10000, "notionalFloor": 5000, - "maintMarginRatio": 0.015, + "maintMarginRatio": 0.02, "cum": 25.0 } }, @@ -59498,15 +59500,15 @@ "symbol": "MOODENG/USDT:USDT", "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": 3, - "initialLeverage": 25, - "notionalCap": 50000, + "initialLeverage": 20, + "notionalCap": 25000, "notionalFloor": 10000, - "maintMarginRatio": 0.02, + "maintMarginRatio": 0.025, "cum": 75.0 } }, @@ -59514,51 +59516,51 @@ "tier": 4.0, "symbol": "MOODENG/USDT:USDT", "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 25000.0, + "maxNotional": 62500.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 4, - "initialLeverage": 20, - "notionalCap": 100000, - "notionalFloor": 50000, - "maintMarginRatio": 0.025, - "cum": 325.0 + "initialLeverage": 10, + "notionalCap": 62500, + "notionalFloor": 25000, + "maintMarginRatio": 0.05, + "cum": 700.0 } }, { "tier": 5.0, "symbol": "MOODENG/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 175000.0, - "maintenanceMarginRate": 0.0333, - "maxLeverage": 15.0, + "minNotional": 62500.0, + "maxNotional": 125000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 5, - "initialLeverage": 15, - "notionalCap": 175000, - "notionalFloor": 100000, - "maintMarginRatio": 0.0333, - "cum": 1155.0 + "initialLeverage": 5, + "notionalCap": 125000, + "notionalFloor": 62500, + "maintMarginRatio": 0.1, + "cum": 3825.0 } }, { "tier": 6.0, "symbol": "MOODENG/USDT:USDT", "currency": "USDT", - "minNotional": 175000.0, + "minNotional": 125000.0, "maxNotional": 250000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 6, - "initialLeverage": 10, + "initialLeverage": 4, "notionalCap": 250000, - "notionalFloor": 175000, - "maintMarginRatio": 0.05, - "cum": 4077.5 + "notionalFloor": 125000, + "maintMarginRatio": 0.125, + "cum": 6950.0 } }, { @@ -59566,71 +59568,37 @@ "symbol": "MOODENG/USDT:USDT", "currency": "USDT", "minNotional": 250000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, "info": { "bracket": 7, - "initialLeverage": 5, - "notionalCap": 750000, + "initialLeverage": 3, + "notionalCap": 500000, "notionalFloor": 250000, - "maintMarginRatio": 0.1, - "cum": 16577.5 + "maintMarginRatio": 0.1667, + "cum": 17375.0 } }, { "tier": 8.0, "symbol": "MOODENG/USDT:USDT", "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, - "info": { - "bracket": 8, - "initialLeverage": 4, - "notionalCap": 1500000, - "notionalFloor": 750000, - "maintMarginRatio": 0.125, - "cum": 35327.5 - } - }, - { - "tier": 9.0, - "symbol": "MOODENG/USDT:USDT", - "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 4500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, - "info": { - "bracket": 9, - "initialLeverage": 3, - "notionalCap": 4500000, - "notionalFloor": 1500000, - "maintMarginRatio": 0.1667, - "cum": 97877.5 - } - }, - { - "tier": 10.0, - "symbol": "MOODENG/USDT:USDT", - "currency": "USDT", - "minNotional": 4500000.0, + "minNotional": 500000.0, "maxNotional": 7500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": 10, + "bracket": 8, "initialLeverage": 2, "notionalCap": 7500000, - "notionalFloor": 4500000, + "notionalFloor": 500000, "maintMarginRatio": 0.25, - "cum": 472727.5 + "cum": 59025.0 } }, { - "tier": 11.0, + "tier": 9.0, "symbol": "MOODENG/USDT:USDT", "currency": "USDT", "minNotional": 7500000.0, @@ -59638,12 +59606,12 @@ "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 11, + "bracket": 9, "initialLeverage": 1, "notionalCap": 12500000, "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 2347727.5 + "cum": 1934025.0 } } ], @@ -62740,13 +62708,13 @@ "symbol": "NMR/USDT:USDT", "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 50000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": 3, "initialLeverage": 25, - "notionalCap": 50000, + "notionalCap": 25000, "notionalFloor": 10000, "maintMarginRatio": 0.02, "cum": 75.0 @@ -62756,51 +62724,51 @@ "tier": 4.0, "symbol": "NMR/USDT:USDT", "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, + "minNotional": 25000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": 4, "initialLeverage": 20, - "notionalCap": 100000, - "notionalFloor": 50000, + "notionalCap": 50000, + "notionalFloor": 25000, "maintMarginRatio": 0.025, - "cum": 325.0 + "cum": 200.0 } }, { "tier": 5.0, "symbol": "NMR/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 175000.0, - "maintenanceMarginRate": 0.0333, - "maxLeverage": 15.0, + "minNotional": 50000.0, + "maxNotional": 125000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 5, - "initialLeverage": 15, - "notionalCap": 175000, - "notionalFloor": 100000, - "maintMarginRatio": 0.0333, - "cum": 1155.0 + "initialLeverage": 10, + "notionalCap": 125000, + "notionalFloor": 50000, + "maintMarginRatio": 0.05, + "cum": 1450.0 } }, { "tier": 6.0, "symbol": "NMR/USDT:USDT", "currency": "USDT", - "minNotional": 175000.0, + "minNotional": 125000.0, "maxNotional": 250000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 6, - "initialLeverage": 10, + "initialLeverage": 5, "notionalCap": 250000, - "notionalFloor": 175000, - "maintMarginRatio": 0.05, - "cum": 4077.5 + "notionalFloor": 125000, + "maintMarginRatio": 0.1, + "cum": 7700.0 } }, { @@ -62808,71 +62776,54 @@ "symbol": "NMR/USDT:USDT", "currency": "USDT", "minNotional": 250000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 7, - "initialLeverage": 5, - "notionalCap": 750000, + "initialLeverage": 4, + "notionalCap": 500000, "notionalFloor": 250000, - "maintMarginRatio": 0.1, - "cum": 16577.5 + "maintMarginRatio": 0.125, + "cum": 13950.0 } }, { "tier": 8.0, "symbol": "NMR/USDT:USDT", "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, "info": { "bracket": 8, - "initialLeverage": 4, - "notionalCap": 1500000, - "notionalFloor": 750000, - "maintMarginRatio": 0.125, - "cum": 35327.5 + "initialLeverage": 3, + "notionalCap": 1000000, + "notionalFloor": 500000, + "maintMarginRatio": 0.1667, + "cum": 34800.0 } }, { "tier": 9.0, "symbol": "NMR/USDT:USDT", "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 4500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, - "info": { - "bracket": 9, - "initialLeverage": 3, - "notionalCap": 4500000, - "notionalFloor": 1500000, - "maintMarginRatio": 0.1667, - "cum": 97877.5 - } - }, - { - "tier": 10.0, - "symbol": "NMR/USDT:USDT", - "currency": "USDT", - "minNotional": 4500000.0, + "minNotional": 1000000.0, "maxNotional": 7500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": 10, + "bracket": 9, "initialLeverage": 2, "notionalCap": 7500000, - "notionalFloor": 4500000, + "notionalFloor": 1000000, "maintMarginRatio": 0.25, - "cum": 472727.5 + "cum": 118100.0 } }, { - "tier": 11.0, + "tier": 10.0, "symbol": "NMR/USDT:USDT", "currency": "USDT", "minNotional": 7500000.0, @@ -62880,12 +62831,12 @@ "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 11, + "bracket": 10, "initialLeverage": 1, "notionalCap": 12500000, "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 2347727.5 + "cum": 1993100.0 } } ], @@ -71101,13 +71052,13 @@ "symbol": "PROVE/USDT:USDT", "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 50000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": 3, "initialLeverage": 25, - "notionalCap": 50000, + "notionalCap": 25000, "notionalFloor": 10000, "maintMarginRatio": 0.02, "cum": 75.0 @@ -71117,51 +71068,51 @@ "tier": 4.0, "symbol": "PROVE/USDT:USDT", "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, + "minNotional": 25000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": 4, "initialLeverage": 20, - "notionalCap": 100000, - "notionalFloor": 50000, + "notionalCap": 50000, + "notionalFloor": 25000, "maintMarginRatio": 0.025, - "cum": 325.0 + "cum": 200.0 } }, { "tier": 5.0, "symbol": "PROVE/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 175000.0, - "maintenanceMarginRate": 0.0333, - "maxLeverage": 15.0, + "minNotional": 50000.0, + "maxNotional": 125000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 5, - "initialLeverage": 15, - "notionalCap": 175000, - "notionalFloor": 100000, - "maintMarginRatio": 0.0333, - "cum": 1155.0 + "initialLeverage": 10, + "notionalCap": 125000, + "notionalFloor": 50000, + "maintMarginRatio": 0.05, + "cum": 1450.0 } }, { "tier": 6.0, "symbol": "PROVE/USDT:USDT", "currency": "USDT", - "minNotional": 175000.0, + "minNotional": 125000.0, "maxNotional": 250000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 6, - "initialLeverage": 10, + "initialLeverage": 5, "notionalCap": 250000, - "notionalFloor": 175000, - "maintMarginRatio": 0.05, - "cum": 4077.5 + "notionalFloor": 125000, + "maintMarginRatio": 0.1, + "cum": 7700.0 } }, { @@ -71169,71 +71120,54 @@ "symbol": "PROVE/USDT:USDT", "currency": "USDT", "minNotional": 250000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 7, - "initialLeverage": 5, - "notionalCap": 750000, + "initialLeverage": 4, + "notionalCap": 500000, "notionalFloor": 250000, - "maintMarginRatio": 0.1, - "cum": 16577.5 + "maintMarginRatio": 0.125, + "cum": 13950.0 } }, { "tier": 8.0, "symbol": "PROVE/USDT:USDT", "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, "info": { "bracket": 8, - "initialLeverage": 4, - "notionalCap": 1500000, - "notionalFloor": 750000, - "maintMarginRatio": 0.125, - "cum": 35327.5 + "initialLeverage": 3, + "notionalCap": 1000000, + "notionalFloor": 500000, + "maintMarginRatio": 0.1667, + "cum": 34800.0 } }, { "tier": 9.0, "symbol": "PROVE/USDT:USDT", "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 4500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, - "info": { - "bracket": 9, - "initialLeverage": 3, - "notionalCap": 4500000, - "notionalFloor": 1500000, - "maintMarginRatio": 0.1667, - "cum": 97877.5 - } - }, - { - "tier": 10.0, - "symbol": "PROVE/USDT:USDT", - "currency": "USDT", - "minNotional": 4500000.0, + "minNotional": 1000000.0, "maxNotional": 7500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": 10, + "bracket": 9, "initialLeverage": 2, "notionalCap": 7500000, - "notionalFloor": 4500000, + "notionalFloor": 1000000, "maintMarginRatio": 0.25, - "cum": 472727.5 + "cum": 118100.0 } }, { - "tier": 11.0, + "tier": 10.0, "symbol": "PROVE/USDT:USDT", "currency": "USDT", "minNotional": 7500000.0, @@ -71241,12 +71175,12 @@ "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 11, + "bracket": 10, "initialLeverage": 1, "notionalCap": 12000000, "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 2347727.5 + "cum": 1993100.0 } } ], @@ -79965,13 +79899,13 @@ "symbol": "SNX/USDT:USDT", "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 50000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": 3, "initialLeverage": 25, - "notionalCap": 50000, + "notionalCap": 25000, "notionalFloor": 10000, "maintMarginRatio": 0.02, "cum": 75.0 @@ -79981,51 +79915,51 @@ "tier": 4.0, "symbol": "SNX/USDT:USDT", "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, + "minNotional": 25000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": 4, "initialLeverage": 20, - "notionalCap": 100000, - "notionalFloor": 50000, + "notionalCap": 50000, + "notionalFloor": 25000, "maintMarginRatio": 0.025, - "cum": 325.0 + "cum": 200.0 } }, { "tier": 5.0, "symbol": "SNX/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 175000.0, - "maintenanceMarginRate": 0.0333, - "maxLeverage": 15.0, + "minNotional": 50000.0, + "maxNotional": 125000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 5, - "initialLeverage": 15, - "notionalCap": 175000, - "notionalFloor": 100000, - "maintMarginRatio": 0.0333, - "cum": 1155.0 + "initialLeverage": 10, + "notionalCap": 125000, + "notionalFloor": 50000, + "maintMarginRatio": 0.05, + "cum": 1450.0 } }, { "tier": 6.0, "symbol": "SNX/USDT:USDT", "currency": "USDT", - "minNotional": 175000.0, + "minNotional": 125000.0, "maxNotional": 250000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 6, - "initialLeverage": 10, + "initialLeverage": 5, "notionalCap": 250000, - "notionalFloor": 175000, - "maintMarginRatio": 0.05, - "cum": 4077.5 + "notionalFloor": 125000, + "maintMarginRatio": 0.1, + "cum": 7700.0 } }, { @@ -80033,71 +79967,54 @@ "symbol": "SNX/USDT:USDT", "currency": "USDT", "minNotional": 250000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 7, - "initialLeverage": 5, - "notionalCap": 750000, + "initialLeverage": 4, + "notionalCap": 500000, "notionalFloor": 250000, - "maintMarginRatio": 0.1, - "cum": 16577.5 + "maintMarginRatio": 0.125, + "cum": 13950.0 } }, { "tier": 8.0, "symbol": "SNX/USDT:USDT", "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, "info": { "bracket": 8, - "initialLeverage": 4, - "notionalCap": 1500000, - "notionalFloor": 750000, - "maintMarginRatio": 0.125, - "cum": 35327.5 + "initialLeverage": 3, + "notionalCap": 1000000, + "notionalFloor": 500000, + "maintMarginRatio": 0.1667, + "cum": 34800.0 } }, { "tier": 9.0, "symbol": "SNX/USDT:USDT", "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 4500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, - "info": { - "bracket": 9, - "initialLeverage": 3, - "notionalCap": 4500000, - "notionalFloor": 1500000, - "maintMarginRatio": 0.1667, - "cum": 97877.5 - } - }, - { - "tier": 10.0, - "symbol": "SNX/USDT:USDT", - "currency": "USDT", - "minNotional": 4500000.0, + "minNotional": 1000000.0, "maxNotional": 7500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": 10, + "bracket": 9, "initialLeverage": 2, "notionalCap": 7500000, - "notionalFloor": 4500000, + "notionalFloor": 1000000, "maintMarginRatio": 0.25, - "cum": 472727.5 + "cum": 118100.0 } }, { - "tier": 11.0, + "tier": 10.0, "symbol": "SNX/USDT:USDT", "currency": "USDT", "minNotional": 7500000.0, @@ -80105,12 +80022,12 @@ "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 11, + "bracket": 10, "initialLeverage": 1, "notionalCap": 12500000, "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 2347727.5 + "cum": 1993100.0 } } ], @@ -81448,14 +81365,14 @@ "currency": "USDT", "minNotional": 0.0, "maxNotional": 5000.0, - "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": 1, - "initialLeverage": 75, + "initialLeverage": 50, "notionalCap": 5000, "notionalFloor": 0, - "maintMarginRatio": 0.01, + "maintMarginRatio": 0.015, "cum": 0.0 } }, @@ -81465,14 +81382,14 @@ "currency": "USDT", "minNotional": 5000.0, "maxNotional": 10000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": 2, - "initialLeverage": 50, + "initialLeverage": 25, "notionalCap": 10000, "notionalFloor": 5000, - "maintMarginRatio": 0.015, + "maintMarginRatio": 0.02, "cum": 25.0 } }, @@ -81481,15 +81398,15 @@ "symbol": "SPK/USDT:USDT", "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": 3, - "initialLeverage": 25, - "notionalCap": 50000, + "initialLeverage": 20, + "notionalCap": 25000, "notionalFloor": 10000, - "maintMarginRatio": 0.02, + "maintMarginRatio": 0.025, "cum": 75.0 } }, @@ -81497,51 +81414,51 @@ "tier": 4.0, "symbol": "SPK/USDT:USDT", "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 25000.0, + "maxNotional": 62500.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 4, - "initialLeverage": 20, - "notionalCap": 100000, - "notionalFloor": 50000, - "maintMarginRatio": 0.025, - "cum": 325.0 + "initialLeverage": 10, + "notionalCap": 62500, + "notionalFloor": 25000, + "maintMarginRatio": 0.05, + "cum": 700.0 } }, { "tier": 5.0, "symbol": "SPK/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 175000.0, - "maintenanceMarginRate": 0.0333, - "maxLeverage": 15.0, + "minNotional": 62500.0, + "maxNotional": 125000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 5, - "initialLeverage": 15, - "notionalCap": 175000, - "notionalFloor": 100000, - "maintMarginRatio": 0.0333, - "cum": 1155.0 + "initialLeverage": 5, + "notionalCap": 125000, + "notionalFloor": 62500, + "maintMarginRatio": 0.1, + "cum": 3825.0 } }, { "tier": 6.0, "symbol": "SPK/USDT:USDT", "currency": "USDT", - "minNotional": 175000.0, + "minNotional": 125000.0, "maxNotional": 250000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 6, - "initialLeverage": 10, + "initialLeverage": 4, "notionalCap": 250000, - "notionalFloor": 175000, - "maintMarginRatio": 0.05, - "cum": 4077.5 + "notionalFloor": 125000, + "maintMarginRatio": 0.125, + "cum": 6950.0 } }, { @@ -81549,71 +81466,37 @@ "symbol": "SPK/USDT:USDT", "currency": "USDT", "minNotional": 250000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, "info": { "bracket": 7, - "initialLeverage": 5, - "notionalCap": 750000, + "initialLeverage": 3, + "notionalCap": 500000, "notionalFloor": 250000, - "maintMarginRatio": 0.1, - "cum": 16577.5 + "maintMarginRatio": 0.1667, + "cum": 17375.0 } }, { "tier": 8.0, "symbol": "SPK/USDT:USDT", "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, - "info": { - "bracket": 8, - "initialLeverage": 4, - "notionalCap": 1500000, - "notionalFloor": 750000, - "maintMarginRatio": 0.125, - "cum": 35327.5 - } - }, - { - "tier": 9.0, - "symbol": "SPK/USDT:USDT", - "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 4500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, - "info": { - "bracket": 9, - "initialLeverage": 3, - "notionalCap": 4500000, - "notionalFloor": 1500000, - "maintMarginRatio": 0.1667, - "cum": 97877.5 - } - }, - { - "tier": 10.0, - "symbol": "SPK/USDT:USDT", - "currency": "USDT", - "minNotional": 4500000.0, + "minNotional": 500000.0, "maxNotional": 7500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": 10, + "bracket": 8, "initialLeverage": 2, "notionalCap": 7500000, - "notionalFloor": 4500000, + "notionalFloor": 500000, "maintMarginRatio": 0.25, - "cum": 472727.5 + "cum": 59025.0 } }, { - "tier": 11.0, + "tier": 9.0, "symbol": "SPK/USDT:USDT", "currency": "USDT", "minNotional": 7500000.0, @@ -81621,12 +81504,12 @@ "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 11, + "bracket": 9, "initialLeverage": 1, "notionalCap": 12000000, "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 2347727.5 + "cum": 1934025.0 } } ], @@ -84600,13 +84483,13 @@ "symbol": "SUSHI/USDT:USDT", "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 50000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": 3, "initialLeverage": 25, - "notionalCap": 50000, + "notionalCap": 25000, "notionalFloor": 10000, "maintMarginRatio": 0.02, "cum": 75.0 @@ -84616,51 +84499,51 @@ "tier": 4.0, "symbol": "SUSHI/USDT:USDT", "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, + "minNotional": 25000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": 4, "initialLeverage": 20, - "notionalCap": 100000, - "notionalFloor": 50000, + "notionalCap": 50000, + "notionalFloor": 25000, "maintMarginRatio": 0.025, - "cum": 325.0 + "cum": 200.0 } }, { "tier": 5.0, "symbol": "SUSHI/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 175000.0, - "maintenanceMarginRate": 0.0333, - "maxLeverage": 15.0, + "minNotional": 50000.0, + "maxNotional": 125000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 5, - "initialLeverage": 15, - "notionalCap": 175000, - "notionalFloor": 100000, - "maintMarginRatio": 0.0333, - "cum": 1155.0 + "initialLeverage": 10, + "notionalCap": 125000, + "notionalFloor": 50000, + "maintMarginRatio": 0.05, + "cum": 1450.0 } }, { "tier": 6.0, "symbol": "SUSHI/USDT:USDT", "currency": "USDT", - "minNotional": 175000.0, + "minNotional": 125000.0, "maxNotional": 250000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 6, - "initialLeverage": 10, + "initialLeverage": 5, "notionalCap": 250000, - "notionalFloor": 175000, - "maintMarginRatio": 0.05, - "cum": 4077.5 + "notionalFloor": 125000, + "maintMarginRatio": 0.1, + "cum": 7700.0 } }, { @@ -84668,71 +84551,54 @@ "symbol": "SUSHI/USDT:USDT", "currency": "USDT", "minNotional": 250000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 7, - "initialLeverage": 5, - "notionalCap": 750000, + "initialLeverage": 4, + "notionalCap": 500000, "notionalFloor": 250000, - "maintMarginRatio": 0.1, - "cum": 16577.5 + "maintMarginRatio": 0.125, + "cum": 13950.0 } }, { "tier": 8.0, "symbol": "SUSHI/USDT:USDT", "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, "info": { "bracket": 8, - "initialLeverage": 4, - "notionalCap": 1500000, - "notionalFloor": 750000, - "maintMarginRatio": 0.125, - "cum": 35327.5 + "initialLeverage": 3, + "notionalCap": 1000000, + "notionalFloor": 500000, + "maintMarginRatio": 0.1667, + "cum": 34800.0 } }, { "tier": 9.0, "symbol": "SUSHI/USDT:USDT", "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 4500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, - "info": { - "bracket": 9, - "initialLeverage": 3, - "notionalCap": 4500000, - "notionalFloor": 1500000, - "maintMarginRatio": 0.1667, - "cum": 97877.5 - } - }, - { - "tier": 10.0, - "symbol": "SUSHI/USDT:USDT", - "currency": "USDT", - "minNotional": 4500000.0, + "minNotional": 1000000.0, "maxNotional": 7500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": 10, + "bracket": 9, "initialLeverage": 2, "notionalCap": 7500000, - "notionalFloor": 4500000, + "notionalFloor": 1000000, "maintMarginRatio": 0.25, - "cum": 472727.5 + "cum": 118100.0 } }, { - "tier": 11.0, + "tier": 10.0, "symbol": "SUSHI/USDT:USDT", "currency": "USDT", "minNotional": 7500000.0, @@ -84740,12 +84606,12 @@ "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 11, + "bracket": 10, "initialLeverage": 1, "notionalCap": 12000000, "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 2347727.5 + "cum": 1993100.0 } } ], @@ -88070,14 +87936,14 @@ "currency": "USDT", "minNotional": 0.0, "maxNotional": 5000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 40.0, + "maintenanceMarginRate": 0.04, + "maxLeverage": 20.0, "info": { "bracket": 1, - "initialLeverage": 40, + "initialLeverage": 20, "notionalCap": 5000, "notionalFloor": 0, - "maintMarginRatio": 0.02, + "maintMarginRatio": 0.04, "cum": 0.0 } }, @@ -88087,15 +87953,15 @@ "currency": "USDT", "minNotional": 5000.0, "maxNotional": 10000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 2, - "initialLeverage": 20, + "initialLeverage": 10, "notionalCap": 10000, "notionalFloor": 5000, - "maintMarginRatio": 0.025, - "cum": 25.0 + "maintMarginRatio": 0.05, + "cum": 50.0 } }, { @@ -88103,37 +87969,20 @@ "symbol": "TRADOOR/USDT:USDT", "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 20000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, - "info": { - "bracket": 3, - "initialLeverage": 10, - "notionalCap": 20000, - "notionalFloor": 10000, - "maintMarginRatio": 0.05, - "cum": 275.0 - } - }, - { - "tier": 4.0, - "symbol": "TRADOOR/USDT:USDT", - "currency": "USDT", - "minNotional": 20000.0, "maxNotional": 50000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { - "bracket": 4, + "bracket": 3, "initialLeverage": 5, "notionalCap": 50000, - "notionalFloor": 20000, + "notionalFloor": 10000, "maintMarginRatio": 0.1, - "cum": 1275.0 + "cum": 550.0 } }, { - "tier": 5.0, + "tier": 4.0, "symbol": "TRADOOR/USDT:USDT", "currency": "USDT", "minNotional": 50000.0, @@ -88141,63 +87990,63 @@ "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { - "bracket": 5, + "bracket": 4, "initialLeverage": 4, "notionalCap": 100000, "notionalFloor": 50000, "maintMarginRatio": 0.125, - "cum": 2525.0 + "cum": 1800.0 + } + }, + { + "tier": 5.0, + "symbol": "TRADOOR/USDT:USDT", + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, + "info": { + "bracket": 5, + "initialLeverage": 3, + "notionalCap": 200000, + "notionalFloor": 100000, + "maintMarginRatio": 0.1667, + "cum": 5970.0 } }, { "tier": 6.0, "symbol": "TRADOOR/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 250000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, + "minNotional": 200000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, "info": { "bracket": 6, - "initialLeverage": 3, - "notionalCap": 250000, - "notionalFloor": 100000, - "maintMarginRatio": 0.1667, - "cum": 6695.0 + "initialLeverage": 2, + "notionalCap": 1000000, + "notionalFloor": 200000, + "maintMarginRatio": 0.25, + "cum": 22630.0 } }, { "tier": 7.0, "symbol": "TRADOOR/USDT:USDT", "currency": "USDT", - "minNotional": 250000.0, - "maxNotional": 2500000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, - "info": { - "bracket": 7, - "initialLeverage": 2, - "notionalCap": 2500000, - "notionalFloor": 250000, - "maintMarginRatio": 0.25, - "cum": 27520.0 - } - }, - { - "tier": 8.0, - "symbol": "TRADOOR/USDT:USDT", - "currency": "USDT", - "minNotional": 2500000.0, - "maxNotional": 5000000.0, + "minNotional": 1000000.0, + "maxNotional": 1200000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 8, + "bracket": 7, "initialLeverage": 1, - "notionalCap": 5000000, - "notionalFloor": 2500000, + "notionalCap": 1200000, + "notionalFloor": 1000000, "maintMarginRatio": 0.5, - "cum": 652520.0 + "cum": 272630.0 } } ], @@ -88208,14 +88057,14 @@ "currency": "USDT", "minNotional": 0.0, "maxNotional": 5000.0, - "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": 1, - "initialLeverage": 75, + "initialLeverage": 50, "notionalCap": 5000, "notionalFloor": 0, - "maintMarginRatio": 0.01, + "maintMarginRatio": 0.015, "cum": 0.0 } }, @@ -88225,14 +88074,14 @@ "currency": "USDT", "minNotional": 5000.0, "maxNotional": 10000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": 2, - "initialLeverage": 50, + "initialLeverage": 25, "notionalCap": 10000, "notionalFloor": 5000, - "maintMarginRatio": 0.015, + "maintMarginRatio": 0.02, "cum": 25.0 } }, @@ -88241,15 +88090,15 @@ "symbol": "TRB/USDT:USDT", "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": 3, - "initialLeverage": 25, - "notionalCap": 50000, + "initialLeverage": 20, + "notionalCap": 25000, "notionalFloor": 10000, - "maintMarginRatio": 0.02, + "maintMarginRatio": 0.025, "cum": 75.0 } }, @@ -88257,51 +88106,51 @@ "tier": 4.0, "symbol": "TRB/USDT:USDT", "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 25000.0, + "maxNotional": 62500.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 4, - "initialLeverage": 20, - "notionalCap": 100000, - "notionalFloor": 50000, - "maintMarginRatio": 0.025, - "cum": 325.0 + "initialLeverage": 10, + "notionalCap": 62500, + "notionalFloor": 25000, + "maintMarginRatio": 0.05, + "cum": 700.0 } }, { "tier": 5.0, "symbol": "TRB/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 175000.0, - "maintenanceMarginRate": 0.0333, - "maxLeverage": 15.0, + "minNotional": 62500.0, + "maxNotional": 125000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 5, - "initialLeverage": 15, - "notionalCap": 175000, - "notionalFloor": 100000, - "maintMarginRatio": 0.0333, - "cum": 1155.0 + "initialLeverage": 5, + "notionalCap": 125000, + "notionalFloor": 62500, + "maintMarginRatio": 0.1, + "cum": 3825.0 } }, { "tier": 6.0, "symbol": "TRB/USDT:USDT", "currency": "USDT", - "minNotional": 175000.0, + "minNotional": 125000.0, "maxNotional": 250000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 6, - "initialLeverage": 10, + "initialLeverage": 4, "notionalCap": 250000, - "notionalFloor": 175000, - "maintMarginRatio": 0.05, - "cum": 4077.5 + "notionalFloor": 125000, + "maintMarginRatio": 0.125, + "cum": 6950.0 } }, { @@ -88309,71 +88158,37 @@ "symbol": "TRB/USDT:USDT", "currency": "USDT", "minNotional": 250000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, "info": { "bracket": 7, - "initialLeverage": 5, - "notionalCap": 750000, + "initialLeverage": 3, + "notionalCap": 500000, "notionalFloor": 250000, - "maintMarginRatio": 0.1, - "cum": 16577.5 + "maintMarginRatio": 0.1667, + "cum": 17375.0 } }, { "tier": 8.0, "symbol": "TRB/USDT:USDT", "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, - "info": { - "bracket": 8, - "initialLeverage": 4, - "notionalCap": 1500000, - "notionalFloor": 750000, - "maintMarginRatio": 0.125, - "cum": 35327.5 - } - }, - { - "tier": 9.0, - "symbol": "TRB/USDT:USDT", - "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 4500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, - "info": { - "bracket": 9, - "initialLeverage": 3, - "notionalCap": 4500000, - "notionalFloor": 1500000, - "maintMarginRatio": 0.1667, - "cum": 97877.5 - } - }, - { - "tier": 10.0, - "symbol": "TRB/USDT:USDT", - "currency": "USDT", - "minNotional": 4500000.0, + "minNotional": 500000.0, "maxNotional": 7500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": 10, + "bracket": 8, "initialLeverage": 2, "notionalCap": 7500000, - "notionalFloor": 4500000, + "notionalFloor": 500000, "maintMarginRatio": 0.25, - "cum": 472727.5 + "cum": 59025.0 } }, { - "tier": 11.0, + "tier": 9.0, "symbol": "TRB/USDT:USDT", "currency": "USDT", "minNotional": 7500000.0, @@ -88381,12 +88196,12 @@ "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 11, + "bracket": 9, "initialLeverage": 1, "notionalCap": 12000000, "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 2347727.5 + "cum": 1934025.0 } } ], @@ -94105,13 +93920,13 @@ "symbol": "W/USDT:USDT", "currency": "USDT", "minNotional": 0.0, - "maxNotional": 7500.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, "maxLeverage": 75.0, "info": { "bracket": 1, "initialLeverage": 75, - "notionalCap": 7500, + "notionalCap": 5000, "notionalFloor": 0, "maintMarginRatio": 0.01, "cum": 0.0 @@ -94121,136 +93936,136 @@ "tier": 2.0, "symbol": "W/USDT:USDT", "currency": "USDT", - "minNotional": 7500.0, - "maxNotional": 15000.0, + "minNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, "maxLeverage": 50.0, "info": { "bracket": 2, "initialLeverage": 50, - "notionalCap": 15000, - "notionalFloor": 7500, + "notionalCap": 10000, + "notionalFloor": 5000, "maintMarginRatio": 0.015, - "cum": 37.5 + "cum": 25.0 } }, { "tier": 3.0, "symbol": "W/USDT:USDT", "currency": "USDT", - "minNotional": 15000.0, - "maxNotional": 75000.0, + "minNotional": 10000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": 3, "initialLeverage": 25, - "notionalCap": 75000, - "notionalFloor": 15000, + "notionalCap": 25000, + "notionalFloor": 10000, "maintMarginRatio": 0.02, - "cum": 112.5 + "cum": 75.0 } }, { "tier": 4.0, "symbol": "W/USDT:USDT", "currency": "USDT", - "minNotional": 75000.0, - "maxNotional": 200000.0, + "minNotional": 25000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": 4, "initialLeverage": 20, - "notionalCap": 200000, - "notionalFloor": 75000, + "notionalCap": 50000, + "notionalFloor": 25000, "maintMarginRatio": 0.025, - "cum": 487.5 + "cum": 200.0 } }, { "tier": 5.0, "symbol": "W/USDT:USDT", "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 350000.0, - "maintenanceMarginRate": 0.0333, - "maxLeverage": 15.0, + "minNotional": 50000.0, + "maxNotional": 125000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 5, - "initialLeverage": 15, - "notionalCap": 350000, - "notionalFloor": 200000, - "maintMarginRatio": 0.0333, - "cum": 2147.5 + "initialLeverage": 10, + "notionalCap": 125000, + "notionalFloor": 50000, + "maintMarginRatio": 0.05, + "cum": 1450.0 } }, { "tier": 6.0, "symbol": "W/USDT:USDT", "currency": "USDT", - "minNotional": 350000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 125000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 6, - "initialLeverage": 10, - "notionalCap": 750000, - "notionalFloor": 350000, - "maintMarginRatio": 0.05, - "cum": 7992.5 + "initialLeverage": 5, + "notionalCap": 250000, + "notionalFloor": 125000, + "maintMarginRatio": 0.1, + "cum": 7700.0 } }, { "tier": 7.0, "symbol": "W/USDT:USDT", "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 250000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 7, - "initialLeverage": 5, - "notionalCap": 3000000, - "notionalFloor": 750000, - "maintMarginRatio": 0.1, - "cum": 45492.5 + "initialLeverage": 4, + "notionalCap": 500000, + "notionalFloor": 250000, + "maintMarginRatio": 0.125, + "cum": 13950.0 } }, { "tier": 8.0, "symbol": "W/USDT:USDT", "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 4500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, "info": { "bracket": 8, - "initialLeverage": 4, - "notionalCap": 4500000, - "notionalFloor": 3000000, - "maintMarginRatio": 0.125, - "cum": 120492.5 + "initialLeverage": 3, + "notionalCap": 1000000, + "notionalFloor": 500000, + "maintMarginRatio": 0.1667, + "cum": 34800.0 } }, { "tier": 9.0, "symbol": "W/USDT:USDT", "currency": "USDT", - "minNotional": 4500000.0, + "minNotional": 1000000.0, "maxNotional": 7500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, "info": { "bracket": 9, - "initialLeverage": 3, + "initialLeverage": 2, "notionalCap": 7500000, - "notionalFloor": 4500000, - "maintMarginRatio": 0.1667, - "cum": 308142.5 + "notionalFloor": 1000000, + "maintMarginRatio": 0.25, + "cum": 118100.0 } }, { @@ -94258,33 +94073,16 @@ "symbol": "W/USDT:USDT", "currency": "USDT", "minNotional": 7500000.0, - "maxNotional": 12000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, - "info": { - "bracket": 10, - "initialLeverage": 2, - "notionalCap": 12000000, - "notionalFloor": 7500000, - "maintMarginRatio": 0.25, - "cum": 932892.5 - } - }, - { - "tier": 11.0, - "symbol": "W/USDT:USDT", - "currency": "USDT", - "minNotional": 12000000.0, - "maxNotional": 18000000.0, + "maxNotional": 12500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 11, + "bracket": 10, "initialLeverage": 1, - "notionalCap": 18000000, - "notionalFloor": 12000000, + "notionalCap": 12500000, + "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 3932892.5 + "cum": 1993100.0 } } ], @@ -95156,13 +94954,13 @@ "symbol": "WIF/USDT:USDT", "currency": "USDT", "minNotional": 0.0, - "maxNotional": 20000.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, "maxLeverage": 75.0, "info": { "bracket": 1, "initialLeverage": 75, - "notionalCap": 20000, + "notionalCap": 5000, "notionalFloor": 0, "maintMarginRatio": 0.01, "cum": 0.0 @@ -95172,136 +94970,170 @@ "tier": 2.0, "symbol": "WIF/USDT:USDT", "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 200000.0, + "minNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, "maxLeverage": 50.0, "info": { "bracket": 2, "initialLeverage": 50, - "notionalCap": 200000, - "notionalFloor": 20000, + "notionalCap": 10000, + "notionalFloor": 5000, "maintMarginRatio": 0.015, - "cum": 100.0 + "cum": 25.0 } }, { "tier": 3.0, "symbol": "WIF/USDT:USDT", "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 1000000.0, + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": 3, "initialLeverage": 25, - "notionalCap": 1000000, - "notionalFloor": 200000, + "notionalCap": 50000, + "notionalFloor": 10000, "maintMarginRatio": 0.02, - "cum": 1100.0 + "cum": 75.0 } }, { "tier": 4.0, "symbol": "WIF/USDT:USDT", "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "minNotional": 50000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": 4, "initialLeverage": 20, - "notionalCap": 2000000, - "notionalFloor": 1000000, + "notionalCap": 100000, + "notionalFloor": 50000, "maintMarginRatio": 0.025, - "cum": 6100.0 + "cum": 325.0 } }, { "tier": 5.0, "symbol": "WIF/USDT:USDT", "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 100000.0, + "maxNotional": 175000.0, + "maintenanceMarginRate": 0.0333, + "maxLeverage": 15.0, "info": { "bracket": 5, - "initialLeverage": 10, - "notionalCap": 5000000, - "notionalFloor": 2000000, - "maintMarginRatio": 0.05, - "cum": 56100.0 + "initialLeverage": 15, + "notionalCap": 175000, + "notionalFloor": 100000, + "maintMarginRatio": 0.0333, + "cum": 1155.0 } }, { "tier": 6.0, "symbol": "WIF/USDT:USDT", "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 7500000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 175000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 6, - "initialLeverage": 5, - "notionalCap": 7500000, - "notionalFloor": 5000000, - "maintMarginRatio": 0.1, - "cum": 306100.0 + "initialLeverage": 10, + "notionalCap": 250000, + "notionalFloor": 175000, + "maintMarginRatio": 0.05, + "cum": 4077.5 } }, { "tier": 7.0, "symbol": "WIF/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 10000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 250000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 7, - "initialLeverage": 4, - "notionalCap": 10000000, - "notionalFloor": 7500000, - "maintMarginRatio": 0.125, - "cum": 493600.0 + "initialLeverage": 5, + "notionalCap": 750000, + "notionalFloor": 250000, + "maintMarginRatio": 0.1, + "cum": 16577.5 } }, { "tier": 8.0, "symbol": "WIF/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 12500000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 8, - "initialLeverage": 2, - "notionalCap": 12500000, - "notionalFloor": 10000000, - "maintMarginRatio": 0.25, - "cum": 1743600.0 + "initialLeverage": 4, + "notionalCap": 1500000, + "notionalFloor": 750000, + "maintMarginRatio": 0.125, + "cum": 35327.5 } }, { "tier": 9.0, "symbol": "WIF/USDT:USDT", "currency": "USDT", - "minNotional": 12500000.0, - "maxNotional": 15000000.0, + "minNotional": 1500000.0, + "maxNotional": 4500000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, + "info": { + "bracket": 9, + "initialLeverage": 3, + "notionalCap": 4500000, + "notionalFloor": 1500000, + "maintMarginRatio": 0.1667, + "cum": 97877.5 + } + }, + { + "tier": 10.0, + "symbol": "WIF/USDT:USDT", + "currency": "USDT", + "minNotional": 4500000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": 10, + "initialLeverage": 2, + "notionalCap": 7500000, + "notionalFloor": 4500000, + "maintMarginRatio": 0.25, + "cum": 472727.5 + } + }, + { + "tier": 11.0, + "symbol": "WIF/USDT:USDT", + "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 12500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 9, + "bracket": 11, "initialLeverage": 1, - "notionalCap": 15000000, - "notionalFloor": 12500000, + "notionalCap": 12500000, + "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 4868600.0 + "cum": 2347727.5 } } ], @@ -96758,14 +96590,14 @@ "currency": "USDT", "minNotional": 0.0, "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": 1, - "initialLeverage": 50, + "initialLeverage": 75, "notionalCap": 5000, "notionalFloor": 0, - "maintMarginRatio": 0.015, + "maintMarginRatio": 0.01, "cum": 0.0 } }, @@ -96775,14 +96607,14 @@ "currency": "USDT", "minNotional": 5000.0, "maxNotional": 10000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": 2, - "initialLeverage": 25, + "initialLeverage": 50, "notionalCap": 10000, "notionalFloor": 5000, - "maintMarginRatio": 0.02, + "maintMarginRatio": 0.015, "cum": 25.0 } }, @@ -96791,15 +96623,15 @@ "symbol": "XAUT/USDT:USDT", "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxNotional": 50000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": 3, - "initialLeverage": 20, - "notionalCap": 25000, + "initialLeverage": 25, + "notionalCap": 50000, "notionalFloor": 10000, - "maintMarginRatio": 0.025, + "maintMarginRatio": 0.02, "cum": 75.0 } }, @@ -96807,102 +96639,136 @@ "tier": 4.0, "symbol": "XAUT/USDT:USDT", "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 62500.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 50000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": 4, - "initialLeverage": 10, - "notionalCap": 62500, - "notionalFloor": 25000, - "maintMarginRatio": 0.05, - "cum": 700.0 + "initialLeverage": 20, + "notionalCap": 100000, + "notionalFloor": 50000, + "maintMarginRatio": 0.025, + "cum": 325.0 } }, { "tier": 5.0, "symbol": "XAUT/USDT:USDT", "currency": "USDT", - "minNotional": 62500.0, - "maxNotional": 125000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 100000.0, + "maxNotional": 175000.0, + "maintenanceMarginRate": 0.03333, + "maxLeverage": 15.0, "info": { "bracket": 5, - "initialLeverage": 5, - "notionalCap": 125000, - "notionalFloor": 62500, - "maintMarginRatio": 0.1, - "cum": 3825.0 + "initialLeverage": 15, + "notionalCap": 175000, + "notionalFloor": 100000, + "maintMarginRatio": 0.03333, + "cum": 1158.0 } }, { "tier": 6.0, "symbol": "XAUT/USDT:USDT", "currency": "USDT", - "minNotional": 125000.0, - "maxNotional": 250000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 175000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 6, - "initialLeverage": 4, - "notionalCap": 250000, - "notionalFloor": 125000, - "maintMarginRatio": 0.125, - "cum": 6950.0 + "initialLeverage": 10, + "notionalCap": 500000, + "notionalFloor": 175000, + "maintMarginRatio": 0.05, + "cum": 4075.25 } }, { "tier": 7.0, "symbol": "XAUT/USDT:USDT", "currency": "USDT", - "minNotional": 250000.0, - "maxNotional": 500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, + "minNotional": 500000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 7, - "initialLeverage": 3, - "notionalCap": 500000, - "notionalFloor": 250000, - "maintMarginRatio": 0.1667, - "cum": 17375.0 + "initialLeverage": 5, + "notionalCap": 750000, + "notionalFloor": 500000, + "maintMarginRatio": 0.1, + "cum": 29075.25 } }, { "tier": 8.0, "symbol": "XAUT/USDT:USDT", "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 7500000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 8, - "initialLeverage": 2, - "notionalCap": 7500000, - "notionalFloor": 500000, - "maintMarginRatio": 0.25, - "cum": 59025.0 + "initialLeverage": 4, + "notionalCap": 1500000, + "notionalFloor": 750000, + "maintMarginRatio": 0.125, + "cum": 47825.25 } }, { "tier": 9.0, "symbol": "XAUT/USDT:USDT", "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 4500000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, + "info": { + "bracket": 9, + "initialLeverage": 3, + "notionalCap": 4500000, + "notionalFloor": 1500000, + "maintMarginRatio": 0.1667, + "cum": 110375.25 + } + }, + { + "tier": 10.0, + "symbol": "XAUT/USDT:USDT", + "currency": "USDT", + "minNotional": 4500000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": 10, + "initialLeverage": 2, + "notionalCap": 7500000, + "notionalFloor": 4500000, + "maintMarginRatio": 0.25, + "cum": 485225.25 + } + }, + { + "tier": 11.0, + "symbol": "XAUT/USDT:USDT", + "currency": "USDT", "minNotional": 7500000.0, "maxNotional": 12500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 9, + "bracket": 11, "initialLeverage": 1, "notionalCap": 12500000, "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 1934025.0 + "cum": 2360225.25 } } ], @@ -97895,13 +97761,13 @@ "symbol": "XPL/USDT:USDT", "currency": "USDT", "minNotional": 0.0, - "maxNotional": 20000.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, "maxLeverage": 75.0, "info": { "bracket": 1, "initialLeverage": 75, - "notionalCap": 20000, + "notionalCap": 5000, "notionalFloor": 0, "maintMarginRatio": 0.01, "cum": 0.0 @@ -97911,136 +97777,170 @@ "tier": 2.0, "symbol": "XPL/USDT:USDT", "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 200000.0, + "minNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, "maxLeverage": 50.0, "info": { "bracket": 2, "initialLeverage": 50, - "notionalCap": 200000, - "notionalFloor": 20000, + "notionalCap": 10000, + "notionalFloor": 5000, "maintMarginRatio": 0.015, - "cum": 100.0 + "cum": 25.0 } }, { "tier": 3.0, "symbol": "XPL/USDT:USDT", "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 1000000.0, + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": 3, "initialLeverage": 25, - "notionalCap": 1000000, - "notionalFloor": 200000, + "notionalCap": 50000, + "notionalFloor": 10000, "maintMarginRatio": 0.02, - "cum": 1100.0 + "cum": 75.0 } }, { "tier": 4.0, "symbol": "XPL/USDT:USDT", "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "minNotional": 50000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": 4, "initialLeverage": 20, - "notionalCap": 2000000, - "notionalFloor": 1000000, + "notionalCap": 100000, + "notionalFloor": 50000, "maintMarginRatio": 0.025, - "cum": 6100.0 + "cum": 325.0 } }, { "tier": 5.0, "symbol": "XPL/USDT:USDT", "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 100000.0, + "maxNotional": 175000.0, + "maintenanceMarginRate": 0.0333, + "maxLeverage": 15.0, "info": { "bracket": 5, - "initialLeverage": 10, - "notionalCap": 5000000, - "notionalFloor": 2000000, - "maintMarginRatio": 0.05, - "cum": 56100.0 + "initialLeverage": 15, + "notionalCap": 175000, + "notionalFloor": 100000, + "maintMarginRatio": 0.0333, + "cum": 1155.0 } }, { "tier": 6.0, "symbol": "XPL/USDT:USDT", "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 7500000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 175000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 6, - "initialLeverage": 5, - "notionalCap": 7500000, - "notionalFloor": 5000000, - "maintMarginRatio": 0.1, - "cum": 306100.0 + "initialLeverage": 10, + "notionalCap": 250000, + "notionalFloor": 175000, + "maintMarginRatio": 0.05, + "cum": 4077.5 } }, { "tier": 7.0, "symbol": "XPL/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 10000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 250000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 7, - "initialLeverage": 4, - "notionalCap": 10000000, - "notionalFloor": 7500000, - "maintMarginRatio": 0.125, - "cum": 493600.0 + "initialLeverage": 5, + "notionalCap": 750000, + "notionalFloor": 250000, + "maintMarginRatio": 0.1, + "cum": 16577.5 } }, { "tier": 8.0, "symbol": "XPL/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 12500000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 8, - "initialLeverage": 2, - "notionalCap": 12500000, - "notionalFloor": 10000000, - "maintMarginRatio": 0.25, - "cum": 1743600.0 + "initialLeverage": 4, + "notionalCap": 1500000, + "notionalFloor": 750000, + "maintMarginRatio": 0.125, + "cum": 35327.5 } }, { "tier": 9.0, "symbol": "XPL/USDT:USDT", "currency": "USDT", - "minNotional": 12500000.0, - "maxNotional": 15000000.0, + "minNotional": 1500000.0, + "maxNotional": 4500000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, + "info": { + "bracket": 9, + "initialLeverage": 3, + "notionalCap": 4500000, + "notionalFloor": 1500000, + "maintMarginRatio": 0.1667, + "cum": 97877.5 + } + }, + { + "tier": 10.0, + "symbol": "XPL/USDT:USDT", + "currency": "USDT", + "minNotional": 4500000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": 10, + "initialLeverage": 2, + "notionalCap": 7500000, + "notionalFloor": 4500000, + "maintMarginRatio": 0.25, + "cum": 472727.5 + } + }, + { + "tier": 11.0, + "symbol": "XPL/USDT:USDT", + "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 12500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 9, + "bracket": 11, "initialLeverage": 1, - "notionalCap": 15000000, - "notionalFloor": 12500000, + "notionalCap": 12500000, + "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 4868600.0 + "cum": 2347727.5 } } ], @@ -100254,13 +100154,13 @@ "symbol": "ZEN/USDT:USDT", "currency": "USDT", "minNotional": 0.0, - "maxNotional": 7500.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, "maxLeverage": 75.0, "info": { "bracket": 1, "initialLeverage": 75, - "notionalCap": 7500, + "notionalCap": 5000, "notionalFloor": 0, "maintMarginRatio": 0.01, "cum": 0.0 @@ -100270,170 +100170,170 @@ "tier": 2.0, "symbol": "ZEN/USDT:USDT", "currency": "USDT", - "minNotional": 7500.0, - "maxNotional": 15000.0, + "minNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, "maxLeverage": 50.0, "info": { "bracket": 2, "initialLeverage": 50, - "notionalCap": 15000, - "notionalFloor": 7500, + "notionalCap": 10000, + "notionalFloor": 5000, "maintMarginRatio": 0.015, - "cum": 37.5 + "cum": 25.0 } }, { "tier": 3.0, "symbol": "ZEN/USDT:USDT", "currency": "USDT", - "minNotional": 15000.0, - "maxNotional": 75000.0, + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": 3, "initialLeverage": 25, - "notionalCap": 75000, - "notionalFloor": 15000, + "notionalCap": 50000, + "notionalFloor": 10000, "maintMarginRatio": 0.02, - "cum": 112.5 + "cum": 75.0 } }, { "tier": 4.0, "symbol": "ZEN/USDT:USDT", "currency": "USDT", - "minNotional": 75000.0, - "maxNotional": 200000.0, + "minNotional": 50000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": 4, "initialLeverage": 20, - "notionalCap": 200000, - "notionalFloor": 75000, + "notionalCap": 100000, + "notionalFloor": 50000, "maintMarginRatio": 0.025, - "cum": 487.5 + "cum": 325.0 } }, { "tier": 5.0, "symbol": "ZEN/USDT:USDT", "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 350000.0, + "minNotional": 100000.0, + "maxNotional": 175000.0, "maintenanceMarginRate": 0.0333, "maxLeverage": 15.0, "info": { "bracket": 5, "initialLeverage": 15, - "notionalCap": 350000, - "notionalFloor": 200000, + "notionalCap": 175000, + "notionalFloor": 100000, "maintMarginRatio": 0.0333, - "cum": 2147.5 + "cum": 1155.0 } }, { "tier": 6.0, "symbol": "ZEN/USDT:USDT", "currency": "USDT", - "minNotional": 350000.0, - "maxNotional": 750000.0, + "minNotional": 175000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": 6, "initialLeverage": 10, - "notionalCap": 750000, - "notionalFloor": 350000, + "notionalCap": 250000, + "notionalFloor": 175000, "maintMarginRatio": 0.05, - "cum": 7992.5 + "cum": 4077.5 } }, { "tier": 7.0, "symbol": "ZEN/USDT:USDT", "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 3000000.0, + "minNotional": 250000.0, + "maxNotional": 750000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": 7, "initialLeverage": 5, - "notionalCap": 3000000, - "notionalFloor": 750000, + "notionalCap": 750000, + "notionalFloor": 250000, "maintMarginRatio": 0.1, - "cum": 45492.5 + "cum": 16577.5 } }, { "tier": 8.0, "symbol": "ZEN/USDT:USDT", "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 4500000.0, + "minNotional": 750000.0, + "maxNotional": 1500000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": 8, "initialLeverage": 4, - "notionalCap": 4500000, - "notionalFloor": 3000000, + "notionalCap": 1500000, + "notionalFloor": 750000, "maintMarginRatio": 0.125, - "cum": 120492.5 + "cum": 35327.5 } }, { "tier": 9.0, "symbol": "ZEN/USDT:USDT", "currency": "USDT", - "minNotional": 4500000.0, - "maxNotional": 7500000.0, + "minNotional": 1500000.0, + "maxNotional": 4500000.0, "maintenanceMarginRate": 0.1667, "maxLeverage": 3.0, "info": { "bracket": 9, "initialLeverage": 3, - "notionalCap": 7500000, - "notionalFloor": 4500000, + "notionalCap": 4500000, + "notionalFloor": 1500000, "maintMarginRatio": 0.1667, - "cum": 308142.5 + "cum": 97877.5 } }, { "tier": 10.0, "symbol": "ZEN/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 12000000.0, + "minNotional": 4500000.0, + "maxNotional": 7500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": 10, "initialLeverage": 2, - "notionalCap": 12000000, - "notionalFloor": 7500000, + "notionalCap": 7500000, + "notionalFloor": 4500000, "maintMarginRatio": 0.25, - "cum": 932892.5 + "cum": 472727.5 } }, { "tier": 11.0, "symbol": "ZEN/USDT:USDT", "currency": "USDT", - "minNotional": 12000000.0, - "maxNotional": 18000000.0, + "minNotional": 7500000.0, + "maxNotional": 12500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": 11, "initialLeverage": 1, - "notionalCap": 18000000, - "notionalFloor": 12000000, + "notionalCap": 12500000, + "notionalFloor": 7500000, "maintMarginRatio": 0.5, - "cum": 3932892.5 + "cum": 2347727.5 } } ], @@ -102081,14 +101981,14 @@ "currency": "USDT", "minNotional": 0.0, "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maintenanceMarginRate": 0.04, + "maxLeverage": 20.0, "info": { "bracket": 1, - "initialLeverage": 50, + "initialLeverage": 20, "notionalCap": 5000, "notionalFloor": 0, - "maintMarginRatio": 0.015, + "maintMarginRatio": 0.04, "cum": 0.0 } }, @@ -102097,135 +101997,101 @@ "symbol": "\u5e01\u5b89\u4eba\u751f/USDT:USDT", "currency": "USDT", "minNotional": 5000.0, - "maxNotional": 10000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxNotional": 15000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": 2, - "initialLeverage": 25, - "notionalCap": 10000, + "initialLeverage": 10, + "notionalCap": 15000, "notionalFloor": 5000, - "maintMarginRatio": 0.02, - "cum": 25.0 + "maintMarginRatio": 0.05, + "cum": 50.0 } }, { "tier": 3.0, "symbol": "\u5e01\u5b89\u4eba\u751f/USDT:USDT", "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 15000.0, + "maxNotional": 60000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": 3, - "initialLeverage": 20, - "notionalCap": 25000, - "notionalFloor": 10000, - "maintMarginRatio": 0.025, - "cum": 75.0 + "initialLeverage": 5, + "notionalCap": 60000, + "notionalFloor": 15000, + "maintMarginRatio": 0.1, + "cum": 800.0 } }, { "tier": 4.0, "symbol": "\u5e01\u5b89\u4eba\u751f/USDT:USDT", "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 62500.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 60000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": 4, - "initialLeverage": 10, - "notionalCap": 62500, - "notionalFloor": 25000, - "maintMarginRatio": 0.05, - "cum": 700.0 + "initialLeverage": 4, + "notionalCap": 200000, + "notionalFloor": 60000, + "maintMarginRatio": 0.125, + "cum": 2300.0 } }, { "tier": 5.0, "symbol": "\u5e01\u5b89\u4eba\u751f/USDT:USDT", "currency": "USDT", - "minNotional": 62500.0, - "maxNotional": 125000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 200000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1667, + "maxLeverage": 3.0, "info": { "bracket": 5, - "initialLeverage": 5, - "notionalCap": 125000, - "notionalFloor": 62500, - "maintMarginRatio": 0.1, - "cum": 3825.0 + "initialLeverage": 3, + "notionalCap": 500000, + "notionalFloor": 200000, + "maintMarginRatio": 0.1667, + "cum": 10640.0 } }, { "tier": 6.0, "symbol": "\u5e01\u5b89\u4eba\u751f/USDT:USDT", "currency": "USDT", - "minNotional": 125000.0, - "maxNotional": 250000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 500000.0, + "maxNotional": 2500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, "info": { "bracket": 6, - "initialLeverage": 4, - "notionalCap": 250000, - "notionalFloor": 125000, - "maintMarginRatio": 0.125, - "cum": 6950.0 + "initialLeverage": 2, + "notionalCap": 2500000, + "notionalFloor": 500000, + "maintMarginRatio": 0.25, + "cum": 52290.0 } }, { "tier": 7.0, "symbol": "\u5e01\u5b89\u4eba\u751f/USDT:USDT", "currency": "USDT", - "minNotional": 250000.0, - "maxNotional": 500000.0, - "maintenanceMarginRate": 0.1667, - "maxLeverage": 3.0, - "info": { - "bracket": 7, - "initialLeverage": 3, - "notionalCap": 500000, - "notionalFloor": 250000, - "maintMarginRatio": 0.1667, - "cum": 17375.0 - } - }, - { - "tier": 8.0, - "symbol": "\u5e01\u5b89\u4eba\u751f/USDT:USDT", - "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 7500000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, - "info": { - "bracket": 8, - "initialLeverage": 2, - "notionalCap": 7500000, - "notionalFloor": 500000, - "maintMarginRatio": 0.25, - "cum": 59025.0 - } - }, - { - "tier": 9.0, - "symbol": "\u5e01\u5b89\u4eba\u751f/USDT:USDT", - "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 12500000.0, + "minNotional": 2500000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": 9, + "bracket": 7, "initialLeverage": 1, - "notionalCap": 12500000, - "notionalFloor": 7500000, + "notionalCap": 5000000, + "notionalFloor": 2500000, "maintMarginRatio": 0.5, - "cum": 1934025.0 + "cum": 677290.0 } } ], From 7e3e206ab3407a2ca07029c82ed8344fd82a8279 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 16 Apr 2026 06:35:04 +0200 Subject: [PATCH 49/49] chore(ci): move leverage tiers update by 1 hour --- .github/workflows/binance-lev-tier-update.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/binance-lev-tier-update.yml b/.github/workflows/binance-lev-tier-update.yml index 4354c233b..cc0c11c68 100644 --- a/.github/workflows/binance-lev-tier-update.yml +++ b/.github/workflows/binance-lev-tier-update.yml @@ -2,7 +2,7 @@ name: Binance Leverage tiers update on: schedule: - - cron: "25 3 * * 4" + - cron: "25 2 * * 4" # on demand workflow_dispatch: