From 8f8859a5f50fe4f02ec44c3dcb3733735d6af90a Mon Sep 17 00:00:00 2001 From: jainanuj94 Date: Fri, 2 Aug 2024 15:54:03 +0530 Subject: [PATCH 001/187] Initial commit - create a different file for signals --- freqtrade/data/entryexitanalysis.py | 29 +++++++++++++++++-- freqtrade/optimize/backtesting.py | 15 ++++++++-- .../optimize/optimize_reports/__init__.py | 3 +- .../optimize/optimize_reports/bt_storage.py | 7 ++++- .../optimize_reports/optimize_reports.py | 27 +++++++++++++++-- tests/optimize/test_optimize_reports.py | 8 ++--- 6 files changed, 76 insertions(+), 13 deletions(-) diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index e76f2dff7..7b18097df 100644 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -47,9 +47,12 @@ def _load_signal_candles(backtest_dir: Path): return _load_backtest_analysis_data(backtest_dir, "signals") +def _load_exit_signal_candles(backtest_dir: Path): + return _load_backtest_analysis_data(backtest_dir, "exited") + + def _process_candles_and_indicators(pairlist, strategy_name, trades, signal_candles): - analysed_trades_dict = {} - analysed_trades_dict[strategy_name] = {} + analysed_trades_dict = {strategy_name: {}} try: logger.info(f"Processing {strategy_name} : {len(pairlist)} pairs") @@ -333,6 +336,7 @@ def process_entry_exit_reasons(config: Config): if trades is not None and not trades.empty: signal_candles = _load_signal_candles(config["exportfilename"]) + exit_signal_candles = _load_exit_signal_candles(config["exportfilename"]) rej_df = None if do_rejected: @@ -349,6 +353,10 @@ def process_entry_exit_reasons(config: Config): config["exchange"]["pair_whitelist"], strategy_name, trades, signal_candles ) + exited_trades_dict = _process_candles_and_indicators( + config["exchange"]["pair_whitelist"], strategy_name, trades, exit_signal_candles + ) + res_df = prepare_results( analysed_trades_dict, strategy_name, @@ -357,6 +365,23 @@ def process_entry_exit_reasons(config: Config): timerange=timerange, ) + exited_df = prepare_results( + exited_trades_dict, + strategy_name, + enter_reason_list, + exit_reason_list, + timerange=timerange, + ) + + print_results( + exited_df, + analysis_groups, + indicator_list, + to_csv=False, + rejected_signals=None, + csv_path=csv_path, + ) + print_results( res_df, analysis_groups, diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index c28c080f5..8beb05ff4 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -42,7 +42,8 @@ from freqtrade.optimize.bt_progress import BTProgress from freqtrade.optimize.optimize_reports import ( generate_backtest_stats, generate_rejected_signals, - generate_trade_signal_candles, + generate_trade_entry_signal_candles, + generate_trade_exit_signal_candles, show_backtest_results, store_backtest_analysis_results, store_backtest_stats, @@ -122,6 +123,7 @@ class Backtesting: self.processed_dfs: Dict[str, Dict] = {} self.rejected_dict: Dict[str, List] = {} self.rejected_df: Dict[str, Dict] = {} + self.exited_dfs: Dict[str, Dict] = {} self._exchange_name = self.config["exchange"]["name"] if not exchange: @@ -1558,12 +1560,15 @@ class Backtesting: self.config.get("export", "none") == "signals" and self.dataprovider.runmode == RunMode.BACKTEST ): - self.processed_dfs[strategy_name] = generate_trade_signal_candles( + self.processed_dfs[strategy_name] = generate_trade_entry_signal_candles( preprocessed_tmp, results ) self.rejected_df[strategy_name] = generate_rejected_signals( preprocessed_tmp, self.rejected_dict ) + self.exited_dfs[strategy_name] = generate_trade_exit_signal_candles( + preprocessed_tmp, results + ) return min_date, max_date @@ -1639,7 +1644,11 @@ class Backtesting: and self.dataprovider.runmode == RunMode.BACKTEST ): store_backtest_analysis_results( - self.config["exportfilename"], self.processed_dfs, self.rejected_df, dt_appendix + self.config["exportfilename"], + self.processed_dfs, + self.rejected_df, + self.exited_dfs, + dt_appendix, ) # Results may be mixed up now. Sort them so they follow --strategy-list order. diff --git a/freqtrade/optimize/optimize_reports/__init__.py b/freqtrade/optimize/optimize_reports/__init__.py index 6f3278a1c..1dcc1e885 100644 --- a/freqtrade/optimize/optimize_reports/__init__.py +++ b/freqtrade/optimize/optimize_reports/__init__.py @@ -25,6 +25,7 @@ from freqtrade.optimize.optimize_reports.optimize_reports import ( generate_strategy_comparison, generate_strategy_stats, generate_tag_metrics, - generate_trade_signal_candles, + generate_trade_entry_signal_candles, + generate_trade_exit_signal_candles, generate_trading_stats, ) diff --git a/freqtrade/optimize/optimize_reports/bt_storage.py b/freqtrade/optimize/optimize_reports/bt_storage.py index ea8991337..ed0667cf4 100644 --- a/freqtrade/optimize/optimize_reports/bt_storage.py +++ b/freqtrade/optimize/optimize_reports/bt_storage.py @@ -90,7 +90,12 @@ def _store_backtest_analysis_data( def store_backtest_analysis_results( - recordfilename: Path, candles: Dict[str, Dict], trades: Dict[str, Dict], dtappendix: str + recordfilename: Path, + candles: Dict[str, Dict], + trades: Dict[str, Dict], + exited: Dict[str, Dict], + dtappendix: str, ) -> None: _store_backtest_analysis_data(recordfilename, candles, dtappendix, "signals") _store_backtest_analysis_data(recordfilename, trades, dtappendix, "rejected") + _store_backtest_analysis_data(recordfilename, exited, dtappendix, "exited") diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index ef5fce0e1..e82184516 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -24,9 +24,9 @@ from freqtrade.util import decimals_per_coin, fmt_coin logger = logging.getLogger(__name__) -def generate_trade_signal_candles( +def generate_trade_entry_signal_candles( preprocessed_df: Dict[str, DataFrame], bt_results: Dict[str, Any] -) -> DataFrame: +) -> Dict[str, DataFrame]: signal_candles_only = {} for pair in preprocessed_df.keys(): signal_candles_only_df = DataFrame() @@ -47,6 +47,29 @@ def generate_trade_signal_candles( return signal_candles_only +def generate_trade_exit_signal_candles( + preprocessed_df: Dict[str, DataFrame], bt_results: Dict[str, Any] +) -> Dict[str, DataFrame]: + signal_candles_only = {} + for pair in preprocessed_df.keys(): + signal_candles_only_df = DataFrame() + + pairdf = preprocessed_df[pair] + resdf = bt_results["results"] + pairresults = resdf.loc[(resdf["pair"] == pair)] + + if pairdf.shape[0] > 0: + for t, v in pairresults.close_date.items(): + allinds = pairdf.loc[(pairdf["date"] < v)] + signal_inds = allinds.iloc[[-1]] + signal_candles_only_df = concat( + [signal_candles_only_df.infer_objects(), signal_inds.infer_objects()] + ) + + signal_candles_only[pair] = signal_candles_only_df + return signal_candles_only + + def generate_rejected_signals( preprocessed_df: Dict[str, DataFrame], rejected_dict: Dict[str, DataFrame] ) -> Dict[str, DataFrame]: diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 4c7ce06e8..60106d3bf 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -293,7 +293,7 @@ def test_store_backtest_candles(testdatadir, mocker): candle_dict = {"DefStrat": {"UNITTEST/BTC": pd.DataFrame()}} # mock directory exporting - store_backtest_analysis_results(testdatadir, candle_dict, {}, "2022_01_01_15_05_13") + store_backtest_analysis_results(testdatadir, candle_dict, {}, {}, "2022_01_01_15_05_13") assert dump_mock.call_count == 2 assert isinstance(dump_mock.call_args_list[0][0][0], Path) @@ -302,7 +302,7 @@ def test_store_backtest_candles(testdatadir, mocker): dump_mock.reset_mock() # mock file exporting filename = Path(testdatadir / "testresult") - store_backtest_analysis_results(filename, candle_dict, {}, "2022_01_01_15_05_13") + store_backtest_analysis_results(filename, candle_dict, {}, {}, "2022_01_01_15_05_13") assert dump_mock.call_count == 2 assert isinstance(dump_mock.call_args_list[0][0][0], Path) # result will be testdatadir / testresult-_signals.pkl @@ -315,7 +315,7 @@ def test_write_read_backtest_candles(tmp_path): # test directory exporting sample_date = "2022_01_01_15_05_13" - store_backtest_analysis_results(tmp_path, candle_dict, {}, sample_date) + store_backtest_analysis_results(tmp_path, candle_dict, {}, {}, sample_date) stored_file = tmp_path / f"backtest-result-{sample_date}_signals.pkl" with stored_file.open("rb") as scp: pickled_signal_candles = joblib.load(scp) @@ -330,7 +330,7 @@ def test_write_read_backtest_candles(tmp_path): # test file exporting filename = tmp_path / "testresult" - store_backtest_analysis_results(filename, candle_dict, {}, sample_date) + store_backtest_analysis_results(filename, candle_dict, {}, {}, sample_date) stored_file = tmp_path / f"testresult-{sample_date}_signals.pkl" with stored_file.open("rb") as scp: pickled_signal_candles = joblib.load(scp) From b0e863dbbb46c5fd17524292e47e4a49395a4793 Mon Sep 17 00:00:00 2001 From: jainanuj94 Date: Fri, 2 Aug 2024 20:09:56 +0530 Subject: [PATCH 002/187] Introduce --exit-signals flag to backtesting-analysis command --- freqtrade/commands/arguments.py | 1 + freqtrade/commands/cli_options.py | 5 +++++ freqtrade/configuration/configuration.py | 1 + freqtrade/data/entryexitanalysis.py | 28 +++++------------------- tests/optimize/test_optimize_reports.py | 4 ++-- 5 files changed, 14 insertions(+), 25 deletions(-) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 0c93af78a..a7ecfb83c 100755 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -222,6 +222,7 @@ ARGS_ANALYZE_ENTRIES_EXITS = [ "indicator_list", "timerange", "analysis_rejected", + "analysis_exited", "analysis_to_csv", "analysis_csv_path", ] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index b9236a0ab..72df9b0c7 100755 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -720,6 +720,11 @@ AVAILABLE_CLI_OPTIONS = { help="Analyse rejected signals", action="store_true", ), + "analysis_exited": Arg( + "--exit-signals", + help="Analyse indicators at exit signals", + action="store_true", + ), "analysis_to_csv": Arg( "--analysis-to-csv", help="Save selected analysis tables to individual CSVs", diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 184f9decf..2e3eff740 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -401,6 +401,7 @@ class Configuration: ("indicator_list", "Analysis indicator list: {}"), ("timerange", "Filter trades by timerange: {}"), ("analysis_rejected", "Analyse rejected signals: {}"), + ("analysis_exited", "Analyse exited signals: {}"), ("analysis_to_csv", "Store analysis tables to CSV: {}"), ("analysis_csv_path", "Path to store analysis CSVs: {}"), # Lookahead analysis results diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index 7b18097df..3b7f2e354 100644 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -319,6 +319,7 @@ def process_entry_exit_reasons(config: Config): enter_reason_list = config.get("enter_reason_list", ["all"]) exit_reason_list = config.get("exit_reason_list", ["all"]) indicator_list = config.get("indicator_list", []) + do_exited = config.get("analysis_exited", False) do_rejected = config.get("analysis_rejected", False) to_csv = config.get("analysis_to_csv", False) csv_path = Path(config.get("analysis_csv_path", config["exportfilename"])) @@ -335,8 +336,10 @@ def process_entry_exit_reasons(config: Config): trades = load_backtest_data(config["exportfilename"], strategy_name) if trades is not None and not trades.empty: - signal_candles = _load_signal_candles(config["exportfilename"]) - exit_signal_candles = _load_exit_signal_candles(config["exportfilename"]) + if do_exited is True: + signal_candles = _load_exit_signal_candles(config["exportfilename"]) + else: + signal_candles = _load_signal_candles(config["exportfilename"]) rej_df = None if do_rejected: @@ -353,10 +356,6 @@ def process_entry_exit_reasons(config: Config): config["exchange"]["pair_whitelist"], strategy_name, trades, signal_candles ) - exited_trades_dict = _process_candles_and_indicators( - config["exchange"]["pair_whitelist"], strategy_name, trades, exit_signal_candles - ) - res_df = prepare_results( analysed_trades_dict, strategy_name, @@ -365,23 +364,6 @@ def process_entry_exit_reasons(config: Config): timerange=timerange, ) - exited_df = prepare_results( - exited_trades_dict, - strategy_name, - enter_reason_list, - exit_reason_list, - timerange=timerange, - ) - - print_results( - exited_df, - analysis_groups, - indicator_list, - to_csv=False, - rejected_signals=None, - csv_path=csv_path, - ) - print_results( res_df, analysis_groups, diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 60106d3bf..abbed1e54 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -295,7 +295,7 @@ def test_store_backtest_candles(testdatadir, mocker): # mock directory exporting store_backtest_analysis_results(testdatadir, candle_dict, {}, {}, "2022_01_01_15_05_13") - assert dump_mock.call_count == 2 + assert dump_mock.call_count == 3 assert isinstance(dump_mock.call_args_list[0][0][0], Path) assert str(dump_mock.call_args_list[0][0][0]).endswith("_signals.pkl") @@ -303,7 +303,7 @@ def test_store_backtest_candles(testdatadir, mocker): # mock file exporting filename = Path(testdatadir / "testresult") store_backtest_analysis_results(filename, candle_dict, {}, {}, "2022_01_01_15_05_13") - assert dump_mock.call_count == 2 + assert dump_mock.call_count == 3 assert isinstance(dump_mock.call_args_list[0][0][0], Path) # result will be testdatadir / testresult-_signals.pkl assert str(dump_mock.call_args_list[0][0][0]).endswith("_signals.pkl") From ecf9c173c44256541db09a86f31ee8ab0eb49134 Mon Sep 17 00:00:00 2001 From: jainanuj94 Date: Fri, 2 Aug 2024 20:46:19 +0530 Subject: [PATCH 003/187] Add test for backtesitng-analysis --- freqtrade/data/entryexitanalysis.py | 4 + tests/data/test_entryexitanalysis.py | 235 +++++++++++++++++++++++++++ 2 files changed, 239 insertions(+) diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index 3b7f2e354..d274eabe0 100644 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -260,8 +260,11 @@ def print_results( csv_path: Path, rejected_signals=None, to_csv=False, + exited_signals=False, ): if res_df.shape[0] > 0: + if exited_signals is True: + print("Analysing on exit signals.") if analysis_groups: _do_group_table_output(res_df, analysis_groups, to_csv=to_csv, csv_path=csv_path) @@ -371,6 +374,7 @@ def process_entry_exit_reasons(config: Config): rejected_signals=rej_df, to_csv=to_csv, csv_path=csv_path, + exited_signals=do_exited, ) except ValueError as e: diff --git a/tests/data/test_entryexitanalysis.py b/tests/data/test_entryexitanalysis.py index e7909c339..1a00e22dd 100644 --- a/tests/data/test_entryexitanalysis.py +++ b/tests/data/test_entryexitanalysis.py @@ -140,6 +140,7 @@ def test_backtest_analysis_nomock(default_conf, mocker, caplog, testdatadir, use ) start_analysis_entries_exits(args) captured = capsys.readouterr() + assert "Analysing on exit signals." not in captured.out assert "LTC/BTC" in captured.out assert "ETH/BTC" in captured.out assert "enter_tag_long_a" in captured.out @@ -245,3 +246,237 @@ def test_backtest_analysis_nomock(default_conf, mocker, caplog, testdatadir, use start_analysis_entries_exits(args) captured = capsys.readouterr() assert "no rejected signals" in captured.out + + +def test_backtest_analysis_on_exit_signals_nomock( + default_conf, mocker, caplog, testdatadir, user_dir, capsys +): + caplog.set_level(logging.INFO) + (user_dir / "backtest_results").mkdir(parents=True, exist_ok=True) + + default_conf.update( + { + "use_exit_signal": True, + "exit_profit_only": False, + "exit_profit_offset": 0.0, + "ignore_roi_if_entry_signal": False, + } + ) + patch_exchange(mocker) + result1 = pd.DataFrame( + { + "pair": ["ETH/BTC", "LTC/BTC", "ETH/BTC", "LTC/BTC"], + "profit_ratio": [0.025, 0.05, -0.1, -0.05], + "profit_abs": [0.5, 2.0, -4.0, -2.0], + "open_date": pd.to_datetime( + [ + "2018-01-29 18:40:00", + "2018-01-30 03:30:00", + "2018-01-30 08:10:00", + "2018-01-31 13:30:00", + ], + utc=True, + ), + "close_date": pd.to_datetime( + [ + "2018-01-29 20:45:00", + "2018-01-30 05:35:00", + "2018-01-30 09:10:00", + "2018-01-31 15:00:00", + ], + utc=True, + ), + "trade_duration": [235, 40, 60, 90], + "is_open": [False, False, False, False], + "stake_amount": [0.01, 0.01, 0.01, 0.01], + "open_rate": [0.104445, 0.10302485, 0.10302485, 0.10302485], + "close_rate": [0.104969, 0.103541, 0.102041, 0.102541], + "is_short": [False, False, False, False], + "enter_tag": [ + "enter_tag_long_a", + "enter_tag_long_b", + "enter_tag_long_a", + "enter_tag_long_b", + ], + "exit_reason": [ + ExitType.ROI.value, + ExitType.EXIT_SIGNAL.value, + ExitType.STOP_LOSS.value, + ExitType.TRAILING_STOP_LOSS.value, + ], + } + ) + + backtestmock = MagicMock( + side_effect=[ + { + "results": result1, + "config": default_conf, + "locks": [], + "rejected_signals": 20, + "timedout_entry_orders": 0, + "timedout_exit_orders": 0, + "canceled_trade_entries": 0, + "canceled_entry_orders": 0, + "replaced_entry_orders": 0, + "final_balance": 1000, + } + ] + ) + mocker.patch( + "freqtrade.plugins.pairlistmanager.PairListManager.whitelist", + PropertyMock(return_value=["ETH/BTC", "LTC/BTC", "DASH/BTC"]), + ) + mocker.patch("freqtrade.optimize.backtesting.Backtesting.backtest", backtestmock) + + patched_configuration_load_config_file(mocker, default_conf) + + args = [ + "backtesting", + "--config", + "config.json", + "--datadir", + str(testdatadir), + "--user-data-dir", + str(user_dir), + "--timeframe", + "5m", + "--timerange", + "1515560100-1517287800", + "--export", + "signals", + "--cache", + "none", + ] + args = get_args(args) + start_backtesting(args) + + captured = capsys.readouterr() + assert "BACKTESTING REPORT" in captured.out + assert "EXIT REASON STATS" in captured.out + assert "LEFT OPEN TRADES REPORT" in captured.out + + base_args = [ + "backtesting-analysis", + "--config", + "config.json", + "--datadir", + str(testdatadir), + "--user-data-dir", + str(user_dir), + ] + + # test group 0 and indicator list + args = get_args( + base_args + + [ + "--analysis-groups", + "0", + "--exit-signals", + "--indicator-list", + "close", + "rsi", + "profit_abs", + ] + ) + start_analysis_entries_exits(args) + captured = capsys.readouterr() + assert "Analysing on exit signals." in captured.out + assert "LTC/BTC" in captured.out + assert "ETH/BTC" in captured.out + assert "enter_tag_long_a" in captured.out + assert "enter_tag_long_b" in captured.out + assert "exit_signal" in captured.out + assert "roi" in captured.out + assert "stop_loss" in captured.out + assert "trailing_stop_loss" in captured.out + assert "0.5" in captured.out + assert "-4" in captured.out + assert "-2" in captured.out + assert "nan" in captured.out + assert "57.654" in captured.out + assert "0" in captured.out + assert "0.104" in captured.out + assert "0.016" in captured.out + assert "52.829" in captured.out + + # test group 1 + args = get_args(base_args + ["--analysis-groups", "1"]) + start_analysis_entries_exits(args) + captured = capsys.readouterr() + assert "enter_tag_long_a" in captured.out + assert "enter_tag_long_b" in captured.out + assert "total_profit_pct" in captured.out + assert "-3.5" in captured.out + assert "-1.75" in captured.out + assert "-7.5" in captured.out + assert "-3.75" in captured.out + assert "0" in captured.out + + # test group 2 + args = get_args(base_args + ["--analysis-groups", "2"]) + start_analysis_entries_exits(args) + captured = capsys.readouterr() + assert "enter_tag_long_a" in captured.out + assert "enter_tag_long_b" in captured.out + assert "exit_signal" in captured.out + assert "roi" in captured.out + assert "stop_loss" in captured.out + assert "trailing_stop_loss" in captured.out + assert "total_profit_pct" in captured.out + assert "-10" in captured.out + assert "-5" in captured.out + assert "2.5" in captured.out + + # test group 3 + args = get_args(base_args + ["--analysis-groups", "3"]) + start_analysis_entries_exits(args) + captured = capsys.readouterr() + assert "LTC/BTC" in captured.out + assert "ETH/BTC" in captured.out + assert "enter_tag_long_a" in captured.out + assert "enter_tag_long_b" in captured.out + assert "total_profit_pct" in captured.out + assert "-7.5" in captured.out + assert "-3.75" in captured.out + assert "-1.75" in captured.out + assert "0" in captured.out + assert "2" in captured.out + + # test group 4 + args = get_args(base_args + ["--analysis-groups", "4"]) + start_analysis_entries_exits(args) + captured = capsys.readouterr() + assert "LTC/BTC" in captured.out + assert "ETH/BTC" in captured.out + assert "enter_tag_long_a" in captured.out + assert "enter_tag_long_b" in captured.out + assert "exit_signal" in captured.out + assert "roi" in captured.out + assert "stop_loss" in captured.out + assert "trailing_stop_loss" in captured.out + assert "total_profit_pct" in captured.out + assert "-10" in captured.out + assert "-5" in captured.out + assert "-4" in captured.out + assert "0.5" in captured.out + assert "1" in captured.out + assert "2.5" in captured.out + + # test group 5 + args = get_args(base_args + ["--analysis-groups", "5"]) + start_analysis_entries_exits(args) + captured = capsys.readouterr() + assert "exit_signal" in captured.out + assert "roi" in captured.out + assert "stop_loss" in captured.out + assert "trailing_stop_loss" in captured.out + + # test date filtering + args = get_args( + base_args + ["--analysis-groups", "0", "1", "2", "--timerange", "20180129-20180130"] + ) + start_analysis_entries_exits(args) + captured = capsys.readouterr() + assert "enter_tag_long_a" in captured.out + assert "enter_tag_long_b" not in captured.out From 7f0e5dd3350167a838f62c5459f62070eead3fcb Mon Sep 17 00:00:00 2001 From: jainanuj94 Date: Mon, 5 Aug 2024 23:19:38 +0530 Subject: [PATCH 004/187] Refactor and add documentation --- docs/advanced-backtesting.md | 18 ++++++++--- freqtrade/data/entryexitanalysis.py | 22 +++++++++---- freqtrade/optimize/backtesting.py | 11 +++---- .../optimize/optimize_reports/__init__.py | 3 +- .../optimize_reports/optimize_reports.py | 31 +++---------------- tests/data/test_entryexitanalysis.py | 2 +- 6 files changed, 40 insertions(+), 47 deletions(-) diff --git a/docs/advanced-backtesting.md b/docs/advanced-backtesting.md index 563e5df08..c01d763f8 100644 --- a/docs/advanced-backtesting.md +++ b/docs/advanced-backtesting.md @@ -18,15 +18,15 @@ freqtrade backtesting -c --timeframe --strategy --rejected-signals ``` +### Printing analysis on exit signals + +Use the `--exit-signals` option to print out analysis on exited signals. + +```bash +freqtrade backtesting-analysis -c --exit-signals +``` + ### Writing tables to CSV Some of the tabular outputs can become large, so printing them out to the terminal is not preferable. diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index d274eabe0..f2440a787 100644 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -51,7 +51,9 @@ def _load_exit_signal_candles(backtest_dir: Path): return _load_backtest_analysis_data(backtest_dir, "exited") -def _process_candles_and_indicators(pairlist, strategy_name, trades, signal_candles): +def _process_candles_and_indicators( + pairlist, strategy_name, trades, signal_candles, analyse_on="open_date" +): analysed_trades_dict = {strategy_name: {}} try: @@ -60,7 +62,7 @@ def _process_candles_and_indicators(pairlist, strategy_name, trades, signal_cand for pair in pairlist: if pair in signal_candles[strategy_name]: analysed_trades_dict[strategy_name][pair] = _analyze_candles_and_indicators( - pair, trades, signal_candles[strategy_name][pair] + pair, trades, signal_candles[strategy_name][pair], analyse_on ) except Exception as e: print(f"Cannot process entry/exit reasons for {strategy_name}: ", e) @@ -68,7 +70,9 @@ def _process_candles_and_indicators(pairlist, strategy_name, trades, signal_cand return analysed_trades_dict -def _analyze_candles_and_indicators(pair, trades: pd.DataFrame, signal_candles: pd.DataFrame): +def _analyze_candles_and_indicators( + pair, trades: pd.DataFrame, signal_candles: pd.DataFrame, analyse_on="open_date" +): buyf = signal_candles if len(buyf) > 0: @@ -78,8 +82,8 @@ def _analyze_candles_and_indicators(pair, trades: pd.DataFrame, signal_candles: trades_inds = pd.DataFrame() if trades_red.shape[0] > 0 and buyf.shape[0] > 0: - for t, v in trades_red.open_date.items(): - allinds = buyf.loc[(buyf["date"] < v)] + for t, v in trades_red.iterrows(): + allinds = buyf.loc[(buyf["date"] < v[analyse_on])] if allinds.shape[0] > 0: tmp_inds = allinds.iloc[[-1]] @@ -339,8 +343,10 @@ def process_entry_exit_reasons(config: Config): trades = load_backtest_data(config["exportfilename"], strategy_name) if trades is not None and not trades.empty: + analyse_on = "open_date" if do_exited is True: signal_candles = _load_exit_signal_candles(config["exportfilename"]) + analyse_on = "close_date" else: signal_candles = _load_signal_candles(config["exportfilename"]) @@ -356,7 +362,11 @@ def process_entry_exit_reasons(config: Config): ) analysed_trades_dict = _process_candles_and_indicators( - config["exchange"]["pair_whitelist"], strategy_name, trades, signal_candles + config["exchange"]["pair_whitelist"], + strategy_name, + trades, + signal_candles, + analyse_on, ) res_df = prepare_results( diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 8beb05ff4..bb088d064 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -42,8 +42,7 @@ from freqtrade.optimize.bt_progress import BTProgress from freqtrade.optimize.optimize_reports import ( generate_backtest_stats, generate_rejected_signals, - generate_trade_entry_signal_candles, - generate_trade_exit_signal_candles, + generate_trade_signal_candles, show_backtest_results, store_backtest_analysis_results, store_backtest_stats, @@ -1560,14 +1559,14 @@ class Backtesting: self.config.get("export", "none") == "signals" and self.dataprovider.runmode == RunMode.BACKTEST ): - self.processed_dfs[strategy_name] = generate_trade_entry_signal_candles( - preprocessed_tmp, results + self.processed_dfs[strategy_name] = generate_trade_signal_candles( + preprocessed_tmp, results, "open_date" ) self.rejected_df[strategy_name] = generate_rejected_signals( preprocessed_tmp, self.rejected_dict ) - self.exited_dfs[strategy_name] = generate_trade_exit_signal_candles( - preprocessed_tmp, results + self.exited_dfs[strategy_name] = generate_trade_signal_candles( + preprocessed_tmp, results, "close_date" ) return min_date, max_date diff --git a/freqtrade/optimize/optimize_reports/__init__.py b/freqtrade/optimize/optimize_reports/__init__.py index 1dcc1e885..6f3278a1c 100644 --- a/freqtrade/optimize/optimize_reports/__init__.py +++ b/freqtrade/optimize/optimize_reports/__init__.py @@ -25,7 +25,6 @@ from freqtrade.optimize.optimize_reports.optimize_reports import ( generate_strategy_comparison, generate_strategy_stats, generate_tag_metrics, - generate_trade_entry_signal_candles, - generate_trade_exit_signal_candles, + generate_trade_signal_candles, generate_trading_stats, ) diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index e82184516..2b0fd54bf 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -24,8 +24,8 @@ from freqtrade.util import decimals_per_coin, fmt_coin logger = logging.getLogger(__name__) -def generate_trade_entry_signal_candles( - preprocessed_df: Dict[str, DataFrame], bt_results: Dict[str, Any] +def generate_trade_signal_candles( + preprocessed_df: Dict[str, DataFrame], bt_results: Dict[str, Any], analysis_on="open_date" ) -> Dict[str, DataFrame]: signal_candles_only = {} for pair in preprocessed_df.keys(): @@ -36,31 +36,8 @@ def generate_trade_entry_signal_candles( pairresults = resdf.loc[(resdf["pair"] == pair)] if pairdf.shape[0] > 0: - for t, v in pairresults.open_date.items(): - allinds = pairdf.loc[(pairdf["date"] < v)] - signal_inds = allinds.iloc[[-1]] - signal_candles_only_df = concat( - [signal_candles_only_df.infer_objects(), signal_inds.infer_objects()] - ) - - signal_candles_only[pair] = signal_candles_only_df - return signal_candles_only - - -def generate_trade_exit_signal_candles( - preprocessed_df: Dict[str, DataFrame], bt_results: Dict[str, Any] -) -> Dict[str, DataFrame]: - signal_candles_only = {} - for pair in preprocessed_df.keys(): - signal_candles_only_df = DataFrame() - - pairdf = preprocessed_df[pair] - resdf = bt_results["results"] - pairresults = resdf.loc[(resdf["pair"] == pair)] - - if pairdf.shape[0] > 0: - for t, v in pairresults.close_date.items(): - allinds = pairdf.loc[(pairdf["date"] < v)] + for t, v in pairresults.iterrows(): + allinds = pairdf.loc[(pairdf["date"] < v[analysis_on])] signal_inds = allinds.iloc[[-1]] signal_candles_only_df = concat( [signal_candles_only_df.infer_objects(), signal_inds.infer_objects()] diff --git a/tests/data/test_entryexitanalysis.py b/tests/data/test_entryexitanalysis.py index 1a00e22dd..66e0179f8 100644 --- a/tests/data/test_entryexitanalysis.py +++ b/tests/data/test_entryexitanalysis.py @@ -393,8 +393,8 @@ def test_backtest_analysis_on_exit_signals_nomock( assert "0.5" in captured.out assert "-4" in captured.out assert "-2" in captured.out - assert "nan" in captured.out assert "57.654" in captured.out + assert "44.428" in captured.out assert "0" in captured.out assert "0.104" in captured.out assert "0.016" in captured.out From 103991746bfe29725a1634f1157c9b344e0b23a7 Mon Sep 17 00:00:00 2001 From: jainanuj94 Date: Mon, 5 Aug 2024 23:57:24 +0530 Subject: [PATCH 005/187] chore: type safety and refactoring --- freqtrade/data/entryexitanalysis.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index f2440a787..99b0e3bcb 100644 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -1,6 +1,6 @@ import logging from pathlib import Path -from typing import List +from typing import Dict, List import joblib import pandas as pd @@ -47,7 +47,7 @@ def _load_signal_candles(backtest_dir: Path): return _load_backtest_analysis_data(backtest_dir, "signals") -def _load_exit_signal_candles(backtest_dir: Path): +def _load_exit_signal_candles(backtest_dir: Path) -> Dict[str, Dict[str, pd.DataFrame]]: return _load_backtest_analysis_data(backtest_dir, "exited") @@ -71,8 +71,8 @@ def _process_candles_and_indicators( def _analyze_candles_and_indicators( - pair, trades: pd.DataFrame, signal_candles: pd.DataFrame, analyse_on="open_date" -): + pair: str, trades: pd.DataFrame, signal_candles: pd.DataFrame, analyse_on="open_date" +) -> pd.DataFrame: buyf = signal_candles if len(buyf) > 0: @@ -242,7 +242,7 @@ def _select_rows_by_tags(df, enter_reason_list, exit_reason_list): def prepare_results( analysed_trades, stratname, enter_reason_list, exit_reason_list, timerange=None -): +) -> pd.DataFrame: res_df = pd.DataFrame() for pair, trades in analysed_trades[stratname].items(): if trades.shape[0] > 0: From 3ebc5b136c98e37abd7883171fea54c502730ce8 Mon Sep 17 00:00:00 2001 From: jainanuj94 Date: Tue, 6 Aug 2024 12:55:48 +0530 Subject: [PATCH 006/187] review comments and update test for exit signals --- docs/advanced-backtesting.md | 2 +- .../optimize/optimize_reports/optimize_reports.py | 2 +- tests/data/test_entryexitanalysis.py | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/advanced-backtesting.md b/docs/advanced-backtesting.md index c01d763f8..627ff20cd 100644 --- a/docs/advanced-backtesting.md +++ b/docs/advanced-backtesting.md @@ -18,7 +18,7 @@ freqtrade backtesting -c --timeframe --strategy Dict[str, DataFrame]: signal_candles_only = {} for pair in preprocessed_df.keys(): diff --git a/tests/data/test_entryexitanalysis.py b/tests/data/test_entryexitanalysis.py index 66e0179f8..b55661bab 100644 --- a/tests/data/test_entryexitanalysis.py +++ b/tests/data/test_entryexitanalysis.py @@ -18,7 +18,9 @@ def entryexitanalysis_cleanup() -> None: Backtesting.cleanup() -def test_backtest_analysis_nomock(default_conf, mocker, caplog, testdatadir, user_dir, capsys): +def test_backtest_analysis_on_entry_and_rejected_signals_nomock( + default_conf, mocker, caplog, testdatadir, user_dir, capsys +): caplog.set_level(logging.INFO) (user_dir / "backtest_results").mkdir(parents=True, exist_ok=True) @@ -140,7 +142,6 @@ def test_backtest_analysis_nomock(default_conf, mocker, caplog, testdatadir, use ) start_analysis_entries_exits(args) captured = capsys.readouterr() - assert "Analysing on exit signals." not in captured.out assert "LTC/BTC" in captured.out assert "ETH/BTC" in captured.out assert "enter_tag_long_a" in captured.out @@ -279,7 +280,7 @@ def test_backtest_analysis_on_exit_signals_nomock( ), "close_date": pd.to_datetime( [ - "2018-01-29 20:45:00", + "2018-01-30 20:45:00", "2018-01-30 05:35:00", "2018-01-30 09:10:00", "2018-01-31 15:00:00", @@ -381,7 +382,6 @@ def test_backtest_analysis_on_exit_signals_nomock( ) start_analysis_entries_exits(args) captured = capsys.readouterr() - assert "Analysing on exit signals." in captured.out assert "LTC/BTC" in captured.out assert "ETH/BTC" in captured.out assert "enter_tag_long_a" in captured.out @@ -394,7 +394,7 @@ def test_backtest_analysis_on_exit_signals_nomock( assert "-4" in captured.out assert "-2" in captured.out assert "57.654" in captured.out - assert "44.428" in captured.out + assert "-8" in captured.out assert "0" in captured.out assert "0.104" in captured.out assert "0.016" in captured.out From d351ed0173eae322f1d2ed011c91ce0debe1f83f Mon Sep 17 00:00:00 2001 From: jainanuj94 Date: Tue, 6 Aug 2024 15:16:30 +0530 Subject: [PATCH 007/187] refactor: change analyse_on variable name to date_col --- freqtrade/data/entryexitanalysis.py | 18 ++++++++---------- .../optimize_reports/optimize_reports.py | 4 ++-- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index 99b0e3bcb..4e64c1ecc 100644 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -51,10 +51,8 @@ def _load_exit_signal_candles(backtest_dir: Path) -> Dict[str, Dict[str, pd.Data return _load_backtest_analysis_data(backtest_dir, "exited") -def _process_candles_and_indicators( - pairlist, strategy_name, trades, signal_candles, analyse_on="open_date" -): - analysed_trades_dict = {strategy_name: {}} +def _process_candles_and_indicators(pairlist, strategy_name, trades, signal_candles, date_col: str): + analysed_trades_dict: Dict[str, Dict] = {strategy_name: {}} try: logger.info(f"Processing {strategy_name} : {len(pairlist)} pairs") @@ -62,7 +60,7 @@ def _process_candles_and_indicators( for pair in pairlist: if pair in signal_candles[strategy_name]: analysed_trades_dict[strategy_name][pair] = _analyze_candles_and_indicators( - pair, trades, signal_candles[strategy_name][pair], analyse_on + pair, trades, signal_candles[strategy_name][pair], date_col ) except Exception as e: print(f"Cannot process entry/exit reasons for {strategy_name}: ", e) @@ -71,7 +69,7 @@ def _process_candles_and_indicators( def _analyze_candles_and_indicators( - pair: str, trades: pd.DataFrame, signal_candles: pd.DataFrame, analyse_on="open_date" + pair: str, trades: pd.DataFrame, signal_candles: pd.DataFrame, date_col: str ) -> pd.DataFrame: buyf = signal_candles @@ -83,7 +81,7 @@ def _analyze_candles_and_indicators( if trades_red.shape[0] > 0 and buyf.shape[0] > 0: for t, v in trades_red.iterrows(): - allinds = buyf.loc[(buyf["date"] < v[analyse_on])] + allinds = buyf.loc[(buyf["date"] < v[date_col])] if allinds.shape[0] > 0: tmp_inds = allinds.iloc[[-1]] @@ -343,10 +341,10 @@ def process_entry_exit_reasons(config: Config): trades = load_backtest_data(config["exportfilename"], strategy_name) if trades is not None and not trades.empty: - analyse_on = "open_date" + date_col = "open_date" if do_exited is True: signal_candles = _load_exit_signal_candles(config["exportfilename"]) - analyse_on = "close_date" + date_col = "close_date" else: signal_candles = _load_signal_candles(config["exportfilename"]) @@ -366,7 +364,7 @@ def process_entry_exit_reasons(config: Config): strategy_name, trades, signal_candles, - analyse_on, + date_col, ) res_df = prepare_results( diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index f90bba3f9..24c2d049f 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -25,7 +25,7 @@ logger = logging.getLogger(__name__) def generate_trade_signal_candles( - preprocessed_df: Dict[str, DataFrame], bt_results: Dict[str, Any], analysis_on: str + preprocessed_df: Dict[str, DataFrame], bt_results: Dict[str, Any], date_col: str ) -> Dict[str, DataFrame]: signal_candles_only = {} for pair in preprocessed_df.keys(): @@ -37,7 +37,7 @@ def generate_trade_signal_candles( if pairdf.shape[0] > 0: for t, v in pairresults.iterrows(): - allinds = pairdf.loc[(pairdf["date"] < v[analysis_on])] + allinds = pairdf.loc[(pairdf["date"] < v[date_col])] signal_inds = allinds.iloc[[-1]] signal_candles_only_df = concat( [signal_candles_only_df.infer_objects(), signal_inds.infer_objects()] From 8085e24dcde19744e5b8e42ff9ce8212a21c2d88 Mon Sep 17 00:00:00 2001 From: jainanuj94 Date: Tue, 6 Aug 2024 20:00:05 +0530 Subject: [PATCH 008/187] update tests --- tests/optimize/test_optimize_reports.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index abbed1e54..40673a1b6 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -298,6 +298,8 @@ def test_store_backtest_candles(testdatadir, mocker): assert dump_mock.call_count == 3 assert isinstance(dump_mock.call_args_list[0][0][0], Path) assert str(dump_mock.call_args_list[0][0][0]).endswith("_signals.pkl") + assert str(dump_mock.call_args_list[1][0][0]).endswith("_rejected.pkl") + assert str(dump_mock.call_args_list[2][0][0]).endswith("_exited.pkl") dump_mock.reset_mock() # mock file exporting @@ -307,6 +309,9 @@ def test_store_backtest_candles(testdatadir, mocker): assert isinstance(dump_mock.call_args_list[0][0][0], Path) # result will be testdatadir / testresult-_signals.pkl assert str(dump_mock.call_args_list[0][0][0]).endswith("_signals.pkl") + assert str(dump_mock.call_args_list[1][0][0]).endswith("_rejected.pkl") + assert str(dump_mock.call_args_list[2][0][0]).endswith("_exited.pkl") + dump_mock.reset_mock() From 19a2e06c0bc31beff77571ffb9f56686f0a54c0f Mon Sep 17 00:00:00 2001 From: jainanuj94 Date: Sun, 18 Aug 2024 18:41:04 +0530 Subject: [PATCH 009/187] #000 | Anuj | Merge Dfs for entry and exit in one table --- freqtrade/data/entryexitanalysis.py | 93 ++++++++--- tests/data/test_entryexitanalysis.py | 241 +-------------------------- 2 files changed, 76 insertions(+), 258 deletions(-) diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index 4e64c1ecc..e217294a2 100644 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -257,16 +257,14 @@ def prepare_results( def print_results( res_df: pd.DataFrame, + exit_df: pd.DataFrame, analysis_groups: List[str], indicator_list: List[str], csv_path: Path, rejected_signals=None, to_csv=False, - exited_signals=False, ): if res_df.shape[0] > 0: - if exited_signals is True: - print("Analysing on exit signals.") if analysis_groups: _do_group_table_output(res_df, analysis_groups, to_csv=to_csv, csv_path=csv_path) @@ -286,9 +284,11 @@ def print_results( for ind in indicator_list: if ind in res_df: available_inds.append(ind) - ilist = ["pair", "enter_reason", "exit_reason"] + available_inds + + merged_df = _merge_dfs(res_df, exit_df, available_inds) + _print_table( - res_df[ilist], + merged_df, sortcols=["exit_reason"], show_index=False, name="Indicators:", @@ -299,6 +299,21 @@ def print_results( print("\\No trades to show") +def _merge_dfs(entry_df, exit_df, available_inds): + merge_on = ["pair", "open_date"] + columns_to_keep = merge_on + ["enter_reason", "exit_reason"] + available_inds + if exit_df is not None and not exit_df.empty: + merged_df = pd.merge( + entry_df[columns_to_keep], + exit_df[merge_on + available_inds], + on=merge_on, + suffixes=(" (entry)", " (exit)"), + ) + else: + merged_df = entry_df[columns_to_keep] + return merged_df + + def _print_table( df: pd.DataFrame, sortcols=None, *, show_index=False, name=None, to_csv=False, csv_path: Path ): @@ -324,7 +339,6 @@ def process_entry_exit_reasons(config: Config): enter_reason_list = config.get("enter_reason_list", ["all"]) exit_reason_list = config.get("exit_reason_list", ["all"]) indicator_list = config.get("indicator_list", []) - do_exited = config.get("analysis_exited", False) do_rejected = config.get("analysis_rejected", False) to_csv = config.get("analysis_to_csv", False) csv_path = Path(config.get("analysis_csv_path", config["exportfilename"])) @@ -341,12 +355,8 @@ def process_entry_exit_reasons(config: Config): trades = load_backtest_data(config["exportfilename"], strategy_name) if trades is not None and not trades.empty: - date_col = "open_date" - if do_exited is True: - signal_candles = _load_exit_signal_candles(config["exportfilename"]) - date_col = "close_date" - else: - signal_candles = _load_signal_candles(config["exportfilename"]) + signal_candles = _load_signal_candles(config["exportfilename"]) + exit_signals = _load_exit_signal_candles(config["exportfilename"]) rej_df = None if do_rejected: @@ -359,31 +369,64 @@ def process_entry_exit_reasons(config: Config): timerange=timerange, ) - analysed_trades_dict = _process_candles_and_indicators( + entry_df = _generate_dfs( config["exchange"]["pair_whitelist"], - strategy_name, - trades, - signal_candles, - date_col, - ) - - res_df = prepare_results( - analysed_trades_dict, - strategy_name, enter_reason_list, exit_reason_list, - timerange=timerange, + signal_candles, + strategy_name, + timerange, + trades, + "open_date", + ) + + exit_df = _generate_dfs( + config["exchange"]["pair_whitelist"], + enter_reason_list, + exit_reason_list, + exit_signals, + strategy_name, + timerange, + trades, + "close_date", ) print_results( - res_df, + entry_df, + exit_df, analysis_groups, indicator_list, rejected_signals=rej_df, to_csv=to_csv, csv_path=csv_path, - exited_signals=do_exited, ) except ValueError as e: raise OperationalException(e) from e + + +def _generate_dfs( + pairlist: list, + enter_reason_list: list, + exit_reason_list: list, + signal_candles: Dict, + strategy_name: str, + timerange: TimeRange, + trades: pd.DataFrame, + date_col: str, +) -> pd.DataFrame: + analysed_trades_dict = _process_candles_and_indicators( + pairlist, + strategy_name, + trades, + signal_candles, + date_col, + ) + res_df = prepare_results( + analysed_trades_dict, + strategy_name, + enter_reason_list, + exit_reason_list, + timerange=timerange, + ) + return res_df diff --git a/tests/data/test_entryexitanalysis.py b/tests/data/test_entryexitanalysis.py index b55661bab..39456b7a3 100644 --- a/tests/data/test_entryexitanalysis.py +++ b/tests/data/test_entryexitanalysis.py @@ -160,6 +160,14 @@ def test_backtest_analysis_on_entry_and_rejected_signals_nomock( assert "34.049" in captured.out assert "0.104" in captured.out assert "52.829" in captured.out + # assert indicator list + assert "close (entry)" in captured.out + assert "0.016" in captured.out + assert "rsi (entry)" in captured.out + assert "54.320" in captured.out + assert "close (exit)" in captured.out + assert "rsi (exit)" in captured.out + assert "52.829" in captured.out # test group 1 args = get_args(base_args + ["--analysis-groups", "1"]) @@ -247,236 +255,3 @@ def test_backtest_analysis_on_entry_and_rejected_signals_nomock( start_analysis_entries_exits(args) captured = capsys.readouterr() assert "no rejected signals" in captured.out - - -def test_backtest_analysis_on_exit_signals_nomock( - default_conf, mocker, caplog, testdatadir, user_dir, capsys -): - caplog.set_level(logging.INFO) - (user_dir / "backtest_results").mkdir(parents=True, exist_ok=True) - - default_conf.update( - { - "use_exit_signal": True, - "exit_profit_only": False, - "exit_profit_offset": 0.0, - "ignore_roi_if_entry_signal": False, - } - ) - patch_exchange(mocker) - result1 = pd.DataFrame( - { - "pair": ["ETH/BTC", "LTC/BTC", "ETH/BTC", "LTC/BTC"], - "profit_ratio": [0.025, 0.05, -0.1, -0.05], - "profit_abs": [0.5, 2.0, -4.0, -2.0], - "open_date": pd.to_datetime( - [ - "2018-01-29 18:40:00", - "2018-01-30 03:30:00", - "2018-01-30 08:10:00", - "2018-01-31 13:30:00", - ], - utc=True, - ), - "close_date": pd.to_datetime( - [ - "2018-01-30 20:45:00", - "2018-01-30 05:35:00", - "2018-01-30 09:10:00", - "2018-01-31 15:00:00", - ], - utc=True, - ), - "trade_duration": [235, 40, 60, 90], - "is_open": [False, False, False, False], - "stake_amount": [0.01, 0.01, 0.01, 0.01], - "open_rate": [0.104445, 0.10302485, 0.10302485, 0.10302485], - "close_rate": [0.104969, 0.103541, 0.102041, 0.102541], - "is_short": [False, False, False, False], - "enter_tag": [ - "enter_tag_long_a", - "enter_tag_long_b", - "enter_tag_long_a", - "enter_tag_long_b", - ], - "exit_reason": [ - ExitType.ROI.value, - ExitType.EXIT_SIGNAL.value, - ExitType.STOP_LOSS.value, - ExitType.TRAILING_STOP_LOSS.value, - ], - } - ) - - backtestmock = MagicMock( - side_effect=[ - { - "results": result1, - "config": default_conf, - "locks": [], - "rejected_signals": 20, - "timedout_entry_orders": 0, - "timedout_exit_orders": 0, - "canceled_trade_entries": 0, - "canceled_entry_orders": 0, - "replaced_entry_orders": 0, - "final_balance": 1000, - } - ] - ) - mocker.patch( - "freqtrade.plugins.pairlistmanager.PairListManager.whitelist", - PropertyMock(return_value=["ETH/BTC", "LTC/BTC", "DASH/BTC"]), - ) - mocker.patch("freqtrade.optimize.backtesting.Backtesting.backtest", backtestmock) - - patched_configuration_load_config_file(mocker, default_conf) - - args = [ - "backtesting", - "--config", - "config.json", - "--datadir", - str(testdatadir), - "--user-data-dir", - str(user_dir), - "--timeframe", - "5m", - "--timerange", - "1515560100-1517287800", - "--export", - "signals", - "--cache", - "none", - ] - args = get_args(args) - start_backtesting(args) - - captured = capsys.readouterr() - assert "BACKTESTING REPORT" in captured.out - assert "EXIT REASON STATS" in captured.out - assert "LEFT OPEN TRADES REPORT" in captured.out - - base_args = [ - "backtesting-analysis", - "--config", - "config.json", - "--datadir", - str(testdatadir), - "--user-data-dir", - str(user_dir), - ] - - # test group 0 and indicator list - args = get_args( - base_args - + [ - "--analysis-groups", - "0", - "--exit-signals", - "--indicator-list", - "close", - "rsi", - "profit_abs", - ] - ) - start_analysis_entries_exits(args) - captured = capsys.readouterr() - assert "LTC/BTC" in captured.out - assert "ETH/BTC" in captured.out - assert "enter_tag_long_a" in captured.out - assert "enter_tag_long_b" in captured.out - assert "exit_signal" in captured.out - assert "roi" in captured.out - assert "stop_loss" in captured.out - assert "trailing_stop_loss" in captured.out - assert "0.5" in captured.out - assert "-4" in captured.out - assert "-2" in captured.out - assert "57.654" in captured.out - assert "-8" in captured.out - assert "0" in captured.out - assert "0.104" in captured.out - assert "0.016" in captured.out - assert "52.829" in captured.out - - # test group 1 - args = get_args(base_args + ["--analysis-groups", "1"]) - start_analysis_entries_exits(args) - captured = capsys.readouterr() - assert "enter_tag_long_a" in captured.out - assert "enter_tag_long_b" in captured.out - assert "total_profit_pct" in captured.out - assert "-3.5" in captured.out - assert "-1.75" in captured.out - assert "-7.5" in captured.out - assert "-3.75" in captured.out - assert "0" in captured.out - - # test group 2 - args = get_args(base_args + ["--analysis-groups", "2"]) - start_analysis_entries_exits(args) - captured = capsys.readouterr() - assert "enter_tag_long_a" in captured.out - assert "enter_tag_long_b" in captured.out - assert "exit_signal" in captured.out - assert "roi" in captured.out - assert "stop_loss" in captured.out - assert "trailing_stop_loss" in captured.out - assert "total_profit_pct" in captured.out - assert "-10" in captured.out - assert "-5" in captured.out - assert "2.5" in captured.out - - # test group 3 - args = get_args(base_args + ["--analysis-groups", "3"]) - start_analysis_entries_exits(args) - captured = capsys.readouterr() - assert "LTC/BTC" in captured.out - assert "ETH/BTC" in captured.out - assert "enter_tag_long_a" in captured.out - assert "enter_tag_long_b" in captured.out - assert "total_profit_pct" in captured.out - assert "-7.5" in captured.out - assert "-3.75" in captured.out - assert "-1.75" in captured.out - assert "0" in captured.out - assert "2" in captured.out - - # test group 4 - args = get_args(base_args + ["--analysis-groups", "4"]) - start_analysis_entries_exits(args) - captured = capsys.readouterr() - assert "LTC/BTC" in captured.out - assert "ETH/BTC" in captured.out - assert "enter_tag_long_a" in captured.out - assert "enter_tag_long_b" in captured.out - assert "exit_signal" in captured.out - assert "roi" in captured.out - assert "stop_loss" in captured.out - assert "trailing_stop_loss" in captured.out - assert "total_profit_pct" in captured.out - assert "-10" in captured.out - assert "-5" in captured.out - assert "-4" in captured.out - assert "0.5" in captured.out - assert "1" in captured.out - assert "2.5" in captured.out - - # test group 5 - args = get_args(base_args + ["--analysis-groups", "5"]) - start_analysis_entries_exits(args) - captured = capsys.readouterr() - assert "exit_signal" in captured.out - assert "roi" in captured.out - assert "stop_loss" in captured.out - assert "trailing_stop_loss" in captured.out - - # test date filtering - args = get_args( - base_args + ["--analysis-groups", "0", "1", "2", "--timerange", "20180129-20180130"] - ) - start_analysis_entries_exits(args) - captured = capsys.readouterr() - assert "enter_tag_long_a" in captured.out - assert "enter_tag_long_b" not in captured.out From c3679910a43ee034e752dce01391e04d9d448d60 Mon Sep 17 00:00:00 2001 From: jainanuj94 Date: Sun, 18 Aug 2024 23:14:21 +0530 Subject: [PATCH 010/187] remove additional argument --- freqtrade/commands/arguments.py | 1 - freqtrade/commands/cli_options.py | 5 ----- freqtrade/configuration/configuration.py | 1 - 3 files changed, 7 deletions(-) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index a7ecfb83c..0c93af78a 100755 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -222,7 +222,6 @@ ARGS_ANALYZE_ENTRIES_EXITS = [ "indicator_list", "timerange", "analysis_rejected", - "analysis_exited", "analysis_to_csv", "analysis_csv_path", ] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 72df9b0c7..b9236a0ab 100755 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -720,11 +720,6 @@ AVAILABLE_CLI_OPTIONS = { help="Analyse rejected signals", action="store_true", ), - "analysis_exited": Arg( - "--exit-signals", - help="Analyse indicators at exit signals", - action="store_true", - ), "analysis_to_csv": Arg( "--analysis-to-csv", help="Save selected analysis tables to individual CSVs", diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 2e3eff740..184f9decf 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -401,7 +401,6 @@ class Configuration: ("indicator_list", "Analysis indicator list: {}"), ("timerange", "Filter trades by timerange: {}"), ("analysis_rejected", "Analyse rejected signals: {}"), - ("analysis_exited", "Analyse exited signals: {}"), ("analysis_to_csv", "Store analysis tables to CSV: {}"), ("analysis_csv_path", "Path to store analysis CSVs: {}"), # Lookahead analysis results From b6702d1d322a6c22d59c0fe2c319bfe7347d306f Mon Sep 17 00:00:00 2001 From: jainanuj94 Date: Sun, 18 Aug 2024 23:22:20 +0530 Subject: [PATCH 011/187] simplify merging logic --- freqtrade/data/entryexitanalysis.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index e217294a2..da5489731 100644 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -302,16 +302,16 @@ def print_results( def _merge_dfs(entry_df, exit_df, available_inds): merge_on = ["pair", "open_date"] columns_to_keep = merge_on + ["enter_reason", "exit_reason"] + available_inds - if exit_df is not None and not exit_df.empty: - merged_df = pd.merge( - entry_df[columns_to_keep], - exit_df[merge_on + available_inds], - on=merge_on, - suffixes=(" (entry)", " (exit)"), - ) - else: - merged_df = entry_df[columns_to_keep] - return merged_df + + if exit_df is None or exit_df.empty: + return entry_df[columns_to_keep] + + return pd.merge( + entry_df[columns_to_keep], + exit_df[merge_on + available_inds], + on=merge_on, + suffixes=(" (entry)", " (exit)"), + ) def _print_table( From 268683f8eafb17fb9c5525d5cdede9e151bdafd1 Mon Sep 17 00:00:00 2001 From: jainanuj94 Date: Mon, 19 Aug 2024 12:50:54 +0530 Subject: [PATCH 012/187] update documentation --- docs/advanced-backtesting.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/docs/advanced-backtesting.md b/docs/advanced-backtesting.md index 627ff20cd..e1f7d77d4 100644 --- a/docs/advanced-backtesting.md +++ b/docs/advanced-backtesting.md @@ -103,6 +103,10 @@ The indicators have to be present in your strategy's main DataFrame (either for timeframe or for informative timeframes) otherwise they will simply be ignored in the script output. +!!! note "Indicator List" + The indicator values will be displayed for both entry and exit points. If `--indicator-list all` is specified, + only the indicators at the entry point will be shown to avoid excessively large lists, which could occur depending on the strategy. + There are a range of candle and trade-related fields that are included in the analysis so are automatically accessible by including them on the indicator-list, and these include: @@ -141,14 +145,6 @@ Use the `--rejected-signals` option to print out rejected signals. freqtrade backtesting-analysis -c --rejected-signals ``` -### Printing analysis on exit signals - -Use the `--exit-signals` option to print out analysis on exited signals. - -```bash -freqtrade backtesting-analysis -c --exit-signals -``` - ### Writing tables to CSV Some of the tabular outputs can become large, so printing them out to the terminal is not preferable. From a881d3fd8102669d67a0ed90b31f0c7c5e431ee8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 31 Aug 2024 08:31:42 +0200 Subject: [PATCH 013/187] chore: bump version to 2024.9-dev --- freqtrade/__init__.py | 2 +- ft_client/freqtrade_client/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/__init__.py b/freqtrade/__init__.py index be9980671..ba26f214d 100644 --- a/freqtrade/__init__.py +++ b/freqtrade/__init__.py @@ -1,6 +1,6 @@ """Freqtrade bot""" -__version__ = "2024.8-dev" +__version__ = "2024.9-dev" if "dev" in __version__: from pathlib import Path diff --git a/ft_client/freqtrade_client/__init__.py b/ft_client/freqtrade_client/__init__.py index 68ef44422..d43690126 100644 --- a/ft_client/freqtrade_client/__init__.py +++ b/ft_client/freqtrade_client/__init__.py @@ -1,7 +1,7 @@ from freqtrade_client.ft_rest_client import FtRestClient -__version__ = "2024.8-dev" +__version__ = "2024.9-dev" if "dev" in __version__: from pathlib import Path From 7edc50865f498c3b5957012795060ff04915a1db Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 31 Aug 2024 08:34:48 +0200 Subject: [PATCH 014/187] docs: improve release documentation --- docs/developer.md | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/docs/developer.md b/docs/developer.md index 8cf20d966..e2f7766bb 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -481,21 +481,24 @@ Once the PR against stable is merged (best right after merging): ### pypi -!!! Note - This process is now automated as part of Github Actions. +!!! Warning "Manual Releases" + This process is automated as part of Github Actions. + Manual pypi pushes should not be necessary. -To create a pypi release, please run the following commands: +??? example "Manual release" + To manually create a pypi release, please run the following commands: -Additional requirement: `wheel`, `twine` (for uploading), account on pypi with proper permissions. + Additional requirement: `wheel`, `twine` (for uploading), account on pypi with proper permissions. -``` bash -python setup.py sdist bdist_wheel + ``` bash + pip install -U build + python -m build --sdist --wheel -# For pypi test (to check if some change to the installation did work) -twine upload --repository-url https://test.pypi.org/legacy/ dist/* + # For pypi test (to check if some change to the installation did work) + twine upload --repository-url https://test.pypi.org/legacy/ dist/* -# For production: -twine upload dist/* -``` + # For production: + twine upload dist/* + ``` -Please don't push non-releases to the productive / real pypi instance. + Please don't push non-releases to the productive / real pypi instance. From ef96116c3fbeefefac43aa3ac1b9fef9d9b84085 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 31 Aug 2024 20:34:02 +0200 Subject: [PATCH 015/187] docs: add note about freqUI support of dp.current_whitelist closes #10600 --- docs/freq-ui.md | 1 - docs/strategy-customization.md | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/freq-ui.md b/docs/freq-ui.md index 9b319d808..f1eec3cb9 100644 --- a/docs/freq-ui.md +++ b/docs/freq-ui.md @@ -58,7 +58,6 @@ The plot configuration can be accessed via the "Plot Configurator" (Cog icon) bu ### Settings - Several UI related settings can be changed by accessing the settings page. Things you can change (among others): diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index a8b9dcb4c..c7a66b03b 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -717,6 +717,7 @@ This is where calling `self.dp.current_whitelist()` comes in handy. ??? Note "Plotting with current_whitelist" Current whitelist is not supported for `plot-dataframe`, as this command is usually used by providing an explicit pairlist - and would therefore make the return values of this method misleading. + It's also not supported for freqUI visualization in [webserver mode](utils.md#webserver-mode) - as the configuration for webserver mode doesn't require a pairlist to be set. ### *get_pair_dataframe(pair, timeframe)* From a7fd03f1b79c4aac915e19af8572a37d36647bf5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 Sep 2024 08:22:58 +0200 Subject: [PATCH 016/187] chore: improve ccxt test --- tests/exchange_online/conftest.py | 2 +- tests/exchange_online/test_ccxt_compat.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/exchange_online/conftest.py b/tests/exchange_online/conftest.py index a2e6c8a74..466020551 100644 --- a/tests/exchange_online/conftest.py +++ b/tests/exchange_online/conftest.py @@ -225,7 +225,7 @@ EXCHANGES = { "id": "123412341234", "create_time": "167997798", "create_time_ms": "167997798825.566200", - "currency_pair": "ETH_USDT", + "currency_pair": "SOL_USDT", "side": "sell", "role": "taker", "amount": "0.0115", diff --git a/tests/exchange_online/test_ccxt_compat.py b/tests/exchange_online/test_ccxt_compat.py index 408f47e7d..fbb6bca05 100644 --- a/tests/exchange_online/test_ccxt_compat.py +++ b/tests/exchange_online/test_ccxt_compat.py @@ -92,9 +92,8 @@ class TestCCXTExchange: if trades := EXCHANGES[exchange_name].get("sample_my_trades"): pair = "SOL/USDT" for trade in trades: - market = exch._api.markets[pair] po = exch._api.parse_trade(trade) - (trade, market) + assert po["symbol"] == pair assert isinstance(po["id"], str) assert isinstance(po["side"], str) assert isinstance(po["amount"], float) From a554352ae0849c58a2fca66989b8ad6965d2b5c0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 Sep 2024 08:24:21 +0200 Subject: [PATCH 017/187] test: remove unused mutable argument --- tests/data/test_converter_orderflow.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/data/test_converter_orderflow.py b/tests/data/test_converter_orderflow.py index 9126edfe3..9a337da91 100644 --- a/tests/data/test_converter_orderflow.py +++ b/tests/data/test_converter_orderflow.py @@ -13,7 +13,8 @@ from freqtrade.data.converter.trade_converter import trades_list_to_df BIN_SIZE_SCALE = 0.5 -def read_csv(filename, converter_columns: list = ["side", "type"]): +def read_csv(filename): + converter_columns: list = ["side", "type"] return pd.read_csv( filename, skipinitialspace=True, From c6b46d75cbf3510a29586eef912b999ddfcd6067 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 Sep 2024 08:24:47 +0200 Subject: [PATCH 018/187] chore: fix B018 violation --- tests/data/test_download_data.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/data/test_download_data.py b/tests/data/test_download_data.py index f2c8a51d4..f26a30ce1 100644 --- a/tests/data/test_download_data.py +++ b/tests/data/test_download_data.py @@ -86,7 +86,6 @@ def test_download_data_main_trades(mocker): # Exchange that doesn't support historic downloads config["exchange"]["name"] = "bybit" with pytest.raises(OperationalException, match=r"Trade history not available for .*"): - config download_data_main(config) From b25520cf1821cd34ff02cd7e435949476ddecd2b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 Sep 2024 08:27:53 +0200 Subject: [PATCH 019/187] chore: improve rhci_progress typing, remove mutable arguments --- freqtrade/util/rich_progress.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/freqtrade/util/rich_progress.py b/freqtrade/util/rich_progress.py index f4f993f7e..b7d8f4c3d 100644 --- a/freqtrade/util/rich_progress.py +++ b/freqtrade/util/rich_progress.py @@ -1,13 +1,20 @@ -from typing import Callable, List, Union +from typing import Callable, List, Optional, Union from rich.console import ConsoleRenderable, Group, RichCast from rich.progress import Progress class CustomProgress(Progress): - def __init__(self, *args, cust_objs=[], cust_callables: List[Callable] = [], **kwargs) -> None: - self._cust_objs = cust_objs - self._cust_callables = cust_callables + def __init__( + self, + *args, + cust_objs: Optional[List[ConsoleRenderable]] = None, + cust_callables: Optional[List[Callable[[], ConsoleRenderable]]] = None, + **kwargs, + ) -> None: + self._cust_objs = cust_objs or [] + self._cust_callables = cust_callables or [] + super().__init__(*args, **kwargs) def get_renderable(self) -> Union[ConsoleRenderable, RichCast, str]: From 97c937e554c4f799a193111a86687a281a8040bf Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 Sep 2024 08:32:42 +0200 Subject: [PATCH 020/187] chore: add Bugbear Ruff checking --- freqtrade/configuration/configuration.py | 2 +- pyproject.toml | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 184f9decf..d9c860abd 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -468,7 +468,7 @@ class Configuration: else: logger.info(logstring.format(config[argname])) if deprecated_msg: - warnings.warn(f"DEPRECATED: {deprecated_msg}", DeprecationWarning) + warnings.warn(f"DEPRECATED: {deprecated_msg}", DeprecationWarning, stacklevel=1) def _resolve_pairs_list(self, config: Config) -> None: """ diff --git a/pyproject.toml b/pyproject.toml index 49fdff752..bd36d15c6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -128,7 +128,7 @@ target-version = "py38" # Exclude UP036 as it's causing the "exit if < 3.9" to fail. extend-select = [ "C90", # mccabe - # "B", # bugbear + "B", # bugbear # "N", # pep8-naming "F", # pyflakes "E", # pycodestyle @@ -155,10 +155,11 @@ extend-ignore = [ "E272", # Multiple spaces before keyword "E221", # Multiple spaces before operator "B007", # Loop control variable not used + "B904", # BugBear - except raise from "S603", # `subprocess` call: check for execution of untrusted input "S607", # Starting a process with a partial executable path "S608", # Possible SQL injection vector through string-based query construction - "NPY002", # Numpy legacy random generator + "NPY002", # Numpy legacy random generator ] [tool.ruff.lint.mccabe] @@ -166,7 +167,9 @@ max-complexity = 12 [tool.ruff.lint.per-file-ignores] "freqtrade/freqai/**/*.py" = [ - "S311" # Standard pseudo-random generators are not suitable for cryptographic purposes + "S311", # Standard pseudo-random generators are not suitable for cryptographic purposes + "B006", # Bugbear - mutable default argument + "B008", # bugbear - Do not perform function calls in argument defaults ] "tests/**/*.py" = [ "S101", # allow assert in tests From 4726afbebff19551a2ab6f67c01d92a9edd852eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 03:04:55 +0000 Subject: [PATCH 021/187] chore(deps): bump the mkdocs group with 2 updates Bumps the mkdocs group with 2 updates: [mkdocs](https://github.com/mkdocs/mkdocs) and [mkdocs-material](https://github.com/squidfunk/mkdocs-material). Updates `mkdocs` from 1.6.0 to 1.6.1 - [Release notes](https://github.com/mkdocs/mkdocs/releases) - [Commits](https://github.com/mkdocs/mkdocs/compare/1.6.0...1.6.1) Updates `mkdocs-material` from 9.5.33 to 9.5.34 - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.33...9.5.34) --- updated-dependencies: - dependency-name: mkdocs dependency-type: direct:production update-type: version-update:semver-patch dependency-group: mkdocs - dependency-name: mkdocs-material dependency-type: direct:production update-type: version-update:semver-patch dependency-group: mkdocs ... Signed-off-by: dependabot[bot] --- docs/requirements-docs.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index 91a2ad768..a354b3fc0 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,6 +1,6 @@ markdown==3.7 -mkdocs==1.6.0 -mkdocs-material==9.5.33 +mkdocs==1.6.1 +mkdocs-material==9.5.34 mdx_truly_sane_lists==1.3 pymdown-extensions==10.9 jinja2==3.1.4 From 96d03ec13d1d0d6d6ae757c5e06cb22a2a4c3b61 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 03:05:06 +0000 Subject: [PATCH 022/187] chore(deps-dev): bump ruff from 0.6.2 to 0.6.3 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.2 to 0.6.3. - [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.6.2...0.6.3) --- updated-dependencies: - dependency-name: ruff 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 63c43e820..b0a46db71 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,7 +7,7 @@ -r docs/requirements-docs.txt coveralls==4.0.1 -ruff==0.6.2 +ruff==0.6.3 mypy==1.11.2 pre-commit==3.8.0 pytest==8.3.2 From 17617c58d7c6a8a25597061a3372339270638923 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 03:05:10 +0000 Subject: [PATCH 023/187] chore(deps): bump rich from 13.7.1 to 13.8.0 Bumps [rich](https://github.com/Textualize/rich) from 13.7.1 to 13.8.0. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.7.1...v13.8.0) --- updated-dependencies: - dependency-name: rich 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 4cf3132b8..efda746b0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -26,7 +26,7 @@ jinja2==3.1.4 tables==3.9.1; python_version < "3.10" tables==3.10.1; python_version >= "3.10" joblib==1.4.2 -rich==13.7.1 +rich==13.8.0 pyarrow==17.0.0; platform_machine != 'armv7l' # find first, C search in arrays From 803677e8841b41fefe50a90d9b5005ea7e1c9174 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 03:05:14 +0000 Subject: [PATCH 024/187] chore(deps): bump plotly from 5.23.0 to 5.24.0 Bumps [plotly](https://github.com/plotly/plotly.py) from 5.23.0 to 5.24.0. - [Release notes](https://github.com/plotly/plotly.py/releases) - [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md) - [Commits](https://github.com/plotly/plotly.py/compare/v5.23.0...v5.24.0) --- updated-dependencies: - dependency-name: plotly dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements-plot.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-plot.txt b/requirements-plot.txt index 6641fe524..987447cb2 100644 --- a/requirements-plot.txt +++ b/requirements-plot.txt @@ -1,4 +1,4 @@ # Include all requirements to run the bot. -r requirements.txt -plotly==5.23.0 +plotly==5.24.0 From 4d53797cbac682bb65c13ce7836fb57e1da6780d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 03:05:21 +0000 Subject: [PATCH 025/187] chore(deps): bump websockets from 13.0 to 13.0.1 Bumps [websockets](https://github.com/python-websockets/websockets) from 13.0 to 13.0.1. - [Release notes](https://github.com/python-websockets/websockets/releases) - [Commits](https://github.com/python-websockets/websockets/compare/13.0...13.0.1) --- updated-dependencies: - dependency-name: websockets 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 4cf3132b8..0b8ee1538 100644 --- a/requirements.txt +++ b/requirements.txt @@ -59,7 +59,7 @@ pytz==2024.1 schedule==1.2.2 #WS Messages -websockets==13.0 +websockets==13.0.1 janus==1.0.0 ast-comments==1.2.2 From 585761e9319b6ecafbb008c2d5c43718b893479c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 03:05:45 +0000 Subject: [PATCH 026/187] chore(deps): bump python-telegram-bot from 21.4 to 21.5 Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 21.4 to 21.5. - [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases) - [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst) - [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v21.4...v21.5) --- updated-dependencies: - dependency-name: python-telegram-bot 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 4cf3132b8..38d8faa82 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,7 +9,7 @@ cryptography==42.0.8; platform_machine == 'armv7l' cryptography==43.0.0; platform_machine != 'armv7l' aiohttp==3.10.5 SQLAlchemy==2.0.32 -python-telegram-bot==21.4 +python-telegram-bot==21.5 # can't be hard-pinned due to telegram-bot pinning httpx with ~ httpx>=0.24.1 humanize==4.10.0 From 904f5303a6599ee9387ce0e4ed6838d8e5ee6790 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 03:05:58 +0000 Subject: [PATCH 027/187] chore(deps): bump pypa/gh-action-pypi-publish from 1.9.0 to 1.10.0 Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.9.0 to 1.10.0. - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.9.0...v1.10.0) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db11ba833..6ec36161b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -537,12 +537,12 @@ jobs: - name: Publish to PyPI (Test) - uses: pypa/gh-action-pypi-publish@v1.9.0 + uses: pypa/gh-action-pypi-publish@v1.10.0 with: repository-url: https://test.pypi.org/legacy/ - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@v1.9.0 + uses: pypa/gh-action-pypi-publish@v1.10.0 deploy-docker: From 4a1592dd92e66822c3f8c750731b085727898ec5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 2 Sep 2024 06:57:02 +0200 Subject: [PATCH 028/187] feat: initialize hyperliquid in spot mode by default --- freqtrade/exchange/hyperliquid.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/freqtrade/exchange/hyperliquid.py b/freqtrade/exchange/hyperliquid.py index 1255b977a..f8835d1dc 100644 --- a/freqtrade/exchange/hyperliquid.py +++ b/freqtrade/exchange/hyperliquid.py @@ -5,6 +5,7 @@ from typing import Dict from ccxt import SIGNIFICANT_DIGITS +from freqtrade.enums import TradingMode from freqtrade.exchange import Exchange @@ -25,6 +26,16 @@ class Hyperliquid(Exchange): "exchange_has_overrides": {"fetchTrades": False}, } + @property + def _ccxt_config(self) -> Dict: + # Parameters to add directly to ccxt sync/async initialization. + # ccxt defaults to swap mode. + config = {} + if self.trading_mode == TradingMode.SPOT: + config.update({"options": {"defaultType": "spot"}}) + config.update(super()._ccxt_config) + return config + @property def precision_mode_price(self) -> int: """ From d4ba83764150b37593a367849ea8b14128e182f8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 2 Sep 2024 06:58:30 +0200 Subject: [PATCH 029/187] chore: mark Bybit as supported exchange --- README.md | 1 + docs/index.md | 1 + freqtrade/exchange/common.py | 1 + 3 files changed, 3 insertions(+) diff --git a/README.md b/README.md index 137078214..317a6cfdf 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Please read the [exchange specific notes](docs/exchanges.md) to learn about even - [X] [Binance](https://www.binance.com/) - [X] [Bitmart](https://bitmart.com/) - [X] [BingX](https://bingx.com/invite/0EM9RX) +- [X] [Bybit](https://bybit.com/) - [X] [Gate.io](https://www.gate.io/ref/6266643) - [X] [HTX](https://www.htx.com/) (Former Huobi) - [X] [Kraken](https://kraken.com/) diff --git a/docs/index.md b/docs/index.md index 55835f555..f2d1482c9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -42,6 +42,7 @@ Please read the [exchange specific notes](exchanges.md) to learn about eventual, - [X] [Binance](https://www.binance.com/) - [X] [Bitmart](https://bitmart.com/) - [X] [BingX](https://bingx.com/invite/0EM9RX) +- [X] [Bybit](https://bybit.com/) - [X] [Gate.io](https://www.gate.io/ref/6266643) - [X] [HTX](https://www.htx.com/) (Former Huobi) - [X] [Kraken](https://kraken.com/) diff --git a/freqtrade/exchange/common.py b/freqtrade/exchange/common.py index 224f24efc..cac86ab3c 100644 --- a/freqtrade/exchange/common.py +++ b/freqtrade/exchange/common.py @@ -54,6 +54,7 @@ SUPPORTED_EXCHANGES = [ "binance", "bingx", "bitmart", + "bybit", "gate", "htx", "kraken", From bc4c6935259a622f459e8bd0106b6877c25768ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 05:08:37 +0000 Subject: [PATCH 030/187] chore(deps): bump ccxt from 4.3.88 to 4.3.93 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.3.88 to 4.3.93. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.3.88...4.3.93) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 69130c41e..fc968b590 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ bottleneck==1.4.0 numexpr==2.10.1 pandas-ta==0.3.14b -ccxt==4.3.88 +ccxt==4.3.93 cryptography==42.0.8; platform_machine == 'armv7l' cryptography==43.0.0; platform_machine != 'armv7l' aiohttp==3.10.5 From 331db99a4ea855680898306d87b029d816af27a4 Mon Sep 17 00:00:00 2001 From: xmatthias <5024695+xmatthias@users.noreply.github.com> Date: Tue, 3 Sep 2024 03:02:47 +0000 Subject: [PATCH 031/187] chore: update pre-commit hooks --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f69ac5737..3e1d9fa34 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: - repo: https://github.com/charliermarsh/ruff-pre-commit # Ruff version. - rev: 'v0.6.2' + rev: 'v0.6.3' hooks: - id: ruff From c0e9173c9b24ed612a833c19e7deec34fe53c22a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 00:25:37 +0000 Subject: [PATCH 032/187] chore(deps): bump cryptography from 42.0.8 to 43.0.1 Bumps [cryptography](https://github.com/pyca/cryptography) from 42.0.8 to 43.0.1. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/42.0.8...43.0.1) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 8add4c773..31d663b15 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ pandas-ta==0.3.14b ccxt==4.3.93 cryptography==42.0.8; platform_machine == 'armv7l' -cryptography==43.0.0; platform_machine != 'armv7l' +cryptography==43.0.1; platform_machine != 'armv7l' aiohttp==3.10.5 SQLAlchemy==2.0.32 python-telegram-bot==21.5 From 08d5174d026f0cabce5262c216e0ddbf6a7445dd Mon Sep 17 00:00:00 2001 From: Anuj Jain Date: Wed, 4 Sep 2024 09:56:12 +0530 Subject: [PATCH 033/187] update documentation and add default values --- docs/advanced-backtesting.md | 21 +++++++++++++++++++++ freqtrade/data/entryexitanalysis.py | 6 ++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/docs/advanced-backtesting.md b/docs/advanced-backtesting.md index e1f7d77d4..de1264ae8 100644 --- a/docs/advanced-backtesting.md +++ b/docs/advanced-backtesting.md @@ -122,6 +122,27 @@ automatically accessible by including them on the indicator-list, and these incl - **profit_ratio :** trade profit ratio - **profit_abs :** absolute profit return of the trade +#### Sample Output for Indicator Values + +```bash +freqtrade backtesting-analysis -c user_data/config.json --analysis-groups 0 --indicator-list chikou_span tenkan_sen +``` +In this example, +we aim to display the `chikou_span` and `tenkan_sen` indicator values at both the entry and exit points of trades. + +A sample output for indicators might look like this: + +| pair | open_date | enter_reason | exit_reason | chikou_span (entry) | tenkan_sen (entry) | chikou_span (exit) | tenkan_sen (exit) | +|-----------|---------------------------|--------------|-------------|---------------------|--------------------|--------------------|-------------------| +| DOGE/USDT | 2024-07-06 00:35:00+00:00 | | exit_signal | 0.105 | 0.106 | 0.105 | 0.107 | +| BTC/USDT | 2024-08-05 14:20:00+00:00 | | roi | 54643.440 | 51696.400 | 54386.000 | 52072.010 | + +As shown in the table, `chikou_span (entry)` represents the indicator value at the time of trade entry, +while `chikou_span (exit)` reflects its value at the time of exit. +This detailed view of indicator values enhances the analysis. + +The `(entry)` and `(exit)` suffixes are added to indicators +to distinguish the values at the entry and exit points of the trade. ### Filtering the trade output by date diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index da5489731..964c4f86f 100644 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -51,7 +51,9 @@ def _load_exit_signal_candles(backtest_dir: Path) -> Dict[str, Dict[str, pd.Data return _load_backtest_analysis_data(backtest_dir, "exited") -def _process_candles_and_indicators(pairlist, strategy_name, trades, signal_candles, date_col: str): +def _process_candles_and_indicators( + pairlist, strategy_name, trades, signal_candles, date_col: str = "open_date" +): analysed_trades_dict: Dict[str, Dict] = {strategy_name: {}} try: @@ -69,7 +71,7 @@ def _process_candles_and_indicators(pairlist, strategy_name, trades, signal_cand def _analyze_candles_and_indicators( - pair: str, trades: pd.DataFrame, signal_candles: pd.DataFrame, date_col: str + pair: str, trades: pd.DataFrame, signal_candles: pd.DataFrame, date_col: str = "open_date" ) -> pd.DataFrame: buyf = signal_candles From e3a5831d64a59ac88ca7f922bc4a555f84beb1c6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 4 Sep 2024 06:42:51 +0200 Subject: [PATCH 034/187] refactor: rename exchange.types --- freqtrade/data/dataprovider.py | 2 +- freqtrade/exchange/binance.py | 2 +- freqtrade/exchange/exchange.py | 16 ++++++++-------- .../exchange/{types.py => exchange_types.py} | 0 freqtrade/exchange/exchange_ws.py | 2 +- freqtrade/exchange/kraken.py | 2 +- freqtrade/plugins/pairlist/AgeFilter.py | 2 +- freqtrade/plugins/pairlist/FullTradesFilter.py | 2 +- freqtrade/plugins/pairlist/IPairList.py | 2 +- freqtrade/plugins/pairlist/MarketCapPairList.py | 2 +- freqtrade/plugins/pairlist/OffsetFilter.py | 2 +- .../plugins/pairlist/PercentChangePairList.py | 2 +- freqtrade/plugins/pairlist/PerformanceFilter.py | 2 +- freqtrade/plugins/pairlist/PrecisionFilter.py | 2 +- freqtrade/plugins/pairlist/PriceFilter.py | 2 +- freqtrade/plugins/pairlist/ProducerPairList.py | 2 +- freqtrade/plugins/pairlist/RemotePairList.py | 2 +- freqtrade/plugins/pairlist/ShuffleFilter.py | 2 +- freqtrade/plugins/pairlist/SpreadFilter.py | 2 +- freqtrade/plugins/pairlist/StaticPairList.py | 2 +- freqtrade/plugins/pairlist/VolatilityFilter.py | 2 +- freqtrade/plugins/pairlist/VolumePairList.py | 2 +- .../plugins/pairlist/rangestabilityfilter.py | 2 +- freqtrade/plugins/pairlistmanager.py | 2 +- freqtrade/rpc/rpc.py | 2 +- 25 files changed, 31 insertions(+), 31 deletions(-) rename freqtrade/exchange/{types.py => exchange_types.py} (100%) diff --git a/freqtrade/data/dataprovider.py b/freqtrade/data/dataprovider.py index 6db9831b3..b4950f515 100644 --- a/freqtrade/data/dataprovider.py +++ b/freqtrade/data/dataprovider.py @@ -23,7 +23,7 @@ from freqtrade.data.history import get_datahandler, load_pair_history from freqtrade.enums import CandleType, RPCMessageType, RunMode, TradingMode from freqtrade.exceptions import ExchangeError, OperationalException from freqtrade.exchange import Exchange, timeframe_to_prev_date, timeframe_to_seconds -from freqtrade.exchange.types import OrderBook +from freqtrade.exchange.exchange_types import OrderBook from freqtrade.misc import append_candles_to_dataframe from freqtrade.rpc import RPCManager from freqtrade.rpc.rpc_types import RPCAnalyzedDFMsg diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index d347c2cd9..2b681081a 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -11,7 +11,7 @@ from freqtrade.enums import CandleType, MarginMode, PriceType, TradingMode from freqtrade.exceptions import DDosProtection, OperationalException, TemporaryError from freqtrade.exchange import Exchange from freqtrade.exchange.common import retrier -from freqtrade.exchange.types import OHLCVResponse, Tickers +from freqtrade.exchange.exchange_types import OHLCVResponse, Tickers from freqtrade.misc import deep_merge_dicts, json_load diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 48e800d35..7bd8b694b 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -67,6 +67,14 @@ from freqtrade.exchange.common import ( retrier, retrier_async, ) +from freqtrade.exchange.exchange_types import ( + CcxtBalances, + CcxtPosition, + OHLCVResponse, + OrderBook, + Ticker, + Tickers, +) from freqtrade.exchange.exchange_utils import ( ROUND, ROUND_DOWN, @@ -88,14 +96,6 @@ from freqtrade.exchange.exchange_utils_timeframe import ( timeframe_to_seconds, ) from freqtrade.exchange.exchange_ws import ExchangeWS -from freqtrade.exchange.types import ( - CcxtBalances, - CcxtPosition, - OHLCVResponse, - OrderBook, - Ticker, - Tickers, -) from freqtrade.misc import ( chunks, deep_merge_dicts, diff --git a/freqtrade/exchange/types.py b/freqtrade/exchange/exchange_types.py similarity index 100% rename from freqtrade/exchange/types.py rename to freqtrade/exchange/exchange_types.py diff --git a/freqtrade/exchange/exchange_ws.py b/freqtrade/exchange/exchange_ws.py index 0c093171b..5851cdea6 100644 --- a/freqtrade/exchange/exchange_ws.py +++ b/freqtrade/exchange/exchange_ws.py @@ -11,7 +11,7 @@ import ccxt from freqtrade.constants import Config, PairWithTimeframe from freqtrade.enums.candletype import CandleType from freqtrade.exchange.exchange import timeframe_to_seconds -from freqtrade.exchange.types import OHLCVResponse +from freqtrade.exchange.exchange_types import OHLCVResponse from freqtrade.util import dt_ts, format_ms_time diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index 4b178420a..b0734cb6c 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -12,7 +12,7 @@ from freqtrade.enums import MarginMode, TradingMode from freqtrade.exceptions import DDosProtection, OperationalException, TemporaryError from freqtrade.exchange import Exchange from freqtrade.exchange.common import retrier -from freqtrade.exchange.types import CcxtBalances, Tickers +from freqtrade.exchange.exchange_types import CcxtBalances, Tickers logger = logging.getLogger(__name__) diff --git a/freqtrade/plugins/pairlist/AgeFilter.py b/freqtrade/plugins/pairlist/AgeFilter.py index 88f0d23d8..0c691346a 100644 --- a/freqtrade/plugins/pairlist/AgeFilter.py +++ b/freqtrade/plugins/pairlist/AgeFilter.py @@ -11,7 +11,7 @@ from pandas import DataFrame from freqtrade.constants import ListPairsWithTimeframes from freqtrade.exceptions import OperationalException -from freqtrade.exchange.types import Tickers +from freqtrade.exchange.exchange_types import Tickers from freqtrade.misc import plural from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting from freqtrade.util import PeriodicCache, dt_floor_day, dt_now, dt_ts diff --git a/freqtrade/plugins/pairlist/FullTradesFilter.py b/freqtrade/plugins/pairlist/FullTradesFilter.py index caa69cb1e..ba7590ae1 100644 --- a/freqtrade/plugins/pairlist/FullTradesFilter.py +++ b/freqtrade/plugins/pairlist/FullTradesFilter.py @@ -5,7 +5,7 @@ Full trade slots pair list filter import logging from typing import List -from freqtrade.exchange.types import Tickers +from freqtrade.exchange.exchange_types import Tickers from freqtrade.persistence import Trade from freqtrade.plugins.pairlist.IPairList import IPairList, SupportsBacktesting diff --git a/freqtrade/plugins/pairlist/IPairList.py b/freqtrade/plugins/pairlist/IPairList.py index e84700f8f..755f52b06 100644 --- a/freqtrade/plugins/pairlist/IPairList.py +++ b/freqtrade/plugins/pairlist/IPairList.py @@ -11,7 +11,7 @@ from typing import Any, Dict, List, Literal, Optional, TypedDict, Union from freqtrade.constants import Config from freqtrade.exceptions import OperationalException from freqtrade.exchange import Exchange, market_is_active -from freqtrade.exchange.types import Ticker, Tickers +from freqtrade.exchange.exchange_types import Ticker, Tickers from freqtrade.mixins import LoggingMixin diff --git a/freqtrade/plugins/pairlist/MarketCapPairList.py b/freqtrade/plugins/pairlist/MarketCapPairList.py index 677abed4b..95f0e2805 100644 --- a/freqtrade/plugins/pairlist/MarketCapPairList.py +++ b/freqtrade/plugins/pairlist/MarketCapPairList.py @@ -10,7 +10,7 @@ from typing import Dict, List from cachetools import TTLCache from freqtrade.exceptions import OperationalException -from freqtrade.exchange.types import Tickers +from freqtrade.exchange.exchange_types import Tickers from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting from freqtrade.util.coin_gecko import FtCoinGeckoApi diff --git a/freqtrade/plugins/pairlist/OffsetFilter.py b/freqtrade/plugins/pairlist/OffsetFilter.py index 5defaaf60..f06ec411d 100644 --- a/freqtrade/plugins/pairlist/OffsetFilter.py +++ b/freqtrade/plugins/pairlist/OffsetFilter.py @@ -6,7 +6,7 @@ import logging from typing import Dict, List from freqtrade.exceptions import OperationalException -from freqtrade.exchange.types import Tickers +from freqtrade.exchange.exchange_types import Tickers from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting diff --git a/freqtrade/plugins/pairlist/PercentChangePairList.py b/freqtrade/plugins/pairlist/PercentChangePairList.py index b22891b98..411edbf26 100644 --- a/freqtrade/plugins/pairlist/PercentChangePairList.py +++ b/freqtrade/plugins/pairlist/PercentChangePairList.py @@ -16,7 +16,7 @@ from pandas import DataFrame from freqtrade.constants import ListPairsWithTimeframes, PairWithTimeframe from freqtrade.exceptions import OperationalException from freqtrade.exchange import timeframe_to_minutes, timeframe_to_prev_date -from freqtrade.exchange.types import Ticker, Tickers +from freqtrade.exchange.exchange_types import Ticker, Tickers from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting from freqtrade.util import dt_now, format_ms_time diff --git a/freqtrade/plugins/pairlist/PerformanceFilter.py b/freqtrade/plugins/pairlist/PerformanceFilter.py index 77a2caf56..64f9529ed 100644 --- a/freqtrade/plugins/pairlist/PerformanceFilter.py +++ b/freqtrade/plugins/pairlist/PerformanceFilter.py @@ -7,7 +7,7 @@ from typing import Dict, List import pandas as pd -from freqtrade.exchange.types import Tickers +from freqtrade.exchange.exchange_types import Tickers from freqtrade.persistence import Trade from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting diff --git a/freqtrade/plugins/pairlist/PrecisionFilter.py b/freqtrade/plugins/pairlist/PrecisionFilter.py index 660ff8fea..43072a26a 100644 --- a/freqtrade/plugins/pairlist/PrecisionFilter.py +++ b/freqtrade/plugins/pairlist/PrecisionFilter.py @@ -7,7 +7,7 @@ from typing import Optional from freqtrade.exceptions import OperationalException from freqtrade.exchange import ROUND_UP -from freqtrade.exchange.types import Ticker +from freqtrade.exchange.exchange_types import Ticker from freqtrade.plugins.pairlist.IPairList import IPairList, SupportsBacktesting diff --git a/freqtrade/plugins/pairlist/PriceFilter.py b/freqtrade/plugins/pairlist/PriceFilter.py index 3da7d8443..efea28683 100644 --- a/freqtrade/plugins/pairlist/PriceFilter.py +++ b/freqtrade/plugins/pairlist/PriceFilter.py @@ -6,7 +6,7 @@ import logging from typing import Dict, Optional from freqtrade.exceptions import OperationalException -from freqtrade.exchange.types import Ticker +from freqtrade.exchange.exchange_types import Ticker from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting diff --git a/freqtrade/plugins/pairlist/ProducerPairList.py b/freqtrade/plugins/pairlist/ProducerPairList.py index 18af7a734..b52dd46b9 100644 --- a/freqtrade/plugins/pairlist/ProducerPairList.py +++ b/freqtrade/plugins/pairlist/ProducerPairList.py @@ -8,7 +8,7 @@ import logging from typing import Dict, List, Optional from freqtrade.exceptions import OperationalException -from freqtrade.exchange.types import Tickers +from freqtrade.exchange.exchange_types import Tickers from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting diff --git a/freqtrade/plugins/pairlist/RemotePairList.py b/freqtrade/plugins/pairlist/RemotePairList.py index 317aad20b..8a28af123 100644 --- a/freqtrade/plugins/pairlist/RemotePairList.py +++ b/freqtrade/plugins/pairlist/RemotePairList.py @@ -15,7 +15,7 @@ from cachetools import TTLCache from freqtrade import __version__ from freqtrade.configuration.load_config import CONFIG_PARSE_MODE from freqtrade.exceptions import OperationalException -from freqtrade.exchange.types import Tickers +from freqtrade.exchange.exchange_types import Tickers from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist diff --git a/freqtrade/plugins/pairlist/ShuffleFilter.py b/freqtrade/plugins/pairlist/ShuffleFilter.py index 3882ec8a8..bad2602d2 100644 --- a/freqtrade/plugins/pairlist/ShuffleFilter.py +++ b/freqtrade/plugins/pairlist/ShuffleFilter.py @@ -8,7 +8,7 @@ from typing import Dict, List, Literal from freqtrade.enums import RunMode from freqtrade.exchange import timeframe_to_seconds -from freqtrade.exchange.types import Tickers +from freqtrade.exchange.exchange_types import Tickers from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting from freqtrade.util.periodic_cache import PeriodicCache diff --git a/freqtrade/plugins/pairlist/SpreadFilter.py b/freqtrade/plugins/pairlist/SpreadFilter.py index 00109abb3..5e4e9de94 100644 --- a/freqtrade/plugins/pairlist/SpreadFilter.py +++ b/freqtrade/plugins/pairlist/SpreadFilter.py @@ -6,7 +6,7 @@ import logging from typing import Dict, Optional from freqtrade.exceptions import OperationalException -from freqtrade.exchange.types import Ticker +from freqtrade.exchange.exchange_types import Ticker from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting diff --git a/freqtrade/plugins/pairlist/StaticPairList.py b/freqtrade/plugins/pairlist/StaticPairList.py index c4f322353..0591f4f19 100644 --- a/freqtrade/plugins/pairlist/StaticPairList.py +++ b/freqtrade/plugins/pairlist/StaticPairList.py @@ -8,7 +8,7 @@ import logging from copy import deepcopy from typing import Dict, List -from freqtrade.exchange.types import Tickers +from freqtrade.exchange.exchange_types import Tickers from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting diff --git a/freqtrade/plugins/pairlist/VolatilityFilter.py b/freqtrade/plugins/pairlist/VolatilityFilter.py index 2d11e45ef..a2808ddfe 100644 --- a/freqtrade/plugins/pairlist/VolatilityFilter.py +++ b/freqtrade/plugins/pairlist/VolatilityFilter.py @@ -13,7 +13,7 @@ from pandas import DataFrame from freqtrade.constants import ListPairsWithTimeframes from freqtrade.exceptions import OperationalException -from freqtrade.exchange.types import Tickers +from freqtrade.exchange.exchange_types import Tickers from freqtrade.misc import plural from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting from freqtrade.util import dt_floor_day, dt_now, dt_ts diff --git a/freqtrade/plugins/pairlist/VolumePairList.py b/freqtrade/plugins/pairlist/VolumePairList.py index 7cc91f743..4b56e0c7f 100644 --- a/freqtrade/plugins/pairlist/VolumePairList.py +++ b/freqtrade/plugins/pairlist/VolumePairList.py @@ -13,7 +13,7 @@ from cachetools import TTLCache from freqtrade.constants import ListPairsWithTimeframes from freqtrade.exceptions import OperationalException from freqtrade.exchange import timeframe_to_minutes, timeframe_to_prev_date -from freqtrade.exchange.types import Tickers +from freqtrade.exchange.exchange_types import Tickers from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting from freqtrade.util import dt_now, format_ms_time diff --git a/freqtrade/plugins/pairlist/rangestabilityfilter.py b/freqtrade/plugins/pairlist/rangestabilityfilter.py index 175e5b18a..25cc6e423 100644 --- a/freqtrade/plugins/pairlist/rangestabilityfilter.py +++ b/freqtrade/plugins/pairlist/rangestabilityfilter.py @@ -11,7 +11,7 @@ from pandas import DataFrame from freqtrade.constants import ListPairsWithTimeframes from freqtrade.exceptions import OperationalException -from freqtrade.exchange.types import Tickers +from freqtrade.exchange.exchange_types import Tickers from freqtrade.misc import plural from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting from freqtrade.util import dt_floor_day, dt_now, dt_ts diff --git a/freqtrade/plugins/pairlistmanager.py b/freqtrade/plugins/pairlistmanager.py index 803a60d18..ba80d09da 100644 --- a/freqtrade/plugins/pairlistmanager.py +++ b/freqtrade/plugins/pairlistmanager.py @@ -13,7 +13,7 @@ from freqtrade.data.dataprovider import DataProvider from freqtrade.enums import CandleType from freqtrade.enums.runmode import RunMode from freqtrade.exceptions import OperationalException -from freqtrade.exchange.types import Tickers +from freqtrade.exchange.exchange_types import Tickers from freqtrade.mixins import LoggingMixin from freqtrade.plugins.pairlist.IPairList import IPairList, SupportsBacktesting from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 0c555e860..99fcaf7d7 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -31,7 +31,7 @@ from freqtrade.enums import ( ) from freqtrade.exceptions import ExchangeError, PricingError from freqtrade.exchange import timeframe_to_minutes, timeframe_to_msecs -from freqtrade.exchange.types import Tickers +from freqtrade.exchange.exchange_types import Tickers from freqtrade.loggers import bufferHandler from freqtrade.persistence import KeyStoreKeys, KeyValueStore, PairLocks, Trade from freqtrade.persistence.models import PairLock From d6b274829394c4899831c0d8f6e1d22ae3bca557 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 4 Sep 2024 06:44:48 +0200 Subject: [PATCH 035/187] chore: rename types to ft_types --- freqtrade/commands/list_commands.py | 2 +- freqtrade/data/btanalysis.py | 2 +- freqtrade/exchange/exchange_utils.py | 2 +- freqtrade/{types => ft_types}/__init__.py | 4 ++-- freqtrade/{types => ft_types}/backtest_result_type.py | 0 freqtrade/{types => ft_types}/valid_exchanges_type.py | 0 freqtrade/optimize/backtesting.py | 2 +- freqtrade/optimize/optimize_reports/bt_output.py | 2 +- freqtrade/optimize/optimize_reports/bt_storage.py | 2 +- freqtrade/optimize/optimize_reports/optimize_reports.py | 2 +- freqtrade/rpc/api_server/api_backtest.py | 2 +- freqtrade/rpc/api_server/api_schemas.py | 2 +- 12 files changed, 11 insertions(+), 11 deletions(-) rename freqtrade/{types => ft_types}/__init__.py (52%) rename freqtrade/{types => ft_types}/backtest_result_type.py (100%) rename freqtrade/{types => ft_types}/valid_exchanges_type.py (100%) diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index 494ee87fa..af6e4571f 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -12,9 +12,9 @@ from freqtrade.configuration import setup_utils_configuration from freqtrade.enums import RunMode from freqtrade.exceptions import ConfigurationError, OperationalException from freqtrade.exchange import list_available_exchanges, market_is_active +from freqtrade.ft_types import ValidExchangesType from freqtrade.misc import parse_db_uri_for_logging, plural from freqtrade.resolvers import ExchangeResolver, StrategyResolver -from freqtrade.types.valid_exchanges_type import ValidExchangesType from freqtrade.util import print_rich_table diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index a237b10f1..580807a76 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -13,10 +13,10 @@ import pandas as pd from freqtrade.constants import LAST_BT_RESULT_FN, IntOrInf from freqtrade.exceptions import ConfigurationError, OperationalException +from freqtrade.ft_types import BacktestHistoryEntryType, BacktestResultType from freqtrade.misc import file_dump_json, json_load from freqtrade.optimize.backtest_caching import get_backtest_metadata_filename from freqtrade.persistence import LocalTrade, Trade, init_db -from freqtrade.types import BacktestHistoryEntryType, BacktestResultType logger = logging.getLogger(__name__) diff --git a/freqtrade/exchange/exchange_utils.py b/freqtrade/exchange/exchange_utils.py index fc3824dcf..c150d751b 100644 --- a/freqtrade/exchange/exchange_utils.py +++ b/freqtrade/exchange/exchange_utils.py @@ -26,7 +26,7 @@ from freqtrade.exchange.common import ( SUPPORTED_EXCHANGES, ) from freqtrade.exchange.exchange_utils_timeframe import timeframe_to_minutes, timeframe_to_prev_date -from freqtrade.types import ValidExchangesType +from freqtrade.ft_types import ValidExchangesType from freqtrade.util import FtPrecise diff --git a/freqtrade/types/__init__.py b/freqtrade/ft_types/__init__.py similarity index 52% rename from freqtrade/types/__init__.py rename to freqtrade/ft_types/__init__.py index 6420baba0..2eb4e5dda 100644 --- a/freqtrade/types/__init__.py +++ b/freqtrade/ft_types/__init__.py @@ -1,8 +1,8 @@ # flake8: noqa: F401 -from freqtrade.types.backtest_result_type import ( +from freqtrade.ft_types.backtest_result_type import ( BacktestHistoryEntryType, BacktestMetadataType, BacktestResultType, get_BacktestResultType_default, ) -from freqtrade.types.valid_exchanges_type import ValidExchangesType +from freqtrade.ft_types.valid_exchanges_type import ValidExchangesType diff --git a/freqtrade/types/backtest_result_type.py b/freqtrade/ft_types/backtest_result_type.py similarity index 100% rename from freqtrade/types/backtest_result_type.py rename to freqtrade/ft_types/backtest_result_type.py diff --git a/freqtrade/types/valid_exchanges_type.py b/freqtrade/ft_types/valid_exchanges_type.py similarity index 100% rename from freqtrade/types/valid_exchanges_type.py rename to freqtrade/ft_types/valid_exchanges_type.py diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 1487d9f10..7ea0b44c9 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -36,6 +36,7 @@ from freqtrade.exchange import ( timeframe_to_seconds, ) from freqtrade.exchange.exchange import Exchange +from freqtrade.ft_types import BacktestResultType, get_BacktestResultType_default from freqtrade.mixins import LoggingMixin from freqtrade.optimize.backtest_caching import get_strategy_run_id from freqtrade.optimize.bt_progress import BTProgress @@ -61,7 +62,6 @@ from freqtrade.plugins.protectionmanager import ProtectionManager from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.strategy.interface import IStrategy from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper -from freqtrade.types import BacktestResultType, get_BacktestResultType_default from freqtrade.util import FtPrecise from freqtrade.util.migrations import migrate_data from freqtrade.wallets import Wallets diff --git a/freqtrade/optimize/optimize_reports/bt_output.py b/freqtrade/optimize/optimize_reports/bt_output.py index 620b6da7e..ef58975ca 100644 --- a/freqtrade/optimize/optimize_reports/bt_output.py +++ b/freqtrade/optimize/optimize_reports/bt_output.py @@ -2,8 +2,8 @@ import logging from typing import Any, Dict, List, Literal, Union 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 -from freqtrade.types import BacktestResultType from freqtrade.util import decimals_per_coin, fmt_coin, print_rich_table diff --git a/freqtrade/optimize/optimize_reports/bt_storage.py b/freqtrade/optimize/optimize_reports/bt_storage.py index ea8991337..2953c65e7 100644 --- a/freqtrade/optimize/optimize_reports/bt_storage.py +++ b/freqtrade/optimize/optimize_reports/bt_storage.py @@ -5,9 +5,9 @@ from typing import Dict, Optional from pandas import DataFrame from freqtrade.constants import LAST_BT_RESULT_FN +from freqtrade.ft_types import BacktestResultType from freqtrade.misc import file_dump_joblib, file_dump_json from freqtrade.optimize.backtest_caching import get_backtest_metadata_filename -from freqtrade.types import BacktestResultType logger = logging.getLogger(__name__) diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index ef5fce0e1..38a6cfbf8 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -17,7 +17,7 @@ from freqtrade.data.metrics import ( calculate_sharpe, calculate_sortino, ) -from freqtrade.types import BacktestResultType +from freqtrade.ft_types import BacktestResultType from freqtrade.util import decimals_per_coin, fmt_coin diff --git a/freqtrade/rpc/api_server/api_backtest.py b/freqtrade/rpc/api_server/api_backtest.py index 4295d9d19..e4b598807 100644 --- a/freqtrade/rpc/api_server/api_backtest.py +++ b/freqtrade/rpc/api_server/api_backtest.py @@ -21,6 +21,7 @@ from freqtrade.data.btanalysis import ( from freqtrade.enums import BacktestState from freqtrade.exceptions import ConfigurationError, DependencyException, OperationalException from freqtrade.exchange.common import remove_exchange_credentials +from freqtrade.ft_types import get_BacktestResultType_default from freqtrade.misc import deep_merge_dicts, is_file_in_dir from freqtrade.rpc.api_server.api_schemas import ( BacktestHistoryEntry, @@ -32,7 +33,6 @@ from freqtrade.rpc.api_server.api_schemas import ( from freqtrade.rpc.api_server.deps import get_config from freqtrade.rpc.api_server.webserver_bgwork import ApiBG from freqtrade.rpc.rpc import RPCException -from freqtrade.types import get_BacktestResultType_default logger = logging.getLogger(__name__) diff --git a/freqtrade/rpc/api_server/api_schemas.py b/freqtrade/rpc/api_server/api_schemas.py index 6ba65d0ec..e3e23d211 100644 --- a/freqtrade/rpc/api_server/api_schemas.py +++ b/freqtrade/rpc/api_server/api_schemas.py @@ -5,7 +5,7 @@ from pydantic import AwareDatetime, BaseModel, RootModel, SerializeAsAny from freqtrade.constants import IntOrInf from freqtrade.enums import MarginMode, OrderTypeValues, SignalDirection, TradingMode -from freqtrade.types import ValidExchangesType +from freqtrade.ft_types import ValidExchangesType class ExchangeModePayloadMixin(BaseModel): From d49c556291eefa34d3088a3aa570981f0dc92ac5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 4 Sep 2024 06:57:13 +0200 Subject: [PATCH 036/187] chore: rename ft_has setting from ws.enabled to ws_enabled --- freqtrade/exchange/binance.py | 4 ++-- freqtrade/exchange/bybit.py | 2 +- freqtrade/exchange/exchange.py | 4 ++-- freqtrade/exchange/okx.py | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 2b681081a..f20920df6 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -30,7 +30,7 @@ class Binance(Exchange): "trades_pagination_arg": "fromId", "trades_has_history": True, "l2_limit_range": [5, 10, 20, 50, 100, 500, 1000], - "ws.enabled": True, + "ws_enabled": True, } _ft_has_futures: Dict = { "stoploss_order_types": {"limit": "stop", "market": "stop_market"}, @@ -43,7 +43,7 @@ class Binance(Exchange): PriceType.LAST: "CONTRACT_PRICE", PriceType.MARK: "MARK_PRICE", }, - "ws.enabled": False, + "ws_enabled": False, } _supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [ diff --git a/freqtrade/exchange/bybit.py b/freqtrade/exchange/bybit.py index 16932947d..ce9c38fff 100644 --- a/freqtrade/exchange/bybit.py +++ b/freqtrade/exchange/bybit.py @@ -33,7 +33,7 @@ class Bybit(Exchange): "ohlcv_candle_limit": 1000, "ohlcv_has_history": True, "order_time_in_force": ["GTC", "FOK", "IOC", "PO"], - "ws.enabled": True, + "ws_enabled": True, "trades_has_history": False, # Endpoint doesn't support pagination } _ft_has_futures: Dict = { diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 7bd8b694b..df1971999 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -154,7 +154,7 @@ class Exchange: "marketOrderRequiresPrice": False, "exchange_has_overrides": {}, # Dictionary overriding ccxt's "has". # Expected to be in the format {"fetchOHLCV": True} or {"fetchOHLCV": False} - "ws.enabled": False, # Set to true for exchanges with tested websocket support + "ws_enabled": False, # Set to true for exchanges with tested websocket support } _ft_has: Dict = {} _ft_has_futures: Dict = {} @@ -261,7 +261,7 @@ class Exchange: exchange_conf.get("ccxt_async_config", {}), ccxt_async_config ) self._api_async = self._init_ccxt(exchange_conf, False, ccxt_async_config) - self._has_watch_ohlcv = self.exchange_has("watchOHLCV") and self._ft_has["ws.enabled"] + self._has_watch_ohlcv = self.exchange_has("watchOHLCV") and self._ft_has["ws_enabled"] if ( self._config["runmode"] in TRADE_MODES and exchange_conf.get("enable_ws", True) diff --git a/freqtrade/exchange/okx.py b/freqtrade/exchange/okx.py index db94f576d..248028973 100644 --- a/freqtrade/exchange/okx.py +++ b/freqtrade/exchange/okx.py @@ -34,7 +34,7 @@ class Okx(Exchange): "stoploss_order_types": {"limit": "limit"}, "stoploss_on_exchange": True, "trades_has_history": False, # Endpoint doesn't have a "since" parameter - "ws.enabled": True, + "ws_enabled": True, } _ft_has_futures: Dict = { "tickers_have_quoteVolume": False, @@ -44,7 +44,7 @@ class Okx(Exchange): PriceType.MARK: "index", PriceType.INDEX: "mark", }, - "ws.enabled": True, + "ws_enabled": True, } _supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [ From 964d437c7a029db8c59b65e441515485d65550bc Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 4 Sep 2024 07:15:17 +0200 Subject: [PATCH 037/187] chore: type _ft_has --- freqtrade/exchange/binance.py | 6 ++-- freqtrade/exchange/bingx.py | 4 +-- freqtrade/exchange/bitmart.py | 4 +-- freqtrade/exchange/bitvavo.py | 4 +-- freqtrade/exchange/bybit.py | 5 +-- freqtrade/exchange/coinbasepro.py | 4 +-- freqtrade/exchange/cryptocom.py | 4 +-- freqtrade/exchange/exchange.py | 10 +++--- freqtrade/exchange/exchange_types.py | 47 ++++++++++++++++++++++++++++ freqtrade/exchange/gate.py | 5 +-- freqtrade/exchange/hitbtc.py | 4 +-- freqtrade/exchange/htx.py | 3 +- freqtrade/exchange/hyperliquid.py | 3 +- freqtrade/exchange/idex.py | 4 +-- freqtrade/exchange/kraken.py | 4 +-- freqtrade/exchange/kucoin.py | 3 +- freqtrade/exchange/okx.py | 5 +-- 17 files changed, 87 insertions(+), 32 deletions(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index f20920df6..d2e74f9eb 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -11,7 +11,7 @@ from freqtrade.enums import CandleType, MarginMode, PriceType, TradingMode from freqtrade.exceptions import DDosProtection, OperationalException, TemporaryError from freqtrade.exchange import Exchange from freqtrade.exchange.common import retrier -from freqtrade.exchange.exchange_types import OHLCVResponse, Tickers +from freqtrade.exchange.exchange_types import FtHas, OHLCVResponse, Tickers from freqtrade.misc import deep_merge_dicts, json_load @@ -19,7 +19,7 @@ logger = logging.getLogger(__name__) class Binance(Exchange): - _ft_has: Dict = { + _ft_has: FtHas = { "stoploss_on_exchange": True, "stop_price_param": "stopPrice", "stop_price_prop": "stopPrice", @@ -32,7 +32,7 @@ class Binance(Exchange): "l2_limit_range": [5, 10, 20, 50, 100, 500, 1000], "ws_enabled": True, } - _ft_has_futures: Dict = { + _ft_has_futures: FtHas = { "stoploss_order_types": {"limit": "stop", "market": "stop_market"}, "order_time_in_force": ["GTC", "FOK", "IOC"], "tickers_have_price": False, diff --git a/freqtrade/exchange/bingx.py b/freqtrade/exchange/bingx.py index 4dcff8a21..1caf7a737 100644 --- a/freqtrade/exchange/bingx.py +++ b/freqtrade/exchange/bingx.py @@ -1,9 +1,9 @@ """Bingx exchange subclass""" import logging -from typing import Dict from freqtrade.exchange import Exchange +from freqtrade.exchange.exchange_types import FtHas logger = logging.getLogger(__name__) @@ -15,7 +15,7 @@ class Bingx(Exchange): with this exchange. """ - _ft_has: Dict = { + _ft_has: FtHas = { "ohlcv_candle_limit": 1000, "stoploss_on_exchange": True, "stoploss_order_types": {"limit": "limit", "market": "market"}, diff --git a/freqtrade/exchange/bitmart.py b/freqtrade/exchange/bitmart.py index ab509c786..8fed36bec 100644 --- a/freqtrade/exchange/bitmart.py +++ b/freqtrade/exchange/bitmart.py @@ -1,9 +1,9 @@ """Bitmart exchange subclass""" import logging -from typing import Dict from freqtrade.exchange import Exchange +from freqtrade.exchange.exchange_types import FtHas logger = logging.getLogger(__name__) @@ -15,7 +15,7 @@ class Bitmart(Exchange): with this exchange. """ - _ft_has: Dict = { + _ft_has: FtHas = { "stoploss_on_exchange": False, # Bitmart API does not support stoploss orders "ohlcv_candle_limit": 200, "trades_has_history": False, # Endpoint doesn't seem to support pagination diff --git a/freqtrade/exchange/bitvavo.py b/freqtrade/exchange/bitvavo.py index ff0c0e37f..fdbb8a7d4 100644 --- a/freqtrade/exchange/bitvavo.py +++ b/freqtrade/exchange/bitvavo.py @@ -1,11 +1,11 @@ """Bitvavo exchange subclass.""" import logging -from typing import Dict from ccxt import DECIMAL_PLACES from freqtrade.exchange import Exchange +from freqtrade.exchange.exchange_types import FtHas logger = logging.getLogger(__name__) @@ -21,7 +21,7 @@ class Bitvavo(Exchange): may still not work as expected. """ - _ft_has: Dict = { + _ft_has: FtHas = { "ohlcv_candle_limit": 1440, } diff --git a/freqtrade/exchange/bybit.py b/freqtrade/exchange/bybit.py index ce9c38fff..52cf37d31 100644 --- a/freqtrade/exchange/bybit.py +++ b/freqtrade/exchange/bybit.py @@ -11,6 +11,7 @@ from freqtrade.enums import CandleType, MarginMode, PriceType, TradingMode from freqtrade.exceptions import DDosProtection, ExchangeError, OperationalException, TemporaryError from freqtrade.exchange import Exchange from freqtrade.exchange.common import retrier +from freqtrade.exchange.exchange_types import FtHas from freqtrade.util.datetime_helpers import dt_now, dt_ts @@ -29,14 +30,14 @@ class Bybit(Exchange): unified_account = False - _ft_has: Dict = { + _ft_has: FtHas = { "ohlcv_candle_limit": 1000, "ohlcv_has_history": True, "order_time_in_force": ["GTC", "FOK", "IOC", "PO"], "ws_enabled": True, "trades_has_history": False, # Endpoint doesn't support pagination } - _ft_has_futures: Dict = { + _ft_has_futures: FtHas = { "ohlcv_has_history": True, "mark_ohlcv_timeframe": "4h", "funding_fee_timeframe": "8h", diff --git a/freqtrade/exchange/coinbasepro.py b/freqtrade/exchange/coinbasepro.py index e234002ad..cc561e8ce 100644 --- a/freqtrade/exchange/coinbasepro.py +++ b/freqtrade/exchange/coinbasepro.py @@ -1,9 +1,9 @@ """CoinbasePro exchange subclass""" import logging -from typing import Dict from freqtrade.exchange import Exchange +from freqtrade.exchange.exchange_types import FtHas logger = logging.getLogger(__name__) @@ -19,6 +19,6 @@ class Coinbasepro(Exchange): may still not work as expected. """ - _ft_has: Dict = { + _ft_has: FtHas = { "ohlcv_candle_limit": 300, } diff --git a/freqtrade/exchange/cryptocom.py b/freqtrade/exchange/cryptocom.py index 56b007b07..4782c5a49 100644 --- a/freqtrade/exchange/cryptocom.py +++ b/freqtrade/exchange/cryptocom.py @@ -1,9 +1,9 @@ """Crypto.com exchange subclass""" import logging -from typing import Dict from freqtrade.exchange import Exchange +from freqtrade.exchange.exchange_types import FtHas logger = logging.getLogger(__name__) @@ -14,6 +14,6 @@ class Cryptocom(Exchange): Contains adjustments needed for Freqtrade to work with this exchange. """ - _ft_has: Dict = { + _ft_has: FtHas = { "ohlcv_candle_limit": 300, } diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index df1971999..cb1c1a49a 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -70,6 +70,7 @@ from freqtrade.exchange.common import ( from freqtrade.exchange.exchange_types import ( CcxtBalances, CcxtPosition, + FtHas, OHLCVResponse, OrderBook, Ticker, @@ -122,10 +123,11 @@ class Exchange: # Dict to specify which options each exchange implements # This defines defaults, which can be selectively overridden by subclasses using _ft_has # or by specifying them in the configuration. - _ft_has_default: Dict = { + _ft_has_default: FtHas = { "stoploss_on_exchange": False, "stop_price_param": "stopLossPrice", # Used for stoploss_on_exchange request "stop_price_prop": "stopLossPrice", # Used for stoploss_on_exchange response parsing + "stoploss_order_types": {}, "order_time_in_force": ["GTC"], "ohlcv_params": {}, "ohlcv_candle_limit": 500, @@ -156,8 +158,8 @@ class Exchange: # Expected to be in the format {"fetchOHLCV": True} or {"fetchOHLCV": False} "ws_enabled": False, # Set to true for exchanges with tested websocket support } - _ft_has: Dict = {} - _ft_has_futures: Dict = {} + _ft_has: FtHas = {} + _ft_has_futures: FtHas = {} _supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [ # TradingMode.SPOT always supported and not required in this list @@ -466,7 +468,7 @@ class Exchange: """ return int( self._ft_has.get("ohlcv_candle_limit_per_timeframe", {}).get( - timeframe, self._ft_has.get("ohlcv_candle_limit") + timeframe, str(self._ft_has.get("ohlcv_candle_limit")) ) ) diff --git a/freqtrade/exchange/exchange_types.py b/freqtrade/exchange/exchange_types.py index 2a9ae1078..ef3ed274b 100644 --- a/freqtrade/exchange/exchange_types.py +++ b/freqtrade/exchange/exchange_types.py @@ -3,6 +3,53 @@ from typing import Dict, List, Optional, Tuple, TypedDict from freqtrade.enums import CandleType +class FtHas(TypedDict, total=False): + order_time_in_force: List[str] + exchange_has_overrides: Dict[str, bool] + marketOrderRequiresPrice: bool + + # Stoploss on exchange + stoploss_on_exchange: bool + stop_price_param: str + stop_price_prop: str + stop_price_type_field: str + stop_price_type_value_mapping: Dict + stoploss_order_types: Dict[str, str] + # ohlcv + ohlcv_params: Dict + ohlcv_candle_limit: int + ohlcv_has_history: bool + ohlcv_partial_candle: bool + ohlcv_require_since: bool + ohlcv_volume_currency: str + ohlcv_candle_limit_per_timeframe: Dict[str, int] + # Tickers + tickers_have_quoteVolume: bool + tickers_have_percentage: bool + tickers_have_bid_ask: bool + tickers_have_price: bool + # Trades + trades_limit: int + trades_pagination: str + trades_pagination_arg: str + trades_has_history: bool + trades_pagination_overlap: bool + # Orderbook + l2_limit_range: Optional[List[int]] + l2_limit_range_required: bool + # Futures + ccxt_futures_name: str # usually swap + mark_ohlcv_price: str + mark_ohlcv_timeframe: str + funding_fee_timeframe: str + floor_leverage: bool + needs_trading_fees: bool + order_props_in_contracts: List[str] + + # Websocket control + ws_enabled: bool + + class Ticker(TypedDict): symbol: str ask: Optional[float] diff --git a/freqtrade/exchange/gate.py b/freqtrade/exchange/gate.py index 9ed5a7366..4096a851a 100644 --- a/freqtrade/exchange/gate.py +++ b/freqtrade/exchange/gate.py @@ -7,6 +7,7 @@ from typing import Any, Dict, List, Optional, Tuple from freqtrade.constants import BuySell from freqtrade.enums import MarginMode, PriceType, TradingMode from freqtrade.exchange import Exchange +from freqtrade.exchange.exchange_types import FtHas from freqtrade.misc import safe_value_fallback2 @@ -23,7 +24,7 @@ class Gate(Exchange): may still not work as expected. """ - _ft_has: Dict = { + _ft_has: FtHas = { "ohlcv_candle_limit": 1000, "order_time_in_force": ["GTC", "IOC"], "stoploss_on_exchange": True, @@ -34,7 +35,7 @@ class Gate(Exchange): "trades_has_history": False, # Endpoint would support this - but ccxt doesn't. } - _ft_has_futures: Dict = { + _ft_has_futures: FtHas = { "needs_trading_fees": True, "marketOrderRequiresPrice": False, "stop_price_type_field": "price_type", diff --git a/freqtrade/exchange/hitbtc.py b/freqtrade/exchange/hitbtc.py index bc4c7aa81..d37c7f12e 100644 --- a/freqtrade/exchange/hitbtc.py +++ b/freqtrade/exchange/hitbtc.py @@ -1,7 +1,7 @@ import logging -from typing import Dict from freqtrade.exchange import Exchange +from freqtrade.exchange.exchange_types import FtHas logger = logging.getLogger(__name__) @@ -17,6 +17,6 @@ class Hitbtc(Exchange): may still not work as expected. """ - _ft_has: Dict = { + _ft_has: FtHas = { "ohlcv_candle_limit": 1000, } diff --git a/freqtrade/exchange/htx.py b/freqtrade/exchange/htx.py index fa26a5ffd..9bd931f51 100644 --- a/freqtrade/exchange/htx.py +++ b/freqtrade/exchange/htx.py @@ -5,6 +5,7 @@ from typing import Dict from freqtrade.constants import BuySell from freqtrade.exchange import Exchange +from freqtrade.exchange.exchange_types import FtHas logger = logging.getLogger(__name__) @@ -16,7 +17,7 @@ class Htx(Exchange): with this exchange. """ - _ft_has: Dict = { + _ft_has: FtHas = { "stoploss_on_exchange": True, "stop_price_param": "stopPrice", "stop_price_prop": "stopPrice", diff --git a/freqtrade/exchange/hyperliquid.py b/freqtrade/exchange/hyperliquid.py index f8835d1dc..69905c416 100644 --- a/freqtrade/exchange/hyperliquid.py +++ b/freqtrade/exchange/hyperliquid.py @@ -7,6 +7,7 @@ from ccxt import SIGNIFICANT_DIGITS from freqtrade.enums import TradingMode from freqtrade.exchange import Exchange +from freqtrade.exchange.exchange_types import FtHas logger = logging.getLogger(__name__) @@ -17,7 +18,7 @@ class Hyperliquid(Exchange): Contains adjustments needed for Freqtrade to work with this exchange. """ - _ft_has: Dict = { + _ft_has: FtHas = { # Only the most recent 5000 candles are available according to the # exchange's API documentation. "ohlcv_has_history": False, diff --git a/freqtrade/exchange/idex.py b/freqtrade/exchange/idex.py index b3bf12110..9c750f64d 100644 --- a/freqtrade/exchange/idex.py +++ b/freqtrade/exchange/idex.py @@ -1,9 +1,9 @@ """Idex exchange subclass""" import logging -from typing import Dict from freqtrade.exchange import Exchange +from freqtrade.exchange.exchange_types import FtHas logger = logging.getLogger(__name__) @@ -15,6 +15,6 @@ class Idex(Exchange): with this exchange. """ - _ft_has: Dict = { + _ft_has: FtHas = { "ohlcv_candle_limit": 1000, } diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index b0734cb6c..7f3346cfe 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -12,7 +12,7 @@ from freqtrade.enums import MarginMode, TradingMode from freqtrade.exceptions import DDosProtection, OperationalException, TemporaryError from freqtrade.exchange import Exchange from freqtrade.exchange.common import retrier -from freqtrade.exchange.exchange_types import CcxtBalances, Tickers +from freqtrade.exchange.exchange_types import CcxtBalances, FtHas, Tickers logger = logging.getLogger(__name__) @@ -20,7 +20,7 @@ logger = logging.getLogger(__name__) class Kraken(Exchange): _params: Dict = {"trading_agreement": "agree"} - _ft_has: Dict = { + _ft_has: FtHas = { "stoploss_on_exchange": True, "stop_price_param": "stopLossPrice", "stop_price_prop": "stopLossPrice", diff --git a/freqtrade/exchange/kucoin.py b/freqtrade/exchange/kucoin.py index 343904276..bbf120d40 100644 --- a/freqtrade/exchange/kucoin.py +++ b/freqtrade/exchange/kucoin.py @@ -5,6 +5,7 @@ from typing import Dict from freqtrade.constants import BuySell from freqtrade.exchange import Exchange +from freqtrade.exchange.exchange_types import FtHas logger = logging.getLogger(__name__) @@ -20,7 +21,7 @@ class Kucoin(Exchange): may still not work as expected. """ - _ft_has: Dict = { + _ft_has: FtHas = { "stoploss_on_exchange": True, "stop_price_param": "stopPrice", "stop_price_prop": "stopPrice", diff --git a/freqtrade/exchange/okx.py b/freqtrade/exchange/okx.py index 248028973..8a781982a 100644 --- a/freqtrade/exchange/okx.py +++ b/freqtrade/exchange/okx.py @@ -14,6 +14,7 @@ from freqtrade.exceptions import ( ) from freqtrade.exchange import Exchange, date_minus_candles from freqtrade.exchange.common import retrier +from freqtrade.exchange.exchange_types import FtHas from freqtrade.misc import safe_value_fallback2 from freqtrade.util import dt_now, dt_ts @@ -27,7 +28,7 @@ class Okx(Exchange): Contains adjustments needed for Freqtrade to work with this exchange. """ - _ft_has: Dict = { + _ft_has: FtHas = { "ohlcv_candle_limit": 100, # Warning, special case with data prior to X months "mark_ohlcv_timeframe": "4h", "funding_fee_timeframe": "8h", @@ -36,7 +37,7 @@ class Okx(Exchange): "trades_has_history": False, # Endpoint doesn't have a "since" parameter "ws_enabled": True, } - _ft_has_futures: Dict = { + _ft_has_futures: FtHas = { "tickers_have_quoteVolume": False, "stop_price_type_field": "slTriggerPxType", "stop_price_type_value_mapping": { From 63092d7d1ae8dd9745740977d8a9e21858ea70dc Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 4 Sep 2024 20:44:15 +0200 Subject: [PATCH 038/187] chore: re-add analytics to docs page --- mkdocs.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mkdocs.yml b/mkdocs.yml index 9e67f1f71..7633181f9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -116,6 +116,9 @@ extra: version: provider: mike alias: true + analytics: + provider: google + property: G-VH170LG9M5 plugins: - search: enabled: true From 2fdf108198fe2efe9da483c2196ee69e0f0fd539 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 4 Sep 2024 21:04:39 +0200 Subject: [PATCH 039/187] chore: update site_url to work correctly --- mkdocs.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 7633181f9..494b18755 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,5 +1,5 @@ site_name: Freqtrade -site_url: !ENV [READTHEDOCS_CANONICAL_URL, 'https://www.freqtrade.io/en/latest/'] +site_url: !ENV [READTHEDOCS_CANONICAL_URL, 'https://www.freqtrade.io/'] site_description: Freqtrade is a free and open source crypto trading bot written in Python, designed to support all major exchanges and be controlled via Telegram or builtin Web UI repo_url: https://github.com/freqtrade/freqtrade edit_uri: edit/develop/docs/ @@ -116,9 +116,6 @@ extra: version: provider: mike alias: true - analytics: - provider: google - property: G-VH170LG9M5 plugins: - search: enabled: true From 824db78234477e6b3aaeecbd031e24da7fe0f551 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 4 Sep 2024 21:07:16 +0200 Subject: [PATCH 040/187] chore: update site_url again --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 494b18755..aa2d79cb2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,5 +1,5 @@ site_name: Freqtrade -site_url: !ENV [READTHEDOCS_CANONICAL_URL, 'https://www.freqtrade.io/'] +site_url: !ENV [READTHEDOCS_CANONICAL_URL, 'https://www.freqtrade.io/en/'] site_description: Freqtrade is a free and open source crypto trading bot written in Python, designed to support all major exchanges and be controlled via Telegram or builtin Web UI repo_url: https://github.com/freqtrade/freqtrade edit_uri: edit/develop/docs/ From 65ba67dedcb7533e2cc8f476add3bdb47d3a5b39 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 4 Sep 2024 21:08:34 +0200 Subject: [PATCH 041/187] chore: re-add analytics. --- mkdocs.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mkdocs.yml b/mkdocs.yml index aa2d79cb2..6d51e136b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -116,6 +116,9 @@ extra: version: provider: mike alias: true + analytics: + provider: google + property: G-VH170LG9M5 plugins: - search: enabled: true From c6a66a8fac7d16e77429015adfbbb9760bb5e613 Mon Sep 17 00:00:00 2001 From: xmatthias <5024695+xmatthias@users.noreply.github.com> Date: Thu, 5 Sep 2024 03:12:48 +0000 Subject: [PATCH 042/187] chore: update pre-commit hooks --- .../exchange/binance_leverage_tiers.json | 1274 +++++++++++------ 1 file changed, 823 insertions(+), 451 deletions(-) diff --git a/freqtrade/exchange/binance_leverage_tiers.json b/freqtrade/exchange/binance_leverage_tiers.json index 303b66eb8..859d87b9f 100644 --- a/freqtrade/exchange/binance_leverage_tiers.json +++ b/freqtrade/exchange/binance_leverage_tiers.json @@ -134,128 +134,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", - "notionalCap": "50000", - "notionalFloor": "5000", - "maintMarginRatio": "0.02", - "cum": "25.0" + "initialLeverage": "50", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 30000.0, + "maxNotional": 150000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "100000", - "notionalFloor": "50000", - "maintMarginRatio": "0.025", - "cum": "275.0" + "initialLeverage": "25", + "notionalCap": "150000", + "notionalFloor": "30000", + "maintMarginRatio": "0.02", + "cum": "200.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 150000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "1000000", - "notionalFloor": "100000", - "maintMarginRatio": "0.05", - "cum": "2775.0" + "initialLeverage": "20", + "notionalCap": "300000", + "notionalFloor": "150000", + "maintMarginRatio": "0.025", + "cum": "950.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 300000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "2000000", - "notionalFloor": "1000000", - "maintMarginRatio": "0.1", - "cum": "52775.0" + "initialLeverage": "10", + "notionalCap": "1500000", + "notionalFloor": "300000", + "maintMarginRatio": "0.05", + "cum": "8450.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 2500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "2500000", - "notionalFloor": "2000000", - "maintMarginRatio": "0.125", - "cum": "102775.0" + "initialLeverage": "5", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.1", + "cum": "83450.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 2500000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 3000000.0, + "maxNotional": 3750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "5000000", - "notionalFloor": "2500000", - "maintMarginRatio": "0.25", - "cum": "415275.0" + "initialLeverage": "4", + "notionalCap": "3750000", + "notionalFloor": "3000000", + "maintMarginRatio": "0.125", + "cum": "158450.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "minNotional": 3750000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "7500000", + "notionalFloor": "3750000", + "maintMarginRatio": "0.25", + "cum": "627200.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 15000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "10000000", - "notionalFloor": "5000000", + "notionalCap": "15000000", + "notionalFloor": "7500000", "maintMarginRatio": "0.5", - "cum": "1665275.0" + "cum": "2502200.0" } } ], @@ -1206,13 +1222,13 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 50.0, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.0065", "cum": "0.0" @@ -1221,17 +1237,17 @@ { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, + "minNotional": 10000.0, "maxNotional": 25000.0, "maintenanceMarginRate": 0.0075, - "maxLeverage": 40.0, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "40", + "initialLeverage": "50", "notionalCap": "25000", - "notionalFloor": "5000", + "notionalFloor": "10000", "maintMarginRatio": "0.0075", - "cum": "5.0" + "cum": "10.0" } }, { @@ -1240,110 +1256,126 @@ "minNotional": 25000.0, "maxNotional": 150000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25.0, + "maxLeverage": 40.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "40", "notionalCap": "150000", "notionalFloor": "25000", "maintMarginRatio": "0.01", - "cum": "67.5" + "cum": "72.5" } }, { "tier": 4.0, "currency": "USDT", "minNotional": 150000.0, - "maxNotional": 600000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "4", - "initialLeverage": "20", - "notionalCap": "600000", + "initialLeverage": "25", + "notionalCap": "300000", "notionalFloor": "150000", - "maintMarginRatio": "0.025", - "cum": "2317.5" + "maintMarginRatio": "0.02", + "cum": "1572.5" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 600000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 300000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "5", - "initialLeverage": "10", - "notionalCap": "1500000", - "notionalFloor": "600000", - "maintMarginRatio": "0.05", - "cum": "17317.5" + "initialLeverage": "20", + "notionalCap": "600000", + "notionalFloor": "300000", + "maintMarginRatio": "0.025", + "cum": "3072.5" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 1500000.0, + "minNotional": 600000.0, "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "6", - "initialLeverage": "5", + "initialLeverage": "10", "notionalCap": "3000000", - "notionalFloor": "1500000", - "maintMarginRatio": "0.1", - "cum": "92317.5" + "notionalFloor": "600000", + "maintMarginRatio": "0.05", + "cum": "18072.5" } }, { "tier": 7.0, "currency": "USDT", "minNotional": 3000000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "maxNotional": 6000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "7", - "initialLeverage": "4", - "notionalCap": "5000000", + "initialLeverage": "5", + "notionalCap": "6000000", "notionalFloor": "3000000", - "maintMarginRatio": "0.125", - "cum": "167317.5" + "maintMarginRatio": "0.1", + "cum": "168072.5" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 9000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 6000000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "8", - "initialLeverage": "2", - "notionalCap": "9000000", - "notionalFloor": "5000000", - "maintMarginRatio": "0.25", - "cum": "792317.5" + "initialLeverage": "4", + "notionalCap": "7500000", + "notionalFloor": "6000000", + "maintMarginRatio": "0.125", + "cum": "318072.5" } }, { "tier": 9.0, "currency": "USDT", - "minNotional": 9000000.0, + "minNotional": 7500000.0, + "maxNotional": 15000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "9", + "initialLeverage": "2", + "notionalCap": "15000000", + "notionalFloor": "7500000", + "maintMarginRatio": "0.25", + "cum": "1255572.5" + } + }, + { + "tier": 10.0, + "currency": "USDT", + "minNotional": 15000000.0, "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "9", + "bracket": "10", "initialLeverage": "1", "notionalCap": "30000000", - "notionalFloor": "9000000", + "notionalFloor": "15000000", "maintMarginRatio": "0.5", - "cum": "3042317.5" + "cum": "5005572.5" } } ], @@ -5270,13 +5302,13 @@ "tier": 2.0, "currency": "USDT", "minNotional": 5000.0, - "maxNotional": 10000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.0065, "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "notionalCap": "10000", + "notionalCap": "25000", "notionalFloor": "5000", "maintMarginRatio": "0.0065", "cum": "7.5" @@ -5285,103 +5317,103 @@ { "tier": 3.0, "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.0075, + "minNotional": 25000.0, + "maxNotional": 80000.0, + "maintenanceMarginRate": 0.01, "maxLeverage": 40.0, "info": { "bracket": "3", "initialLeverage": "40", - "notionalCap": "25000", - "notionalFloor": "10000", - "maintMarginRatio": "0.0075", - "cum": "17.5" + "notionalCap": "80000", + "notionalFloor": "25000", + "maintMarginRatio": "0.01", + "cum": "95.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.01, + "minNotional": 80000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": "4", "initialLeverage": "25", - "notionalCap": "50000", - "notionalFloor": "25000", - "maintMarginRatio": "0.01", - "cum": "80.0" + "notionalCap": "400000", + "notionalFloor": "80000", + "maintMarginRatio": "0.02", + "cum": "895.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 250000.0, + "minNotional": 400000.0, + "maxNotional": 800000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": "5", "initialLeverage": "20", - "notionalCap": "250000", - "notionalFloor": "50000", + "notionalCap": "800000", + "notionalFloor": "400000", "maintMarginRatio": "0.025", - "cum": "830.0" + "cum": "2895.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 250000.0, - "maxNotional": 1000000.0, + "minNotional": 800000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "6", "initialLeverage": "10", - "notionalCap": "1000000", - "notionalFloor": "250000", + "notionalCap": "4000000", + "notionalFloor": "800000", "maintMarginRatio": "0.05", - "cum": "7080.0" + "cum": "22895.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "minNotional": 4000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "7", "initialLeverage": "5", - "notionalCap": "2000000", - "notionalFloor": "1000000", + "notionalCap": "8000000", + "notionalFloor": "4000000", "maintMarginRatio": "0.1", - "cum": "57080.0" + "cum": "222895.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 5000000.0, + "minNotional": 8000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "8", "initialLeverage": "4", - "notionalCap": "5000000", - "notionalFloor": "2000000", + "notionalCap": "10000000", + "notionalFloor": "8000000", "maintMarginRatio": "0.125", - "cum": "107080.0" + "cum": "422895.0" } }, { "tier": 9.0, "currency": "USDT", - "minNotional": 5000000.0, + "minNotional": 10000000.0, "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, @@ -5389,9 +5421,9 @@ "bracket": "9", "initialLeverage": "2", "notionalCap": "20000000", - "notionalFloor": "5000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", - "cum": "732080.0" + "cum": "1672895.0" } }, { @@ -5407,7 +5439,7 @@ "notionalCap": "50000000", "notionalFloor": "20000000", "maintMarginRatio": "0.5", - "cum": "5732080.0" + "cum": "6672895.0" } } ], @@ -6732,13 +6764,13 @@ "tier": 3.0, "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 50000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.01, "maxLeverage": 40.0, "info": { "bracket": "3", "initialLeverage": "40", - "notionalCap": "50000", + "notionalCap": "100000", "notionalFloor": "10000", "maintMarginRatio": "0.01", "cum": "42.5" @@ -6747,7 +6779,7 @@ { "tier": 4.0, "currency": "USDT", - "minNotional": 50000.0, + "minNotional": 100000.0, "maxNotional": 500000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, @@ -6755,95 +6787,95 @@ "bracket": "4", "initialLeverage": "25", "notionalCap": "500000", - "notionalFloor": "50000", + "notionalFloor": "100000", "maintMarginRatio": "0.02", - "cum": "542.5" + "cum": "1042.5" } }, { "tier": 5.0, "currency": "USDT", "minNotional": 500000.0, - "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "5", - "initialLeverage": "10", - "notionalCap": "2000000", + "initialLeverage": "20", + "notionalCap": "1000000", "notionalFloor": "500000", - "maintMarginRatio": "0.05", - "cum": "15542.5" + "maintMarginRatio": "0.025", + "cum": "3542.5" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 4000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 1000000.0, + "maxNotional": 5000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "6", - "initialLeverage": "5", - "notionalCap": "4000000", - "notionalFloor": "2000000", - "maintMarginRatio": "0.1", - "cum": "115542.5" + "initialLeverage": "10", + "notionalCap": "5000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.05", + "cum": "28542.5" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 4000000.0, - "maxNotional": 8000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 5000000.0, + "maxNotional": 10000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "7", - "initialLeverage": "4", - "notionalCap": "8000000", - "notionalFloor": "4000000", - "maintMarginRatio": "0.125", - "cum": "215542.5" + "initialLeverage": "5", + "notionalCap": "10000000", + "notionalFloor": "5000000", + "maintMarginRatio": "0.1", + "cum": "278542.5" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 8000000.0, + "minNotional": 10000000.0, "maxNotional": 15000000.0, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "8", - "initialLeverage": "3", + "initialLeverage": "4", "notionalCap": "15000000", - "notionalFloor": "8000000", - "maintMarginRatio": "0.15", - "cum": "415542.5" + "notionalFloor": "10000000", + "maintMarginRatio": "0.125", + "cum": "528542.5" } }, { "tier": 9.0, "currency": "USDT", "minNotional": 15000000.0, - "maxNotional": 20000000.0, + "maxNotional": 25000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "9", "initialLeverage": "2", - "notionalCap": "20000000", + "notionalCap": "25000000", "notionalFloor": "15000000", "maintMarginRatio": "0.25", - "cum": "1915542.5" + "cum": "2403542.5" } }, { "tier": 10.0, "currency": "USDT", - "minNotional": 20000000.0, + "minNotional": 25000000.0, "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, @@ -6851,9 +6883,9 @@ "bracket": "10", "initialLeverage": "1", "notionalCap": "50000000", - "notionalFloor": "20000000", + "notionalFloor": "25000000", "maintMarginRatio": "0.5", - "cum": "6915542.5" + "cum": "8653542.5" } } ], @@ -10093,6 +10125,152 @@ } } ], + "CHESS/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "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, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "40000", + "notionalFloor": "20000", + "maintMarginRatio": "0.025", + "cum": "175.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.05", + "cum": "1175.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "11175.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.125", + "cum": "21175.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.25", + "cum": "83675.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "333675.0" + } + } + ], "CHR/USDT:USDT": [ { "tier": 1.0, @@ -12508,13 +12686,13 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.01, "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "notionalCap": "5000", + "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" @@ -12523,129 +12701,129 @@ { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 10000.0, + "minNotional": 10000.0, + "maxNotional": 40000.0, "maintenanceMarginRate": 0.015, "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "notionalCap": "10000", - "notionalFloor": "5000", + "notionalCap": "40000", + "notionalFloor": "10000", "maintMarginRatio": "0.015", - "cum": "25.0" + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 20000.0, + "minNotional": 40000.0, + "maxNotional": 200000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "notionalCap": "20000", - "notionalFloor": "10000", + "notionalCap": "200000", + "notionalFloor": "40000", "maintMarginRatio": "0.02", - "cum": "75.0" + "cum": "250.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 40000.0, + "minNotional": 200000.0, + "maxNotional": 400000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": "4", "initialLeverage": "20", - "notionalCap": "40000", - "notionalFloor": "20000", + "notionalCap": "400000", + "notionalFloor": "200000", "maintMarginRatio": "0.025", - "cum": "175.0" + "cum": "1250.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 40000.0, - "maxNotional": 200000.0, + "minNotional": 400000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "200000", - "notionalFloor": "40000", + "notionalCap": "2000000", + "notionalFloor": "400000", "maintMarginRatio": "0.05", - "cum": "1175.0" + "cum": "11250.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 400000.0, + "minNotional": 2000000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "400000", - "notionalFloor": "200000", + "notionalCap": "4000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.1", - "cum": "11175.0" + "cum": "111250.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 400000.0, - "maxNotional": 500000.0, + "minNotional": 4000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "500000", - "notionalFloor": "400000", + "notionalCap": "5000000", + "notionalFloor": "4000000", "maintMarginRatio": "0.125", - "cum": "21175.0" + "cum": "211250.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 1000000.0, + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "1000000", - "notionalFloor": "500000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.25", - "cum": "83675.0" + "cum": "836250.0" } }, { "tier": 9.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "2000000", - "notionalFloor": "1000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.5", - "cum": "333675.0" + "cum": "3336250.0" } } ], @@ -16027,6 +16205,152 @@ } } ], + "FLUX/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "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, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "40000", + "notionalFloor": "20000", + "maintMarginRatio": "0.025", + "cum": "175.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.05", + "cum": "1175.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "11175.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.125", + "cum": "21175.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.25", + "cum": "83675.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "333675.0" + } + } + ], "FRONT/USDT:USDT": [ { "tier": 1.0, @@ -24150,112 +24474,112 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", - "notionalCap": "25000", - "notionalFloor": "5000", - "maintMarginRatio": "0.02", - "cum": "25.0" + "initialLeverage": "50", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 20000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "50000", - "notionalFloor": "25000", - "maintMarginRatio": "0.025", + "initialLeverage": "25", + "notionalCap": "100000", + "notionalFloor": "20000", + "maintMarginRatio": "0.02", "cum": "150.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 500000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 100000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "500000", - "notionalFloor": "50000", - "maintMarginRatio": "0.05", - "cum": "1400.0" + "initialLeverage": "20", + "notionalCap": "200000", + "notionalFloor": "100000", + "maintMarginRatio": "0.025", + "cum": "650.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 500000.0, + "minNotional": 200000.0, "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", + "initialLeverage": "10", "notionalCap": "1000000", - "notionalFloor": "500000", - "maintMarginRatio": "0.1", - "cum": "26400.0" + "notionalFloor": "200000", + "maintMarginRatio": "0.05", + "cum": "5650.0" } }, { "tier": 6.0, "currency": "USDT", "minNotional": 1000000.0, - "maxNotional": 1250000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "1250000", + "initialLeverage": "5", + "notionalCap": "2000000", "notionalFloor": "1000000", - "maintMarginRatio": "0.125", - "cum": "51400.0" + "maintMarginRatio": "0.1", + "cum": "55650.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 1250000.0, + "minNotional": 2000000.0, "maxNotional": 2500000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "7", - "initialLeverage": "2", + "initialLeverage": "4", "notionalCap": "2500000", - "notionalFloor": "1250000", - "maintMarginRatio": "0.25", - "cum": "207650.0" + "notionalFloor": "2000000", + "maintMarginRatio": "0.125", + "cum": "105650.0" } }, { @@ -24263,15 +24587,31 @@ "currency": "USDT", "minNotional": 2500000.0, "maxNotional": 5000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "5000000", + "notionalFloor": "2500000", + "maintMarginRatio": "0.25", + "cum": "418150.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "5000000", - "notionalFloor": "2500000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.5", - "cum": "832650.0" + "cum": "1668150.0" } } ], @@ -33748,13 +34088,13 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50.0, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" @@ -33763,113 +34103,129 @@ { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "minNotional": 10000.0, + "maxNotional": 80000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", - "notionalCap": "50000", - "notionalFloor": "5000", - "maintMarginRatio": "0.02", + "initialLeverage": "50", + "notionalCap": "80000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 600000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 80000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "600000", - "notionalFloor": "50000", - "maintMarginRatio": "0.025", - "cum": "300.0" + "initialLeverage": "25", + "notionalCap": "400000", + "notionalFloor": "80000", + "maintMarginRatio": "0.02", + "cum": "450.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 600000.0, - "maxNotional": 1200000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 400000.0, + "maxNotional": 800000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "1200000", - "notionalFloor": "600000", - "maintMarginRatio": "0.05", - "cum": "15300.0" + "initialLeverage": "20", + "notionalCap": "800000", + "notionalFloor": "400000", + "maintMarginRatio": "0.025", + "cum": "2450.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 1200000.0, - "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 800000.0, + "maxNotional": 4000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "3000000", - "notionalFloor": "1200000", - "maintMarginRatio": "0.1", - "cum": "75300.0" + "initialLeverage": "10", + "notionalCap": "4000000", + "notionalFloor": "800000", + "maintMarginRatio": "0.05", + "cum": "22450.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 4000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 4000000.0, + "maxNotional": 8000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "4000000", - "notionalFloor": "3000000", - "maintMarginRatio": "0.125", - "cum": "150300.0" + "initialLeverage": "5", + "notionalCap": "8000000", + "notionalFloor": "4000000", + "maintMarginRatio": "0.1", + "cum": "222450.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 4000000.0, - "maxNotional": 6000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 8000000.0, + "maxNotional": 10000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "6000000", - "notionalFloor": "4000000", - "maintMarginRatio": "0.25", - "cum": "650300.0" + "initialLeverage": "4", + "notionalCap": "10000000", + "notionalFloor": "8000000", + "maintMarginRatio": "0.125", + "cum": "422450.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 6000000.0, - "maxNotional": 10000000.0, + "minNotional": 10000000.0, + "maxNotional": 20000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "20000000", + "notionalFloor": "10000000", + "maintMarginRatio": "0.25", + "cum": "1672450.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 40000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "10000000", - "notionalFloor": "6000000", + "notionalCap": "40000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", - "cum": "2150300.0" + "cum": "6672450.0" } } ], @@ -35634,128 +35990,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "minNotional": 10000.0, + "maxNotional": 80000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", - "notionalCap": "50000", - "notionalFloor": "5000", - "maintMarginRatio": "0.02", - "cum": "25.0" + "initialLeverage": "50", + "notionalCap": "80000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 80000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "100000", - "notionalFloor": "50000", - "maintMarginRatio": "0.025", - "cum": "275.0" + "initialLeverage": "25", + "notionalCap": "400000", + "notionalFloor": "80000", + "maintMarginRatio": "0.02", + "cum": "450.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 400000.0, + "maxNotional": 800000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "1000000", - "notionalFloor": "100000", - "maintMarginRatio": "0.05", - "cum": "2775.0" + "initialLeverage": "20", + "notionalCap": "800000", + "notionalFloor": "400000", + "maintMarginRatio": "0.025", + "cum": "2450.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 800000.0, + "maxNotional": 4000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "2000000", - "notionalFloor": "1000000", - "maintMarginRatio": "0.1", - "cum": "52775.0" + "initialLeverage": "10", + "notionalCap": "4000000", + "notionalFloor": "800000", + "maintMarginRatio": "0.05", + "cum": "22450.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 2500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 4000000.0, + "maxNotional": 8000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "2500000", - "notionalFloor": "2000000", - "maintMarginRatio": "0.125", - "cum": "102775.0" + "initialLeverage": "5", + "notionalCap": "8000000", + "notionalFloor": "4000000", + "maintMarginRatio": "0.1", + "cum": "222450.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 2500000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 8000000.0, + "maxNotional": 10000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "5000000", - "notionalFloor": "2500000", - "maintMarginRatio": "0.25", - "cum": "415275.0" + "initialLeverage": "4", + "notionalCap": "10000000", + "notionalFloor": "8000000", + "maintMarginRatio": "0.125", + "cum": "422450.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "minNotional": 10000000.0, + "maxNotional": 20000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "20000000", + "notionalFloor": "10000000", + "maintMarginRatio": "0.25", + "cum": "1672450.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 40000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "10000000", - "notionalFloor": "5000000", + "notionalCap": "40000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", - "cum": "1665275.0" + "cum": "6672450.0" } } ], @@ -38316,13 +38688,13 @@ "tier": 2.0, "currency": "USDT", "minNotional": 5000.0, - "maxNotional": 25000.0, + "maxNotional": 60000.0, "maintenanceMarginRate": 0.01, "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "notionalCap": "25000", + "notionalCap": "60000", "notionalFloor": "5000", "maintMarginRatio": "0.01", "cum": "20.0" @@ -38331,39 +38703,39 @@ { "tier": 3.0, "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 150000.0, + "minNotional": 60000.0, + "maxNotional": 300000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "notionalCap": "150000", - "notionalFloor": "25000", + "notionalCap": "300000", + "notionalFloor": "60000", "maintMarginRatio": "0.02", - "cum": "270.0" + "cum": "620.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 150000.0, - "maxNotional": 300000.0, + "minNotional": 300000.0, + "maxNotional": 600000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": "4", "initialLeverage": "20", - "notionalCap": "300000", - "notionalFloor": "150000", + "notionalCap": "600000", + "notionalFloor": "300000", "maintMarginRatio": "0.025", - "cum": "1020.0" + "cum": "2120.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 300000.0, + "minNotional": 600000.0, "maxNotional": 3000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, @@ -38371,9 +38743,9 @@ "bracket": "5", "initialLeverage": "10", "notionalCap": "3000000", - "notionalFloor": "300000", + "notionalFloor": "600000", "maintMarginRatio": "0.05", - "cum": "8520.0" + "cum": "17120.0" } }, { @@ -38389,7 +38761,7 @@ "notionalCap": "6000000", "notionalFloor": "3000000", "maintMarginRatio": "0.1", - "cum": "158520.0" + "cum": "167120.0" } }, { @@ -38405,7 +38777,7 @@ "notionalCap": "7500000", "notionalFloor": "6000000", "maintMarginRatio": "0.125", - "cum": "308520.0" + "cum": "317120.0" } }, { @@ -38421,7 +38793,7 @@ "notionalCap": "15000000", "notionalFloor": "7500000", "maintMarginRatio": "0.25", - "cum": "1246020.0" + "cum": "1254620.0" } }, { @@ -38437,7 +38809,7 @@ "notionalCap": "30000000", "notionalFloor": "15000000", "maintMarginRatio": "0.5", - "cum": "4996020.0" + "cum": "5004620.0" } } ], From b7145debfb04b03916e3b3a39cc743b4959cd12b Mon Sep 17 00:00:00 2001 From: Anuj Jain Date: Thu, 5 Sep 2024 21:52:09 +0530 Subject: [PATCH 043/187] handle trade wide indicators --- docs/advanced-backtesting.md | 4 ++++ freqtrade/data/entryexitanalysis.py | 11 ++++++++++- tests/data/test_entryexitanalysis.py | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/advanced-backtesting.md b/docs/advanced-backtesting.md index de1264ae8..5004dfc2a 100644 --- a/docs/advanced-backtesting.md +++ b/docs/advanced-backtesting.md @@ -144,6 +144,10 @@ This detailed view of indicator values enhances the analysis. The `(entry)` and `(exit)` suffixes are added to indicators to distinguish the values at the entry and exit points of the trade. +!!! note "Trade-wide Indicators" + Certain trade-wide indicators do not have the `(entry)` or `(exit)` suffix. These indicators include: + `"open_date"`, `"close_date"`, `"min_rate"`, `"max_rate"`, `"profit_ratio"`, and `"profit_abs"`. + ### Filtering the trade output by date To show only trades between dates within your backtested timerange, supply the usual `timerange` option in `YYYYMMDD-[YYYYMMDD]` format: diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index 964c4f86f..974e39d39 100644 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -303,6 +303,15 @@ def print_results( def _merge_dfs(entry_df, exit_df, available_inds): merge_on = ["pair", "open_date"] + trade_wide_indicators = [ + "open_date", + "close_date", + "min_rate", + "max_rate", + "profit_ratio", + "profit_abs", + ] + signal_wide_indicators = list(set(available_inds) - set(trade_wide_indicators)) columns_to_keep = merge_on + ["enter_reason", "exit_reason"] + available_inds if exit_df is None or exit_df.empty: @@ -310,7 +319,7 @@ def _merge_dfs(entry_df, exit_df, available_inds): return pd.merge( entry_df[columns_to_keep], - exit_df[merge_on + available_inds], + exit_df[merge_on + signal_wide_indicators], on=merge_on, suffixes=(" (entry)", " (exit)"), ) diff --git a/tests/data/test_entryexitanalysis.py b/tests/data/test_entryexitanalysis.py index 39456b7a3..374b84fc7 100644 --- a/tests/data/test_entryexitanalysis.py +++ b/tests/data/test_entryexitanalysis.py @@ -168,6 +168,7 @@ def test_backtest_analysis_on_entry_and_rejected_signals_nomock( assert "close (exit)" in captured.out assert "rsi (exit)" in captured.out assert "52.829" in captured.out + assert "profit_abs" in captured.out # test group 1 args = get_args(base_args + ["--analysis-groups", "1"]) From 8d96844312cdd5f398107ee102313796a44ce5df Mon Sep 17 00:00:00 2001 From: Anuj Jain Date: Fri, 6 Sep 2024 12:28:02 +0530 Subject: [PATCH 044/187] use BT_DATA_COLUMNS for trade wide indicators --- docs/advanced-backtesting.md | 6 ++++-- freqtrade/data/entryexitanalysis.py | 11 ++--------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/docs/advanced-backtesting.md b/docs/advanced-backtesting.md index 5004dfc2a..a6b30b5f8 100644 --- a/docs/advanced-backtesting.md +++ b/docs/advanced-backtesting.md @@ -145,8 +145,10 @@ The `(entry)` and `(exit)` suffixes are added to indicators to distinguish the values at the entry and exit points of the trade. !!! note "Trade-wide Indicators" - Certain trade-wide indicators do not have the `(entry)` or `(exit)` suffix. These indicators include: - `"open_date"`, `"close_date"`, `"min_rate"`, `"max_rate"`, `"profit_ratio"`, and `"profit_abs"`. + Certain trade-wide indicators do not have the `(entry)` or `(exit)` suffix. These indicators include: `pair`, `stake_amount`, + `max_stake_amount`, `amount`, `open_date`, `close_date`, `open_rate`, `close_rate`, `fee_open`, `fee_close`, `trade_duration`, + `profit_ratio`, `profit_abs`, `exit_reason`,`initial_stop_loss_abs`, `initial_stop_loss_ratio`, `stop_loss_abs`, `stop_loss_ratio`, + `min_rate`, `max_rate`, `is_open`, `enter_tag`, `leverage`, `is_short`, `open_timestamp`, `close_timestamp` and `orders` ### Filtering the trade output by date diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index 974e39d39..8077e104a 100644 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -8,6 +8,7 @@ import pandas as pd from freqtrade.configuration import TimeRange from freqtrade.constants import Config from freqtrade.data.btanalysis import ( + BT_DATA_COLUMNS, get_latest_backtest_filename, load_backtest_data, load_backtest_stats, @@ -303,15 +304,7 @@ def print_results( def _merge_dfs(entry_df, exit_df, available_inds): merge_on = ["pair", "open_date"] - trade_wide_indicators = [ - "open_date", - "close_date", - "min_rate", - "max_rate", - "profit_ratio", - "profit_abs", - ] - signal_wide_indicators = list(set(available_inds) - set(trade_wide_indicators)) + signal_wide_indicators = list(set(available_inds) - set(BT_DATA_COLUMNS)) columns_to_keep = merge_on + ["enter_reason", "exit_reason"] + available_inds if exit_df is None or exit_df.empty: From 6a4b6412509f4c758fa615504e73abfed305e9dd Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 6 Sep 2024 20:58:54 +0200 Subject: [PATCH 045/187] feat: implement __str__ for marign and tradingmode enums --- freqtrade/enums/marginmode.py | 3 +++ freqtrade/enums/tradingmode.py | 3 +++ freqtrade/exchange/binance.py | 2 +- freqtrade/exchange/exchange.py | 4 ++-- freqtrade/persistence/trade_model.py | 4 ++-- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/freqtrade/enums/marginmode.py b/freqtrade/enums/marginmode.py index 0e8887a9a..9aa814c39 100644 --- a/freqtrade/enums/marginmode.py +++ b/freqtrade/enums/marginmode.py @@ -11,3 +11,6 @@ class MarginMode(str, Enum): CROSS = "cross" ISOLATED = "isolated" NONE = "" + + def __str__(self): + return f"{self.name.lower()}" diff --git a/freqtrade/enums/tradingmode.py b/freqtrade/enums/tradingmode.py index 62f9b4255..a681d60f9 100644 --- a/freqtrade/enums/tradingmode.py +++ b/freqtrade/enums/tradingmode.py @@ -10,3 +10,6 @@ class TradingMode(str, Enum): SPOT = "spot" MARGIN = "margin" FUTURES = "futures" + + def __str__(self): + return f"{self.name.lower()}" diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index d2e74f9eb..d7fb0a353 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -192,7 +192,7 @@ class Binance(Exchange): if maintenance_amt is None: raise OperationalException( "Parameter maintenance_amt is required by Binance.liquidation_price" - f"for {self.trading_mode.value}" + f"for {self.trading_mode}" ) if self.trading_mode == TradingMode.FUTURES: diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index cb1c1a49a..684eaa5d8 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -707,7 +707,7 @@ class Exchange: # Note: ccxt has BaseCurrency/QuoteCurrency format for pairs if self.markets and pair not in self.markets: raise OperationalException( - f"Pair {pair} is not available on {self.name} {self.trading_mode.value}. " + f"Pair {pair} is not available on {self.name} {self.trading_mode}. " f"Please remove {pair} from your whitelist." ) @@ -890,7 +890,7 @@ class Exchange: ): mm_value = margin_mode and margin_mode.value raise OperationalException( - f"Freqtrade does not support {mm_value} {trading_mode.value} on {self.name}" + f"Freqtrade does not support {mm_value} {trading_mode} on {self.name}" ) def get_option(self, param: str, default: Optional[Any] = None) -> Any: diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index 4e7f01906..49afd927b 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -623,7 +623,7 @@ class LocalTrade: self.orders = [] if self.trading_mode == TradingMode.MARGIN and self.interest_rate is None: raise OperationalException( - f"{self.trading_mode.value} trading requires param interest_rate on trades" + f"{self.trading_mode} trading requires param interest_rate on trades" ) def __repr__(self): @@ -1079,7 +1079,7 @@ class LocalTrade: return float(self._calc_base_close(amount1, rate, self.fee_close)) + funding_fees else: raise OperationalException( - f"{self.trading_mode.value} trading is not yet available using freqtrade" + f"{self.trading_mode} trading is not yet available using freqtrade" ) def calc_profit( From f714e306da948707034b189a2af3b296cd10d0a9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 6 Sep 2024 21:15:10 +0200 Subject: [PATCH 046/187] test: add margin and trading mode to test config --- tests/conftest.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index 8f15388ef..99c42de5f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -617,6 +617,8 @@ def get_default_conf(testdatadir): "dataformat_ohlcv": "feather", "dataformat_trades": "feather", "runmode": "dry_run", + "trading_mode": "spot", + "margin_mode": "", "candle_type_def": CandleType.SPOT, } return configuration From 1a2578a4b76891ce18bc04dd558b36ae572524ff Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 7 Sep 2024 08:47:45 +0200 Subject: [PATCH 047/187] feat: Add margin/Trading mode output to bt-output --- .../optimize/optimize_reports/bt_output.py | 20 +++++++++++++++++++ .../optimize_reports/optimize_reports.py | 2 ++ 2 files changed, 22 insertions(+) diff --git a/freqtrade/optimize/optimize_reports/bt_output.py b/freqtrade/optimize/optimize_reports/bt_output.py index ef58975ca..d509b75fb 100644 --- a/freqtrade/optimize/optimize_reports/bt_output.py +++ b/freqtrade/optimize/optimize_reports/bt_output.py @@ -263,12 +263,32 @@ def text_table_add_metrics(strat_results: Dict) -> None: else [] ) + trading_mode = ( + ( + [ + ( + "Trading Mode", + ( + "" + if not strat_results.get("margin_mode") + or strat_results.get("trading_mode", "spot") == "spot" + else f"{strat_results['margin_mode'].capitalize()} " + ) + + f"{strat_results['trading_mode'].capitalize()}", + ) + ] + ) + if "trading_mode" in strat_results + else [] + ) + # 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 # results with missing new fields. metrics = [ ("Backtesting from", strat_results["backtest_start"]), ("Backtesting to", strat_results["backtest_end"]), + *trading_mode, ("Max open trades", strat_results["max_open_trades"]), ("", ""), # Empty line to improve readability ( diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index 38a6cfbf8..c3bb607dd 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -504,6 +504,8 @@ def generate_strategy_stats( "exit_profit_only": config["exit_profit_only"], "exit_profit_offset": config["exit_profit_offset"], "ignore_roi_if_entry_signal": config["ignore_roi_if_entry_signal"], + "trading_mode": config["trading_mode"], + "margin_mode": config["margin_mode"], **periodic_breakdown, **daily_stats, **trade_stats, From d9ec66695c8c9d4256086839c530eae14f23720c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 7 Sep 2024 08:49:30 +0200 Subject: [PATCH 048/187] docs: update backtesting docs with new row --- docs/backtesting.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/backtesting.md b/docs/backtesting.md index 2feba7ada..12a6c346e 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -293,6 +293,7 @@ A backtesting result will look like that: |-----------------------------+---------------------| | Backtesting from | 2019-01-01 00:00:00 | | Backtesting to | 2019-05-01 00:00:00 | +| Trading Mode | Spot | | Max open trades | 3 | | | | | Total/Daily Avg Trades | 429 / 3.575 | @@ -398,6 +399,7 @@ It contains some useful key metrics about performance of your strategy on backte |-----------------------------+---------------------| | Backtesting from | 2019-01-01 00:00:00 | | Backtesting to | 2019-05-01 00:00:00 | +| Trading Mode | Spot | | Max open trades | 3 | | | | | Total/Daily Avg Trades | 429 / 3.575 | @@ -452,6 +454,7 @@ It contains some useful key metrics about performance of your strategy on backte - `Backtesting from` / `Backtesting to`: Backtesting range (usually defined with the `--timerange` option). - `Max open trades`: Setting of `max_open_trades` (or `--max-open-trades`) - or number of pairs in the pairlist (whatever is lower). +- `Trading Mode`: Spot or Futures trading. - `Total/Daily Avg Trades`: Identical to the total trades of the backtest output table / Total trades divided by the backtesting duration in days (this will give you information about how many trades to expect from the strategy). - `Starting balance`: Start balance - as given by dry-run-wallet (config or command line). - `Final balance`: Final balance - starting balance + absolute profit. From 1b00f512c1e546620697c79bd99ebcddd80b19dc Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 7 Sep 2024 09:24:21 +0200 Subject: [PATCH 049/187] fix: call order_filled callback for left open trades --- freqtrade/optimize/backtesting.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 7ea0b44c9..828908a4c 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -1165,12 +1165,10 @@ class Backtesting: self._exit_trade( trade, exit_row, exit_row[OPEN_IDX], trade.amount, ExitType.FORCE_EXIT.value ) - trade.orders[-1].close_bt_order(exit_row[DATE_IDX].to_pydatetime(), trade) - - trade.close_date = exit_row[DATE_IDX].to_pydatetime() trade.exit_reason = ExitType.FORCE_EXIT.value - trade.close(exit_row[OPEN_IDX], show_msg=False) - LocalTrade.close_bt_trade(trade) + self._process_exit_order( + trade.orders[-1], trade, exit_row[DATE_IDX].to_pydatetime(), exit_row, pair + ) def trade_slot_available(self, open_trade_count: int) -> bool: # Always allow trades when max_open_trades is enabled. From f95cc960e1db63584a8d226cbb2778d02dcbd5e3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 7 Sep 2024 09:25:20 +0200 Subject: [PATCH 050/187] test: tests should consider additional ff-update call --- tests/optimize/test_backtesting.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index d159c8602..b25230791 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -941,7 +941,7 @@ def test_backtest_one_detail(default_conf_usdt, mocker, testdatadir, use_detail) "use_detail,exp_funding_fee, exp_ff_updates", [ (True, -0.018054162, 11), - (False, -0.01780296, 5), + (False, -0.01780296, 6), ], ) def test_backtest_one_detail_futures( @@ -1051,8 +1051,8 @@ def test_backtest_one_detail_futures( @pytest.mark.parametrize( "use_detail,entries,max_stake,ff_updates,expected_ff", [ - (True, 50, 3000, 54, -1.18038144), - (False, 6, 360, 10, -0.14679994), + (True, 50, 3000, 55, -1.18038144), + (False, 6, 360, 11, -0.14679994), ], ) def test_backtest_one_detail_futures_funding_fees( From 704e32b0dc18034739337078e324882eded02e50 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 7 Sep 2024 09:28:35 +0200 Subject: [PATCH 051/187] feat: properly parse marginmode on startup --- freqtrade/configuration/configuration.py | 10 +++++++++- freqtrade/freqtradebot.py | 8 +++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index d9c860abd..1bbc84861 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -15,7 +15,14 @@ from freqtrade.configuration.directory_operations import create_datadir, create_ from freqtrade.configuration.environment_vars import enironment_vars_to_dict from freqtrade.configuration.load_config import load_file, load_from_files from freqtrade.constants import Config -from freqtrade.enums import NON_UTIL_MODES, TRADE_MODES, CandleType, RunMode, TradingMode +from freqtrade.enums import ( + NON_UTIL_MODES, + TRADE_MODES, + CandleType, + MarginMode, + RunMode, + TradingMode, +) from freqtrade.exceptions import OperationalException from freqtrade.loggers import setup_logging from freqtrade.misc import deep_merge_dicts, parse_db_uri_for_logging @@ -389,6 +396,7 @@ class Configuration: config.get("trading_mode", "spot") or "spot" ) config["trading_mode"] = TradingMode(config.get("trading_mode", "spot") or "spot") + config["margin_mode"] = MarginMode(config.get("margin_mode", "") or "") self._args_to_config( config, argname="candle_types", logstring="Detected --candle-types: {}" ) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index dff99e93e..15a3ae6ee 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -22,6 +22,7 @@ from freqtrade.edge import Edge from freqtrade.enums import ( ExitCheckTuple, ExitType, + MarginMode, RPCMessageType, SignalDirection, State, @@ -108,6 +109,7 @@ class FreqtradeBot(LoggingMixin): PairLocks.timeframe = self.config["timeframe"] self.trading_mode: TradingMode = self.config.get("trading_mode", TradingMode.SPOT) + self.margin_mode: MarginMode = self.config.get("margin_mode", MarginMode.NONE) self.last_process: Optional[datetime] = None # RPC runs in separate threads, can start handling external commands just after @@ -2216,7 +2218,11 @@ class FreqtradeBot(LoggingMixin): # TODO: should shorting/leverage be supported by Edge, # then this will need to be fixed. trade.adjust_stop_loss(trade.open_rate, self.strategy.stoploss, initial=True) - if order.ft_order_side == trade.entry_side or (trade.amount > 0 and trade.is_open): + if ( + order.ft_order_side == trade.entry_side + or (trade.amount > 0 and trade.is_open) + or self.margin_mode == MarginMode.CROSS + ): # Must also run for partial exits # TODO: Margin will need to use interest_rate as well. # interest_rate = self.exchange.get_interest_rate() From 0858e0a21ecfc6be391bf9f79741a32a3f4a5bbd Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 7 Sep 2024 15:29:23 +0200 Subject: [PATCH 052/187] Minor update to docs --- docs/advanced-backtesting.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/advanced-backtesting.md b/docs/advanced-backtesting.md index a6b30b5f8..b97db79c5 100644 --- a/docs/advanced-backtesting.md +++ b/docs/advanced-backtesting.md @@ -19,14 +19,12 @@ freqtrade backtesting -c --timeframe --strategy Date: Sat, 7 Sep 2024 18:28:56 +0200 Subject: [PATCH 053/187] feat(bybit): add support for unified Accounts --- docs/exchanges.md | 12 +++++++++--- freqtrade/exchange/bybit.py | 6 ++---- tests/exchange/test_bybit.py | 12 +++++------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/docs/exchanges.md b/docs/exchanges.md index f3550e97e..f55c45919 100644 --- a/docs/exchanges.md +++ b/docs/exchanges.md @@ -255,18 +255,24 @@ The configuration parameter `exchange.unknown_fee_rate` can be used to specify t ## Bybit Futures trading on bybit is currently supported for USDT markets, and will use isolated futures mode. -Users with unified accounts (there's no way back) can create a Sub-account which will start as "non-unified", and can therefore use isolated futures. -On startup, freqtrade will set the position mode to "One-way Mode" for the whole (sub)account. This avoids making this call over and over again (slowing down bot operations), but means that changes to this setting may result in exceptions and errors + +On startup, freqtrade will set the position mode to "One-way Mode" for the whole (sub)account. This avoids making this call over and over again (slowing down bot operations), but means that changes to this setting may result in exceptions and errors. As bybit doesn't provide funding rate history, the dry-run calculation is used for live trades as well. -API Keys for live futures trading (Subaccount on non-unified) must have the following permissions: +API Keys for live futures trading must have the following permissions: * Read-write * Contract - Orders * Contract - Positions We do strongly recommend to limit all API keys to the IP you're going to use it from. +!!! Warning "Unified accounts" + Freqtrade assumes accounts to be dedicated to the bot. + We therefore recommend the usage of one subaccount per bot. This is especially important when using unified accounts. + Other configurations (multiple bots on one account, manual non-bot trades on the bot account) are not supported and may lead to unexpected behavior. + + !!! Tip "Stoploss on Exchange" Bybit (futures only) supports `stoploss_on_exchange` and uses `stop-loss-limit` orders. It provides great advantages, so we recommend to benefit from it by enabling stoploss on exchange. On futures, Bybit supports both `stop-limit` as well as `stop-market` orders. You can use either `"limit"` or `"market"` in the `order_types.stoploss` configuration setting to decide which type to use. diff --git a/freqtrade/exchange/bybit.py b/freqtrade/exchange/bybit.py index 52cf37d31..af0071039 100644 --- a/freqtrade/exchange/bybit.py +++ b/freqtrade/exchange/bybit.py @@ -90,10 +90,8 @@ class Bybit(Exchange): # Returns a tuple of bools, first for margin, second for Account if is_unified and len(is_unified) > 1 and is_unified[1]: self.unified_account = True - logger.info("Bybit: Unified account.") - raise OperationalException( - "Bybit: Unified account is not supported. " - "Please use a standard (sub)account." + logger.info( + "Bybit: Unified account. Assuming dedicated subaccount for this bot." ) else: self.unified_account = False diff --git a/tests/exchange/test_bybit.py b/tests/exchange/test_bybit.py index 8dc11667c..c72d5ae0d 100644 --- a/tests/exchange/test_bybit.py +++ b/tests/exchange/test_bybit.py @@ -27,13 +27,11 @@ def test_additional_exchange_init_bybit(default_conf, mocker, caplog): api_mock.set_position_mode.reset_mock() api_mock.is_unified_enabled = MagicMock(return_value=[False, True]) - with pytest.raises(OperationalException, match=r"Bybit: Unified account is not supported.*"): - get_patched_exchange(mocker, default_conf, exchange="bybit", api_mock=api_mock) - assert log_has("Bybit: Unified account.", caplog) - # exchange = get_patched_exchange(mocker, default_conf, exchange="bybit", api_mock=api_mock) - # assert api_mock.set_position_mode.call_count == 1 - # assert api_mock.is_unified_enabled.call_count == 1 - # assert exchange.unified_account is True + exchange = get_patched_exchange(mocker, default_conf, exchange="bybit", api_mock=api_mock) + assert log_has("Bybit: Unified account. Assuming dedicated subaccount for this bot.", caplog) + assert api_mock.set_position_mode.call_count == 1 + assert api_mock.is_unified_enabled.call_count == 1 + assert exchange.unified_account is True ccxt_exceptionhandlers( mocker, default_conf, api_mock, "bybit", "additional_exchange_init", "set_position_mode" From a1681cdd637a42e66e5c5248cbb800f3dab10373 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 8 Sep 2024 08:24:48 +0200 Subject: [PATCH 054/187] chore: improve typing --- freqtrade/data/converter/orderflow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/data/converter/orderflow.py b/freqtrade/data/converter/orderflow.py index ca19a2622..f0cc726d2 100644 --- a/freqtrade/data/converter/orderflow.py +++ b/freqtrade/data/converter/orderflow.py @@ -12,7 +12,7 @@ from typing import Tuple import numpy as np import pandas as pd -from freqtrade.constants import DEFAULT_ORDERFLOW_COLUMNS +from freqtrade.constants import DEFAULT_ORDERFLOW_COLUMNS, Config from freqtrade.enums import RunMode from freqtrade.exceptions import DependencyException @@ -63,7 +63,7 @@ def _calculate_ohlcv_candle_start_and_end(df: pd.DataFrame, timeframe: str): def populate_dataframe_with_trades( cached_grouped_trades: OrderedDict[Tuple[datetime, datetime], pd.DataFrame], - config, + config: Config, dataframe: pd.DataFrame, trades: pd.DataFrame, ) -> Tuple[pd.DataFrame, OrderedDict[Tuple[datetime, datetime], pd.DataFrame]]: From 6e2aa6b4b81ef64d1ff95c2e2f40ba153cfaa849 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 8 Sep 2024 08:28:12 +0200 Subject: [PATCH 055/187] tests: remove unused imports --- tests/exchange/test_bybit.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/exchange/test_bybit.py b/tests/exchange/test_bybit.py index c72d5ae0d..f4b8a8ea1 100644 --- a/tests/exchange/test_bybit.py +++ b/tests/exchange/test_bybit.py @@ -1,11 +1,8 @@ from datetime import datetime, timedelta, timezone from unittest.mock import MagicMock -import pytest - from freqtrade.enums.marginmode import MarginMode from freqtrade.enums.tradingmode import TradingMode -from freqtrade.exceptions import OperationalException from tests.conftest import EXMS, get_mock_coro, get_patched_exchange, log_has from tests.exchange.test_exchange import ccxt_exceptionhandlers From 82e30c8519042187a1c7953ec8387e9b946b48d7 Mon Sep 17 00:00:00 2001 From: KingND <81396266+KingND@users.noreply.github.com> Date: Fri, 6 Sep 2024 22:03:17 -0400 Subject: [PATCH 056/187] feat: if a biased_indicator starting with & appears in a lookahead-analysis, caption the table with a note that freqai targets appearing here can be ignored --- .../optimize/analysis/lookahead_helpers.py | 24 +++- tests/optimize/test_lookahead_analysis.py | 114 ++++++++++++++++++ 2 files changed, 135 insertions(+), 3 deletions(-) diff --git a/freqtrade/optimize/analysis/lookahead_helpers.py b/freqtrade/optimize/analysis/lookahead_helpers.py index a8fb1cd35..aff2083bf 100644 --- a/freqtrade/optimize/analysis/lookahead_helpers.py +++ b/freqtrade/optimize/analysis/lookahead_helpers.py @@ -19,7 +19,9 @@ logger = logging.getLogger(__name__) class LookaheadAnalysisSubFunctions: @staticmethod def text_table_lookahead_analysis_instances( - config: Dict[str, Any], lookahead_instances: List[LookaheadAnalysis] + config: Dict[str, Any], + lookahead_instances: List[LookaheadAnalysis], + caption: str | None = None, ): headers = [ "filename", @@ -65,7 +67,12 @@ class LookaheadAnalysisSubFunctions: ] ) - print_rich_table(data, headers, summary="Lookahead Analysis") + print_rich_table( + data, + headers, + summary="Lookahead Analysis", + table_kwargs={"caption": caption} + ) return data @staticmethod @@ -239,8 +246,19 @@ class LookaheadAnalysisSubFunctions: # report the results if lookaheadAnalysis_instances: + caption: str | None = None + if any([ + any([ + indicator.startswith("&") + for indicator in inst.current_analysis.false_indicators + ]) for inst in lookaheadAnalysis_instances + ]): + caption = ( + "Any indicators in 'biased_indicators' which are used within " + "set_freqai_targets() can be ignored." + ) LookaheadAnalysisSubFunctions.text_table_lookahead_analysis_instances( - config, lookaheadAnalysis_instances + config, lookaheadAnalysis_instances, caption=caption ) if config.get("lookahead_analysis_exportfilename") is not None: LookaheadAnalysisSubFunctions.export_to_csv(config, lookaheadAnalysis_instances) diff --git a/tests/optimize/test_lookahead_analysis.py b/tests/optimize/test_lookahead_analysis.py index f7d38b24b..387587afb 100644 --- a/tests/optimize/test_lookahead_analysis.py +++ b/tests/optimize/test_lookahead_analysis.py @@ -133,6 +133,72 @@ def test_lookahead_helper_start(lookahead_conf, mocker) -> None: text_table_mock.reset_mock() +@pytest.mark.parametrize( + "indicators, expected_caption_text", + [ + ( + ["&indicator1", "indicator2"], + "Any indicators in 'biased_indicators' which are used " + "within set_freqai_targets() can be ignored." + ), + ( + ["indicator1", "&indicator2"], + "Any indicators in 'biased_indicators' which are used " + "within set_freqai_targets() can be ignored." + ), + ( + ["&indicator1", "&indicator2"], + "Any indicators in 'biased_indicators' which are used " + "within set_freqai_targets() can be ignored." + ), + ( + ["indicator1", "indicator2"], + None + ), + ( + [], + None + ) + ], + ids=( + "First of two biased indicators starts with '&'", + "Second of two biased indicators starts with '&'", + "Both biased indicators start with '&'", + "No biased indicators start with '&'", + "Empty biased indicators list", + ) +) +def test_lookahead_helper_start__caption_based_on_indicators( + indicators, + expected_caption_text, + lookahead_conf, + mocker +): + """Test that the table caption is only populated if a biased_indicator starts with '&'.""" + + single_mock = MagicMock() + lookahead_analysis = LookaheadAnalysis( + lookahead_conf, + {"name": "strategy_test_v3_with_lookahead_bias"}, + ) + lookahead_analysis.current_analysis.false_indicators = indicators + single_mock.return_value = lookahead_analysis + text_table_mock = MagicMock() + mocker.patch.multiple( + "freqtrade.optimize.analysis.lookahead_helpers.LookaheadAnalysisSubFunctions", + initialize_single_lookahead_analysis=single_mock, + text_table_lookahead_analysis_instances=text_table_mock, + ) + + LookaheadAnalysisSubFunctions.start(lookahead_conf) + + text_table_mock.assert_called_once_with( + lookahead_conf, + [lookahead_analysis], + caption=expected_caption_text + ) + + def test_lookahead_helper_text_table_lookahead_analysis_instances(lookahead_conf): analysis = Analysis() analysis.has_bias = True @@ -199,6 +265,54 @@ def test_lookahead_helper_text_table_lookahead_analysis_instances(lookahead_conf assert len(data) == 3 + +@pytest.mark.parametrize( + "caption", + [ + "", + "A test caption", + None, + False, + ], + ids=( + "Pass empty string", + "Pass non-empty string", + "Pass None", + "Don't pass caption", + ) +) +def test_lookahead_helper_text_table_lookahead_analysis_instances__caption( + caption, + lookahead_conf, + mocker, +): + """Test that the caption is passed in the table kwargs when calling print_rich_table().""" + + print_rich_table_mock = MagicMock() + mocker.patch( + "freqtrade.optimize.analysis.lookahead_helpers.print_rich_table", + print_rich_table_mock, + ) + lookahead_analysis = LookaheadAnalysis( + lookahead_conf, + { + "name": "strategy_test_v3_with_lookahead_bias", + "location": Path(lookahead_conf["strategy_path"], f"{lookahead_conf['strategy']}.py"), + } + ) + kwargs = {} + if caption is not False: + kwargs["caption"] = caption + + LookaheadAnalysisSubFunctions.text_table_lookahead_analysis_instances( + lookahead_conf, [lookahead_analysis], **kwargs + ) + + assert print_rich_table_mock.call_args[-1]["table_kwargs"]["caption"] == ( + caption if caption is not False else None + ) + + def test_lookahead_helper_export_to_csv(lookahead_conf): import pandas as pd From 5f52fc4338c59029f4d176d2103a4bf40ab5bf74 Mon Sep 17 00:00:00 2001 From: KingND <81396266+KingND@users.noreply.github.com> Date: Fri, 6 Sep 2024 22:17:53 -0400 Subject: [PATCH 057/187] feat: update lookahead-analysis doc caveats to include info regarding the false positive on FreqAI targets --- docs/lookahead-analysis.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/lookahead-analysis.md b/docs/lookahead-analysis.md index 90ba7041a..12dc355fa 100644 --- a/docs/lookahead-analysis.md +++ b/docs/lookahead-analysis.md @@ -101,3 +101,4 @@ This could lead to a false-negative (the strategy will then be reported as non-b - `lookahead-analysis` has access to everything that backtesting has too. Please don't provoke any configs like enabling position stacking. If you decide to do so, then make doubly sure that you won't ever run out of `max_open_trades` amount and neither leftover money in your wallet. +- `biased_indicators` will falsely flag FreqAI target indicators defined in `set_freqai_targets()` as biased. These are not biased and can safely be ignored. From bb9f64027af88abaca71c9fb72e94fd1c8a8ff49 Mon Sep 17 00:00:00 2001 From: KingND <81396266+KingND@users.noreply.github.com> Date: Fri, 6 Sep 2024 22:32:13 -0400 Subject: [PATCH 058/187] chore: improve language in docs --- docs/lookahead-analysis.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/lookahead-analysis.md b/docs/lookahead-analysis.md index 12dc355fa..1cdf9aaf0 100644 --- a/docs/lookahead-analysis.md +++ b/docs/lookahead-analysis.md @@ -101,4 +101,4 @@ This could lead to a false-negative (the strategy will then be reported as non-b - `lookahead-analysis` has access to everything that backtesting has too. Please don't provoke any configs like enabling position stacking. If you decide to do so, then make doubly sure that you won't ever run out of `max_open_trades` amount and neither leftover money in your wallet. -- `biased_indicators` will falsely flag FreqAI target indicators defined in `set_freqai_targets()` as biased. These are not biased and can safely be ignored. +- In the results table, the `biased_indicators` column will falsely flag FreqAI target indicators defined in `set_freqai_targets()` as biased. These are not biased and can safely be ignored. From c6c65b1799c99e120c4a58a024ed838cae02534d Mon Sep 17 00:00:00 2001 From: KingND <81396266+KingND@users.noreply.github.com> Date: Fri, 6 Sep 2024 22:38:56 -0400 Subject: [PATCH 059/187] chore: flake8 --- tests/optimize/test_lookahead_analysis.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/optimize/test_lookahead_analysis.py b/tests/optimize/test_lookahead_analysis.py index 387587afb..eb64ad42d 100644 --- a/tests/optimize/test_lookahead_analysis.py +++ b/tests/optimize/test_lookahead_analysis.py @@ -265,7 +265,6 @@ def test_lookahead_helper_text_table_lookahead_analysis_instances(lookahead_conf assert len(data) == 3 - @pytest.mark.parametrize( "caption", [ From 53cab5074b0f94800e62c400dee7750b9121f986 Mon Sep 17 00:00:00 2001 From: KingND <81396266+KingND@users.noreply.github.com> Date: Fri, 6 Sep 2024 22:42:44 -0400 Subject: [PATCH 060/187] chore: refactor and cleanup tests --- tests/optimize/test_lookahead_analysis.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/optimize/test_lookahead_analysis.py b/tests/optimize/test_lookahead_analysis.py index eb64ad42d..dd036cdc9 100644 --- a/tests/optimize/test_lookahead_analysis.py +++ b/tests/optimize/test_lookahead_analysis.py @@ -13,6 +13,12 @@ from freqtrade.optimize.analysis.lookahead_helpers import LookaheadAnalysisSubFu from tests.conftest import EXMS, get_args, log_has_re, patch_exchange +IGNORE_BIASED_INDICATORS_CAPTION = ( + "Any indicators in 'biased_indicators' which are used within " + "set_freqai_targets() can be ignored." +) + + @pytest.fixture def lookahead_conf(default_conf_usdt, tmp_path): default_conf_usdt["user_data_dir"] = tmp_path @@ -138,18 +144,15 @@ def test_lookahead_helper_start(lookahead_conf, mocker) -> None: [ ( ["&indicator1", "indicator2"], - "Any indicators in 'biased_indicators' which are used " - "within set_freqai_targets() can be ignored." + IGNORE_BIASED_INDICATORS_CAPTION, ), ( ["indicator1", "&indicator2"], - "Any indicators in 'biased_indicators' which are used " - "within set_freqai_targets() can be ignored." + IGNORE_BIASED_INDICATORS_CAPTION, ), ( ["&indicator1", "&indicator2"], - "Any indicators in 'biased_indicators' which are used " - "within set_freqai_targets() can be ignored." + IGNORE_BIASED_INDICATORS_CAPTION, ), ( ["indicator1", "indicator2"], @@ -158,7 +161,7 @@ def test_lookahead_helper_start(lookahead_conf, mocker) -> None: ( [], None - ) + ), ], ids=( "First of two biased indicators starts with '&'", @@ -166,7 +169,7 @@ def test_lookahead_helper_start(lookahead_conf, mocker) -> None: "Both biased indicators start with '&'", "No biased indicators start with '&'", "Empty biased indicators list", - ) + ), ) def test_lookahead_helper_start__caption_based_on_indicators( indicators, @@ -278,7 +281,7 @@ def test_lookahead_helper_text_table_lookahead_analysis_instances(lookahead_conf "Pass non-empty string", "Pass None", "Don't pass caption", - ) + ), ) def test_lookahead_helper_text_table_lookahead_analysis_instances__caption( caption, From 69678574d4e3421ed3fe697a58b9624091f03242 Mon Sep 17 00:00:00 2001 From: KingND <81396266+KingND@users.noreply.github.com> Date: Sat, 7 Sep 2024 16:01:52 -0400 Subject: [PATCH 061/187] fix: support python 3.9 union type hinting --- freqtrade/optimize/analysis/lookahead_helpers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/optimize/analysis/lookahead_helpers.py b/freqtrade/optimize/analysis/lookahead_helpers.py index aff2083bf..b3cba9ed4 100644 --- a/freqtrade/optimize/analysis/lookahead_helpers.py +++ b/freqtrade/optimize/analysis/lookahead_helpers.py @@ -1,7 +1,7 @@ import logging import time from pathlib import Path -from typing import Any, Dict, List +from typing import Any, Dict, List, Union import pandas as pd from rich.text import Text @@ -21,7 +21,7 @@ class LookaheadAnalysisSubFunctions: def text_table_lookahead_analysis_instances( config: Dict[str, Any], lookahead_instances: List[LookaheadAnalysis], - caption: str | None = None, + caption: Union[str, None] = None, ): headers = [ "filename", @@ -246,7 +246,7 @@ class LookaheadAnalysisSubFunctions: # report the results if lookaheadAnalysis_instances: - caption: str | None = None + caption: Union[str, None] = None if any([ any([ indicator.startswith("&") From f970454cb49d6d9f213e4114a960de2f4c2516f6 Mon Sep 17 00:00:00 2001 From: KingND <81396266+KingND@users.noreply.github.com> Date: Sun, 8 Sep 2024 13:57:48 -0400 Subject: [PATCH 062/187] chore: ruff format --- .../optimize/analysis/lookahead_helpers.py | 22 ++++++++++--------- tests/optimize/test_lookahead_analysis.py | 21 +++++------------- 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/freqtrade/optimize/analysis/lookahead_helpers.py b/freqtrade/optimize/analysis/lookahead_helpers.py index b3cba9ed4..730f9fd72 100644 --- a/freqtrade/optimize/analysis/lookahead_helpers.py +++ b/freqtrade/optimize/analysis/lookahead_helpers.py @@ -68,10 +68,7 @@ class LookaheadAnalysisSubFunctions: ) print_rich_table( - data, - headers, - summary="Lookahead Analysis", - table_kwargs={"caption": caption} + data, headers, summary="Lookahead Analysis", table_kwargs={"caption": caption} ) return data @@ -247,12 +244,17 @@ class LookaheadAnalysisSubFunctions: # report the results if lookaheadAnalysis_instances: caption: Union[str, None] = None - if any([ - any([ - indicator.startswith("&") - for indicator in inst.current_analysis.false_indicators - ]) for inst in lookaheadAnalysis_instances - ]): + if any( + [ + any( + [ + indicator.startswith("&") + for indicator in inst.current_analysis.false_indicators + ] + ) + for inst in lookaheadAnalysis_instances + ] + ): caption = ( "Any indicators in 'biased_indicators' which are used within " "set_freqai_targets() can be ignored." diff --git a/tests/optimize/test_lookahead_analysis.py b/tests/optimize/test_lookahead_analysis.py index dd036cdc9..67c83762a 100644 --- a/tests/optimize/test_lookahead_analysis.py +++ b/tests/optimize/test_lookahead_analysis.py @@ -154,14 +154,8 @@ def test_lookahead_helper_start(lookahead_conf, mocker) -> None: ["&indicator1", "&indicator2"], IGNORE_BIASED_INDICATORS_CAPTION, ), - ( - ["indicator1", "indicator2"], - None - ), - ( - [], - None - ), + (["indicator1", "indicator2"], None), + ([], None), ], ids=( "First of two biased indicators starts with '&'", @@ -172,10 +166,7 @@ def test_lookahead_helper_start(lookahead_conf, mocker) -> None: ), ) def test_lookahead_helper_start__caption_based_on_indicators( - indicators, - expected_caption_text, - lookahead_conf, - mocker + indicators, expected_caption_text, lookahead_conf, mocker ): """Test that the table caption is only populated if a biased_indicator starts with '&'.""" @@ -196,9 +187,7 @@ def test_lookahead_helper_start__caption_based_on_indicators( LookaheadAnalysisSubFunctions.start(lookahead_conf) text_table_mock.assert_called_once_with( - lookahead_conf, - [lookahead_analysis], - caption=expected_caption_text + lookahead_conf, [lookahead_analysis], caption=expected_caption_text ) @@ -300,7 +289,7 @@ def test_lookahead_helper_text_table_lookahead_analysis_instances__caption( { "name": "strategy_test_v3_with_lookahead_bias", "location": Path(lookahead_conf["strategy_path"], f"{lookahead_conf['strategy']}.py"), - } + }, ) kwargs = {} if caption is not False: From df9669ba2c161f87f65f21bd5ca75551df7e2b2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 03:43:50 +0000 Subject: [PATCH 063/187] chore(deps-dev): bump the types group with 2 updates Bumps the types group with 2 updates: [types-requests](https://github.com/python/typeshed) and [types-python-dateutil](https://github.com/python/typeshed). Updates `types-requests` from 2.32.0.20240712 to 2.32.0.20240907 - [Commits](https://github.com/python/typeshed/commits) Updates `types-python-dateutil` from 2.9.0.20240821 to 2.9.0.20240906 - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-requests dependency-type: direct:development update-type: version-update:semver-patch dependency-group: types - dependency-name: types-python-dateutil dependency-type: direct:development update-type: version-update:semver-patch dependency-group: types ... Signed-off-by: dependabot[bot] --- requirements-dev.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index b0a46db71..06b770232 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -27,6 +27,6 @@ nbconvert==7.16.4 # mypy types types-cachetools==5.5.0.20240820 types-filelock==3.2.7 -types-requests==2.32.0.20240712 +types-requests==2.32.0.20240907 types-tabulate==0.9.0.20240106 -types-python-dateutil==2.9.0.20240821 +types-python-dateutil==2.9.0.20240906 From 9856c2cfc48e632dc4edc9d6a8003f573c255c75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 03:44:57 +0000 Subject: [PATCH 064/187] chore(deps): bump pydantic from 2.8.2 to 2.9.0 Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.8.2 to 2.9.0. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v2.8.2...v2.9.0) --- updated-dependencies: - dependency-name: pydantic dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 31d663b15..390d94295 100644 --- a/requirements.txt +++ b/requirements.txt @@ -42,7 +42,7 @@ sdnotify==0.3.2 # API Server fastapi==0.112.2 -pydantic==2.8.2 +pydantic==2.9.0 uvicorn==0.30.6 pyjwt==2.9.0 aiofiles==24.1.0 From 47358a822964c120e9170b58d3ab4c9d7427e5d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 03:45:03 +0000 Subject: [PATCH 065/187] chore(deps): bump catboost from 1.2.5 to 1.2.7 Bumps [catboost](https://github.com/catboost/catboost) from 1.2.5 to 1.2.7. - [Release notes](https://github.com/catboost/catboost/releases) - [Changelog](https://github.com/catboost/catboost/blob/master/RELEASE.md) - [Commits](https://github.com/catboost/catboost/compare/v1.2.5...v1.2.7) --- updated-dependencies: - dependency-name: catboost dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements-freqai.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-freqai.txt b/requirements-freqai.txt index 0db247289..1731ac054 100644 --- a/requirements-freqai.txt +++ b/requirements-freqai.txt @@ -5,7 +5,7 @@ # Required for freqai scikit-learn==1.5.1 joblib==1.4.2 -catboost==1.2.5; 'arm' not in platform_machine +catboost==1.2.7; 'arm' not in platform_machine # Pin Matplotlib - it's depended on by catboost # Temporary downgrade of matplotlib due to https://github.com/matplotlib/matplotlib/issues/28551 matplotlib==3.9.2 From ccf93cfdcdb7f89359410bb4342b1cd31cf52c8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 03:45:14 +0000 Subject: [PATCH 066/187] chore(deps): bump torch from 2.2.2 to 2.4.1 Bumps [torch](https://github.com/pytorch/pytorch) from 2.2.2 to 2.4.1. - [Release notes](https://github.com/pytorch/pytorch/releases) - [Changelog](https://github.com/pytorch/pytorch/blob/main/RELEASE.md) - [Commits](https://github.com/pytorch/pytorch/compare/v2.2.2...v2.4.1) --- updated-dependencies: - dependency-name: torch dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements-freqai-rl.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-freqai-rl.txt b/requirements-freqai-rl.txt index 9b808f66f..c9db23d96 100644 --- a/requirements-freqai-rl.txt +++ b/requirements-freqai-rl.txt @@ -3,7 +3,7 @@ # Required for freqai-rl torch==2.2.2; sys_platform == 'darwin' and platform_machine == 'x86_64' -torch==2.4.0; sys_platform != 'darwin' or platform_machine != 'x86_64' +torch==2.4.1; sys_platform != 'darwin' or platform_machine != 'x86_64' gymnasium==0.29.1 stable_baselines3==2.3.2 sb3_contrib>=2.2.1 From 699be03bb73d492acb898521c181a53afcd9768a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 03:45:29 +0000 Subject: [PATCH 067/187] chore(deps): bump filelock from 3.15.4 to 3.16.0 Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.15.4 to 3.16.0. - [Release notes](https://github.com/tox-dev/py-filelock/releases) - [Changelog](https://github.com/tox-dev/filelock/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/py-filelock/compare/3.15.4...3.16.0) --- updated-dependencies: - dependency-name: filelock dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements-hyperopt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index 3391d8c68..0daa19128 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -6,4 +6,4 @@ scipy==1.14.1; python_version >= "3.10" scipy==1.13.1; python_version < "3.10" scikit-learn==1.5.1 ft-scikit-optimize==0.9.2 -filelock==3.15.4 +filelock==3.16.0 From d099f30a3420d329da728bd9c3a1982f1864f6d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 03:45:51 +0000 Subject: [PATCH 068/187] chore(deps-dev): bump ruff from 0.6.3 to 0.6.4 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.3 to 0.6.4. - [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.6.3...0.6.4) --- updated-dependencies: - dependency-name: ruff 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 b0a46db71..371596538 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,7 +7,7 @@ -r docs/requirements-docs.txt coveralls==4.0.1 -ruff==0.6.3 +ruff==0.6.4 mypy==1.11.2 pre-commit==3.8.0 pytest==8.3.2 From b0976031aedc2dcdc04cc5694a21443c36e837d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 03:46:05 +0000 Subject: [PATCH 069/187] chore(deps): bump ccxt from 4.3.93 to 4.3.98 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.3.93 to 4.3.98. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.3.93...4.3.98) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 31d663b15..91ae1509a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ bottleneck==1.4.0 numexpr==2.10.1 pandas-ta==0.3.14b -ccxt==4.3.93 +ccxt==4.3.98 cryptography==42.0.8; platform_machine == 'armv7l' cryptography==43.0.1; platform_machine != 'armv7l' aiohttp==3.10.5 From b7bda2355d94f79081b95ee803c4703eadccc088 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 03:46:24 +0000 Subject: [PATCH 070/187] chore(deps): bump sqlalchemy from 2.0.32 to 2.0.34 Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.32 to 2.0.34. - [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases) - [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst) - [Commits](https://github.com/sqlalchemy/sqlalchemy/commits) --- updated-dependencies: - dependency-name: sqlalchemy dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 31d663b15..0aeda9948 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ ccxt==4.3.93 cryptography==42.0.8; platform_machine == 'armv7l' cryptography==43.0.1; platform_machine != 'armv7l' aiohttp==3.10.5 -SQLAlchemy==2.0.32 +SQLAlchemy==2.0.34 python-telegram-bot==21.5 # can't be hard-pinned due to telegram-bot pinning httpx with ~ httpx>=0.24.1 From 05af6df5363832579854dda96f5ff2ca2fe7a992 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 03:59:29 +0000 Subject: [PATCH 071/187] chore(deps): bump peter-evans/create-pull-request from 6 to 7 Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6 to 7. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/v6...v7) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/binance-lev-tier-update.yml | 2 +- .github/workflows/pre-commit-update.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/binance-lev-tier-update.yml b/.github/workflows/binance-lev-tier-update.yml index 2e0a3d3b2..844a6c8f5 100644 --- a/.github/workflows/binance-lev-tier-update.yml +++ b/.github/workflows/binance-lev-tier-update.yml @@ -32,7 +32,7 @@ jobs: run: python build_helpers/binance_update_lev_tiers.py - - uses: peter-evans/create-pull-request@v6 + - uses: peter-evans/create-pull-request@v7 with: token: ${{ secrets.REPO_SCOPED_TOKEN }} add-paths: freqtrade/exchange/binance_leverage_tiers.json diff --git a/.github/workflows/pre-commit-update.yml b/.github/workflows/pre-commit-update.yml index d30fdd1bf..5d71f513f 100644 --- a/.github/workflows/pre-commit-update.yml +++ b/.github/workflows/pre-commit-update.yml @@ -26,7 +26,7 @@ jobs: - name: Run auto-update run: pre-commit autoupdate - - uses: peter-evans/create-pull-request@v6 + - uses: peter-evans/create-pull-request@v7 with: token: ${{ secrets.REPO_SCOPED_TOKEN }} add-paths: .pre-commit-config.yaml From 621be1139518934dd0c615d75b8f72a90570ffe3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 03:59:34 +0000 Subject: [PATCH 072/187] chore(deps): bump pypa/gh-action-pypi-publish from 1.10.0 to 1.10.1 Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.10.0 to 1.10.1. - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.10.0...v1.10.1) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6ec36161b..d45841a28 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -537,12 +537,12 @@ jobs: - name: Publish to PyPI (Test) - uses: pypa/gh-action-pypi-publish@v1.10.0 + uses: pypa/gh-action-pypi-publish@v1.10.1 with: repository-url: https://test.pypi.org/legacy/ - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@v1.10.0 + uses: pypa/gh-action-pypi-publish@v1.10.1 deploy-docker: From 9b97be4aa4f68ea97bfdf6f10d900e51910ca566 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 9 Sep 2024 06:44:35 +0200 Subject: [PATCH 073/187] Bump pre-commit dependencies --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3e1d9fa34..9da692bce 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,9 +16,9 @@ repos: additional_dependencies: - types-cachetools==5.5.0.20240820 - types-filelock==3.2.7 - - types-requests==2.32.0.20240712 + - types-requests==2.32.0.20240907 - types-tabulate==0.9.0.20240106 - - types-python-dateutil==2.9.0.20240821 + - types-python-dateutil==2.9.0.20240906 - SQLAlchemy==2.0.32 # stages: [push] From 7aa7027a3452839debf484216eeadba00b95812b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 06:55:07 +0000 Subject: [PATCH 074/187] chore(deps): bump fastapi from 0.112.2 to 0.114.0 Bumps [fastapi](https://github.com/fastapi/fastapi) from 0.112.2 to 0.114.0. - [Release notes](https://github.com/fastapi/fastapi/releases) - [Commits](https://github.com/fastapi/fastapi/compare/0.112.2...0.114.0) --- updated-dependencies: - dependency-name: fastapi 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 390d94295..0dce545d2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -41,7 +41,7 @@ orjson==3.10.7 sdnotify==0.3.2 # API Server -fastapi==0.112.2 +fastapi==0.114.0 pydantic==2.9.0 uvicorn==0.30.6 pyjwt==2.9.0 From 2c17551b2750c1b2fd132957ce349052427b10c5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 9 Sep 2024 10:15:18 +0200 Subject: [PATCH 075/187] chore: bump sqlalchemy in mypy additional deps --- .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 3e1d9fa34..328387ead 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: - types-requests==2.32.0.20240712 - types-tabulate==0.9.0.20240106 - types-python-dateutil==2.9.0.20240821 - - SQLAlchemy==2.0.32 + - SQLAlchemy==2.0.34 # stages: [push] - repo: https://github.com/pycqa/isort From 9742216479b3deef0812483efa4969992d0e76a2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 9 Sep 2024 18:23:07 +0200 Subject: [PATCH 076/187] chore: run ruff-format on pre-commit --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6fe2f79d2..66c81b3de 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -34,6 +34,7 @@ repos: rev: 'v0.6.3' hooks: - id: ruff + - id: ruff-format - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.6.0 From ae155c78c26d26fc778201ad800ff94acf615ac7 Mon Sep 17 00:00:00 2001 From: dxbstyle Date: Mon, 9 Sep 2024 21:29:49 +0200 Subject: [PATCH 077/187] added check --- freqtrade/exchange/kraken.py | 1 + 1 file changed, 1 insertion(+) diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index 7f3346cfe..553e61ff8 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -78,6 +78,7 @@ class Kraken(Exchange): # x["side"], x["amount"], ) for x in orders + if x["price"] is not None ] for bal in balances: if not isinstance(balances[bal], dict): From 01da36f984f8bab317a1f33cfd5dc49e90da46bf Mon Sep 17 00:00:00 2001 From: xmatthias <5024695+xmatthias@users.noreply.github.com> Date: Tue, 10 Sep 2024 03:03:23 +0000 Subject: [PATCH 078/187] chore: update pre-commit hooks --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 66c81b3de..3fcde5a36 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: - repo: https://github.com/charliermarsh/ruff-pre-commit # Ruff version. - rev: 'v0.6.3' + rev: 'v0.6.4' hooks: - id: ruff - id: ruff-format From 98e08df807325aa2f4494ded2a0d1e2ea44faf39 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 04:07:26 +0000 Subject: [PATCH 079/187] chore(deps): bump python Bumps python from 3.12.5-slim-bookworm to 3.12.6-slim-bookworm. --- updated-dependencies: - dependency-name: python dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index fbe1de165..bc2fc4635 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.12.5-slim-bookworm as base +FROM python:3.12.6-slim-bookworm as base # Setup env ENV LANG C.UTF-8 From 95fa7083a9989cb2551f01894493fdd29e32359a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 04:07:33 +0000 Subject: [PATCH 080/187] chore(deps): bump python in /docker Bumps python from 3.11.9-slim-bookworm to 3.12.6-slim-bookworm. --- updated-dependencies: - dependency-name: python dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- docker/Dockerfile.armhf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile.armhf b/docker/Dockerfile.armhf index ed3c5fbde..2fdf1606c 100644 --- a/docker/Dockerfile.armhf +++ b/docker/Dockerfile.armhf @@ -1,4 +1,4 @@ -FROM python:3.11.9-slim-bookworm as base +FROM python:3.12.6-slim-bookworm as base # Setup env ENV LANG C.UTF-8 From 8c1b119e8424f7e5ad565f96ec10010738c610f9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 10 Sep 2024 06:25:17 +0200 Subject: [PATCH 081/187] chore: rpi image should remain on 3.11 series --- docker/Dockerfile.armhf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile.armhf b/docker/Dockerfile.armhf index 2fdf1606c..1a6d52ad4 100644 --- a/docker/Dockerfile.armhf +++ b/docker/Dockerfile.armhf @@ -1,4 +1,4 @@ -FROM python:3.12.6-slim-bookworm as base +FROM python:3.11.10-slim-bookworm as base # Setup env ENV LANG C.UTF-8 From 4765656f87d5e4411218e01923d9742671e87076 Mon Sep 17 00:00:00 2001 From: Anuj Jain Date: Tue, 10 Sep 2024 15:21:56 +0530 Subject: [PATCH 082/187] Add filter for entry and exit only parameter --- freqtrade/commands/arguments.py | 2 ++ freqtrade/commands/cli_options.py | 6 ++++ freqtrade/configuration/configuration.py | 2 ++ freqtrade/data/entryexitanalysis.py | 37 ++++++++++++++++++++---- 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 62a79b0e8..0bc3bc7f7 100755 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -228,6 +228,8 @@ ARGS_ANALYZE_ENTRIES_EXITS = [ "enter_reason_list", "exit_reason_list", "indicator_list", + "entry_only", + "exit_only", "timerange", "analysis_rejected", "analysis_to_csv", diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 54e139443..d279569c5 100755 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -719,6 +719,12 @@ AVAILABLE_CLI_OPTIONS = { nargs="+", default=[], ), + "entry_only": Arg( + "--entry-only", help=("Only analyze entry signals."), action="store_true", default=False + ), + "exit_only": Arg( + "--exit-only", help=("Only analyze exit signals."), action="store_true", default=False + ), "analysis_rejected": Arg( "--rejected-signals", help="Analyse rejected signals", diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 1bbc84861..0a99f9044 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -407,6 +407,8 @@ class Configuration: ("enter_reason_list", "Analysis enter tag list: {}"), ("exit_reason_list", "Analysis exit tag list: {}"), ("indicator_list", "Analysis indicator list: {}"), + ("entry_only", "Only analyze entry signals: {}"), + ("exit_only", "Only analyze exit signals: {}"), ("timerange", "Filter trades by timerange: {}"), ("analysis_rejected", "Analyse rejected signals: {}"), ("analysis_to_csv", "Store analysis tables to CSV: {}"), diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index 8077e104a..f7ab7836f 100644 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -263,6 +263,8 @@ def print_results( exit_df: pd.DataFrame, analysis_groups: List[str], indicator_list: List[str], + entry_only: bool, + exit_only: bool, csv_path: Path, rejected_signals=None, to_csv=False, @@ -288,7 +290,7 @@ def print_results( if ind in res_df: available_inds.append(ind) - merged_df = _merge_dfs(res_df, exit_df, available_inds) + merged_df = _merge_dfs(res_df, exit_df, available_inds, entry_only, exit_only) _print_table( merged_df, @@ -302,16 +304,30 @@ def print_results( print("\\No trades to show") -def _merge_dfs(entry_df, exit_df, available_inds): +def _merge_dfs( + entry_df: pd.DataFrame, + exit_df: pd.DataFrame, + available_inds: List[str], + entry_only: bool, + exit_only: bool, +): merge_on = ["pair", "open_date"] signal_wide_indicators = list(set(available_inds) - set(BT_DATA_COLUMNS)) - columns_to_keep = merge_on + ["enter_reason", "exit_reason"] + available_inds + columns_to_keep = merge_on + ["enter_reason", "exit_reason"] - if exit_df is None or exit_df.empty: - return entry_df[columns_to_keep] + if exit_df is None or exit_df.empty or entry_only is True: + return entry_df[columns_to_keep + available_inds] + + if exit_only is True: + return pd.merge( + entry_df[columns_to_keep], + exit_df[merge_on + signal_wide_indicators], + on=merge_on, + suffixes=(" (entry)", " (exit)"), + ) return pd.merge( - entry_df[columns_to_keep], + entry_df[columns_to_keep + available_inds], exit_df[merge_on + signal_wide_indicators], on=merge_on, suffixes=(" (entry)", " (exit)"), @@ -343,9 +359,16 @@ def process_entry_exit_reasons(config: Config): enter_reason_list = config.get("enter_reason_list", ["all"]) exit_reason_list = config.get("exit_reason_list", ["all"]) indicator_list = config.get("indicator_list", []) + entry_only = config.get("entry_only", False) + exit_only = config.get("exit_only", False) do_rejected = config.get("analysis_rejected", False) to_csv = config.get("analysis_to_csv", False) csv_path = Path(config.get("analysis_csv_path", config["exportfilename"])) + + if entry_only is True and exit_only is True: + raise OperationalException( + "Cannot use --entry-only and --exit-only at the same time. Please choose one." + ) if to_csv and not csv_path.is_dir(): raise OperationalException(f"Specified directory {csv_path} does not exist.") @@ -400,6 +423,8 @@ def process_entry_exit_reasons(config: Config): exit_df, analysis_groups, indicator_list, + entry_only, + exit_only, rejected_signals=rej_df, to_csv=to_csv, csv_path=csv_path, From f1df7e9bdc3306bea81df8b019dee6c30153e7b4 Mon Sep 17 00:00:00 2001 From: colorfulgray0 Date: Wed, 11 Sep 2024 11:33:38 +0800 Subject: [PATCH 083/187] chore: remove redundant method --- freqtrade/rpc/telegram.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 22b574621..46939daed 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -1274,7 +1274,7 @@ class Telegram(RPCHandler): InlineKeyboardButton(text=trade[1], callback_data=f"force_exit__{trade[0]}") for trade in trades ] - buttons_aligned = self._layout_inline_keyboard_onecol(trade_buttons) + buttons_aligned = self._layout_inline_keyboard(trade_buttons, cols=1) buttons_aligned.append( [InlineKeyboardButton(text="Cancel", callback_data="force_exit__cancel")] @@ -1348,12 +1348,6 @@ class Telegram(RPCHandler): ) -> List[List[InlineKeyboardButton]]: return [buttons[i : i + cols] for i in range(0, len(buttons), cols)] - @staticmethod - def _layout_inline_keyboard_onecol( - buttons: List[InlineKeyboardButton], cols=1 - ) -> List[List[InlineKeyboardButton]]: - return [buttons[i : i + cols] for i in range(0, len(buttons), cols)] - @authorized_only async def _force_enter( self, update: Update, context: CallbackContext, order_side: SignalDirection From addd27faf816afb00a667e131a48f4d27c246d5e Mon Sep 17 00:00:00 2001 From: Anuj Jain Date: Wed, 11 Sep 2024 15:33:26 +0530 Subject: [PATCH 084/187] Update tests and docs --- docs/advanced-backtesting.md | 19 ++ tests/data/test_entryexitanalysis.py | 304 +++++++++++++++++++++++++++ 2 files changed, 323 insertions(+) diff --git a/docs/advanced-backtesting.md b/docs/advanced-backtesting.md index b97db79c5..40584a656 100644 --- a/docs/advanced-backtesting.md +++ b/docs/advanced-backtesting.md @@ -149,6 +149,25 @@ to distinguish the values at the entry and exit points of the trade. `profit_ratio`, `profit_abs`, `exit_reason`,`initial_stop_loss_abs`, `initial_stop_loss_ratio`, `stop_loss_abs`, `stop_loss_ratio`, `min_rate`, `max_rate`, `is_open`, `enter_tag`, `leverage`, `is_short`, `open_timestamp`, `close_timestamp` and `orders` +#### Filtering Indicators Based on Entry or Exit Signals + +The `--indicator-list` option, by default, displays indicator values for both entry and exit signals. To filter the indicator values exclusively for entry signals, you can use the `--entry-only` argument. Similarly, to display indicator values only at exit signals, use the `--exit-only` argument. + +Example: Display indicator values at entry signals: + +```bash +freqtrade backtesting-analysis -c user_data/config.json --analysis-groups 0 --indicator-list chikou_span tenkan_sen --entry-only +``` + +Example: Display indicator values at exit signals: + +```bash +freqtrade backtesting-analysis -c user_data/config.json --analysis-groups 0 --indicator-list chikou_span tenkan_sen --exit-only +``` + +!!! note + When using these filters, the indicator names will not be suffixed with `(entry)` or `(exit)`. + ### Filtering the trade output by date To show only trades between dates within your backtested timerange, supply the usual `timerange` option in `YYYYMMDD-[YYYYMMDD]` format: diff --git a/tests/data/test_entryexitanalysis.py b/tests/data/test_entryexitanalysis.py index 374b84fc7..509c9b92c 100644 --- a/tests/data/test_entryexitanalysis.py +++ b/tests/data/test_entryexitanalysis.py @@ -7,6 +7,7 @@ import pytest from freqtrade.commands.analyze_commands import start_analysis_entries_exits from freqtrade.commands.optimize_commands import start_backtesting from freqtrade.enums import ExitType +from freqtrade.exceptions import OperationalException from freqtrade.optimize.backtesting import Backtesting from tests.conftest import get_args, patch_exchange, patched_configuration_load_config_file @@ -256,3 +257,306 @@ def test_backtest_analysis_on_entry_and_rejected_signals_nomock( start_analysis_entries_exits(args) captured = capsys.readouterr() assert "no rejected signals" in captured.out + + +def test_backtest_analysis_with_invalid_config( + default_conf, mocker, caplog, testdatadir, user_dir, capsys +): + caplog.set_level(logging.INFO) + (user_dir / "backtest_results").mkdir(parents=True, exist_ok=True) + + default_conf.update( + { + "use_exit_signal": True, + "exit_profit_only": False, + "exit_profit_offset": 0.0, + "ignore_roi_if_entry_signal": False, + } + ) + patch_exchange(mocker) + result1 = pd.DataFrame( + { + "pair": ["ETH/BTC", "LTC/BTC", "ETH/BTC", "LTC/BTC"], + "profit_ratio": [0.025, 0.05, -0.1, -0.05], + "profit_abs": [0.5, 2.0, -4.0, -2.0], + "open_date": pd.to_datetime( + [ + "2018-01-29 18:40:00", + "2018-01-30 03:30:00", + "2018-01-30 08:10:00", + "2018-01-31 13:30:00", + ], + utc=True, + ), + "close_date": pd.to_datetime( + [ + "2018-01-29 20:45:00", + "2018-01-30 05:35:00", + "2018-01-30 09:10:00", + "2018-01-31 15:00:00", + ], + utc=True, + ), + "trade_duration": [235, 40, 60, 90], + "is_open": [False, False, False, False], + "stake_amount": [0.01, 0.01, 0.01, 0.01], + "open_rate": [0.104445, 0.10302485, 0.10302485, 0.10302485], + "close_rate": [0.104969, 0.103541, 0.102041, 0.102541], + "is_short": [False, False, False, False], + "enter_tag": [ + "enter_tag_long_a", + "enter_tag_long_b", + "enter_tag_long_a", + "enter_tag_long_b", + ], + "exit_reason": [ + ExitType.ROI.value, + ExitType.EXIT_SIGNAL.value, + ExitType.STOP_LOSS.value, + ExitType.TRAILING_STOP_LOSS.value, + ], + } + ) + + backtestmock = MagicMock( + side_effect=[ + { + "results": result1, + "config": default_conf, + "locks": [], + "rejected_signals": 20, + "timedout_entry_orders": 0, + "timedout_exit_orders": 0, + "canceled_trade_entries": 0, + "canceled_entry_orders": 0, + "replaced_entry_orders": 0, + "final_balance": 1000, + } + ] + ) + mocker.patch( + "freqtrade.plugins.pairlistmanager.PairListManager.whitelist", + PropertyMock(return_value=["ETH/BTC", "LTC/BTC", "DASH/BTC"]), + ) + mocker.patch("freqtrade.optimize.backtesting.Backtesting.backtest", backtestmock) + + patched_configuration_load_config_file(mocker, default_conf) + + args = [ + "backtesting", + "--config", + "config.json", + "--datadir", + str(testdatadir), + "--user-data-dir", + str(user_dir), + "--timeframe", + "5m", + "--timerange", + "1515560100-1517287800", + "--export", + "signals", + "--cache", + "none", + ] + args = get_args(args) + start_backtesting(args) + + captured = capsys.readouterr() + assert "BACKTESTING REPORT" in captured.out + assert "EXIT REASON STATS" in captured.out + assert "LEFT OPEN TRADES REPORT" in captured.out + + base_args = [ + "backtesting-analysis", + "--config", + "config.json", + "--datadir", + str(testdatadir), + "--user-data-dir", + str(user_dir), + ] + + # test with both entry and exit only arguments + args = get_args( + base_args + + [ + "--analysis-groups", + "0", + "--indicator-list", + "close", + "rsi", + "profit_abs", + "--entry-only", + "--exit-only", + ] + ) + with pytest.raises( + OperationalException, + match=r"Cannot use --entry-only and --exit-only at the same time. Please choose one.", + ): + start_analysis_entries_exits(args) + + +def test_backtest_analysis_on_entry_and_rejected_signals_only_entry_signals( + default_conf, mocker, caplog, testdatadir, user_dir, capsys +): + caplog.set_level(logging.INFO) + (user_dir / "backtest_results").mkdir(parents=True, exist_ok=True) + + default_conf.update( + { + "use_exit_signal": True, + "exit_profit_only": False, + "exit_profit_offset": 0.0, + "ignore_roi_if_entry_signal": False, + } + ) + patch_exchange(mocker) + result1 = pd.DataFrame( + { + "pair": ["ETH/BTC", "LTC/BTC", "ETH/BTC", "LTC/BTC"], + "profit_ratio": [0.025, 0.05, -0.1, -0.05], + "profit_abs": [0.5, 2.0, -4.0, -2.0], + "open_date": pd.to_datetime( + [ + "2018-01-29 18:40:00", + "2018-01-30 03:30:00", + "2018-01-30 08:10:00", + "2018-01-31 13:30:00", + ], + utc=True, + ), + "close_date": pd.to_datetime( + [ + "2018-01-29 20:45:00", + "2018-01-30 05:35:00", + "2018-01-30 09:10:00", + "2018-01-31 15:00:00", + ], + utc=True, + ), + "trade_duration": [235, 40, 60, 90], + "is_open": [False, False, False, False], + "stake_amount": [0.01, 0.01, 0.01, 0.01], + "open_rate": [0.104445, 0.10302485, 0.10302485, 0.10302485], + "close_rate": [0.104969, 0.103541, 0.102041, 0.102541], + "is_short": [False, False, False, False], + "enter_tag": [ + "enter_tag_long_a", + "enter_tag_long_b", + "enter_tag_long_a", + "enter_tag_long_b", + ], + "exit_reason": [ + ExitType.ROI.value, + ExitType.EXIT_SIGNAL.value, + ExitType.STOP_LOSS.value, + ExitType.TRAILING_STOP_LOSS.value, + ], + } + ) + + backtestmock = MagicMock( + side_effect=[ + { + "results": result1, + "config": default_conf, + "locks": [], + "rejected_signals": 20, + "timedout_entry_orders": 0, + "timedout_exit_orders": 0, + "canceled_trade_entries": 0, + "canceled_entry_orders": 0, + "replaced_entry_orders": 0, + "final_balance": 1000, + } + ] + ) + mocker.patch( + "freqtrade.plugins.pairlistmanager.PairListManager.whitelist", + PropertyMock(return_value=["ETH/BTC", "LTC/BTC", "DASH/BTC"]), + ) + mocker.patch("freqtrade.optimize.backtesting.Backtesting.backtest", backtestmock) + + patched_configuration_load_config_file(mocker, default_conf) + + args = [ + "backtesting", + "--config", + "config.json", + "--datadir", + str(testdatadir), + "--user-data-dir", + str(user_dir), + "--timeframe", + "5m", + "--timerange", + "1515560100-1517287800", + "--export", + "signals", + "--cache", + "none", + ] + args = get_args(args) + start_backtesting(args) + + captured = capsys.readouterr() + assert "BACKTESTING REPORT" in captured.out + assert "EXIT REASON STATS" in captured.out + assert "LEFT OPEN TRADES REPORT" in captured.out + + base_args = [ + "backtesting-analysis", + "--config", + "config.json", + "--datadir", + str(testdatadir), + "--user-data-dir", + str(user_dir), + ] + + # test group 0 and indicator list + args = get_args( + base_args + + [ + "--analysis-groups", + "0", + "--indicator-list", + "close", + "rsi", + "profit_abs", + "--entry-only", + ] + ) + start_analysis_entries_exits(args) + captured = capsys.readouterr() + assert "LTC/BTC" in captured.out + assert "ETH/BTC" in captured.out + assert "enter_tag_long_a" in captured.out + assert "enter_tag_long_b" in captured.out + assert "exit_signal" in captured.out + assert "roi" in captured.out + assert "stop_loss" in captured.out + assert "trailing_stop_loss" in captured.out + assert "0.5" in captured.out + assert "-4" in captured.out + assert "-2" in captured.out + assert "-3.5" in captured.out + assert "50" in captured.out + assert "0" in captured.out + assert "0.016" in captured.out + assert "34.049" in captured.out + assert "0.104" in captured.out + assert "52.829" in captured.out + # assert indicator list + assert "close" in captured.out + assert "close (entry)" not in captured.out + assert "0.016" in captured.out + assert "rsi (entry)" not in captured.out + assert "rsi" in captured.out + assert "54.320" in captured.out + assert "close (exit)" not in captured.out + assert "rsi (exit)" not in captured.out + assert "52.829" in captured.out + assert "profit_abs" in captured.out From c9acb1466ca5580a958d3dd8ed49ae671d77bf71 Mon Sep 17 00:00:00 2001 From: Joe Schr <8218910+TheJoeSchr@users.noreply.github.com> Date: Tue, 10 Sep 2024 15:28:53 +0200 Subject: [PATCH 085/187] fix: orderflow data missing for plotting and other runmodes --- freqtrade/data/dataprovider.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/freqtrade/data/dataprovider.py b/freqtrade/data/dataprovider.py index b4950f515..e40228511 100644 --- a/freqtrade/data/dataprovider.py +++ b/freqtrade/data/dataprovider.py @@ -520,7 +520,7 @@ class DataProvider: return self._exchange.trades( (pair, timeframe or self._config["timeframe"], _candle_type), copy=copy ) - elif self.runmode in (RunMode.BACKTEST, RunMode.HYPEROPT): + else: data_handler = get_datahandler( self._config["datadir"], data_format=self._config["dataformat_trades"] ) @@ -529,9 +529,6 @@ class DataProvider: ) return trades_df - else: - return DataFrame() - def market(self, pair: str) -> Optional[Dict[str, Any]]: """ Return market data for the pair From 439658fcf1222b18363296dcb022719775ad4a16 Mon Sep 17 00:00:00 2001 From: Joe Schr <8218910+TheJoeSchr@users.noreply.github.com> Date: Wed, 11 Sep 2024 16:50:27 +0200 Subject: [PATCH 086/187] fix: remove tests for orderflow data missing of other runmodes --- tests/data/test_dataprovider.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/data/test_dataprovider.py b/tests/data/test_dataprovider.py index 8656da10b..220aafef0 100644 --- a/tests/data/test_dataprovider.py +++ b/tests/data/test_dataprovider.py @@ -90,13 +90,6 @@ def test_historic_trades(mocker, default_conf, trades_history_df): assert isinstance(data, DataFrame) assert len(data) == len(trades_history_df) - # Random other runmode - default_conf["runmode"] = RunMode.UTIL_EXCHANGE - dp = DataProvider(default_conf, None) - data = dp.trades("UNITTEST/BTC", "5m") - assert isinstance(data, DataFrame) - assert len(data) == 0 - def test_historic_ohlcv_dataformat(mocker, default_conf, ohlcv_history): hdf5loadmock = MagicMock(return_value=ohlcv_history) From d15921b3f2894c1e19045536178bc771c370ebd7 Mon Sep 17 00:00:00 2001 From: xmatthias <5024695+xmatthias@users.noreply.github.com> Date: Thu, 12 Sep 2024 03:12:54 +0000 Subject: [PATCH 087/187] chore: update pre-commit hooks --- .../exchange/binance_leverage_tiers.json | 2920 ++++++++++------- 1 file changed, 1734 insertions(+), 1186 deletions(-) diff --git a/freqtrade/exchange/binance_leverage_tiers.json b/freqtrade/exchange/binance_leverage_tiers.json index 859d87b9f..bcf497efe 100644 --- a/freqtrade/exchange/binance_leverage_tiers.json +++ b/freqtrade/exchange/binance_leverage_tiers.json @@ -280,128 +280,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", - "notionalCap": "50000", - "notionalFloor": "5000", - "maintMarginRatio": "0.02", - "cum": "25.0" + "initialLeverage": "50", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 30000.0, + "maxNotional": 150000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "100000", - "notionalFloor": "50000", - "maintMarginRatio": "0.025", - "cum": "275.0" + "initialLeverage": "25", + "notionalCap": "150000", + "notionalFloor": "30000", + "maintMarginRatio": "0.02", + "cum": "200.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 150000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "1000000", - "notionalFloor": "100000", - "maintMarginRatio": "0.05", - "cum": "2775.0" + "initialLeverage": "20", + "notionalCap": "300000", + "notionalFloor": "150000", + "maintMarginRatio": "0.025", + "cum": "950.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 300000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "2000000", - "notionalFloor": "1000000", - "maintMarginRatio": "0.1", - "cum": "52775.0" + "initialLeverage": "10", + "notionalCap": "1500000", + "notionalFloor": "300000", + "maintMarginRatio": "0.05", + "cum": "8450.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 2500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "2500000", - "notionalFloor": "2000000", - "maintMarginRatio": "0.125", - "cum": "102775.0" + "initialLeverage": "5", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.1", + "cum": "83450.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 2500000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 3000000.0, + "maxNotional": 3750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "5000000", - "notionalFloor": "2500000", - "maintMarginRatio": "0.25", - "cum": "415275.0" + "initialLeverage": "4", + "notionalCap": "3750000", + "notionalFloor": "3000000", + "maintMarginRatio": "0.125", + "cum": "158450.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "minNotional": 3750000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "7500000", + "notionalFloor": "3750000", + "maintMarginRatio": "0.25", + "cum": "627200.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 15000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "10000000", - "notionalFloor": "5000000", + "notionalCap": "15000000", + "notionalFloor": "7500000", "maintMarginRatio": "0.5", - "cum": "1665275.0" + "cum": "2502200.0" } } ], @@ -1580,128 +1596,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 10000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "20", - "notionalCap": "25000", - "notionalFloor": "5000", - "maintMarginRatio": "0.025", + "initialLeverage": "50", + "notionalCap": "40000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 100000.0, - "maintenanceMarginRate": 0.03, - "maxLeverage": 15.0, + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "15", - "notionalCap": "100000", - "notionalFloor": "25000", - "maintMarginRatio": "0.03", - "cum": "175.0" + "initialLeverage": "25", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.02", + "cum": "250.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 100000.0, + "minNotional": 200000.0, "maxNotional": 400000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "10", + "initialLeverage": "20", "notionalCap": "400000", - "notionalFloor": "100000", - "maintMarginRatio": "0.05", - "cum": "2175.0" + "notionalFloor": "200000", + "maintMarginRatio": "0.025", + "cum": "1250.0" } }, { "tier": 5.0, "currency": "USDT", "minNotional": 400000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "1000000", + "initialLeverage": "10", + "notionalCap": "2000000", "notionalFloor": "400000", - "maintMarginRatio": "0.1", - "cum": "22175.0" + "maintMarginRatio": "0.05", + "cum": "11250.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 2000000.0, + "maxNotional": 4000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "2000000", - "notionalFloor": "1000000", - "maintMarginRatio": "0.125", - "cum": "47175.0" + "initialLeverage": "5", + "notionalCap": "4000000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.1", + "cum": "111250.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 6000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 4000000.0, + "maxNotional": 5000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "6000000", - "notionalFloor": "2000000", - "maintMarginRatio": "0.25", - "cum": "297175.0" + "initialLeverage": "4", + "notionalCap": "5000000", + "notionalFloor": "4000000", + "maintMarginRatio": "0.125", + "cum": "211250.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 6000000.0, + "minNotional": 5000000.0, "maxNotional": 10000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "10000000", + "notionalFloor": "5000000", + "maintMarginRatio": "0.25", + "cum": "836250.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "10000000", - "notionalFloor": "6000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.5", - "cum": "1797175.0" + "cum": "3336250.0" } } ], @@ -1970,13 +2002,13 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.005, "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "notionalCap": "5000", + "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.005", "cum": "0.0" @@ -1985,65 +2017,65 @@ { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 10000.0, - "maintenanceMarginRate": 0.006, + "minNotional": 10000.0, + "maxNotional": 50000.0, + "maintenanceMarginRate": 0.01, "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "notionalCap": "10000", - "notionalFloor": "5000", - "maintMarginRatio": "0.006", - "cum": "5.0" + "notionalCap": "50000", + "notionalFloor": "10000", + "maintMarginRatio": "0.01", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.01, + "minNotional": 50000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.015, "maxLeverage": 40.0, "info": { "bracket": "3", "initialLeverage": "40", - "notionalCap": "50000", - "notionalFloor": "10000", - "maintMarginRatio": "0.01", - "cum": "45.0" + "notionalCap": "100000", + "notionalFloor": "50000", + "maintMarginRatio": "0.015", + "cum": "300.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 250000.0, + "minNotional": 100000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": "4", "initialLeverage": "25", - "notionalCap": "250000", - "notionalFloor": "50000", + "notionalCap": "500000", + "notionalFloor": "100000", "maintMarginRatio": "0.02", - "cum": "545.0" + "cum": "800.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 250000.0, + "minNotional": 500000.0, "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "20", "notionalCap": "1000000", - "notionalFloor": "250000", - "maintMarginRatio": "0.05", - "cum": "8045.0" + "notionalFloor": "500000", + "maintMarginRatio": "0.025", + "cum": "3300.0" } }, { @@ -2051,15 +2083,15 @@ "currency": "USDT", "minNotional": 1000000.0, "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "6", - "initialLeverage": "5", + "initialLeverage": "10", "notionalCap": "5000000", "notionalFloor": "1000000", - "maintMarginRatio": "0.1", - "cum": "58045.0" + "maintMarginRatio": "0.05", + "cum": "28300.0" } }, { @@ -2067,15 +2099,15 @@ "currency": "USDT", "minNotional": 5000000.0, "maxNotional": 10000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "7", - "initialLeverage": "4", + "initialLeverage": "5", "notionalCap": "10000000", "notionalFloor": "5000000", - "maintMarginRatio": "0.125", - "cum": "183045.0" + "maintMarginRatio": "0.1", + "cum": "278300.0" } }, { @@ -2083,15 +2115,15 @@ "currency": "USDT", "minNotional": 10000000.0, "maxNotional": 20000000.0, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "8", - "initialLeverage": "3", + "initialLeverage": "4", "notionalCap": "20000000", "notionalFloor": "10000000", - "maintMarginRatio": "0.15", - "cum": "433045.0" + "maintMarginRatio": "0.125", + "cum": "528300.0" } }, { @@ -2107,7 +2139,7 @@ "notionalCap": "30000000", "notionalFloor": "20000000", "maintMarginRatio": "0.25", - "cum": "2433045.0" + "cum": "3028300.0" } }, { @@ -2123,7 +2155,153 @@ "notionalCap": "50000000", "notionalFloor": "30000000", "maintMarginRatio": "0.5", - "cum": "9933045.0" + "cum": "10528300.0" + } + } + ], + "AERGO/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "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, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "40000", + "notionalFloor": "20000", + "maintMarginRatio": "0.025", + "cum": "175.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.05", + "cum": "1175.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "11175.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.125", + "cum": "21175.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.25", + "cum": "83675.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "333675.0" } } ], @@ -3774,13 +3952,13 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50.0, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" @@ -3789,113 +3967,129 @@ { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 25000.0, + "minNotional": 10000.0, + "maxNotional": 60000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 25.0, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", - "notionalCap": "25000", - "notionalFloor": "5000", + "initialLeverage": "50", + "notionalCap": "60000", + "notionalFloor": "10000", "maintMarginRatio": "0.015", - "cum": "25.0" + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 25000.0, + "minNotional": 60000.0, "maxNotional": 900000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 20.0, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "20", + "initialLeverage": "25", "notionalCap": "900000", - "notionalFloor": "25000", + "notionalFloor": "60000", "maintMarginRatio": "0.02", - "cum": "150.0" + "cum": "350.0" } }, { "tier": 4.0, "currency": "USDT", "minNotional": 900000.0, - "maxNotional": 1800000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxNotional": 1100000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "1800000", + "initialLeverage": "20", + "notionalCap": "1100000", "notionalFloor": "900000", - "maintMarginRatio": "0.05", - "cum": "27150.0" + "maintMarginRatio": "0.025", + "cum": "4850.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 1800000.0, - "maxNotional": 4800000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 1100000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "4800000", - "notionalFloor": "1800000", - "maintMarginRatio": "0.1", - "cum": "117150.0" + "initialLeverage": "10", + "notionalCap": "3000000", + "notionalFloor": "1100000", + "maintMarginRatio": "0.05", + "cum": "32350.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 4800000.0, + "minNotional": 3000000.0, "maxNotional": 6000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "4", + "initialLeverage": "5", "notionalCap": "6000000", - "notionalFloor": "4800000", - "maintMarginRatio": "0.125", - "cum": "237150.0" + "notionalFloor": "3000000", + "maintMarginRatio": "0.1", + "cum": "182350.0" } }, { "tier": 7.0, "currency": "USDT", "minNotional": 6000000.0, - "maxNotional": 18000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "18000000", + "initialLeverage": "4", + "notionalCap": "7500000", "notionalFloor": "6000000", - "maintMarginRatio": "0.25", - "cum": "987150.0" + "maintMarginRatio": "0.125", + "cum": "332350.0" } }, { "tier": 8.0, "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 18000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "18000000", + "notionalFloor": "7500000", + "maintMarginRatio": "0.25", + "cum": "1269850.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", "minNotional": 18000000.0, "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", "notionalCap": "30000000", "notionalFloor": "18000000", "maintMarginRatio": "0.5", - "cum": "5487150.0" + "cum": "5769850.0" } } ], @@ -8727,6 +8921,152 @@ } } ], + "BSW/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "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, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "40000", + "notionalFloor": "20000", + "maintMarginRatio": "0.025", + "cum": "175.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.05", + "cum": "1175.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "11175.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.125", + "cum": "21175.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.25", + "cum": "83675.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "333675.0" + } + } + ], "BTC/USDC:USDC": [ { "tier": 1.0, @@ -13710,128 +14050,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", - "notionalCap": "50000", - "notionalFloor": "5000", - "maintMarginRatio": "0.02", - "cum": "25.0" + "initialLeverage": "50", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 50000.0, + "minNotional": 30000.0, "maxNotional": 150000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "20", + "initialLeverage": "25", "notionalCap": "150000", - "notionalFloor": "50000", - "maintMarginRatio": "0.025", - "cum": "275.0" + "notionalFloor": "30000", + "maintMarginRatio": "0.02", + "cum": "200.0" } }, { "tier": 4.0, "currency": "USDT", "minNotional": 150000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "1500000", + "initialLeverage": "20", + "notionalCap": "300000", "notionalFloor": "150000", - "maintMarginRatio": "0.05", - "cum": "4025.0" + "maintMarginRatio": "0.025", + "cum": "950.0" } }, { "tier": 5.0, "currency": "USDT", + "minNotional": 300000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "1500000", + "notionalFloor": "300000", + "maintMarginRatio": "0.05", + "cum": "8450.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", "minNotional": 1500000.0, "maxNotional": 3000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { - "bracket": "5", + "bracket": "6", "initialLeverage": "5", "notionalCap": "3000000", "notionalFloor": "1500000", "maintMarginRatio": "0.1", - "cum": "79025.0" + "cum": "83450.0" } }, { - "tier": 6.0, + "tier": 7.0, "currency": "USDT", "minNotional": 3000000.0, "maxNotional": 3750000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { - "bracket": "6", + "bracket": "7", "initialLeverage": "4", "notionalCap": "3750000", "notionalFloor": "3000000", "maintMarginRatio": "0.125", - "cum": "154025.0" + "cum": "158450.0" } }, { - "tier": 7.0, + "tier": 8.0, "currency": "USDT", "minNotional": 3750000.0, "maxNotional": 7500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": "7", + "bracket": "8", "initialLeverage": "2", "notionalCap": "7500000", "notionalFloor": "3750000", "maintMarginRatio": "0.25", - "cum": "622775.0" + "cum": "627200.0" } }, { - "tier": 8.0, + "tier": 9.0, "currency": "USDT", "minNotional": 7500000.0, "maxNotional": 15000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", "notionalCap": "15000000", "notionalFloor": "7500000", "maintMarginRatio": "0.5", - "cum": "2497775.0" + "cum": "2502200.0" } } ], @@ -15560,128 +15916,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 20.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "20", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 15.0, + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "15", - "notionalCap": "25000", - "notionalFloor": "5000", - "maintMarginRatio": "0.02", - "cum": "25.0" + "initialLeverage": "50", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 80000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 10.0, + "minNotional": 30000.0, + "maxNotional": 150000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "10", - "notionalCap": "80000", - "notionalFloor": "25000", - "maintMarginRatio": "0.025", - "cum": "150.0" + "initialLeverage": "25", + "notionalCap": "150000", + "notionalFloor": "30000", + "maintMarginRatio": "0.02", + "cum": "200.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 80000.0, - "maxNotional": 800000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 8.0, + "minNotional": 150000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "8", - "notionalCap": "800000", - "notionalFloor": "80000", - "maintMarginRatio": "0.05", - "cum": "2150.0" + "initialLeverage": "20", + "notionalCap": "300000", + "notionalFloor": "150000", + "maintMarginRatio": "0.025", + "cum": "950.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 800000.0, - "maxNotional": 1600000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 300000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "1600000", - "notionalFloor": "800000", - "maintMarginRatio": "0.1", - "cum": "42150.0" + "initialLeverage": "10", + "notionalCap": "1500000", + "notionalFloor": "300000", + "maintMarginRatio": "0.05", + "cum": "8450.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 1600000.0, - "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "2000000", - "notionalFloor": "1600000", - "maintMarginRatio": "0.125", - "cum": "82150.0" + "initialLeverage": "5", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.1", + "cum": "83450.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 4000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 3000000.0, + "maxNotional": 3750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "4000000", - "notionalFloor": "2000000", - "maintMarginRatio": "0.25", - "cum": "332150.0" + "initialLeverage": "4", + "notionalCap": "3750000", + "notionalFloor": "3000000", + "maintMarginRatio": "0.125", + "cum": "158450.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 4000000.0, - "maxNotional": 5000000.0, + "minNotional": 3750000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "7500000", + "notionalFloor": "3750000", + "maintMarginRatio": "0.25", + "cum": "627200.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 15000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "5000000", - "notionalFloor": "4000000", + "notionalCap": "15000000", + "notionalFloor": "7500000", "maintMarginRatio": "0.5", - "cum": "1332150.0" + "cum": "2502200.0" } } ], @@ -16351,120 +16723,6 @@ } } ], - "FRONT/USDT:USDT": [ - { - "tier": 1.0, - "currency": "USDT", - "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 21.0, - "info": { - "bracket": "1", - "initialLeverage": "21", - "notionalCap": "5000", - "notionalFloor": "0", - "maintMarginRatio": "0.015", - "cum": "0.0" - } - }, - { - "tier": 2.0, - "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, - "info": { - "bracket": "2", - "initialLeverage": "20", - "notionalCap": "25000", - "notionalFloor": "5000", - "maintMarginRatio": "0.025", - "cum": "50.0" - } - }, - { - "tier": 3.0, - "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 200000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, - "info": { - "bracket": "3", - "initialLeverage": "10", - "notionalCap": "200000", - "notionalFloor": "25000", - "maintMarginRatio": "0.05", - "cum": "675.0" - } - }, - { - "tier": 4.0, - "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 500000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, - "info": { - "bracket": "4", - "initialLeverage": "5", - "notionalCap": "500000", - "notionalFloor": "200000", - "maintMarginRatio": "0.1", - "cum": "10675.0" - } - }, - { - "tier": 5.0, - "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, - "info": { - "bracket": "5", - "initialLeverage": "4", - "notionalCap": "1000000", - "notionalFloor": "500000", - "maintMarginRatio": "0.125", - "cum": "23175.0" - } - }, - { - "tier": 6.0, - "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, - "info": { - "bracket": "6", - "initialLeverage": "2", - "notionalCap": "3000000", - "notionalFloor": "1000000", - "maintMarginRatio": "0.25", - "cum": "148175.0" - } - }, - { - "tier": 7.0, - "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 3500000.0, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1.0, - "info": { - "bracket": "7", - "initialLeverage": "1", - "notionalCap": "3500000", - "notionalFloor": "3000000", - "maintMarginRatio": "0.5", - "cum": "898175.0" - } - } - ], "FTM/USDT:USDT": [ { "tier": 1.0, @@ -16472,10 +16730,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.006, - "maxLeverage": 50.0, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", + "initialLeverage": "75", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.006", @@ -16488,10 +16746,10 @@ "minNotional": 5000.0, "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25.0, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", + "initialLeverage": "50", "notionalCap": "50000", "notionalFloor": "5000", "maintMarginRatio": "0.01", @@ -16502,96 +16760,128 @@ "tier": 3.0, "currency": "USDT", "minNotional": 50000.0, - "maxNotional": 400000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxNotional": 80000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 40.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "400000", + "initialLeverage": "40", + "notionalCap": "80000", "notionalFloor": "50000", - "maintMarginRatio": "0.025", - "cum": "770.0" + "maintMarginRatio": "0.015", + "cum": "270.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 400000.0, - "maxNotional": 800000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 80000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "800000", - "notionalFloor": "400000", - "maintMarginRatio": "0.05", - "cum": "10770.0" + "initialLeverage": "25", + "notionalCap": "300000", + "notionalFloor": "80000", + "maintMarginRatio": "0.02", + "cum": "670.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 800000.0, - "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 300000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "2000000", - "notionalFloor": "800000", - "maintMarginRatio": "0.1", - "cum": "50770.0" + "initialLeverage": "20", + "notionalCap": "600000", + "notionalFloor": "300000", + "maintMarginRatio": "0.025", + "cum": "2170.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 600000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "5000000", - "notionalFloor": "2000000", - "maintMarginRatio": "0.125", - "cum": "100770.0" + "initialLeverage": "10", + "notionalCap": "3000000", + "notionalFloor": "600000", + "maintMarginRatio": "0.05", + "cum": "17170.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 12000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 3000000.0, + "maxNotional": 6000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "12000000", - "notionalFloor": "5000000", - "maintMarginRatio": "0.25", - "cum": "725770.0" + "initialLeverage": "5", + "notionalCap": "6000000", + "notionalFloor": "3000000", + "maintMarginRatio": "0.1", + "cum": "167170.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 12000000.0, - "maxNotional": 20000000.0, + "minNotional": 6000000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "8", + "initialLeverage": "4", + "notionalCap": "7500000", + "notionalFloor": "6000000", + "maintMarginRatio": "0.125", + "cum": "317170.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 15000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "9", + "initialLeverage": "2", + "notionalCap": "15000000", + "notionalFloor": "7500000", + "maintMarginRatio": "0.25", + "cum": "1254670.0" + } + }, + { + "tier": 10.0, + "currency": "USDT", + "minNotional": 15000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "10", "initialLeverage": "1", - "notionalCap": "20000000", - "notionalFloor": "12000000", + "notionalCap": "30000000", + "notionalFloor": "15000000", "maintMarginRatio": "0.5", - "cum": "3725770.0" + "cum": "5004670.0" } } ], @@ -16910,13 +17200,13 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.006, - "maxLeverage": 50.0, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.006", "cum": "0.0" @@ -16925,113 +17215,145 @@ { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, + "minNotional": 10000.0, "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25.0, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", + "initialLeverage": "50", "notionalCap": "50000", - "notionalFloor": "5000", + "notionalFloor": "10000", "maintMarginRatio": "0.01", - "cum": "20.0" + "cum": "40.0" } }, { "tier": 3.0, "currency": "USDT", "minNotional": 50000.0, - "maxNotional": 900000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxNotional": 80000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 40.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "900000", + "initialLeverage": "40", + "notionalCap": "80000", "notionalFloor": "50000", - "maintMarginRatio": "0.025", - "cum": "770.0" + "maintMarginRatio": "0.015", + "cum": "290.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 900000.0, - "maxNotional": 1800000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 80000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "1800000", - "notionalFloor": "900000", - "maintMarginRatio": "0.05", - "cum": "23270.0" + "initialLeverage": "25", + "notionalCap": "200000", + "notionalFloor": "80000", + "maintMarginRatio": "0.02", + "cum": "690.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 1800000.0, - "maxNotional": 4800000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 200000.0, + "maxNotional": 900000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "4800000", - "notionalFloor": "1800000", - "maintMarginRatio": "0.1", - "cum": "113270.0" + "initialLeverage": "20", + "notionalCap": "900000", + "notionalFloor": "200000", + "maintMarginRatio": "0.025", + "cum": "1690.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 4800000.0, - "maxNotional": 6000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 900000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "6000000", - "notionalFloor": "4800000", - "maintMarginRatio": "0.125", - "cum": "233270.0" + "initialLeverage": "10", + "notionalCap": "2000000", + "notionalFloor": "900000", + "maintMarginRatio": "0.05", + "cum": "24190.0" } }, { "tier": 7.0, "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "7", + "initialLeverage": "5", + "notionalCap": "5000000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.1", + "cum": "124190.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 6000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "8", + "initialLeverage": "4", + "notionalCap": "6000000", + "notionalFloor": "5000000", + "maintMarginRatio": "0.125", + "cum": "249190.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", "minNotional": 6000000.0, "maxNotional": 18000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": "7", + "bracket": "9", "initialLeverage": "2", "notionalCap": "18000000", "notionalFloor": "6000000", "maintMarginRatio": "0.25", - "cum": "983270.0" + "cum": "999190.0" } }, { - "tier": 8.0, + "tier": 10.0, "currency": "USDT", "minNotional": 18000000.0, "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "10", "initialLeverage": "1", "notionalCap": "30000000", "notionalFloor": "18000000", "maintMarginRatio": "0.5", - "cum": "5483270.0" + "cum": "5499190.0" } } ], @@ -22686,13 +23008,13 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.005, "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "notionalCap": "5000", + "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.005", "cum": "0.0" @@ -22701,39 +23023,39 @@ { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 10000.0, - "maintenanceMarginRate": 0.006, + "minNotional": 10000.0, + "maxNotional": 50000.0, + "maintenanceMarginRate": 0.01, "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "notionalCap": "10000", - "notionalFloor": "5000", - "maintMarginRatio": "0.006", - "cum": "5.0" + "notionalCap": "50000", + "notionalFloor": "10000", + "maintMarginRatio": "0.01", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.01, + "minNotional": 50000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.015, "maxLeverage": 40.0, "info": { "bracket": "3", "initialLeverage": "40", - "notionalCap": "50000", - "notionalFloor": "10000", - "maintMarginRatio": "0.01", - "cum": "45.0" + "notionalCap": "100000", + "notionalFloor": "50000", + "maintMarginRatio": "0.015", + "cum": "300.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 50000.0, + "minNotional": 100000.0, "maxNotional": 750000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, @@ -22741,73 +23063,73 @@ "bracket": "4", "initialLeverage": "25", "notionalCap": "750000", - "notionalFloor": "50000", + "notionalFloor": "100000", "maintMarginRatio": "0.02", - "cum": "545.0" + "cum": "800.0" } }, { "tier": 5.0, "currency": "USDT", "minNotional": 750000.0, - "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "5", - "initialLeverage": "10", - "notionalCap": "3000000", + "initialLeverage": "20", + "notionalCap": "1000000", "notionalFloor": "750000", - "maintMarginRatio": "0.05", - "cum": "23045.0" + "maintMarginRatio": "0.025", + "cum": "4550.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 10000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 1000000.0, + "maxNotional": 5000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "6", - "initialLeverage": "5", - "notionalCap": "10000000", - "notionalFloor": "3000000", - "maintMarginRatio": "0.1", - "cum": "173045.0" + "initialLeverage": "10", + "notionalCap": "5000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.05", + "cum": "29550.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 12000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 5000000.0, + "maxNotional": 10000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "7", - "initialLeverage": "4", - "notionalCap": "12000000", - "notionalFloor": "10000000", - "maintMarginRatio": "0.125", - "cum": "423045.0" + "initialLeverage": "5", + "notionalCap": "10000000", + "notionalFloor": "5000000", + "maintMarginRatio": "0.1", + "cum": "279550.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 12000000.0, + "minNotional": 10000000.0, "maxNotional": 20000000.0, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "8", - "initialLeverage": "3", + "initialLeverage": "4", "notionalCap": "20000000", - "notionalFloor": "12000000", - "maintMarginRatio": "0.15", - "cum": "723045.0" + "notionalFloor": "10000000", + "maintMarginRatio": "0.125", + "cum": "529550.0" } }, { @@ -22823,7 +23145,7 @@ "notionalCap": "30000000", "notionalFloor": "20000000", "maintMarginRatio": "0.25", - "cum": "2723045.0" + "cum": "3029550.0" } }, { @@ -22839,7 +23161,7 @@ "notionalCap": "50000000", "notionalFloor": "30000000", "maintMarginRatio": "0.5", - "cum": "10223045.0" + "cum": "10529550.0" } } ], @@ -23445,298 +23767,6 @@ } } ], - "MATIC/USDC:USDC": [ - { - "tier": 1.0, - "currency": "USDC", - "minNotional": 0.0, - "maxNotional": 10000.0, - "maintenanceMarginRate": 0.006, - "maxLeverage": 51.0, - "info": { - "bracket": "1", - "initialLeverage": "51", - "notionalCap": "10000", - "notionalFloor": "0", - "maintMarginRatio": "0.006", - "cum": "0.0" - } - }, - { - "tier": 2.0, - "currency": "USDC", - "minNotional": 10000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.007, - "maxLeverage": 50.0, - "info": { - "bracket": "2", - "initialLeverage": "50", - "notionalCap": "25000", - "notionalFloor": "10000", - "maintMarginRatio": "0.007", - "cum": "10.0" - } - }, - { - "tier": 3.0, - "currency": "USDC", - "minNotional": 25000.0, - "maxNotional": 600000.0, - "maintenanceMarginRate": 0.01, - "maxLeverage": 25.0, - "info": { - "bracket": "3", - "initialLeverage": "25", - "notionalCap": "600000", - "notionalFloor": "25000", - "maintMarginRatio": "0.01", - "cum": "85.0" - } - }, - { - "tier": 4.0, - "currency": "USDC", - "minNotional": 600000.0, - "maxNotional": 900000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, - "info": { - "bracket": "4", - "initialLeverage": "20", - "notionalCap": "900000", - "notionalFloor": "600000", - "maintMarginRatio": "0.025", - "cum": "9085.0" - } - }, - { - "tier": 5.0, - "currency": "USDC", - "minNotional": 900000.0, - "maxNotional": 1800000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, - "info": { - "bracket": "5", - "initialLeverage": "10", - "notionalCap": "1800000", - "notionalFloor": "900000", - "maintMarginRatio": "0.05", - "cum": "31585.0" - } - }, - { - "tier": 6.0, - "currency": "USDC", - "minNotional": 1800000.0, - "maxNotional": 4800000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, - "info": { - "bracket": "6", - "initialLeverage": "5", - "notionalCap": "4800000", - "notionalFloor": "1800000", - "maintMarginRatio": "0.1", - "cum": "121585.0" - } - }, - { - "tier": 7.0, - "currency": "USDC", - "minNotional": 4800000.0, - "maxNotional": 6000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, - "info": { - "bracket": "7", - "initialLeverage": "4", - "notionalCap": "6000000", - "notionalFloor": "4800000", - "maintMarginRatio": "0.125", - "cum": "241585.0" - } - }, - { - "tier": 8.0, - "currency": "USDC", - "minNotional": 6000000.0, - "maxNotional": 18000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, - "info": { - "bracket": "8", - "initialLeverage": "2", - "notionalCap": "18000000", - "notionalFloor": "6000000", - "maintMarginRatio": "0.25", - "cum": "991585.0" - } - }, - { - "tier": 9.0, - "currency": "USDC", - "minNotional": 18000000.0, - "maxNotional": 19000000.0, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1.0, - "info": { - "bracket": "9", - "initialLeverage": "1", - "notionalCap": "19000000", - "notionalFloor": "18000000", - "maintMarginRatio": "0.5", - "cum": "5491585.0" - } - } - ], - "MATIC/USDT:USDT": [ - { - "tier": 1.0, - "currency": "USDT", - "minNotional": 0.0, - "maxNotional": 10000.0, - "maintenanceMarginRate": 0.006, - "maxLeverage": 51.0, - "info": { - "bracket": "1", - "initialLeverage": "51", - "notionalCap": "10000", - "notionalFloor": "0", - "maintMarginRatio": "0.006", - "cum": "0.0" - } - }, - { - "tier": 2.0, - "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.007, - "maxLeverage": 50.0, - "info": { - "bracket": "2", - "initialLeverage": "50", - "notionalCap": "25000", - "notionalFloor": "10000", - "maintMarginRatio": "0.007", - "cum": "10.0" - } - }, - { - "tier": 3.0, - "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 600000.0, - "maintenanceMarginRate": 0.01, - "maxLeverage": 25.0, - "info": { - "bracket": "3", - "initialLeverage": "25", - "notionalCap": "600000", - "notionalFloor": "25000", - "maintMarginRatio": "0.01", - "cum": "85.0" - } - }, - { - "tier": 4.0, - "currency": "USDT", - "minNotional": 600000.0, - "maxNotional": 900000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, - "info": { - "bracket": "4", - "initialLeverage": "20", - "notionalCap": "900000", - "notionalFloor": "600000", - "maintMarginRatio": "0.025", - "cum": "9085.0" - } - }, - { - "tier": 5.0, - "currency": "USDT", - "minNotional": 900000.0, - "maxNotional": 1800000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, - "info": { - "bracket": "5", - "initialLeverage": "10", - "notionalCap": "1800000", - "notionalFloor": "900000", - "maintMarginRatio": "0.05", - "cum": "31585.0" - } - }, - { - "tier": 6.0, - "currency": "USDT", - "minNotional": 1800000.0, - "maxNotional": 4800000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, - "info": { - "bracket": "6", - "initialLeverage": "5", - "notionalCap": "4800000", - "notionalFloor": "1800000", - "maintMarginRatio": "0.1", - "cum": "121585.0" - } - }, - { - "tier": 7.0, - "currency": "USDT", - "minNotional": 4800000.0, - "maxNotional": 6000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, - "info": { - "bracket": "7", - "initialLeverage": "4", - "notionalCap": "6000000", - "notionalFloor": "4800000", - "maintMarginRatio": "0.125", - "cum": "241585.0" - } - }, - { - "tier": 8.0, - "currency": "USDT", - "minNotional": 6000000.0, - "maxNotional": 18000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, - "info": { - "bracket": "8", - "initialLeverage": "2", - "notionalCap": "18000000", - "notionalFloor": "6000000", - "maintMarginRatio": "0.25", - "cum": "991585.0" - } - }, - { - "tier": 9.0, - "currency": "USDT", - "minNotional": 18000000.0, - "maxNotional": 19000000.0, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1.0, - "info": { - "bracket": "9", - "initialLeverage": "1", - "notionalCap": "19000000", - "notionalFloor": "18000000", - "maintMarginRatio": "0.5", - "cum": "5491585.0" - } - } - ], "MAV/USDT:USDT": [ { "tier": 1.0, @@ -25461,6 +25491,152 @@ } } ], + "NEIROETH/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "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, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "40000", + "notionalFloor": "20000", + "maintMarginRatio": "0.025", + "cum": "175.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.05", + "cum": "1175.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "11175.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.125", + "cum": "21175.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.25", + "cum": "83675.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "333675.0" + } + } + ], "NEO/USDC:USDC": [ { "tier": 1.0, @@ -29657,6 +29833,152 @@ } } ], + "QUICK/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "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, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "40000", + "notionalFloor": "20000", + "maintMarginRatio": "0.025", + "cum": "175.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.05", + "cum": "1175.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "11175.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.125", + "cum": "21175.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.25", + "cum": "83675.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "333675.0" + } + } + ], "RAD/USDT:USDT": [ { "tier": 1.0, @@ -30020,112 +30342,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "20", - "notionalCap": "50000", - "notionalFloor": "5000", - "maintMarginRatio": "0.025", + "initialLeverage": "50", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 600000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 20000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "10", - "notionalCap": "600000", - "notionalFloor": "50000", - "maintMarginRatio": "0.05", - "cum": "1300.0" + "initialLeverage": "25", + "notionalCap": "100000", + "notionalFloor": "20000", + "maintMarginRatio": "0.02", + "cum": "150.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 600000.0, - "maxNotional": 1600000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 100000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "5", - "notionalCap": "1600000", - "notionalFloor": "600000", - "maintMarginRatio": "0.1", - "cum": "31300.0" + "initialLeverage": "20", + "notionalCap": "200000", + "notionalFloor": "100000", + "maintMarginRatio": "0.025", + "cum": "650.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 1600000.0, - "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 200000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "4", - "notionalCap": "2000000", - "notionalFloor": "1600000", - "maintMarginRatio": "0.125", - "cum": "71300.0" + "initialLeverage": "10", + "notionalCap": "1000000", + "notionalFloor": "200000", + "maintMarginRatio": "0.05", + "cum": "5650.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 6000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "2", - "notionalCap": "6000000", - "notionalFloor": "2000000", - "maintMarginRatio": "0.25", - "cum": "321300.0" + "initialLeverage": "5", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.1", + "cum": "55650.0" } }, { "tier": 7.0, "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 2500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "2500000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.125", + "cum": "105650.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 2500000.0, + "maxNotional": 6000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "6000000", + "notionalFloor": "2500000", + "maintMarginRatio": "0.25", + "cum": "418150.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", "minNotional": 6000000.0, "maxNotional": 10000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "7", + "bracket": "9", "initialLeverage": "1", "notionalCap": "10000000", "notionalFloor": "6000000", "maintMarginRatio": "0.5", - "cum": "1821300.0" + "cum": "1918150.0" } } ], @@ -31089,6 +31443,152 @@ } } ], + "RPL/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "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, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "40000", + "notionalFloor": "20000", + "maintMarginRatio": "0.025", + "cum": "175.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.05", + "cum": "1175.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "11175.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.125", + "cum": "21175.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.25", + "cum": "83675.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "333675.0" + } + } + ], "RSR/USDT:USDT": [ { "tier": 1.0, @@ -34250,13 +34750,13 @@ "tier": 2.0, "currency": "USDT", "minNotional": 5000.0, - "maxNotional": 10000.0, + "maxNotional": 16000.0, "maintenanceMarginRate": 0.015, "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "notionalCap": "10000", + "notionalCap": "16000", "notionalFloor": "5000", "maintMarginRatio": "0.015", "cum": "25.0" @@ -34265,113 +34765,113 @@ { "tier": 3.0, "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 20000.0, + "minNotional": 16000.0, + "maxNotional": 80000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "notionalCap": "20000", - "notionalFloor": "10000", + "notionalCap": "80000", + "notionalFloor": "16000", "maintMarginRatio": "0.02", - "cum": "75.0" + "cum": "105.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 40000.0, + "minNotional": 80000.0, + "maxNotional": 160000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": "4", "initialLeverage": "20", - "notionalCap": "40000", - "notionalFloor": "20000", + "notionalCap": "160000", + "notionalFloor": "80000", "maintMarginRatio": "0.025", - "cum": "175.0" + "cum": "505.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 40000.0, - "maxNotional": 200000.0, + "minNotional": 160000.0, + "maxNotional": 800000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "200000", - "notionalFloor": "40000", + "notionalCap": "800000", + "notionalFloor": "160000", "maintMarginRatio": "0.05", - "cum": "1175.0" + "cum": "4505.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 400000.0, + "minNotional": 800000.0, + "maxNotional": 1600000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "400000", - "notionalFloor": "200000", + "notionalCap": "1600000", + "notionalFloor": "800000", "maintMarginRatio": "0.1", - "cum": "11175.0" + "cum": "44505.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 400000.0, - "maxNotional": 500000.0, + "minNotional": 1600000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "500000", - "notionalFloor": "400000", + "notionalCap": "2000000", + "notionalFloor": "1600000", "maintMarginRatio": "0.125", - "cum": "21175.0" + "cum": "84505.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 1000000.0, + "minNotional": 2000000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "1000000", - "notionalFloor": "500000", + "notionalCap": "4000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.25", - "cum": "83675.0" + "cum": "334505.0" } }, { "tier": 9.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "minNotional": 4000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "2000000", - "notionalFloor": "1000000", + "notionalCap": "8000000", + "notionalFloor": "4000000", "maintMarginRatio": "0.5", - "cum": "333675.0" + "cum": "1334505.0" } } ], @@ -35113,14 +35613,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" } }, @@ -35128,112 +35628,128 @@ "tier": 2.0, "currency": "USDT", "minNotional": 5000.0, - "maxNotional": 20000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxNotional": 16000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", - "notionalCap": "20000", + "initialLeverage": "50", + "notionalCap": "16000", "notionalFloor": "5000", - "maintMarginRatio": "0.02", + "maintMarginRatio": "0.015", "cum": "25.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 30000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 16000.0, + "maxNotional": 80000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "30000", - "notionalFloor": "20000", - "maintMarginRatio": "0.025", - "cum": "125.0" + "initialLeverage": "25", + "notionalCap": "80000", + "notionalFloor": "16000", + "maintMarginRatio": "0.02", + "cum": "105.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 30000.0, - "maxNotional": 300000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 80000.0, + "maxNotional": 160000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "300000", - "notionalFloor": "30000", - "maintMarginRatio": "0.05", - "cum": "875.0" + "initialLeverage": "20", + "notionalCap": "160000", + "notionalFloor": "80000", + "maintMarginRatio": "0.025", + "cum": "505.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 300000.0, - "maxNotional": 600000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 160000.0, + "maxNotional": 800000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "600000", - "notionalFloor": "300000", - "maintMarginRatio": "0.1", - "cum": "15875.0" + "initialLeverage": "10", + "notionalCap": "800000", + "notionalFloor": "160000", + "maintMarginRatio": "0.05", + "cum": "4505.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 600000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 800000.0, + "maxNotional": 1600000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "750000", - "notionalFloor": "600000", - "maintMarginRatio": "0.125", - "cum": "30875.0" + "initialLeverage": "5", + "notionalCap": "1600000", + "notionalFloor": "800000", + "maintMarginRatio": "0.1", + "cum": "44505.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 1600000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "1500000", - "notionalFloor": "750000", - "maintMarginRatio": "0.25", - "cum": "124625.0" + "initialLeverage": "4", + "notionalCap": "2000000", + "notionalFloor": "1600000", + "maintMarginRatio": "0.125", + "cum": "84505.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "minNotional": 2000000.0, + "maxNotional": 4000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "4000000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.25", + "cum": "334505.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 4000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "3000000", - "notionalFloor": "1500000", + "notionalCap": "8000000", + "notionalFloor": "4000000", "maintMarginRatio": "0.5", - "cum": "499625.0" + "cum": "1334505.0" } } ], @@ -36412,112 +36928,128 @@ "tier": 3.0, "currency": "USDT", "minNotional": 90000.0, - "maxNotional": 645000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 20.0, + "maxNotional": 120000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 40.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "645000", + "initialLeverage": "40", + "notionalCap": "120000", "notionalFloor": "90000", - "maintMarginRatio": "0.02", - "cum": "935.0" + "maintMarginRatio": "0.015", + "cum": "485.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 645000.0, - "maxNotional": 1200000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 120000.0, + "maxNotional": 650000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "1200000", - "notionalFloor": "645000", - "maintMarginRatio": "0.05", - "cum": "20285.0" + "initialLeverage": "25", + "notionalCap": "650000", + "notionalFloor": "120000", + "maintMarginRatio": "0.02", + "cum": "1085.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 1200000.0, - "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 650000.0, + "maxNotional": 800000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "3000000", - "notionalFloor": "1200000", - "maintMarginRatio": "0.1", - "cum": "80285.0" + "initialLeverage": "20", + "notionalCap": "800000", + "notionalFloor": "650000", + "maintMarginRatio": "0.025", + "cum": "4335.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 6000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 800000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "6000000", - "notionalFloor": "3000000", - "maintMarginRatio": "0.125", - "cum": "155285.0" + "initialLeverage": "10", + "notionalCap": "3000000", + "notionalFloor": "800000", + "maintMarginRatio": "0.05", + "cum": "24335.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 6000000.0, - "maxNotional": 12000000.0, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3.0, + "minNotional": 3000000.0, + "maxNotional": 6000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "7", - "initialLeverage": "3", - "notionalCap": "12000000", - "notionalFloor": "6000000", - "maintMarginRatio": "0.15", - "cum": "305285.0" + "initialLeverage": "5", + "notionalCap": "6000000", + "notionalFloor": "3000000", + "maintMarginRatio": "0.1", + "cum": "174335.0" } }, { "tier": 8.0, "currency": "USDT", + "minNotional": 6000000.0, + "maxNotional": 12000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "8", + "initialLeverage": "4", + "notionalCap": "12000000", + "notionalFloor": "6000000", + "maintMarginRatio": "0.125", + "cum": "324335.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", "minNotional": 12000000.0, "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "2", "notionalCap": "20000000", "notionalFloor": "12000000", "maintMarginRatio": "0.25", - "cum": "1505285.0" + "cum": "1824335.0" } }, { - "tier": 9.0, + "tier": 10.0, "currency": "USDT", "minNotional": 20000000.0, "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "9", + "bracket": "10", "initialLeverage": "1", "notionalCap": "30000000", "notionalFloor": "20000000", "maintMarginRatio": "0.5", - "cum": "6505285.0" + "cum": "6824335.0" } } ], @@ -37632,13 +38164,13 @@ "tier": 2.0, "currency": "USDT", "minNotional": 5000.0, - "maxNotional": 10000.0, + "maxNotional": 16000.0, "maintenanceMarginRate": 0.015, "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "notionalCap": "10000", + "notionalCap": "16000", "notionalFloor": "5000", "maintMarginRatio": "0.015", "cum": "25.0" @@ -37647,113 +38179,113 @@ { "tier": 3.0, "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 20000.0, + "minNotional": 16000.0, + "maxNotional": 80000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "notionalCap": "20000", - "notionalFloor": "10000", + "notionalCap": "80000", + "notionalFloor": "16000", "maintMarginRatio": "0.02", - "cum": "75.0" + "cum": "105.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 40000.0, + "minNotional": 80000.0, + "maxNotional": 160000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": "4", "initialLeverage": "20", - "notionalCap": "40000", - "notionalFloor": "20000", + "notionalCap": "160000", + "notionalFloor": "80000", "maintMarginRatio": "0.025", - "cum": "175.0" + "cum": "505.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 40000.0, - "maxNotional": 200000.0, + "minNotional": 160000.0, + "maxNotional": 800000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "200000", - "notionalFloor": "40000", + "notionalCap": "800000", + "notionalFloor": "160000", "maintMarginRatio": "0.05", - "cum": "1175.0" + "cum": "4505.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 400000.0, + "minNotional": 800000.0, + "maxNotional": 1600000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "400000", - "notionalFloor": "200000", + "notionalCap": "1600000", + "notionalFloor": "800000", "maintMarginRatio": "0.1", - "cum": "11175.0" + "cum": "44505.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 400000.0, - "maxNotional": 500000.0, + "minNotional": 1600000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "500000", - "notionalFloor": "400000", + "notionalCap": "2000000", + "notionalFloor": "1600000", "maintMarginRatio": "0.125", - "cum": "21175.0" + "cum": "84505.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 1000000.0, + "minNotional": 2000000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "1000000", - "notionalFloor": "500000", + "notionalCap": "4000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.25", - "cum": "83675.0" + "cum": "334505.0" } }, { "tier": 9.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "minNotional": 4000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "2000000", - "notionalFloor": "1000000", + "notionalCap": "8000000", + "notionalFloor": "4000000", "maintMarginRatio": "0.5", - "cum": "333675.0" + "cum": "1334505.0" } } ], @@ -40932,128 +41464,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", - "notionalCap": "50000", - "notionalFloor": "5000", - "maintMarginRatio": "0.02", - "cum": "25.0" + "initialLeverage": "50", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 30000.0, + "maxNotional": 150000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "100000", - "notionalFloor": "50000", - "maintMarginRatio": "0.025", - "cum": "275.0" + "initialLeverage": "25", + "notionalCap": "150000", + "notionalFloor": "30000", + "maintMarginRatio": "0.02", + "cum": "200.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 150000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "1000000", - "notionalFloor": "100000", - "maintMarginRatio": "0.05", - "cum": "2775.0" + "initialLeverage": "20", + "notionalCap": "300000", + "notionalFloor": "150000", + "maintMarginRatio": "0.025", + "cum": "950.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 300000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "2000000", - "notionalFloor": "1000000", - "maintMarginRatio": "0.1", - "cum": "52775.0" + "initialLeverage": "10", + "notionalCap": "1500000", + "notionalFloor": "300000", + "maintMarginRatio": "0.05", + "cum": "8450.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 2500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "2500000", - "notionalFloor": "2000000", - "maintMarginRatio": "0.125", - "cum": "102775.0" + "initialLeverage": "5", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.1", + "cum": "83450.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 2500000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 3000000.0, + "maxNotional": 3750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "5000000", - "notionalFloor": "2500000", - "maintMarginRatio": "0.25", - "cum": "415275.0" + "initialLeverage": "4", + "notionalCap": "3750000", + "notionalFloor": "3000000", + "maintMarginRatio": "0.125", + "cum": "158450.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "minNotional": 3750000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "7500000", + "notionalFloor": "3750000", + "maintMarginRatio": "0.25", + "cum": "627200.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 15000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "10000000", - "notionalFloor": "5000000", + "notionalCap": "15000000", + "notionalFloor": "7500000", "maintMarginRatio": "0.5", - "cum": "1665275.0" + "cum": "2502200.0" } } ], From 6024903bdeb165afaae28d6cf3b04db704bfcac2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 13 Sep 2024 07:16:05 +0200 Subject: [PATCH 088/187] feat: conditionally apply retrier to market-reload closes #10641 --- freqtrade/exchange/exchange.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 684eaa5d8..9b35289c6 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -623,11 +623,21 @@ class Exchange: if self._exchange_ws: self._exchange_ws.reset_connections() + async def _api_reload_markets(self, reload: bool = False) -> None: + try: + return await self._api_async.load_markets(reload=reload, params={}) + except ccxt.DDoSProtection as e: + raise DDosProtection(e) from e + except (ccxt.OperationFailed, ccxt.ExchangeError) as e: + raise TemporaryError( + f"Error in reload_markets due to {e.__class__.__name__}. Message: {e}" + ) from e + except ccxt.BaseError as e: + raise TemporaryError(e) from e + def _load_async_markets(self, reload: bool = False) -> Dict[str, Any]: try: - markets = self.loop.run_until_complete( - self._api_async.load_markets(reload=reload, params={}) - ) + markets = self.loop.run_until_complete(self._api_reload_markets(reload=reload)) if isinstance(markets, Exception): raise markets @@ -652,7 +662,12 @@ class Exchange: logger.debug("Performing scheduled market reload..") try: # Reload async markets, then assign them to sync api - self._markets = self._load_async_markets(reload=True) + if force: + # Force reload of markets - retry several times + self._markets = retrier(self._load_async_markets, retries=3)(reload=True) + else: + # Normal market reload - accept temporary errors and use "old" markets + self._markets = self._load_async_markets(reload=True) self._api.set_markets(self._api_async.markets, self._api_async.currencies) # Assign options array, as it contains some temporary information from the exchange. self._api.options = self._api_async.options From 11eaa6d77cd461e0ade383a982d1a47733abd544 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 13 Sep 2024 07:16:51 +0200 Subject: [PATCH 089/187] test: Add tests for new behavior --- tests/exchange/test_exchange.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 6c9a1a9ba..212c65e54 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -567,7 +567,15 @@ def test__load_async_markets(default_conf, mocker, caplog): caplog.set_level(logging.DEBUG) exchange._api_async.load_markets = get_mock_coro(side_effect=ccxt.BaseError("deadbeef")) - with pytest.raises(ccxt.BaseError, match="deadbeef"): + with pytest.raises(TemporaryError, match="deadbeef"): + exchange._load_async_markets() + + exchange._api_async.load_markets = get_mock_coro(side_effect=ccxt.DDoSProtection("deadbeef")) + with pytest.raises(DDosProtection, match="deadbeef"): + exchange._load_async_markets() + + exchange._api_async.load_markets = get_mock_coro(side_effect=ccxt.OperationFailed("deadbeef")) + with pytest.raises(TemporaryError, match="deadbeef"): exchange._load_async_markets() From 5112736385f9b5d0cca43480c040a81469229039 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 13 Sep 2024 07:19:15 +0200 Subject: [PATCH 090/187] feat: Simplify reload_markets logic --- freqtrade/exchange/exchange.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 9b35289c6..0b73cd6e6 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -661,13 +661,10 @@ class Exchange: return None logger.debug("Performing scheduled market reload..") try: + # on initial load, we retry 3 times to ensure we get the markets + retries = 3 if force else 1 # Reload async markets, then assign them to sync api - if force: - # Force reload of markets - retry several times - self._markets = retrier(self._load_async_markets, retries=3)(reload=True) - else: - # Normal market reload - accept temporary errors and use "old" markets - self._markets = self._load_async_markets(reload=True) + self._markets = retrier(self._load_async_markets, retries=retries)(reload=True) self._api.set_markets(self._api_async.markets, self._api_async.currencies) # Assign options array, as it contains some temporary information from the exchange. self._api.options = self._api_async.options From c04cf6c5cb48a7071b395e48d0a401c1d269cac7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 13 Sep 2024 07:23:46 +0200 Subject: [PATCH 091/187] test: Improve test coverage of retry/fail logic --- freqtrade/exchange/exchange.py | 2 +- tests/exchange/test_exchange.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 0b73cd6e6..30c2aae6d 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -662,7 +662,7 @@ class Exchange: logger.debug("Performing scheduled market reload..") try: # on initial load, we retry 3 times to ensure we get the markets - retries = 3 if force else 1 + retries = 3 if force else 0 # Reload async markets, then assign them to sync api self._markets = retrier(self._load_async_markets, retries=retries)(reload=True) self._api.set_markets(self._api_async.markets, self._api_async.currencies) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 212c65e54..35cc82db1 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -638,6 +638,21 @@ def test_reload_markets(default_conf, mocker, caplog, time_machine): exchange.reload_markets() assert lam_spy.call_count == 0 + # Another reload should happen but it fails. + time_machine.move_to(start_dt + timedelta(minutes=51), tick=False) + api_mock.load_markets = get_mock_coro(side_effect=ccxt.NetworkError("LoadError")) + + exchange.reload_markets(force=False) + assert exchange.markets == updated_markets + assert lam_spy.call_count == 1 + # Tried once, failed + + lam_spy.reset_mock() + # When forceing (bot startup), it should retry 3 times. + exchange.reload_markets(force=True) + assert lam_spy.call_count == 4 + assert exchange.markets == updated_markets + def test_reload_markets_exception(default_conf, mocker, caplog): caplog.set_level(logging.DEBUG) From 9f34153c8424044cf1925d73d6827fced8a93624 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 13 Sep 2024 19:45:30 +0200 Subject: [PATCH 092/187] chore: update typing for reload function --- freqtrade/exchange/common.py | 4 ++++ freqtrade/exchange/exchange.py | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/freqtrade/exchange/common.py b/freqtrade/exchange/common.py index cac86ab3c..1bb738dcb 100644 --- a/freqtrade/exchange/common.py +++ b/freqtrade/exchange/common.py @@ -164,6 +164,10 @@ F = TypeVar("F", bound=Callable[..., Any]) def retrier(_func: F) -> F: ... +@overload +def retrier(_func: F, *, retries=API_RETRY_COUNT) -> F: ... + + @overload def retrier(*, retries=API_RETRY_COUNT) -> Callable[[F], F]: ... diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 30c2aae6d..6e5b2720b 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -623,7 +623,7 @@ class Exchange: if self._exchange_ws: self._exchange_ws.reset_connections() - async def _api_reload_markets(self, reload: bool = False) -> None: + async def _api_reload_markets(self, reload: bool = False) -> Dict[str, Any]: try: return await self._api_async.load_markets(reload=reload, params={}) except ccxt.DDoSProtection as e: @@ -662,7 +662,7 @@ class Exchange: logger.debug("Performing scheduled market reload..") try: # on initial load, we retry 3 times to ensure we get the markets - retries = 3 if force else 0 + retries: int = 3 if force else 0 # Reload async markets, then assign them to sync api self._markets = retrier(self._load_async_markets, retries=retries)(reload=True) self._api.set_markets(self._api_async.markets, self._api_async.currencies) From 0f505c6d7b3a1f3cc71a2e19b9289243656aa110 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 14 Sep 2024 10:04:28 +0200 Subject: [PATCH 093/187] Improve check to cover more potential api oddities --- freqtrade/exchange/kraken.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index 553e61ff8..d3e4dfcff 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -78,7 +78,7 @@ class Kraken(Exchange): # x["side"], x["amount"], ) for x in orders - if x["price"] is not None + if (x["price"] is not None or x["side"] != "sell") and x["remaining"] is not None ] for bal in balances: if not isinstance(balances[bal], dict): From 51bdecea530d63aa97b58616c58eaea523918098 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 14 Sep 2024 10:04:28 +0200 Subject: [PATCH 094/187] Improve check to cover more potential api oddities --- freqtrade/exchange/kraken.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index d3e4dfcff..9df9836b0 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -78,7 +78,7 @@ class Kraken(Exchange): # x["side"], x["amount"], ) for x in orders - if (x["price"] is not None or x["side"] != "sell") and x["remaining"] is not None + if x["remaining"] is not None and (x["side"] == "sell" or x["price"] is not None) ] for bal in balances: if not isinstance(balances[bal], dict): From c67a9d4e846e69335587c004c417eb936cbc560f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Sep 2024 09:29:45 +0200 Subject: [PATCH 095/187] docs: update pairlist creation docs --- docs/developer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/developer.md b/docs/developer.md index e2f7766bb..127e8e5d5 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -205,7 +205,7 @@ This is called with each iteration of the bot (only if the Pairlist Handler is a It must return the resulting pairlist (which may then be passed into the chain of Pairlist Handlers). -Validations are optional, the parent class exposes a `_verify_blacklist(pairlist)` and `_whitelist_for_active_markets(pairlist)` to do default filtering. Use this if you limit your result to a certain number of pairs - so the end-result is not shorter than expected. +Validations are optional, the parent class exposes a `verify_blacklist(pairlist)` and `_whitelist_for_active_markets(pairlist)` to do default filtering. Use this if you limit your result to a certain number of pairs - so the end-result is not shorter than expected. #### filter_pairlist @@ -219,7 +219,7 @@ The default implementation in the base class simply calls the `_validate_pair()` If overridden, it must return the resulting pairlist (which may then be passed into the next Pairlist Handler in the chain). -Validations are optional, the parent class exposes a `_verify_blacklist(pairlist)` and `_whitelist_for_active_markets(pairlist)` to do default filters. Use this if you limit your result to a certain number of pairs - so the end result is not shorter than expected. +Validations are optional, the parent class exposes a `verify_blacklist(pairlist)` and `_whitelist_for_active_markets(pairlist)` to do default filters. Use this if you limit your result to a certain number of pairs - so the end result is not shorter than expected. In `VolumePairList`, this implements different methods of sorting, does early validation so only the expected number of pairs is returned. From 12299d481064d2eff6a83536c9c24c729f0533bd Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Sep 2024 09:46:47 +0200 Subject: [PATCH 096/187] feat: staticPairlist to warn for invalid pairs Warnings about invalid pairs were "covered" by the implicit filtering of `expand_pairlist()` --- freqtrade/plugins/pairlist/StaticPairList.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/freqtrade/plugins/pairlist/StaticPairList.py b/freqtrade/plugins/pairlist/StaticPairList.py index 0591f4f19..5c7ee7e62 100644 --- a/freqtrade/plugins/pairlist/StaticPairList.py +++ b/freqtrade/plugins/pairlist/StaticPairList.py @@ -61,14 +61,13 @@ class StaticPairList(IPairList): :param tickers: Tickers (from exchange.get_tickers). May be cached. :return: List of pairs """ + wl = self.verify_whitelist( + self._config["exchange"]["pair_whitelist"], logger.info, keep_invalid=True + ) if self._allow_inactive: - return self.verify_whitelist( - self._config["exchange"]["pair_whitelist"], logger.info, keep_invalid=True - ) + return wl else: - return self._whitelist_for_active_markets( - self.verify_whitelist(self._config["exchange"]["pair_whitelist"], logger.info) - ) + return self._whitelist_for_active_markets(wl) def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]: """ From bfb14614ccf7c93df117d20f77a11824f973887b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Sep 2024 09:48:44 +0200 Subject: [PATCH 097/187] chore: enhance change with comment --- freqtrade/plugins/pairlist/StaticPairList.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/freqtrade/plugins/pairlist/StaticPairList.py b/freqtrade/plugins/pairlist/StaticPairList.py index 5c7ee7e62..6a493a5c5 100644 --- a/freqtrade/plugins/pairlist/StaticPairList.py +++ b/freqtrade/plugins/pairlist/StaticPairList.py @@ -67,6 +67,8 @@ class StaticPairList(IPairList): if self._allow_inactive: return wl else: + # Avoid implicit filtering of "verify_whitelist" to keep + # proper warnings in the log return self._whitelist_for_active_markets(wl) def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]: From 95c250ebcce62686af6dae663a5186d76158c47f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Sep 2024 10:37:28 +0200 Subject: [PATCH 098/187] chore: add explaining comment --- freqtrade/plugins/pairlist/pairlist_helpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/freqtrade/plugins/pairlist/pairlist_helpers.py b/freqtrade/plugins/pairlist/pairlist_helpers.py index 9bbd85182..cbe79c5f5 100644 --- a/freqtrade/plugins/pairlist/pairlist_helpers.py +++ b/freqtrade/plugins/pairlist/pairlist_helpers.py @@ -28,6 +28,7 @@ def expand_pairlist( except re.error as err: raise ValueError(f"Wildcard error in {pair_wc}, {err}") + # Remove wildcard pairs that didn't have a match. result = [element for element in result if re.fullmatch(r"^[A-Za-z0-9:/-]+$", element)] else: From 79020bba28e37fc1ed5b506dd60a76766522fca4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Sep 2024 10:49:26 +0200 Subject: [PATCH 099/187] chore: Remove "prohibitedIn" check it's only been used for bitrex, which does no longer exist. apparently this was forgotten when decomissioning bittrex. --- freqtrade/exchange/exchange.py | 10 ---------- tests/exchange/test_exchange.py | 24 ------------------------ 2 files changed, 34 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 6e5b2720b..0f8e321c9 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -729,16 +729,6 @@ class Exchange: # The internal info array is different for each particular market, # its contents depend on the exchange. # It can also be a string or similar ... so we need to verify that first. - elif isinstance(self.markets[pair].get("info"), dict) and self.markets[pair].get( - "info", {} - ).get("prohibitedIn", False): - # Warn users about restricted pairs in whitelist. - # We cannot determine reliably if Users are affected. - logger.warning( - f"Pair {pair} is restricted for some users on this exchange." - f"Please check if you are impacted by this restriction " - f"on the exchange and eventually remove {pair} from your whitelist." - ) if ( self._config["stake_currency"] and self.get_pair_quote_currency(pair) != self._config["stake_currency"] diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 35cc82db1..187cb011b 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -812,30 +812,6 @@ def test_validate_pairs_exception(default_conf, mocker, caplog): assert log_has("Unable to validate pairs (assuming they are correct).", caplog) -def test_validate_pairs_restricted(default_conf, mocker, caplog): - api_mock = MagicMock() - type(api_mock).load_markets = get_mock_coro( - return_value={ - "ETH/BTC": {"quote": "BTC"}, - "LTC/BTC": {"quote": "BTC"}, - "XRP/BTC": {"quote": "BTC", "info": {"prohibitedIn": ["US"]}}, - "NEO/BTC": {"quote": "BTC", "info": "TestString"}, # info can also be a string ... - } - ) - mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) - mocker.patch(f"{EXMS}.validate_timeframes") - mocker.patch(f"{EXMS}.validate_pricing") - mocker.patch(f"{EXMS}.validate_stakecurrency") - - Exchange(default_conf) - assert log_has( - "Pair XRP/BTC is restricted for some users on this exchange." - "Please check if you are impacted by this restriction " - "on the exchange and eventually remove XRP/BTC from your whitelist.", - caplog, - ) - - def test_validate_pairs_stakecompatibility(default_conf, mocker): api_mock = MagicMock() type(api_mock).load_markets = get_mock_coro( From 7ebe1b8c148699c1412570bcb4982c5f561255a8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Sep 2024 11:02:49 +0200 Subject: [PATCH 100/187] chore: remove pointless validation pairs are validated through expand_pairlist. If they're not in markets, they'll no longer be in the pairlist once this function function is hit. --- freqtrade/data/history/history_utils.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/freqtrade/data/history/history_utils.py b/freqtrade/data/history/history_utils.py index bbc9ec4d7..9deab401e 100644 --- a/freqtrade/data/history/history_utils.py +++ b/freqtrade/data/history/history_utils.py @@ -610,9 +610,6 @@ def download_data_main(config: Config) -> None: if "timeframes" not in config: config["timeframes"] = DL_DATA_TIMEFRAMES - # Manual validations of relevant settings - if not config["exchange"].get("skip_pair_validation", False): - exchange.validate_pairs(expanded_pairs) logger.info( f"About to download pairs: {expanded_pairs}, " f"intervals: {config['timeframes']} to {config['datadir']}" From 94ef4380d44ad5a0261c884c69751fd9d21e72cb Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Sep 2024 11:27:07 +0200 Subject: [PATCH 101/187] chore: remove validate_pairs from exchange class Invalid pairs were filtered out before this was called in most cases. in cases where it's not - regular pairlist-filtering provides proper warnings. --- freqtrade/exchange/exchange.py | 41 ---------------------------------- 1 file changed, 41 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 0f8e321c9..a63a8b6a0 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -104,7 +104,6 @@ from freqtrade.misc import ( file_load_json, safe_value_fallback2, ) -from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist from freqtrade.util import dt_from_ts, dt_now from freqtrade.util.datetime_helpers import dt_humanize_delta, dt_ts, format_ms_time from freqtrade.util.periodic_cache import PeriodicCache @@ -331,8 +330,6 @@ class Exchange: # Check if all pairs are available self.validate_stakecurrency(config["stake_currency"]) - if not config["exchange"].get("skip_pair_validation"): - self.validate_pairs(config["exchange"]["pair_whitelist"]) self.validate_ordertypes(config.get("order_types", {})) self.validate_order_time_in_force(config.get("order_time_in_force", {})) self.validate_trading_mode_and_margin_mode(self.trading_mode, self.margin_mode) @@ -702,44 +699,6 @@ class Exchange: f"Available currencies are: {', '.join(quote_currencies)}" ) - def validate_pairs(self, pairs: List[str]) -> None: - """ - Checks if all given pairs are tradable on the current exchange. - :param pairs: list of pairs - :raise: OperationalException if one pair is not available - :return: None - """ - - if not self.markets: - logger.warning("Unable to validate pairs (assuming they are correct).") - return - extended_pairs = expand_pairlist(pairs, list(self.markets), keep_invalid=True) - invalid_pairs = [] - for pair in extended_pairs: - # Note: ccxt has BaseCurrency/QuoteCurrency format for pairs - if self.markets and pair not in self.markets: - raise OperationalException( - f"Pair {pair} is not available on {self.name} {self.trading_mode}. " - f"Please remove {pair} from your whitelist." - ) - - # From ccxt Documentation: - # markets.info: An associative array of non-common market properties, - # including fees, rates, limits and other general market information. - # The internal info array is different for each particular market, - # its contents depend on the exchange. - # It can also be a string or similar ... so we need to verify that first. - if ( - self._config["stake_currency"] - and self.get_pair_quote_currency(pair) != self._config["stake_currency"] - ): - invalid_pairs.append(pair) - if invalid_pairs: - raise OperationalException( - f"Stake-currency '{self._config['stake_currency']}' not compatible with " - f"pair-whitelist. Please remove the following pairs: {invalid_pairs}" - ) - def get_valid_pair_combination(self, curr_1: str, curr_2: str) -> str: """ Get valid pair combination of curr_1 and curr_2 by trying both combinations. From f4881e7c6ffbd8f53d6a3971c8f861451ca0f61b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Sep 2024 11:27:23 +0200 Subject: [PATCH 102/187] tests: Adjust tests for removed validate_pairlist functionality --- tests/exchange/test_exchange.py | 135 ------------------------ tests/freqtradebot/test_freqtradebot.py | 1 - 2 files changed, 136 deletions(-) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 187cb011b..3114a3408 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -255,7 +255,6 @@ def test_init_exception(default_conf, mocker): def test_exchange_resolver(default_conf, mocker, caplog): mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=MagicMock())) mocker.patch(f"{EXMS}._load_async_markets") - mocker.patch(f"{EXMS}.validate_pairs") mocker.patch(f"{EXMS}.validate_timeframes") mocker.patch(f"{EXMS}.validate_stakecurrency") mocker.patch(f"{EXMS}.validate_pricing") @@ -555,7 +554,6 @@ def test_get_min_pair_stake_amount_real_data(mocker, default_conf) -> None: def test__load_async_markets(default_conf, mocker, caplog): mocker.patch(f"{EXMS}._init_ccxt") - mocker.patch(f"{EXMS}.validate_pairs") mocker.patch(f"{EXMS}.validate_timeframes") mocker.patch(f"{EXMS}.reload_markets") mocker.patch(f"{EXMS}.validate_stakecurrency") @@ -584,7 +582,6 @@ def test__load_markets(default_conf, mocker, caplog): api_mock = MagicMock() api_mock.load_markets = get_mock_coro(side_effect=ccxt.BaseError("SomeError")) mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) - mocker.patch(f"{EXMS}.validate_pairs") mocker.patch(f"{EXMS}.validate_timeframes") mocker.patch(f"{EXMS}.validate_stakecurrency") mocker.patch(f"{EXMS}.validate_pricing") @@ -684,7 +681,6 @@ def test_validate_stakecurrency(default_conf, stake_currency, mocker, caplog): } ) mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) - mocker.patch(f"{EXMS}.validate_pairs") mocker.patch(f"{EXMS}.validate_timeframes") mocker.patch(f"{EXMS}.validate_pricing") Exchange(default_conf) @@ -702,7 +698,6 @@ def test_validate_stakecurrency_error(default_conf, mocker, caplog): } ) mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) - mocker.patch(f"{EXMS}.validate_pairs") mocker.patch(f"{EXMS}.validate_timeframes") with pytest.raises( ConfigurationError, @@ -755,123 +750,6 @@ def test_get_pair_base_currency(default_conf, mocker, pair, expected): assert ex.get_pair_base_currency(pair) == expected -def test_validate_pairs(default_conf, mocker): - api_mock = MagicMock() - id_mock = PropertyMock(return_value="test_exchange") - type(api_mock).id = id_mock - - mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) - mocker.patch(f"{EXMS}.validate_timeframes") - mocker.patch( - f"{EXMS}._load_async_markets", - return_value={ - "ETH/BTC": {"quote": "BTC"}, - "LTC/BTC": {"quote": "BTC"}, - "XRP/BTC": {"quote": "BTC"}, - "NEO/BTC": {"quote": "BTC"}, - }, - ) - mocker.patch(f"{EXMS}.validate_stakecurrency") - mocker.patch(f"{EXMS}.validate_pricing") - # test exchange.validate_pairs directly - # No assert - but this should not fail (!) - Exchange(default_conf) - - -def test_validate_pairs_not_available(default_conf, mocker): - api_mock = MagicMock() - type(api_mock).markets = PropertyMock( - return_value={"XRP/BTC": {"inactive": True, "base": "XRP", "quote": "BTC"}} - ) - mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) - mocker.patch(f"{EXMS}.validate_timeframes") - mocker.patch(f"{EXMS}.validate_stakecurrency") - mocker.patch(f"{EXMS}._load_async_markets") - - with pytest.raises(OperationalException, match=r"not available"): - Exchange(default_conf) - - -def test_validate_pairs_exception(default_conf, mocker, caplog): - caplog.set_level(logging.INFO) - api_mock = MagicMock() - mocker.patch(f"{EXMS}.name", PropertyMock(return_value="Binance")) - - type(api_mock).markets = PropertyMock(return_value={}) - mocker.patch(f"{EXMS}._init_ccxt", api_mock) - mocker.patch(f"{EXMS}.validate_timeframes") - mocker.patch(f"{EXMS}.validate_stakecurrency") - mocker.patch(f"{EXMS}.validate_pricing") - mocker.patch(f"{EXMS}._load_async_markets") - - with pytest.raises(OperationalException, match=r"Pair ETH/BTC is not available on Binance"): - Exchange(default_conf) - - mocker.patch(f"{EXMS}.markets", PropertyMock(return_value={})) - Exchange(default_conf) - assert log_has("Unable to validate pairs (assuming they are correct).", caplog) - - -def test_validate_pairs_stakecompatibility(default_conf, mocker): - api_mock = MagicMock() - type(api_mock).load_markets = get_mock_coro( - return_value={ - "ETH/BTC": {"quote": "BTC"}, - "LTC/BTC": {"quote": "BTC"}, - "XRP/BTC": {"quote": "BTC"}, - "NEO/BTC": {"quote": "BTC"}, - "HELLO-WORLD": {"quote": "BTC"}, - } - ) - mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) - mocker.patch(f"{EXMS}.validate_timeframes") - mocker.patch(f"{EXMS}.validate_stakecurrency") - mocker.patch(f"{EXMS}.validate_pricing") - - Exchange(default_conf) - - -def test_validate_pairs_stakecompatibility_downloaddata(default_conf, mocker): - api_mock = MagicMock() - default_conf["stake_currency"] = "" - type(api_mock).load_markets = get_mock_coro( - return_value={ - "ETH/BTC": {"quote": "BTC"}, - "LTC/BTC": {"quote": "BTC"}, - "XRP/BTC": {"quote": "BTC"}, - "NEO/BTC": {"quote": "BTC"}, - "HELLO-WORLD": {"quote": "BTC"}, - } - ) - mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) - mocker.patch(f"{EXMS}.validate_timeframes") - mocker.patch(f"{EXMS}.validate_stakecurrency") - mocker.patch(f"{EXMS}.validate_pricing") - - Exchange(default_conf) - assert type(api_mock).load_markets.call_count == 1 - - -def test_validate_pairs_stakecompatibility_fail(default_conf, mocker): - default_conf["exchange"]["pair_whitelist"].append("HELLO-WORLD") - api_mock = MagicMock() - type(api_mock).load_markets = get_mock_coro( - return_value={ - "ETH/BTC": {"quote": "BTC"}, - "LTC/BTC": {"quote": "BTC"}, - "XRP/BTC": {"quote": "BTC"}, - "NEO/BTC": {"quote": "BTC"}, - "HELLO-WORLD": {"quote": "USDT"}, - } - ) - mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) - mocker.patch(f"{EXMS}.validate_timeframes") - mocker.patch(f"{EXMS}.validate_stakecurrency") - - with pytest.raises(OperationalException, match=r"Stake-currency 'BTC' not compatible with.*"): - Exchange(default_conf) - - @pytest.mark.parametrize("timeframe", [("5m"), ("1m"), ("15m"), ("1h")]) def test_validate_timeframes(default_conf, mocker, timeframe): default_conf["timeframe"] = timeframe @@ -883,7 +761,6 @@ def test_validate_timeframes(default_conf, mocker, timeframe): mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) mocker.patch(f"{EXMS}.reload_markets") - mocker.patch(f"{EXMS}.validate_pairs") mocker.patch(f"{EXMS}.validate_stakecurrency") mocker.patch(f"{EXMS}.validate_pricing") Exchange(default_conf) @@ -901,7 +778,6 @@ def test_validate_timeframes_failed(default_conf, mocker): mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) mocker.patch(f"{EXMS}.reload_markets") - mocker.patch(f"{EXMS}.validate_pairs") mocker.patch(f"{EXMS}.validate_stakecurrency") mocker.patch(f"{EXMS}.validate_pricing") with pytest.raises( @@ -931,7 +807,6 @@ def test_validate_timeframes_emulated_ohlcv_1(default_conf, mocker): mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) mocker.patch(f"{EXMS}.reload_markets") - mocker.patch(f"{EXMS}.validate_pairs") mocker.patch(f"{EXMS}.validate_stakecurrency") with pytest.raises( OperationalException, @@ -953,7 +828,6 @@ def test_validate_timeframes_emulated_ohlcvi_2(default_conf, mocker): mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) mocker.patch(f"{EXMS}.reload_markets") - mocker.patch(f"{EXMS}.validate_pairs", MagicMock()) mocker.patch(f"{EXMS}.validate_stakecurrency") with pytest.raises( OperationalException, @@ -975,7 +849,6 @@ def test_validate_timeframes_not_in_config(default_conf, mocker): mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) mocker.patch(f"{EXMS}.reload_markets") - mocker.patch(f"{EXMS}.validate_pairs") mocker.patch(f"{EXMS}.validate_stakecurrency") mocker.patch(f"{EXMS}.validate_pricing") mocker.patch(f"{EXMS}.validate_required_startup_candles") @@ -992,7 +865,6 @@ def test_validate_pricing(default_conf, mocker): mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) mocker.patch(f"{EXMS}.reload_markets") mocker.patch(f"{EXMS}.validate_trading_mode_and_margin_mode") - mocker.patch(f"{EXMS}.validate_pairs") mocker.patch(f"{EXMS}.validate_timeframes") mocker.patch(f"{EXMS}.validate_stakecurrency") mocker.patch(f"{EXMS}.name", "Binance") @@ -1027,7 +899,6 @@ def test_validate_ordertypes(default_conf, mocker): type(api_mock).has = PropertyMock(return_value={"createMarketOrder": True}) mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) mocker.patch(f"{EXMS}.reload_markets") - mocker.patch(f"{EXMS}.validate_pairs") mocker.patch(f"{EXMS}.validate_timeframes") mocker.patch(f"{EXMS}.validate_stakecurrency") mocker.patch(f"{EXMS}.validate_pricing") @@ -1086,7 +957,6 @@ def test_validate_ordertypes_stop_advanced(default_conf, mocker, exchange_name, type(api_mock).has = PropertyMock(return_value={"createMarketOrder": True}) mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) mocker.patch(f"{EXMS}.reload_markets") - mocker.patch(f"{EXMS}.validate_pairs") mocker.patch(f"{EXMS}.validate_timeframes") mocker.patch(f"{EXMS}.validate_stakecurrency") mocker.patch(f"{EXMS}.validate_pricing") @@ -1111,7 +981,6 @@ def test_validate_order_types_not_in_config(default_conf, mocker): api_mock = MagicMock() mocker.patch(f"{EXMS}._init_ccxt", MagicMock(return_value=api_mock)) mocker.patch(f"{EXMS}.reload_markets") - mocker.patch(f"{EXMS}.validate_pairs") mocker.patch(f"{EXMS}.validate_timeframes") mocker.patch(f"{EXMS}.validate_pricing") mocker.patch(f"{EXMS}.validate_stakecurrency") @@ -1127,7 +996,6 @@ def test_validate_required_startup_candles(default_conf, mocker, caplog): mocker.patch(f"{EXMS}._init_ccxt", api_mock) mocker.patch(f"{EXMS}.validate_timeframes") mocker.patch(f"{EXMS}._load_async_markets") - mocker.patch(f"{EXMS}.validate_pairs") mocker.patch(f"{EXMS}.validate_pricing") mocker.patch(f"{EXMS}.validate_stakecurrency") @@ -4161,7 +4029,6 @@ def test_merge_ft_has_dict(default_conf, mocker): EXMS, _init_ccxt=MagicMock(return_value=MagicMock()), _load_async_markets=MagicMock(), - validate_pairs=MagicMock(), validate_timeframes=MagicMock(), validate_stakecurrency=MagicMock(), validate_pricing=MagicMock(), @@ -4196,7 +4063,6 @@ def test_get_valid_pair_combination(default_conf, mocker, markets): EXMS, _init_ccxt=MagicMock(return_value=MagicMock()), _load_async_markets=MagicMock(), - validate_pairs=MagicMock(), validate_timeframes=MagicMock(), validate_pricing=MagicMock(), markets=PropertyMock(return_value=markets), @@ -4476,7 +4342,6 @@ def test_get_markets( EXMS, _init_ccxt=MagicMock(return_value=MagicMock()), _load_async_markets=MagicMock(), - validate_pairs=MagicMock(), validate_timeframes=MagicMock(), validate_pricing=MagicMock(), markets=PropertyMock(return_value=markets_static), diff --git a/tests/freqtradebot/test_freqtradebot.py b/tests/freqtradebot/test_freqtradebot.py index 7c45928a2..f0b2d5b36 100644 --- a/tests/freqtradebot/test_freqtradebot.py +++ b/tests/freqtradebot/test_freqtradebot.py @@ -2204,7 +2204,6 @@ def test_manage_open_orders_buy_exception( patch_exchange(mocker) mocker.patch.multiple( EXMS, - validate_pairs=MagicMock(), fetch_ticker=ticker_usdt, fetch_order=MagicMock(side_effect=ExchangeError), cancel_order=cancel_order_mock, From ae41ab101a0296a31729b00add3f4adb7682ce9c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Sep 2024 11:27:38 +0200 Subject: [PATCH 103/187] docs: remove skip_pair_validation - it's no longer used. --- docs/configuration.md | 1 - docs/includes/pairlists.md | 1 - 2 files changed, 2 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index aed34762b..b05b1dcaa 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -222,7 +222,6 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `exchange.ccxt_async_config` | Additional CCXT parameters passed to the async ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://docs.ccxt.com/#/README?id=overriding-exchange-properties-upon-instantiation)
**Datatype:** Dict | `exchange.enable_ws` | Enable the usage of Websockets for the exchange.
[More information](#consuming-exchange-websockets).
*Defaults to `true`.*
**Datatype:** Boolean | `exchange.markets_refresh_interval` | The interval in minutes in which markets are reloaded.
*Defaults to `60` minutes.*
**Datatype:** Positive Integer -| `exchange.skip_pair_validation` | Skip pairlist validation on startup.
*Defaults to `false`*
**Datatype:** Boolean | `exchange.skip_open_order_update` | Skips open order updates on startup should the exchange cause problems. Only relevant in live conditions.
*Defaults to `false`*
**Datatype:** Boolean | `exchange.unknown_fee_rate` | Fallback value to use when calculating trading fees. This can be useful for exchanges which have fees in non-tradable currencies. The value provided here will be multiplied with the "fee cost".
*Defaults to `None`
**Datatype:** float | `exchange.log_responses` | Log relevant exchange responses. For debug mode only - use with care.
*Defaults to `false`*
**Datatype:** Boolean diff --git a/docs/includes/pairlists.md b/docs/includes/pairlists.md index b3b69f996..804190e24 100644 --- a/docs/includes/pairlists.md +++ b/docs/includes/pairlists.md @@ -55,7 +55,6 @@ It uses configuration from `exchange.pair_whitelist` and `exchange.pair_blacklis By default, only currently enabled pairs are allowed. To skip pair validation against active markets, set `"allow_inactive": true` within the `StaticPairList` configuration. This can be useful for backtesting expired pairs (like quarterly spot-markets). -This option must be configured along with `exchange.skip_pair_validation` in the exchange configuration. When used in a "follow-up" position (e.g. after VolumePairlist), all pairs in `'pair_whitelist'` will be added to the end of the pairlist. From ad8e6e7d67cfe11e107e0fb74fc1a18683594bb6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 03:15:58 +0000 Subject: [PATCH 104/187] chore(deps-dev): bump types-requests in the types group Bumps the types group with 1 update: [types-requests](https://github.com/python/typeshed). Updates `types-requests` from 2.32.0.20240907 to 2.32.0.20240914 - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-requests dependency-type: direct:development update-type: version-update:semver-patch dependency-group: types ... Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 08fed3d02..5f9250c29 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -27,6 +27,6 @@ nbconvert==7.16.4 # mypy types types-cachetools==5.5.0.20240820 types-filelock==3.2.7 -types-requests==2.32.0.20240907 +types-requests==2.32.0.20240914 types-tabulate==0.9.0.20240106 types-python-dateutil==2.9.0.20240906 From cf3af42477f84459116dcff89f62fd68ccbbe7f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 03:16:39 +0000 Subject: [PATCH 105/187] chore(deps-dev): bump pytest from 8.3.2 to 8.3.3 in the pytest group Bumps the pytest group with 1 update: [pytest](https://github.com/pytest-dev/pytest). Updates `pytest` from 8.3.2 to 8.3.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/8.3.2...8.3.3) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-patch dependency-group: pytest ... Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 08fed3d02..0ea0a7d08 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -10,7 +10,7 @@ coveralls==4.0.1 ruff==0.6.4 mypy==1.11.2 pre-commit==3.8.0 -pytest==8.3.2 +pytest==8.3.3 pytest-asyncio==0.24.0 pytest-cov==5.0.0 pytest-mock==3.14.0 From d7a9841328b28763349211a7cd302e382da5d9b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 03:17:01 +0000 Subject: [PATCH 106/187] chore(deps): bump plotly from 5.24.0 to 5.24.1 Bumps [plotly](https://github.com/plotly/plotly.py) from 5.24.0 to 5.24.1. - [Release notes](https://github.com/plotly/plotly.py/releases) - [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md) - [Commits](https://github.com/plotly/plotly.py/compare/v5.24.0...v5.24.1) --- updated-dependencies: - dependency-name: plotly dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements-plot.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-plot.txt b/requirements-plot.txt index 987447cb2..a50d56ead 100644 --- a/requirements-plot.txt +++ b/requirements-plot.txt @@ -1,4 +1,4 @@ # Include all requirements to run the bot. -r requirements.txt -plotly==5.24.0 +plotly==5.24.1 From d37405a30715343de01cb593d1d7cb48cc32d517 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 03:17:05 +0000 Subject: [PATCH 107/187] chore(deps): bump urllib3 from 2.2.2 to 2.2.3 Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.2.2 to 2.2.3. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.2.2...2.2.3) --- updated-dependencies: - dependency-name: urllib3 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 c23e89163..3c3b1e9e8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ httpx>=0.24.1 humanize==4.10.0 cachetools==5.5.0 requests==2.32.3 -urllib3==2.2.2 +urllib3==2.2.3 jsonschema==4.23.0 TA-Lib==0.4.32 technical==1.4.4 From c3b6f4ca855eaf7d7db479c9df214bda78e59472 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 03:17:21 +0000 Subject: [PATCH 108/187] chore(deps): bump pytz from 2024.1 to 2024.2 Bumps [pytz](https://github.com/stub42/pytz) from 2024.1 to 2024.2. - [Release notes](https://github.com/stub42/pytz/releases) - [Commits](https://github.com/stub42/pytz/compare/release_2024.1...release_2024.2) --- updated-dependencies: - dependency-name: pytz dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c23e89163..d2270b9d9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -53,7 +53,7 @@ questionary==2.0.1 prompt-toolkit==3.0.36 # Extensions to datetime library python-dateutil==2.9.0.post0 -pytz==2024.1 +pytz==2024.2 #Futures schedule==1.2.2 From 11d6ec33b3955a64a535f485b17ae837c7b88469 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 03:17:39 +0000 Subject: [PATCH 109/187] chore(deps): bump scikit-learn from 1.5.1 to 1.5.2 Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 1.5.1 to 1.5.2. - [Release notes](https://github.com/scikit-learn/scikit-learn/releases) - [Commits](https://github.com/scikit-learn/scikit-learn/compare/1.5.1...1.5.2) --- updated-dependencies: - dependency-name: scikit-learn dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements-freqai.txt | 2 +- requirements-hyperopt.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-freqai.txt b/requirements-freqai.txt index 1731ac054..e71dfc129 100644 --- a/requirements-freqai.txt +++ b/requirements-freqai.txt @@ -3,7 +3,7 @@ -r requirements-plot.txt # Required for freqai -scikit-learn==1.5.1 +scikit-learn==1.5.2 joblib==1.4.2 catboost==1.2.7; 'arm' not in platform_machine # Pin Matplotlib - it's depended on by catboost diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index 0daa19128..a8e8b557c 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -4,6 +4,6 @@ # Required for hyperopt scipy==1.14.1; python_version >= "3.10" scipy==1.13.1; python_version < "3.10" -scikit-learn==1.5.1 +scikit-learn==1.5.2 ft-scikit-optimize==0.9.2 filelock==3.16.0 From e9ccc98ada48607d0945f774d247041ce9401e93 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 03:17:46 +0000 Subject: [PATCH 110/187] chore(deps): bump fastapi from 0.114.0 to 0.114.2 Bumps [fastapi](https://github.com/fastapi/fastapi) from 0.114.0 to 0.114.2. - [Release notes](https://github.com/fastapi/fastapi/releases) - [Commits](https://github.com/fastapi/fastapi/compare/0.114.0...0.114.2) --- updated-dependencies: - dependency-name: fastapi 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 c23e89163..301306006 100644 --- a/requirements.txt +++ b/requirements.txt @@ -41,7 +41,7 @@ orjson==3.10.7 sdnotify==0.3.2 # API Server -fastapi==0.114.0 +fastapi==0.114.2 pydantic==2.9.0 uvicorn==0.30.6 pyjwt==2.9.0 From db4c4b971a8ded49902575382ea00da8ea8e51a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 03:17:58 +0000 Subject: [PATCH 111/187] chore(deps): bump ccxt from 4.3.98 to 4.4.3 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.3.98 to 4.4.3. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.3.98...4.4.3) --- updated-dependencies: - dependency-name: ccxt 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 c23e89163..d56439965 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ bottleneck==1.4.0 numexpr==2.10.1 pandas-ta==0.3.14b -ccxt==4.3.98 +ccxt==4.4.3 cryptography==42.0.8; platform_machine == 'armv7l' cryptography==43.0.1; platform_machine != 'armv7l' aiohttp==3.10.5 From c73fa2b0eb5611eb33930c43de65e92a47ddc227 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 03:18:09 +0000 Subject: [PATCH 112/187] chore(deps): bump rich from 13.8.0 to 13.8.1 Bumps [rich](https://github.com/Textualize/rich) from 13.8.0 to 13.8.1. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.8.0...v13.8.1) --- updated-dependencies: - dependency-name: rich 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 c23e89163..17debc5aa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -26,7 +26,7 @@ jinja2==3.1.4 tables==3.9.1; python_version < "3.10" tables==3.10.1; python_version >= "3.10" joblib==1.4.2 -rich==13.8.0 +rich==13.8.1 pyarrow==17.0.0; platform_machine != 'armv7l' # find first, C search in arrays From a7f46500ed5778a0b30da4eee7c7a4a15e377022 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 16 Sep 2024 06:38:45 +0200 Subject: [PATCH 113/187] chore: bump types-requests in pre-commit --- .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 3fcde5a36..490f09eed 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: additional_dependencies: - types-cachetools==5.5.0.20240820 - types-filelock==3.2.7 - - types-requests==2.32.0.20240907 + - types-requests==2.32.0.20240914 - types-tabulate==0.9.0.20240106 - types-python-dateutil==2.9.0.20240906 - SQLAlchemy==2.0.34 From 09c14594117555c7cd824a7bd0d7d59a9efe0f8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 06:17:40 +0000 Subject: [PATCH 114/187] chore(deps-dev): bump ruff from 0.6.4 to 0.6.5 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.4 to 0.6.5. - [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.6.4...0.6.5) --- updated-dependencies: - dependency-name: ruff 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 0ea0a7d08..06eb01833 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,7 +7,7 @@ -r docs/requirements-docs.txt coveralls==4.0.1 -ruff==0.6.4 +ruff==0.6.5 mypy==1.11.2 pre-commit==3.8.0 pytest==8.3.3 From 65e6c737cd768895f835a05e9a67cc9495355cb1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 07:07:06 +0000 Subject: [PATCH 115/187] chore(deps): bump pydantic from 2.9.0 to 2.9.1 Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.9.0 to 2.9.1. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v2.9.0...v2.9.1) --- updated-dependencies: - dependency-name: pydantic 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 6f1e67bbb..060518391 100644 --- a/requirements.txt +++ b/requirements.txt @@ -42,7 +42,7 @@ sdnotify==0.3.2 # API Server fastapi==0.114.2 -pydantic==2.9.0 +pydantic==2.9.1 uvicorn==0.30.6 pyjwt==2.9.0 aiofiles==24.1.0 From 2fe67edab3ecb4e76936b51547f1986bf4c54003 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 16 Sep 2024 19:05:00 +0200 Subject: [PATCH 116/187] chore: update link to okx liquidation formula --- freqtrade/exchange/exchange.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index a63a8b6a0..47ff89f46 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -3594,7 +3594,7 @@ class Exchange: Wherein, "+" or "-" depends on whether the contract goes long or short: "-" for long, and "+" for short. - okex: https://www.okex.com/support/hc/en-us/articles/ + okex: https://www.okx.com/support/hc/en-us/articles/ 360053909592-VI-Introduction-to-the-isolated-mode-of-Single-Multi-currency-Portfolio-margin :param pair: Pair to calculate liquidation price for From dc26d0d7ba421cf95e00968a6cf786d5c8224474 Mon Sep 17 00:00:00 2001 From: "Jakub Werner (jakubikan)" Date: Mon, 16 Sep 2024 22:50:08 +0200 Subject: [PATCH 117/187] adding category for MarketCapPairList.py --- freqtrade/plugins/pairlist/MarketCapPairList.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/freqtrade/plugins/pairlist/MarketCapPairList.py b/freqtrade/plugins/pairlist/MarketCapPairList.py index 95f0e2805..e865a2ea5 100644 --- a/freqtrade/plugins/pairlist/MarketCapPairList.py +++ b/freqtrade/plugins/pairlist/MarketCapPairList.py @@ -35,6 +35,7 @@ class MarketCapPairList(IPairList): self._number_assets = self._pairlistconfig["number_assets"] self._max_rank = self._pairlistconfig.get("max_rank", 30) self._refresh_period = self._pairlistconfig.get("refresh_period", 86400) + self._category = self._pairlistconfig.get("category", None) self._marketcap_cache: TTLCache = TTLCache(maxsize=1, ttl=self._refresh_period) self._def_candletype = self._config["candle_type_def"] @@ -85,6 +86,12 @@ class MarketCapPairList(IPairList): "description": "Max rank of assets", "help": "Maximum rank of assets to use from the pairlist", }, + "category": { + "type": "string", + "default": None, + "description": "The Category", + "help": "Th Category of the coin e.g layer-1 default None", + }, "refresh_period": { "type": "number", "default": 86400, @@ -133,6 +140,9 @@ class MarketCapPairList(IPairList): marketcap_list = self._marketcap_cache.get("marketcap") if marketcap_list is None: + # categories = self._coingecko.get_coins_categories() + # print([cat['id'] for cat in categories]) + data = self._coingecko.get_coins_markets( vs_currency="usd", order="market_cap_desc", @@ -140,6 +150,7 @@ class MarketCapPairList(IPairList): page="1", sparkline="false", locale="en", + **({"category": self._category} if self._category else {}) ) if data: marketcap_list = [row["symbol"] for row in data] @@ -153,11 +164,11 @@ class MarketCapPairList(IPairList): if market == "futures": pair_format += f":{self._stake_currency.upper()}" - top_marketcap = marketcap_list[: self._max_rank :] + top_marketcap = marketcap_list[: self._max_rank:] for mc_pair in top_marketcap: test_pair = f"{mc_pair.upper()}/{pair_format}" - if test_pair in pairlist: + if test_pair in pairlist and test_pair not in filtered_pairlist: filtered_pairlist.append(test_pair) if len(filtered_pairlist) == self._number_assets: break From 92af01b0cba577a7877d236025786cc039c894b5 Mon Sep 17 00:00:00 2001 From: "Jakub Werner (jakubikan)" Date: Mon, 16 Sep 2024 22:51:42 +0200 Subject: [PATCH 118/187] adding category for MarketCapPairList.py --- freqtrade/plugins/pairlist/MarketCapPairList.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/freqtrade/plugins/pairlist/MarketCapPairList.py b/freqtrade/plugins/pairlist/MarketCapPairList.py index e865a2ea5..25e0c21b7 100644 --- a/freqtrade/plugins/pairlist/MarketCapPairList.py +++ b/freqtrade/plugins/pairlist/MarketCapPairList.py @@ -34,9 +34,11 @@ class MarketCapPairList(IPairList): self._stake_currency = self._config["stake_currency"] self._number_assets = self._pairlistconfig["number_assets"] self._max_rank = self._pairlistconfig.get("max_rank", 30) - self._refresh_period = self._pairlistconfig.get("refresh_period", 86400) + self._refresh_period = self._pairlistconfig.get( + "refresh_period", 86400) self._category = self._pairlistconfig.get("category", None) - self._marketcap_cache: TTLCache = TTLCache(maxsize=1, ttl=self._refresh_period) + self._marketcap_cache: TTLCache = TTLCache( + maxsize=1, ttl=self._refresh_period) self._def_candletype = self._config["candle_type_def"] _coingecko_config = self._config.get("coingecko", {}) @@ -47,7 +49,8 @@ class MarketCapPairList(IPairList): ) if self._max_rank > 250: - raise OperationalException("This filter only support marketcap rank up to 250.") + raise OperationalException( + "This filter only support marketcap rank up to 250.") @property def needstickers(self) -> bool: From 0b7cb2a1a81c575885e4352b91a40d17d8f1c944 Mon Sep 17 00:00:00 2001 From: "Jakub Werner (jakubikan)" Date: Mon, 16 Sep 2024 22:52:26 +0200 Subject: [PATCH 119/187] cleanup --- freqtrade/plugins/pairlist/MarketCapPairList.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/freqtrade/plugins/pairlist/MarketCapPairList.py b/freqtrade/plugins/pairlist/MarketCapPairList.py index 25e0c21b7..05f2e6a0a 100644 --- a/freqtrade/plugins/pairlist/MarketCapPairList.py +++ b/freqtrade/plugins/pairlist/MarketCapPairList.py @@ -143,8 +143,6 @@ class MarketCapPairList(IPairList): marketcap_list = self._marketcap_cache.get("marketcap") if marketcap_list is None: - # categories = self._coingecko.get_coins_categories() - # print([cat['id'] for cat in categories]) data = self._coingecko.get_coins_markets( vs_currency="usd", From ff9d1f272863c496d5b2d43c1af6cffbff730098 Mon Sep 17 00:00:00 2001 From: xmatthias <5024695+xmatthias@users.noreply.github.com> Date: Tue, 17 Sep 2024 03:03:39 +0000 Subject: [PATCH 120/187] chore: update pre-commit hooks --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 490f09eed..4a287743e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: - repo: https://github.com/charliermarsh/ruff-pre-commit # Ruff version. - rev: 'v0.6.4' + rev: 'v0.6.5' hooks: - id: ruff - id: ruff-format From ad295946c0ed81aaaf05e1cfd7d1548d4a1ce3d5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 17 Sep 2024 20:19:22 +0200 Subject: [PATCH 121/187] fix: use precise calculation for decrease adjustment calculations --- freqtrade/freqtradebot.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 15a3ae6ee..0bc11e0fd 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -62,7 +62,7 @@ from freqtrade.rpc.rpc_types import ( ) from freqtrade.strategy.interface import IStrategy from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper -from freqtrade.util import MeasureTime +from freqtrade.util import FtPrecise, MeasureTime from freqtrade.util.migrations.binance_mig import migrate_binance_futures_names from freqtrade.wallets import Wallets @@ -784,7 +784,14 @@ class FreqtradeBot(LoggingMixin): if stake_amount is not None and stake_amount < 0.0: # We should decrease our position amount = self.exchange.amount_to_contract_precision( - trade.pair, abs(float(stake_amount * trade.amount / trade.stake_amount)) + trade.pair, + abs( + float( + FtPrecise(stake_amount) + * FtPrecise(trade.amount) + / FtPrecise(trade.stake_amount) + ) + ), ) if amount == 0.0: From 03ee3aaf40b4bee8e2724574e559bf21a81f4d44 Mon Sep 17 00:00:00 2001 From: "Jakub Werner (jakubikan)" Date: Tue, 17 Sep 2024 22:35:00 +0200 Subject: [PATCH 122/187] adding category list if the category is not from the category --- freqtrade/plugins/pairlist/MarketCapPairList.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/freqtrade/plugins/pairlist/MarketCapPairList.py b/freqtrade/plugins/pairlist/MarketCapPairList.py index 05f2e6a0a..738081d46 100644 --- a/freqtrade/plugins/pairlist/MarketCapPairList.py +++ b/freqtrade/plugins/pairlist/MarketCapPairList.py @@ -14,7 +14,6 @@ from freqtrade.exchange.exchange_types import Tickers from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting from freqtrade.util.coin_gecko import FtCoinGeckoApi - logger = logging.getLogger(__name__) @@ -34,11 +33,9 @@ class MarketCapPairList(IPairList): self._stake_currency = self._config["stake_currency"] self._number_assets = self._pairlistconfig["number_assets"] self._max_rank = self._pairlistconfig.get("max_rank", 30) - self._refresh_period = self._pairlistconfig.get( - "refresh_period", 86400) + self._refresh_period = self._pairlistconfig.get("refresh_period", 86400) self._category = self._pairlistconfig.get("category", None) - self._marketcap_cache: TTLCache = TTLCache( - maxsize=1, ttl=self._refresh_period) + self._marketcap_cache: TTLCache = TTLCache(maxsize=1, ttl=self._refresh_period) self._def_candletype = self._config["candle_type_def"] _coingecko_config = self._config.get("coingecko", {}) @@ -48,9 +45,14 @@ class MarketCapPairList(IPairList): is_demo=_coingecko_config.get("is_demo", True), ) + categories = self._coingecko.get_coins_categories_list() + category_ids = [cat['category_id'] for cat in categories] + + if self._category not in category_ids: + raise OperationalException(f"category not in coingecko category list you can choose from {category_ids}") + if self._max_rank > 250: - raise OperationalException( - "This filter only support marketcap rank up to 250.") + raise OperationalException("This filter only support marketcap rank up to 250.") @property def needstickers(self) -> bool: From 660623181a00d5677a0414ef3360c5fe7dfd510c Mon Sep 17 00:00:00 2001 From: "Jakub Werner (jakubikan)" Date: Tue, 17 Sep 2024 22:36:21 +0200 Subject: [PATCH 123/187] adding category list if the category is not from the category --- freqtrade/plugins/pairlist/MarketCapPairList.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/freqtrade/plugins/pairlist/MarketCapPairList.py b/freqtrade/plugins/pairlist/MarketCapPairList.py index 738081d46..72ef939d5 100644 --- a/freqtrade/plugins/pairlist/MarketCapPairList.py +++ b/freqtrade/plugins/pairlist/MarketCapPairList.py @@ -14,6 +14,7 @@ from freqtrade.exchange.exchange_types import Tickers from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting from freqtrade.util.coin_gecko import FtCoinGeckoApi + logger = logging.getLogger(__name__) @@ -46,10 +47,12 @@ class MarketCapPairList(IPairList): ) categories = self._coingecko.get_coins_categories_list() - category_ids = [cat['category_id'] for cat in categories] + category_ids = [cat["category_id"] for cat in categories] if self._category not in category_ids: - raise OperationalException(f"category not in coingecko category list you can choose from {category_ids}") + raise OperationalException( + f"category not in coingecko category list you can choose from {category_ids}" + ) if self._max_rank > 250: raise OperationalException("This filter only support marketcap rank up to 250.") @@ -145,7 +148,6 @@ class MarketCapPairList(IPairList): marketcap_list = self._marketcap_cache.get("marketcap") if marketcap_list is None: - data = self._coingecko.get_coins_markets( vs_currency="usd", order="market_cap_desc", @@ -153,7 +155,7 @@ class MarketCapPairList(IPairList): page="1", sparkline="false", locale="en", - **({"category": self._category} if self._category else {}) + **({"category": self._category} if self._category else {}), ) if data: marketcap_list = [row["symbol"] for row in data] @@ -167,7 +169,7 @@ class MarketCapPairList(IPairList): if market == "futures": pair_format += f":{self._stake_currency.upper()}" - top_marketcap = marketcap_list[: self._max_rank:] + top_marketcap = marketcap_list[: self._max_rank :] for mc_pair in top_marketcap: test_pair = f"{mc_pair.upper()}/{pair_format}" From 50f07e7b1116fa13b9c9983487e2040c695c266e Mon Sep 17 00:00:00 2001 From: "Jakub Werner (jakubikan)" Date: Tue, 17 Sep 2024 23:03:51 +0200 Subject: [PATCH 124/187] only doing this if the category is set --- freqtrade/plugins/pairlist/MarketCapPairList.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/freqtrade/plugins/pairlist/MarketCapPairList.py b/freqtrade/plugins/pairlist/MarketCapPairList.py index 72ef939d5..96edf81b5 100644 --- a/freqtrade/plugins/pairlist/MarketCapPairList.py +++ b/freqtrade/plugins/pairlist/MarketCapPairList.py @@ -46,13 +46,14 @@ class MarketCapPairList(IPairList): is_demo=_coingecko_config.get("is_demo", True), ) - categories = self._coingecko.get_coins_categories_list() - category_ids = [cat["category_id"] for cat in categories] + if self._category: + categories = self._coingecko.get_coins_categories_list() + category_ids = [cat["category_id"] for cat in categories] - if self._category not in category_ids: - raise OperationalException( - f"category not in coingecko category list you can choose from {category_ids}" - ) + if self._category not in category_ids: + raise OperationalException( + f"category not in coingecko category list you can choose from {category_ids}" + ) if self._max_rank > 250: raise OperationalException("This filter only support marketcap rank up to 250.") @@ -173,7 +174,7 @@ class MarketCapPairList(IPairList): for mc_pair in top_marketcap: test_pair = f"{mc_pair.upper()}/{pair_format}" - if test_pair in pairlist and test_pair not in filtered_pairlist: + if test_pair in pairlist: filtered_pairlist.append(test_pair) if len(filtered_pairlist) == self._number_assets: break From f50a633f8759437e5fc9e55b693cbb7a258cf326 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Sep 2024 08:10:45 +0200 Subject: [PATCH 125/187] docs: order table formatting --- docs/trade-object.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/trade-object.md b/docs/trade-object.md index ec9cf14ec..4962d6b30 100644 --- a/docs/trade-object.md +++ b/docs/trade-object.md @@ -130,20 +130,20 @@ Most properties here can be None as they are dependent on the exchange response. | Attribute | DataType | Description | |------------|-------------|-------------| -`trade` | Trade | Trade object this order is attached to -`ft_pair` | string | Pair this order is for -`ft_is_open` | boolean | is the order filled? -`order_type` | string | Order type as defined on the exchange - usually market, limit or stoploss -`status` | string | Status as defined by ccxt. Usually open, closed, expired or canceled -`side` | string | Buy or Sell -`price` | float | Price the order was placed at -`average` | float | Average price the order filled at -`amount` | float | Amount in base currency -`filled` | float | Filled amount (in base currency) -`remaining` | float | Remaining amount -`cost` | float | Cost of the order - usually average * filled (*Exchange dependent on futures, may contain the cost with or without leverage and may be in contracts.*) -`stake_amount` | float | Stake amount used for this order. *Added in 2023.7.* -`order_date` | datetime | Order creation date **use `order_date_utc` instead** -`order_date_utc` | datetime | Order creation date (in UTC) -`order_fill_date` | datetime | Order fill date **use `order_fill_utc` instead** -`order_fill_date_utc` | datetime | Order fill date +| `trade` | Trade | Trade object this order is attached to | +| `ft_pair` | string | Pair this order is for | +| `ft_is_open` | boolean | is the order filled? | +| `order_type` | string | Order type as defined on the exchange - usually market, limit or stoploss | +| `status` | string | Status as defined by ccxt. Usually open, closed, expired or canceled | +| `side` | string | Buy or Sell | +| `price` | float | Price the order was placed at | +| `average` | float | Average price the order filled at | +| `amount` | float | Amount in base currency | +| `filled` | float | Filled amount (in base currency) | +| `remaining` | float | Remaining amount | +| `cost` | float | Cost of the order - usually average * filled (*Exchange dependent on futures, may contain the cost with or without leverage and may be in contracts.*) | +| `stake_amount` | float | Stake amount used for this order. *Added in 2023.7.* | +| `order_date` | datetime | Order creation date **use `order_date_utc` instead** | +| `order_date_utc` | datetime | Order creation date (in UTC) | +| `order_fill_date` | datetime | Order fill date **use `order_fill_utc` instead** | +| `order_fill_date_utc` | datetime | Order fill date | From 75616923520fbb8b7b731a1622050431e7d60b4f Mon Sep 17 00:00:00 2001 From: xmatthias <5024695+xmatthias@users.noreply.github.com> Date: Thu, 19 Sep 2024 03:15:32 +0000 Subject: [PATCH 126/187] chore: update pre-commit hooks --- .../exchange/binance_leverage_tiers.json | 2782 +++++++++++------ 1 file changed, 1900 insertions(+), 882 deletions(-) diff --git a/freqtrade/exchange/binance_leverage_tiers.json b/freqtrade/exchange/binance_leverage_tiers.json index bcf497efe..8b0882d64 100644 --- a/freqtrade/exchange/binance_leverage_tiers.json +++ b/freqtrade/exchange/binance_leverage_tiers.json @@ -1591,6 +1591,152 @@ } } ], + "1MBABYDOGE/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "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, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "40000", + "notionalFloor": "20000", + "maintMarginRatio": "0.025", + "cum": "175.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.05", + "cum": "1175.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "11175.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.125", + "cum": "21175.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.25", + "cum": "83675.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "333675.0" + } + } + ], "AAVE/USDT:USDT": [ { "tier": 1.0, @@ -3676,13 +3822,13 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 50.0, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "25000", "notionalFloor": "0", "maintMarginRatio": "0.0065", "cum": "0.0" @@ -3691,129 +3837,145 @@ { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.0075, - "maxLeverage": 40.0, + "minNotional": 25000.0, + "maxNotional": 50000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "40", - "notionalCap": "25000", - "notionalFloor": "5000", - "maintMarginRatio": "0.0075", - "cum": "5.0" + "initialLeverage": "50", + "notionalCap": "50000", + "notionalFloor": "25000", + "maintMarginRatio": "0.01", + "cum": "87.5" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.01, - "maxLeverage": 25.0, + "minNotional": 50000.0, + "maxNotional": 80000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 40.0, "info": { "bracket": "3", - "initialLeverage": "25", - "notionalCap": "50000", - "notionalFloor": "25000", - "maintMarginRatio": "0.01", - "cum": "67.5" + "initialLeverage": "40", + "notionalCap": "80000", + "notionalFloor": "50000", + "maintMarginRatio": "0.015", + "cum": "337.5" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 50000.0, + "minNotional": 80000.0, "maxNotional": 150000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "25", "notionalCap": "150000", - "notionalFloor": "50000", - "maintMarginRatio": "0.025", - "cum": "817.5" + "notionalFloor": "80000", + "maintMarginRatio": "0.02", + "cum": "737.5" } }, { "tier": 5.0, "currency": "USDT", "minNotional": 150000.0, - "maxNotional": 250000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "5", - "initialLeverage": "10", - "notionalCap": "250000", + "initialLeverage": "20", + "notionalCap": "300000", "notionalFloor": "150000", - "maintMarginRatio": "0.05", - "cum": "4567.5" + "maintMarginRatio": "0.025", + "cum": "1487.5" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 250000.0, - "maxNotional": 500000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 300000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "6", - "initialLeverage": "5", - "notionalCap": "500000", - "notionalFloor": "250000", - "maintMarginRatio": "0.1", - "cum": "17067.5" + "initialLeverage": "10", + "notionalCap": "1500000", + "notionalFloor": "300000", + "maintMarginRatio": "0.05", + "cum": "8987.5" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "7", - "initialLeverage": "4", - "notionalCap": "1000000", - "notionalFloor": "500000", - "maintMarginRatio": "0.125", - "cum": "29567.5" + "initialLeverage": "5", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.1", + "cum": "83987.5" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 3000000.0, + "maxNotional": 3750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "8", - "initialLeverage": "2", - "notionalCap": "5000000", - "notionalFloor": "1000000", - "maintMarginRatio": "0.25", - "cum": "154567.5" + "initialLeverage": "4", + "notionalCap": "3750000", + "notionalFloor": "3000000", + "maintMarginRatio": "0.125", + "cum": "158987.5" } }, { "tier": 9.0, "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "minNotional": 3750000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "9", + "initialLeverage": "2", + "notionalCap": "7500000", + "notionalFloor": "3750000", + "maintMarginRatio": "0.25", + "cum": "627737.5" + } + }, + { + "tier": 10.0, + "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 15000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "9", + "bracket": "10", "initialLeverage": "1", - "notionalCap": "10000000", - "notionalFloor": "5000000", + "notionalCap": "15000000", + "notionalFloor": "7500000", "maintMarginRatio": "0.5", - "cum": "1404567.5" + "cum": "2502737.5" } } ], @@ -7414,112 +7576,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "20", - "notionalCap": "25000", - "notionalFloor": "5000", - "maintMarginRatio": "0.025", + "initialLeverage": "50", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 150000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 20000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "10", - "notionalCap": "150000", - "notionalFloor": "25000", - "maintMarginRatio": "0.05", - "cum": "675.0" + "initialLeverage": "25", + "notionalCap": "100000", + "notionalFloor": "20000", + "maintMarginRatio": "0.02", + "cum": "150.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 150000.0, - "maxNotional": 300000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 100000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "5", - "notionalCap": "300000", - "notionalFloor": "150000", - "maintMarginRatio": "0.1", - "cum": "8175.0" + "initialLeverage": "20", + "notionalCap": "200000", + "notionalFloor": "100000", + "maintMarginRatio": "0.025", + "cum": "650.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 300000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 200000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "4", - "notionalCap": "750000", - "notionalFloor": "300000", - "maintMarginRatio": "0.125", - "cum": "15675.0" + "initialLeverage": "10", + "notionalCap": "1000000", + "notionalFloor": "200000", + "maintMarginRatio": "0.05", + "cum": "5650.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "2", - "notionalCap": "1500000", - "notionalFloor": "750000", - "maintMarginRatio": "0.25", - "cum": "109425.0" + "initialLeverage": "5", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.1", + "cum": "55650.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "minNotional": 2000000.0, + "maxNotional": 2500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "2500000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.125", + "cum": "105650.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 2500000.0, + "maxNotional": 5000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "5000000", + "notionalFloor": "2500000", + "maintMarginRatio": "0.25", + "cum": "418150.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "7", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "3000000", - "notionalFloor": "1500000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.5", - "cum": "484425.0" + "cum": "1668150.0" } } ], @@ -13204,112 +13398,128 @@ "tier": 3.0, "currency": "USDT", "minNotional": 50000.0, - "maxNotional": 500000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 40.0, "info": { "bracket": "3", - "initialLeverage": "25", - "notionalCap": "500000", + "initialLeverage": "40", + "notionalCap": "100000", "notionalFloor": "50000", - "maintMarginRatio": "0.02", - "cum": "535.0" + "maintMarginRatio": "0.015", + "cum": "285.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 100000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "2000000", - "notionalFloor": "500000", - "maintMarginRatio": "0.05", - "cum": "15535.0" + "initialLeverage": "25", + "notionalCap": "500000", + "notionalFloor": "100000", + "maintMarginRatio": "0.02", + "cum": "785.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 500000.0, + "maxNotional": 800000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "5000000", - "notionalFloor": "2000000", - "maintMarginRatio": "0.1", - "cum": "115535.0" + "initialLeverage": "20", + "notionalCap": "800000", + "notionalFloor": "500000", + "maintMarginRatio": "0.025", + "cum": "3285.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 7000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 800000.0, + "maxNotional": 4000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "7000000", - "notionalFloor": "5000000", - "maintMarginRatio": "0.125", - "cum": "240535.0" + "initialLeverage": "10", + "notionalCap": "4000000", + "notionalFloor": "800000", + "maintMarginRatio": "0.05", + "cum": "23285.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 7000000.0, - "maxNotional": 10000000.0, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3.0, + "minNotional": 4000000.0, + "maxNotional": 8000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "7", - "initialLeverage": "3", - "notionalCap": "10000000", - "notionalFloor": "7000000", - "maintMarginRatio": "0.15", - "cum": "415535.0" + "initialLeverage": "5", + "notionalCap": "8000000", + "notionalFloor": "4000000", + "maintMarginRatio": "0.1", + "cum": "223285.0" } }, { "tier": 8.0, "currency": "USDT", + "minNotional": 8000000.0, + "maxNotional": 10000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "8", + "initialLeverage": "4", + "notionalCap": "10000000", + "notionalFloor": "8000000", + "maintMarginRatio": "0.125", + "cum": "423285.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", "minNotional": 10000000.0, "maxNotional": 30000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "2", "notionalCap": "30000000", "notionalFloor": "10000000", "maintMarginRatio": "0.25", - "cum": "1415535.0" + "cum": "1673285.0" } }, { - "tier": 9.0, + "tier": 10.0, "currency": "USDT", "minNotional": 30000000.0, "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "9", + "bracket": "10", "initialLeverage": "1", "notionalCap": "50000000", "notionalFloor": "30000000", "maintMarginRatio": "0.5", - "cum": "8915535.0" + "cum": "9173285.0" } } ], @@ -14424,13 +14634,13 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.005, "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "notionalCap": "5000", + "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.005", "cum": "0.0" @@ -14439,39 +14649,39 @@ { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 10000.0, - "maintenanceMarginRate": 0.006, + "minNotional": 10000.0, + "maxNotional": 50000.0, + "maintenanceMarginRate": 0.01, "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "notionalCap": "10000", - "notionalFloor": "5000", - "maintMarginRatio": "0.006", - "cum": "5.0" + "notionalCap": "50000", + "notionalFloor": "10000", + "maintMarginRatio": "0.01", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.01, + "minNotional": 50000.0, + "maxNotional": 80000.0, + "maintenanceMarginRate": 0.015, "maxLeverage": 40.0, "info": { "bracket": "3", "initialLeverage": "40", - "notionalCap": "50000", - "notionalFloor": "10000", - "maintMarginRatio": "0.01", - "cum": "45.0" + "notionalCap": "80000", + "notionalFloor": "50000", + "maintMarginRatio": "0.015", + "cum": "300.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 50000.0, + "minNotional": 80000.0, "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, @@ -14479,73 +14689,73 @@ "bracket": "4", "initialLeverage": "25", "notionalCap": "250000", - "notionalFloor": "50000", + "notionalFloor": "80000", "maintMarginRatio": "0.02", - "cum": "545.0" + "cum": "700.0" } }, { "tier": 5.0, "currency": "USDT", "minNotional": 250000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "5", - "initialLeverage": "10", - "notionalCap": "1000000", + "initialLeverage": "20", + "notionalCap": "500000", "notionalFloor": "250000", - "maintMarginRatio": "0.05", - "cum": "8045.0" + "maintMarginRatio": "0.025", + "cum": "1950.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 500000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "6", - "initialLeverage": "5", - "notionalCap": "5000000", - "notionalFloor": "1000000", - "maintMarginRatio": "0.1", - "cum": "58045.0" + "initialLeverage": "10", + "notionalCap": "2000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.05", + "cum": "14450.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 10000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 2000000.0, + "maxNotional": 5000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "7", - "initialLeverage": "4", - "notionalCap": "10000000", - "notionalFloor": "5000000", - "maintMarginRatio": "0.125", - "cum": "183045.0" + "initialLeverage": "5", + "notionalCap": "5000000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.1", + "cum": "114450.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 10000000.0, + "minNotional": 5000000.0, "maxNotional": 20000000.0, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "8", - "initialLeverage": "3", + "initialLeverage": "4", "notionalCap": "20000000", - "notionalFloor": "10000000", - "maintMarginRatio": "0.15", - "cum": "433045.0" + "notionalFloor": "5000000", + "maintMarginRatio": "0.125", + "cum": "239450.0" } }, { @@ -14561,7 +14771,7 @@ "notionalCap": "30000000", "notionalFloor": "20000000", "maintMarginRatio": "0.25", - "cum": "2433045.0" + "cum": "2739450.0" } }, { @@ -14577,7 +14787,7 @@ "notionalCap": "50000000", "notionalFloor": "30000000", "maintMarginRatio": "0.5", - "cum": "9933045.0" + "cum": "10239450.0" } } ], @@ -14586,13 +14796,13 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.005, "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "notionalCap": "5000", + "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.005", "cum": "0.0" @@ -14601,39 +14811,39 @@ { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 10000.0, - "maintenanceMarginRate": 0.006, + "minNotional": 10000.0, + "maxNotional": 50000.0, + "maintenanceMarginRate": 0.01, "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "notionalCap": "10000", - "notionalFloor": "5000", - "maintMarginRatio": "0.006", - "cum": "5.0" + "notionalCap": "50000", + "notionalFloor": "10000", + "maintMarginRatio": "0.01", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.01, + "minNotional": 50000.0, + "maxNotional": 80000.0, + "maintenanceMarginRate": 0.015, "maxLeverage": 40.0, "info": { "bracket": "3", "initialLeverage": "40", - "notionalCap": "50000", - "notionalFloor": "10000", - "maintMarginRatio": "0.01", - "cum": "45.0" + "notionalCap": "80000", + "notionalFloor": "50000", + "maintMarginRatio": "0.015", + "cum": "300.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 50000.0, + "minNotional": 80000.0, "maxNotional": 400000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, @@ -14641,73 +14851,73 @@ "bracket": "4", "initialLeverage": "25", "notionalCap": "400000", - "notionalFloor": "50000", + "notionalFloor": "80000", "maintMarginRatio": "0.02", - "cum": "545.0" + "cum": "700.0" } }, { "tier": 5.0, "currency": "USDT", "minNotional": 400000.0, - "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxNotional": 800000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "5", - "initialLeverage": "10", - "notionalCap": "2000000", + "initialLeverage": "20", + "notionalCap": "800000", "notionalFloor": "400000", - "maintMarginRatio": "0.05", - "cum": "12545.0" + "maintMarginRatio": "0.025", + "cum": "2700.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 8000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 800000.0, + "maxNotional": 4000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "6", - "initialLeverage": "5", - "notionalCap": "8000000", - "notionalFloor": "2000000", - "maintMarginRatio": "0.1", - "cum": "112545.0" + "initialLeverage": "10", + "notionalCap": "4000000", + "notionalFloor": "800000", + "maintMarginRatio": "0.05", + "cum": "22700.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 8000000.0, - "maxNotional": 10000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 4000000.0, + "maxNotional": 8000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "7", - "initialLeverage": "4", - "notionalCap": "10000000", - "notionalFloor": "8000000", - "maintMarginRatio": "0.125", - "cum": "312545.0" + "initialLeverage": "5", + "notionalCap": "8000000", + "notionalFloor": "4000000", + "maintMarginRatio": "0.1", + "cum": "222700.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 10000000.0, + "minNotional": 8000000.0, "maxNotional": 20000000.0, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "8", - "initialLeverage": "3", + "initialLeverage": "4", "notionalCap": "20000000", - "notionalFloor": "10000000", - "maintMarginRatio": "0.15", - "cum": "562545.0" + "notionalFloor": "8000000", + "maintMarginRatio": "0.125", + "cum": "422700.0" } }, { @@ -14723,7 +14933,7 @@ "notionalCap": "30000000", "notionalFloor": "20000000", "maintMarginRatio": "0.25", - "cum": "2562545.0" + "cum": "2922700.0" } }, { @@ -14739,7 +14949,7 @@ "notionalCap": "50000000", "notionalFloor": "30000000", "maintMarginRatio": "0.5", - "cum": "10062545.0" + "cum": "10422700.0" } } ], @@ -16226,10 +16436,10 @@ "minNotional": 50000.0, "maxNotional": 250000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 40.0, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "40", + "initialLeverage": "50", "notionalCap": "250000", "notionalFloor": "50000", "maintMarginRatio": "0.01", @@ -16240,112 +16450,128 @@ "tier": 3.0, "currency": "USDT", "minNotional": 250000.0, - "maxNotional": 600000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 20.0, + "maxNotional": 350000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 40.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "600000", + "initialLeverage": "40", + "notionalCap": "350000", "notionalFloor": "250000", - "maintMarginRatio": "0.02", - "cum": "2700.0" + "maintMarginRatio": "0.015", + "cum": "1450.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 600000.0, - "maxNotional": 1200000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 350000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "1200000", - "notionalFloor": "600000", - "maintMarginRatio": "0.05", - "cum": "20700.0" + "initialLeverage": "25", + "notionalCap": "600000", + "notionalFloor": "350000", + "maintMarginRatio": "0.02", + "cum": "3200.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 1200000.0, - "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 600000.0, + "maxNotional": 800000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "3000000", - "notionalFloor": "1200000", - "maintMarginRatio": "0.1", - "cum": "80700.0" + "initialLeverage": "20", + "notionalCap": "800000", + "notionalFloor": "600000", + "maintMarginRatio": "0.025", + "cum": "6200.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 6000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 800000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "6000000", - "notionalFloor": "3000000", - "maintMarginRatio": "0.125", - "cum": "155700.0" + "initialLeverage": "10", + "notionalCap": "3000000", + "notionalFloor": "800000", + "maintMarginRatio": "0.05", + "cum": "26200.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 6000000.0, - "maxNotional": 10000000.0, - "maintenanceMarginRate": 0.165, - "maxLeverage": 3.0, + "minNotional": 3000000.0, + "maxNotional": 6000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "7", - "initialLeverage": "3", - "notionalCap": "10000000", - "notionalFloor": "6000000", - "maintMarginRatio": "0.165", - "cum": "395700.0" + "initialLeverage": "5", + "notionalCap": "6000000", + "notionalFloor": "3000000", + "maintMarginRatio": "0.1", + "cum": "176200.0" } }, { "tier": 8.0, "currency": "USDT", + "minNotional": 6000000.0, + "maxNotional": 10000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "8", + "initialLeverage": "4", + "notionalCap": "10000000", + "notionalFloor": "6000000", + "maintMarginRatio": "0.125", + "cum": "326200.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", "minNotional": 10000000.0, "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "2", "notionalCap": "20000000", "notionalFloor": "10000000", "maintMarginRatio": "0.25", - "cum": "1245700.0" + "cum": "1576200.0" } }, { - "tier": 9.0, + "tier": 10.0, "currency": "USDT", "minNotional": 20000000.0, "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "9", + "bracket": "10", "initialLeverage": "1", "notionalCap": "30000000", "notionalFloor": "20000000", "maintMarginRatio": "0.5", - "cum": "6245700.0" + "cum": "6576200.0" } } ], @@ -19528,112 +19754,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "25", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.02", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 10000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "20", - "notionalCap": "50000", - "notionalFloor": "5000", - "maintMarginRatio": "0.025", - "cum": "25.0" + "initialLeverage": "50", + "notionalCap": "40000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 1600000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "10", - "notionalCap": "1600000", - "notionalFloor": "50000", - "maintMarginRatio": "0.05", - "cum": "1275.0" + "initialLeverage": "25", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.02", + "cum": "250.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 1600000.0, - "maxNotional": 3600000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "5", - "notionalCap": "3600000", - "notionalFloor": "1600000", - "maintMarginRatio": "0.1", - "cum": "81275.0" + "initialLeverage": "20", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.025", + "cum": "1250.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 3600000.0, - "maxNotional": 4000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 400000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "4", - "notionalCap": "4000000", - "notionalFloor": "3600000", - "maintMarginRatio": "0.125", - "cum": "171275.0" + "initialLeverage": "10", + "notionalCap": "2000000", + "notionalFloor": "400000", + "maintMarginRatio": "0.05", + "cum": "11250.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 4000000.0, - "maxNotional": 12000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 2000000.0, + "maxNotional": 4000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "2", - "notionalCap": "12000000", - "notionalFloor": "4000000", - "maintMarginRatio": "0.25", - "cum": "671275.0" + "initialLeverage": "5", + "notionalCap": "4000000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.1", + "cum": "111250.0" } }, { "tier": 7.0, "currency": "USDT", + "minNotional": 4000000.0, + "maxNotional": 5000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "5000000", + "notionalFloor": "4000000", + "maintMarginRatio": "0.125", + "cum": "211250.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 12000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "12000000", + "notionalFloor": "5000000", + "maintMarginRatio": "0.25", + "cum": "836250.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", "minNotional": 12000000.0, "maxNotional": 20000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "7", + "bracket": "9", "initialLeverage": "1", "notionalCap": "20000000", "notionalFloor": "12000000", "maintMarginRatio": "0.5", - "cum": "3671275.0" + "cum": "3836250.0" } } ], @@ -19642,128 +19900,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", - "notionalCap": "50000", - "notionalFloor": "5000", - "maintMarginRatio": "0.02", - "cum": "25.0" + "initialLeverage": "50", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 100000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 30000.0, + "maxNotional": 150000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "100000", - "notionalFloor": "50000", - "maintMarginRatio": "0.025", - "cum": "275.0" + "initialLeverage": "25", + "notionalCap": "150000", + "notionalFloor": "30000", + "maintMarginRatio": "0.02", + "cum": "200.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 150000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "1000000", - "notionalFloor": "100000", - "maintMarginRatio": "0.05", - "cum": "2775.0" + "initialLeverage": "20", + "notionalCap": "300000", + "notionalFloor": "150000", + "maintMarginRatio": "0.025", + "cum": "950.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 300000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "2000000", - "notionalFloor": "1000000", - "maintMarginRatio": "0.1", - "cum": "52775.0" + "initialLeverage": "10", + "notionalCap": "1500000", + "notionalFloor": "300000", + "maintMarginRatio": "0.05", + "cum": "8450.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 2500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "2500000", - "notionalFloor": "2000000", - "maintMarginRatio": "0.125", - "cum": "102775.0" + "initialLeverage": "5", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.1", + "cum": "83450.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 2500000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 3000000.0, + "maxNotional": 3750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "5000000", - "notionalFloor": "2500000", - "maintMarginRatio": "0.25", - "cum": "415275.0" + "initialLeverage": "4", + "notionalCap": "3750000", + "notionalFloor": "3000000", + "maintMarginRatio": "0.125", + "cum": "158450.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "minNotional": 3750000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "7500000", + "notionalFloor": "3750000", + "maintMarginRatio": "0.25", + "cum": "627200.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 15000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "10000000", - "notionalFloor": "5000000", + "notionalCap": "15000000", + "notionalFloor": "7500000", "maintMarginRatio": "0.5", - "cum": "1665275.0" + "cum": "2502200.0" } } ], @@ -20889,6 +21163,152 @@ } } ], + "KDA/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "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, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "40000", + "notionalFloor": "20000", + "maintMarginRatio": "0.025", + "cum": "175.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.05", + "cum": "1175.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "11175.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.125", + "cum": "21175.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.25", + "cum": "83675.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "333675.0" + } + } + ], "KEY/USDT:USDT": [ { "tier": 1.0, @@ -21902,13 +22322,13 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.005, "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "notionalCap": "5000", + "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.005", "cum": "0.0" @@ -21917,113 +22337,113 @@ { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 10000.0, - "maintenanceMarginRate": 0.006, + "minNotional": 10000.0, + "maxNotional": 50000.0, + "maintenanceMarginRate": 0.01, "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "notionalCap": "10000", - "notionalFloor": "5000", - "maintMarginRatio": "0.006", - "cum": "5.0" + "notionalCap": "50000", + "notionalFloor": "10000", + "maintMarginRatio": "0.01", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.01, + "minNotional": 50000.0, + "maxNotional": 80000.0, + "maintenanceMarginRate": 0.015, "maxLeverage": 40.0, "info": { "bracket": "3", "initialLeverage": "40", - "notionalCap": "50000", - "notionalFloor": "10000", - "maintMarginRatio": "0.01", - "cum": "45.0" + "notionalCap": "80000", + "notionalFloor": "50000", + "maintMarginRatio": "0.015", + "cum": "300.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 250000.0, + "minNotional": 80000.0, + "maxNotional": 400000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": "4", "initialLeverage": "25", - "notionalCap": "250000", - "notionalFloor": "50000", + "notionalCap": "400000", + "notionalFloor": "80000", "maintMarginRatio": "0.02", - "cum": "545.0" + "cum": "700.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 250000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 400000.0, + "maxNotional": 800000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "5", - "initialLeverage": "10", - "notionalCap": "1000000", - "notionalFloor": "250000", - "maintMarginRatio": "0.05", - "cum": "8045.0" + "initialLeverage": "20", + "notionalCap": "800000", + "notionalFloor": "400000", + "maintMarginRatio": "0.025", + "cum": "2700.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 800000.0, + "maxNotional": 4000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "6", - "initialLeverage": "5", - "notionalCap": "5000000", - "notionalFloor": "1000000", - "maintMarginRatio": "0.1", - "cum": "58045.0" + "initialLeverage": "10", + "notionalCap": "4000000", + "notionalFloor": "800000", + "maintMarginRatio": "0.05", + "cum": "22700.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 10000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 4000000.0, + "maxNotional": 8000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "7", - "initialLeverage": "4", - "notionalCap": "10000000", - "notionalFloor": "5000000", - "maintMarginRatio": "0.125", - "cum": "183045.0" + "initialLeverage": "5", + "notionalCap": "8000000", + "notionalFloor": "4000000", + "maintMarginRatio": "0.1", + "cum": "222700.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 10000000.0, + "minNotional": 8000000.0, "maxNotional": 20000000.0, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "8", - "initialLeverage": "3", + "initialLeverage": "4", "notionalCap": "20000000", - "notionalFloor": "10000000", - "maintMarginRatio": "0.15", - "cum": "433045.0" + "notionalFloor": "8000000", + "maintMarginRatio": "0.125", + "cum": "422700.0" } }, { @@ -22039,7 +22459,7 @@ "notionalCap": "30000000", "notionalFloor": "20000000", "maintMarginRatio": "0.25", - "cum": "2433045.0" + "cum": "2922700.0" } }, { @@ -22055,7 +22475,7 @@ "notionalCap": "50000000", "notionalFloor": "30000000", "maintMarginRatio": "0.5", - "cum": "9933045.0" + "cum": "10422700.0" } } ], @@ -25367,14 +25787,14 @@ "currency": "USDT", "minNotional": 0.0, "maxNotional": 10000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", + "initialLeverage": "75", "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, @@ -25382,112 +25802,274 @@ "tier": 2.0, "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 250000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "20", - "notionalCap": "250000", + "initialLeverage": "50", + "notionalCap": "40000", "notionalFloor": "10000", - "maintMarginRatio": "0.025", - "cum": "100.0" + "maintMarginRatio": "0.015", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 250000.0, - "maxNotional": 750000.0, - "maintenanceMarginRate": 0.03, - "maxLeverage": 15.0, + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "15", - "notionalCap": "750000", - "notionalFloor": "250000", - "maintMarginRatio": "0.03", - "cum": "1350.0" + "initialLeverage": "25", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.02", + "cum": "250.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 200000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "1500000", - "notionalFloor": "750000", - "maintMarginRatio": "0.05", - "cum": "16350.0" + "initialLeverage": "20", + "notionalCap": "750000", + "notionalFloor": "200000", + "maintMarginRatio": "0.025", + "cum": "1250.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 4000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 750000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "4000000", - "notionalFloor": "1500000", - "maintMarginRatio": "0.1", - "cum": "91350.0" + "initialLeverage": "10", + "notionalCap": "2000000", + "notionalFloor": "750000", + "maintMarginRatio": "0.05", + "cum": "20000.0" } }, { "tier": 6.0, "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 4000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "4000000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.1", + "cum": "120000.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", "minNotional": 4000000.0, "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { - "bracket": "6", + "bracket": "7", "initialLeverage": "4", "notionalCap": "5000000", "notionalFloor": "4000000", "maintMarginRatio": "0.125", - "cum": "191350.0" + "cum": "220000.0" } }, { - "tier": 7.0, + "tier": 8.0, "currency": "USDT", "minNotional": 5000000.0, "maxNotional": 12000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { - "bracket": "7", + "bracket": "8", "initialLeverage": "2", "notionalCap": "12000000", "notionalFloor": "5000000", "maintMarginRatio": "0.25", - "cum": "816350.0" + "cum": "845000.0" } }, { - "tier": 8.0, + "tier": 9.0, "currency": "USDT", "minNotional": 12000000.0, "maxNotional": 20000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", "notionalCap": "20000000", "notionalFloor": "12000000", "maintMarginRatio": "0.5", - "cum": "3816350.0" + "cum": "3845000.0" + } + } + ], + "NEIRO/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "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, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "40000", + "notionalFloor": "20000", + "maintMarginRatio": "0.025", + "cum": "175.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.05", + "cum": "1175.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "11175.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.125", + "cum": "21175.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.25", + "cum": "83675.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "333675.0" } } ], @@ -27726,10 +28308,10 @@ "minNotional": 0.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.006, - "maxLeverage": 50.0, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", + "initialLeverage": "75", "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.006", @@ -27742,10 +28324,10 @@ "minNotional": 10000.0, "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25.0, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", + "initialLeverage": "50", "notionalCap": "50000", "notionalFloor": "10000", "maintMarginRatio": "0.01", @@ -27756,96 +28338,128 @@ "tier": 3.0, "currency": "USDT", "minNotional": 50000.0, - "maxNotional": 600000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxNotional": 80000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 40.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "600000", + "initialLeverage": "40", + "notionalCap": "80000", "notionalFloor": "50000", - "maintMarginRatio": "0.025", - "cum": "790.0" + "maintMarginRatio": "0.015", + "cum": "290.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 600000.0, - "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 80000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "2000000", - "notionalFloor": "600000", - "maintMarginRatio": "0.05", - "cum": "15790.0" + "initialLeverage": "25", + "notionalCap": "300000", + "notionalFloor": "80000", + "maintMarginRatio": "0.02", + "cum": "690.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 300000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "5000000", - "notionalFloor": "2000000", - "maintMarginRatio": "0.1", - "cum": "115790.0" + "initialLeverage": "20", + "notionalCap": "600000", + "notionalFloor": "300000", + "maintMarginRatio": "0.025", + "cum": "2190.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 7000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 600000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "7000000", - "notionalFloor": "5000000", - "maintMarginRatio": "0.125", - "cum": "240790.0" + "initialLeverage": "10", + "notionalCap": "3000000", + "notionalFloor": "600000", + "maintMarginRatio": "0.05", + "cum": "17190.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 7000000.0, - "maxNotional": 18000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 3000000.0, + "maxNotional": 6000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "18000000", - "notionalFloor": "7000000", - "maintMarginRatio": "0.25", - "cum": "1115790.0" + "initialLeverage": "5", + "notionalCap": "6000000", + "notionalFloor": "3000000", + "maintMarginRatio": "0.1", + "cum": "167190.0" } }, { "tier": 8.0, "currency": "USDT", + "minNotional": 6000000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "8", + "initialLeverage": "4", + "notionalCap": "7500000", + "notionalFloor": "6000000", + "maintMarginRatio": "0.125", + "cum": "317190.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 18000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "9", + "initialLeverage": "2", + "notionalCap": "18000000", + "notionalFloor": "7500000", + "maintMarginRatio": "0.25", + "cum": "1254690.0" + } + }, + { + "tier": 10.0, + "currency": "USDT", "minNotional": 18000000.0, "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "10", "initialLeverage": "1", "notionalCap": "30000000", "notionalFloor": "18000000", "maintMarginRatio": "0.5", - "cum": "5615790.0" + "cum": "5754690.0" } } ], @@ -28406,128 +29020,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", - "notionalCap": "25000", - "notionalFloor": "5000", - "maintMarginRatio": "0.02", - "cum": "25.0" + "initialLeverage": "50", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 80000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 20000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "80000", - "notionalFloor": "25000", - "maintMarginRatio": "0.025", + "initialLeverage": "25", + "notionalCap": "100000", + "notionalFloor": "20000", + "maintMarginRatio": "0.02", "cum": "150.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 80000.0, - "maxNotional": 800000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 100000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "800000", - "notionalFloor": "80000", - "maintMarginRatio": "0.05", - "cum": "2150.0" + "initialLeverage": "20", + "notionalCap": "200000", + "notionalFloor": "100000", + "maintMarginRatio": "0.025", + "cum": "650.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 800000.0, - "maxNotional": 1600000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 200000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "1600000", - "notionalFloor": "800000", - "maintMarginRatio": "0.1", - "cum": "42150.0" + "initialLeverage": "10", + "notionalCap": "1000000", + "notionalFloor": "200000", + "maintMarginRatio": "0.05", + "cum": "5650.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 1600000.0, + "minNotional": 1000000.0, "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "4", + "initialLeverage": "5", "notionalCap": "2000000", - "notionalFloor": "1600000", - "maintMarginRatio": "0.125", - "cum": "82150.0" + "notionalFloor": "1000000", + "maintMarginRatio": "0.1", + "cum": "55650.0" } }, { "tier": 7.0, "currency": "USDT", "minNotional": 2000000.0, - "maxNotional": 4000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "maxNotional": 2500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "4000000", + "initialLeverage": "4", + "notionalCap": "2500000", "notionalFloor": "2000000", - "maintMarginRatio": "0.25", - "cum": "332150.0" + "maintMarginRatio": "0.125", + "cum": "105650.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 4000000.0, - "maxNotional": 8000000.0, + "minNotional": 2500000.0, + "maxNotional": 5000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "5000000", + "notionalFloor": "2500000", + "maintMarginRatio": "0.25", + "cum": "418150.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "8000000", - "notionalFloor": "4000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.5", - "cum": "1332150.0" + "cum": "1668150.0" } } ], @@ -28536,112 +29166,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "20", - "notionalCap": "25000", - "notionalFloor": "5000", - "maintMarginRatio": "0.025", + "initialLeverage": "50", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 300000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 30000.0, + "maxNotional": 150000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "10", - "notionalCap": "300000", - "notionalFloor": "25000", - "maintMarginRatio": "0.05", - "cum": "675.0" + "initialLeverage": "25", + "notionalCap": "150000", + "notionalFloor": "30000", + "maintMarginRatio": "0.02", + "cum": "200.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 300000.0, - "maxNotional": 800000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 150000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "5", - "notionalCap": "800000", - "notionalFloor": "300000", - "maintMarginRatio": "0.1", - "cum": "15675.0" + "initialLeverage": "20", + "notionalCap": "300000", + "notionalFloor": "150000", + "maintMarginRatio": "0.025", + "cum": "950.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 800000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 300000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "4", - "notionalCap": "1000000", - "notionalFloor": "800000", - "maintMarginRatio": "0.125", - "cum": "35675.0" + "initialLeverage": "10", + "notionalCap": "1500000", + "notionalFloor": "300000", + "maintMarginRatio": "0.05", + "cum": "8450.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 1000000.0, + "minNotional": 1500000.0, "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "2", + "initialLeverage": "5", "notionalCap": "3000000", - "notionalFloor": "1000000", - "maintMarginRatio": "0.25", - "cum": "160675.0" + "notionalFloor": "1500000", + "maintMarginRatio": "0.1", + "cum": "83450.0" } }, { "tier": 7.0, "currency": "USDT", "minNotional": 3000000.0, - "maxNotional": 5000000.0, + "maxNotional": 3750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "3750000", + "notionalFloor": "3000000", + "maintMarginRatio": "0.125", + "cum": "158450.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 3750000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "7500000", + "notionalFloor": "3750000", + "maintMarginRatio": "0.25", + "cum": "627200.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 15000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "7", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "5000000", - "notionalFloor": "3000000", + "notionalCap": "15000000", + "notionalFloor": "7500000", "maintMarginRatio": "0.5", - "cum": "910675.0" + "cum": "2502200.0" } } ], @@ -28987,6 +29649,152 @@ } } ], + "POL/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "10000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 60000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, + "info": { + "bracket": "2", + "initialLeverage": "50", + "notionalCap": "60000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", + "cum": "50.0" + } + }, + { + "tier": 3.0, + "currency": "USDT", + "minNotional": 60000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "300000", + "notionalFloor": "60000", + "maintMarginRatio": "0.02", + "cum": "350.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 300000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "600000", + "notionalFloor": "300000", + "maintMarginRatio": "0.025", + "cum": "1850.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 600000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "3000000", + "notionalFloor": "600000", + "maintMarginRatio": "0.05", + "cum": "16850.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 3000000.0, + "maxNotional": 6000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "6000000", + "notionalFloor": "3000000", + "maintMarginRatio": "0.1", + "cum": "166850.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 6000000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "7500000", + "notionalFloor": "6000000", + "maintMarginRatio": "0.125", + "cum": "316850.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 15000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "15000000", + "notionalFloor": "7500000", + "maintMarginRatio": "0.25", + "cum": "1254350.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 15000000.0, + "maxNotional": 30000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "30000000", + "notionalFloor": "15000000", + "maintMarginRatio": "0.5", + "cum": "5004350.0" + } + } + ], "POLYX/USDT:USDT": [ { "tier": 1.0, @@ -32326,112 +33134,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "20", - "notionalCap": "25000", - "notionalFloor": "5000", - "maintMarginRatio": "0.025", + "initialLeverage": "50", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 300000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 20000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "10", - "notionalCap": "300000", - "notionalFloor": "25000", - "maintMarginRatio": "0.05", - "cum": "675.0" + "initialLeverage": "25", + "notionalCap": "100000", + "notionalFloor": "20000", + "maintMarginRatio": "0.02", + "cum": "150.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 300000.0, - "maxNotional": 700000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 100000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "5", - "notionalCap": "700000", - "notionalFloor": "300000", - "maintMarginRatio": "0.1", - "cum": "15675.0" + "initialLeverage": "20", + "notionalCap": "200000", + "notionalFloor": "100000", + "maintMarginRatio": "0.025", + "cum": "650.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 700000.0, - "maxNotional": 1200000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 200000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "4", - "notionalCap": "1200000", - "notionalFloor": "700000", - "maintMarginRatio": "0.125", - "cum": "33175.0" + "initialLeverage": "10", + "notionalCap": "1000000", + "notionalFloor": "200000", + "maintMarginRatio": "0.05", + "cum": "5650.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 1200000.0, - "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "2", - "notionalCap": "3000000", - "notionalFloor": "1200000", - "maintMarginRatio": "0.25", - "cum": "183175.0" + "initialLeverage": "5", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.1", + "cum": "55650.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 3000000.0, + "minNotional": 2000000.0, + "maxNotional": 2500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "2500000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.125", + "cum": "105650.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 2500000.0, "maxNotional": 5000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "5000000", + "notionalFloor": "2500000", + "maintMarginRatio": "0.25", + "cum": "418150.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "7", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "5000000", - "notionalFloor": "3000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.5", - "cum": "933175.0" + "cum": "1668150.0" } } ], @@ -36018,13 +36858,13 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50.0, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" @@ -36033,113 +36873,129 @@ { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "minNotional": 10000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", - "notionalCap": "50000", - "notionalFloor": "5000", - "maintMarginRatio": "0.02", + "initialLeverage": "50", + "notionalCap": "40000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 150000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "150000", - "notionalFloor": "50000", - "maintMarginRatio": "0.025", - "cum": "300.0" + "initialLeverage": "25", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.02", + "cum": "250.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 150000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "1500000", - "notionalFloor": "150000", - "maintMarginRatio": "0.05", - "cum": "4050.0" + "initialLeverage": "20", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.025", + "cum": "1250.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 400000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "3000000", - "notionalFloor": "1500000", - "maintMarginRatio": "0.1", - "cum": "79050.0" + "initialLeverage": "10", + "notionalCap": "2000000", + "notionalFloor": "400000", + "maintMarginRatio": "0.05", + "cum": "11250.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 3750000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 2000000.0, + "maxNotional": 4000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "3750000", - "notionalFloor": "3000000", - "maintMarginRatio": "0.125", - "cum": "154050.0" + "initialLeverage": "5", + "notionalCap": "4000000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.1", + "cum": "111250.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 3750000.0, - "maxNotional": 7500000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 4000000.0, + "maxNotional": 5000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "7500000", - "notionalFloor": "3750000", - "maintMarginRatio": "0.25", - "cum": "622800.0" + "initialLeverage": "4", + "notionalCap": "5000000", + "notionalFloor": "4000000", + "maintMarginRatio": "0.125", + "cum": "211250.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 15000000.0, + "minNotional": 5000000.0, + "maxNotional": 10000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "10000000", + "notionalFloor": "5000000", + "maintMarginRatio": "0.25", + "cum": "836250.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "15000000", - "notionalFloor": "7500000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.5", - "cum": "2497800.0" + "cum": "3336250.0" } } ], @@ -37546,112 +38402,128 @@ "tier": 3.0, "currency": "USDT", "minNotional": 50000.0, - "maxNotional": 300000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxNotional": 80000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 40.0, "info": { "bracket": "3", - "initialLeverage": "25", - "notionalCap": "300000", + "initialLeverage": "40", + "notionalCap": "80000", "notionalFloor": "50000", - "maintMarginRatio": "0.02", - "cum": "540.0" + "maintMarginRatio": "0.015", + "cum": "290.0" } }, { "tier": 4.0, "currency": "USDT", + "minNotional": 80000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "4", + "initialLeverage": "25", + "notionalCap": "300000", + "notionalFloor": "80000", + "maintMarginRatio": "0.02", + "cum": "690.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", "minNotional": 300000.0, "maxNotional": 900000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { - "bracket": "4", + "bracket": "5", "initialLeverage": "20", "notionalCap": "900000", "notionalFloor": "300000", "maintMarginRatio": "0.025", - "cum": "2040.0" - } - }, - { - "tier": 5.0, - "currency": "USDT", - "minNotional": 900000.0, - "maxNotional": 1800000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, - "info": { - "bracket": "5", - "initialLeverage": "10", - "notionalCap": "1800000", - "notionalFloor": "900000", - "maintMarginRatio": "0.05", - "cum": "24540.0" + "cum": "2190.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 1800000.0, - "maxNotional": 4800000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 900000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "6", - "initialLeverage": "5", - "notionalCap": "4800000", - "notionalFloor": "1800000", - "maintMarginRatio": "0.1", - "cum": "114540.0" + "initialLeverage": "10", + "notionalCap": "3000000", + "notionalFloor": "900000", + "maintMarginRatio": "0.05", + "cum": "24690.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 4800000.0, + "minNotional": 3000000.0, "maxNotional": 6000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "7", - "initialLeverage": "4", + "initialLeverage": "5", "notionalCap": "6000000", - "notionalFloor": "4800000", - "maintMarginRatio": "0.125", - "cum": "234540.0" + "notionalFloor": "3000000", + "maintMarginRatio": "0.1", + "cum": "174690.0" } }, { "tier": 8.0, "currency": "USDT", "minNotional": 6000000.0, - "maxNotional": 18000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "8", - "initialLeverage": "2", - "notionalCap": "18000000", + "initialLeverage": "4", + "notionalCap": "7500000", "notionalFloor": "6000000", - "maintMarginRatio": "0.25", - "cum": "984540.0" + "maintMarginRatio": "0.125", + "cum": "324690.0" } }, { "tier": 9.0, "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 18000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "9", + "initialLeverage": "2", + "notionalCap": "18000000", + "notionalFloor": "7500000", + "maintMarginRatio": "0.25", + "cum": "1262190.0" + } + }, + { + "tier": 10.0, + "currency": "USDT", "minNotional": 18000000.0, "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "9", + "bracket": "10", "initialLeverage": "1", "notionalCap": "30000000", "notionalFloor": "18000000", "maintMarginRatio": "0.5", - "cum": "5484540.0" + "cum": "5762190.0" } } ], @@ -37899,6 +38771,152 @@ } } ], + "UXLINK/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "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, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "40000", + "notionalFloor": "20000", + "maintMarginRatio": "0.025", + "cum": "175.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.05", + "cum": "1175.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "11175.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.125", + "cum": "21175.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.25", + "cum": "83675.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "333675.0" + } + } + ], "VANRY/USDT:USDT": [ { "tier": 1.0, From 15de53a22d05b2082ec4c5e9ea07504e2db9c65a Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 19 Sep 2024 20:36:42 +0200 Subject: [PATCH 127/187] chore: bump ccxt to 4.4.5 closes #10677 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f3284f326..e3531ed12 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ bottleneck==1.4.0 numexpr==2.10.1 pandas-ta==0.3.14b -ccxt==4.4.3 +ccxt==4.4.5 cryptography==42.0.8; platform_machine == 'armv7l' cryptography==43.0.1; platform_machine != 'armv7l' aiohttp==3.10.5 From 3bbc6cbab13d979a30fcfc367b2354780d8c5491 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 19 Sep 2024 20:41:32 +0200 Subject: [PATCH 128/187] chore: bump ccxt to 4.4.5 closes #10677 From 670a40e67bfb3b7820e2075d89e81f10caf46963 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 20 Sep 2024 07:06:21 +0200 Subject: [PATCH 129/187] chore: remove no longer valid todo --- freqtrade/commands/build_config_commands.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/freqtrade/commands/build_config_commands.py b/freqtrade/commands/build_config_commands.py index a5ab8cb41..cb64e4da9 100644 --- a/freqtrade/commands/build_config_commands.py +++ b/freqtrade/commands/build_config_commands.py @@ -274,8 +274,6 @@ def start_new_config(args: Dict[str, Any]) -> None: def start_show_config(args: Dict[str, Any]) -> None: config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE, set_dry=False) - # TODO: Sanitize from sensitive info before printing - print("Your combined configuration is:") config_sanitized = sanitize_config( config["original_config"], show_sensitive=args.get("show_sensitive", False) From d23c1e8f926ebc4a3b1704a2612c9ba974cf7458 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 20 Sep 2024 07:23:45 +0200 Subject: [PATCH 130/187] refactor: Move dataframe parsing into get_historic_ohlcv --- freqtrade/data/history/history_utils.py | 7 +------ freqtrade/exchange/exchange.py | 6 +++--- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/freqtrade/data/history/history_utils.py b/freqtrade/data/history/history_utils.py index 9deab401e..8a65db26a 100644 --- a/freqtrade/data/history/history_utils.py +++ b/freqtrade/data/history/history_utils.py @@ -17,7 +17,6 @@ from freqtrade.constants import ( from freqtrade.data.converter import ( clean_ohlcv_dataframe, convert_trades_to_ohlcv, - ohlcv_to_dataframe, trades_df_remove_duplicates, trades_list_to_df, ) @@ -273,7 +272,7 @@ def _download_pair_history( ) # Default since_ms to 30 days if nothing is given - new_data = exchange.get_historic_ohlcv( + new_dataframe = exchange.get_historic_ohlcv( pair=pair, timeframe=timeframe, since_ms=( @@ -285,10 +284,6 @@ def _download_pair_history( candle_type=candle_type, until_ms=until_ms if until_ms else None, ) - # TODO: Maybe move parsing to exchange class (?) - new_dataframe = ohlcv_to_dataframe( - new_data, timeframe, pair, fill_missing=False, drop_incomplete=True - ) if data.empty: data = new_dataframe else: diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 47ff89f46..9d84f59e4 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -2223,7 +2223,7 @@ class Exchange: candle_type: CandleType, is_new_pair: bool = False, until_ms: Optional[int] = None, - ) -> List: + ) -> DataFrame: """ Get candle history using asyncio and returns the list of candles. Handles all async work for this. @@ -2233,7 +2233,7 @@ class Exchange: :param since_ms: Timestamp in milliseconds to get history from :param until_ms: Timestamp in milliseconds to get history up to :param candle_type: '', mark, index, premiumIndex, or funding_rate - :return: List with candle (OHLCV) data + :return: Dataframe with candle (OHLCV) data """ pair, _, _, data, _ = self.loop.run_until_complete( self._async_get_historic_ohlcv( @@ -2246,7 +2246,7 @@ class Exchange: ) ) logger.info(f"Downloaded data for {pair} with length {len(data)}.") - return data + return ohlcv_to_dataframe(data, timeframe, pair, fill_missing=False, drop_incomplete=True) async def _async_get_historic_ohlcv( self, From e0df0257d1c5938a65288a5f3a810f01782ee6e3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 20 Sep 2024 07:26:45 +0200 Subject: [PATCH 131/187] tests: Update history tests for new response --- tests/data/test_history.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 425b620f8..b505c4fe3 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -123,12 +123,12 @@ def test_load_data_startup_candles(mocker, testdatadir) -> None: @pytest.mark.parametrize("candle_type", ["mark", ""]) def test_load_data_with_new_pair_1min( - ohlcv_history_list, mocker, caplog, default_conf, tmp_path, candle_type + ohlcv_history, mocker, caplog, default_conf, tmp_path, candle_type ) -> None: """ Test load_pair_history() with 1 min timeframe """ - mocker.patch(f"{EXMS}.get_historic_ohlcv", return_value=ohlcv_history_list) + mocker.patch(f"{EXMS}.get_historic_ohlcv", return_value=ohlcv_history) exchange = get_patched_exchange(mocker, default_conf) file = tmp_path / "MEME_BTC-1m.feather" @@ -303,9 +303,9 @@ def test_load_cached_data_for_updating(mocker, testdatadir) -> None: ], ) def test_download_pair_history( - ohlcv_history_list, mocker, default_conf, tmp_path, candle_type, subdir, file_tail + ohlcv_history, mocker, default_conf, tmp_path, candle_type, subdir, file_tail ) -> None: - mocker.patch(f"{EXMS}.get_historic_ohlcv", return_value=ohlcv_history_list) + mocker.patch(f"{EXMS}.get_historic_ohlcv", return_value=ohlcv_history) exchange = get_patched_exchange(mocker, default_conf) file1_1 = tmp_path / f"{subdir}MEME_BTC-1m{file_tail}.feather" file1_5 = tmp_path / f"{subdir}MEME_BTC-5m{file_tail}.feather" @@ -351,16 +351,12 @@ def test_download_pair_history( assert file2_5.is_file() -def test_download_pair_history2(mocker, default_conf, testdatadir) -> None: - tick = [ - [1509836520000, 0.00162008, 0.00162008, 0.00162008, 0.00162008, 108.14853839], - [1509836580000, 0.00161, 0.00161, 0.00161, 0.00161, 82.390199], - ] +def test_download_pair_history2(mocker, default_conf, testdatadir, ohlcv_history) -> None: json_dump_mock = mocker.patch( "freqtrade.data.history.datahandlers.featherdatahandler.FeatherDataHandler.ohlcv_store", return_value=None, ) - mocker.patch(f"{EXMS}.get_historic_ohlcv", return_value=tick) + mocker.patch(f"{EXMS}.get_historic_ohlcv", return_value=ohlcv_history) exchange = get_patched_exchange(mocker, default_conf) _download_pair_history( datadir=testdatadir, From 85138b0bc823d5f4b65600d6bb259a603f1db9e0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 21 Sep 2024 09:06:26 +0200 Subject: [PATCH 132/187] tests: Have exchange test get_historic_ohlcv properly --- tests/exchange/test_exchange.py | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 3114a3408..0a130978b 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -2084,24 +2084,28 @@ def test___now_is_time_to_refresh(default_conf, mocker, exchange_name, time_mach assert exchange._now_is_time_to_refresh(pair, "5m", candle_type) is True -@pytest.mark.parametrize("exchange_name", EXCHANGES) @pytest.mark.parametrize("candle_type", ["mark", ""]) +@pytest.mark.parametrize("exchange_name", EXCHANGES) def test_get_historic_ohlcv(default_conf, mocker, caplog, exchange_name, candle_type): exchange = get_patched_exchange(mocker, default_conf, exchange=exchange_name) - ohlcv = [ - [ - dt_ts(), # unix timestamp ms - 1, # open - 2, # high - 3, # low - 4, # close - 5, # volume (in quote currency) - ] - ] pair = "ETH/BTC" + calls = 0 async def mock_candle_hist(pair, timeframe, candle_type, since_ms): - return pair, timeframe, candle_type, ohlcv, True + nonlocal calls + calls += 1 + ohlcv = [ + [ + dt_ts(dt_now() + timedelta(minutes=5 * (calls + i))), # unix timestamp ms + 1, # open + 2, # high + 3, # low + 4, # close + 5, # volume (in quote currency) + ] + for i in range(2) + ] + return (pair, timeframe, candle_type, ohlcv, True) exchange._async_get_candle_history = Mock(wraps=mock_candle_hist) # one_call calculation * 1.8 should do 2 calls @@ -2112,7 +2116,7 @@ def test_get_historic_ohlcv(default_conf, mocker, caplog, exchange_name, candle_ ) assert exchange._async_get_candle_history.call_count == 2 - # Returns twice the above OHLCV data + # Returns twice the above OHLCV data after truncating the open candle. assert len(ret) == 2 assert log_has_re(r"Downloaded data for .* with length .*\.", caplog) From b21156a8868d0157177f863ace7537c83b4ee703 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 21 Sep 2024 16:34:48 +0200 Subject: [PATCH 133/187] tests: improve stoploss test --- tests/freqtradebot/test_stoploss_on_exchange.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/freqtradebot/test_stoploss_on_exchange.py b/tests/freqtradebot/test_stoploss_on_exchange.py index 451548816..c5dc01b7e 100644 --- a/tests/freqtradebot/test_stoploss_on_exchange.py +++ b/tests/freqtradebot/test_stoploss_on_exchange.py @@ -1109,7 +1109,7 @@ def test_execute_trade_exit_down_stoploss_on_exchange_dry_run( EXMS, fetch_ticker=ticker_usdt, get_fee=fee, - _dry_is_price_crossed=MagicMock(return_value=False), + _dry_is_price_crossed=MagicMock(side_effect=[True, False]), ) patch_whitelist(mocker, default_conf_usdt) freqtrade = FreqtradeBot(default_conf_usdt) @@ -1136,7 +1136,7 @@ def test_execute_trade_exit_down_stoploss_on_exchange_dry_run( trade=trade, limit=trade.stop_loss, exit_check=ExitCheckTuple(exit_type=ExitType.STOP_LOSS) ) - assert rpc_mock.call_count == 2 + # assert rpc_mock.call_count == 2 last_msg = rpc_mock.call_args_list[-1][0][0] assert { @@ -1169,7 +1169,7 @@ def test_execute_trade_exit_down_stoploss_on_exchange_dry_run( "cumulative_profit": 0.0, "stake_amount": pytest.approx(60), "is_final_exit": False, - "final_profit_ratio": None, + "final_profit_ratio": ANY, } == last_msg From b326908487c2d6ef021a106c52ec638c9ce7518c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 21 Sep 2024 16:39:54 +0200 Subject: [PATCH 134/187] tests: Improve test resiliance --- tests/freqtradebot/test_freqtradebot.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/freqtradebot/test_freqtradebot.py b/tests/freqtradebot/test_freqtradebot.py index f0b2d5b36..8b24e5d70 100644 --- a/tests/freqtradebot/test_freqtradebot.py +++ b/tests/freqtradebot/test_freqtradebot.py @@ -2882,7 +2882,7 @@ def test_execute_trade_exit_up( EXMS, fetch_ticker=ticker_usdt, get_fee=fee, - _dry_is_price_crossed=MagicMock(return_value=False), + _dry_is_price_crossed=MagicMock(side_effect=[True, False]), ) patch_whitelist(mocker, default_conf_usdt) freqtrade = FreqtradeBot(default_conf_usdt) @@ -2974,7 +2974,7 @@ def test_execute_trade_exit_down( EXMS, fetch_ticker=ticker_usdt, get_fee=fee, - _dry_is_price_crossed=MagicMock(return_value=False), + _dry_is_price_crossed=MagicMock(side_effect=[True, False]), ) patch_whitelist(mocker, default_conf_usdt) freqtrade = FreqtradeBot(default_conf_usdt) @@ -2997,7 +2997,7 @@ def test_execute_trade_exit_down( exit_check=ExitCheckTuple(exit_type=ExitType.STOP_LOSS), ) - assert rpc_mock.call_count == 2 + assert rpc_mock.call_count == 3 last_msg = rpc_mock.call_args_list[-1][0][0] assert { "type": RPCMessageType.EXIT, @@ -3061,7 +3061,7 @@ def test_execute_trade_exit_custom_exit_price( EXMS, fetch_ticker=ticker_usdt, get_fee=fee, - _dry_is_price_crossed=MagicMock(return_value=False), + _dry_is_price_crossed=MagicMock(side_effect=[True, False]), ) config = deepcopy(default_conf_usdt) config["custom_price_max_distance_ratio"] = 0.1 From 2bbec9f9b1f052d4afe6e9b9e515f4c91fbebe5a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 21 Sep 2024 16:58:34 +0200 Subject: [PATCH 135/187] tests: fix random test failure by reading time only once --- tests/exchange/test_exchange.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 0a130978b..e3032aa9f 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -2090,13 +2090,14 @@ def test_get_historic_ohlcv(default_conf, mocker, caplog, exchange_name, candle_ exchange = get_patched_exchange(mocker, default_conf, exchange=exchange_name) pair = "ETH/BTC" calls = 0 + now = dt_now() async def mock_candle_hist(pair, timeframe, candle_type, since_ms): nonlocal calls calls += 1 ohlcv = [ [ - dt_ts(dt_now() + timedelta(minutes=5 * (calls + i))), # unix timestamp ms + dt_ts(now + timedelta(minutes=5 * (calls + i))), # unix timestamp ms 1, # open 2, # high 3, # low From d377d8462f5c9bbff1a870be419900dd09f6c542 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 21 Sep 2024 16:30:04 +0200 Subject: [PATCH 136/187] fix: improve resiliance of order parsing closes #10676 --- freqtrade/persistence/trade_model.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index 49afd927b..e276d547d 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -341,8 +341,8 @@ class Order(ModelBase): order_id=str(order["id"]), ft_order_side=side, ft_pair=pair, - ft_amount=amount if amount else order["amount"], - ft_price=price if price else order["price"], + ft_amount=amount or order.get("amount", None) or 0.0, + ft_price=price or order.get("price", None), ) o.update_from_ccxt_object(order) From b084efdd06fcbedf64290e51f815e0f820cbbc0a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 21 Sep 2024 16:24:56 +0200 Subject: [PATCH 137/187] feat: initialize trade objects with 0 amount This way, it'll represent the owned amount which will be updated once the order fills --- freqtrade/freqtradebot.py | 2 +- freqtrade/optimize/backtesting.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 0bc11e0fd..fe270f670 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -987,7 +987,7 @@ class FreqtradeBot(LoggingMixin): base_currency=base_currency, stake_currency=self.config["stake_currency"], stake_amount=stake_amount, - amount=amount, + amount=0, is_open=True, amount_requested=amount_requested, fee_open=fee, diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 71adfbb4b..20116f670 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -1099,7 +1099,7 @@ class Backtesting: open_rate_requested=propose_rate, open_date=current_time, stake_amount=stake_amount, - amount=amount, + amount=0, amount_requested=amount, fee_open=self.fee, fee_close=self.fee, From 004e30d6bebbf55ec1ceef69accf4edc01bd875b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 21 Sep 2024 16:53:49 +0200 Subject: [PATCH 138/187] tests: update force_sell test to not use empty amount column --- tests/rpc/test_rpc.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index feb7f9f1a..4c2453145 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -762,7 +762,7 @@ def test_rpc_force_exit(default_conf, ticker, fee, mocker) -> None: freqtradebot.enter_positions() # make an limit-buy open trade trade = Trade.session.scalars(select(Trade).filter(Trade.id == "3")).first() - filled_amount = trade.amount / 2 + filled_amount = trade.amount_requested / 2 # Fetch order - it's open first, and closed after cancel_order is called. mocker.patch( f"{EXMS}.fetch_order", @@ -799,7 +799,7 @@ def test_rpc_force_exit(default_conf, ticker, fee, mocker) -> None: cancel_order_mock.reset_mock() trade = Trade.session.scalars(select(Trade).filter(Trade.id == "3")).first() - amount = trade.amount + amount = trade.amount_requested # make an limit-sell open order trade mocker.patch( f"{EXMS}.fetch_order", @@ -832,7 +832,7 @@ def test_rpc_force_exit(default_conf, ticker, fee, mocker) -> None: assert cancel_order_mock.call_count == 0 trade = Trade.session.scalars(select(Trade).filter(Trade.id == "4")).first() - amount = trade.amount + amount = trade.amount_requested # make an limit-buy open trade, if there is no 'filled', don't sell it mocker.patch( f"{EXMS}.fetch_order", From b8ba6cd9708596ce331e6e646e41a3f4dfd4cbc9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 21 Sep 2024 16:56:20 +0200 Subject: [PATCH 139/187] tests: update rpc_status --- tests/rpc/test_rpc.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index 4c2453145..dd8c1bb9a 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -149,7 +149,10 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: # Different from "filled" response: response_unfilled.update( { - "amount": 91.07468124, + "amount": 0.0, + "open_trade_value": 0.0, + "stoploss_entry_dist": 0.0, + "stoploss_entry_dist_ratio": 0.0, "profit_ratio": 0.0, "profit_pct": 0.0, "profit_abs": 0.0, From c69b09cbfff3b2fe549d7d2d8e2a40ce2d8d2f5b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 21 Sep 2024 20:35:14 +0200 Subject: [PATCH 140/187] tests: fix amount=0 test --- tests/freqtradebot/test_freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/freqtradebot/test_freqtradebot.py b/tests/freqtradebot/test_freqtradebot.py index 8b24e5d70..bbaee5ffc 100644 --- a/tests/freqtradebot/test_freqtradebot.py +++ b/tests/freqtradebot/test_freqtradebot.py @@ -1684,7 +1684,7 @@ def test_handle_trade_roi( create_order=MagicMock( side_effect=[ open_order, - {"id": 1234553382}, + {"id": 1234553382, "amount": open_order["amount"]}, ] ), get_fee=fee, From 0e0af8229041d84fb1f6a9921ee090c21b5619cc Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 21 Sep 2024 20:36:01 +0200 Subject: [PATCH 141/187] fix: odd calculation in calc_profit_ratio --- freqtrade/persistence/trade_model.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index e276d547d..698e9721c 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -1161,10 +1161,7 @@ class LocalTrade: else: open_trade_value = self._calc_open_trade_value(amount, open_rate) - short_close_zero = self.is_short and close_trade_value == 0.0 - long_close_zero = not self.is_short and open_trade_value == 0.0 - - if short_close_zero or long_close_zero: + if open_trade_value == 0.0: return 0.0 else: if self.is_short: From b09f80ca3095e8b850447b9b77768c8d65a8d2f1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 21 Sep 2024 20:55:55 +0200 Subject: [PATCH 142/187] tests: improve create_trade test --- tests/freqtradebot/test_freqtradebot.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/freqtradebot/test_freqtradebot.py b/tests/freqtradebot/test_freqtradebot.py index bbaee5ffc..8587e7f9d 100644 --- a/tests/freqtradebot/test_freqtradebot.py +++ b/tests/freqtradebot/test_freqtradebot.py @@ -689,13 +689,29 @@ def test_process_trade_creation( assert trade.open_date is not None assert trade.exchange == "binance" assert trade.open_rate == ticker_usdt.return_value[ticker_side] - assert pytest.approx(trade.amount) == 60 / ticker_usdt.return_value[ticker_side] + # Trade opens with 0 amount. Only trade filling will set the amount + assert pytest.approx(trade.amount) == 0 + assert pytest.approx(trade.amount_requested) == 60 / ticker_usdt.return_value[ticker_side] assert log_has( f'{"Short" if is_short else "Long"} signal found: about create a new trade for ETH/USDT ' "with stake_amount: 60.0 ...", caplog, ) + mocker.patch("freqtrade.freqtradebot.FreqtradeBot._check_and_execute_exit") + + # Fill trade. + freqtrade.process() + trades = Trade.get_open_trades() + assert len(trades) == 1 + trade = trades[0] + assert trade is not None + assert trade.is_open + assert trade.open_date is not None + assert trade.exchange == "binance" + assert trade.open_rate == limit_order[entry_side(is_short)]["price"] + # Filled trade has amount set to filled order amount + assert pytest.approx(trade.amount) == limit_order[entry_side(is_short)]["filled"] def test_process_exchange_failures(default_conf_usdt, ticker_usdt, mocker) -> None: From 9b346c09379360fd820ce82fd832544608247f05 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Sep 2024 09:20:49 +0200 Subject: [PATCH 143/187] docs: add hint about amount being 0 --- docs/trade-object.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/trade-object.md b/docs/trade-object.md index 4962d6b30..7434b826d 100644 --- a/docs/trade-object.md +++ b/docs/trade-object.md @@ -18,7 +18,7 @@ The following attributes / properties are available for each individual trade - | `open_rate` | float | Rate this trade was entered at (Avg. entry rate in case of trade-adjustments). | | `close_rate` | float | Close rate - only set when is_open = False. | | `stake_amount` | float | Amount in Stake (or Quote) currency. | -| `amount` | float | Amount in Asset / Base currency that is currently owned. | +| `amount` | float | Amount in Asset / Base currency that is currently owned. Will be 0.0 until the initial order fills. | | `open_date` | datetime | Timestamp when trade was opened **use `open_date_utc` instead** | | `open_date_utc` | datetime | Timestamp when trade was opened - in UTC. | | `close_date` | datetime | Timestamp when trade was closed **use `close_date_utc` instead** | From 8e6151fe65d1a398b504b0cf5a4d3cfb266c1369 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Sep 2024 13:17:27 +0200 Subject: [PATCH 144/187] fix: properly consider open order values as "tied up" stake. --- freqtrade/wallets.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/freqtrade/wallets.py b/freqtrade/wallets.py index f888ef92e..e67bdd79e 100644 --- a/freqtrade/wallets.py +++ b/freqtrade/wallets.py @@ -99,11 +99,21 @@ class Wallets: used_stake = 0.0 if self._config.get("trading_mode", "spot") != TradingMode.FUTURES: - current_stake = self.start_cap + tot_profit - tot_in_trades - total_stake = current_stake for trade in open_trades: curr = self._exchange.get_pair_base_currency(trade.pair) - _wallets[curr] = Wallet(curr, trade.amount, 0, trade.amount) + used_stake += sum( + o.stake_amount for o in trade.open_orders if o.ft_order_side == trade.entry_side + ) + pending = sum( + o.amount + for o in trade.open_orders + if o.amount and o.ft_order_side == trade.exit_side + ) + + _wallets[curr] = Wallet(curr, trade.amount - pending, pending, trade.amount) + + current_stake = self.start_cap + tot_profit - tot_in_trades + total_stake = current_stake + used_stake else: tot_in_trades = 0 for position in open_trades: From b37dadcc057709143fda5aca71abb6312ae95270 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Sep 2024 13:22:37 +0200 Subject: [PATCH 145/187] tests: dry-wallets test update --- tests/test_wallets.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/test_wallets.py b/tests/test_wallets.py index a2aebeea4..ef3129b88 100644 --- a/tests/test_wallets.py +++ b/tests/test_wallets.py @@ -365,13 +365,18 @@ def test_sync_wallet_dry(mocker, default_conf_usdt, fee): assert bal["NEO"].total == 10 assert bal["XRP"].total == 10 assert bal["LTC"].total == 2 - assert bal["USDT"].total == 922.74 + usdt_bal = bal["USDT"] + assert usdt_bal.free == 922.74 + assert usdt_bal.total == 942.74 + assert usdt_bal.used == 20.0 + # sum of used and free should be total. + assert usdt_bal.total == usdt_bal.free + usdt_bal.used assert freqtrade.wallets.get_starting_balance() == default_conf_usdt["dry_run_wallet"] total = freqtrade.wallets.get_total("LTC") free = freqtrade.wallets.get_free("LTC") used = freqtrade.wallets.get_used("LTC") - assert free != 0 + assert used != 0 assert free + used == total From 01e7b0da465fc50034b1c961ee1274e6e2f3c08e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 03:22:42 +0000 Subject: [PATCH 146/187] chore(deps): bump pypa/gh-action-pypi-publish from 1.10.1 to 1.10.2 Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.10.1 to 1.10.2. - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.10.1...v1.10.2) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d45841a28..a9a38e7d8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -537,12 +537,12 @@ jobs: - name: Publish to PyPI (Test) - uses: pypa/gh-action-pypi-publish@v1.10.1 + uses: pypa/gh-action-pypi-publish@v1.10.2 with: repository-url: https://test.pypi.org/legacy/ - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@v1.10.1 + uses: pypa/gh-action-pypi-publish@v1.10.2 deploy-docker: From 0428dc83812a4a2b0c6863d641e9e289867d8b2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 03:47:22 +0000 Subject: [PATCH 147/187] chore(deps): bump mkdocs-material in the mkdocs group Bumps the mkdocs group with 1 update: [mkdocs-material](https://github.com/squidfunk/mkdocs-material). Updates `mkdocs-material` from 9.5.34 to 9.5.36 - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.34...9.5.36) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:production update-type: version-update:semver-patch dependency-group: mkdocs ... Signed-off-by: dependabot[bot] --- docs/requirements-docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index a354b3fc0..5831c54fd 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,6 +1,6 @@ markdown==3.7 mkdocs==1.6.1 -mkdocs-material==9.5.34 +mkdocs-material==9.5.36 mdx_truly_sane_lists==1.3 pymdown-extensions==10.9 jinja2==3.1.4 From cbd5c6d3e96cdc14426c8a186ff9859d44324ce0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 03:47:32 +0000 Subject: [PATCH 148/187] chore(deps): bump pydantic from 2.9.1 to 2.9.2 Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.9.1 to 2.9.2. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v2.9.1...v2.9.2) --- updated-dependencies: - dependency-name: pydantic 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 e3531ed12..f33294f7e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -42,7 +42,7 @@ sdnotify==0.3.2 # API Server fastapi==0.114.2 -pydantic==2.9.1 +pydantic==2.9.2 uvicorn==0.30.6 pyjwt==2.9.0 aiofiles==24.1.0 From 94322664f21b04f79b204b4143ad9c3170c997c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 03:47:39 +0000 Subject: [PATCH 149/187] chore(deps): bump websockets from 13.0.1 to 13.1 Bumps [websockets](https://github.com/python-websockets/websockets) from 13.0.1 to 13.1. - [Release notes](https://github.com/python-websockets/websockets/releases) - [Commits](https://github.com/python-websockets/websockets/compare/13.0.1...13.1) --- updated-dependencies: - dependency-name: websockets 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 e3531ed12..55a22a51a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -59,7 +59,7 @@ pytz==2024.2 schedule==1.2.2 #WS Messages -websockets==13.0.1 +websockets==13.1 janus==1.0.0 ast-comments==1.2.2 From a2ca136f1fab60ee22737e4cc66cc819b54ef3b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 03:47:58 +0000 Subject: [PATCH 150/187] chore(deps): bump pandas from 2.2.2 to 2.2.3 Bumps [pandas](https://github.com/pandas-dev/pandas) from 2.2.2 to 2.2.3. - [Release notes](https://github.com/pandas-dev/pandas/releases) - [Commits](https://github.com/pandas-dev/pandas/compare/v2.2.2...v2.2.3) --- updated-dependencies: - dependency-name: pandas 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 e3531ed12..e29296b28 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ numpy==1.26.4 -pandas==2.2.2 +pandas==2.2.3 bottleneck==1.4.0 numexpr==2.10.1 pandas-ta==0.3.14b From 1e761b4c7d4f3652a2c93fe0265b3126ae31513f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 03:48:12 +0000 Subject: [PATCH 151/187] chore(deps): bump sqlalchemy from 2.0.34 to 2.0.35 Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.34 to 2.0.35. - [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases) - [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst) - [Commits](https://github.com/sqlalchemy/sqlalchemy/commits) --- updated-dependencies: - dependency-name: sqlalchemy dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e3531ed12..3d488fd79 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ ccxt==4.4.5 cryptography==42.0.8; platform_machine == 'armv7l' cryptography==43.0.1; platform_machine != 'armv7l' aiohttp==3.10.5 -SQLAlchemy==2.0.34 +SQLAlchemy==2.0.35 python-telegram-bot==21.5 # can't be hard-pinned due to telegram-bot pinning httpx with ~ httpx>=0.24.1 From 2fc97f83f489a6abd4abf48e6af0c2680bff10e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 03:48:26 +0000 Subject: [PATCH 152/187] chore(deps-dev): bump ruff from 0.6.5 to 0.6.7 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.5 to 0.6.7. - [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.6.5...0.6.7) --- updated-dependencies: - dependency-name: ruff 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 9c685f12f..0036f6b68 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,7 +7,7 @@ -r docs/requirements-docs.txt coveralls==4.0.1 -ruff==0.6.5 +ruff==0.6.7 mypy==1.11.2 pre-commit==3.8.0 pytest==8.3.3 From 29e6e3b374f8282c251e85174ea4d5d22a2081d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 03:48:38 +0000 Subject: [PATCH 153/187] chore(deps): bump python-telegram-bot from 21.5 to 21.6 Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 21.5 to 21.6. - [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases) - [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst) - [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v21.5...v21.6) --- updated-dependencies: - dependency-name: python-telegram-bot 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 e3531ed12..ff05aa9af 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,7 +9,7 @@ cryptography==42.0.8; platform_machine == 'armv7l' cryptography==43.0.1; platform_machine != 'armv7l' aiohttp==3.10.5 SQLAlchemy==2.0.34 -python-telegram-bot==21.5 +python-telegram-bot==21.6 # can't be hard-pinned due to telegram-bot pinning httpx with ~ httpx>=0.24.1 humanize==4.10.0 From 06eb5abf11276ca76bd2788c6a2d1268006b66d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 03:48:44 +0000 Subject: [PATCH 154/187] chore(deps): bump filelock from 3.16.0 to 3.16.1 Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.16.0 to 3.16.1. - [Release notes](https://github.com/tox-dev/py-filelock/releases) - [Changelog](https://github.com/tox-dev/filelock/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/py-filelock/compare/3.16.0...3.16.1) --- updated-dependencies: - dependency-name: filelock dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements-hyperopt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index a8e8b557c..41afe6d58 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -6,4 +6,4 @@ scipy==1.14.1; python_version >= "3.10" scipy==1.13.1; python_version < "3.10" scikit-learn==1.5.2 ft-scikit-optimize==0.9.2 -filelock==3.16.0 +filelock==3.16.1 From 9f5e4b58124e72fe2202dcf9bb29b083a761920d Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Sep 2024 06:34:12 +0200 Subject: [PATCH 155/187] chore: update 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 4a287743e..3aa3acb66 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: - types-requests==2.32.0.20240914 - types-tabulate==0.9.0.20240106 - types-python-dateutil==2.9.0.20240906 - - SQLAlchemy==2.0.34 + - SQLAlchemy==2.0.35 # stages: [push] - repo: https://github.com/pycqa/isort From 04abc4d12f08ff9fea99cdde9cb7608405db2430 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 06:24:37 +0000 Subject: [PATCH 156/187] chore(deps): bump pymdown-extensions from 10.9 to 10.10.1 Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 10.9 to 10.10.1. - [Release notes](https://github.com/facelessuser/pymdown-extensions/releases) - [Commits](https://github.com/facelessuser/pymdown-extensions/compare/10.9...10.10.1) --- updated-dependencies: - dependency-name: pymdown-extensions dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- docs/requirements-docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index 5831c54fd..141490354 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -2,6 +2,6 @@ markdown==3.7 mkdocs==1.6.1 mkdocs-material==9.5.36 mdx_truly_sane_lists==1.3 -pymdown-extensions==10.9 +pymdown-extensions==10.10.1 jinja2==3.1.4 mike==2.1.3 From 1cdf8b29a536eea2eca5cdedbcdcdca304fd5129 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 06:38:27 +0000 Subject: [PATCH 157/187] chore(deps): bump fastapi from 0.114.2 to 0.115.0 Bumps [fastapi](https://github.com/fastapi/fastapi) from 0.114.2 to 0.115.0. - [Release notes](https://github.com/fastapi/fastapi/releases) - [Commits](https://github.com/fastapi/fastapi/compare/0.114.2...0.115.0) --- updated-dependencies: - dependency-name: fastapi 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 27a2da835..1641b0ced 100644 --- a/requirements.txt +++ b/requirements.txt @@ -41,7 +41,7 @@ orjson==3.10.7 sdnotify==0.3.2 # API Server -fastapi==0.114.2 +fastapi==0.115.0 pydantic==2.9.2 uvicorn==0.30.6 pyjwt==2.9.0 From b228f177f3f2fde61c46570779320a18c7e12e22 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 09:57:20 +0000 Subject: [PATCH 158/187] chore(deps): bump ccxt from 4.4.5 to 4.4.6 Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.4.5 to 4.4.6. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/4.4.5...4.4.6) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c4777cd4c..04469b882 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ bottleneck==1.4.0 numexpr==2.10.1 pandas-ta==0.3.14b -ccxt==4.4.5 +ccxt==4.4.6 cryptography==42.0.8; platform_machine == 'armv7l' cryptography==43.0.1; platform_machine != 'armv7l' aiohttp==3.10.5 From b44e8199b5b49986bbe740ba7d2c152bad303482 Mon Sep 17 00:00:00 2001 From: xmatthias <5024695+xmatthias@users.noreply.github.com> Date: Tue, 24 Sep 2024 03:06:51 +0000 Subject: [PATCH 159/187] chore: update pre-commit hooks --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3aa3acb66..57a5ad437 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: - repo: https://github.com/charliermarsh/ruff-pre-commit # Ruff version. - rev: 'v0.6.5' + rev: 'v0.6.7' hooks: - id: ruff - id: ruff-format From 3d1acc65afb2e150d02881ea491ccf62a4feaa9b Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Sep 2024 19:38:11 +0200 Subject: [PATCH 160/187] tests: add test for #10704 --- tests/exchange/test_okx.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/exchange/test_okx.py b/tests/exchange/test_okx.py index 97f8a3a4c..8d505da7f 100644 --- a/tests/exchange/test_okx.py +++ b/tests/exchange/test_okx.py @@ -6,6 +6,7 @@ import pytest from freqtrade.enums import CandleType, MarginMode, TradingMode from freqtrade.exceptions import RetryableOrderError, TemporaryError +from freqtrade.exchange.common import API_FETCH_ORDER_RETRY_COUNT from freqtrade.exchange.exchange import timeframe_to_minutes from tests.conftest import EXMS, get_patched_exchange, log_has from tests.exchange.test_exchange import ccxt_exceptionhandlers @@ -610,6 +611,39 @@ def test_fetch_stoploss_order_okx(default_conf, mocker): assert dro_mock.call_count == 1 +def test_fetch_stoploss_order_okx_exceptions(default_conf_usdt, mocker): + default_conf_usdt["dry_run"] = False + api_mock = MagicMock() + ccxt_exceptionhandlers( + mocker, + default_conf_usdt, + api_mock, + "okx", + "fetch_stoploss_order", + "fetch_order", + retries=API_FETCH_ORDER_RETRY_COUNT + 1, + order_id="12345", + pair="ETH/USDT", + ) + + # Test 2nd part of the function + api_mock.fetch_order = MagicMock(side_effect=ccxt.OrderNotFound()) + api_mock.fetch_closed_orders = MagicMock(return_value=[]) + api_mock.fetch_canceled_orders = MagicMock(return_value=[]) + + ccxt_exceptionhandlers( + mocker, + default_conf_usdt, + api_mock, + "okx", + "fetch_stoploss_order", + "fetch_open_orders", + retries=API_FETCH_ORDER_RETRY_COUNT + 1, + order_id="12345", + pair="ETH/USDT", + ) + + @pytest.mark.parametrize( "sl1,sl2,sl3,side", [(1501, 1499, 1501, "sell"), (1499, 1501, 1499, "buy")] ) From 333f2cb47233f2b63c9bc28629c581ea5c3028fe Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Sep 2024 19:38:36 +0200 Subject: [PATCH 161/187] fix: Improve error handling for OKX stop orders closes #10704 --- freqtrade/exchange/okx.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/freqtrade/exchange/okx.py b/freqtrade/exchange/okx.py index 8a781982a..85fa805d9 100644 --- a/freqtrade/exchange/okx.py +++ b/freqtrade/exchange/okx.py @@ -13,7 +13,7 @@ from freqtrade.exceptions import ( TemporaryError, ) from freqtrade.exchange import Exchange, date_minus_candles -from freqtrade.exchange.common import retrier +from freqtrade.exchange.common import API_FETCH_ORDER_RETRY_COUNT, retrier from freqtrade.exchange.exchange_types import FtHas from freqtrade.misc import safe_value_fallback2 from freqtrade.util import dt_now, dt_ts @@ -208,6 +208,7 @@ class Okx(Exchange): order["type"] = "stoploss" return order + @retrier(retries=API_FETCH_ORDER_RETRY_COUNT) def fetch_stoploss_order(self, order_id: str, pair: str, params: Optional[Dict] = None) -> Dict: if self._config["dry_run"]: return self.fetch_dry_run_order(order_id) @@ -217,8 +218,17 @@ class Okx(Exchange): order_reg = self._api.fetch_order(order_id, pair, params=params1) self._log_exchange_response("fetch_stoploss_order", order_reg) return self._convert_stop_order(pair, order_id, order_reg) - except ccxt.OrderNotFound: + 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 + params2 = {"stop": True, "ordType": "conditional"} for method in ( self._api.fetch_open_orders, @@ -231,8 +241,16 @@ class Okx(Exchange): if orders_f: order = orders_f[0] return self._convert_stop_order(pair, order_id, order) - except ccxt.BaseError: + 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}).") def get_order_id_conditional(self, order: Dict[str, Any]) -> str: From 566c0c8f721407c1d3ae728242091e827fa0ab32 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Sep 2024 20:02:55 +0200 Subject: [PATCH 162/187] refactor: split okx fetch stop fallback --- freqtrade/exchange/okx.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/freqtrade/exchange/okx.py b/freqtrade/exchange/okx.py index 85fa805d9..f878393b9 100644 --- a/freqtrade/exchange/okx.py +++ b/freqtrade/exchange/okx.py @@ -1,6 +1,6 @@ import logging from datetime import timedelta -from typing import Any, Dict, List, Optional, Tuple +from typing import Any, Dict, List, Optional, Tuple, Union import ccxt @@ -229,6 +229,9 @@ class Okx(Exchange): except ccxt.BaseError as e: raise OperationalException(e) from e + return self._fetch_stop_order_fallback(order_id, pair) + + def _fetch_stop_order_fallback(self, order_id: str, pair: str) -> Dict: params2 = {"stop": True, "ordType": "conditional"} for method in ( self._api.fetch_open_orders, From 0a68b0515c4a5e91b56b4091b69af20140495264 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Sep 2024 20:13:49 +0200 Subject: [PATCH 163/187] chore: reduce retry count for stop orders --- freqtrade/exchange/okx.py | 4 ++-- tests/exchange/test_okx.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/freqtrade/exchange/okx.py b/freqtrade/exchange/okx.py index f878393b9..7c3408fd7 100644 --- a/freqtrade/exchange/okx.py +++ b/freqtrade/exchange/okx.py @@ -13,7 +13,7 @@ from freqtrade.exceptions import ( TemporaryError, ) from freqtrade.exchange import Exchange, date_minus_candles -from freqtrade.exchange.common import API_FETCH_ORDER_RETRY_COUNT, retrier +from freqtrade.exchange.common import API_RETRY_COUNT, retrier from freqtrade.exchange.exchange_types import FtHas from freqtrade.misc import safe_value_fallback2 from freqtrade.util import dt_now, dt_ts @@ -208,7 +208,7 @@ class Okx(Exchange): order["type"] = "stoploss" return order - @retrier(retries=API_FETCH_ORDER_RETRY_COUNT) + @retrier(retries=API_RETRY_COUNT) def fetch_stoploss_order(self, order_id: str, pair: str, params: Optional[Dict] = None) -> Dict: if self._config["dry_run"]: return self.fetch_dry_run_order(order_id) diff --git a/tests/exchange/test_okx.py b/tests/exchange/test_okx.py index 8d505da7f..6ed24cd62 100644 --- a/tests/exchange/test_okx.py +++ b/tests/exchange/test_okx.py @@ -6,7 +6,7 @@ import pytest from freqtrade.enums import CandleType, MarginMode, TradingMode from freqtrade.exceptions import RetryableOrderError, TemporaryError -from freqtrade.exchange.common import API_FETCH_ORDER_RETRY_COUNT +from freqtrade.exchange.common import API_RETRY_COUNT from freqtrade.exchange.exchange import timeframe_to_minutes from tests.conftest import EXMS, get_patched_exchange, log_has from tests.exchange.test_exchange import ccxt_exceptionhandlers @@ -621,7 +621,7 @@ def test_fetch_stoploss_order_okx_exceptions(default_conf_usdt, mocker): "okx", "fetch_stoploss_order", "fetch_order", - retries=API_FETCH_ORDER_RETRY_COUNT + 1, + retries=API_RETRY_COUNT + 1, order_id="12345", pair="ETH/USDT", ) @@ -638,7 +638,7 @@ def test_fetch_stoploss_order_okx_exceptions(default_conf_usdt, mocker): "okx", "fetch_stoploss_order", "fetch_open_orders", - retries=API_FETCH_ORDER_RETRY_COUNT + 1, + retries=API_RETRY_COUNT + 1, order_id="12345", pair="ETH/USDT", ) From 28eabfe47769f3003f689b2ae4cff971e3d2ec9c Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Sep 2024 20:24:54 +0200 Subject: [PATCH 164/187] tests: update test for retryable okx behavior --- freqtrade/exchange/okx.py | 2 +- tests/exchange/test_okx.py | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/freqtrade/exchange/okx.py b/freqtrade/exchange/okx.py index 7c3408fd7..a0fbb6729 100644 --- a/freqtrade/exchange/okx.py +++ b/freqtrade/exchange/okx.py @@ -1,6 +1,6 @@ import logging from datetime import timedelta -from typing import Any, Dict, List, Optional, Tuple, Union +from typing import Any, Dict, List, Optional, Tuple import ccxt diff --git a/tests/exchange/test_okx.py b/tests/exchange/test_okx.py index 6ed24cd62..1bf783daa 100644 --- a/tests/exchange/test_okx.py +++ b/tests/exchange/test_okx.py @@ -552,6 +552,7 @@ def test__set_leverage_okx(mocker, default_conf): @pytest.mark.usefixtures("init_persistence") def test_fetch_stoploss_order_okx(default_conf, mocker): default_conf["dry_run"] = False + mocker.patch("freqtrade.exchange.common.time.sleep") api_mock = MagicMock() api_mock.fetch_order = MagicMock() @@ -570,10 +571,10 @@ def test_fetch_stoploss_order_okx(default_conf, mocker): with pytest.raises(RetryableOrderError): exchange.fetch_stoploss_order("1234", "ETH/BTC") - assert api_mock.fetch_order.call_count == 1 - assert api_mock.fetch_open_orders.call_count == 1 - assert api_mock.fetch_closed_orders.call_count == 1 - assert api_mock.fetch_canceled_orders.call_count == 1 + assert api_mock.fetch_order.call_count == API_RETRY_COUNT + 1 + assert api_mock.fetch_open_orders.call_count == API_RETRY_COUNT + 1 + assert api_mock.fetch_closed_orders.call_count == API_RETRY_COUNT + 1 + assert api_mock.fetch_canceled_orders.call_count == API_RETRY_COUNT + 1 api_mock.fetch_order.reset_mock() api_mock.fetch_open_orders.reset_mock() From a3ca1ff1e90af68d9a6a51c696f3f2314fa4c81d Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Sep 2024 19:02:32 +0200 Subject: [PATCH 165/187] fix: send acknoledged to bybit fetch_order calls --- freqtrade/exchange/bybit.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/freqtrade/exchange/bybit.py b/freqtrade/exchange/bybit.py index af0071039..ec6c51716 100644 --- a/freqtrade/exchange/bybit.py +++ b/freqtrade/exchange/bybit.py @@ -238,7 +238,13 @@ class Bybit(Exchange): return orders def fetch_order(self, order_id: str, pair: str, params: Optional[Dict] = None) -> Dict: + if self.exchange_has("fetchOrder"): + # Set acknowledged to True to avoid ccxt exception + params = {"acknowledged": True} + order = super().fetch_order(order_id, pair, params) + if not order: + order = self.fetch_order_emulated(order_id, pair, params) if ( order.get("status") == "canceled" and order.get("filled") == 0.0 From 096a051b991d7d8dfe4aed8fdac3b969dfa2ac38 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Sep 2024 19:03:03 +0200 Subject: [PATCH 166/187] test: update test --- tests/exchange/test_exchange.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index e3032aa9f..d71d2062e 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -3569,7 +3569,7 @@ def test_cancel_order_with_result( mocker.patch(f"{EXMS}.exchange_has", return_value=True) api_mock = MagicMock() api_mock.cancel_order = MagicMock(return_value=corder) - api_mock.fetch_order = MagicMock(return_value={}) + api_mock.fetch_order = MagicMock(return_value={"id": "1234"}) exchange = get_patched_exchange(mocker, default_conf, api_mock, exchange=exchange_name) res = exchange.cancel_order_with_result("1234", "ETH/BTC", 1234) assert isinstance(res, dict) From 4b70bea21f32df67498a25eb0ca2b6c813c226fd Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Sep 2024 19:11:01 +0200 Subject: [PATCH 167/187] chore: reset params for emulated call --- freqtrade/exchange/bybit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/exchange/bybit.py b/freqtrade/exchange/bybit.py index ec6c51716..719c64dc3 100644 --- a/freqtrade/exchange/bybit.py +++ b/freqtrade/exchange/bybit.py @@ -244,7 +244,7 @@ class Bybit(Exchange): order = super().fetch_order(order_id, pair, params) if not order: - order = self.fetch_order_emulated(order_id, pair, params) + order = self.fetch_order_emulated(order_id, pair, {}) if ( order.get("status") == "canceled" and order.get("filled") == 0.0 From 0dbe507b26ffc45ec2d4f07ff41720781c9873d9 Mon Sep 17 00:00:00 2001 From: "Jakub Werner (jakubikan)" Date: Wed, 25 Sep 2024 21:11:52 +0200 Subject: [PATCH 168/187] making list of categories available --- freqtrade/plugins/pairlist/IPairList.py | 20 +++--- .../plugins/pairlist/MarketCapPairList.py | 63 ++++++++++++------- 2 files changed, 52 insertions(+), 31 deletions(-) diff --git a/freqtrade/plugins/pairlist/IPairList.py b/freqtrade/plugins/pairlist/IPairList.py index 755f52b06..7be86df7e 100644 --- a/freqtrade/plugins/pairlist/IPairList.py +++ b/freqtrade/plugins/pairlist/IPairList.py @@ -38,6 +38,11 @@ class __OptionPairlistParameter(__PairlistParameterBase): default: Union[str, None] options: List[str] +class __ListPairListParamenter(__PairlistParameterBase): + type: Literal["list"] + default: Union[List[str], None] + options: List[str] + class __BoolPairlistParameter(__PairlistParameterBase): type: Literal["boolean"] @@ -49,6 +54,7 @@ PairlistParameter = Union[ __StringPairlistParameter, __OptionPairlistParameter, __BoolPairlistParameter, + __ListPairListParamenter ] @@ -68,12 +74,12 @@ class IPairList(LoggingMixin, ABC): supports_backtesting: SupportsBacktesting = SupportsBacktesting.NO def __init__( - self, - exchange: Exchange, - pairlistmanager, - config: Config, - pairlistconfig: Dict[str, Any], - pairlist_pos: int, + self, + exchange: Exchange, + pairlistmanager, + config: Config, + pairlistconfig: Dict[str, Any], + pairlist_pos: int, ) -> None: """ :param exchange: Exchange instance @@ -213,7 +219,7 @@ class IPairList(LoggingMixin, ABC): return self._pairlistmanager.verify_blacklist(pairlist, logmethod) def verify_whitelist( - self, pairlist: List[str], logmethod, keep_invalid: bool = False + self, pairlist: List[str], logmethod, keep_invalid: bool = False ) -> List[str]: """ Proxy method to verify_whitelist for easy access for child classes. diff --git a/freqtrade/plugins/pairlist/MarketCapPairList.py b/freqtrade/plugins/pairlist/MarketCapPairList.py index 96edf81b5..b9461589d 100644 --- a/freqtrade/plugins/pairlist/MarketCapPairList.py +++ b/freqtrade/plugins/pairlist/MarketCapPairList.py @@ -14,7 +14,6 @@ from freqtrade.exchange.exchange_types import Tickers from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting from freqtrade.util.coin_gecko import FtCoinGeckoApi - logger = logging.getLogger(__name__) @@ -35,7 +34,7 @@ class MarketCapPairList(IPairList): self._number_assets = self._pairlistconfig["number_assets"] self._max_rank = self._pairlistconfig.get("max_rank", 30) self._refresh_period = self._pairlistconfig.get("refresh_period", 86400) - self._category = self._pairlistconfig.get("category", None) + self._categories = self._pairlistconfig.get("categories", []) self._marketcap_cache: TTLCache = TTLCache(maxsize=1, ttl=self._refresh_period) self._def_candletype = self._config["candle_type_def"] @@ -46,14 +45,14 @@ class MarketCapPairList(IPairList): is_demo=_coingecko_config.get("is_demo", True), ) - if self._category: + if self._categories: categories = self._coingecko.get_coins_categories_list() - category_ids = [cat["category_id"] for cat in categories] + category_ids = [cat['category_id'] for cat in categories] - if self._category not in category_ids: - raise OperationalException( - f"category not in coingecko category list you can choose from {category_ids}" - ) + for category in self._categories: + if category not in category_ids: + raise OperationalException( + f"category not in coingecko category list you can choose from {category_ids}") if self._max_rank > 250: raise OperationalException("This filter only support marketcap rank up to 250.") @@ -95,11 +94,11 @@ class MarketCapPairList(IPairList): "description": "Max rank of assets", "help": "Maximum rank of assets to use from the pairlist", }, - "category": { - "type": "string", - "default": None, - "description": "The Category", - "help": "Th Category of the coin e.g layer-1 default None", + "categories": { + "type": "list", + "default": [], + "description": "The Categories to be set", + "help": "The Category of the coin e.g layer-1 default [] (https://www.coingecko.com/en/categories)", }, "refresh_period": { "type": "number", @@ -148,16 +147,32 @@ class MarketCapPairList(IPairList): """ marketcap_list = self._marketcap_cache.get("marketcap") + default_kwargs = { + "vs_currency": "usd", + "order": "market_cap_desc", + "per_page": "250", + "page": "1", + "sparkline": "false", + "locale": "en", + } + if marketcap_list is None: - data = self._coingecko.get_coins_markets( - vs_currency="usd", - order="market_cap_desc", - per_page="250", - page="1", - sparkline="false", - locale="en", - **({"category": self._category} if self._category else {}), - ) + data = [] + + if not self._categories: + data = self._coingecko.get_coins_markets( + **default_kwargs + ) + else: + for category in self._categories: + category_data = self._coingecko.get_coins_markets( + **default_kwargs, + **({"category": category} if category else {}) + ) + data += category_data + + data.sort(key=lambda d: float(d['market_cap'] or 0.0), reverse=True) + if data: marketcap_list = [row["symbol"] for row in data] self._marketcap_cache["marketcap"] = marketcap_list @@ -170,11 +185,11 @@ class MarketCapPairList(IPairList): if market == "futures": pair_format += f":{self._stake_currency.upper()}" - top_marketcap = marketcap_list[: self._max_rank :] + top_marketcap = marketcap_list[: self._max_rank:] for mc_pair in top_marketcap: test_pair = f"{mc_pair.upper()}/{pair_format}" - if test_pair in pairlist: + if test_pair in pairlist and test_pair not in filtered_pairlist: filtered_pairlist.append(test_pair) if len(filtered_pairlist) == self._number_assets: break From b00ca5470741166f74a03642af5c720fa8c9617e Mon Sep 17 00:00:00 2001 From: "Jakub Werner (jakubikan)" Date: Wed, 25 Sep 2024 21:20:35 +0200 Subject: [PATCH 169/187] adding docu --- docs/includes/pairlists.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/includes/pairlists.md b/docs/includes/pairlists.md index 804190e24..fe6a11bc1 100644 --- a/docs/includes/pairlists.md +++ b/docs/includes/pairlists.md @@ -360,7 +360,8 @@ The optional `bearer_token` will be included in the requests Authorization Heade "method": "MarketCapPairList", "number_assets": 20, "max_rank": 50, - "refresh_period": 86400 + "refresh_period": 86400, + "categories": ['layer-1'] } ] ``` @@ -369,6 +370,8 @@ The optional `bearer_token` will be included in the requests Authorization Heade `refresh_period` setting defines the period (in seconds) at which the marketcap rank data will be refreshed. Defaults to 86,400s (1 day). The pairlist cache (`refresh_period`) is applicable on both generating pairlists (first position in the list) and filtering instances (not the first position in the list). +`categories` settings this defines takes the list of coins from a category on coingecko. (https://www.coingecko.com/en/categories). Defaults to []. If you choose a wrong category string the Plugin will print the categories you that you can choose from on coingecko. Category is the id of the category so e.g. https://www.coingecko.com/en/categories/layer-1 -> `layer-1` would be the category. You can pass in a list `["layer-1", "meme-token"]` is possible if you choose to. + #### AgeFilter Removes pairs that have been listed on the exchange for less than `min_days_listed` days (defaults to `10`) or more than `max_days_listed` days (defaults `None` mean infinity). From 514558796b863543ca0161dc89aa5933208d47a2 Mon Sep 17 00:00:00 2001 From: "Jakub Werner (jakubikan)" Date: Wed, 25 Sep 2024 21:21:56 +0200 Subject: [PATCH 170/187] double quotes --- docs/includes/pairlists.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/includes/pairlists.md b/docs/includes/pairlists.md index fe6a11bc1..4a797930b 100644 --- a/docs/includes/pairlists.md +++ b/docs/includes/pairlists.md @@ -361,7 +361,7 @@ The optional `bearer_token` will be included in the requests Authorization Heade "number_assets": 20, "max_rank": 50, "refresh_period": 86400, - "categories": ['layer-1'] + "categories": ["layer-1"] } ] ``` From 8aefae3aff3faa264e4c07215824773e326d881d Mon Sep 17 00:00:00 2001 From: "Jakub Werner (jakubikan)" Date: Wed, 25 Sep 2024 21:22:40 +0200 Subject: [PATCH 171/187] format --- freqtrade/plugins/pairlist/IPairList.py | 17 +++++++++-------- freqtrade/plugins/pairlist/MarketCapPairList.py | 16 +++++++--------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/freqtrade/plugins/pairlist/IPairList.py b/freqtrade/plugins/pairlist/IPairList.py index 7be86df7e..4e566f899 100644 --- a/freqtrade/plugins/pairlist/IPairList.py +++ b/freqtrade/plugins/pairlist/IPairList.py @@ -38,6 +38,7 @@ class __OptionPairlistParameter(__PairlistParameterBase): default: Union[str, None] options: List[str] + class __ListPairListParamenter(__PairlistParameterBase): type: Literal["list"] default: Union[List[str], None] @@ -54,7 +55,7 @@ PairlistParameter = Union[ __StringPairlistParameter, __OptionPairlistParameter, __BoolPairlistParameter, - __ListPairListParamenter + __ListPairListParamenter, ] @@ -74,12 +75,12 @@ class IPairList(LoggingMixin, ABC): supports_backtesting: SupportsBacktesting = SupportsBacktesting.NO def __init__( - self, - exchange: Exchange, - pairlistmanager, - config: Config, - pairlistconfig: Dict[str, Any], - pairlist_pos: int, + self, + exchange: Exchange, + pairlistmanager, + config: Config, + pairlistconfig: Dict[str, Any], + pairlist_pos: int, ) -> None: """ :param exchange: Exchange instance @@ -219,7 +220,7 @@ class IPairList(LoggingMixin, ABC): return self._pairlistmanager.verify_blacklist(pairlist, logmethod) def verify_whitelist( - self, pairlist: List[str], logmethod, keep_invalid: bool = False + self, pairlist: List[str], logmethod, keep_invalid: bool = False ) -> List[str]: """ Proxy method to verify_whitelist for easy access for child classes. diff --git a/freqtrade/plugins/pairlist/MarketCapPairList.py b/freqtrade/plugins/pairlist/MarketCapPairList.py index b9461589d..922d5235c 100644 --- a/freqtrade/plugins/pairlist/MarketCapPairList.py +++ b/freqtrade/plugins/pairlist/MarketCapPairList.py @@ -47,12 +47,13 @@ class MarketCapPairList(IPairList): if self._categories: categories = self._coingecko.get_coins_categories_list() - category_ids = [cat['category_id'] for cat in categories] + category_ids = [cat["category_id"] for cat in categories] for category in self._categories: if category not in category_ids: raise OperationalException( - f"category not in coingecko category list you can choose from {category_ids}") + f"category not in coingecko category list you can choose from {category_ids}" + ) if self._max_rank > 250: raise OperationalException("This filter only support marketcap rank up to 250.") @@ -160,18 +161,15 @@ class MarketCapPairList(IPairList): data = [] if not self._categories: - data = self._coingecko.get_coins_markets( - **default_kwargs - ) + data = self._coingecko.get_coins_markets(**default_kwargs) else: for category in self._categories: category_data = self._coingecko.get_coins_markets( - **default_kwargs, - **({"category": category} if category else {}) + **default_kwargs, **({"category": category} if category else {}) ) data += category_data - data.sort(key=lambda d: float(d['market_cap'] or 0.0), reverse=True) + data.sort(key=lambda d: float(d["market_cap"] or 0.0), reverse=True) if data: marketcap_list = [row["symbol"] for row in data] @@ -185,7 +183,7 @@ class MarketCapPairList(IPairList): if market == "futures": pair_format += f":{self._stake_currency.upper()}" - top_marketcap = marketcap_list[: self._max_rank:] + top_marketcap = marketcap_list[: self._max_rank :] for mc_pair in top_marketcap: test_pair = f"{mc_pair.upper()}/{pair_format}" From 1d66ef2f2da240e1e07c9a37371cf6f947a7733f Mon Sep 17 00:00:00 2001 From: xmatthias <5024695+xmatthias@users.noreply.github.com> Date: Thu, 26 Sep 2024 03:17:36 +0000 Subject: [PATCH 172/187] chore: update pre-commit hooks --- .../exchange/binance_leverage_tiers.json | 1458 +++++++++++++---- 1 file changed, 1126 insertions(+), 332 deletions(-) diff --git a/freqtrade/exchange/binance_leverage_tiers.json b/freqtrade/exchange/binance_leverage_tiers.json index 8b0882d64..c0eac5b0e 100644 --- a/freqtrade/exchange/binance_leverage_tiers.json +++ b/freqtrade/exchange/binance_leverage_tiers.json @@ -1628,13 +1628,13 @@ "tier": 3.0, "currency": "USDT", "minNotional": 10000.0, - "maxNotional": 20000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "notionalCap": "20000", + "notionalCap": "50000", "notionalFloor": "10000", "maintMarginRatio": "0.02", "cum": "75.0" @@ -1643,97 +1643,97 @@ { "tier": 4.0, "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 40000.0, + "minNotional": 50000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": "4", "initialLeverage": "20", - "notionalCap": "40000", - "notionalFloor": "20000", + "notionalCap": "100000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", - "cum": "175.0" + "cum": "325.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 40000.0, - "maxNotional": 200000.0, + "minNotional": 100000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "200000", - "notionalFloor": "40000", + "notionalCap": "500000", + "notionalFloor": "100000", "maintMarginRatio": "0.05", - "cum": "1175.0" + "cum": "2825.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 400000.0, + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "400000", - "notionalFloor": "200000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.1", - "cum": "11175.0" + "cum": "27825.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 400000.0, - "maxNotional": 500000.0, + "minNotional": 1000000.0, + "maxNotional": 1250000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "500000", - "notionalFloor": "400000", + "notionalCap": "1250000", + "notionalFloor": "1000000", "maintMarginRatio": "0.125", - "cum": "21175.0" + "cum": "52825.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 1000000.0, + "minNotional": 1250000.0, + "maxNotional": 2500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "1000000", - "notionalFloor": "500000", + "notionalCap": "2500000", + "notionalFloor": "1250000", "maintMarginRatio": "0.25", - "cum": "83675.0" + "cum": "209075.0" } }, { "tier": 9.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "minNotional": 2500000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "2000000", - "notionalFloor": "1000000", + "notionalCap": "5000000", + "notionalFloor": "2500000", "maintMarginRatio": "0.5", - "cum": "333675.0" + "cum": "834075.0" } } ], @@ -10301,6 +10301,152 @@ } } ], + "CATI/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "10000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, + "info": { + "bracket": "2", + "initialLeverage": "50", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", + "cum": "50.0" + } + }, + { + "tier": 3.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "100000", + "notionalFloor": "20000", + "maintMarginRatio": "0.02", + "cum": "150.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "200000", + "notionalFloor": "100000", + "maintMarginRatio": "0.025", + "cum": "650.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "1000000", + "notionalFloor": "200000", + "maintMarginRatio": "0.05", + "cum": "5650.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.1", + "cum": "55650.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 2500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "2500000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.125", + "cum": "105650.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 2500000.0, + "maxNotional": 5000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "5000000", + "notionalFloor": "2500000", + "maintMarginRatio": "0.25", + "cum": "418150.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "10000000", + "notionalFloor": "5000000", + "maintMarginRatio": "0.5", + "cum": "1668150.0" + } + } + ], "CELO/USDT:USDT": [ { "tier": 1.0, @@ -11006,112 +11152,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 20.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "20", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.02", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 15.0, + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "15", - "notionalCap": "25000", - "notionalFloor": "5000", - "maintMarginRatio": "0.025", - "cum": "25.0" + "initialLeverage": "50", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 200000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 20000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "10", - "notionalCap": "200000", - "notionalFloor": "25000", - "maintMarginRatio": "0.05", - "cum": "650.0" + "initialLeverage": "25", + "notionalCap": "100000", + "notionalFloor": "20000", + "maintMarginRatio": "0.02", + "cum": "150.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 500000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 100000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "5", - "notionalCap": "500000", - "notionalFloor": "200000", - "maintMarginRatio": "0.1", - "cum": "10650.0" + "initialLeverage": "20", + "notionalCap": "200000", + "notionalFloor": "100000", + "maintMarginRatio": "0.025", + "cum": "650.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 500000.0, + "minNotional": 200000.0, "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "4", + "initialLeverage": "10", "notionalCap": "1000000", - "notionalFloor": "500000", - "maintMarginRatio": "0.125", - "cum": "23150.0" + "notionalFloor": "200000", + "maintMarginRatio": "0.05", + "cum": "5650.0" } }, { "tier": 6.0, "currency": "USDT", "minNotional": 1000000.0, - "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "2", - "notionalCap": "3000000", + "initialLeverage": "5", + "notionalCap": "2000000", "notionalFloor": "1000000", - "maintMarginRatio": "0.25", - "cum": "148150.0" + "maintMarginRatio": "0.1", + "cum": "55650.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 3000000.0, + "minNotional": 2000000.0, + "maxNotional": 2500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "2500000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.125", + "cum": "105650.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 2500000.0, "maxNotional": 5000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "5000000", + "notionalFloor": "2500000", + "maintMarginRatio": "0.25", + "cum": "418150.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "7", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "5000000", - "notionalFloor": "3000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.5", - "cum": "898150.0" + "cum": "1668150.0" } } ], @@ -16267,6 +16445,152 @@ } } ], + "FIDA/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "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, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "40000", + "notionalFloor": "20000", + "maintMarginRatio": "0.025", + "cum": "175.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.05", + "cum": "1175.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "11175.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.125", + "cum": "21175.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.25", + "cum": "83675.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "333675.0" + } + } + ], "FIL/USDC:USDC": [ { "tier": 1.0, @@ -16575,6 +16899,152 @@ } } ], + "FIO/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "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, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "40000", + "notionalFloor": "20000", + "maintMarginRatio": "0.025", + "cum": "175.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.05", + "cum": "1175.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "11175.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.125", + "cum": "21175.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.25", + "cum": "83675.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "333675.0" + } + } + ], "FLM/USDT:USDT": [ { "tier": 1.0, @@ -17697,6 +18167,152 @@ } } ], + "GHST/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "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, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "40000", + "notionalFloor": "20000", + "maintMarginRatio": "0.025", + "cum": "175.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.05", + "cum": "1175.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "11175.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.125", + "cum": "21175.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.25", + "cum": "83675.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "333675.0" + } + } + ], "GLM/USDT:USDT": [ { "tier": 1.0, @@ -22739,6 +23355,152 @@ } } ], + "LOKA/USDT:USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "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, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 20000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "20000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 20000.0, + "maxNotional": 40000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "40000", + "notionalFloor": "20000", + "maintMarginRatio": "0.025", + "cum": "175.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 40000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "40000", + "maintMarginRatio": "0.05", + "cum": "1175.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "400000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "11175.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 400000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.125", + "cum": "21175.0" + } + }, + { + "tier": 8.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.25", + "cum": "83675.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "333675.0" + } + } + ], "LOOM/USDT:USDT": [ { "tier": 1.0, @@ -25932,13 +26694,13 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.01, "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "notionalCap": "5000", + "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" @@ -25947,129 +26709,129 @@ { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 10000.0, + "minNotional": 10000.0, + "maxNotional": 40000.0, "maintenanceMarginRate": 0.015, "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "notionalCap": "10000", - "notionalFloor": "5000", + "notionalCap": "40000", + "notionalFloor": "10000", "maintMarginRatio": "0.015", - "cum": "25.0" + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 20000.0, + "minNotional": 40000.0, + "maxNotional": 200000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "notionalCap": "20000", - "notionalFloor": "10000", + "notionalCap": "200000", + "notionalFloor": "40000", "maintMarginRatio": "0.02", - "cum": "75.0" + "cum": "250.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 40000.0, + "minNotional": 200000.0, + "maxNotional": 400000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": "4", "initialLeverage": "20", - "notionalCap": "40000", - "notionalFloor": "20000", + "notionalCap": "400000", + "notionalFloor": "200000", "maintMarginRatio": "0.025", - "cum": "175.0" + "cum": "1250.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 40000.0, - "maxNotional": 200000.0, + "minNotional": 400000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "200000", - "notionalFloor": "40000", + "notionalCap": "2000000", + "notionalFloor": "400000", "maintMarginRatio": "0.05", - "cum": "1175.0" + "cum": "11250.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 400000.0, + "minNotional": 2000000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "400000", - "notionalFloor": "200000", + "notionalCap": "4000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.1", - "cum": "11175.0" + "cum": "111250.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 400000.0, - "maxNotional": 500000.0, + "minNotional": 4000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "500000", - "notionalFloor": "400000", + "notionalCap": "5000000", + "notionalFloor": "4000000", "maintMarginRatio": "0.125", - "cum": "21175.0" + "cum": "211250.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 1000000.0, + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "1000000", - "notionalFloor": "500000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.25", - "cum": "83675.0" + "cum": "836250.0" } }, { "tier": 9.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "2000000", - "notionalFloor": "1000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.5", - "cum": "333675.0" + "cum": "3336250.0" } } ], @@ -29930,13 +30692,13 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.01, "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "notionalCap": "5000", + "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" @@ -29945,129 +30707,129 @@ { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 10000.0, + "minNotional": 10000.0, + "maxNotional": 20000.0, "maintenanceMarginRate": 0.015, "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "notionalCap": "10000", - "notionalFloor": "5000", + "notionalCap": "20000", + "notionalFloor": "10000", "maintMarginRatio": "0.015", - "cum": "25.0" + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 20000.0, + "minNotional": 20000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "notionalCap": "20000", - "notionalFloor": "10000", + "notionalCap": "100000", + "notionalFloor": "20000", "maintMarginRatio": "0.02", - "cum": "75.0" + "cum": "150.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 40000.0, + "minNotional": 100000.0, + "maxNotional": 200000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": "4", "initialLeverage": "20", - "notionalCap": "40000", - "notionalFloor": "20000", + "notionalCap": "200000", + "notionalFloor": "100000", "maintMarginRatio": "0.025", - "cum": "175.0" + "cum": "650.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 40000.0, - "maxNotional": 200000.0, + "minNotional": 200000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "200000", - "notionalFloor": "40000", + "notionalCap": "1000000", + "notionalFloor": "200000", "maintMarginRatio": "0.05", - "cum": "1175.0" + "cum": "5650.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 400000.0, + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "400000", - "notionalFloor": "200000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", - "cum": "11175.0" + "cum": "55650.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 400000.0, - "maxNotional": 500000.0, + "minNotional": 2000000.0, + "maxNotional": 2500000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "500000", - "notionalFloor": "400000", + "notionalCap": "2500000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", - "cum": "21175.0" + "cum": "105650.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 1000000.0, + "minNotional": 2500000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "1000000", - "notionalFloor": "500000", + "notionalCap": "5000000", + "notionalFloor": "2500000", "maintMarginRatio": "0.25", - "cum": "83675.0" + "cum": "418150.0" } }, { "tier": 9.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "2000000", - "notionalFloor": "1000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.5", - "cum": "333675.0" + "cum": "1668150.0" } } ], @@ -32760,128 +33522,144 @@ "tier": 1.0, "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, "info": { "bracket": "1", - "initialLeverage": "50", - "notionalCap": "5000", + "initialLeverage": "75", + "notionalCap": "10000", "notionalFloor": "0", - "maintMarginRatio": "0.015", + "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2.0, "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", - "notionalCap": "25000", - "notionalFloor": "5000", - "maintMarginRatio": "0.02", - "cum": "25.0" + "initialLeverage": "50", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.015", + "cum": "50.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 50000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 30000.0, + "maxNotional": 150000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "50000", - "notionalFloor": "25000", - "maintMarginRatio": "0.025", - "cum": "150.0" + "initialLeverage": "25", + "notionalCap": "150000", + "notionalFloor": "30000", + "maintMarginRatio": "0.02", + "cum": "200.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 50000.0, - "maxNotional": 500000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 150000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "4", - "initialLeverage": "10", - "notionalCap": "500000", - "notionalFloor": "50000", - "maintMarginRatio": "0.05", - "cum": "1400.0" + "initialLeverage": "20", + "notionalCap": "300000", + "notionalFloor": "150000", + "maintMarginRatio": "0.025", + "cum": "950.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 300000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "1000000", - "notionalFloor": "500000", - "maintMarginRatio": "0.1", - "cum": "26400.0" + "initialLeverage": "10", + "notionalCap": "1500000", + "notionalFloor": "300000", + "maintMarginRatio": "0.05", + "cum": "8450.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 1250000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "1250000", - "notionalFloor": "1000000", - "maintMarginRatio": "0.125", - "cum": "51400.0" + "initialLeverage": "5", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.1", + "cum": "83450.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 1250000.0, - "maxNotional": 2500000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 3000000.0, + "maxNotional": 3750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "2500000", - "notionalFloor": "1250000", - "maintMarginRatio": "0.25", - "cum": "207650.0" + "initialLeverage": "4", + "notionalCap": "3750000", + "notionalFloor": "3000000", + "maintMarginRatio": "0.125", + "cum": "158450.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 2500000.0, - "maxNotional": 5000000.0, + "minNotional": 3750000.0, + "maxNotional": 7500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "7500000", + "notionalFloor": "3750000", + "maintMarginRatio": "0.25", + "cum": "627200.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 7500000.0, + "maxNotional": 15000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "5000000", - "notionalFloor": "2500000", + "notionalCap": "15000000", + "notionalFloor": "7500000", "maintMarginRatio": "0.5", - "cum": "832650.0" + "cum": "2502200.0" } } ], @@ -37915,14 +38693,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" } }, @@ -37930,112 +38708,128 @@ "tier": 2.0, "currency": "USDT", "minNotional": 5000.0, - "maxNotional": 20000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, "info": { "bracket": "2", - "initialLeverage": "25", - "notionalCap": "20000", + "initialLeverage": "50", + "notionalCap": "10000", "notionalFloor": "5000", - "maintMarginRatio": "0.02", + "maintMarginRatio": "0.015", "cum": "25.0" } }, { "tier": 3.0, "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "minNotional": 10000.0, + "maxNotional": 50000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "25000", - "notionalFloor": "20000", - "maintMarginRatio": "0.025", - "cum": "125.0" + "initialLeverage": "25", + "notionalCap": "50000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 25000.0, - "maxNotional": 200000.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": "200000", - "notionalFloor": "25000", - "maintMarginRatio": "0.05", - "cum": "750.0" + "initialLeverage": "20", + "notionalCap": "100000", + "notionalFloor": "50000", + "maintMarginRatio": "0.025", + "cum": "325.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 400000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 100000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "5", - "initialLeverage": "5", - "notionalCap": "400000", - "notionalFloor": "200000", - "maintMarginRatio": "0.1", - "cum": "10750.0" + "initialLeverage": "10", + "notionalCap": "500000", + "notionalFloor": "100000", + "maintMarginRatio": "0.05", + "cum": "2825.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 400000.0, - "maxNotional": 500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 500000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "6", - "initialLeverage": "4", - "notionalCap": "500000", - "notionalFloor": "400000", - "maintMarginRatio": "0.125", - "cum": "20750.0" + "initialLeverage": "5", + "notionalCap": "1000000", + "notionalFloor": "500000", + "maintMarginRatio": "0.1", + "cum": "27825.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, + "minNotional": 1000000.0, + "maxNotional": 1250000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, "info": { "bracket": "7", - "initialLeverage": "2", - "notionalCap": "1000000", - "notionalFloor": "500000", - "maintMarginRatio": "0.25", - "cum": "83250.0" + "initialLeverage": "4", + "notionalCap": "1250000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.125", + "cum": "52825.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "minNotional": 1250000.0, + "maxNotional": 2500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "2500000", + "notionalFloor": "1250000", + "maintMarginRatio": "0.25", + "cum": "209075.0" + } + }, + { + "tier": 9.0, + "currency": "USDT", + "minNotional": 2500000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "8", + "bracket": "9", "initialLeverage": "1", - "notionalCap": "2000000", - "notionalFloor": "1000000", + "notionalCap": "5000000", + "notionalFloor": "2500000", "maintMarginRatio": "0.5", - "cum": "333250.0" + "cum": "834075.0" } } ], @@ -38792,13 +39586,13 @@ "tier": 2.0, "currency": "USDT", "minNotional": 5000.0, - "maxNotional": 10000.0, + "maxNotional": 16000.0, "maintenanceMarginRate": 0.015, "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "notionalCap": "10000", + "notionalCap": "16000", "notionalFloor": "5000", "maintMarginRatio": "0.015", "cum": "25.0" @@ -38807,113 +39601,113 @@ { "tier": 3.0, "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 20000.0, + "minNotional": 16000.0, + "maxNotional": 80000.0, "maintenanceMarginRate": 0.02, "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "notionalCap": "20000", - "notionalFloor": "10000", + "notionalCap": "80000", + "notionalFloor": "16000", "maintMarginRatio": "0.02", - "cum": "75.0" + "cum": "105.0" } }, { "tier": 4.0, "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 40000.0, + "minNotional": 80000.0, + "maxNotional": 160000.0, "maintenanceMarginRate": 0.025, "maxLeverage": 20.0, "info": { "bracket": "4", "initialLeverage": "20", - "notionalCap": "40000", - "notionalFloor": "20000", + "notionalCap": "160000", + "notionalFloor": "80000", "maintMarginRatio": "0.025", - "cum": "175.0" + "cum": "505.0" } }, { "tier": 5.0, "currency": "USDT", - "minNotional": 40000.0, - "maxNotional": 200000.0, + "minNotional": 160000.0, + "maxNotional": 800000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "200000", - "notionalFloor": "40000", + "notionalCap": "800000", + "notionalFloor": "160000", "maintMarginRatio": "0.05", - "cum": "1175.0" + "cum": "4505.0" } }, { "tier": 6.0, "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 400000.0, + "minNotional": 800000.0, + "maxNotional": 1600000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "400000", - "notionalFloor": "200000", + "notionalCap": "1600000", + "notionalFloor": "800000", "maintMarginRatio": "0.1", - "cum": "11175.0" + "cum": "44505.0" } }, { "tier": 7.0, "currency": "USDT", - "minNotional": 400000.0, - "maxNotional": 500000.0, + "minNotional": 1600000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "500000", - "notionalFloor": "400000", + "notionalCap": "2000000", + "notionalFloor": "1600000", "maintMarginRatio": "0.125", - "cum": "21175.0" + "cum": "84505.0" } }, { "tier": 8.0, "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 1000000.0, + "minNotional": 2000000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "1000000", - "notionalFloor": "500000", + "notionalCap": "4000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.25", - "cum": "83675.0" + "cum": "334505.0" } }, { "tier": 9.0, "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "minNotional": 4000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "2000000", - "notionalFloor": "1000000", + "notionalCap": "8000000", + "notionalFloor": "4000000", "maintMarginRatio": "0.5", - "cum": "333675.0" + "cum": "1334505.0" } } ], From 123909cdace327fd42d98ed886768a2411309299 Mon Sep 17 00:00:00 2001 From: Robert Caulk Date: Thu, 26 Sep 2024 16:31:43 +0200 Subject: [PATCH 173/187] fix: Update BasePyTorchRegressor.py --- freqtrade/freqai/base_models/BasePyTorchRegressor.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/freqtrade/freqai/base_models/BasePyTorchRegressor.py b/freqtrade/freqai/base_models/BasePyTorchRegressor.py index 9b429db23..5f53e7d07 100644 --- a/freqtrade/freqai/base_models/BasePyTorchRegressor.py +++ b/freqtrade/freqai/base_models/BasePyTorchRegressor.py @@ -86,9 +86,6 @@ class BasePyTorchRegressor(BasePyTorchModel): dk.feature_pipeline = self.define_data_pipeline(threads=dk.thread_count) dk.label_pipeline = self.define_label_pipeline(threads=dk.thread_count) - dd["train_labels"], _, _ = dk.label_pipeline.fit_transform(dd["train_labels"]) - dd["test_labels"], _, _ = dk.label_pipeline.transform(dd["test_labels"]) - (dd["train_features"], dd["train_labels"], dd["train_weights"]) = ( dk.feature_pipeline.fit_transform( dd["train_features"], dd["train_labels"], dd["train_weights"] From d18d8cf0ea532fc95f838556f1fbd74f0aec30a2 Mon Sep 17 00:00:00 2001 From: Robert Caulk Date: Thu, 26 Sep 2024 17:54:14 +0200 Subject: [PATCH 174/187] freqai_info -> ft_params --- .../freqai/prediction_models/PyTorchTransformerRegressor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqai/prediction_models/PyTorchTransformerRegressor.py b/freqtrade/freqai/prediction_models/PyTorchTransformerRegressor.py index 27b7de832..2d60d68cf 100644 --- a/freqtrade/freqai/prediction_models/PyTorchTransformerRegressor.py +++ b/freqtrade/freqai/prediction_models/PyTorchTransformerRegressor.py @@ -141,7 +141,7 @@ class PyTorchTransformerRegressor(BasePyTorchRegressor): pred_df = pd.DataFrame(yb.detach().numpy(), columns=dk.label_list) pred_df, _, _ = dk.label_pipeline.inverse_transform(pred_df) - if self.freqai_info.get("DI_threshold", 0) > 0: + if self.ft_params.get("DI_threshold", 0) > 0: dk.DI_values = dk.feature_pipeline["di"].di_values else: dk.DI_values = np.zeros(outliers.shape[0]) From 31680f3b590b550a402db305da5fbbcf88775ce7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 26 Sep 2024 19:31:43 +0200 Subject: [PATCH 175/187] chore: Improve UI wording --- freqtrade/plugins/pairlist/MarketCapPairList.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/freqtrade/plugins/pairlist/MarketCapPairList.py b/freqtrade/plugins/pairlist/MarketCapPairList.py index 922d5235c..5542cfaf0 100644 --- a/freqtrade/plugins/pairlist/MarketCapPairList.py +++ b/freqtrade/plugins/pairlist/MarketCapPairList.py @@ -14,6 +14,7 @@ from freqtrade.exchange.exchange_types import Tickers from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting from freqtrade.util.coin_gecko import FtCoinGeckoApi + logger = logging.getLogger(__name__) @@ -98,8 +99,11 @@ class MarketCapPairList(IPairList): "categories": { "type": "list", "default": [], - "description": "The Categories to be set", - "help": "The Category of the coin e.g layer-1 default [] (https://www.coingecko.com/en/categories)", + "description": "Coin Categories", + "help": ( + "The Category of the coin e.g layer-1 default [] " + "(https://www.coingecko.com/en/categories)" + ), }, "refresh_period": { "type": "number", From 6837196e4451e2409ececfdf5300ed7449b0101f Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 26 Sep 2024 19:59:23 +0200 Subject: [PATCH 176/187] fix: treat marketcap as optional parameter --- freqtrade/plugins/pairlist/MarketCapPairList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/plugins/pairlist/MarketCapPairList.py b/freqtrade/plugins/pairlist/MarketCapPairList.py index 5542cfaf0..35b1cba8f 100644 --- a/freqtrade/plugins/pairlist/MarketCapPairList.py +++ b/freqtrade/plugins/pairlist/MarketCapPairList.py @@ -173,7 +173,7 @@ class MarketCapPairList(IPairList): ) data += category_data - data.sort(key=lambda d: float(d["market_cap"] or 0.0), reverse=True) + data.sort(key=lambda d: float(d.get("market_cap") or 0.0), reverse=True) if data: marketcap_list = [row["symbol"] for row in data] From 7b93b55b784a8b1fef1e10490336f904ad52895f Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 26 Sep 2024 20:07:41 +0200 Subject: [PATCH 177/187] docs: rephrase categories docs and add performance warning --- docs/includes/pairlists.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/includes/pairlists.md b/docs/includes/pairlists.md index 4a797930b..8d79a7bc1 100644 --- a/docs/includes/pairlists.md +++ b/docs/includes/pairlists.md @@ -368,9 +368,13 @@ The optional `bearer_token` will be included in the requests Authorization Heade `number_assets` defines the maximum number of pairs returned by the pairlist. `max_rank` will determine the maximum rank used in creating/filtering the pairlist. It's expected that some coins within the top `max_rank` marketcap will not be included in the resulting pairlist since not all pairs will have active trading pairs in your preferred market/stake/exchange combination. -`refresh_period` setting defines the period (in seconds) at which the marketcap rank data will be refreshed. Defaults to 86,400s (1 day). The pairlist cache (`refresh_period`) is applicable on both generating pairlists (first position in the list) and filtering instances (not the first position in the list). +The `refresh_period` setting defines the interval (in seconds) at which the marketcap rank data will be refreshed. The default is 86,400 seconds (1 day). The pairlist cache (`refresh_period`) applies to both generating pairlists (when in the first position in the list) and filtering instances (when not in the first position in the list). -`categories` settings this defines takes the list of coins from a category on coingecko. (https://www.coingecko.com/en/categories). Defaults to []. If you choose a wrong category string the Plugin will print the categories you that you can choose from on coingecko. Category is the id of the category so e.g. https://www.coingecko.com/en/categories/layer-1 -> `layer-1` would be the category. You can pass in a list `["layer-1", "meme-token"]` is possible if you choose to. +The `categories` setting specifies the [coingecko categories](https://www.coingecko.com/en/categories) from which to select coins from. The default is an empty list `[]`, meaning no category filtering is applied. +If an incorrect category string is chosen, the plugin will print the available categories from CoinGecko and fail. The category should be the ID of the category, for example, for `https://www.coingecko.com/en/categories/layer-1`, the category ID would be `layer-1`. You can pass multiple categories such as `["layer-1", "meme-token"]` to select from several categories. + +!!! Warning "Many categories" + Each added category corresponds to one API call to CoinGecko. The more categories you add, the longer the pairlist generation will take, potentially causing rate limit issues. #### AgeFilter From cb36f2844e87a7566aad10dac40338f6a507932d Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 26 Sep 2024 20:21:27 +0200 Subject: [PATCH 178/187] chore: Improve "wrong category" error. --- freqtrade/plugins/pairlist/MarketCapPairList.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/plugins/pairlist/MarketCapPairList.py b/freqtrade/plugins/pairlist/MarketCapPairList.py index 35b1cba8f..37c8c3c8b 100644 --- a/freqtrade/plugins/pairlist/MarketCapPairList.py +++ b/freqtrade/plugins/pairlist/MarketCapPairList.py @@ -53,7 +53,8 @@ class MarketCapPairList(IPairList): for category in self._categories: if category not in category_ids: raise OperationalException( - f"category not in coingecko category list you can choose from {category_ids}" + f"category {category} not in coingecko category list. " + f"You can choose from {category_ids}" ) if self._max_rank > 250: From 1ed5a37280aa6cb35ffffc6c8aae42b6111f1a18 Mon Sep 17 00:00:00 2001 From: "Jakub W." Date: Thu, 26 Sep 2024 23:38:17 +0200 Subject: [PATCH 179/187] Update freqtrade/plugins/pairlist/IPairList.py Co-authored-by: Matthias --- freqtrade/plugins/pairlist/IPairList.py | 1 - 1 file changed, 1 deletion(-) diff --git a/freqtrade/plugins/pairlist/IPairList.py b/freqtrade/plugins/pairlist/IPairList.py index 4e566f899..6a4ad32fb 100644 --- a/freqtrade/plugins/pairlist/IPairList.py +++ b/freqtrade/plugins/pairlist/IPairList.py @@ -42,7 +42,6 @@ class __OptionPairlistParameter(__PairlistParameterBase): class __ListPairListParamenter(__PairlistParameterBase): type: Literal["list"] default: Union[List[str], None] - options: List[str] class __BoolPairlistParameter(__PairlistParameterBase): From 3dc92b42fe90c8de7da843d73edae741a3ae01f7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Sep 2024 09:54:49 +0200 Subject: [PATCH 180/187] fix: Check if sub-directories are actually directories and fail otherwise. This will explicitly fail if a file (or an invalid symlink) is present. Freqtrade requires these files to be valid files - so failing here is correct behavior. closes #10720 --- freqtrade/configuration/directory_operations.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/freqtrade/configuration/directory_operations.py b/freqtrade/configuration/directory_operations.py index 3e6ed92ed..a904e441c 100644 --- a/freqtrade/configuration/directory_operations.py +++ b/freqtrade/configuration/directory_operations.py @@ -82,6 +82,11 @@ def create_userdata_dir(directory: str, create_dir: bool = False) -> Path: for f in sub_dirs: subfolder = folder / f if not subfolder.is_dir(): + if subfolder.exists(follow_symlinks=False): + raise OperationalException( + f"File `{subfolder}` exists already and is not a directory. " + "Freqtrade requires this to be a directory." + ) subfolder.mkdir(parents=False) return folder From 8c097a81ea55855ad88d7afdc2499c0044b934e7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Sep 2024 10:10:07 +0200 Subject: [PATCH 181/187] tests: enhance test for marketcappairlist --- tests/plugins/test_pairlist.py | 53 ++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/tests/plugins/test_pairlist.py b/tests/plugins/test_pairlist.py index 37ebdc58b..79ca8dc0c 100644 --- a/tests/plugins/test_pairlist.py +++ b/tests/plugins/test_pairlist.py @@ -2212,7 +2212,7 @@ def test_FullTradesFilter(mocker, default_conf_usdt, fee, caplog) -> None: @pytest.mark.parametrize( - "pairlists,trade_mode,result", + "pairlists,trade_mode,result,coin_market_calls", [ ( [ @@ -2222,6 +2222,7 @@ def test_FullTradesFilter(mocker, default_conf_usdt, fee, caplog) -> None: ], "spot", ["BTC/USDT", "ETH/USDT"], + 1, ), ( [ @@ -2231,6 +2232,7 @@ def test_FullTradesFilter(mocker, default_conf_usdt, fee, caplog) -> None: ], "spot", ["BTC/USDT", "ETH/USDT", "XRP/USDT", "ADA/USDT"], + 1, ), ( [ @@ -2240,6 +2242,7 @@ def test_FullTradesFilter(mocker, default_conf_usdt, fee, caplog) -> None: ], "spot", ["BTC/USDT", "ETH/USDT", "XRP/USDT"], + 1, ), ( [ @@ -2249,6 +2252,7 @@ def test_FullTradesFilter(mocker, default_conf_usdt, fee, caplog) -> None: ], "spot", ["BTC/USDT", "ETH/USDT", "XRP/USDT"], + 1, ), ( [ @@ -2257,6 +2261,7 @@ def test_FullTradesFilter(mocker, default_conf_usdt, fee, caplog) -> None: ], "spot", ["BTC/USDT", "ETH/USDT", "XRP/USDT"], + 1, ), ( [ @@ -2265,6 +2270,7 @@ def test_FullTradesFilter(mocker, default_conf_usdt, fee, caplog) -> None: ], "spot", ["BTC/USDT", "ETH/USDT"], + 1, ), ( [ @@ -2273,6 +2279,7 @@ def test_FullTradesFilter(mocker, default_conf_usdt, fee, caplog) -> None: ], "futures", ["ETH/USDT:USDT"], + 1, ), ( [ @@ -2281,11 +2288,34 @@ def test_FullTradesFilter(mocker, default_conf_usdt, fee, caplog) -> None: ], "futures", ["ETH/USDT:USDT", "ADA/USDT:USDT"], + 1, + ), + ( + [ + # MarketCapPairList as generator - futures, 1 category + {"method": "MarketCapPairList", "number_assets": 2, "categories": ["layer-1"]} + ], + "futures", + ["ETH/USDT:USDT", "ADA/USDT:USDT"], + ["layer-1"], + ), + ( + [ + # MarketCapPairList as generator - futures, 1 category + { + "method": "MarketCapPairList", + "number_assets": 2, + "categories": ["layer-1", "protocol"], + } + ], + "futures", + ["ETH/USDT:USDT", "ADA/USDT:USDT"], + ["layer-1", "protocol"], ), ], ) def test_MarketCapPairList_filter( - mocker, default_conf_usdt, trade_mode, markets, pairlists, result + mocker, default_conf_usdt, trade_mode, markets, pairlists, result, coin_market_calls ): test_value = [ {"symbol": "btc"}, @@ -2309,8 +2339,16 @@ def test_MarketCapPairList_filter( markets=PropertyMock(return_value=markets), exchange_has=MagicMock(return_value=True), ) - mocker.patch( + "freqtrade.plugins.pairlist.MarketCapPairList.FtCoinGeckoApi.get_coins_categories_list", + return_value=[ + {"category_id": "layer-1"}, + {"category_id": "protocol"}, + {"category_id": "defi"}, + ], + ) + + gcm_mock = mocker.patch( "freqtrade.plugins.pairlist.MarketCapPairList.FtCoinGeckoApi.get_coins_markets", return_value=test_value, ) @@ -2319,6 +2357,15 @@ def test_MarketCapPairList_filter( pm = PairListManager(exchange, default_conf_usdt) pm.refresh_pairlist() + if isinstance(coin_market_calls, int): + assert gcm_mock.call_count == coin_market_calls + else: + assert gcm_mock.call_count == len(coin_market_calls) + for call in coin_market_calls: + assert any( + "category" in c.kwargs and c.kwargs["category"] == call + for c in gcm_mock.call_args_list + ) assert pm.whitelist == result From 255ad7cac559490c1ec1835a12be7d5928ab6f92 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Sep 2024 10:14:31 +0200 Subject: [PATCH 182/187] tests: test invalid category in list --- tests/plugins/test_pairlist.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/plugins/test_pairlist.py b/tests/plugins/test_pairlist.py index 79ca8dc0c..aa1872cd1 100644 --- a/tests/plugins/test_pairlist.py +++ b/tests/plugins/test_pairlist.py @@ -2438,6 +2438,27 @@ def test_MarketCapPairList_exceptions(mocker, default_conf_usdt): ): PairListManager(exchange, default_conf_usdt) + # Test invalid coinmarkets list + mocker.patch( + "freqtrade.plugins.pairlist.MarketCapPairList.FtCoinGeckoApi.get_coins_categories_list", + return_value=[ + {"category_id": "layer-1"}, + {"category_id": "protocol"}, + {"category_id": "defi"}, + ], + ) + default_conf_usdt["pairlists"] = [ + { + "method": "MarketCapPairList", + "number_assets": 20, + "categories": ["layer-1", "defi", "layer250"], + } + ] + with pytest.raises( + OperationalException, match="category layer250 not in coingecko category list." + ): + PairListManager(exchange, default_conf_usdt) + @pytest.mark.parametrize( "pairlists,expected_error,expected_warning", From 56835f5f094ba62fbece6df0526101e6004c0b48 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Sep 2024 10:17:52 +0200 Subject: [PATCH 183/187] chore: manually check for symlink --- freqtrade/configuration/directory_operations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/configuration/directory_operations.py b/freqtrade/configuration/directory_operations.py index a904e441c..448cf1acd 100644 --- a/freqtrade/configuration/directory_operations.py +++ b/freqtrade/configuration/directory_operations.py @@ -82,7 +82,7 @@ def create_userdata_dir(directory: str, create_dir: bool = False) -> Path: for f in sub_dirs: subfolder = folder / f if not subfolder.is_dir(): - if subfolder.exists(follow_symlinks=False): + if subfolder.exists() or subfolder.is_symlink(): raise OperationalException( f"File `{subfolder}` exists already and is not a directory. " "Freqtrade requires this to be a directory." From f4d76aa36090e4ade7613a7fec908ddc08bacaf3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Sep 2024 10:18:59 +0200 Subject: [PATCH 184/187] chore: improved wording --- freqtrade/plugins/pairlist/MarketCapPairList.py | 2 +- tests/plugins/test_pairlist.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/plugins/pairlist/MarketCapPairList.py b/freqtrade/plugins/pairlist/MarketCapPairList.py index 37c8c3c8b..8bd425c32 100644 --- a/freqtrade/plugins/pairlist/MarketCapPairList.py +++ b/freqtrade/plugins/pairlist/MarketCapPairList.py @@ -53,7 +53,7 @@ class MarketCapPairList(IPairList): for category in self._categories: if category not in category_ids: raise OperationalException( - f"category {category} not in coingecko category list. " + f"Category {category} not in coingecko category list. " f"You can choose from {category_ids}" ) diff --git a/tests/plugins/test_pairlist.py b/tests/plugins/test_pairlist.py index aa1872cd1..6c58acd68 100644 --- a/tests/plugins/test_pairlist.py +++ b/tests/plugins/test_pairlist.py @@ -2455,7 +2455,7 @@ def test_MarketCapPairList_exceptions(mocker, default_conf_usdt): } ] with pytest.raises( - OperationalException, match="category layer250 not in coingecko category list." + OperationalException, match="Category layer250 not in coingecko category list." ): PairListManager(exchange, default_conf_usdt) From 51c596a21fad06bfb23a6ba7923564ed19b2fff4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Sep 2024 19:44:38 +0200 Subject: [PATCH 185/187] chore: add test for "no pair from coingecko" case this should return an empty list --- tests/plugins/test_pairlist.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/plugins/test_pairlist.py b/tests/plugins/test_pairlist.py index 6c58acd68..1c138cc55 100644 --- a/tests/plugins/test_pairlist.py +++ b/tests/plugins/test_pairlist.py @@ -2423,6 +2423,33 @@ def test_MarketCapPairList_timing(mocker, default_conf_usdt, markets, time_machi assert markets_mock.call_count == 3 +def test_MarketCapPairList_filter_special_no_pair_from_coingecko( + mocker, + default_conf_usdt, + markets, +): + default_conf_usdt["pairlists"] = [{"method": "MarketCapPairList", "number_assets": 2}] + + mocker.patch.multiple( + EXMS, + markets=PropertyMock(return_value=markets), + exchange_has=MagicMock(return_value=True), + ) + + # Simulate no pair returned from coingecko + gcm_mock = mocker.patch( + "freqtrade.plugins.pairlist.MarketCapPairList.FtCoinGeckoApi.get_coins_markets", + return_value=[], + ) + + exchange = get_patched_exchange(mocker, default_conf_usdt) + + pm = PairListManager(exchange, default_conf_usdt) + pm.refresh_pairlist() + assert gcm_mock.call_count == 1 + assert pm.whitelist == [] + + def test_MarketCapPairList_exceptions(mocker, default_conf_usdt): exchange = get_patched_exchange(mocker, default_conf_usdt) default_conf_usdt["pairlists"] = [{"method": "MarketCapPairList"}] From 415b8354f4de6ade64f6ae2c256e401e7e9f2c56 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Sep 2024 19:45:01 +0200 Subject: [PATCH 186/187] fix: if coingecko when no pair returned fails to return valid pairs, the pairlist should be empty --- freqtrade/plugins/pairlist/MarketCapPairList.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/plugins/pairlist/MarketCapPairList.py b/freqtrade/plugins/pairlist/MarketCapPairList.py index 8bd425c32..3ca31fbf2 100644 --- a/freqtrade/plugins/pairlist/MarketCapPairList.py +++ b/freqtrade/plugins/pairlist/MarketCapPairList.py @@ -200,4 +200,5 @@ class MarketCapPairList(IPairList): if len(filtered_pairlist) > 0: return filtered_pairlist - return pairlist + # If no pairs are found, return the original pairlist + return [] From 27af9455f506feca1af87da6eda29814c90b33f4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 29 Sep 2024 19:53:20 +0200 Subject: [PATCH 187/187] chore: bump version to 2024.9 --- freqtrade/__init__.py | 2 +- ft_client/freqtrade_client/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/__init__.py b/freqtrade/__init__.py index b1cd1c9cb..dcb8a8616 100644 --- a/freqtrade/__init__.py +++ b/freqtrade/__init__.py @@ -1,6 +1,6 @@ """Freqtrade bot""" -__version__ = "2024.8" +__version__ = "2024.9" if "dev" in __version__: from pathlib import Path diff --git a/ft_client/freqtrade_client/__init__.py b/ft_client/freqtrade_client/__init__.py index ea75c43e1..ca1fd67bc 100644 --- a/ft_client/freqtrade_client/__init__.py +++ b/ft_client/freqtrade_client/__init__.py @@ -1,7 +1,7 @@ from freqtrade_client.ft_rest_client import FtRestClient -__version__ = "2024.8" +__version__ = "2024.9" if "dev" in __version__: from pathlib import Path