diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d11285ba4..4fe1ad853 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,10 @@ on: schedule: - cron: '0 5 * * 4' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build_linux: @@ -26,7 +30,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} @@ -62,12 +66,12 @@ jobs: - name: Tests run: | pytest --random-order --cov=freqtrade --cov-config=.coveragerc - if: matrix.python-version != '3.9' + if: matrix.python-version != '3.9' || matrix.os != 'ubuntu-22.04' - name: Tests incl. ccxt compatibility tests run: | pytest --random-order --cov=freqtrade --cov-config=.coveragerc --longrun - if: matrix.python-version == '3.9' + if: matrix.python-version == '3.9' && matrix.os == 'ubuntu-22.04' - name: Coveralls if: (runner.os == 'Linux' && matrix.python-version == '3.9') @@ -78,11 +82,13 @@ jobs: # Allow failure for coveralls coveralls || true - - name: Backtesting + - name: Backtesting (multi) run: | cp config_examples/config_bittrex.example.json config.json freqtrade create-userdir --userdir user_data - freqtrade backtesting --datadir tests/testdata --strategy SampleStrategy + freqtrade new-strategy -s AwesomeStrategy + freqtrade new-strategy -s AwesomeStrategyMin --template minimal + freqtrade backtesting --datadir tests/testdata --strategy-list AwesomeStrategy AwesomeStrategyMin -i 5m - name: Hyperopt run: | @@ -121,7 +127,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} @@ -164,7 +170,8 @@ jobs: run: | cp config_examples/config_bittrex.example.json config.json freqtrade create-userdir --userdir user_data - freqtrade backtesting --datadir tests/testdata --strategy SampleStrategy + freqtrade new-strategy -s AwesomeStrategyAdv --template advanced + freqtrade backtesting --datadir tests/testdata --strategy AwesomeStrategyAdv - name: Hyperopt run: | @@ -204,7 +211,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} @@ -256,7 +263,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 with: python-version: "3.10" @@ -275,7 +282,7 @@ jobs: ./tests/test_docs.sh - name: Set up Python - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 with: python-version: "3.10" @@ -293,18 +300,6 @@ jobs: details: Freqtrade doc test failed! webhookUrl: ${{ secrets.DISCORD_WEBHOOK }} - cleanup-prior-runs: - permissions: - actions: write # for rokroskar/workflow-run-cleanup-action to obtain workflow name & cancel it - contents: read # for rokroskar/workflow-run-cleanup-action to obtain branch - runs-on: ubuntu-20.04 - steps: - - name: Cleanup previous runs on this branch - uses: rokroskar/workflow-run-cleanup-action@v0.3.3 - if: "!startsWith(github.ref, 'refs/tags/') && github.ref != 'refs/heads/stable' && github.repository == 'freqtrade/freqtrade'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - # Notify only once - when CI completes (and after deploy) in case it's successfull notify-complete: needs: [ build_linux, build_macos, build_windows, docs_check, mypy_version_check ] @@ -341,7 +336,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 with: python-version: "3.9" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ee909185a..e057627cf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,11 +13,11 @@ repos: - id: mypy exclude: build_helpers additional_dependencies: - - types-cachetools==5.0.1 - - types-filelock==3.2.5 - - types-requests==2.27.25 + - types-cachetools==5.0.2 + - types-filelock==3.2.7 + - types-requests==2.27.30 - types-tabulate==0.8.9 - - types-python-dateutil==2.8.15 + - types-python-dateutil==2.8.17 # stages: [push] - repo: https://github.com/pycqa/isort diff --git a/Dockerfile b/Dockerfile index 5f7b52265..5138ecec9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.10.4-slim-bullseye as base +FROM python:3.10.5-slim-bullseye as base # Setup env ENV LANG C.UTF-8 diff --git a/README.md b/README.md index cad39f9ac..881895c9a 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,6 @@ Freqtrade is a free and open source crypto trading bot written in Python. It is ![freqtrade](https://raw.githubusercontent.com/freqtrade/freqtrade/develop/docs/assets/freqtrade-screenshot.png) -## Sponsored promotion - -[![tokenbot-promo](https://raw.githubusercontent.com/freqtrade/freqtrade/develop/docs/assets/TokenBot-Freqtrade-banner.png)](https://tokenbot.com/?utm_source=github&utm_medium=freqtrade&utm_campaign=algodevs) - ## Disclaimer This software is for educational purposes only. Do not risk money which @@ -39,7 +35,7 @@ Please read the [exchange specific notes](docs/exchanges.md) to learn about even - [X] [OKX](https://okx.com/) (Former OKEX) - [ ] [potentially many others](https://github.com/ccxt/ccxt/). _(We cannot guarantee they will work)_ -### Experimentally, freqtrade also supports futures on the following exchanges +### Supported Futures Exchanges (experimental) - [X] [Binance](https://www.binance.com/) - [X] [Gate.io](https://www.gate.io/ref/6266643) diff --git a/docker/Dockerfile.custom b/docker/Dockerfile.custom index 3b55fcb0e..6e321f14d 100644 --- a/docker/Dockerfile.custom +++ b/docker/Dockerfile.custom @@ -7,4 +7,5 @@ FROM freqtradeorg/freqtrade:develop # The below dependency - pyti - serves as an example. Please use whatever you need! RUN pip install --user pyti +# Switch back to user (only if you required root above) # USER ftuser diff --git a/docs/advanced-backtesting.md b/docs/advanced-backtesting.md index 2a484da69..5c2500f18 100644 --- a/docs/advanced-backtesting.md +++ b/docs/advanced-backtesting.md @@ -22,50 +22,79 @@ DataFrame of the candles that resulted in buy signals. Depending on how many buy makes, this file may get quite large, so periodically check your `user_data/backtest_results` folder to delete old exports. -To analyze the buy tags, we need to use the `buy_reasons.py` script from -[froggleston's repo](https://github.com/froggleston/freqtrade-buyreasons). Follow the instructions -in their README to copy the script into your `freqtrade/scripts/` folder. - Before running your next backtest, make sure you either delete your old backtest results or run backtesting with the `--cache none` option to make sure no cached results are used. If all goes well, you should now see a `backtest-result-{timestamp}_signals.pkl` file in the `user_data/backtest_results` folder. -Now run the `buy_reasons.py` script, supplying a few options: +To analyze the entry/exit tags, we now need to use the `freqtrade backtesting-analysis` command +with `--analysis-groups` option provided with space-separated arguments (default `0 1 2`): ``` bash -python3 scripts/buy_reasons.py -c -s -t -g0,1,2,3,4 +freqtrade backtesting-analysis -c --analysis-groups 0 1 2 3 4 ``` -The `-g` option is used to specify the various tabular outputs, ranging from the simplest (0) -to the most detailed per pair, per buy and per sell tag (4). More options are available by -running with the `-h` option. +This command will read from the last backtesting results. The `--analysis-groups` option is +used to specify the various tabular outputs showing the profit fo each group or trade, +ranging from the simplest (0) to the most detailed per pair, per buy and per sell tag (4): + +* 1: profit summaries grouped by enter_tag +* 2: profit summaries grouped by enter_tag and exit_tag +* 3: profit summaries grouped by pair and enter_tag +* 4: profit summaries grouped by pair, enter_ and exit_tag (this can get quite large) + +More options are available by running with the `-h` option. + +### Using export-filename + +Normally, `backtesting-analysis` uses the latest backtest results, but if you wanted to go +back to a previous backtest output, you need to supply the `--export-filename` option. +You can supply the same parameter to `backtest-analysis` with the name of the final backtest +output file. This allows you to keep historical versions of backtest results and re-analyse +them at a later date: + +``` bash +freqtrade backtesting -c --timeframe --strategy --timerange= --export=signals --export-filename=/tmp/mystrat_backtest.json +``` + +You should see some output similar to below in the logs with the name of the timestamped +filename that was exported: + +``` +2022-06-14 16:28:32,698 - freqtrade.misc - INFO - dumping json to "/tmp/mystrat_backtest-2022-06-14_16-28-32.json" +``` + +You can then use that filename in `backtesting-analysis`: + +``` +freqtrade backtesting-analysis -c --export-filename=/tmp/mystrat_backtest-2022-06-14_16-28-32.json +``` ### Tuning the buy tags and sell tags to display To show only certain buy and sell tags in the displayed output, use the following two options: ``` ---enter_reason_list : Comma separated list of enter signals to analyse. Default: "all" ---exit_reason_list : Comma separated list of exit signals to analyse. Default: "stop_loss,trailing_stop_loss" +--enter-reason-list : Space-separated list of enter signals to analyse. Default: "all" +--exit-reason-list : Space-separated list of exit signals to analyse. Default: "all" ``` For example: ```bash -python3 scripts/buy_reasons.py -c -s -t -g0,1,2,3,4 --enter_reason_list "enter_tag_a,enter_tag_b" --exit_reason_list "roi,custom_exit_tag_a,stop_loss" +freqtrade backtesting-analysis -c --analysis-groups 0 2 --enter-reason-list enter_tag_a enter_tag_b --exit-reason-list roi custom_exit_tag_a stop_loss ``` ### Outputting signal candle indicators -The real power of the buy_reasons.py script comes from the ability to print out the indicator +The real power of `freqtrade backtesting-analysis` comes from the ability to print out the indicator values present on signal candles to allow fine-grained investigation and tuning of buy signal indicators. To print out a column for a given set of indicators, use the `--indicator-list` option: ```bash -python3 scripts/buy_reasons.py -c -s -t -g0,1,2,3,4 --enter_reason_list "enter_tag_a,enter_tag_b" --exit_reason_list "roi,custom_exit_tag_a,stop_loss" --indicator_list "rsi,rsi_1h,bb_lowerband,ema_9,macd,macdsignal" +freqtrade backtesting-analysis -c --analysis-groups 0 2 --enter-reason-list enter_tag_a enter_tag_b --exit-reason-list roi custom_exit_tag_a stop_loss --indicator-list rsi rsi_1h bb_lowerband ema_9 macd macdsignal ``` The indicators have to be present in your strategy's main DataFrame (either for your main diff --git a/docs/advanced-hyperopt.md b/docs/advanced-hyperopt.md index 7f1bd0fed..8a1ebaff3 100644 --- a/docs/advanced-hyperopt.md +++ b/docs/advanced-hyperopt.md @@ -98,6 +98,23 @@ class MyAwesomeStrategy(IStrategy): !!! Note All overrides are optional and can be mixed/matched as necessary. +### Dynamic parameters + +Parameters can also be defined dynamically, but must be available to the instance once the * [`bot_start()` callback](strategy-callbacks.md#bot-start) has been called. + +``` python + +class MyAwesomeStrategy(IStrategy): + + def bot_start(self, **kwargs) -> None: + self.buy_adx = IntParameter(20, 30, default=30, optimize=True) + + # ... +``` + +!!! Warning + Parameters created this way will not show up in the `list-strategies` parameter count. + ### Overriding Base estimator You can define your own estimator for Hyperopt by implementing `generate_estimator()` in the Hyperopt subclass. diff --git a/docs/assets/discord_notification.png b/docs/assets/discord_notification.png new file mode 100644 index 000000000..05a7705d7 Binary files /dev/null and b/docs/assets/discord_notification.png differ diff --git a/docs/backtesting.md b/docs/backtesting.md index b4d9aef80..50fc96923 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -300,6 +300,7 @@ A backtesting result will look like that: | Absolute profit | 0.00762792 BTC | | Total profit % | 76.2% | | CAGR % | 460.87% | +| Profit factor | 1.11 | | Avg. stake amount | 0.001 BTC | | Total trade volume | 0.429 BTC | | | | @@ -399,6 +400,7 @@ It contains some useful key metrics about performance of your strategy on backte | Absolute profit | 0.00762792 BTC | | Total profit % | 76.2% | | CAGR % | 460.87% | +| Profit factor | 1.11 | | Avg. stake amount | 0.001 BTC | | Total trade volume | 0.429 BTC | | | | @@ -444,6 +446,8 @@ It contains some useful key metrics about performance of your strategy on backte - `Final balance`: Final balance - starting balance + absolute profit. - `Absolute profit`: Profit made in stake currency. - `Total profit %`: Total profit. Aligned to the `TOTAL` row's `Tot Profit %` from the first table. Calculated as `(End capital − Starting capital) / Starting capital`. +- `CAGR %`: Compound annual growth rate. +- `Profit factor`: profit / loss. - `Avg. stake amount`: Average stake amount, either `stake_amount` or the average when using dynamic stake amount. - `Total trade volume`: Volume generated on the exchange to reach the above profit. - `Best Pair` / `Worst Pair`: Best and worst performing pair, and it's corresponding `Cum Profit %`. @@ -530,8 +534,9 @@ Since backtesting lacks some detailed information about what happens within a ca - Exit-reason does not explain if a trade was positive or negative, just what triggered the exit (this can look odd if negative ROI values are used) - Evaluation sequence (if multiple signals happen on the same candle) - Exit-signal - - ROI (if not stoploss) - Stoploss + - ROI + - Trailing stoploss Taking these assumptions, backtesting tries to mirror real trading as closely as possible. However, backtesting will **never** replace running a strategy in dry-run mode. Also, keep in mind that past results don't guarantee future success. diff --git a/docs/configuration.md b/docs/configuration.md index 80cd52c5b..0f3069478 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -140,7 +140,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `dry_run` | **Required.** Define if the bot must be in Dry Run or production mode.
*Defaults to `true`.*
**Datatype:** Boolean | `dry_run_wallet` | Define the starting amount in stake currency for the simulated wallet used by the bot running in Dry Run mode.
*Defaults to `1000`.*
**Datatype:** Float | `cancel_open_orders_on_exit` | Cancel open orders when the `/stop` RPC command is issued, `Ctrl+C` is pressed or the bot dies unexpectedly. When set to `true`, this allows you to use `/stop` to cancel unfilled and partially filled orders in the event of a market crash. It does not impact open positions.
*Defaults to `false`.*
**Datatype:** Boolean -| `process_only_new_candles` | Enable processing of indicators only when new candles arrive. If false each loop populates the indicators, this will mean the same candle is processed many times creating system load but can be useful of your strategy depends on tick data not only candle. [Strategy Override](#parameters-in-the-strategy).
*Defaults to `false`.*
**Datatype:** Boolean +| `process_only_new_candles` | Enable processing of indicators only when new candles arrive. If false each loop populates the indicators, this will mean the same candle is processed many times creating system load but can be useful of your strategy depends on tick data not only candle. [Strategy Override](#parameters-in-the-strategy).
*Defaults to `true`.*
**Datatype:** Boolean | `minimal_roi` | **Required.** Set the threshold as ratio the bot will use to exit a trade. [More information below](#understand-minimal_roi). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Dict | `stoploss` | **Required.** Value as ratio of the stoploss used by the bot. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Float (as ratio) | `trailing_stop` | Enables trailing stoploss (based on `stoploss` in either configuration or strategy file). More details in the [stoploss documentation](stoploss.md#trailing-stop-loss). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Boolean @@ -230,6 +230,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `dataformat_trades` | Data format to use to store historical trades data.
*Defaults to `jsongz`*.
**Datatype:** String | `position_adjustment_enable` | Enables the strategy to use position adjustments (additional buys or sells). [More information here](strategy-callbacks.md#adjust-trade-position).
[Strategy Override](#parameters-in-the-strategy).
*Defaults to `false`.*
**Datatype:** Boolean | `max_entry_position_adjustment` | Maximum additional order(s) for each open trade on top of the first entry Order. Set it to `-1` for unlimited additional orders. [More information here](strategy-callbacks.md#adjust-trade-position).
[Strategy Override](#parameters-in-the-strategy).
*Defaults to `-1`.*
**Datatype:** Positive Integer or -1 +| `futures_funding_rate` | User-specified funding rate to be used when historical funding rates are not available from the exchange. This does not overwrite real historical rates. It is recommended that this be set to 0 unless you are testing a specific coin and you understand how the funding rate will affect freqtrade's profit calculations. [More information here](leverage.md#unavailable-funding-rates)
*Defaults to None.*
**Datatype:** Float ### Parameters in the strategy @@ -583,7 +584,7 @@ Once you will be happy with your bot performance running in the Dry-run mode, yo * Market orders fill based on orderbook volume the moment the order is placed. * Limit orders fill once the price reaches the defined level - or time out based on `unfilledtimeout` settings. * In combination with `stoploss_on_exchange`, the stop_loss price is assumed to be filled. -* Open orders (not trades, which are stored in the database) are reset on bot restart. +* Open orders (not trades, which are stored in the database) are kept open after bot restarts, with the assumption that they were not filled while being offline. ## Switch to production mode diff --git a/docs/developer.md b/docs/developer.md index 185bfc92e..ce7fb37e1 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -314,6 +314,32 @@ The output will show the last entry from the Exchange as well as the current UTC If the day shows the same day, then the last candle can be assumed as incomplete and should be dropped (leave the setting `"ohlcv_partial_candle"` from the exchange-class untouched / True). Otherwise, set `"ohlcv_partial_candle"` to `False` to not drop Candles (shown in the example above). Another way is to run this command multiple times in a row and observe if the volume is changing (while the date remains the same). +### Update binance cached leverage tiers + +Updating leveraged tiers should be done regularly - and requires an authenticated account with futures enabled. + +``` python +import ccxt +import json +from pathlib import Path + +exchange = ccxt.binance({ + 'apiKey': '', + 'secret': '' + 'options': {'defaultType': 'future'} + }) +_ = exchange.load_markets() + +lev_tiers = exchange.fetch_leverage_tiers() + +# Assumes this is running in the root of the repository. +file = Path('freqtrade/exchange/binance_leverage_tiers.json') +json.dump(lev_tiers, file.open('w'), indent=2) + +``` + +This file should then be contributed upstream, so others can benefit from this, too. + ## Updating example notebooks To keep the jupyter notebooks aligned with the documentation, the following should be ran after updating a example notebook. diff --git a/docs/hyperopt.md b/docs/hyperopt.md index 030d73f4b..63c7a4413 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -680,7 +680,7 @@ class MyAwesomeStrategy(IStrategy): !!! Note Values in the configuration file will overwrite Parameter-file level parameters - and both will overwrite parameters within the strategy. - The prevalence is therefore: config > parameter file > strategy + The prevalence is therefore: config > parameter file > strategy `*_params` > parameter default ### Understand Hyperopt ROI results diff --git a/docs/index.md b/docs/index.md index e0a88a381..7c35e92b6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -22,10 +22,6 @@ Freqtrade is a free and open source crypto trading bot written in Python. It is ![freqtrade screenshot](assets/freqtrade-screenshot.png) -## Sponsored promotion - -[![tokenbot-promo](assets/TokenBot-Freqtrade-banner.png)](https://tokenbot.com/?utm_source=github&utm_medium=freqtrade&utm_campaign=algodevs) - ## Features - Develop your Strategy: Write your strategy in python, using [pandas](https://pandas.pydata.org/). Example strategies to inspire you are available in the [strategy repository](https://github.com/freqtrade/freqtrade-strategies). @@ -51,7 +47,7 @@ Please read the [exchange specific notes](exchanges.md) to learn about eventual, - [X] [OKX](https://okx.com/) (Former OKEX) - [ ] [potentially many others through ccxt](https://github.com/ccxt/ccxt/). _(We cannot guarantee they will work)_ -### Experimentally, freqtrade also supports futures on the following exchanges: +### Supported Futures Exchanges (experimental) - [X] [Binance](https://www.binance.com/) - [X] [Gate.io](https://www.gate.io/ref/6266643) diff --git a/docs/leverage.md b/docs/leverage.md index 79d3c9842..491e6eda0 100644 --- a/docs/leverage.md +++ b/docs/leverage.md @@ -64,7 +64,10 @@ You will also have to pick a "margin mode" (explanation below) - with freqtrade ### Margin mode -The possible values are: `isolated`, or `cross`(*currently unavailable*) +On top of `trading_mode` - you will also have to configure your `margin_mode`. +While freqtrade currently only supports one margin mode, this will change, and by configuring it now you're all set for future updates. + +The possible values are: `isolated`, or `cross`(*currently unavailable*). #### Isolated margin mode @@ -82,6 +85,16 @@ One account is used to share collateral between markets (trading pairs). Margin "margin_mode": "cross" ``` +## Set leverage to use + +Different strategies and risk profiles will require different levels of leverage. +While you could configure one static leverage value - freqtrade offers you the flexibility to adjust this via [strategy leverage callback](strategy-callbacks.md#leverage-callback) - which allows you to use different leverages by pair, or based on some other factor benefitting your strategy result. + +If not implemented, leverage defaults to 1x (no leverage). + +!!! Warning + Higher leverage also equals higher risk - be sure you fully understand the implications of using leverage! + ## Understand `liquidation_buffer` *Defaults to `0.05`* @@ -101,6 +114,13 @@ Possible values are any floats between 0.0 and 0.99 !!! Danger "A `liquidation_buffer` of 0.0, or a low `liquidation_buffer` is likely to result in liquidations, and liquidation fees" Currently Freqtrade is able to calculate liquidation prices, but does not calculate liquidation fees. Setting your `liquidation_buffer` to 0.0, or using a low `liquidation_buffer` could result in your positions being liquidated. Freqtrade does not track liquidation fees, so liquidations will result in inaccurate profit/loss results for your bot. If you use a low `liquidation_buffer`, it is recommended to use `stoploss_on_exchange` if your exchange supports this. +## Unavailable funding rates + +For futures data, exchanges commonly provide the futures candles, the marks, and the funding rates. However, it is common that whilst candles and marks might be available, the funding rates are not. This can affect backtesting timeranges, i.e. you may only be able to test recent timeranges and not earlier, experiencing the `No data found. Terminating.` error. To get around this, add the `futures_funding_rate` config option as listed in [configuration.md](configuration.md), and it is recommended that you set this to `0`, unless you know a given specific funding rate for your pair, exchange and timerange. Setting this to anything other than `0` can have drastic effects on your profit calculations within strategy, e.g. within the `custom_exit`, `custom_stoploss`, etc functions. + +!!! Warning "This will mean your backtests are inaccurate." + This will not overwrite funding rates that are available from the exchange, but bear in mind that setting a false funding rate will mean backtesting results will be inaccurate for historical timeranges where funding rates are not available. + ### Developer #### Margin mode diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index 3fa35d80d..6477ad23f 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,5 +1,5 @@ mkdocs==1.3.0 -mkdocs-material==8.2.15 +mkdocs-material==8.3.6 mdx_truly_sane_lists==1.2 -pymdown-extensions==9.4 +pymdown-extensions==9.5 jinja2==3.1.2 diff --git a/docs/sql_cheatsheet.md b/docs/sql_cheatsheet.md index 49372b002..c42cb5575 100644 --- a/docs/sql_cheatsheet.md +++ b/docs/sql_cheatsheet.md @@ -89,11 +89,12 @@ WHERE id=31; If you'd still like to remove a trade from the database directly, you can use the below query. -```sql -DELETE FROM trades WHERE id = ; -``` +!!! Danger + Some systems (Ubuntu) disable foreign keys in their sqlite3 packaging. When using sqlite - please ensure that foreign keys are on by running `PRAGMA foreign_keys = ON` before the above query. ```sql +DELETE FROM trades WHERE id = ; + DELETE FROM trades WHERE id = 31; ``` @@ -102,13 +103,20 @@ DELETE FROM trades WHERE id = 31; ## Use a different database system +Freqtrade is using SQLAlchemy, which supports multiple different database systems. As such, a multitude of database systems should be supported. +Freqtrade does not depend or install any additional database driver. Please refer to the [SQLAlchemy docs](https://docs.sqlalchemy.org/en/14/core/engines.html#database-urls) on installation instructions for the respective database systems. + +The following systems have been tested and are known to work with freqtrade: + +* sqlite (default) +* PostgreSQL) +* MariaDB + !!! Warning - By using one of the below database systems, you acknowledge that you know how to manage such a system. Freqtrade will not provide any support with setup or maintenance (or backups) of the below database systems. + By using one of the below database systems, you acknowledge that you know how to manage such a system. The freqtrade team will not provide any support with setup or maintenance (or backups) of the below database systems. ### PostgreSQL -Freqtrade supports PostgreSQL by using SQLAlchemy, which supports multiple different database systems. - Installation: `pip install psycopg2-binary` diff --git a/docs/stoploss.md b/docs/stoploss.md index 573fdbd6c..83f787947 100644 --- a/docs/stoploss.md +++ b/docs/stoploss.md @@ -191,6 +191,19 @@ For example, simplified math: !!! Tip Make sure to have this value (`trailing_stop_positive_offset`) lower than minimal ROI, otherwise minimal ROI will apply first and sell the trade. +## Stoploss and Leverage + +Stoploss should be thought of as "risk on this trade" - so a stoploss of 10% on a 100$ trade means you are willing to lose 10$ (10%) on this trade - which would trigger if the price moves 10% to the downside. + +When using leverage, the same principle is applied - with stoploss defining the risk on the trade (the amount you are willing to lose). + +Therefore, a stoploss of 10% on a 10x trade would trigger on a 1% price move. +If your stake amount (own capital) was 100$ - this trade would be 1000$ at 10x (after leverage). +If price moves 1% - you've lost 10$ of your own capital - therfore stoploss will trigger in this case. + +Make sure to be aware of this, and avoid using too tight stoploss (at 10x leverage, 10% risk may be too little to allow the trade to "breath" a little). + + ## Changing stoploss on open trades A stoploss on an open trade can be changed by changing the value in the configuration or strategy and use the `/reload_config` command (alternatively, completely stopping and restarting the bot also works). diff --git a/docs/strategy-callbacks.md b/docs/strategy-callbacks.md index ab67a3c26..beffba56b 100644 --- a/docs/strategy-callbacks.md +++ b/docs/strategy-callbacks.md @@ -46,6 +46,9 @@ class AwesomeStrategy(IStrategy): self.cust_remote_data = requests.get('https://some_remote_source.example.com') ``` + +During hyperopt, this runs only once at startup. + ## Bot loop start A simple callback which is called once at the start of every bot throttling iteration (roughly every 5 seconds, unless configured differently). @@ -546,10 +549,12 @@ class AwesomeStrategy(IStrategy): :param pair: Pair that's about to be bought/shorted. :param order_type: Order type (as configured in order_types). usually limit or market. - :param amount: Amount in target (quote) currency that's going to be traded. - :param rate: Rate that's going to be used when using limit orders + :param amount: Amount in target (base) currency that's going to be traded. + :param rate: Rate that's going to be used when using limit orders + or current rate for market orders. :param time_in_force: Time in force. Defaults to GTC (Good-til-cancelled). :param current_time: datetime object, containing the current datetime + :param entry_tag: Optional entry_tag (buy_tag) if provided with the buy signal. :param side: 'long' or 'short' - indicating the direction of the proposed trade :param **kwargs: Ensure to keep this here so updates to this won't break your strategy. :return bool: When True is returned, then the buy-order is placed on the exchange. @@ -563,6 +568,14 @@ class AwesomeStrategy(IStrategy): `confirm_trade_exit()` can be used to abort a trade exit (sell) at the latest second (maybe because the price is not what we expect). +`confirm_trade_exit()` may be called multiple times within one iteration for the same trade if different exit-reasons apply. +The exit-reasons (if applicable) will be in the following sequence: + +* `exit_signal` / `custom_exit` +* `stop_loss` +* `roi` +* `trailing_stop_loss` + ``` python from freqtrade.persistence import Trade @@ -575,7 +588,7 @@ class AwesomeStrategy(IStrategy): rate: float, time_in_force: str, exit_reason: str, current_time: datetime, **kwargs) -> bool: """ - Called right before placing a regular sell order. + Called right before placing a regular exit order. Timing for this function is critical, so avoid doing heavy computations or network requests in this method. @@ -583,17 +596,19 @@ class AwesomeStrategy(IStrategy): When not implemented by a strategy, returns True (always confirming). - :param pair: Pair that's about to be sold. + :param pair: Pair for trade that's about to be exited. + :param trade: trade object. :param order_type: Order type (as configured in order_types). usually limit or market. - :param amount: Amount in quote currency. + :param amount: Amount in base currency. :param rate: Rate that's going to be used when using limit orders + or current rate for market orders. :param time_in_force: Time in force. Defaults to GTC (Good-til-cancelled). :param exit_reason: Exit reason. Can be any of ['roi', 'stop_loss', 'stoploss_on_exchange', 'trailing_stop_loss', 'exit_signal', 'force_exit', 'emergency_exit'] :param current_time: datetime object, containing the current datetime :param **kwargs: Ensure to keep this here so updates to this won't break your strategy. - :return bool: When True is returned, then the exit-order is placed on the exchange. + :return bool: When True, then the exit-order is placed on the exchange. False aborts the process """ if exit_reason == 'force_exit' and trade.calc_profit_ratio(rate) < 0: @@ -605,6 +620,9 @@ class AwesomeStrategy(IStrategy): ``` +!!! Warning + `confirm_trade_exit()` can prevent stoploss exits, causing significant losses as this would ignore stoploss exits. + ## Adjust trade position The `position_adjustment_enable` strategy property enables the usage of `adjust_trade_position()` callback in the strategy. @@ -656,7 +674,7 @@ class DigDeeperStrategy(IStrategy): # This is called when placing the initial order (opening trade) def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float, - proposed_stake: float, min_stake: float, max_stake: float, + proposed_stake: float, min_stake: Optional[float], max_stake: float, entry_tag: Optional[str], side: str, **kwargs) -> float: # We need to leave most of the funds for possible further DCA orders @@ -664,7 +682,7 @@ class DigDeeperStrategy(IStrategy): return proposed_stake / self.max_dca_multiplier def adjust_trade_position(self, trade: Trade, current_time: datetime, - current_rate: float, current_profit: float, min_stake: float, + current_rate: float, current_profit: float, min_stake: Optional[float], max_stake: float, **kwargs): """ Custom trade adjustment logic, returning the stake amount that a trade should be increased. @@ -788,19 +806,23 @@ For markets / exchanges that don't support leverage, this method is ignored. ``` python class AwesomeStrategy(IStrategy): - def leverage(self, pair: str, current_time: 'datetime', current_rate: float, - proposed_leverage: float, max_leverage: float, side: str, + def leverage(self, pair: str, current_time: datetime, current_rate: float, + proposed_leverage: float, max_leverage: float, entry_tag: Optional[str], side: str, **kwargs) -> float: """ - Customize leverage for each new trade. + Customize leverage for each new trade. This method is only called in futures mode. :param pair: Pair that's currently analyzed :param current_time: datetime object, containing the current datetime :param current_rate: Rate, calculated based on pricing settings in exit_pricing. :param proposed_leverage: A leverage proposed by the bot. :param max_leverage: Max leverage allowed on this pair + :param entry_tag: Optional entry_tag (buy_tag) if provided with the buy signal. :param side: 'long' or 'short' - indicating the direction of the proposed trade :return: A leverage amount, which is between 1.0 and max_leverage. """ return 1.0 ``` + +All profit calculations include leverage. Stoploss / ROI also include leverage in their calculation. +Defining a stoploss of 10% at 10x leverage would trigger the stoploss with a 1% move to the downside. diff --git a/docs/strategy_migration.md b/docs/strategy_migration.md index 458e80d0e..471ffa601 100644 --- a/docs/strategy_migration.md +++ b/docs/strategy_migration.md @@ -199,7 +199,7 @@ New string argument `side` - which can be either `"long"` or `"short"`. ``` python hl_lines="4" class AwesomeStrategy(IStrategy): def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float, - proposed_stake: float, min_stake: float, max_stake: float, + proposed_stake: float, min_stake: Optional[float], max_stake: float, entry_tag: Optional[str], **kwargs) -> float: # ... return proposed_stake @@ -208,7 +208,7 @@ class AwesomeStrategy(IStrategy): ``` python hl_lines="4" class AwesomeStrategy(IStrategy): def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float, - proposed_stake: float, min_stake: float, max_stake: float, + proposed_stake: float, min_stake: Optional[float], max_stake: float, entry_tag: Optional[str], side: str, **kwargs) -> float: # ... return proposed_stake diff --git a/docs/telegram-usage.md b/docs/telegram-usage.md index 27f5f91b6..2145797b4 100644 --- a/docs/telegram-usage.md +++ b/docs/telegram-usage.md @@ -171,8 +171,8 @@ official commands. You can ask at any moment for help with `/help`. | `/locks` | Show currently locked pairs. | `/unlock ` | Remove the lock for this pair (or for this lock id). | `/profit []` | Display a summary of your profit/loss from close trades and some stats about your performance, over the last n days (all trades by default) -| `/forceexit ` | Instantly exits the given trade (Ignoring `minimum_roi`). -| `/forceexit all` | Instantly exits all open trades (Ignoring `minimum_roi`). +| `/forceexit | /fx ` | Instantly exits the given trade (Ignoring `minimum_roi`). +| `/forceexit all | /fx all` | Instantly exits all open trades (Ignoring `minimum_roi`). | `/fx` | alias for `/forceexit` | `/forcelong [rate]` | Instantly buys the given pair. Rate is optional and only applies to limit orders. (`force_entry_enable` must be set to True) | `/forceshort [rate]` | Instantly shorts the given pair. Rate is optional and only applies to limit orders. This will only work on non-spot markets. (`force_entry_enable` must be set to True) @@ -270,10 +270,15 @@ Return a summary of your profit/loss and performance. > **Latest Trade opened:** `2 minutes ago` > **Avg. Duration:** `2:33:45` > **Best Performing:** `PAY/BTC: 50.23%` +> **Trading volume:** `0.5 BTC` +> **Profit factor:** `1.04` +> **Max Drawdown:** `9.23% (0.01255 BTC)` The relative profit of `1.2%` is the average profit per trade. -The relative profit of `15.2 Σ%` is be based on the starting capital - so in this case, the starting capital was `0.00485701 * 1.152 = 0.00738 BTC`. -Starting capital is either taken from the `available_capital` setting, or calculated by using current wallet size - profits. +The relative profit of `15.2 Σ%` is be based on the starting capital - so in this case, the starting capital was `0.00485701 * 1.152 = 0.00738 BTC`. +Starting capital is either taken from the `available_capital` setting, or calculated by using current wallet size - profits. +Profit Factor is calculated as gross profits / gross losses - and should serve as an overall metric for the strategy. +Max drawdown corresponds to the backtesting metric `Absolute Drawdown (Account)` - calculated as `(Absolute Drawdown) / (DrawdownHigh + startingBalance)`. ### /forceexit @@ -281,6 +286,7 @@ Starting capital is either taken from the `available_capital` setting, or calcul !!! Tip You can get a list of all open trades by calling `/forceexit` without parameter, which will show a list of buttons to simply exit a trade. + This command has an alias in `/fx` - which has the same capabilities, but is faster to type in "emergency" situations. ### /forcelong [rate] | /forceshort [rate] @@ -328,11 +334,11 @@ Per default `/daily` will return the 7 last days. The example below if for `/dai > **Daily Profit over the last 3 days:** ``` -Day Profit BTC Profit USD ----------- -------------- ------------ -2018-01-03 0.00224175 BTC 29,142 USD -2018-01-02 0.00033131 BTC 4,307 USD -2018-01-01 0.00269130 BTC 34.986 USD +Day (count) USDT USD Profit % +-------------- ------------ ---------- ---------- +2022-06-11 (1) -0.746 USDT -0.75 USD -0.08% +2022-06-10 (0) 0 USDT 0.00 USD 0.00% +2022-06-09 (5) 20 USDT 20.10 USD 5.00% ``` ### /weekly @@ -342,11 +348,11 @@ from Monday. The example below if for `/weekly 3`: > **Weekly Profit over the last 3 weeks (starting from Monday):** ``` -Monday Profit BTC Profit USD ----------- -------------- ------------ -2018-01-03 0.00224175 BTC 29,142 USD -2017-12-27 0.00033131 BTC 4,307 USD -2017-12-20 0.00269130 BTC 34.986 USD +Monday (count) Profit BTC Profit USD Profit % +------------- -------------- ------------ ---------- +2018-01-03 (5) 0.00224175 BTC 29,142 USD 4.98% +2017-12-27 (1) 0.00033131 BTC 4,307 USD 0.00% +2017-12-20 (4) 0.00269130 BTC 34.986 USD 5.12% ``` ### /monthly @@ -356,11 +362,11 @@ if for `/monthly 3`: > **Monthly Profit over the last 3 months:** ``` -Month Profit BTC Profit USD ----------- -------------- ------------ -2018-01 0.00224175 BTC 29,142 USD -2017-12 0.00033131 BTC 4,307 USD -2017-11 0.00269130 BTC 34.986 USD +Month (count) Profit BTC Profit USD Profit % +------------- -------------- ------------ ---------- +2018-01 (20) 0.00224175 BTC 29,142 USD 4.98% +2017-12 (5) 0.00033131 BTC 4,307 USD 0.00% +2017-11 (10) 0.00269130 BTC 34.986 USD 5.10% ``` ### /whitelist diff --git a/docs/updating.md b/docs/updating.md index 1839edc4c..8dc7279a4 100644 --- a/docs/updating.md +++ b/docs/updating.md @@ -32,4 +32,8 @@ Please ensure that you're also updating dependencies - otherwise things might br ``` bash git pull pip install -U -r requirements.txt +pip install -e . + +# Ensure freqUI is at the latest version +freqtrade install-ui ``` diff --git a/docs/utils.md b/docs/utils.md index 9b799e5fc..0dd88b242 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -651,6 +651,61 @@ Common arguments: ``` +## Detailed backtest analysis + +Advanced backtest result analysis. + +More details in the [Backtesting analysis](advanced-backtesting.md#analyze-the-buyentry-and-sellexit-tags) Section. + +``` +usage: freqtrade backtesting-analysis [-h] [-v] [--logfile FILE] [-V] + [-c PATH] [-d PATH] [--userdir PATH] + [--export-filename PATH] + [--analysis-groups {0,1,2,3,4} [{0,1,2,3,4} ...]] + [--enter-reason-list ENTER_REASON_LIST [ENTER_REASON_LIST ...]] + [--exit-reason-list EXIT_REASON_LIST [EXIT_REASON_LIST ...]] + [--indicator-list INDICATOR_LIST [INDICATOR_LIST ...]] + +optional arguments: + -h, --help show this help message and exit + --export-filename PATH, --backtest-filename PATH + Use this filename for backtest results.Requires + `--export` to be set as well. Example: `--export-filen + ame=user_data/backtest_results/backtest_today.json` + --analysis-groups {0,1,2,3,4} [{0,1,2,3,4} ...] + grouping output - 0: simple wins/losses by enter tag, + 1: by enter_tag, 2: by enter_tag and exit_tag, 3: by + pair and enter_tag, 4: by pair, enter_ and exit_tag + (this can get quite large) + --enter-reason-list ENTER_REASON_LIST [ENTER_REASON_LIST ...] + Comma separated list of entry signals to analyse. + Default: all. e.g. 'entry_tag_a,entry_tag_b' + --exit-reason-list EXIT_REASON_LIST [EXIT_REASON_LIST ...] + Comma separated list of exit signals to analyse. + Default: all. e.g. + 'exit_tag_a,roi,stop_loss,trailing_stop_loss' + --indicator-list INDICATOR_LIST [INDICATOR_LIST ...] + Comma separated list of indicators to analyse. e.g. + 'close,rsi,bb_lowerband,profit_abs' + +Common arguments: + -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). + --logfile FILE Log to the file specified. Special values are: + 'syslog', 'journald'. See the documentation for more + details. + -V, --version show program's version number and exit + -c PATH, --config PATH + Specify configuration file (default: + `userdir/config.json` or `config.json` whichever + exists). Multiple --config options may be used. Can be + set to `-` to read config from stdin. + -d PATH, --datadir PATH + Path to directory with historical backtesting data. + --userdir PATH, --user-data-dir PATH + Path to userdata directory. + +``` + ## List Hyperopt results You can list the hyperoptimization epochs the Hyperopt module evaluated previously with the `hyperopt-list` sub-command. diff --git a/docs/webhook-config.md b/docs/webhook-config.md index 5f5933b47..3677ebe89 100644 --- a/docs/webhook-config.md +++ b/docs/webhook-config.md @@ -239,3 +239,52 @@ Possible parameters are: The fields in `webhook.webhookstatus` are used for regular status messages (Started / Stopped / ...). Parameters are filled using string.format. The only possible value here is `{status}`. + +## Discord + +A special form of webhooks is available for discord. +You can configure this as follows: + +```json +"discord": { + "enabled": true, + "webhook_url": "https://discord.com/api/webhooks/", + "exit_fill": [ + {"Trade ID": "{trade_id}"}, + {"Exchange": "{exchange}"}, + {"Pair": "{pair}"}, + {"Direction": "{direction}"}, + {"Open rate": "{open_rate}"}, + {"Close rate": "{close_rate}"}, + {"Amount": "{amount}"}, + {"Open date": "{open_date:%Y-%m-%d %H:%M:%S}"}, + {"Close date": "{close_date:%Y-%m-%d %H:%M:%S}"}, + {"Profit": "{profit_amount} {stake_currency}"}, + {"Profitability": "{profit_ratio:.2%}"}, + {"Enter tag": "{enter_tag}"}, + {"Exit Reason": "{exit_reason}"}, + {"Strategy": "{strategy}"}, + {"Timeframe": "{timeframe}"}, + ], + "entry_fill": [ + {"Trade ID": "{trade_id}"}, + {"Exchange": "{exchange}"}, + {"Pair": "{pair}"}, + {"Direction": "{direction}"}, + {"Open rate": "{open_rate}"}, + {"Amount": "{amount}"}, + {"Open date": "{open_date:%Y-%m-%d %H:%M:%S}"}, + {"Enter tag": "{enter_tag}"}, + {"Strategy": "{strategy} {timeframe}"}, + ] +} +``` + + +The above represents the default (`exit_fill` and `entry_fill` are optional and will default to the above configuration) - modifications are obviously possible. + +Available fields correspond to the fields for webhooks and are documented in the corresponding webhook sections. + +The notifications will look as follows by default. + +![discord-notification](assets/discord_notification.png) diff --git a/freqtrade/commands/__init__.py b/freqtrade/commands/__init__.py index 0e637c487..d93ed1e09 100644 --- a/freqtrade/commands/__init__.py +++ b/freqtrade/commands/__init__.py @@ -6,6 +6,7 @@ Contains all start-commands, subcommands and CLI Interface creation. Note: Be careful with file-scoped imports in these subfiles. as they are parsed on startup, nothing containing optional modules should be loaded. """ +from freqtrade.commands.analyze_commands import start_analysis_entries_exits from freqtrade.commands.arguments import Arguments from freqtrade.commands.build_config_commands import start_new_config from freqtrade.commands.data_commands import (start_convert_data, start_convert_trades, diff --git a/freqtrade/commands/analyze_commands.py b/freqtrade/commands/analyze_commands.py new file mode 100755 index 000000000..b6b790788 --- /dev/null +++ b/freqtrade/commands/analyze_commands.py @@ -0,0 +1,69 @@ +import logging +from pathlib import Path +from typing import Any, Dict + +from freqtrade.configuration import setup_utils_configuration +from freqtrade.enums import RunMode +from freqtrade.exceptions import OperationalException + + +logger = logging.getLogger(__name__) + + +def setup_analyze_configuration(args: Dict[str, Any], method: RunMode) -> Dict[str, Any]: + """ + Prepare the configuration for the entry/exit reason analysis module + :param args: Cli args from Arguments() + :param method: Bot running mode + :return: Configuration + """ + config = setup_utils_configuration(args, method) + + no_unlimited_runmodes = { + RunMode.BACKTEST: 'backtesting', + } + if method in no_unlimited_runmodes.keys(): + from freqtrade.data.btanalysis import get_latest_backtest_filename + + if 'exportfilename' in config: + if config['exportfilename'].is_dir(): + btfile = Path(get_latest_backtest_filename(config['exportfilename'])) + signals_file = f"{config['exportfilename']}/{btfile.stem}_signals.pkl" + else: + if config['exportfilename'].exists(): + btfile = Path(config['exportfilename']) + signals_file = f"{btfile.parent}/{btfile.stem}_signals.pkl" + else: + raise OperationalException(f"{config['exportfilename']} does not exist.") + else: + raise OperationalException('exportfilename not in config.') + + if (not Path(signals_file).exists()): + raise OperationalException( + (f"Cannot find latest backtest signals file: {signals_file}." + "Run backtesting with `--export signals`.") + ) + + return config + + +def start_analysis_entries_exits(args: Dict[str, Any]) -> None: + """ + Start analysis script + :param args: Cli args from Arguments() + :return: None + """ + from freqtrade.data.entryexitanalysis import process_entry_exit_reasons + + # Initialize configuration + config = setup_analyze_configuration(args, RunMode.BACKTEST) + + logger.info('Starting freqtrade in analysis mode') + + process_entry_exit_reasons(config['exportfilename'], + config['exchange']['pair_whitelist'], + config['analysis_groups'], + config['enter_reason_list'], + config['exit_reason_list'], + config['indicator_list'] + ) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 815e28175..1e3e2845a 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -101,6 +101,9 @@ ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperop "print_json", "hyperoptexportfilename", "hyperopt_show_no_header", "disableparamexport", "backtest_breakdown"] +ARGS_ANALYZE_ENTRIES_EXITS = ["exportfilename", "analysis_groups", "enter_reason_list", + "exit_reason_list", "indicator_list"] + NO_CONF_REQURIED = ["convert-data", "convert-trade-data", "download-data", "list-timeframes", "list-markets", "list-pairs", "list-strategies", "list-data", "hyperopt-list", "hyperopt-show", "backtest-filter", @@ -182,8 +185,9 @@ class Arguments: self.parser = argparse.ArgumentParser(description='Free, open source crypto trading bot') self._build_args(optionlist=['version'], parser=self.parser) - from freqtrade.commands import (start_backtesting, start_backtesting_show, - start_convert_data, start_convert_db, start_convert_trades, + from freqtrade.commands import (start_analysis_entries_exits, start_backtesting, + start_backtesting_show, start_convert_data, + start_convert_db, start_convert_trades, start_create_userdir, start_download_data, start_edge, start_hyperopt, start_hyperopt_list, start_hyperopt_show, start_install_ui, start_list_data, start_list_exchanges, @@ -283,6 +287,13 @@ class Arguments: backtesting_show_cmd.set_defaults(func=start_backtesting_show) self._build_args(optionlist=ARGS_BACKTEST_SHOW, parser=backtesting_show_cmd) + # Add backtesting analysis subcommand + analysis_cmd = subparsers.add_parser('backtesting-analysis', + help='Backtest Analysis module.', + parents=[_common_parser]) + analysis_cmd.set_defaults(func=start_analysis_entries_exits) + self._build_args(optionlist=ARGS_ANALYZE_ENTRIES_EXITS, parser=analysis_cmd) + # Add edge subcommand edge_cmd = subparsers.add_parser('edge', help='Edge module.', parents=[_common_parser, _strategy_parser]) diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index aac9f5713..3370ce64b 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -614,4 +614,37 @@ AVAILABLE_CLI_OPTIONS = { "that do not contain any parameters."), action="store_true", ), + "analysis_groups": Arg( + "--analysis-groups", + help=("grouping output - " + "0: simple wins/losses by enter tag, " + "1: by enter_tag, " + "2: by enter_tag and exit_tag, " + "3: by pair and enter_tag, " + "4: by pair, enter_ and exit_tag (this can get quite large)"), + nargs='+', + default=['0', '1', '2'], + choices=['0', '1', '2', '3', '4'], + ), + "enter_reason_list": Arg( + "--enter-reason-list", + help=("Comma separated list of entry signals to analyse. Default: all. " + "e.g. 'entry_tag_a,entry_tag_b'"), + nargs='+', + default=['all'], + ), + "exit_reason_list": Arg( + "--exit-reason-list", + help=("Comma separated list of exit signals to analyse. Default: all. " + "e.g. 'exit_tag_a,roi,stop_loss,trailing_stop_loss'"), + nargs='+', + default=['all'], + ), + "indicator_list": Arg( + "--indicator-list", + help=("Comma separated list of indicators to analyse. " + "e.g. 'close,rsi,bb_lowerband,profit_abs'"), + nargs='+', + default=[], + ), } diff --git a/freqtrade/commands/db_commands.py b/freqtrade/commands/db_commands.py index d93aafcb6..618b5cb6e 100644 --- a/freqtrade/commands/db_commands.py +++ b/freqtrade/commands/db_commands.py @@ -19,9 +19,9 @@ def start_convert_db(args: Dict[str, Any]) -> None: config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) - init_db(config['db_url'], False) + init_db(config['db_url']) session_target = Trade._session - init_db(config['db_url_from'], False) + init_db(config['db_url_from']) logger.info("Starting db migration.") trade_count = 0 diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index 2a5223917..eb761eeec 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -212,7 +212,7 @@ def start_show_trades(args: Dict[str, Any]) -> None: raise OperationalException("--db-url is required for this command.") logger.info(f'Using DB: "{parse_db_uri_for_logging(config["db_url"])}"') - init_db(config['db_url'], clean_open_orders=False) + init_db(config['db_url']) tfilter = [] if config.get('trade_ids'): diff --git a/freqtrade/configuration/check_exchange.py b/freqtrade/configuration/check_exchange.py index fa1f47f9b..2be13ce4f 100644 --- a/freqtrade/configuration/check_exchange.py +++ b/freqtrade/configuration/check_exchange.py @@ -27,7 +27,7 @@ def check_exchange(config: Dict[str, Any], check_for_bad: bool = True) -> bool: return True logger.info("Checking exchange...") - exchange = config.get('exchange', {}).get('name').lower() + exchange = config.get('exchange', {}).get('name', '').lower() if not exchange: raise OperationalException( f'This command requires a configured exchange. You should either use ' diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index e4c7b8f9d..d46d54cb0 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -95,6 +95,8 @@ class Configuration: self._process_data_options(config) + self._process_analyze_options(config) + # Check if the exchange set by the user is supported check_exchange(config, config.get('experimental', {}).get('block_bad_exchanges', True)) @@ -433,6 +435,19 @@ class Configuration: self._args_to_config(config, argname='candle_types', logstring='Detected --candle-types: {}') + def _process_analyze_options(self, config: Dict[str, Any]) -> None: + self._args_to_config(config, argname='analysis_groups', + logstring='Analysis reason groups: {}') + + self._args_to_config(config, argname='enter_reason_list', + logstring='Analysis enter tag list: {}') + + self._args_to_config(config, argname='exit_reason_list', + logstring='Analysis exit tag list: {}') + + self._args_to_config(config, argname='indicator_list', + logstring='Analysis indicator list: {}') + def _process_runmode(self, config: Dict[str, Any]) -> None: self._args_to_config(config, argname='dry_run', @@ -490,7 +505,8 @@ class Configuration: if not pairs_file.exists(): raise OperationalException(f'No pairs file found with path "{pairs_file}".') config['pairs'] = load_file(pairs_file) - config['pairs'].sort() + if isinstance(config['pairs'], list): + config['pairs'].sort() return if 'config' in self.args and self.args['config']: @@ -501,5 +517,5 @@ class Configuration: pairs_file = config['datadir'] / 'pairs.json' if pairs_file.exists(): config['pairs'] = load_file(pairs_file) - if 'pairs' in config: + if 'pairs' in config and isinstance(config['pairs'], list): config['pairs'].sort() diff --git a/freqtrade/configuration/deprecated_settings.py b/freqtrade/configuration/deprecated_settings.py index 70d29e2bd..e88383785 100644 --- a/freqtrade/configuration/deprecated_settings.py +++ b/freqtrade/configuration/deprecated_settings.py @@ -113,7 +113,7 @@ def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None: process_removed_setting(config, 'experimental', 'ignore_roi_if_buy_signal', None, 'ignore_roi_if_entry_signal') - process_removed_setting(config, 'ask_strategy', 'use_sell_signal', None, 'exit_sell_signal') + process_removed_setting(config, 'ask_strategy', 'use_sell_signal', None, 'use_exit_signal') process_removed_setting(config, 'ask_strategy', 'sell_profit_only', None, 'exit_profit_only') process_removed_setting(config, 'ask_strategy', 'sell_profit_offset', None, 'exit_profit_offset') diff --git a/freqtrade/configuration/directory_operations.py b/freqtrade/configuration/directory_operations.py index ca305c260..771fd53cc 100644 --- a/freqtrade/configuration/directory_operations.py +++ b/freqtrade/configuration/directory_operations.py @@ -15,7 +15,7 @@ def create_datadir(config: Dict[str, Any], datadir: Optional[str] = None) -> Pat folder = Path(datadir) if datadir else Path(f"{config['user_data_dir']}/data") if not datadir: # set datadir - exchange_name = config.get('exchange', {}).get('name').lower() + exchange_name = config.get('exchange', {}).get('name', '').lower() folder = folder.joinpath(exchange_name) if not folder.is_dir(): diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 372472db8..18dbea259 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -302,12 +302,12 @@ CONF_SCHEMA = { 'exit_fill': { 'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS, - 'default': 'off' + 'default': 'on' }, 'protection_trigger': { 'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS, - 'default': 'off' + 'default': 'on' }, 'protection_trigger_global': { 'type': 'string', @@ -336,6 +336,47 @@ CONF_SCHEMA = { 'webhookstatus': {'type': 'object'}, }, }, + 'discord': { + 'type': 'object', + 'properties': { + 'enabled': {'type': 'boolean'}, + 'webhook_url': {'type': 'string'}, + "exit_fill": { + 'type': 'array', 'items': {'type': 'object'}, + 'default': [ + {"Trade ID": "{trade_id}"}, + {"Exchange": "{exchange}"}, + {"Pair": "{pair}"}, + {"Direction": "{direction}"}, + {"Open rate": "{open_rate}"}, + {"Close rate": "{close_rate}"}, + {"Amount": "{amount}"}, + {"Open date": "{open_date:%Y-%m-%d %H:%M:%S}"}, + {"Close date": "{close_date:%Y-%m-%d %H:%M:%S}"}, + {"Profit": "{profit_amount} {stake_currency}"}, + {"Profitability": "{profit_ratio:.2%}"}, + {"Enter tag": "{enter_tag}"}, + {"Exit Reason": "{exit_reason}"}, + {"Strategy": "{strategy}"}, + {"Timeframe": "{timeframe}"}, + ] + }, + "entry_fill": { + 'type': 'array', 'items': {'type': 'object'}, + 'default': [ + {"Trade ID": "{trade_id}"}, + {"Exchange": "{exchange}"}, + {"Pair": "{pair}"}, + {"Direction": "{direction}"}, + {"Open rate": "{open_rate}"}, + {"Amount": "{amount}"}, + {"Open date": "{open_date:%Y-%m-%d %H:%M:%S}"}, + {"Enter tag": "{enter_tag}"}, + {"Strategy": "{strategy} {timeframe}"}, + ] + }, + } + }, 'api_server': { 'type': 'object', 'properties': { diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index e29d9ebe4..9e38f6833 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -26,7 +26,7 @@ BT_DATA_COLUMNS = ['pair', 'stake_amount', 'amount', 'open_date', 'close_date', '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', - 'is_short' + 'is_short', 'open_timestamp', 'close_timestamp', 'orders' ] @@ -283,6 +283,8 @@ def load_backtest_data(filename: Union[Path, str], strategy: Optional[str] = Non if 'enter_tag' not in df.columns: df['enter_tag'] = df['buy_tag'] df = df.drop(['buy_tag'], axis=1) + if 'orders' not in df.columns: + df.loc[:, 'orders'] = None else: # old format - only with lists. @@ -337,7 +339,7 @@ def trade_list_to_dataframe(trades: List[LocalTrade]) -> pd.DataFrame: :param trades: List of trade objects :return: Dataframe with BT_DATA_COLUMNS """ - df = pd.DataFrame.from_records([t.to_json() for t in trades], columns=BT_DATA_COLUMNS) + df = pd.DataFrame.from_records([t.to_json(True) for t in trades], columns=BT_DATA_COLUMNS) if len(df) > 0: df.loc[:, 'close_date'] = pd.to_datetime(df['close_date'], utc=True) df.loc[:, 'open_date'] = pd.to_datetime(df['open_date'], utc=True) @@ -353,7 +355,7 @@ def load_trades_from_db(db_url: str, strategy: Optional[str] = None) -> pd.DataF Can also serve as protection to load the correct result. :return: Dataframe containing Trades """ - init_db(db_url, clean_open_orders=False) + init_db(db_url) filters = [] if strategy: diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py new file mode 100755 index 000000000..b22c3f87e --- /dev/null +++ b/freqtrade/data/entryexitanalysis.py @@ -0,0 +1,227 @@ +import logging +from pathlib import Path +from typing import List, Optional + +import joblib +import pandas as pd +from tabulate import tabulate + +from freqtrade.data.btanalysis import (get_latest_backtest_filename, load_backtest_data, + load_backtest_stats) +from freqtrade.exceptions import OperationalException + + +logger = logging.getLogger(__name__) + + +def _load_signal_candles(backtest_dir: Path): + if backtest_dir.is_dir(): + scpf = Path(backtest_dir, + Path(get_latest_backtest_filename(backtest_dir)).stem + "_signals.pkl" + ) + else: + scpf = Path(backtest_dir.parent / f"{backtest_dir.stem}_signals.pkl") + + try: + scp = open(scpf, "rb") + signal_candles = joblib.load(scp) + logger.info(f"Loaded signal candles: {str(scpf)}") + except Exception as e: + logger.error("Cannot load signal candles from pickled results: ", e) + + return signal_candles + + +def _process_candles_and_indicators(pairlist, strategy_name, trades, signal_candles): + analysed_trades_dict = {} + analysed_trades_dict[strategy_name] = {} + + try: + logger.info(f"Processing {strategy_name} : {len(pairlist)} pairs") + + 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]) + except Exception as e: + print(f"Cannot process entry/exit reasons for {strategy_name}: ", e) + + return analysed_trades_dict + + +def _analyze_candles_and_indicators(pair, trades, signal_candles): + buyf = signal_candles + + if len(buyf) > 0: + buyf = buyf.set_index('date', drop=False) + trades_red = trades.loc[trades['pair'] == pair].copy() + + 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)] + if allinds.shape[0] > 0: + tmp_inds = allinds.iloc[[-1]] + + trades_red.loc[t, 'signal_date'] = tmp_inds['date'].values[0] + trades_red.loc[t, 'enter_reason'] = trades_red.loc[t, 'enter_tag'] + tmp_inds.index.rename('signal_date', inplace=True) + trades_inds = pd.concat([trades_inds, tmp_inds]) + + if 'signal_date' in trades_red: + trades_red['signal_date'] = pd.to_datetime(trades_red['signal_date'], utc=True) + trades_red.set_index('signal_date', inplace=True) + + try: + trades_red = pd.merge(trades_red, trades_inds, on='signal_date', how='outer') + except Exception as e: + raise e + return trades_red + else: + return pd.DataFrame() + + +def _do_group_table_output(bigdf, glist): + for g in glist: + # 0: summary wins/losses grouped by enter tag + if g == "0": + group_mask = ['enter_reason'] + wins = bigdf.loc[bigdf['profit_abs'] >= 0] \ + .groupby(group_mask) \ + .agg({'profit_abs': ['sum']}) + + wins.columns = ['profit_abs_wins'] + loss = bigdf.loc[bigdf['profit_abs'] < 0] \ + .groupby(group_mask) \ + .agg({'profit_abs': ['sum']}) + loss.columns = ['profit_abs_loss'] + + new = bigdf.groupby(group_mask).agg({'profit_abs': [ + 'count', + lambda x: sum(x > 0), + lambda x: sum(x <= 0)]}) + new = pd.concat([new, wins, loss], axis=1).fillna(0) + + new['profit_tot'] = new['profit_abs_wins'] - abs(new['profit_abs_loss']) + new['wl_ratio_pct'] = (new.iloc[:, 1] / new.iloc[:, 0] * 100).fillna(0) + new['avg_win'] = (new['profit_abs_wins'] / new.iloc[:, 1]).fillna(0) + new['avg_loss'] = (new['profit_abs_loss'] / new.iloc[:, 2]).fillna(0) + + new.columns = ['total_num_buys', 'wins', 'losses', 'profit_abs_wins', 'profit_abs_loss', + 'profit_tot', 'wl_ratio_pct', 'avg_win', 'avg_loss'] + + sortcols = ['total_num_buys'] + + _print_table(new, sortcols, show_index=True) + + else: + agg_mask = {'profit_abs': ['count', 'sum', 'median', 'mean'], + 'profit_ratio': ['sum', 'median', 'mean']} + agg_cols = ['num_buys', 'profit_abs_sum', 'profit_abs_median', + 'profit_abs_mean', 'median_profit_pct', 'mean_profit_pct', + 'total_profit_pct'] + sortcols = ['profit_abs_sum', 'enter_reason'] + + # 1: profit summaries grouped by enter_tag + if g == "1": + group_mask = ['enter_reason'] + + # 2: profit summaries grouped by enter_tag and exit_tag + if g == "2": + group_mask = ['enter_reason', 'exit_reason'] + + # 3: profit summaries grouped by pair and enter_tag + if g == "3": + group_mask = ['pair', 'enter_reason'] + + # 4: profit summaries grouped by pair, enter_ and exit_tag (this can get quite large) + if g == "4": + group_mask = ['pair', 'enter_reason', 'exit_reason'] + if group_mask: + new = bigdf.groupby(group_mask).agg(agg_mask).reset_index() + new.columns = group_mask + agg_cols + new['median_profit_pct'] = new['median_profit_pct'] * 100 + new['mean_profit_pct'] = new['mean_profit_pct'] * 100 + new['total_profit_pct'] = new['total_profit_pct'] * 100 + + _print_table(new, sortcols) + else: + logger.warning("Invalid group mask specified.") + + +def _print_results(analysed_trades, stratname, analysis_groups, + enter_reason_list, exit_reason_list, + indicator_list, columns=None): + if columns is None: + columns = ['pair', 'open_date', 'close_date', 'profit_abs', 'enter_reason', 'exit_reason'] + + bigdf = pd.DataFrame() + for pair, trades in analysed_trades[stratname].items(): + bigdf = pd.concat([bigdf, trades], ignore_index=True) + + if bigdf.shape[0] > 0 and ('enter_reason' in bigdf.columns): + if analysis_groups: + _do_group_table_output(bigdf, analysis_groups) + + if enter_reason_list and "all" not in enter_reason_list: + bigdf = bigdf.loc[(bigdf['enter_reason'].isin(enter_reason_list))] + + if exit_reason_list and "all" not in exit_reason_list: + bigdf = bigdf.loc[(bigdf['exit_reason'].isin(exit_reason_list))] + + if "all" in indicator_list: + print(bigdf) + elif indicator_list is not None: + available_inds = [] + for ind in indicator_list: + if ind in bigdf: + available_inds.append(ind) + ilist = ["pair", "enter_reason", "exit_reason"] + available_inds + _print_table(bigdf[ilist], sortcols=['exit_reason'], show_index=False) + else: + print("\\_ No trades to show") + + +def _print_table(df, sortcols=None, show_index=False): + if (sortcols is not None): + data = df.sort_values(sortcols) + else: + data = df + + print( + tabulate( + data, + headers='keys', + tablefmt='psql', + showindex=show_index + ) + ) + + +def process_entry_exit_reasons(backtest_dir: Path, + pairlist: List[str], + analysis_groups: Optional[List[str]] = ["0", "1", "2"], + enter_reason_list: Optional[List[str]] = ["all"], + exit_reason_list: Optional[List[str]] = ["all"], + indicator_list: Optional[List[str]] = []): + try: + backtest_stats = load_backtest_stats(backtest_dir) + for strategy_name, results in backtest_stats['strategy'].items(): + trades = load_backtest_data(backtest_dir, strategy_name) + + if not trades.empty: + signal_candles = _load_signal_candles(backtest_dir) + analysed_trades_dict = _process_candles_and_indicators(pairlist, strategy_name, + trades, signal_candles) + _print_results(analysed_trades_dict, + strategy_name, + analysis_groups, + enter_reason_list, + exit_reason_list, + indicator_list) + + except ValueError as e: + raise OperationalException(e) from e diff --git a/freqtrade/data/history/history_utils.py b/freqtrade/data/history/history_utils.py index eb36d2042..c972c841c 100644 --- a/freqtrade/data/history/history_utils.py +++ b/freqtrade/data/history/history_utils.py @@ -68,7 +68,8 @@ def load_data(datadir: Path, startup_candles: int = 0, fail_without_data: bool = False, data_format: str = 'json', - candle_type: CandleType = CandleType.SPOT + candle_type: CandleType = CandleType.SPOT, + user_futures_funding_rate: int = None, ) -> Dict[str, DataFrame]: """ Load ohlcv history data for a list of pairs. @@ -100,6 +101,10 @@ def load_data(datadir: Path, ) if not hist.empty: result[pair] = hist + else: + if candle_type is CandleType.FUNDING_RATE and user_futures_funding_rate is not None: + logger.warn(f"{pair} using user specified [{user_futures_funding_rate}]") + result[pair] = DataFrame(columns=["open", "close", "high", "low", "volume"]) if fail_without_data and not result: raise OperationalException("No data found. Terminating.") @@ -216,7 +221,7 @@ def _download_pair_history(pair: str, *, prepend=prepend) logger.info(f'({process}) - Download history data for "{pair}", {timeframe}, ' - f'{candle_type} and store in {datadir}.' + f'{candle_type} and store in {datadir}. ' f'From {format_ms_time(since_ms) if since_ms else "start"} to ' f'{format_ms_time(until_ms) if until_ms else "now"}' ) @@ -277,6 +282,7 @@ def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes pairs_not_available = [] data_handler = get_datahandler(datadir, data_format) candle_type = CandleType.get_default(trading_mode) + process = '' for idx, pair in enumerate(pairs, start=1): if pair not in exchange.markets: pairs_not_available.append(pair) diff --git a/freqtrade/enums/exitchecktuple.py b/freqtrade/enums/exitchecktuple.py index c245a05da..cb6411caf 100644 --- a/freqtrade/enums/exitchecktuple.py +++ b/freqtrade/enums/exitchecktuple.py @@ -15,3 +15,9 @@ class ExitCheckTuple: @property def exit_flag(self): return self.exit_type != ExitType.NONE + + def __eq__(self, other): + return self.exit_type == other.exit_type and self.exit_reason == other.exit_reason + + def __repr__(self): + return f"ExitCheckTuple({self.exit_type}, {self.exit_reason})" diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 69ae5198a..37a3c419d 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -52,12 +52,17 @@ class Binance(Exchange): ordertype = 'stop' if self.trading_mode == TradingMode.FUTURES else 'stop_loss_limit' - return order['type'] == ordertype and ( - (side == "sell" and stop_loss > float(order['info']['stopPrice'])) or - (side == "buy" and stop_loss < float(order['info']['stopPrice'])) - ) + return ( + order.get('stopPrice', None) is None + or ( + order['type'] == ordertype + and ( + (side == "sell" and stop_loss > float(order['stopPrice'])) or + (side == "buy" and stop_loss < float(order['stopPrice'])) + ) + )) - def get_tickers(self, symbols: List[str] = None, cached: bool = False) -> Dict: + def get_tickers(self, symbols: Optional[List[str]] = None, cached: bool = False) -> Dict: tickers = super().get_tickers(symbols=symbols, cached=cached) if self.trading_mode == TradingMode.FUTURES: # Binance's future result has no bid/ask values. @@ -95,7 +100,7 @@ class Binance(Exchange): async def _async_get_historic_ohlcv(self, pair: str, timeframe: str, since_ms: int, candle_type: CandleType, is_new_pair: bool = False, raise_: bool = False, - until_ms: int = None + until_ms: Optional[int] = None ) -> Tuple[str, str, str, List]: """ Overwrite to introduce "fast new pair" functionality by detecting the pair's listing date diff --git a/freqtrade/exchange/binance_leverage_tiers.json b/freqtrade/exchange/binance_leverage_tiers.json index ddffe1250..126b3b62f 100644 --- a/freqtrade/exchange/binance_leverage_tiers.json +++ b/freqtrade/exchange/binance_leverage_tiers.json @@ -1,91 +1,195 @@ { "RAY/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "386950.0" + } + } + ], + "API3/USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "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": "75.0" + } + }, + { + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "100000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "700.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "250000", + "notionalFloor": "100000", + "maintMarginRatio": "0.1", + "cum": "5700.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 2.0, + "info": { + "bracket": "5", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "250000", + "maintMarginRatio": "0.125", + "cum": "11950.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "6", + "initialLeverage": "1", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -93,106 +197,113 @@ ], "SUSHI/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 50000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "2000000", + "notionalCap": "50000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } @@ -200,91 +311,97 @@ ], "CVC/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -292,91 +409,97 @@ ], "BTS/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -384,91 +507,97 @@ ], "HOT/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -476,91 +605,97 @@ ], "ZRX/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -568,91 +703,97 @@ ], "QTUM/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -660,91 +801,97 @@ ], "IOTA/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -752,151 +899,161 @@ ], "BTC/BUSD": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "BUSD", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.004, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.004", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 2.0, + "currency": "BUSD", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.005, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "2", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.005", "cum": "50.0" } }, { - "tier": 3, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 3.0, + "currency": "BUSD", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "3", "initialLeverage": "20", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.01", "cum": "1300.0" } }, { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 7500000, + "tier": 4.0, + "currency": "BUSD", + "minNotional": 1000000.0, + "maxNotional": 7500000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "4", "initialLeverage": "10", - "maxNotional": "7500000", - "minNotional": "1000000", + "notionalCap": "7500000", + "notionalFloor": "1000000", "maintMarginRatio": "0.025", "cum": "16300.0" } }, { - "tier": 5, - "minNotional": 7500000, - "maxNotional": 40000000, + "tier": 5.0, + "currency": "BUSD", + "minNotional": 7500000.0, + "maxNotional": 40000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 6, + "maxLeverage": 6.0, "info": { "bracket": "5", "initialLeverage": "6", - "maxNotional": "40000000", - "minNotional": "7500000", + "notionalCap": "40000000", + "notionalFloor": "7500000", "maintMarginRatio": "0.05", "cum": "203800.0" } }, { - "tier": 6, - "minNotional": 40000000, - "maxNotional": 100000000, + "tier": 6.0, + "currency": "BUSD", + "minNotional": 40000000.0, + "maxNotional": 100000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "maxNotional": "100000000", - "minNotional": "40000000", + "notionalCap": "100000000", + "notionalFloor": "40000000", "maintMarginRatio": "0.1", "cum": "2203800.0" } }, { - "tier": 7, - "minNotional": 100000000, - "maxNotional": 200000000, + "tier": 7.0, + "currency": "BUSD", + "minNotional": 100000000.0, + "maxNotional": 200000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "maxNotional": "200000000", - "minNotional": "100000000", + "notionalCap": "200000000", + "notionalFloor": "100000000", "maintMarginRatio": "0.125", "cum": "4703800.0" } }, { - "tier": 8, - "minNotional": 200000000, - "maxNotional": 400000000, + "tier": 8.0, + "currency": "BUSD", + "minNotional": 200000000.0, + "maxNotional": 400000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "8", "initialLeverage": "3", - "maxNotional": "400000000", - "minNotional": "200000000", + "notionalCap": "400000000", + "notionalFloor": "200000000", "maintMarginRatio": "0.15", "cum": "9703800.0" } }, { - "tier": 9, - "minNotional": 400000000, - "maxNotional": 600000000, + "tier": 9.0, + "currency": "BUSD", + "minNotional": 400000000.0, + "maxNotional": 600000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "9", "initialLeverage": "2", - "maxNotional": "600000000", - "minNotional": "400000000", + "notionalCap": "600000000", + "notionalFloor": "400000000", "maintMarginRatio": "0.25", "cum": "4.97038E7" } }, { - "tier": 10, - "minNotional": 600000000, - "maxNotional": 1000000000, + "tier": 10.0, + "currency": "BUSD", + "minNotional": 600000000.0, + "maxNotional": 1000000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "10", "initialLeverage": "1", - "maxNotional": "1000000000", - "minNotional": "600000000", + "notionalCap": "1000000000", + "notionalFloor": "600000000", "maintMarginRatio": "0.5", "cum": "1.997038E8" } @@ -904,91 +1061,97 @@ ], "WAVES/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -996,136 +1159,145 @@ ], "ADA/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, + "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "maxNotional": "10000", - "minNotional": "0", + "notionalCap": "10000", + "notionalFloor": "0", "maintMarginRatio": "0.0065", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 10000, - "maxNotional": 50000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "10000", + "notionalCap": "50000", + "notionalFloor": "10000", "maintMarginRatio": "0.01", "cum": "35.0" } }, { - "tier": 3, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "535.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "4", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8035.0" } }, { - "tier": 5, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "5", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58035.0" } }, { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "6", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108035.0" } }, { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "7", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.15", "cum": "233035.0" } }, { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1233035.0" } }, { - "tier": 9, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 9.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6233035.0" } @@ -1133,183 +1305,97 @@ ], "LIT/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", - "maintMarginRatio": "0.5", - "cum": "386950.0" - } - } - ], - "NU/USDT": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, - "maintenanceMarginRate": 0.01, - "maxLeverage": 25, - "info": { - "bracket": "1", - "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", - "maintMarginRatio": "0.01", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20, - "info": { - "bracket": "2", - "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", - "maintMarginRatio": "0.025", - "cum": "75.0" - } - }, - { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "3", - "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", - "maintMarginRatio": "0.05", - "cum": "700.0" - } - }, - { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "4", - "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", - "maintMarginRatio": "0.1", - "cum": "5700.0" - } - }, - { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 2, - "info": { - "bracket": "5", - "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", - "maintMarginRatio": "0.125", - "cum": "11950.0" - } - }, - { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1, - "info": { - "bracket": "6", - "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -1317,136 +1403,145 @@ ], "XTZ/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, + "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "maxNotional": "10000", - "minNotional": "0", + "notionalCap": "10000", + "notionalFloor": "0", "maintMarginRatio": "0.0065", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 10000, - "maxNotional": 50000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "10000", + "notionalCap": "50000", + "notionalFloor": "10000", "maintMarginRatio": "0.01", "cum": "35.0" } }, { - "tier": 3, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "535.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "4", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8035.0" } }, { - "tier": 5, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "5", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58035.0" } }, { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "6", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108035.0" } }, { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "7", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.15", "cum": "233035.0" } }, { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1233035.0" } }, { - "tier": 9, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 9.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6233035.0" } @@ -1454,136 +1549,145 @@ ], "BNB/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, + "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "maxNotional": "10000", - "minNotional": "0", + "notionalCap": "10000", + "notionalFloor": "0", "maintMarginRatio": "0.0065", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 10000, - "maxNotional": 50000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "10000", + "notionalCap": "50000", + "notionalFloor": "10000", "maintMarginRatio": "0.01", "cum": "35.0" } }, { - "tier": 3, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "535.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "4", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8035.0" } }, { - "tier": 5, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "5", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58035.0" } }, { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "6", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108035.0" } }, { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "7", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.15", "cum": "233035.0" } }, { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1233035.0" } }, { - "tier": 9, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 9.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6233035.0" } @@ -1591,183 +1695,293 @@ ], "AKRO/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.012, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.012", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "65.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "690.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5690.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11940.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386940.0" } } ], - "HNT/USDT": [ + "DAR/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "386950.0" + } + } + ], + "HNT/USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 50.0, + "info": { + "bracket": "1", + "initialLeverage": "50", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "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": "75.0" + } + }, + { + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "100000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "700.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "250000", + "notionalFloor": "100000", + "maintMarginRatio": "0.1", + "cum": "5700.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 2.0, + "info": { + "bracket": "5", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "250000", + "maintMarginRatio": "0.125", + "cum": "11950.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "6", + "initialLeverage": "1", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -1775,136 +1989,145 @@ ], "ETC/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, + "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "maxNotional": "10000", - "minNotional": "0", + "notionalCap": "10000", + "notionalFloor": "0", "maintMarginRatio": "0.0065", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 10000, - "maxNotional": 50000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "10000", + "notionalCap": "50000", + "notionalFloor": "10000", "maintMarginRatio": "0.01", "cum": "35.0" } }, { - "tier": 3, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "535.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "4", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8035.0" } }, { - "tier": 5, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "5", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58035.0" } }, { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "6", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108035.0" } }, { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "7", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.15", "cum": "233035.0" } }, { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1233035.0" } }, { - "tier": 9, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 9.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6233035.0" } @@ -1912,136 +2135,145 @@ ], "XMR/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, + "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "maxNotional": "10000", - "minNotional": "0", + "notionalCap": "10000", + "notionalFloor": "0", "maintMarginRatio": "0.0065", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 10000, - "maxNotional": 50000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "10000", + "notionalCap": "50000", + "notionalFloor": "10000", "maintMarginRatio": "0.01", "cum": "35.0" } }, { - "tier": 3, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "535.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "4", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8035.0" } }, { - "tier": 5, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "5", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58035.0" } }, { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "6", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108035.0" } }, { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "7", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.15", "cum": "233035.0" } }, { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1233035.0" } }, { - "tier": 9, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 9.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6233035.0" } @@ -2049,91 +2281,97 @@ ], "YFI/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -2141,365 +2379,259 @@ ], "FTT/BUSD": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 100000, + "tier": 1.0, + "currency": "BUSD", + "minNotional": 0.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "1", "initialLeverage": "20", - "maxNotional": "100000", - "minNotional": "0", + "notionalCap": "100000", + "notionalFloor": "0", "maintMarginRatio": "0.025", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 100000, - "maxNotional": 500000, + "tier": 2.0, + "currency": "BUSD", + "minNotional": 100000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "2", "initialLeverage": "10", - "maxNotional": "500000", - "minNotional": "100000", + "notionalCap": "500000", + "notionalFloor": "100000", "maintMarginRatio": "0.05", "cum": "2500.0" } }, { - "tier": 3, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 3.0, + "currency": "BUSD", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "3", "initialLeverage": "5", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.1", "cum": "27500.0" } }, { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 4.0, + "currency": "BUSD", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "4", "initialLeverage": "3", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.15", "cum": "77500.0" } }, { - "tier": 5, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 5.0, + "currency": "BUSD", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.25", "cum": "277500.0" } }, { - "tier": 6, - "minNotional": 5000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "BUSD", + "minNotional": 5000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "5000000", + "notionalCap": "30000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.5", "cum": "1527500.0" } } ], - "BTCUSDT_210326": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, - "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, - "info": { - "bracket": "1", - "initialLeverage": "75", - "maxNotional": "10000", - "minNotional": "0", - "maintMarginRatio": "0.0065", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 10000, - "maxNotional": 50000, - "maintenanceMarginRate": 0.01, - "maxLeverage": 50, - "info": { - "bracket": "2", - "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "10000", - "maintMarginRatio": "0.01", - "cum": "35.0" - } - }, - { - "tier": 3, - "minNotional": 50000, - "maxNotional": 250000, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25, - "info": { - "bracket": "3", - "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", - "maintMarginRatio": "0.02", - "cum": "535.0" - } - }, - { - "tier": 4, - "minNotional": 250000, - "maxNotional": 1000000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "4", - "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", - "maintMarginRatio": "0.05", - "cum": "8035.0" - } - }, - { - "tier": 5, - "minNotional": 1000000, - "maxNotional": 2000000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "5", - "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", - "maintMarginRatio": "0.1", - "cum": "58035.0" - } - }, - { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4, - "info": { - "bracket": "6", - "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", - "maintMarginRatio": "0.125", - "cum": "108035.0" - } - }, - { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3, - "info": { - "bracket": "7", - "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", - "maintMarginRatio": "0.15", - "cum": "233035.0" - } - }, - { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 9223372036854776000, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2, - "info": { - "bracket": "8", - "initialLeverage": "2", - "maxNotional": "9223372036854775807", - "minNotional": "10000000", - "maintMarginRatio": "0.25", - "cum": "1233035.0" - } - } - ], "ETH/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.005, - "maxLeverage": 100, + "maxLeverage": 100.0, "info": { "bracket": "1", "initialLeverage": "100", - "maxNotional": "10000", - "minNotional": "0", + "notionalCap": "10000", + "notionalFloor": "0", "maintMarginRatio": "0.005", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 10000, - "maxNotional": 100000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, + "maxLeverage": 75.0, "info": { "bracket": "2", "initialLeverage": "75", - "maxNotional": "100000", - "minNotional": "10000", + "notionalCap": "100000", + "notionalFloor": "10000", "maintMarginRatio": "0.0065", "cum": "15.0" } }, { - "tier": 3, - "minNotional": 100000, - "maxNotional": 500000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "3", "initialLeverage": "50", - "maxNotional": "500000", - "minNotional": "100000", + "notionalCap": "500000", + "notionalFloor": "100000", "maintMarginRatio": "0.01", "cum": "365.0" } }, { - "tier": 4, - "minNotional": 500000, - "maxNotional": 1500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1500000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "4", "initialLeverage": "25", - "maxNotional": "1500000", - "minNotional": "500000", + "notionalCap": "1500000", + "notionalFloor": "500000", "maintMarginRatio": "0.02", "cum": "5365.0" } }, { - "tier": 5, - "minNotional": 1500000, - "maxNotional": 4000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "maxNotional": "4000000", - "minNotional": "1500000", + "notionalCap": "4000000", + "notionalFloor": "1500000", "maintMarginRatio": "0.05", "cum": "50365.0" } }, { - "tier": 6, - "minNotional": 4000000, - "maxNotional": 10000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 4000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "maxNotional": "10000000", - "minNotional": "4000000", + "notionalCap": "10000000", + "notionalFloor": "4000000", "maintMarginRatio": "0.1", "cum": "250365.0" } }, { - "tier": 7, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.125", "cum": "500365.0" } }, { - "tier": 8, - "minNotional": 20000000, - "maxNotional": 40000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 40000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "8", "initialLeverage": "3", - "maxNotional": "40000000", - "minNotional": "20000000", + "notionalCap": "40000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.15", "cum": "1000365.0" } }, { - "tier": 9, - "minNotional": 40000000, - "maxNotional": 150000000, + "tier": 9.0, + "currency": "USDT", + "minNotional": 40000000.0, + "maxNotional": 150000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "9", "initialLeverage": "2", - "maxNotional": "150000000", - "minNotional": "40000000", + "notionalCap": "150000000", + "notionalFloor": "40000000", "maintMarginRatio": "0.25", "cum": "5000365.0" } }, { - "tier": 10, - "minNotional": 150000000, - "maxNotional": 500000000, + "tier": 10.0, + "currency": "USDT", + "minNotional": 150000000.0, + "maxNotional": 500000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "10", "initialLeverage": "1", - "maxNotional": "500000000", - "minNotional": "150000000", + "notionalCap": "500000000", + "notionalFloor": "150000000", "maintMarginRatio": "0.5", "cum": "4.2500365E7" } @@ -2507,106 +2639,113 @@ ], "ALICE/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "2000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } @@ -2614,91 +2753,195 @@ ], "ALPHA/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "386950.0" + } + } + ], + "WOO/USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "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": "75.0" + } + }, + { + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "100000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "700.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "250000", + "notionalFloor": "100000", + "maintMarginRatio": "0.1", + "cum": "5700.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 2.0, + "info": { + "bracket": "5", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "250000", + "maintMarginRatio": "0.125", + "cum": "11950.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "6", + "initialLeverage": "1", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -2706,91 +2949,97 @@ ], "SFP/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -2798,91 +3047,97 @@ ], "REEF/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -2890,91 +3145,97 @@ ], "BAT/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -2982,106 +3243,113 @@ ], "DOGE/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "7000.0" } }, { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "57000.0" } }, { - "tier": 5, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "107000.0" } }, { - "tier": 6, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.25", "cum": "732000.0" } }, { - "tier": 7, - "minNotional": 10000000, - "maxNotional": 50000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "10000000", + "notionalCap": "50000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.5", "cum": "3232000.0" } @@ -3089,136 +3357,145 @@ ], "TRX/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, + "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "maxNotional": "10000", - "minNotional": "0", + "notionalCap": "10000", + "notionalFloor": "0", "maintMarginRatio": "0.0065", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 10000, - "maxNotional": 50000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "10000", + "notionalCap": "50000", + "notionalFloor": "10000", "maintMarginRatio": "0.01", "cum": "35.0" } }, { - "tier": 3, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "535.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "4", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8035.0" } }, { - "tier": 5, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "5", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58035.0" } }, { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "6", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108035.0" } }, { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "7", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.15", "cum": "233035.0" } }, { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1233035.0" } }, { - "tier": 9, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 9.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6233035.0" } @@ -3226,275 +3503,195 @@ ], "RLC/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } } ], - "DOTECOUSDT": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, - "maintenanceMarginRate": 0.012, - "maxLeverage": 20, - "info": { - "bracket": "1", - "initialLeverage": "20", - "maxNotional": "5000", - "minNotional": "0", - "maintMarginRatio": "0.012", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, - "maintenanceMarginRate": 0.025, - "maxLeverage": 10, - "info": { - "bracket": "2", - "initialLeverage": "10", - "maxNotional": "25000", - "minNotional": "5000", - "maintMarginRatio": "0.025", - "cum": "65.0" - } - }, - { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 5, - "info": { - "bracket": "3", - "initialLeverage": "5", - "maxNotional": "100000", - "minNotional": "25000", - "maintMarginRatio": "0.05", - "cum": "690.0" - } - }, - { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 4, - "info": { - "bracket": "4", - "initialLeverage": "4", - "maxNotional": "250000", - "minNotional": "100000", - "maintMarginRatio": "0.1", - "cum": "5690.0" - } - }, - { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 2, - "info": { - "bracket": "5", - "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", - "maintMarginRatio": "0.125", - "cum": "11940.0" - } - }, - { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 9223372036854776000, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1, - "info": { - "bracket": "6", - "initialLeverage": "1", - "maxNotional": "9223372036854775807", - "minNotional": "1000000", - "maintMarginRatio": "0.5", - "cum": "386940.0" - } - } - ], "BTCSTUSDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 9223372036854776000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 9.223372036854776e+18, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "9223372036854775807", - "minNotional": "1000000", + "notionalCap": "9223372036854775807", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -3502,91 +3699,97 @@ ], "STORJ/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -3594,275 +3797,195 @@ ], "SNX/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } } ], - "ETHUSDT_210625": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 250000, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25, - "info": { - "bracket": "1", - "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "0", - "maintMarginRatio": "0.02", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 250000, - "maxNotional": 1000000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "2", - "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", - "maintMarginRatio": "0.05", - "cum": "7500.0" - } - }, - { - "tier": 3, - "minNotional": 1000000, - "maxNotional": 2000000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "3", - "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", - "maintMarginRatio": "0.1", - "cum": "57500.0" - } - }, - { - "tier": 4, - "minNotional": 2000000, - "maxNotional": 5000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4, - "info": { - "bracket": "4", - "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", - "maintMarginRatio": "0.125", - "cum": "107500.0" - } - }, - { - "tier": 5, - "minNotional": 5000000, - "maxNotional": 10000000, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3, - "info": { - "bracket": "5", - "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", - "maintMarginRatio": "0.15", - "cum": "232500.0" - } - }, - { - "tier": 6, - "minNotional": 10000000, - "maxNotional": 9223372036854776000, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2, - "info": { - "bracket": "6", - "initialLeverage": "2", - "maxNotional": "9223372036854775807", - "minNotional": "10000000", - "maintMarginRatio": "0.25", - "cum": "1232500.0" - } - } - ], "1000XEC/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -3870,457 +3993,505 @@ ], "AUDIO/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } } ], + "NEAR/BUSD": [ + { + "tier": 1.0, + "currency": "BUSD", + "minNotional": 0.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "1", + "initialLeverage": "20", + "notionalCap": "25000", + "notionalFloor": "0", + "maintMarginRatio": "0.025", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "currency": "BUSD", + "minNotional": 25000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "2", + "initialLeverage": "10", + "notionalCap": "100000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "625.0" + } + }, + { + "tier": 3.0, + "currency": "BUSD", + "minNotional": 100000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "3", + "initialLeverage": "5", + "notionalCap": "250000", + "notionalFloor": "100000", + "maintMarginRatio": "0.1", + "cum": "5625.0" + } + }, + { + "tier": 4.0, + "currency": "BUSD", + "minNotional": 250000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 2.0, + "info": { + "bracket": "4", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "250000", + "maintMarginRatio": "0.125", + "cum": "11875.0" + } + }, + { + "tier": 5.0, + "currency": "BUSD", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "5", + "initialLeverage": "1", + "notionalCap": "30000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "386875.0" + } + } + ], "XLM/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, + "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "maxNotional": "10000", - "minNotional": "0", + "notionalCap": "10000", + "notionalFloor": "0", "maintMarginRatio": "0.0065", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 10000, - "maxNotional": 50000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "10000", + "notionalCap": "50000", + "notionalFloor": "10000", "maintMarginRatio": "0.01", "cum": "35.0" } }, { - "tier": 3, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "535.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "4", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8035.0" } }, { - "tier": 5, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "5", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58035.0" } }, { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "6", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108035.0" } }, { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "7", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.15", "cum": "233035.0" } }, { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1233035.0" } }, { - "tier": 9, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 9.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6233035.0" } } ], - "BTCBUSD_210129": [ + "APE/BUSD": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, - "maintenanceMarginRate": 0.004, - "maxLeverage": 20, + "tier": 1.0, + "currency": "BUSD", + "minNotional": 0.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, "info": { "bracket": "1", "initialLeverage": "20", - "maxNotional": "5000", - "minNotional": "0", - "maintMarginRatio": "0.004", + "notionalCap": "25000", + "notionalFloor": "0", + "maintMarginRatio": "0.025", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, - "maintenanceMarginRate": 0.005, - "maxLeverage": 15, + "tier": 2.0, + "currency": "BUSD", + "minNotional": 25000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, "info": { "bracket": "2", - "initialLeverage": "15", - "maxNotional": "25000", - "minNotional": "5000", - "maintMarginRatio": "0.005", - "cum": "5.0" + "initialLeverage": "10", + "notionalCap": "100000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "625.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, - "maintenanceMarginRate": 0.01, - "maxLeverage": 10, + "tier": 3.0, + "currency": "BUSD", + "minNotional": 100000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, "info": { "bracket": "3", - "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", - "maintMarginRatio": "0.01", - "cum": "130.0" + "initialLeverage": "5", + "notionalCap": "250000", + "notionalFloor": "100000", + "maintMarginRatio": "0.1", + "cum": "5625.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 500000, - "maintenanceMarginRate": 0.025, - "maxLeverage": 7, + "tier": 4.0, + "currency": "BUSD", + "minNotional": 250000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 2.0, "info": { "bracket": "4", - "initialLeverage": "7", - "maxNotional": "500000", - "minNotional": "100000", - "maintMarginRatio": "0.025", - "cum": "1630.0" + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "250000", + "maintMarginRatio": "0.125", + "cum": "11875.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 2000000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 6, + "tier": 5.0, + "currency": "BUSD", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, "info": { "bracket": "5", - "initialLeverage": "6", - "maxNotional": "2000000", - "minNotional": "500000", - "maintMarginRatio": "0.05", - "cum": "14130.0" - } - }, - { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "6", - "initialLeverage": "5", - "maxNotional": "5000000", - "minNotional": "2000000", - "maintMarginRatio": "0.1", - "cum": "114130.0" - } - }, - { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4, - "info": { - "bracket": "7", - "initialLeverage": "4", - "maxNotional": "10000000", - "minNotional": "5000000", - "maintMarginRatio": "0.125", - "cum": "239130.0" - } - }, - { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 20000000, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3, - "info": { - "bracket": "8", - "initialLeverage": "3", - "maxNotional": "20000000", - "minNotional": "10000000", - "maintMarginRatio": "0.15", - "cum": "489130.0" - } - }, - { - "tier": 9, - "minNotional": 20000000, - "maxNotional": 9223372036854776000, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2, - "info": { - "bracket": "9", - "initialLeverage": "2", - "maxNotional": "9223372036854775807", - "minNotional": "20000000", - "maintMarginRatio": "0.25", - "cum": "2489130.0" + "initialLeverage": "1", + "notionalCap": "30000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "386875.0" } } ], "IOTX/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -4328,91 +4499,97 @@ ], "NEO/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -4420,91 +4597,97 @@ ], "UNFI/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -4512,106 +4695,113 @@ ], "SAND/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "2000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } @@ -4619,91 +4809,97 @@ ], "DASH/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -4711,91 +4907,97 @@ ], "KAVA/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -4803,183 +5005,309 @@ ], "RUNE/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } } ], - "CTK/USDT": [ + "APE/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "150000", + "notionalFloor": "50000", + "maintMarginRatio": "0.025", + "cum": "750.0" + } + }, + { + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "250000", + "notionalFloor": "150000", + "maintMarginRatio": "0.05", + "cum": "4500.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "500000", + "notionalFloor": "250000", + "maintMarginRatio": "0.1", + "cum": "17000.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": "29500.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "6", + "initialLeverage": "2", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.25", + "cum": "154500.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", + "initialLeverage": "1", + "notionalCap": "30000000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.5", + "cum": "654500.0" + } + } + ], + "CTK/USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 50.0, + "info": { + "bracket": "1", + "initialLeverage": "50", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "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": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -4987,136 +5315,145 @@ ], "LINK/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, + "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "maxNotional": "10000", - "minNotional": "0", + "notionalCap": "10000", + "notionalFloor": "0", "maintMarginRatio": "0.0065", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 10000, - "maxNotional": 50000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "10000", + "notionalCap": "50000", + "notionalFloor": "10000", "maintMarginRatio": "0.01", "cum": "35.0" } }, { - "tier": 3, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "535.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "4", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8035.0" } }, { - "tier": 5, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "5", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58035.0" } }, { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "6", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108035.0" } }, { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "7", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.15", "cum": "233035.0" } }, { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1233035.0" } }, { - "tier": 9, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 9.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6233035.0" } @@ -5124,106 +5461,227 @@ ], "CELR/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "2000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.5", + "cum": "654500.0" + } + } + ], + "BNX/USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 50.0, + "info": { + "bracket": "1", + "initialLeverage": "50", + "notionalCap": "50000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "2", + "initialLeverage": "20", + "notionalCap": "150000", + "notionalFloor": "50000", + "maintMarginRatio": "0.025", + "cum": "750.0" + } + }, + { + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "250000", + "notionalFloor": "150000", + "maintMarginRatio": "0.05", + "cum": "4500.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "500000", + "notionalFloor": "250000", + "maintMarginRatio": "0.1", + "cum": "17000.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": "29500.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "6", + "initialLeverage": "2", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.25", + "cum": "154500.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 50000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", + "initialLeverage": "1", + "notionalCap": "50000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } @@ -5231,91 +5689,97 @@ ], "RSR/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -5323,91 +5787,97 @@ ], "ADA/BUSD": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 100000, + "tier": 1.0, + "currency": "BUSD", + "minNotional": 0.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "1", "initialLeverage": "20", - "maxNotional": "100000", - "minNotional": "0", + "notionalCap": "100000", + "notionalFloor": "0", "maintMarginRatio": "0.025", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 100000, - "maxNotional": 500000, + "tier": 2.0, + "currency": "BUSD", + "minNotional": 100000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "2", "initialLeverage": "10", - "maxNotional": "500000", - "minNotional": "100000", + "notionalCap": "500000", + "notionalFloor": "100000", "maintMarginRatio": "0.05", "cum": "2500.0" } }, { - "tier": 3, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 3.0, + "currency": "BUSD", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "3", "initialLeverage": "5", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.1", "cum": "27500.0" } }, { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 4.0, + "currency": "BUSD", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "4", "initialLeverage": "3", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.15", "cum": "77500.0" } }, { - "tier": 5, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 5.0, + "currency": "BUSD", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.25", "cum": "277500.0" } }, { - "tier": 6, - "minNotional": 5000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "BUSD", + "minNotional": 5000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "5000000", + "notionalCap": "30000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.5", "cum": "1527500.0" } @@ -5415,91 +5885,97 @@ ], "DGB/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -5507,91 +5983,97 @@ ], "SKL/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -5599,91 +6081,97 @@ ], "REN/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -5691,91 +6179,195 @@ ], "LPT/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "386950.0" + } + } + ], + "JASMY/USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "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": "75.0" + } + }, + { + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "100000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "700.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "250000", + "notionalFloor": "100000", + "maintMarginRatio": "0.1", + "cum": "5700.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 2.0, + "info": { + "bracket": "5", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "250000", + "maintMarginRatio": "0.125", + "cum": "11950.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "6", + "initialLeverage": "1", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -5783,91 +6375,97 @@ ], "TOMO/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -5875,91 +6473,97 @@ ], "MTL/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -5967,136 +6571,145 @@ ], "LTC/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, + "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "maxNotional": "10000", - "minNotional": "0", + "notionalCap": "10000", + "notionalFloor": "0", "maintMarginRatio": "0.0065", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 10000, - "maxNotional": 50000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "10000", + "notionalCap": "50000", + "notionalFloor": "10000", "maintMarginRatio": "0.01", "cum": "35.0" } }, { - "tier": 3, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "535.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "4", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8035.0" } }, { - "tier": 5, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "5", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58035.0" } }, { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "6", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108035.0" } }, { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "7", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.15", "cum": "233035.0" } }, { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1233035.0" } }, { - "tier": 9, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 9.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6233035.0" } @@ -6104,91 +6717,97 @@ ], "DODO/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -6196,91 +6815,97 @@ ], "EGLD/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 50000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "1000000", + "notionalCap": "50000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -6288,91 +6913,97 @@ ], "KSM/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -6380,275 +7011,195 @@ ], "BNB/BUSD": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 100000, + "tier": 1.0, + "currency": "BUSD", + "minNotional": 0.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "1", "initialLeverage": "20", - "maxNotional": "100000", - "minNotional": "0", + "notionalCap": "100000", + "notionalFloor": "0", "maintMarginRatio": "0.025", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 100000, - "maxNotional": 500000, + "tier": 2.0, + "currency": "BUSD", + "minNotional": 100000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "2", "initialLeverage": "10", - "maxNotional": "500000", - "minNotional": "100000", + "notionalCap": "500000", + "notionalFloor": "100000", "maintMarginRatio": "0.05", "cum": "2500.0" } }, { - "tier": 3, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 3.0, + "currency": "BUSD", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "3", "initialLeverage": "5", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.1", "cum": "27500.0" } }, { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 4.0, + "currency": "BUSD", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "4", "initialLeverage": "3", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.15", "cum": "77500.0" } }, { - "tier": 5, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 5.0, + "currency": "BUSD", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.25", "cum": "277500.0" } }, { - "tier": 6, - "minNotional": 5000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "BUSD", + "minNotional": 5000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "5000000", + "notionalCap": "30000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.5", "cum": "1527500.0" } } ], - "BTCUSDT_210625": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 250000, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25, - "info": { - "bracket": "1", - "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "0", - "maintMarginRatio": "0.02", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 250000, - "maxNotional": 1000000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "2", - "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", - "maintMarginRatio": "0.05", - "cum": "7500.0" - } - }, - { - "tier": 3, - "minNotional": 1000000, - "maxNotional": 2000000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "3", - "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", - "maintMarginRatio": "0.1", - "cum": "57500.0" - } - }, - { - "tier": 4, - "minNotional": 2000000, - "maxNotional": 5000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4, - "info": { - "bracket": "4", - "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", - "maintMarginRatio": "0.125", - "cum": "107500.0" - } - }, - { - "tier": 5, - "minNotional": 5000000, - "maxNotional": 10000000, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3, - "info": { - "bracket": "5", - "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", - "maintMarginRatio": "0.15", - "cum": "232500.0" - } - }, - { - "tier": 6, - "minNotional": 10000000, - "maxNotional": 9223372036854776000, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2, - "info": { - "bracket": "6", - "initialLeverage": "2", - "maxNotional": "9223372036854775807", - "minNotional": "10000000", - "maintMarginRatio": "0.25", - "cum": "1232500.0" - } - } - ], "ONT/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -6656,198 +7207,309 @@ ], "VET/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "2000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } } ], - "TRB/USDT": [ + "IMX/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "386950.0" + } + } + ], + "TRB/USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 50.0, + "info": { + "bracket": "1", + "initialLeverage": "50", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "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": "75.0" + } + }, + { + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "100000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "700.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "250000", + "notionalFloor": "100000", + "maintMarginRatio": "0.1", + "cum": "5700.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 2.0, + "info": { + "bracket": "5", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "250000", + "maintMarginRatio": "0.125", + "cum": "11950.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "6", + "initialLeverage": "1", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -6855,198 +7517,309 @@ ], "MANA/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "2000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } } ], - "COTI/USDT": [ + "FLOW/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "386950.0" + } + } + ], + "COTI/USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 50.0, + "info": { + "bracket": "1", + "initialLeverage": "50", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "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": "75.0" + } + }, + { + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "100000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "700.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "250000", + "notionalFloor": "100000", + "maintMarginRatio": "0.1", + "cum": "5700.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 2.0, + "info": { + "bracket": "5", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "250000", + "maintMarginRatio": "0.125", + "cum": "11950.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "6", + "initialLeverage": "1", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -7054,581 +7827,571 @@ ], "CHR/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } } ], - "ETHUSDT_210924": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 250000, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25, - "info": { - "bracket": "1", - "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "0", - "maintMarginRatio": "0.02", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 250000, - "maxNotional": 1000000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "2", - "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", - "maintMarginRatio": "0.05", - "cum": "7500.0" - } - }, - { - "tier": 3, - "minNotional": 1000000, - "maxNotional": 2000000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "3", - "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", - "maintMarginRatio": "0.1", - "cum": "57500.0" - } - }, - { - "tier": 4, - "minNotional": 2000000, - "maxNotional": 5000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4, - "info": { - "bracket": "4", - "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", - "maintMarginRatio": "0.125", - "cum": "107500.0" - } - }, - { - "tier": 5, - "minNotional": 5000000, - "maxNotional": 10000000, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3, - "info": { - "bracket": "5", - "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", - "maintMarginRatio": "0.15", - "cum": "232500.0" - } - }, - { - "tier": 6, - "minNotional": 10000000, - "maxNotional": 20000000, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2, - "info": { - "bracket": "6", - "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", - "maintMarginRatio": "0.25", - "cum": "1232500.0" - } - }, - { - "tier": 7, - "minNotional": 20000000, - "maxNotional": 50000000, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1, - "info": { - "bracket": "7", - "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", - "maintMarginRatio": "0.5", - "cum": "6232500.0" - } - } - ], "BAKE/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } } ], + "AVAX/BUSD": [ + { + "tier": 1.0, + "currency": "BUSD", + "minNotional": 0.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "1", + "initialLeverage": "20", + "notionalCap": "25000", + "notionalFloor": "0", + "maintMarginRatio": "0.025", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "currency": "BUSD", + "minNotional": 25000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "2", + "initialLeverage": "10", + "notionalCap": "100000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "625.0" + } + }, + { + "tier": 3.0, + "currency": "BUSD", + "minNotional": 100000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "3", + "initialLeverage": "5", + "notionalCap": "250000", + "notionalFloor": "100000", + "maintMarginRatio": "0.1", + "cum": "5625.0" + } + }, + { + "tier": 4.0, + "currency": "BUSD", + "minNotional": 250000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 2.0, + "info": { + "bracket": "4", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "250000", + "maintMarginRatio": "0.125", + "cum": "11875.0" + } + }, + { + "tier": 5.0, + "currency": "BUSD", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "5", + "initialLeverage": "1", + "notionalCap": "30000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "386875.0" + } + } + ], "GRT/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } } ], - "ETHUSDT_220325": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 375000, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25, - "info": { - "bracket": "1", - "initialLeverage": "25", - "maxNotional": "375000", - "minNotional": "0", - "maintMarginRatio": "0.02", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 375000, - "maxNotional": 2000000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "2", - "initialLeverage": "10", - "maxNotional": "2000000", - "minNotional": "375000", - "maintMarginRatio": "0.05", - "cum": "11250.0" - } - }, - { - "tier": 3, - "minNotional": 2000000, - "maxNotional": 4000000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "3", - "initialLeverage": "5", - "maxNotional": "4000000", - "minNotional": "2000000", - "maintMarginRatio": "0.1", - "cum": "111250.0" - } - }, - { - "tier": 4, - "minNotional": 4000000, - "maxNotional": 10000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4, - "info": { - "bracket": "4", - "initialLeverage": "4", - "maxNotional": "10000000", - "minNotional": "4000000", - "maintMarginRatio": "0.125", - "cum": "211250.0" - } - }, - { - "tier": 5, - "minNotional": 10000000, - "maxNotional": 20000000, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3, - "info": { - "bracket": "5", - "initialLeverage": "3", - "maxNotional": "20000000", - "minNotional": "10000000", - "maintMarginRatio": "0.15", - "cum": "461250.0" - } - }, - { - "tier": 6, - "minNotional": 20000000, - "maxNotional": 40000000, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2, - "info": { - "bracket": "6", - "initialLeverage": "2", - "maxNotional": "40000000", - "minNotional": "20000000", - "maintMarginRatio": "0.25", - "cum": "2461250.0" - } - }, - { - "tier": 7, - "minNotional": 40000000, - "maxNotional": 400000000, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1, - "info": { - "bracket": "7", - "initialLeverage": "1", - "maxNotional": "400000000", - "minNotional": "40000000", - "maintMarginRatio": "0.5", - "cum": "1.246125E7" - } - } - ], "FLM/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "386950.0" + } + } + ], + "GAL/USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "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": "75.0" + } + }, + { + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "100000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "700.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "250000", + "notionalFloor": "100000", + "maintMarginRatio": "0.1", + "cum": "5700.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 2.0, + "info": { + "bracket": "5", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "250000", + "maintMarginRatio": "0.125", + "cum": "11950.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "6", + "initialLeverage": "1", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -7636,91 +8399,97 @@ ], "MASK/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -7728,335 +8497,243 @@ ], "EOS/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, + "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "maxNotional": "10000", - "minNotional": "0", + "notionalCap": "10000", + "notionalFloor": "0", "maintMarginRatio": "0.0065", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 10000, - "maxNotional": 50000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "10000", + "notionalCap": "50000", + "notionalFloor": "10000", "maintMarginRatio": "0.01", "cum": "35.0" } }, { - "tier": 3, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "535.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "4", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8035.0" } }, { - "tier": 5, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "5", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58035.0" } }, { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "6", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108035.0" } }, { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "7", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.15", "cum": "233035.0" } }, { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1233035.0" } }, { - "tier": 9, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 9.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6233035.0" } } ], - "ETHUSDT_211231": [ + "OGN/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 375000, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "375000", - "minNotional": "0", - "maintMarginRatio": "0.02", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 375000, - "maxNotional": 2000000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "2", - "initialLeverage": "10", - "maxNotional": "2000000", - "minNotional": "375000", - "maintMarginRatio": "0.05", - "cum": "11250.0" - } - }, - { - "tier": 3, - "minNotional": 2000000, - "maxNotional": 4000000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "3", - "initialLeverage": "5", - "maxNotional": "4000000", - "minNotional": "2000000", - "maintMarginRatio": "0.1", - "cum": "111250.0" - } - }, - { - "tier": 4, - "minNotional": 4000000, - "maxNotional": 10000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4, - "info": { - "bracket": "4", - "initialLeverage": "4", - "maxNotional": "10000000", - "minNotional": "4000000", - "maintMarginRatio": "0.125", - "cum": "211250.0" - } - }, - { - "tier": 5, - "minNotional": 10000000, - "maxNotional": 20000000, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3, - "info": { - "bracket": "5", - "initialLeverage": "3", - "maxNotional": "20000000", - "minNotional": "10000000", - "maintMarginRatio": "0.15", - "cum": "461250.0" - } - }, - { - "tier": 6, - "minNotional": 20000000, - "maxNotional": 40000000, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2, - "info": { - "bracket": "6", - "initialLeverage": "2", - "maxNotional": "40000000", - "minNotional": "20000000", - "maintMarginRatio": "0.25", - "cum": "2461250.0" - } - }, - { - "tier": 7, - "minNotional": 40000000, - "maxNotional": 400000000, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1, - "info": { - "bracket": "7", - "initialLeverage": "1", - "maxNotional": "400000000", - "minNotional": "40000000", - "maintMarginRatio": "0.5", - "cum": "1.246125E7" - } - } - ], - "OGN/USDT": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, - "maintenanceMarginRate": 0.01, - "maxLeverage": 50, - "info": { - "bracket": "1", - "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -8064,183 +8741,309 @@ ], "SC/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } } ], + "ETHUSDT_220624": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 375000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "375000", + "notionalFloor": "0", + "maintMarginRatio": "0.02", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "currency": "USDT", + "minNotional": 375000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "2", + "initialLeverage": "10", + "notionalCap": "2000000", + "notionalFloor": "375000", + "maintMarginRatio": "0.05", + "cum": "11250.0" + } + }, + { + "tier": 3.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 4000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "3", + "initialLeverage": "5", + "notionalCap": "4000000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.1", + "cum": "111250.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 4000000.0, + "maxNotional": 10000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "4", + "initialLeverage": "4", + "notionalCap": "10000000", + "notionalFloor": "4000000", + "maintMarginRatio": "0.125", + "cum": "211250.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, + "maintenanceMarginRate": 0.15, + "maxLeverage": 3.0, + "info": { + "bracket": "5", + "initialLeverage": "3", + "notionalCap": "20000000", + "notionalFloor": "10000000", + "maintMarginRatio": "0.15", + "cum": "461250.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 40000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "6", + "initialLeverage": "2", + "notionalCap": "40000000", + "notionalFloor": "20000000", + "maintMarginRatio": "0.25", + "cum": "2461250.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 40000000.0, + "maxNotional": 400000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", + "initialLeverage": "1", + "notionalCap": "400000000", + "notionalFloor": "40000000", + "maintMarginRatio": "0.5", + "cum": "1.246125E7" + } + } + ], "BAL/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -8248,489 +9051,195 @@ ], "STMX/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } } ], - "BTTUSDT": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, - "maintenanceMarginRate": 0.01, - "maxLeverage": 25, - "info": { - "bracket": "1", - "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", - "maintMarginRatio": "0.01", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20, - "info": { - "bracket": "2", - "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", - "maintMarginRatio": "0.025", - "cum": "75.0" - } - }, - { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "3", - "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", - "maintMarginRatio": "0.05", - "cum": "700.0" - } - }, - { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "4", - "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", - "maintMarginRatio": "0.1", - "cum": "5700.0" - } - }, - { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 2, - "info": { - "bracket": "5", - "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", - "maintMarginRatio": "0.125", - "cum": "11950.0" - } - }, - { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1, - "info": { - "bracket": "6", - "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", - "maintMarginRatio": "0.5", - "cum": "386950.0" - } - } - ], - "LUNA/USDT": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, - "maintenanceMarginRate": 0.01, - "maxLeverage": 50, - "info": { - "bracket": "1", - "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", - "maintMarginRatio": "0.01", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 50000, - "maxNotional": 250000, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25, - "info": { - "bracket": "2", - "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", - "maintMarginRatio": "0.02", - "cum": "500.0" - } - }, - { - "tier": 3, - "minNotional": 250000, - "maxNotional": 1000000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "3", - "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", - "maintMarginRatio": "0.05", - "cum": "8000.0" - } - }, - { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 2000000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "4", - "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", - "maintMarginRatio": "0.1", - "cum": "58000.0" - } - }, - { - "tier": 5, - "minNotional": 2000000, - "maxNotional": 5000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4, - "info": { - "bracket": "5", - "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", - "maintMarginRatio": "0.125", - "cum": "108000.0" - } - }, - { - "tier": 6, - "minNotional": 5000000, - "maxNotional": 10000000, - "maintenanceMarginRate": 0.1665, - "maxLeverage": 3, - "info": { - "bracket": "6", - "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", - "maintMarginRatio": "0.1665", - "cum": "315500.0" - } - }, - { - "tier": 7, - "minNotional": 10000000, - "maxNotional": 15000000, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2, - "info": { - "bracket": "7", - "initialLeverage": "2", - "maxNotional": "15000000", - "minNotional": "10000000", - "maintMarginRatio": "0.25", - "cum": "1150500.0" - } - }, - { - "tier": 8, - "minNotional": 15000000, - "maxNotional": 50000000, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1, - "info": { - "bracket": "8", - "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "15000000", - "maintMarginRatio": "0.5", - "cum": "4900500.0" - } - } - ], "DENT/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", - "maintMarginRatio": "0.5", - "cum": "386950.0" - } - } - ], - "1000BTTC/USDT": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, - "maintenanceMarginRate": 0.01, - "maxLeverage": 25, - "info": { - "bracket": "1", - "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", - "maintMarginRatio": "0.01", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20, - "info": { - "bracket": "2", - "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", - "maintMarginRatio": "0.025", - "cum": "75.0" - } - }, - { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "3", - "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", - "maintMarginRatio": "0.05", - "cum": "700.0" - } - }, - { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "4", - "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", - "maintMarginRatio": "0.1", - "cum": "5700.0" - } - }, - { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 2, - "info": { - "bracket": "5", - "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", - "maintMarginRatio": "0.125", - "cum": "11950.0" - } - }, - { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1, - "info": { - "bracket": "6", - "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -8738,91 +9247,97 @@ ], "KNC/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -8830,91 +9345,97 @@ ], "SRM/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -8922,106 +9443,113 @@ ], "ENJ/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "2000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } @@ -9029,91 +9557,97 @@ ], "C98/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -9121,91 +9655,97 @@ ], "ZEN/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -9213,106 +9753,113 @@ ], "ATOM/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "2000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } @@ -9320,106 +9867,113 @@ ], "NEAR/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "2000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } @@ -9427,91 +9981,97 @@ ], "SOL/BUSD": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 100000, + "tier": 1.0, + "currency": "BUSD", + "minNotional": 0.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "1", "initialLeverage": "20", - "maxNotional": "100000", - "minNotional": "0", + "notionalCap": "100000", + "notionalFloor": "0", "maintMarginRatio": "0.025", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 100000, - "maxNotional": 500000, + "tier": 2.0, + "currency": "BUSD", + "minNotional": 100000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "2", "initialLeverage": "10", - "maxNotional": "500000", - "minNotional": "100000", + "notionalCap": "500000", + "notionalFloor": "100000", "maintMarginRatio": "0.05", "cum": "2500.0" } }, { - "tier": 3, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 3.0, + "currency": "BUSD", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "3", "initialLeverage": "5", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.1", "cum": "27500.0" } }, { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 4.0, + "currency": "BUSD", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "4", "initialLeverage": "3", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.15", "cum": "77500.0" } }, { - "tier": 5, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 5.0, + "currency": "BUSD", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.25", "cum": "277500.0" } }, { - "tier": 6, - "minNotional": 5000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "BUSD", + "minNotional": 5000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "5000000", + "notionalCap": "30000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.5", "cum": "1527500.0" } @@ -9519,91 +10079,97 @@ ], "ENS/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -9611,136 +10177,145 @@ ], "BCH/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, + "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "maxNotional": "10000", - "minNotional": "0", + "notionalCap": "10000", + "notionalFloor": "0", "maintMarginRatio": "0.0065", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 10000, - "maxNotional": 50000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "10000", + "notionalCap": "50000", + "notionalFloor": "10000", "maintMarginRatio": "0.01", "cum": "35.0" } }, { - "tier": 3, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "535.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "4", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8035.0" } }, { - "tier": 5, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "5", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58035.0" } }, { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "6", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108035.0" } }, { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "7", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.15", "cum": "233035.0" } }, { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1233035.0" } }, { - "tier": 9, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 9.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6233035.0" } @@ -9748,91 +10323,97 @@ ], "ATA/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -9840,91 +10421,97 @@ ], "IOST/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -9932,91 +10519,97 @@ ], "HBAR/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -10024,106 +10617,113 @@ ], "ZEC/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "2000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } @@ -10131,106 +10731,113 @@ ], "1000SHIB/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "2000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } @@ -10238,91 +10845,97 @@ ], "TLM/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -10330,183 +10943,97 @@ ], "ANT/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", - "maintMarginRatio": "0.5", - "cum": "386950.0" - } - } - ], - "BZRXUSDT": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, - "maintenanceMarginRate": 0.01, - "maxLeverage": 25, - "info": { - "bracket": "1", - "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", - "maintMarginRatio": "0.01", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20, - "info": { - "bracket": "2", - "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", - "maintMarginRatio": "0.025", - "cum": "75.0" - } - }, - { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "3", - "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", - "maintMarginRatio": "0.05", - "cum": "700.0" - } - }, - { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "4", - "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", - "maintMarginRatio": "0.1", - "cum": "5700.0" - } - }, - { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 2, - "info": { - "bracket": "5", - "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", - "maintMarginRatio": "0.125", - "cum": "11950.0" - } - }, - { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1, - "info": { - "bracket": "6", - "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -10514,151 +11041,161 @@ ], "ETH/BUSD": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 25000, + "tier": 1.0, + "currency": "BUSD", + "minNotional": 0.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.004, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "25000", - "minNotional": "0", + "notionalCap": "25000", + "notionalFloor": "0", "maintMarginRatio": "0.004", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 2.0, + "currency": "BUSD", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.005, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "2", "initialLeverage": "25", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.005", "cum": "25.0" } }, { - "tier": 3, - "minNotional": 100000, - "maxNotional": 500000, + "tier": 3.0, + "currency": "BUSD", + "minNotional": 100000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "3", "initialLeverage": "20", - "maxNotional": "500000", - "minNotional": "100000", + "notionalCap": "500000", + "notionalFloor": "100000", "maintMarginRatio": "0.01", "cum": "525.0" } }, { - "tier": 4, - "minNotional": 500000, - "maxNotional": 1500000, + "tier": 4.0, + "currency": "BUSD", + "minNotional": 500000.0, + "maxNotional": 1500000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "4", "initialLeverage": "10", - "maxNotional": "1500000", - "minNotional": "500000", + "notionalCap": "1500000", + "notionalFloor": "500000", "maintMarginRatio": "0.025", "cum": "8025.0" } }, { - "tier": 5, - "minNotional": 1500000, - "maxNotional": 4000000, + "tier": 5.0, + "currency": "BUSD", + "minNotional": 1500000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 6, + "maxLeverage": 6.0, "info": { "bracket": "5", "initialLeverage": "6", - "maxNotional": "4000000", - "minNotional": "1500000", + "notionalCap": "4000000", + "notionalFloor": "1500000", "maintMarginRatio": "0.05", "cum": "45525.0" } }, { - "tier": 6, - "minNotional": 4000000, - "maxNotional": 10000000, + "tier": 6.0, + "currency": "BUSD", + "minNotional": 4000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "maxNotional": "10000000", - "minNotional": "4000000", + "notionalCap": "10000000", + "notionalFloor": "4000000", "maintMarginRatio": "0.1", "cum": "245525.0" } }, { - "tier": 7, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 7.0, + "currency": "BUSD", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.125", "cum": "495525.0" } }, { - "tier": 8, - "minNotional": 20000000, - "maxNotional": 40000000, + "tier": 8.0, + "currency": "BUSD", + "minNotional": 20000000.0, + "maxNotional": 40000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "8", "initialLeverage": "3", - "maxNotional": "40000000", - "minNotional": "20000000", + "notionalCap": "40000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.15", "cum": "995525.0" } }, { - "tier": 9, - "minNotional": 40000000, - "maxNotional": 150000000, + "tier": 9.0, + "currency": "BUSD", + "minNotional": 40000000.0, + "maxNotional": 150000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "9", "initialLeverage": "2", - "maxNotional": "150000000", - "minNotional": "40000000", + "notionalCap": "150000000", + "notionalFloor": "40000000", "maintMarginRatio": "0.25", "cum": "4995525.0" } }, { - "tier": 10, - "minNotional": 150000000, - "maxNotional": 500000000, + "tier": 10.0, + "currency": "BUSD", + "minNotional": 150000000.0, + "maxNotional": 500000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "10", "initialLeverage": "1", - "maxNotional": "500000000", - "minNotional": "150000000", + "notionalCap": "500000000", + "notionalFloor": "150000000", "maintMarginRatio": "0.5", "cum": "4.2495525E7" } @@ -10666,106 +11203,113 @@ ], "GALA/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "2000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } @@ -10773,121 +11317,129 @@ ], "AAVE/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "2", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "500.0" } }, { - "tier": 3, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8000.0" } }, { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58000.0" } }, { - "tier": 5, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108000.0" } }, { - "tier": 6, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.1665, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "6", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.1665", "cum": "315500.0" } }, { - "tier": 7, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "7", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1150500.0" } }, { - "tier": 8, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "8", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6150500.0" } @@ -10895,91 +11447,97 @@ ], "GTC/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -10987,106 +11545,113 @@ ], "ALGO/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "2000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } @@ -11094,305 +11659,211 @@ ], "ICP/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } } ], - "BTCUSDT_210924": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 250000, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25, - "info": { - "bracket": "1", - "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "0", - "maintMarginRatio": "0.02", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 250000, - "maxNotional": 1000000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "2", - "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", - "maintMarginRatio": "0.05", - "cum": "7500.0" - } - }, - { - "tier": 3, - "minNotional": 1000000, - "maxNotional": 2000000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "3", - "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", - "maintMarginRatio": "0.1", - "cum": "57500.0" - } - }, - { - "tier": 4, - "minNotional": 2000000, - "maxNotional": 5000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4, - "info": { - "bracket": "4", - "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", - "maintMarginRatio": "0.125", - "cum": "107500.0" - } - }, - { - "tier": 5, - "minNotional": 5000000, - "maxNotional": 10000000, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3, - "info": { - "bracket": "5", - "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", - "maintMarginRatio": "0.15", - "cum": "232500.0" - } - }, - { - "tier": 6, - "minNotional": 10000000, - "maxNotional": 20000000, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2, - "info": { - "bracket": "6", - "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", - "maintMarginRatio": "0.25", - "cum": "1232500.0" - } - }, - { - "tier": 7, - "minNotional": 20000000, - "maxNotional": 50000000, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1, - "info": { - "bracket": "7", - "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", - "maintMarginRatio": "0.5", - "cum": "6232500.0" - } - } - ], "LRC/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "2000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } @@ -11400,305 +11871,211 @@ ], "AVAX/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", - "cum": "4500.0" + "cum": "7000.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", - "cum": "17000.0" + "cum": "57000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 750000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "750000", - "minNotional": "500000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", - "cum": "29500.0" + "cum": "107000.0" } }, { - "tier": 6, - "minNotional": 750000, - "maxNotional": 1000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "750000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.25", - "cum": "123250.0" + "cum": "732000.0" } }, { - "tier": 7, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "50000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.5", - "cum": "373250.0" - } - } - ], - "BTCUSDT_220325": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 375000, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25, - "info": { - "bracket": "1", - "initialLeverage": "25", - "maxNotional": "375000", - "minNotional": "0", - "maintMarginRatio": "0.02", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 375000, - "maxNotional": 2000000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "2", - "initialLeverage": "10", - "maxNotional": "2000000", - "minNotional": "375000", - "maintMarginRatio": "0.05", - "cum": "11250.0" - } - }, - { - "tier": 3, - "minNotional": 2000000, - "maxNotional": 4000000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "3", - "initialLeverage": "5", - "maxNotional": "4000000", - "minNotional": "2000000", - "maintMarginRatio": "0.1", - "cum": "111250.0" - } - }, - { - "tier": 4, - "minNotional": 4000000, - "maxNotional": 10000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4, - "info": { - "bracket": "4", - "initialLeverage": "4", - "maxNotional": "10000000", - "minNotional": "4000000", - "maintMarginRatio": "0.125", - "cum": "211250.0" - } - }, - { - "tier": 5, - "minNotional": 10000000, - "maxNotional": 20000000, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3, - "info": { - "bracket": "5", - "initialLeverage": "3", - "maxNotional": "20000000", - "minNotional": "10000000", - "maintMarginRatio": "0.15", - "cum": "461250.0" - } - }, - { - "tier": 6, - "minNotional": 20000000, - "maxNotional": 40000000, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2, - "info": { - "bracket": "6", - "initialLeverage": "2", - "maxNotional": "40000000", - "minNotional": "20000000", - "maintMarginRatio": "0.25", - "cum": "2461250.0" - } - }, - { - "tier": 7, - "minNotional": 40000000, - "maxNotional": 400000000, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1, - "info": { - "bracket": "7", - "initialLeverage": "1", - "maxNotional": "400000000", - "minNotional": "40000000", - "maintMarginRatio": "0.5", - "cum": "1.246125E7" + "cum": "3232000.0" } } ], "ARPA/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -11706,91 +12083,97 @@ ], "CELO/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -11798,91 +12181,97 @@ ], "ROSE/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -11890,106 +12279,113 @@ ], "MATIC/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 750000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 750000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "750000", - "minNotional": "500000", + "notionalCap": "750000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 750000, - "maxNotional": 1000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "750000", + "notionalCap": "1000000", + "notionalFloor": "750000", "maintMarginRatio": "0.25", "cum": "123250.0" } }, { - "tier": 7, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "373250.0" } @@ -11997,91 +12393,97 @@ ], "1INCH/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.012, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.012", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "65.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "690.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5690.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11940.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 100000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 100000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "100000000", - "minNotional": "1000000", + "notionalCap": "100000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386940.0" } @@ -12089,91 +12491,97 @@ ], "MKR/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -12181,91 +12589,97 @@ ], "PEOPLE/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -12273,121 +12687,129 @@ ], "THETA/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "2", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "500.0" } }, { - "tier": 3, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8000.0" } }, { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58000.0" } }, { - "tier": 5, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108000.0" } }, { - "tier": 6, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.1665, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "6", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.1665", "cum": "315500.0" } }, { - "tier": 7, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "7", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1150500.0" } }, { - "tier": 8, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "8", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6150500.0" } @@ -12395,335 +12817,227 @@ ], "UNI/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "2", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "500.0" } }, { - "tier": 3, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8000.0" } }, { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58000.0" } }, { - "tier": 5, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108000.0" } }, { - "tier": 6, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.1665, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "6", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.1665", "cum": "315500.0" } }, { - "tier": 7, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "7", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1150500.0" } }, { - "tier": 8, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "8", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6150500.0" } } ], - "ETHUSDT_210326": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, - "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, - "info": { - "bracket": "1", - "initialLeverage": "75", - "maxNotional": "10000", - "minNotional": "0", - "maintMarginRatio": "0.0065", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 10000, - "maxNotional": 50000, - "maintenanceMarginRate": 0.01, - "maxLeverage": 50, - "info": { - "bracket": "2", - "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "10000", - "maintMarginRatio": "0.01", - "cum": "35.0" - } - }, - { - "tier": 3, - "minNotional": 50000, - "maxNotional": 250000, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25, - "info": { - "bracket": "3", - "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", - "maintMarginRatio": "0.02", - "cum": "535.0" - } - }, - { - "tier": 4, - "minNotional": 250000, - "maxNotional": 1000000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "4", - "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", - "maintMarginRatio": "0.05", - "cum": "8035.0" - } - }, - { - "tier": 5, - "minNotional": 1000000, - "maxNotional": 2000000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "5", - "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", - "maintMarginRatio": "0.1", - "cum": "58035.0" - } - }, - { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4, - "info": { - "bracket": "6", - "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", - "maintMarginRatio": "0.125", - "cum": "108035.0" - } - }, - { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3, - "info": { - "bracket": "7", - "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", - "maintMarginRatio": "0.15", - "cum": "233035.0" - } - }, - { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 9223372036854776000, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2, - "info": { - "bracket": "8", - "initialLeverage": "2", - "maxNotional": "9223372036854775807", - "minNotional": "10000000", - "maintMarginRatio": "0.25", - "cum": "1233035.0" - } - } - ], "LINA/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -12731,91 +13045,97 @@ ], "AR/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -12823,91 +13143,97 @@ ], "RVN/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -12915,121 +13241,129 @@ ], "FIL/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "2", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "500.0" } }, { - "tier": 3, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8000.0" } }, { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58000.0" } }, { - "tier": 5, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108000.0" } }, { - "tier": 6, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.1665, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "6", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.1665", "cum": "315500.0" } }, { - "tier": 7, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "7", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1150500.0" } }, { - "tier": 8, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "8", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6150500.0" } @@ -13037,91 +13371,97 @@ ], "NKN/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -13129,91 +13469,97 @@ ], "KLAY/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -13221,91 +13567,97 @@ ], "DEFI/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -13313,91 +13665,97 @@ ], "COMP/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -13405,91 +13763,97 @@ ], "BTCDOM/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -13497,106 +13861,113 @@ ], "SOL/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "7000.0" } }, { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "57000.0" } }, { - "tier": 5, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "107000.0" } }, { - "tier": 6, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.25", "cum": "732000.0" } }, { - "tier": 7, - "minNotional": 10000000, - "maxNotional": 50000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "10000000", + "notionalCap": "50000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.5", "cum": "3232000.0" } @@ -13604,243 +13975,259 @@ ], "BTC/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.004, - "maxLeverage": 125, + "maxLeverage": 125.0, "info": { "bracket": "1", "initialLeverage": "125", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.004", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.005, - "maxLeverage": 100, + "maxLeverage": 100.0, "info": { "bracket": "2", "initialLeverage": "100", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.005", "cum": "50.0" } }, { - "tier": 3, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "3", "initialLeverage": "50", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.01", "cum": "1300.0" } }, { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 7500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "4", "initialLeverage": "20", - "maxNotional": "7500000", - "minNotional": "1000000", + "notionalCap": "10000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.025", "cum": "16300.0" } }, { - "tier": 5, - "minNotional": 7500000, - "maxNotional": 40000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "maxNotional": "40000000", - "minNotional": "7500000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.05", - "cum": "203800.0" + "cum": "266300.0" } }, { - "tier": 6, - "minNotional": 40000000, - "maxNotional": 100000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "maxNotional": "100000000", - "minNotional": "40000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.1", - "cum": "2203800.0" + "cum": "1266300.0" } }, { - "tier": 7, - "minNotional": 100000000, - "maxNotional": 200000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 50000000.0, + "maxNotional": 100000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "maxNotional": "200000000", - "minNotional": "100000000", + "notionalCap": "100000000", + "notionalFloor": "50000000", "maintMarginRatio": "0.125", - "cum": "4703800.0" + "cum": "2516300.0" } }, { - "tier": 8, - "minNotional": 200000000, - "maxNotional": 400000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 100000000.0, + "maxNotional": 200000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "8", "initialLeverage": "3", - "maxNotional": "400000000", - "minNotional": "200000000", + "notionalCap": "200000000", + "notionalFloor": "100000000", "maintMarginRatio": "0.15", - "cum": "9703800.0" + "cum": "5016300.0" } }, { - "tier": 9, - "minNotional": 400000000, - "maxNotional": 600000000, + "tier": 9.0, + "currency": "USDT", + "minNotional": 200000000.0, + "maxNotional": 300000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "9", "initialLeverage": "2", - "maxNotional": "600000000", - "minNotional": "400000000", + "notionalCap": "300000000", + "notionalFloor": "200000000", "maintMarginRatio": "0.25", - "cum": "4.97038E7" + "cum": "2.50163E7" } }, { - "tier": 10, - "minNotional": 600000000, - "maxNotional": 1000000000, + "tier": 10.0, + "currency": "USDT", + "minNotional": 300000000.0, + "maxNotional": 9.223372036854776e+18, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "10", "initialLeverage": "1", - "maxNotional": "1000000000", - "minNotional": "600000000", + "notionalCap": "9223372036854775807", + "notionalFloor": "300000000", "maintMarginRatio": "0.5", - "cum": "1.997038E8" + "cum": "1.000163E8" } } ], "OMG/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.024, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.024", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "5.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "630.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5630.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11880.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 10000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "10000000", - "minNotional": "1000000", + "notionalCap": "10000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386880.0" } @@ -13848,91 +14235,97 @@ ], "ICX/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -13940,810 +14333,521 @@ ], "BLZ/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } } ], - "BTCUSDT_211231": [ + "GMT/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 375000, - "maintenanceMarginRate": 0.02, - "maxLeverage": 25, - "info": { - "bracket": "1", - "initialLeverage": "25", - "maxNotional": "375000", - "minNotional": "0", - "maintMarginRatio": "0.02", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 375000, - "maxNotional": 2000000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "2", - "initialLeverage": "10", - "maxNotional": "2000000", - "minNotional": "375000", - "maintMarginRatio": "0.05", - "cum": "11250.0" - } - }, - { - "tier": 3, - "minNotional": 2000000, - "maxNotional": 4000000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "3", - "initialLeverage": "5", - "maxNotional": "4000000", - "minNotional": "2000000", - "maintMarginRatio": "0.1", - "cum": "111250.0" - } - }, - { - "tier": 4, - "minNotional": 4000000, - "maxNotional": 10000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4, - "info": { - "bracket": "4", - "initialLeverage": "4", - "maxNotional": "10000000", - "minNotional": "4000000", - "maintMarginRatio": "0.125", - "cum": "211250.0" - } - }, - { - "tier": 5, - "minNotional": 10000000, - "maxNotional": 20000000, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3, - "info": { - "bracket": "5", - "initialLeverage": "3", - "maxNotional": "20000000", - "minNotional": "10000000", - "maintMarginRatio": "0.15", - "cum": "461250.0" - } - }, - { - "tier": 6, - "minNotional": 20000000, - "maxNotional": 40000000, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2, - "info": { - "bracket": "6", - "initialLeverage": "2", - "maxNotional": "40000000", - "minNotional": "20000000", - "maintMarginRatio": "0.25", - "cum": "2461250.0" - } - }, - { - "tier": 7, - "minNotional": 40000000, - "maxNotional": 400000000, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1, - "info": { - "bracket": "7", - "initialLeverage": "1", - "maxNotional": "400000000", - "minNotional": "40000000", - "maintMarginRatio": "0.5", - "cum": "1.246125E7" - } - } - ], - "FTM/USDT": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 750000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "750000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 750000, - "maxNotional": 1000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "750000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", - "cum": "123250.0" + "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", - "cum": "373250.0" + "cum": "654500.0" } } ], - "YFII/USDT": [ + "FTM/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", - "cum": "75.0" + "cum": "750.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", - "cum": "700.0" + "cum": "7000.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", - "cum": "5700.0" + "cum": "57000.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 4.0, "info": { "bracket": "5", - "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "initialLeverage": "4", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", - "cum": "11950.0" + "cum": "107000.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "tier": 6.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, "info": { "bracket": "6", - "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", - "maintMarginRatio": "0.5", - "cum": "386950.0" - } - } - ], - "KEEP/USDT": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, - "maintenanceMarginRate": 0.01, - "maxLeverage": 50, - "info": { - "bracket": "1", - "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", - "maintMarginRatio": "0.01", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20, - "info": { - "bracket": "2", - "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", - "maintMarginRatio": "0.025", - "cum": "75.0" - } - }, - { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "3", - "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", - "maintMarginRatio": "0.05", - "cum": "700.0" - } - }, - { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "4", - "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", - "maintMarginRatio": "0.1", - "cum": "5700.0" - } - }, - { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 2, - "info": { - "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", - "maintMarginRatio": "0.125", - "cum": "11950.0" + "notionalCap": "10000000", + "notionalFloor": "5000000", + "maintMarginRatio": "0.25", + "cum": "732000.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { - "bracket": "6", + "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "50000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.5", - "cum": "386950.0" + "cum": "3232000.0" } } ], "BAND/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } } ], - "BTCBUSD_210226": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, - "maintenanceMarginRate": 0.004, - "maxLeverage": 20, - "info": { - "bracket": "1", - "initialLeverage": "20", - "maxNotional": "5000", - "minNotional": "0", - "maintMarginRatio": "0.004", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, - "maintenanceMarginRate": 0.005, - "maxLeverage": 15, - "info": { - "bracket": "2", - "initialLeverage": "15", - "maxNotional": "25000", - "minNotional": "5000", - "maintMarginRatio": "0.005", - "cum": "5.0" - } - }, - { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, - "maintenanceMarginRate": 0.01, - "maxLeverage": 10, - "info": { - "bracket": "3", - "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", - "maintMarginRatio": "0.01", - "cum": "130.0" - } - }, - { - "tier": 4, - "minNotional": 100000, - "maxNotional": 500000, - "maintenanceMarginRate": 0.025, - "maxLeverage": 7, - "info": { - "bracket": "4", - "initialLeverage": "7", - "maxNotional": "500000", - "minNotional": "100000", - "maintMarginRatio": "0.025", - "cum": "1630.0" - } - }, - { - "tier": 5, - "minNotional": 500000, - "maxNotional": 2000000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 6, - "info": { - "bracket": "5", - "initialLeverage": "6", - "maxNotional": "2000000", - "minNotional": "500000", - "maintMarginRatio": "0.05", - "cum": "14130.0" - } - }, - { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "6", - "initialLeverage": "5", - "maxNotional": "5000000", - "minNotional": "2000000", - "maintMarginRatio": "0.1", - "cum": "114130.0" - } - }, - { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4, - "info": { - "bracket": "7", - "initialLeverage": "4", - "maxNotional": "10000000", - "minNotional": "5000000", - "maintMarginRatio": "0.125", - "cum": "239130.0" - } - }, - { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 20000000, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3, - "info": { - "bracket": "8", - "initialLeverage": "3", - "maxNotional": "20000000", - "minNotional": "10000000", - "maintMarginRatio": "0.15", - "cum": "489130.0" - } - }, - { - "tier": 9, - "minNotional": 20000000, - "maxNotional": 9223372036854776000, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2, - "info": { - "bracket": "9", - "initialLeverage": "2", - "maxNotional": "9223372036854775807", - "minNotional": "20000000", - "maintMarginRatio": "0.25", - "cum": "2489130.0" - } - } - ], "XRP/BUSD": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 100000, + "tier": 1.0, + "currency": "BUSD", + "minNotional": 0.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "1", "initialLeverage": "20", - "maxNotional": "100000", - "minNotional": "0", + "notionalCap": "100000", + "notionalFloor": "0", "maintMarginRatio": "0.025", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 100000, - "maxNotional": 500000, + "tier": 2.0, + "currency": "BUSD", + "minNotional": 100000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "2", "initialLeverage": "10", - "maxNotional": "500000", - "minNotional": "100000", + "notionalCap": "500000", + "notionalFloor": "100000", "maintMarginRatio": "0.05", "cum": "2500.0" } }, { - "tier": 3, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 3.0, + "currency": "BUSD", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "3", "initialLeverage": "5", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.1", "cum": "27500.0" } }, { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 4.0, + "currency": "BUSD", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "4", "initialLeverage": "3", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.15", "cum": "77500.0" } }, { - "tier": 5, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 5.0, + "currency": "BUSD", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.25", "cum": "277500.0" } }, { - "tier": 6, - "minNotional": 5000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "BUSD", + "minNotional": 5000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "5000000", + "notionalCap": "30000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.5", "cum": "1527500.0" } @@ -14751,91 +14855,97 @@ ], "DOGE/BUSD": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 100000, + "tier": 1.0, + "currency": "BUSD", + "minNotional": 0.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "1", "initialLeverage": "20", - "maxNotional": "100000", - "minNotional": "0", + "notionalCap": "100000", + "notionalFloor": "0", "maintMarginRatio": "0.025", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 100000, - "maxNotional": 500000, + "tier": 2.0, + "currency": "BUSD", + "minNotional": 100000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "2", "initialLeverage": "10", - "maxNotional": "500000", - "minNotional": "100000", + "notionalCap": "500000", + "notionalFloor": "100000", "maintMarginRatio": "0.05", "cum": "2500.0" } }, { - "tier": 3, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 3.0, + "currency": "BUSD", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "3", "initialLeverage": "5", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.1", "cum": "27500.0" } }, { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 4.0, + "currency": "BUSD", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "4", "initialLeverage": "3", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.15", "cum": "77500.0" } }, { - "tier": 5, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 5.0, + "currency": "BUSD", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.25", "cum": "277500.0" } }, { - "tier": 6, - "minNotional": 5000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "BUSD", + "minNotional": 5000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "5000000", + "notionalCap": "30000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.5", "cum": "1527500.0" } @@ -14843,228 +14953,341 @@ ], "XRP/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, + "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "maxNotional": "10000", - "minNotional": "0", + "notionalCap": "10000", + "notionalFloor": "0", "maintMarginRatio": "0.0065", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 10000, - "maxNotional": 50000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "10000", + "notionalCap": "50000", + "notionalFloor": "10000", "maintMarginRatio": "0.01", "cum": "35.0" } }, { - "tier": 3, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "535.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "4", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8035.0" } }, { - "tier": 5, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "5", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58035.0" } }, { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "6", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108035.0" } }, { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "7", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.15", "cum": "233035.0" } }, { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 20000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "maxNotional": "20000000", - "minNotional": "10000000", + "notionalCap": "20000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1233035.0" } }, { - "tier": 9, - "minNotional": 20000000, - "maxNotional": 50000000, + "tier": 9.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "20000000", + "notionalCap": "50000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.5", "cum": "6233035.0" } } ], - "SXP/USDT": [ + "FTT/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "386950.0" + } + } + ], + "SXP/USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 50.0, + "info": { + "bracket": "1", + "initialLeverage": "50", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "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": "75.0" + } + }, + { + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "100000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "700.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "250000", + "notionalFloor": "100000", + "maintMarginRatio": "0.1", + "cum": "5700.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 2.0, + "info": { + "bracket": "5", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "250000", + "maintMarginRatio": "0.125", + "cum": "11950.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "6", + "initialLeverage": "1", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -15072,106 +15295,113 @@ ], "CRV/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "2000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } @@ -15179,91 +15409,97 @@ ], "BEL/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -15271,136 +15507,145 @@ ], "DOT/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 10000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, "maintenanceMarginRate": 0.0065, - "maxLeverage": 75, + "maxLeverage": 75.0, "info": { "bracket": "1", "initialLeverage": "75", - "maxNotional": "10000", - "minNotional": "0", + "notionalCap": "10000", + "notionalFloor": "0", "maintMarginRatio": "0.0065", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 10000, - "maxNotional": 50000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "2", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "10000", + "notionalCap": "50000", + "notionalFloor": "10000", "maintMarginRatio": "0.01", "cum": "35.0" } }, { - "tier": 3, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "3", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "535.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "4", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8035.0" } }, { - "tier": 5, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "5", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58035.0" } }, { - "tier": 6, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "6", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108035.0" } }, { - "tier": 7, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.15, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "7", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.15", "cum": "233035.0" } }, { - "tier": 8, - "minNotional": 10000000, - "maxNotional": 50000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "maxNotional": "50000000", - "minNotional": "10000000", + "notionalCap": "50000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1233035.0" } }, { - "tier": 9, - "minNotional": 50000000, - "maxNotional": 100000000, + "tier": 9.0, + "currency": "USDT", + "minNotional": 50000000.0, + "maxNotional": 100000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "maxNotional": "100000000", - "minNotional": "50000000", + "notionalCap": "100000000", + "notionalFloor": "50000000", "maintMarginRatio": "0.5", "cum": "1.3733035E7" } @@ -15408,198 +15653,293 @@ ], "XEM/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } } ], + "GMT/BUSD": [ + { + "tier": 1.0, + "currency": "BUSD", + "minNotional": 0.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "1", + "initialLeverage": "20", + "notionalCap": "25000", + "notionalFloor": "0", + "maintMarginRatio": "0.025", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "currency": "BUSD", + "minNotional": 25000.0, + "maxNotional": 100000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "2", + "initialLeverage": "10", + "notionalCap": "100000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "625.0" + } + }, + { + "tier": 3.0, + "currency": "BUSD", + "minNotional": 100000.0, + "maxNotional": 250000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "3", + "initialLeverage": "5", + "notionalCap": "250000", + "notionalFloor": "100000", + "maintMarginRatio": "0.1", + "cum": "5625.0" + } + }, + { + "tier": 4.0, + "currency": "BUSD", + "minNotional": 250000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 2.0, + "info": { + "bracket": "4", + "initialLeverage": "2", + "notionalCap": "1000000", + "notionalFloor": "250000", + "maintMarginRatio": "0.125", + "cum": "11875.0" + } + }, + { + "tier": 5.0, + "currency": "BUSD", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "5", + "initialLeverage": "1", + "notionalCap": "30000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.5", + "cum": "386875.0" + } + } + ], "ONE/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 2000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "2000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } @@ -15607,213 +15947,243 @@ ], "ZIL/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", - "cum": "75.0" + "cum": "750.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", - "cum": "700.0" + "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", - "cum": "5700.0" + "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 4.0, "info": { "bracket": "5", - "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "initialLeverage": "4", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", - "cum": "11950.0" + "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, "info": { "bracket": "6", + "initialLeverage": "2", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.25", + "cum": "154500.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 30000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", - "cum": "386950.0" + "cum": "654500.0" } } ], "AXS/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 250000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "2", "initialLeverage": "25", - "maxNotional": "250000", - "minNotional": "50000", + "notionalCap": "250000", + "notionalFloor": "50000", "maintMarginRatio": "0.02", "cum": "500.0" } }, { - "tier": 3, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.05", "cum": "8000.0" } }, { - "tier": 4, - "minNotional": 1000000, - "maxNotional": 2000000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "2000000", - "minNotional": "1000000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "58000.0" } }, { - "tier": 5, - "minNotional": 2000000, - "maxNotional": 5000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "5000000", - "minNotional": "2000000", + "notionalCap": "5000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", "cum": "108000.0" } }, { - "tier": 6, - "minNotional": 5000000, - "maxNotional": 10000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 5000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.1665, - "maxLeverage": 3, + "maxLeverage": 3.0, "info": { "bracket": "6", "initialLeverage": "3", - "maxNotional": "10000000", - "minNotional": "5000000", + "notionalCap": "10000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.1665", "cum": "315500.0" } }, { - "tier": 7, - "minNotional": 10000000, - "maxNotional": 15000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 15000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "7", "initialLeverage": "2", - "maxNotional": "15000000", - "minNotional": "10000000", + "notionalCap": "15000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1150500.0" } }, { - "tier": 8, - "minNotional": 15000000, - "maxNotional": 50000000, + "tier": 8.0, + "currency": "USDT", + "minNotional": 15000000.0, + "maxNotional": 50000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "8", "initialLeverage": "1", - "maxNotional": "50000000", - "minNotional": "15000000", + "notionalCap": "50000000", + "notionalFloor": "15000000", "maintMarginRatio": "0.5", "cum": "4900500.0" } @@ -15821,106 +16191,113 @@ ], "DYDX/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 50000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 50000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "50000", - "minNotional": "0", + "notionalCap": "50000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 50000, - "maxNotional": 150000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 50000.0, + "maxNotional": 150000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "150000", - "minNotional": "50000", + "notionalCap": "150000", + "notionalFloor": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { - "tier": 3, - "minNotional": 150000, - "maxNotional": 250000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 150000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "250000", - "minNotional": "150000", + "notionalCap": "250000", + "notionalFloor": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { - "tier": 4, - "minNotional": 250000, - "maxNotional": 500000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "500000", - "minNotional": "250000", + "notionalCap": "500000", + "notionalFloor": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { - "tier": 5, - "minNotional": 500000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 4, + "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "maxNotional": "1000000", - "minNotional": "500000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 4000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.25, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "maxNotional": "4000000", - "minNotional": "1000000", + "notionalCap": "4000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { - "tier": 7, - "minNotional": 4000000, - "maxNotional": 30000000, + "tier": 7.0, + "currency": "USDT", + "minNotional": 4000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "4000000", + "notionalCap": "30000000", + "notionalFloor": "4000000", "maintMarginRatio": "0.5", "cum": "1154500.0" } @@ -15928,91 +16305,97 @@ ], "OCEAN/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } @@ -16020,275 +16403,195 @@ ], "CHZ/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.012, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.012", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "65.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "690.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5690.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11940.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386940.0" } } ], - "LENDUSDT": [ - { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, - "maintenanceMarginRate": 0.01, - "maxLeverage": 50, - "info": { - "bracket": "1", - "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", - "maintMarginRatio": "0.01", - "cum": "0.0" - } - }, - { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, - "maintenanceMarginRate": 0.025, - "maxLeverage": 20, - "info": { - "bracket": "2", - "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", - "maintMarginRatio": "0.025", - "cum": "75.0" - } - }, - { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10, - "info": { - "bracket": "3", - "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", - "maintMarginRatio": "0.05", - "cum": "700.0" - } - }, - { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5, - "info": { - "bracket": "4", - "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", - "maintMarginRatio": "0.1", - "cum": "5700.0" - } - }, - { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, - "maintenanceMarginRate": 0.125, - "maxLeverage": 2, - "info": { - "bracket": "5", - "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", - "maintMarginRatio": "0.125", - "cum": "11950.0" - } - }, - { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 9223372036854776000, - "maintenanceMarginRate": 0.5, - "maxLeverage": 1, - "info": { - "bracket": "6", - "initialLeverage": "1", - "maxNotional": "9223372036854775807", - "minNotional": "1000000", - "maintMarginRatio": "0.5", - "cum": "386950.0" - } - } - ], "ANKR/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.012, - "maxLeverage": 50, + "maxLeverage": 50.0, "info": { "bracket": "1", "initialLeverage": "50", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.012", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "65.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "690.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5690.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11940.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386940.0" } @@ -16296,186 +16599,312 @@ ], "DUSK/USDT": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } } ], - "CTSI/USDT": [ + "BTCUSDT_220624": [ { - "tier": 1, - "minNotional": 0, - "maxNotional": 5000, - "maintenanceMarginRate": 0.01, - "maxLeverage": 25, + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 375000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, "info": { "bracket": "1", "initialLeverage": "25", - "maxNotional": "5000", - "minNotional": "0", + "notionalCap": "375000", + "notionalFloor": "0", + "maintMarginRatio": "0.02", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "currency": "USDT", + "minNotional": 375000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "2", + "initialLeverage": "10", + "notionalCap": "2000000", + "notionalFloor": "375000", + "maintMarginRatio": "0.05", + "cum": "11250.0" + } + }, + { + "tier": 3.0, + "currency": "USDT", + "minNotional": 2000000.0, + "maxNotional": 4000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "3", + "initialLeverage": "5", + "notionalCap": "4000000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.1", + "cum": "111250.0" + } + }, + { + "tier": 4.0, + "currency": "USDT", + "minNotional": 4000000.0, + "maxNotional": 10000000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "4", + "initialLeverage": "4", + "notionalCap": "10000000", + "notionalFloor": "4000000", + "maintMarginRatio": "0.125", + "cum": "211250.0" + } + }, + { + "tier": 5.0, + "currency": "USDT", + "minNotional": 10000000.0, + "maxNotional": 20000000.0, + "maintenanceMarginRate": 0.15, + "maxLeverage": 3.0, + "info": { + "bracket": "5", + "initialLeverage": "3", + "notionalCap": "20000000", + "notionalFloor": "10000000", + "maintMarginRatio": "0.15", + "cum": "461250.0" + } + }, + { + "tier": 6.0, + "currency": "USDT", + "minNotional": 20000000.0, + "maxNotional": 40000000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "6", + "initialLeverage": "2", + "notionalCap": "40000000", + "notionalFloor": "20000000", + "maintMarginRatio": "0.25", + "cum": "2461250.0" + } + }, + { + "tier": 7.0, + "currency": "USDT", + "minNotional": 40000000.0, + "maxNotional": 400000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", + "initialLeverage": "1", + "notionalCap": "400000000", + "notionalFloor": "40000000", + "maintMarginRatio": "0.5", + "cum": "1.246125E7" + } + } + ], + "CTSI/USDT": [ + { + "tier": 1.0, + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { - "tier": 2, - "minNotional": 5000, - "maxNotional": 25000, + "tier": 2.0, + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20, + "maxLeverage": 20.0, "info": { "bracket": "2", "initialLeverage": "20", - "maxNotional": "25000", - "minNotional": "5000", + "notionalCap": "25000", + "notionalFloor": "5000", "maintMarginRatio": "0.025", "cum": "75.0" } }, { - "tier": 3, - "minNotional": 25000, - "maxNotional": 100000, + "tier": 3.0, + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10, + "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "maxNotional": "100000", - "minNotional": "25000", + "notionalCap": "100000", + "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "700.0" } }, { - "tier": 4, - "minNotional": 100000, - "maxNotional": 250000, + "tier": 4.0, + "currency": "USDT", + "minNotional": 100000.0, + "maxNotional": 250000.0, "maintenanceMarginRate": 0.1, - "maxLeverage": 5, + "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "maxNotional": "250000", - "minNotional": "100000", + "notionalCap": "250000", + "notionalFloor": "100000", "maintMarginRatio": "0.1", "cum": "5700.0" } }, { - "tier": 5, - "minNotional": 250000, - "maxNotional": 1000000, + "tier": 5.0, + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.125, - "maxLeverage": 2, + "maxLeverage": 2.0, "info": { "bracket": "5", "initialLeverage": "2", - "maxNotional": "1000000", - "minNotional": "250000", + "notionalCap": "1000000", + "notionalFloor": "250000", "maintMarginRatio": "0.125", "cum": "11950.0" } }, { - "tier": 6, - "minNotional": 1000000, - "maxNotional": 30000000, + "tier": 6.0, + "currency": "USDT", + "minNotional": 1000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.5, - "maxLeverage": 1, + "maxLeverage": 1.0, "info": { "bracket": "6", "initialLeverage": "1", - "maxNotional": "30000000", - "minNotional": "1000000", + "notionalCap": "30000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", "cum": "386950.0" } } ] -} +} \ No newline at end of file diff --git a/freqtrade/exchange/bybit.py b/freqtrade/exchange/bybit.py index 484b8b9d3..1c4bb858b 100644 --- a/freqtrade/exchange/bybit.py +++ b/freqtrade/exchange/bybit.py @@ -29,3 +29,17 @@ class Bybit(Exchange): # (TradingMode.FUTURES, MarginMode.CROSS), # (TradingMode.FUTURES, MarginMode.ISOLATED) ] + + @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 diff --git a/freqtrade/exchange/common.py b/freqtrade/exchange/common.py index 4355662a8..841f45cd0 100644 --- a/freqtrade/exchange/common.py +++ b/freqtrade/exchange/common.py @@ -2,6 +2,7 @@ import asyncio import logging import time from functools import wraps +from typing import Any, Callable, Optional, TypeVar, cast, overload from freqtrade.exceptions import DDosProtection, RetryableOrderError, TemporaryError from freqtrade.mixins import LoggingMixin @@ -11,6 +12,14 @@ logger = logging.getLogger(__name__) __logging_mixin = None +def _reset_logging_mixin(): + """ + Reset global logging mixin - used in tests only. + """ + global __logging_mixin + __logging_mixin = LoggingMixin(logger) + + def _get_logging_mixin(): # Logging-mixin to cache kucoin responses # Only to be used in retrier @@ -133,8 +142,22 @@ def retrier_async(f): return wrapper -def retrier(_func=None, retries=API_RETRY_COUNT): - def decorator(f): +F = TypeVar('F', bound=Callable[..., Any]) + + +# Type shenanigans +@overload +def retrier(_func: F) -> F: + ... + + +@overload +def retrier(*, retries=API_RETRY_COUNT) -> Callable[[F], F]: + ... + + +def retrier(_func: Optional[F] = None, *, retries=API_RETRY_COUNT): + def decorator(f: F) -> F: @wraps(f) def wrapper(*args, **kwargs): count = kwargs.pop('count', retries) @@ -155,7 +178,7 @@ def retrier(_func=None, retries=API_RETRY_COUNT): else: logger.warning(msg + 'Giving up.') raise ex - return wrapper + return cast(F, wrapper) # Support both @retrier and @retrier(retries=2) syntax if _func is None: return decorator diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 685f86899..4fa8f1def 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -92,7 +92,7 @@ class Exchange: it does basic validation whether the specified exchange and pairs are valid. :return: None """ - self._api: ccxt.Exchange = None + self._api: ccxt.Exchange self._api_async: ccxt_async.Exchange = None self._markets: Dict = {} self._trading_fees: Dict[str, Any] = {} @@ -291,7 +291,7 @@ class Exchange: return self._markets @property - def precisionMode(self) -> str: + def precisionMode(self) -> int: """exchange ccxt precisionMode""" return self._api.precisionMode @@ -322,7 +322,7 @@ class Exchange: return int(self._ft_has.get('ohlcv_candle_limit_per_timeframe', {}).get( timeframe, self._ft_has.get('ohlcv_candle_limit'))) - def get_markets(self, base_currencies: List[str] = None, quote_currencies: List[str] = None, + def get_markets(self, base_currencies: List[str] = [], quote_currencies: List[str] = [], spot_only: bool = False, margin_only: bool = False, futures_only: bool = False, tradable_only: bool = True, active_only: bool = False) -> Dict[str, Any]: @@ -953,6 +953,12 @@ class Exchange: order = self.check_dry_limit_order_filled(order) return order except KeyError as e: + from freqtrade.persistence import Order + order = Order.order_by_id(order_id) + if order: + ccxt_order = order.to_ccxt_object() + self._dry_run_open_orders[order_id] = ccxt_order + return ccxt_order # Gracefully handle errors with dry-run orders. raise InvalidOrderException( f'Tried to get an invalid dry-run-order (id: {order_id}). Message: {e}') from e @@ -1158,7 +1164,7 @@ class Exchange: raise OperationalException(e) from e @retrier(retries=API_FETCH_ORDER_RETRY_COUNT) - def fetch_order(self, order_id: str, pair: str, params={}) -> Dict: + def fetch_order(self, order_id: str, pair: str, params: Dict = {}) -> Dict: if self._config['dry_run']: return self.fetch_dry_run_order(order_id) try: @@ -1180,8 +1186,8 @@ class Exchange: except ccxt.BaseError as e: raise OperationalException(e) from e - # Assign method to fetch_stoploss_order to allow easy overriding in other classes - fetch_stoploss_order = fetch_order + def fetch_stoploss_order(self, order_id: str, pair: str, params: Dict = {}) -> Dict: + return self.fetch_order(order_id, pair, params) def fetch_order_or_stoploss_order(self, order_id: str, pair: str, stoploss_order: bool = False) -> Dict: @@ -1206,7 +1212,7 @@ class Exchange: and order.get('filled') == 0.0) @retrier - def cancel_order(self, order_id: str, pair: str, params={}) -> Dict: + def cancel_order(self, order_id: str, pair: str, params: Dict = {}) -> Dict: if self._config['dry_run']: try: order = self.fetch_dry_run_order(order_id) @@ -1232,8 +1238,8 @@ class Exchange: except ccxt.BaseError as e: raise OperationalException(e) from e - # Assign method to cancel_stoploss_order to allow easy overriding in other classes - cancel_stoploss_order = cancel_order + def cancel_stoploss_order(self, order_id: str, pair: str, params: Dict = {}) -> Dict: + return self.cancel_order(order_id, pair, params) def is_cancel_order_result_suitable(self, corder) -> bool: if not isinstance(corder, dict): @@ -1345,7 +1351,7 @@ class Exchange: raise OperationalException(e) from e @retrier - def fetch_bids_asks(self, symbols: List[str] = None, cached: bool = False) -> Dict: + def fetch_bids_asks(self, symbols: Optional[List[str]] = None, cached: bool = False) -> Dict: """ :param cached: Allow cached result :return: fetch_tickers result @@ -1373,7 +1379,7 @@ class Exchange: raise OperationalException(e) from e @retrier - def get_tickers(self, symbols: List[str] = None, cached: bool = False) -> Dict: + def get_tickers(self, symbols: Optional[List[str]] = None, cached: bool = False) -> Dict: """ :param cached: Allow cached result :return: fetch_tickers result @@ -1712,7 +1718,7 @@ class Exchange: async def _async_get_historic_ohlcv(self, pair: str, timeframe: str, since_ms: int, candle_type: CandleType, is_new_pair: bool = False, raise_: bool = False, - until_ms: int = None + until_ms: Optional[int] = None ) -> Tuple[str, str, str, List]: """ Download historic ohlcv @@ -1773,7 +1779,7 @@ class Exchange: def refresh_latest_ohlcv(self, pair_list: ListPairsWithTimeframes, *, since_ms: Optional[int] = None, cache: bool = True, - drop_incomplete: bool = None + drop_incomplete: Optional[bool] = None ) -> Dict[PairWithTimeframe, DataFrame]: """ Refresh in-memory OHLCV asynchronously and set `_klines` with the result @@ -2125,10 +2131,11 @@ class Exchange: except ccxt.BaseError as e: raise OperationalException(e) from e - @retrier - def get_market_leverage_tiers(self, symbol) -> List[Dict]: + @retrier_async + async def get_market_leverage_tiers(self, symbol: str) -> Tuple[str, List[Dict]]: try: - return self._api.fetch_market_leverage_tiers(symbol) + tier = await self._api_async.fetch_market_leverage_tiers(symbol) + return symbol, tier except ccxt.DDoSProtection as e: raise DDosProtection(e) from e except (ccxt.NetworkError, ccxt.ExchangeError) as e: @@ -2162,8 +2169,14 @@ class Exchange: f"Initializing leverage_tiers for {len(symbols)} markets. " "This will take about a minute.") - for symbol in sorted(symbols): - tiers[symbol] = self.get_market_leverage_tiers(symbol) + coros = [self.get_market_leverage_tiers(symbol) for symbol in sorted(symbols)] + + for input_coro in chunks(coros, 100): + + results = self.loop.run_until_complete( + asyncio.gather(*input_coro, return_exceptions=True)) + for symbol, res in results: + tiers[symbol] = res logger.info(f"Done initializing {len(symbols)} markets.") @@ -2413,14 +2426,35 @@ class Exchange: ) @staticmethod - def combine_funding_and_mark(funding_rates: DataFrame, mark_rates: DataFrame) -> DataFrame: + def combine_funding_and_mark(funding_rates: DataFrame, mark_rates: DataFrame, + futures_funding_rate: Optional[int] = None) -> DataFrame: """ Combine funding-rates and mark-rates dataframes :param funding_rates: Dataframe containing Funding rates (Type FUNDING_RATE) :param mark_rates: Dataframe containing Mark rates (Type mark_ohlcv_price) + :param futures_funding_rate: Fake funding rate to use if funding_rates are not available """ + if futures_funding_rate is None: + return mark_rates.merge( + funding_rates, on='date', how="inner", suffixes=["_mark", "_fund"]) + else: + if len(funding_rates) == 0: + # No funding rate candles - full fillup with fallback variable + mark_rates['open_fund'] = futures_funding_rate + return mark_rates.rename( + columns={'open': 'open_mark', + 'close': 'close_mark', + 'high': 'high_mark', + 'low': 'low_mark', + 'volume': 'volume_mark'}) - return funding_rates.merge(mark_rates, on='date', how="inner", suffixes=["_fund", "_mark"]) + else: + # Fill up missing funding_rate candles with fallback value + combined = mark_rates.merge( + funding_rates, on='date', how="outer", suffixes=["_mark", "_fund"] + ) + combined['open_fund'] = combined['open_fund'].fillna(futures_funding_rate) + return combined def calculate_funding_fees( self, diff --git a/freqtrade/exchange/ftx.py b/freqtrade/exchange/ftx.py index 65c2a53ca..9ee6894f1 100644 --- a/freqtrade/exchange/ftx.py +++ b/freqtrade/exchange/ftx.py @@ -104,7 +104,7 @@ class Ftx(Exchange): raise OperationalException(e) from e @retrier(retries=API_FETCH_ORDER_RETRY_COUNT) - def fetch_stoploss_order(self, order_id: str, pair: str) -> Dict: + def fetch_stoploss_order(self, order_id: str, pair: str, params: Dict = {}) -> Dict: if self._config['dry_run']: return self.fetch_dry_run_order(order_id) @@ -145,7 +145,7 @@ class Ftx(Exchange): raise OperationalException(e) from e @retrier - def cancel_stoploss_order(self, order_id: str, pair: str) -> Dict: + def cancel_stoploss_order(self, order_id: str, pair: str, params: Dict = {}) -> Dict: if self._config['dry_run']: return {} try: diff --git a/freqtrade/exchange/gateio.py b/freqtrade/exchange/gateio.py index 609cf4901..bf50167da 100644 --- a/freqtrade/exchange/gateio.py +++ b/freqtrade/exchange/gateio.py @@ -3,6 +3,7 @@ import logging from datetime import datetime from typing import Dict, List, Optional, Tuple +from freqtrade.constants import BuySell from freqtrade.enums import MarginMode, TradingMode from freqtrade.exceptions import OperationalException from freqtrade.exchange import Exchange @@ -24,6 +25,8 @@ class Gateio(Exchange): _ft_has: Dict = { "ohlcv_candle_limit": 1000, "ohlcv_volume_currency": "quote", + "time_in_force_parameter": "timeInForce", + "order_time_in_force": ['gtc', 'ioc'], "stoploss_order_types": {"limit": "limit"}, "stoploss_on_exchange": True, } @@ -40,13 +43,33 @@ class Gateio(Exchange): ] def validate_ordertypes(self, order_types: Dict) -> None: - super().validate_ordertypes(order_types) if self.trading_mode != TradingMode.FUTURES: if any(v == 'market' for k, v in order_types.items()): raise OperationalException( f'Exchange {self.name} does not support market orders.') + def _get_params( + self, + side: BuySell, + ordertype: str, + leverage: float, + reduceOnly: bool, + time_in_force: str = 'gtc', + ) -> Dict: + params = super()._get_params( + side=side, + ordertype=ordertype, + leverage=leverage, + reduceOnly=reduceOnly, + time_in_force=time_in_force, + ) + if ordertype == 'market' and self.trading_mode == TradingMode.FUTURES: + params['type'] = 'market' + param = self._ft_has.get('time_in_force_parameter', '') + params.update({param: 'ioc'}) + return params + def get_trades_for_order(self, order_id: str, pair: str, since: datetime, params: Optional[Dict] = None) -> List: trades = super().get_trades_for_order(order_id, pair, since, params) @@ -61,7 +84,8 @@ class Gateio(Exchange): pair_fees = self._trading_fees.get(pair, {}) if pair_fees: for idx, trade in enumerate(trades): - if trade.get('fee', {}).get('cost') is None: + fee = trade.get('fee', {}) + if fee and fee.get('cost') is None: takerOrMaker = trade.get('takerOrMaker', 'taker') if pair_fees.get(takerOrMaker) is not None: trades[idx]['fee'] = { @@ -71,14 +95,14 @@ class Gateio(Exchange): } return trades - def fetch_stoploss_order(self, order_id: str, pair: str, params={}) -> Dict: + def fetch_stoploss_order(self, order_id: str, pair: str, params: Dict = {}) -> Dict: return self.fetch_order( order_id=order_id, pair=pair, params={'stop': True} ) - def cancel_stoploss_order(self, order_id: str, pair: str, params={}) -> Dict: + def cancel_stoploss_order(self, order_id: str, pair: str, params: Dict = {}) -> Dict: return self.cancel_order( order_id=order_id, pair=pair, @@ -90,5 +114,7 @@ class Gateio(Exchange): Verify stop_loss against stoploss-order value (limit or price) Returns True if adjustment is necessary. """ - return ((side == "sell" and stop_loss > float(order['stopPrice'])) or - (side == "buy" and stop_loss < float(order['stopPrice']))) + return (order.get('stopPrice', None) is None or ( + side == "sell" and stop_loss > float(order['stopPrice'])) or + (side == "buy" and stop_loss < float(order['stopPrice'])) + ) diff --git a/freqtrade/exchange/huobi.py b/freqtrade/exchange/huobi.py index 71c4d1cf6..736515dec 100644 --- a/freqtrade/exchange/huobi.py +++ b/freqtrade/exchange/huobi.py @@ -27,7 +27,13 @@ class Huobi(Exchange): Verify stop_loss against stoploss-order value (limit or price) Returns True if adjustment is necessary. """ - return order['type'] == 'stop' and stop_loss > float(order['stopPrice']) + return ( + order.get('stopPrice', None) is None + or ( + order['type'] == 'stop' + and stop_loss > float(order['stopPrice']) + ) + ) def _get_stop_params(self, ordertype: str, stop_price: float) -> Dict: diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index 900f6c898..0103e2702 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -45,7 +45,7 @@ class Kraken(Exchange): return (parent_check and market.get('darkpool', False) is False) - def get_tickers(self, symbols: List[str] = None, cached: bool = False) -> Dict: + def get_tickers(self, symbols: Optional[List[str]] = None, cached: bool = False) -> Dict: # Only fetch tickers for current stake currency # Otherwise the request for kraken becomes too large. symbols = list(self.get_markets(quote_currencies=[self._config['stake_currency']])) diff --git a/freqtrade/exchange/kucoin.py b/freqtrade/exchange/kucoin.py index f23189b3c..21eaa4bc3 100644 --- a/freqtrade/exchange/kucoin.py +++ b/freqtrade/exchange/kucoin.py @@ -33,7 +33,10 @@ class Kucoin(Exchange): Verify stop_loss against stoploss-order value (limit or price) Returns True if adjustment is necessary. """ - return order['info'].get('stop') is not None and stop_loss > float(order['stopPrice']) + return ( + order.get('stopPrice', None) is None + or stop_loss > float(order['stopPrice']) + ) def _get_stop_params(self, ordertype: str, stop_price: float) -> Dict: diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index cbd44a755..affc6f360 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -4,7 +4,7 @@ Freqtrade is the main module of this bot. It contains the class Freqtrade() import copy import logging import traceback -from datetime import datetime, time, timezone +from datetime import datetime, time, timedelta, timezone from math import isclose from threading import Lock from typing import Any, Dict, List, Optional, Tuple @@ -67,14 +67,12 @@ class FreqtradeBot(LoggingMixin): self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config) - init_db(self.config['db_url'], clean_open_orders=self.config['dry_run']) + init_db(self.config['db_url']) self.wallets = Wallets(self.config, self.exchange) PairLocks.timeframe = self.config['timeframe'] - self.protections = ProtectionManager(self.config, self.strategy.protections) - # RPC runs in separate threads, can start handling external commands just after # initialization, even before Freqtradebot has a chance to start its throttling, # so anything in the Freqtradebot instance should be ready (initialized), including @@ -123,7 +121,9 @@ class FreqtradeBot(LoggingMixin): self._schedule.every().day.at(t).do(update) self.last_process = datetime(1970, 1, 1, tzinfo=timezone.utc) - self.strategy.bot_start() + self.strategy.ft_bot_start() + # Initialize protections AFTER bot start - otherwise parameters are not loaded. + self.protections = ProtectionManager(self.config, self.strategy.protections) def notify_status(self, msg: str) -> None: """ @@ -227,7 +227,7 @@ class FreqtradeBot(LoggingMixin): Notify the user when the bot is stopped (not reloaded) and there are still open trades active. """ - open_trades = Trade.get_trades([Trade.is_open.is_(True)]).all() + open_trades = Trade.get_open_trades() if len(open_trades) != 0 and self.state != State.RELOAD_CONFIG: msg = { @@ -299,7 +299,17 @@ class FreqtradeBot(LoggingMixin): fo = self.exchange.fetch_order_or_stoploss_order(order.order_id, order.ft_pair, order.ft_order_side == 'stoploss') - self.update_trade_state(order.trade, order.order_id, fo) + self.update_trade_state(order.trade, order.order_id, fo, + stoploss_order=(order.ft_order_side == 'stoploss')) + + except InvalidOrderException as e: + logger.warning(f"Error updating Order {order.order_id} due to {e}.") + if order.order_date_utc - timedelta(days=5) < datetime.now(timezone.utc): + logger.warning( + "Order is older than 5 days. Assuming order was fully cancelled.") + fo = order.to_ccxt_object() + fo['status'] = 'canceled' + self.handle_timedout_order(fo, order.trade) except ExchangeError as e: @@ -780,7 +790,7 @@ class FreqtradeBot(LoggingMixin): current_rate=enter_limit_requested, proposed_leverage=1.0, max_leverage=max_leverage, - side=trade_side, + side=trade_side, entry_tag=entry_tag, ) if self.trading_mode != TradingMode.SPOT else 1.0 # Cap leverage between 1.0 and max_leverage. leverage = min(max(leverage, 1.0), max_leverage) @@ -1018,7 +1028,7 @@ class FreqtradeBot(LoggingMixin): # Lock pair for one candle to prevent immediate rebuys self.strategy.lock_pair(trade.pair, datetime.now(timezone.utc), reason='Auto lock') - self._notify_exit(trade, "stoploss") + self._notify_exit(trade, "stoploss", True) return True if trade.open_order_id or not trade.is_open: @@ -1105,7 +1115,7 @@ class FreqtradeBot(LoggingMixin): """ Check and execute trade exit """ - should_exit: ExitCheckTuple = self.strategy.should_exit( + exits: List[ExitCheckTuple] = self.strategy.should_exit( trade, exit_rate, datetime.now(timezone.utc), @@ -1113,12 +1123,13 @@ class FreqtradeBot(LoggingMixin): exit_=exit_, force_stoploss=self.edge.stoploss(trade.pair) if self.edge else 0 ) - - if should_exit.exit_flag: - logger.info(f'Exit for {trade.pair} detected. Reason: {should_exit.exit_type}' - f'Tag: {exit_tag if exit_tag is not None else "None"}') - self.execute_trade_exit(trade, exit_rate, should_exit, exit_tag=exit_tag) - return True + for should_exit in exits: + if should_exit.exit_flag: + logger.info(f'Exit for {trade.pair} detected. Reason: {should_exit.exit_type}' + f'{f" Tag: {exit_tag}" if exit_tag is not None else ""}') + exited = self.execute_trade_exit(trade, exit_rate, should_exit, exit_tag=exit_tag) + if exited: + return True return False def manage_open_orders(self) -> None: @@ -1201,15 +1212,15 @@ class FreqtradeBot(LoggingMixin): current_order_rate=order_obj.price, entry_tag=trade.enter_tag, side=trade.entry_side) - full_cancel = False + replacing = True cancel_reason = constants.CANCEL_REASON['REPLACE'] if not adjusted_entry_price: - full_cancel = True if trade.nr_of_successful_entries == 0 else False + replacing = False cancel_reason = constants.CANCEL_REASON['USER_CANCEL'] if order_obj.price != adjusted_entry_price: # cancel existing order if new price is supplied or None self.handle_cancel_enter(trade, order, cancel_reason, - allow_full_cancel=full_cancel) + replacing=replacing) if adjusted_entry_price: # place new order only if new price is supplied self.execute_entry( @@ -1243,10 +1254,11 @@ class FreqtradeBot(LoggingMixin): def handle_cancel_enter( self, trade: Trade, order: Dict, reason: str, - allow_full_cancel: Optional[bool] = True + replacing: Optional[bool] = False ) -> bool: """ Buy cancel - cancel order + :param replacing: Replacing order - prevent trade deletion. :return: True if order was fully cancelled """ was_trade_fully_canceled = False @@ -1284,7 +1296,7 @@ class FreqtradeBot(LoggingMixin): if isclose(filled_amount, 0.0, abs_tol=constants.MATH_CLOSE_PREC): # if trade is not partially completed and it's the only order, just delete the trade open_order_count = len([order for order in trade.orders if order.status == 'open']) - if open_order_count <= 1 and allow_full_cancel: + if open_order_count <= 1 and trade.nr_of_successful_entries == 0 and not replacing: logger.info(f'{side} order fully cancelled. Removing {trade} from database.') trade.delete() was_trade_fully_canceled = True @@ -1293,7 +1305,7 @@ class FreqtradeBot(LoggingMixin): # FIXME TODO: This could possibly reworked to not duplicate the code 15 lines below. self.update_trade_state(trade, trade.open_order_id, corder) trade.open_order_id = None - logger.info(f'Partial {side} order timeout for {trade}.') + logger.info(f'{side} Order timeout for {trade}.') else: # if trade is partially complete, edit the stake details for the trade # and close the order @@ -1405,7 +1417,7 @@ class FreqtradeBot(LoggingMixin): :param trade: Trade instance :param limit: limit rate for the sell order :param exit_check: CheckTuple with signal and reason - :return: True if it succeeds (supported) False (not supported) + :return: True if it succeeds False """ trade.funding_fees = self.exchange.get_funding_fees( pair=trade.pair, @@ -1452,7 +1464,7 @@ class FreqtradeBot(LoggingMixin): time_in_force=time_in_force, exit_reason=exit_reason, sell_reason=exit_reason, # sellreason -> compatibility current_time=datetime.now(timezone.utc)): - logger.info(f"User requested abortion of exiting {trade.pair}") + logger.info(f"User requested abortion of {trade.pair} exit.") return False try: @@ -1663,7 +1675,7 @@ class FreqtradeBot(LoggingMixin): if send_msg and not stoploss_order and not trade.open_order_id: self._notify_exit(trade, '', True) self.handle_protections(trade.pair, trade.trade_direction) - elif send_msg and not trade.open_order_id: + elif send_msg and not trade.open_order_id and not stoploss_order: # Enter fill self._notify_enter(trade, order, fill=True) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index f1ccd3b51..6f566a346 100755 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -187,7 +187,8 @@ class Backtesting: # since a "perfect" stoploss-exit is assumed anyway # And the regular "stoploss" function would not apply to that case self.strategy.order_types['stoploss_on_exchange'] = False - self.strategy.bot_start() + + self.strategy.ft_bot_start() def _load_protections(self, strategy: IStrategy): if self.config.get('enable_protections', False): @@ -275,8 +276,12 @@ class Backtesting: if pair not in self.exchange._leverage_tiers: unavailable_pairs.append(pair) continue - self.futures_data[pair] = funding_rates_dict[pair].merge( - mark_rates_dict[pair], on='date', how="inner", suffixes=["_fund", "_mark"]) + + self.futures_data[pair] = self.exchange.combine_funding_and_mark( + funding_rates=funding_rates_dict[pair], + mark_rates=mark_rates_dict[pair], + futures_funding_rate=self.config.get('futures_funding_rate', None), + ) if unavailable_pairs: raise OperationalException( @@ -496,7 +501,8 @@ class Backtesting: stake_available = self.wallets.get_available_stake_amount() stake_amount = strategy_safe_wrapper(self.strategy.adjust_trade_position, default_retval=None)( - trade=trade, current_time=row[DATE_IDX].to_pydatetime(), current_rate=row[OPEN_IDX], + trade=trade, # type: ignore[arg-type] + current_time=row[DATE_IDX].to_pydatetime(), current_rate=row[OPEN_IDX], current_profit=current_profit, min_stake=min_stake, max_stake=min(max_stake, stake_available)) @@ -527,15 +533,23 @@ class Backtesting: if check_adjust_entry: trade = self._get_adjust_trade_entry_for_candle(trade, row) - exit_candle_time: datetime = row[DATE_IDX].to_pydatetime() enter = row[SHORT_IDX] if trade.is_short else row[LONG_IDX] exit_sig = row[ESHORT_IDX] if trade.is_short else row[ELONG_IDX] - exit_ = self.strategy.should_exit( - trade, row[OPEN_IDX], exit_candle_time, # type: ignore + exits = self.strategy.should_exit( + trade, row[OPEN_IDX], row[DATE_IDX].to_pydatetime(), # type: ignore enter=enter, exit_=exit_sig, low=row[LOW_IDX], high=row[HIGH_IDX] ) + for exit_ in exits: + t = self._get_exit_for_signal(trade, row, exit_) + if t: + return t + return None + def _get_exit_for_signal(self, trade: LocalTrade, row: Tuple, + exit_: ExitCheckTuple) -> Optional[LocalTrade]: + + exit_candle_time: datetime = row[DATE_IDX].to_pydatetime() if exit_.exit_flag: trade.close_date = exit_candle_time exit_reason = exit_.exit_reason @@ -562,7 +576,8 @@ class Backtesting: if order_type == 'limit': close_rate = strategy_safe_wrapper(self.strategy.custom_exit_price, default_retval=close_rate)( - pair=trade.pair, trade=trade, + pair=trade.pair, + trade=trade, # type: ignore[arg-type] current_time=exit_candle_time, proposed_rate=close_rate, current_profit=current_profit, exit_tag=exit_reason) @@ -576,7 +591,10 @@ class Backtesting: time_in_force = self.strategy.order_time_in_force['exit'] if not strategy_safe_wrapper(self.strategy.confirm_trade_exit, default_retval=True)( - pair=trade.pair, trade=trade, order_type='limit', amount=trade.amount, + pair=trade.pair, + trade=trade, # type: ignore[arg-type] + order_type='limit', + amount=trade.amount, rate=close_rate, time_in_force=time_in_force, sell_reason=exit_reason, # deprecated @@ -652,7 +670,7 @@ class Backtesting: return self._get_exit_trade_entry_for_candle(trade, row) def get_valid_price_and_stake( - self, pair: str, row: Tuple, propose_rate: float, stake_amount: Optional[float], + self, pair: str, row: Tuple, propose_rate: float, stake_amount: float, direction: LongShort, current_time: datetime, entry_tag: Optional[str], trade: Optional[LocalTrade], order_type: str ) -> Tuple[float, float, float, float]: @@ -686,7 +704,7 @@ class Backtesting: current_rate=row[OPEN_IDX], proposed_leverage=1.0, max_leverage=max_leverage, - side=direction, + side=direction, entry_tag=entry_tag, ) if self._can_short else 1.0 # Cap leverage between 1.0 and max_leverage. leverage = min(max(leverage, 1.0), max_leverage) @@ -726,8 +744,9 @@ class Backtesting: order_type = self.strategy.order_types['entry'] pos_adjust = trade is not None and requested_rate is None + stake_amount_ = stake_amount or (trade.stake_amount if trade else 0.0) propose_rate, stake_amount, leverage, min_stake_amount = self.get_valid_price_and_stake( - pair, row, row[OPEN_IDX], stake_amount, direction, current_time, entry_tag, trade, + pair, row, row[OPEN_IDX], stake_amount_, direction, current_time, entry_tag, trade, order_type ) @@ -876,28 +895,34 @@ class Backtesting: self.protections.stop_per_pair(pair, current_time, side) self.protections.global_stop(current_time, side) - def manage_open_orders(self, trade: LocalTrade, current_time, row: Tuple) -> bool: + def manage_open_orders(self, trade: LocalTrade, current_time: datetime, row: Tuple) -> bool: """ Check if any open order needs to be cancelled or replaced. Returns True if the trade should be deleted. """ for order in [o for o in trade.orders if o.ft_is_open]: - if self.check_order_cancel(trade, order, current_time): + oc = self.check_order_cancel(trade, order, current_time) + if oc: # delete trade due to order timeout return True - elif self.check_order_replace(trade, order, current_time, row): + elif oc is None and self.check_order_replace(trade, order, current_time, row): # delete trade due to user request self.canceled_trade_entries += 1 return True # default maintain trade return False - def check_order_cancel(self, trade: LocalTrade, order: Order, current_time) -> bool: + def check_order_cancel( + self, trade: LocalTrade, order: Order, current_time: datetime) -> Optional[bool]: """ Check if current analyzed order has to be canceled. - Returns True if the trade should be Deleted (initial order was canceled). + Returns True if the trade should be Deleted (initial order was canceled), + False if it's Canceled + None if the order is still active. """ - timedout = self.strategy.ft_check_timed_out(trade, order, current_time) + timedout = self.strategy.ft_check_timed_out( + trade, # type: ignore[arg-type] + order, current_time) if timedout: if order.side == trade.entry_side: self.timedout_entry_orders += 1 @@ -907,12 +932,15 @@ class Backtesting: else: # Close additional entry order del trade.orders[trade.orders.index(order)] + trade.open_order_id = None + return False if order.side == trade.exit_side: self.timedout_exit_orders += 1 # Close exit order and retry exiting on next signal. del trade.orders[trade.orders.index(order)] - - return False + trade.open_order_id = None + return False + return None def check_order_replace(self, trade: LocalTrade, order: Order, current_time, row: Tuple) -> bool: @@ -926,7 +954,8 @@ class Backtesting: if order.side == trade.entry_side and current_time > order.order_date_utc: requested_rate = strategy_safe_wrapper(self.strategy.adjust_entry_price, default_retval=order.price)( - trade=trade, order=order, pair=trade.pair, current_time=current_time, + trade=trade, # type: ignore[arg-type] + order=order, pair=trade.pair, current_time=current_time, proposed_rate=row[OPEN_IDX], current_order_rate=order.price, entry_tag=trade.enter_tag, side=trade.trade_direction ) # default value is current order price @@ -937,6 +966,7 @@ class Backtesting: return False else: del trade.orders[trade.orders.index(order)] + trade.open_order_id = None self.canceled_entry_orders += 1 # place new order if result was not None @@ -1025,6 +1055,7 @@ class Backtesting: # Close trade open_trade_count -= 1 open_trades[pair].remove(t) + LocalTrade.trades_open.remove(t) self.wallets.update() # 2. Process entries. @@ -1048,6 +1079,8 @@ class Backtesting: open_trade_count += 1 # logger.debug(f"{pair} - Emulate creation of new trade: {trade}.") open_trades[pair].append(trade) + LocalTrade.add_bt_trade(trade) + self.wallets.update() for trade in list(open_trades[pair]): # 3. Process entry orders. @@ -1055,7 +1088,6 @@ class Backtesting: if order and self._get_order_filled(order.price, row): order.close_bt_order(current_time, trade) trade.open_order_id = None - LocalTrade.add_bt_trade(trade) self.wallets.update() # 4. Create exit orders (if any) @@ -1065,6 +1097,7 @@ class Backtesting: # 5. Process exit orders. order = trade.select_order(trade.exit_side, is_open=True) if order and self._get_order_filled(order.price, row): + order.close_bt_order(current_time, trade) trade.open_order_id = None trade.close_date = current_time trade.close(order.price, show_msg=False) @@ -1233,13 +1266,14 @@ class Backtesting: self.results['strategy_comparison'].extend(results['strategy_comparison']) else: self.results = results - + dt_appendix = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") if self.config.get('export', 'none') in ('trades', 'signals'): - store_backtest_stats(self.config['exportfilename'], self.results) + store_backtest_stats(self.config['exportfilename'], self.results, dt_appendix) if (self.config.get('export', 'none') == 'signals' and self.dataprovider.runmode == RunMode.BACKTEST): - store_backtest_signal_candles(self.config['exportfilename'], self.processed_dfs) + store_backtest_signal_candles( + self.config['exportfilename'], self.processed_dfs, dt_appendix) # Results may be mixed up now. Sort them so they follow --strategy-list order. if 'strategy_list' in self.config and len(self.results) > 0: diff --git a/freqtrade/optimize/edge_cli.py b/freqtrade/optimize/edge_cli.py index 30eabecd0..aa3b02529 100644 --- a/freqtrade/optimize/edge_cli.py +++ b/freqtrade/optimize/edge_cli.py @@ -44,7 +44,7 @@ class EdgeCli: self.edge._timerange = TimeRange.parse_timerange(None if self.config.get( 'timerange') is None else str(self.config.get('timerange'))) - self.strategy.bot_start() + self.strategy.ft_bot_start() def start(self) -> None: result = self.edge.calculate(self.config['exchange']['pair_whitelist']) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index a267ca4ac..7c7493590 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -27,8 +27,7 @@ from freqtrade.misc import deep_merge_dicts, file_dump_json, plural from freqtrade.optimize.backtesting import Backtesting # Import IHyperOpt and IHyperOptLoss to allow unpickling classes from these modules from freqtrade.optimize.hyperopt_auto import HyperOptAuto -from freqtrade.optimize.hyperopt_interface import IHyperOpt # noqa: F401 -from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss # noqa: F401 +from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss from freqtrade.optimize.hyperopt_tools import HyperoptTools, hyperopt_serializer from freqtrade.optimize.optimize_reports import generate_strategy_stats from freqtrade.resolvers.hyperopt_resolver import HyperOptLossResolver @@ -62,7 +61,6 @@ class Hyperopt: hyperopt = Hyperopt(config) hyperopt.start() """ - custom_hyperopt: IHyperOpt def __init__(self, config: Dict[str, Any]) -> None: self.buy_space: List[Dimension] = [] @@ -77,6 +75,7 @@ class Hyperopt: self.backtesting = Backtesting(self.config) self.pairlist = self.backtesting.pairlists.whitelist + self.custom_hyperopt: HyperOptAuto if not self.config.get('hyperopt'): self.custom_hyperopt = HyperOptAuto(self.config) @@ -88,7 +87,8 @@ class Hyperopt: self.backtesting._set_strategy(self.backtesting.strategylist[0]) self.custom_hyperopt.strategy = self.backtesting.strategy - self.custom_hyperoptloss = HyperOptLossResolver.load_hyperoptloss(self.config) + self.custom_hyperoptloss: IHyperOptLoss = HyperOptLossResolver.load_hyperoptloss( + self.config) self.calculate_loss = self.custom_hyperoptloss.hyperopt_loss_function time_now = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") strategy = str(self.config['strategy']) @@ -429,7 +429,7 @@ class Hyperopt: return new_list i = 0 asked_non_tried: List[List[Any]] = [] - is_random: List[bool] = [] + is_random_non_tried: List[bool] = [] while i < 5 and len(asked_non_tried) < n_points: if i < 3: self.opt.cache_ = {} @@ -438,9 +438,9 @@ class Hyperopt: else: asked = unique_list(self.opt.space.rvs(n_samples=n_points * 5)) is_random = [True for _ in range(len(asked))] - is_random += [rand for x, rand in zip(asked, is_random) - if x not in self.opt.Xi - and x not in asked_non_tried] + is_random_non_tried += [rand for x, rand in zip(asked, is_random) + if x not in self.opt.Xi + and x not in asked_non_tried] asked_non_tried += [x for x in asked if x not in self.opt.Xi and x not in asked_non_tried] @@ -449,7 +449,7 @@ class Hyperopt: if asked_non_tried: return ( asked_non_tried[:min(len(asked_non_tried), n_points)], - is_random[:min(len(asked_non_tried), n_points)] + is_random_non_tried[:min(len(asked_non_tried), n_points)] ) else: return self.opt.ask(n_points=n_points), [False for _ in range(n_points)] diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index 93336fa3f..44ac4a5b3 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -4,7 +4,6 @@ from datetime import datetime, timedelta, timezone from pathlib import Path from typing import Any, Dict, List, Union -from numpy import int64 from pandas import DataFrame, to_datetime from tabulate import tabulate @@ -18,21 +17,21 @@ from freqtrade.optimize.backtest_caching import get_backtest_metadata_filename logger = logging.getLogger(__name__) -def store_backtest_stats(recordfilename: Path, stats: Dict[str, DataFrame]) -> None: +def store_backtest_stats( + recordfilename: Path, stats: Dict[str, DataFrame], dtappendix: str) -> None: """ Stores backtest results :param recordfilename: Path object, which can either be a filename or a directory. Filenames will be appended with a timestamp right before the suffix while for directories, /backtest-result-.json will be used as filename :param stats: Dataframe containing the backtesting statistics + :param dtappendix: Datetime to use for the filename """ if recordfilename.is_dir(): - filename = (recordfilename / - f'backtest-result-{datetime.now().strftime("%Y-%m-%d_%H-%M-%S")}.json') + filename = (recordfilename / f'backtest-result-{dtappendix}.json') else: filename = Path.joinpath( - recordfilename.parent, - f'{recordfilename.stem}-{datetime.now().strftime("%Y-%m-%d_%H-%M-%S")}' + recordfilename.parent, f'{recordfilename.stem}-{dtappendix}' ).with_suffix(recordfilename.suffix) # Store metadata separately. @@ -45,7 +44,8 @@ def store_backtest_stats(recordfilename: Path, stats: Dict[str, DataFrame]) -> N file_dump_json(latest_filename, {'latest_backtest': str(filename.name)}) -def store_backtest_signal_candles(recordfilename: Path, candles: Dict[str, Dict]) -> Path: +def store_backtest_signal_candles( + recordfilename: Path, candles: Dict[str, Dict], dtappendix: str) -> Path: """ Stores backtest trade signal candles :param recordfilename: Path object, which can either be a filename or a directory. @@ -53,14 +53,13 @@ def store_backtest_signal_candles(recordfilename: Path, candles: Dict[str, Dict] while for directories, /backtest-result-_signals.pkl will be used as filename :param stats: Dict containing the backtesting signal candles + :param dtappendix: Datetime to use for the filename """ if recordfilename.is_dir(): - filename = (recordfilename / - f'backtest-result-{datetime.now().strftime("%Y-%m-%d_%H-%M-%S")}_signals.pkl') + filename = (recordfilename / f'backtest-result-{dtappendix}_signals.pkl') else: filename = Path.joinpath( - recordfilename.parent, - f'{recordfilename.stem}-{datetime.now().strftime("%Y-%m-%d_%H-%M-%S")}_signals.pkl' + recordfilename.parent, f'{recordfilename.stem}-{dtappendix}_signals.pkl' ) file_dump_joblib(filename, candles) @@ -417,9 +416,9 @@ def generate_strategy_stats(pairlist: List[str], key=lambda x: x['profit_sum']) if len(pair_results) > 1 else None worst_pair = min([pair for pair in pair_results if pair['key'] != 'TOTAL'], key=lambda x: x['profit_sum']) if len(pair_results) > 1 else None - if not results.empty: - results['open_timestamp'] = results['open_date'].view(int64) // 1e6 - results['close_timestamp'] = results['close_date'].view(int64) // 1e6 + winning_profit = results.loc[results['profit_abs'] > 0, 'profit_abs'].sum() + losing_profit = results.loc[results['profit_abs'] < 0, 'profit_abs'].sum() + profit_factor = winning_profit / abs(losing_profit) if losing_profit else 0.0 backtest_days = (max_date - min_date).days or 1 strat_stats = { @@ -447,6 +446,7 @@ def generate_strategy_stats(pairlist: List[str], 'profit_total_long_abs': results.loc[~results['is_short'], 'profit_abs'].sum(), 'profit_total_short_abs': results.loc[results['is_short'], 'profit_abs'].sum(), 'cagr': calculate_cagr(backtest_days, start_balance, content['final_balance']), + 'profit_factor': profit_factor, 'backtest_start': min_date.strftime(DATETIME_PRINT_FORMAT), 'backtest_start_ts': int(min_date.timestamp() * 1000), 'backtest_end': max_date.strftime(DATETIME_PRINT_FORMAT), @@ -501,8 +501,10 @@ def generate_strategy_stats(pairlist: List[str], (drawdown_abs, drawdown_start, drawdown_end, high_val, low_val, max_drawdown) = calculate_max_drawdown( results, value_col='profit_abs', starting_balance=start_balance) + # max_relative_drawdown = Underwater (_, _, _, _, _, max_relative_drawdown) = calculate_max_drawdown( results, value_col='profit_abs', starting_balance=start_balance, relative=True) + strat_stats.update({ 'max_drawdown': max_drawdown_legacy, # Deprecated - do not use 'max_drawdown_account': max_drawdown, @@ -781,6 +783,8 @@ def text_table_add_metrics(strat_results: Dict) -> str: strat_results['stake_currency'])), ('Total profit %', f"{strat_results['profit_total']:.2%}"), ('CAGR %', f"{strat_results['cagr']:.2%}" if 'cagr' in strat_results else 'N/A'), + ('Profit factor', f'{strat_results["profit_factor"]:.2f}' if 'profit_factor' + in strat_results else 'N/A'), ('Trades per day', strat_results['trades_per_day']), ('Avg. daily profit %', f"{(strat_results['profit_total'] / strat_results['backtest_days']):.2%}"), diff --git a/freqtrade/persistence/__init__.py b/freqtrade/persistence/__init__.py index ab6e2f6a5..f4e7470a7 100644 --- a/freqtrade/persistence/__init__.py +++ b/freqtrade/persistence/__init__.py @@ -1,5 +1,5 @@ # flake8: noqa: F401 -from freqtrade.persistence.models import clean_dry_run_db, cleanup_db, init_db +from freqtrade.persistence.models import cleanup_db, init_db from freqtrade.persistence.pairlock_middleware import PairLocks from freqtrade.persistence.trade_model import LocalTrade, Order, Trade diff --git a/freqtrade/persistence/migrations.py b/freqtrade/persistence/migrations.py index 53e35d9da..f8fc5d619 100644 --- a/freqtrade/persistence/migrations.py +++ b/freqtrade/persistence/migrations.py @@ -201,16 +201,18 @@ def migrate_orders_table(engine, table_back_name: str, cols_order: List): ft_fee_base = get_column_def(cols_order, 'ft_fee_base', 'null') average = get_column_def(cols_order, 'average', 'null') + stop_price = get_column_def(cols_order, 'stop_price', 'null') # sqlite does not support literals for booleans with engine.begin() as connection: connection.execute(text(f""" insert into orders (id, ft_trade_id, ft_order_side, ft_pair, ft_is_open, order_id, status, symbol, order_type, side, price, amount, filled, average, remaining, cost, - order_date, order_filled_date, order_update_date, ft_fee_base) + stop_price, order_date, order_filled_date, order_update_date, ft_fee_base) select id, ft_trade_id, ft_order_side, ft_pair, ft_is_open, order_id, status, symbol, order_type, side, price, amount, filled, {average} average, remaining, - cost, order_date, order_filled_date, order_update_date, {ft_fee_base} ft_fee_base + cost, {stop_price} stop_price, order_date, order_filled_date, + order_update_date, {ft_fee_base} ft_fee_base from {table_back_name} """)) @@ -247,6 +249,35 @@ def set_sqlite_to_wal(engine): connection.execute(text("PRAGMA journal_mode=wal")) +def fix_old_dry_orders(engine): + with engine.begin() as connection: + connection.execute( + text( + """ + update orders + set ft_is_open = 0 + where ft_is_open = 1 and (ft_trade_id, order_id) not in ( + select id, stoploss_order_id from trades where stoploss_order_id is not null + ) and ft_order_side = 'stoploss' + and order_id like 'dry_%' + """ + ) + ) + connection.execute( + text( + """ + update orders + set ft_is_open = 0 + where ft_is_open = 1 + and (ft_trade_id, order_id) not in ( + select id, open_order_id from trades where open_order_id is not null + ) and ft_order_side != 'stoploss' + and order_id like 'dry_%' + """ + ) + ) + + def check_migrate(engine, decl_base, previous_tables) -> None: """ Checks if migration is necessary and migrates if necessary @@ -265,9 +296,8 @@ def check_migrate(engine, decl_base, previous_tables) -> None: # Check if migration necessary # Migrates both trades and orders table! - # if ('orders' not in previous_tables - # or not has_column(cols_orders, 'leverage')): - if not has_column(cols_trades, 'base_currency'): + if not has_column(cols_orders, 'stop_price'): + # if not has_column(cols_trades, 'base_currency'): logger.info(f"Running database migration for trades - " f"backup: {table_back_name}, {order_table_bak_name}") migrate_trades_and_orders_table( @@ -288,3 +318,4 @@ def check_migrate(engine, decl_base, previous_tables) -> None: "start with a fresh database.") set_sqlite_to_wal(engine) + fix_old_dry_orders(engine) diff --git a/freqtrade/persistence/models.py b/freqtrade/persistence/models.py index c31e50892..86d2f9f9c 100644 --- a/freqtrade/persistence/models.py +++ b/freqtrade/persistence/models.py @@ -21,14 +21,12 @@ logger = logging.getLogger(__name__) _SQL_DOCS_URL = 'http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls' -def init_db(db_url: str, clean_open_orders: bool = False) -> None: +def init_db(db_url: str) -> None: """ Initializes this module with the given config, registers all known command handlers and starts polling for message updates :param db_url: Database to use - :param clean_open_orders: Remove open orders from the database. - Useful for dry-run or if all orders have been reset on the exchange. :return: None """ kwargs = {} @@ -64,10 +62,6 @@ def init_db(db_url: str, clean_open_orders: bool = False) -> None: _DECL_BASE.metadata.create_all(engine) check_migrate(engine, decl_base=_DECL_BASE, previous_tables=previous_tables) - # Clean dry_run DB if the db is not in-memory - if clean_open_orders and db_url != 'sqlite://': - clean_dry_run_db() - def cleanup_db() -> None: """ @@ -75,15 +69,3 @@ def cleanup_db() -> None: :return: None """ Trade.commit() - - -def clean_dry_run_db() -> None: - """ - Remove open_order_id from a Dry_run DB - :return: None - """ - for trade in Trade.query.filter(Trade.open_order_id.isnot(None)).all(): - # Check we are updating only a dry_run order not a prod one - if 'dry_run' in trade.open_order_id: - trade.open_order_id = None - Trade.commit() diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index 358e776e3..324002685 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -8,7 +8,7 @@ from typing import Any, Dict, List, Optional from sqlalchemy import (Boolean, Column, DateTime, Enum, Float, ForeignKey, Integer, String, UniqueConstraint, desc, func) -from sqlalchemy.orm import Query, relationship +from sqlalchemy.orm import Query, lazyload, relationship from freqtrade.constants import DATETIME_PRINT_FORMAT, NON_OPEN_EXCHANGE_STATES, BuySell, LongShort from freqtrade.enums import ExitType, TradingMode @@ -57,6 +57,7 @@ class Order(_DECL_BASE): filled = Column(Float, nullable=True) remaining = Column(Float, nullable=True) cost = Column(Float, nullable=True) + stop_price = Column(Float, nullable=True) order_date = Column(DateTime, nullable=True, default=datetime.utcnow) order_filled_date = Column(DateTime, nullable=True) order_update_date = Column(DateTime, nullable=True) @@ -74,7 +75,7 @@ class Order(_DECL_BASE): @property def safe_filled(self) -> float: - return self.filled or self.amount or 0.0 + return self.filled if self.filled is not None else self.amount or 0.0 @property def safe_fee_base(self) -> float: @@ -107,6 +108,7 @@ class Order(_DECL_BASE): self.average = order.get('average', self.average) self.remaining = order.get('remaining', self.remaining) self.cost = order.get('cost', self.cost) + self.stop_price = order.get('stopPrice', self.stop_price) if 'timestamp' in order and order['timestamp'] is not None: self.order_date = datetime.fromtimestamp(order['timestamp'] / 1000, tz=timezone.utc) @@ -118,35 +120,60 @@ class Order(_DECL_BASE): self.order_filled_date = datetime.now(timezone.utc) self.order_update_date = datetime.now(timezone.utc) - def to_json(self, entry_side: str) -> Dict[str, Any]: + def to_ccxt_object(self) -> Dict[str, Any]: return { - 'pair': self.ft_pair, - 'order_id': self.order_id, - 'status': self.status, + 'id': self.order_id, + 'symbol': self.ft_pair, + 'price': self.price, + 'average': self.average, 'amount': self.amount, - 'average': round(self.average, 8) if self.average else 0, - 'safe_price': self.safe_price, - 'cost': self.cost if self.cost else 0, + 'cost': self.cost, + 'type': self.order_type, + 'side': self.ft_order_side, 'filled': self.filled, + 'remaining': self.remaining, + 'stopPrice': self.stop_price, + 'datetime': self.order_date_utc.strftime('%Y-%m-%dT%H:%M:%S.%f'), + 'timestamp': int(self.order_date_utc.timestamp() * 1000), + 'status': self.status, + 'fee': None, + 'info': {}, + } + + def to_json(self, entry_side: str, minified: bool = False) -> Dict[str, Any]: + resp = { + 'amount': self.amount, + 'safe_price': self.safe_price, 'ft_order_side': self.ft_order_side, - 'is_open': self.ft_is_open, - 'order_date': self.order_date.strftime(DATETIME_PRINT_FORMAT) - if self.order_date else None, - 'order_timestamp': int(self.order_date.replace( - tzinfo=timezone.utc).timestamp() * 1000) if self.order_date else None, - 'order_filled_date': self.order_filled_date.strftime(DATETIME_PRINT_FORMAT) - if self.order_filled_date else None, 'order_filled_timestamp': int(self.order_filled_date.replace( tzinfo=timezone.utc).timestamp() * 1000) if self.order_filled_date else None, - 'order_type': self.order_type, - 'price': self.price, 'ft_is_entry': self.ft_order_side == entry_side, - 'remaining': self.remaining, } + if not minified: + resp.update({ + 'pair': self.ft_pair, + 'order_id': self.order_id, + 'status': self.status, + 'average': round(self.average, 8) if self.average else 0, + 'cost': self.cost if self.cost else 0, + 'filled': self.filled, + 'is_open': self.ft_is_open, + 'order_date': self.order_date.strftime(DATETIME_PRINT_FORMAT) + if self.order_date else None, + 'order_timestamp': int(self.order_date.replace( + tzinfo=timezone.utc).timestamp() * 1000) if self.order_date else None, + 'order_filled_date': self.order_filled_date.strftime(DATETIME_PRINT_FORMAT) + if self.order_filled_date else None, + 'order_type': self.order_type, + 'price': self.price, + 'remaining': self.remaining, + }) + return resp def close_bt_order(self, close_date: datetime, trade: 'LocalTrade'): self.order_filled_date = close_date self.filled = self.amount + self.remaining = 0 self.status = 'closed' self.ft_is_open = False if (self.ft_order_side == trade.entry_side @@ -190,6 +217,14 @@ class Order(_DECL_BASE): """ return Order.query.filter(Order.ft_is_open.is_(True)).all() + @staticmethod + def order_by_id(order_id: str) -> Optional['Order']: + """ + Retrieve order based on order_id + :return: Order or None + """ + return Order.query.filter(Order.order_id == order_id).first() + class LocalTrade(): """ @@ -366,9 +401,9 @@ class LocalTrade(): f'open_rate={self.open_rate:.8f}, open_since={open_since})' ) - def to_json(self) -> Dict[str, Any]: - filled_orders = self.select_filled_orders() - orders = [order.to_json(self.entry_side) for order in filled_orders] + def to_json(self, minified: bool = False) -> Dict[str, Any]: + filled_orders = self.select_filled_or_open_orders() + orders = [order.to_json(self.entry_side, minified) for order in filled_orders] return { 'trade_id': self.id, @@ -592,8 +627,8 @@ class LocalTrade(): """ self.close_rate = rate self.close_date = self.close_date or datetime.utcnow() - self.close_profit = self.calc_profit_ratio() - self.close_profit_abs = self.calc_profit() + self.close_profit = self.calc_profit_ratio(rate) + self.close_profit_abs = self.calc_profit(rate) self.is_open = False self.exit_order_status = 'closed' self.open_order_id = None @@ -661,10 +696,9 @@ class LocalTrade(): """ self.open_trade_value = self._calc_open_trade_value() - def calculate_interest(self, interest_rate: Optional[float] = None) -> Decimal: + def calculate_interest(self) -> Decimal: """ - :param interest_rate: interest_charge for borrowing this coin(optional). - If interest_rate is not set self.interest_rate will be used + Calculate interest for this trade. Only applicable for Margin trading. """ zero = Decimal(0.0) # If nothing was borrowed @@ -677,34 +711,26 @@ class LocalTrade(): total_seconds = Decimal((now - open_date).total_seconds()) hours = total_seconds / sec_per_hour or zero - rate = Decimal(interest_rate or self.interest_rate) + rate = Decimal(self.interest_rate) borrowed = Decimal(self.borrowed) return interest(exchange_name=self.exchange, borrowed=borrowed, rate=rate, hours=hours) - def _calc_base_close(self, amount: Decimal, rate: Optional[float] = None, - fee: Optional[float] = None) -> Decimal: + def _calc_base_close(self, amount: Decimal, rate: float, fee: float) -> Decimal: - close_trade = Decimal(amount) * Decimal(rate or self.close_rate) # type: ignore - fees = close_trade * Decimal(fee or self.fee_close) + close_trade = amount * Decimal(rate) + fees = close_trade * Decimal(fee) if self.is_short: return close_trade + fees else: return close_trade - fees - def calc_close_trade_value(self, rate: Optional[float] = None, - fee: Optional[float] = None, - interest_rate: Optional[float] = None) -> float: + def calc_close_trade_value(self, rate: float) -> float: """ - Calculate the close_rate including fee - :param fee: fee to use on the close rate (optional). - If rate is not set self.fee will be used - :param rate: rate to compare with (optional). - If rate is not set self.close_rate will be used - :param interest_rate: interest_charge for borrowing this coin (optional). - If interest_rate is not set self.interest_rate will be used - :return: Price in BTC of the open trade + Calculate the Trade's close value including fees + :param rate: rate to compare with. + :return: value in stake currency of the open trade """ if rate is None and not self.close_rate: return 0.0 @@ -713,49 +739,38 @@ class LocalTrade(): trading_mode = self.trading_mode or TradingMode.SPOT if trading_mode == TradingMode.SPOT: - return float(self._calc_base_close(amount, rate, fee)) + return float(self._calc_base_close(amount, rate, self.fee_close)) elif (trading_mode == TradingMode.MARGIN): - total_interest = self.calculate_interest(interest_rate) + total_interest = self.calculate_interest() if self.is_short: amount = amount + total_interest - return float(self._calc_base_close(amount, rate, fee)) + return float(self._calc_base_close(amount, rate, self.fee_close)) else: # Currency already owned for longs, no need to purchase - return float(self._calc_base_close(amount, rate, fee) - total_interest) + return float(self._calc_base_close(amount, rate, self.fee_close) - total_interest) elif (trading_mode == TradingMode.FUTURES): funding_fees = self.funding_fees or 0.0 # Positive funding_fees -> Trade has gained from fees. # Negative funding_fees -> Trade had to pay the fees. if self.is_short: - return float(self._calc_base_close(amount, rate, fee)) - funding_fees + return float(self._calc_base_close(amount, rate, self.fee_close)) - funding_fees else: - return float(self._calc_base_close(amount, rate, fee)) + funding_fees + return float(self._calc_base_close(amount, rate, self.fee_close)) + funding_fees else: raise OperationalException( f"{self.trading_mode.value} trading is not yet available using freqtrade") - def calc_profit(self, rate: Optional[float] = None, - fee: Optional[float] = None, - interest_rate: Optional[float] = None) -> float: + def calc_profit(self, rate: float) -> float: """ Calculate the absolute profit in stake currency between Close and Open trade - :param fee: fee to use on the close rate (optional). - If fee is not set self.fee will be used - :param rate: close rate to compare with (optional). - If rate is not set self.close_rate will be used - :param interest_rate: interest_charge for borrowing this coin (optional). - If interest_rate is not set self.interest_rate will be used - :return: profit in stake currency as float + :param rate: close rate to compare with. + :return: profit in stake currency as float """ - close_trade_value = self.calc_close_trade_value( - rate=(rate or self.close_rate), - fee=(fee or self.fee_close), - interest_rate=(interest_rate or self.interest_rate) - ) + close_trade_value = self.calc_close_trade_value(rate) if self.is_short: profit = self.open_trade_value - close_trade_value @@ -763,23 +778,13 @@ class LocalTrade(): profit = close_trade_value - self.open_trade_value return float(f"{profit:.8f}") - def calc_profit_ratio(self, rate: Optional[float] = None, - fee: Optional[float] = None, - interest_rate: Optional[float] = None) -> float: + def calc_profit_ratio(self, rate: float) -> float: """ Calculates the profit as ratio (including fee). - :param rate: rate to compare with (optional). - If rate is not set self.close_rate will be used - :param fee: fee to use on the close rate (optional). - :param interest_rate: interest_charge for borrowing this coin (optional). - If interest_rate is not set self.interest_rate will be used + :param rate: rate to compare with. :return: profit ratio as float """ - close_trade_value = self.calc_close_trade_value( - rate=(rate or self.close_rate), - fee=(fee or self.fee_close), - interest_rate=(interest_rate or self.interest_rate) - ) + close_trade_value = self.calc_close_trade_value(rate) short_close_zero = (self.is_short and close_trade_value == 0.0) long_close_zero = (not self.is_short and self.open_trade_value == 0.0) @@ -796,14 +801,6 @@ class LocalTrade(): return float(f"{profit_ratio:.8f}") def recalc_trade_from_orders(self): - # We need at least 2 entry orders for averaging amounts and rates. - # TODO: this condition could probably be removed - if len(self.select_filled_orders(self.entry_side)) < 2: - self.stake_amount = self.amount * self.open_rate / self.leverage - - # Just in case, still recalc open trade value - self.recalc_open_trade_value() - return total_amount = 0.0 total_stake = 0.0 @@ -815,8 +812,6 @@ class LocalTrade(): tmp_amount = o.safe_amount_after_fee tmp_price = o.average or o.price - if o.filled is not None: - tmp_amount = o.filled if tmp_amount > 0.0 and tmp_price is not None: total_amount += tmp_amount total_stake += tmp_price * tmp_amount @@ -841,8 +836,8 @@ class LocalTrade(): return o return None - def select_order( - self, order_side: str = None, is_open: Optional[bool] = None) -> Optional[Order]: + def select_order(self, order_side: Optional[str] = None, + is_open: Optional[bool] = None) -> Optional[Order]: """ Finds latest order for this orderside and status :param order_side: ft_order_side of the order (either 'buy', 'sell' or 'stoploss') @@ -870,6 +865,21 @@ class LocalTrade(): (o.filled or 0) > 0 and o.status in NON_OPEN_EXCHANGE_STATES] + def select_filled_or_open_orders(self) -> List['Order']: + """ + Finds filled or open orders + :param order_side: Side of the order (either 'buy', 'sell', or None) + :return: array of Order objects + """ + return [o for o in self.orders if + ( + o.ft_is_open is False + and (o.filled or 0) > 0 + and o.status in NON_OPEN_EXCHANGE_STATES + ) + or (o.ft_is_open is True and o.status is not None) + ] + @property def nr_of_successful_entries(self) -> int: """ @@ -1108,7 +1118,7 @@ class Trade(_DECL_BASE, LocalTrade): ) @staticmethod - def get_trades(trade_filter=None) -> Query: + def get_trades(trade_filter=None, include_orders: bool = True) -> Query: """ Helper function to query Trades using filters. NOTE: Not supported in Backtesting. @@ -1123,9 +1133,14 @@ class Trade(_DECL_BASE, LocalTrade): if trade_filter is not None: if not isinstance(trade_filter, list): trade_filter = [trade_filter] - return Trade.query.filter(*trade_filter) + this_query = Trade.query.filter(*trade_filter) else: - return Trade.query + this_query = Trade.query + if not include_orders: + # Don't load order relations + # Consider using noload or raiseload instead of lazyload + this_query = this_query.options(lazyload(Trade.orders)) + return this_query @staticmethod def get_open_order_trades() -> List['Trade']: @@ -1345,3 +1360,18 @@ class Trade(_DECL_BASE, LocalTrade): .group_by(Trade.pair) \ .order_by(desc('profit_sum')).first() return best_pair + + @staticmethod + def get_trading_volume(start_date: datetime = datetime.fromtimestamp(0)) -> float: + """ + Get Trade volume based on Orders + NOTE: Not supported in Backtesting. + :returns: Tuple containing (pair, profit_sum) + """ + trading_volume = Order.query.with_entities( + func.sum(Order.cost).label('volume') + ).filter( + Order.order_filled_date >= start_date, + Order.status == 'closed' + ).scalar() + return trading_volume diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index ce8f54cbd..a64281156 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -633,7 +633,7 @@ def load_and_plot_trades(config: Dict[str, Any]): exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config) IStrategy.dp = DataProvider(config, exchange) - strategy.bot_start() + strategy.ft_bot_start() strategy.bot_loop_start() plot_elements = init_plotscript(config, list(exchange.markets), strategy.startup_candle_count) timerange = plot_elements['timerange'] diff --git a/freqtrade/plugins/pairlist/SpreadFilter.py b/freqtrade/plugins/pairlist/SpreadFilter.py index d1f88d2a5..43856b451 100644 --- a/freqtrade/plugins/pairlist/SpreadFilter.py +++ b/freqtrade/plugins/pairlist/SpreadFilter.py @@ -50,7 +50,7 @@ class SpreadFilter(IPairList): :param ticker: ticker dict as returned from ccxt.fetch_tickers() :return: True if the pair can stay, false if it should be removed """ - if 'bid' in ticker and 'ask' in ticker and ticker['ask']: + if 'bid' in ticker and 'ask' in ticker and ticker['ask'] and ticker['bid']: spread = 1 - ticker['bid'] / ticker['ask'] if spread > self._max_spread_ratio: self.log_once(f"Removed {pair} from whitelist, because spread " diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index 44d590b67..8b01980ce 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -47,26 +47,7 @@ class StrategyResolver(IResolver): strategy: IStrategy = StrategyResolver._load_strategy( strategy_name, config=config, extra_dir=config.get('strategy_path')) - - if strategy._ft_params_from_file: - # Set parameters from Hyperopt results file - params = strategy._ft_params_from_file - strategy.minimal_roi = params.get('roi', getattr(strategy, 'minimal_roi', {})) - - strategy.stoploss = params.get('stoploss', {}).get( - 'stoploss', getattr(strategy, 'stoploss', -0.1)) - trailing = params.get('trailing', {}) - strategy.trailing_stop = trailing.get( - 'trailing_stop', getattr(strategy, 'trailing_stop', False)) - strategy.trailing_stop_positive = trailing.get( - 'trailing_stop_positive', getattr(strategy, 'trailing_stop_positive', None)) - strategy.trailing_stop_positive_offset = trailing.get( - 'trailing_stop_positive_offset', - getattr(strategy, 'trailing_stop_positive_offset', 0)) - strategy.trailing_only_offset_is_reached = trailing.get( - 'trailing_only_offset_is_reached', - getattr(strategy, 'trailing_only_offset_is_reached', 0.0)) - + strategy.ft_load_params_from_file() # Set attributes # Check if we need to override configuration # (Attribute name, default, subkey) diff --git a/freqtrade/rpc/api_server/api_backtest.py b/freqtrade/rpc/api_server/api_backtest.py index 26b100408..06f04729b 100644 --- a/freqtrade/rpc/api_server/api_backtest.py +++ b/freqtrade/rpc/api_server/api_backtest.py @@ -1,6 +1,7 @@ import asyncio import logging from copy import deepcopy +from datetime import datetime from typing import Any, Dict, List from fastapi import APIRouter, BackgroundTasks, Depends @@ -102,7 +103,10 @@ async def api_start_backtest(bt_settings: BacktestRequest, background_tasks: Bac min_date=min_date, max_date=max_date) if btconfig.get('export', 'none') == 'trades': - store_backtest_stats(btconfig['exportfilename'], ApiServer._bt.results) + store_backtest_stats( + btconfig['exportfilename'], ApiServer._bt.results, + datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + ) logger.info("Backtest finished.") diff --git a/freqtrade/rpc/api_server/api_schemas.py b/freqtrade/rpc/api_server/api_schemas.py index d78ea8b78..333f2fe6e 100644 --- a/freqtrade/rpc/api_server/api_schemas.py +++ b/freqtrade/rpc/api_server/api_schemas.py @@ -104,6 +104,10 @@ class Profit(BaseModel): best_pair_profit_ratio: float winning_trades: int losing_trades: int + profit_factor: float + max_drawdown: float + max_drawdown_abs: float + trading_volume: Optional[float] class SellReason(BaseModel): @@ -120,6 +124,8 @@ class Stats(BaseModel): class DailyRecord(BaseModel): date: date abs_profit: float + rel_profit: float + starting_balance: float fiat_value: float trade_count: int @@ -166,7 +172,7 @@ class ShowConfig(BaseModel): trailing_stop_positive: Optional[float] trailing_stop_positive_offset: Optional[float] trailing_only_offset_is_reached: Optional[bool] - unfilledtimeout: UnfilledTimeout + unfilledtimeout: Optional[UnfilledTimeout] # Empty in webserver mode order_types: Optional[OrderTypes] use_custom_stoploss: Optional[bool] timeframe: Optional[str] @@ -256,6 +262,7 @@ class TradeSchema(BaseModel): leverage: Optional[float] interest_rate: Optional[float] + liquidation_price: Optional[float] funding_fees: Optional[float] trading_mode: Optional[TradingMode] @@ -276,6 +283,7 @@ class OpenTradeSchema(TradeSchema): class TradeResponse(BaseModel): trades: List[TradeSchema] trades_count: int + offset: int total_trades: int diff --git a/freqtrade/rpc/api_server/api_v1.py b/freqtrade/rpc/api_server/api_v1.py index c8299a153..b3506409d 100644 --- a/freqtrade/rpc/api_server/api_v1.py +++ b/freqtrade/rpc/api_server/api_v1.py @@ -36,7 +36,8 @@ logger = logging.getLogger(__name__) # versions 2.xx -> futures/short branch # 2.14: Add entry/exit orders to trade response # 2.15: Add backtest history endpoints -API_VERSION = 2.15 +# 2.16: Additional daily metrics +API_VERSION = 2.16 # Public API, requires no auth. router_public = APIRouter() @@ -86,8 +87,8 @@ def stats(rpc: RPC = Depends(get_rpc)): @router.get('/daily', response_model=Daily, tags=['info']) def daily(timescale: int = 7, rpc: RPC = Depends(get_rpc), config=Depends(get_config)): - return rpc._rpc_daily_profit(timescale, config['stake_currency'], - config.get('fiat_display_currency', '')) + return rpc._rpc_timeunit_profit(timescale, config['stake_currency'], + config.get('fiat_display_currency', '')) @router.get('/status', response_model=List[OpenTradeSchema], tags=['info']) diff --git a/freqtrade/rpc/discord.py b/freqtrade/rpc/discord.py new file mode 100644 index 000000000..5991f7126 --- /dev/null +++ b/freqtrade/rpc/discord.py @@ -0,0 +1,59 @@ +import logging +from typing import Any, Dict + +from freqtrade.enums.rpcmessagetype import RPCMessageType +from freqtrade.rpc import RPC +from freqtrade.rpc.webhook import Webhook + + +logger = logging.getLogger(__name__) + + +class Discord(Webhook): + def __init__(self, rpc: 'RPC', config: Dict[str, Any]): + # super().__init__(rpc, config) + self.rpc = rpc + self.config = config + self.strategy = config.get('strategy', '') + self.timeframe = config.get('timeframe', '') + + self._url = self.config['discord']['webhook_url'] + self._format = 'json' + self._retries = 1 + self._retry_delay = 0.1 + + def cleanup(self) -> None: + """ + Cleanup pending module resources. + This will do nothing for webhooks, they will simply not be called anymore + """ + pass + + def send_msg(self, msg) -> None: + logger.info(f"Sending discord message: {msg}") + + if msg['type'].value in self.config['discord']: + + msg['strategy'] = self.strategy + msg['timeframe'] = self.timeframe + fields = self.config['discord'].get(msg['type'].value) + color = 0x0000FF + if msg['type'] in (RPCMessageType.EXIT, RPCMessageType.EXIT_FILL): + profit_ratio = msg.get('profit_ratio') + color = (0x00FF00 if profit_ratio > 0 else 0xFF0000) + + embeds = [{ + 'title': f"Trade: {msg['pair']} {msg['type'].value}", + 'color': color, + 'fields': [], + + }] + for f in fields: + for k, v in f.items(): + v = v.format(**msg) + embeds[0]['fields'].append( # type: ignore + {'name': k, 'value': v, 'inline': True}) + + # Send the message to discord channel + payload = {'embeds': embeds} + self._send_msg(payload) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 4c03b8bd4..e6948c9e2 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -18,6 +18,7 @@ from freqtrade import __version__ from freqtrade.configuration.timerange import TimeRange from freqtrade.constants import CANCEL_REASON, DATETIME_PRINT_FORMAT from freqtrade.data.history import load_data +from freqtrade.data.metrics import calculate_max_drawdown from freqtrade.enums import (CandleType, ExitCheckTuple, ExitType, SignalDirection, State, TradingMode) from freqtrade.exceptions import ExchangeError, PricingError @@ -283,33 +284,57 @@ class RPC: columns.append('# Entries') return trades_list, columns, fiat_profit_sum - def _rpc_daily_profit( + def _rpc_timeunit_profit( self, timescale: int, - stake_currency: str, fiat_display_currency: str) -> Dict[str, Any]: - today = datetime.now(timezone.utc).date() - profit_days: Dict[date, Dict] = {} + stake_currency: str, fiat_display_currency: str, + timeunit: str = 'days') -> Dict[str, Any]: + """ + :param timeunit: Valid entries are 'days', 'weeks', 'months' + """ + start_date = datetime.now(timezone.utc).date() + if timeunit == 'weeks': + # weekly + start_date = start_date - timedelta(days=start_date.weekday()) # Monday + if timeunit == 'months': + start_date = start_date.replace(day=1) + + def time_offset(step: int): + if timeunit == 'months': + return relativedelta(months=step) + return timedelta(**{timeunit: step}) if not (isinstance(timescale, int) and timescale > 0): raise RPCException('timescale must be an integer greater than 0') + profit_units: Dict[date, Dict] = {} + daily_stake = self._freqtrade.wallets.get_total_stake_amount() + for day in range(0, timescale): - profitday = today - timedelta(days=day) - trades = Trade.get_trades(trade_filter=[ + profitday = start_date - time_offset(day) + # Only query for necessary columns for performance reasons. + trades = Trade.query.session.query(Trade.close_profit_abs).filter( Trade.is_open.is_(False), Trade.close_date >= profitday, - Trade.close_date < (profitday + timedelta(days=1)) - ]).order_by(Trade.close_date).all() + Trade.close_date < (profitday + time_offset(1)) + ).order_by(Trade.close_date).all() + curdayprofit = sum( trade.close_profit_abs for trade in trades if trade.close_profit_abs is not None) - profit_days[profitday] = { + # Calculate this periods starting balance + daily_stake = daily_stake - curdayprofit + profit_units[profitday] = { 'amount': curdayprofit, - 'trades': len(trades) + 'daily_stake': daily_stake, + 'rel_profit': round(curdayprofit / daily_stake, 8) if daily_stake > 0 else 0, + 'trades': len(trades), } data = [ { - 'date': key, + 'date': f"{key.year}-{key.month:02d}" if timeunit == 'months' else key, 'abs_profit': value["amount"], + 'starting_balance': value["daily_stake"], + 'rel_profit': value["rel_profit"], 'fiat_value': self._fiat_converter.convert_amount( value['amount'], stake_currency, @@ -317,92 +342,7 @@ class RPC: ) if self._fiat_converter else 0, 'trade_count': value["trades"], } - for key, value in profit_days.items() - ] - return { - 'stake_currency': stake_currency, - 'fiat_display_currency': fiat_display_currency, - 'data': data - } - - def _rpc_weekly_profit( - self, timescale: int, - stake_currency: str, fiat_display_currency: str) -> Dict[str, Any]: - today = datetime.now(timezone.utc).date() - first_iso_day_of_week = today - timedelta(days=today.weekday()) # Monday - profit_weeks: Dict[date, Dict] = {} - - if not (isinstance(timescale, int) and timescale > 0): - raise RPCException('timescale must be an integer greater than 0') - - for week in range(0, timescale): - profitweek = first_iso_day_of_week - timedelta(weeks=week) - trades = Trade.get_trades(trade_filter=[ - Trade.is_open.is_(False), - Trade.close_date >= profitweek, - Trade.close_date < (profitweek + timedelta(weeks=1)) - ]).order_by(Trade.close_date).all() - curweekprofit = sum( - trade.close_profit_abs for trade in trades if trade.close_profit_abs is not None) - profit_weeks[profitweek] = { - 'amount': curweekprofit, - 'trades': len(trades) - } - - data = [ - { - 'date': key, - 'abs_profit': value["amount"], - 'fiat_value': self._fiat_converter.convert_amount( - value['amount'], - stake_currency, - fiat_display_currency - ) if self._fiat_converter else 0, - 'trade_count': value["trades"], - } - for key, value in profit_weeks.items() - ] - return { - 'stake_currency': stake_currency, - 'fiat_display_currency': fiat_display_currency, - 'data': data - } - - def _rpc_monthly_profit( - self, timescale: int, - stake_currency: str, fiat_display_currency: str) -> Dict[str, Any]: - first_day_of_month = datetime.now(timezone.utc).date().replace(day=1) - profit_months: Dict[date, Dict] = {} - - if not (isinstance(timescale, int) and timescale > 0): - raise RPCException('timescale must be an integer greater than 0') - - for month in range(0, timescale): - profitmonth = first_day_of_month - relativedelta(months=month) - trades = Trade.get_trades(trade_filter=[ - Trade.is_open.is_(False), - Trade.close_date >= profitmonth, - Trade.close_date < (profitmonth + relativedelta(months=1)) - ]).order_by(Trade.close_date).all() - curmonthprofit = sum( - trade.close_profit_abs for trade in trades if trade.close_profit_abs is not None) - profit_months[profitmonth] = { - 'amount': curmonthprofit, - 'trades': len(trades) - } - - data = [ - { - 'date': f"{key.year}-{key.month:02d}", - 'abs_profit': value["amount"], - 'fiat_value': self._fiat_converter.convert_amount( - value['amount'], - stake_currency, - fiat_display_currency - ) if self._fiat_converter else 0, - 'trade_count': value["trades"], - } - for key, value in profit_months.items() + for key, value in profit_units.items() ] return { 'stake_currency': stake_currency, @@ -425,6 +365,7 @@ class RPC: return { "trades": output, "trades_count": len(output), + "offset": offset, "total_trades": Trade.get_trades([Trade.is_open.is_(False)]).count(), } @@ -439,7 +380,7 @@ class RPC: return 'losses' else: return 'draws' - trades: List[Trade] = Trade.get_trades([Trade.is_open.is_(False)]) + trades: List[Trade] = Trade.get_trades([Trade.is_open.is_(False)], include_orders=False) # Sell reason exit_reasons = {} for trade in trades: @@ -467,7 +408,8 @@ class RPC: """ Returns cumulative profit statistics """ trade_filter = ((Trade.is_open.is_(False) & (Trade.close_date >= start_date)) | Trade.is_open.is_(True)) - trades: List[Trade] = Trade.get_trades(trade_filter).order_by(Trade.id).all() + trades: List[Trade] = Trade.get_trades( + trade_filter, include_orders=False).order_by(Trade.id).all() profit_all_coin = [] profit_all_ratio = [] @@ -476,6 +418,8 @@ class RPC: durations = [] winning_trades = 0 losing_trades = 0 + winning_profit = 0.0 + losing_profit = 0.0 for trade in trades: current_rate: float = 0.0 @@ -491,8 +435,10 @@ class RPC: profit_closed_ratio.append(profit_ratio) if trade.close_profit >= 0: winning_trades += 1 + winning_profit += trade.close_profit_abs else: losing_trades += 1 + losing_profit += trade.close_profit_abs else: # Get current rate try: @@ -508,6 +454,7 @@ class RPC: profit_all_ratio.append(profit_ratio) best_pair = Trade.get_best_pair(start_date) + trading_volume = Trade.get_trading_volume(start_date) # Prepare data to display profit_closed_coin_sum = round(sum(profit_closed_coin), 8) @@ -531,6 +478,21 @@ class RPC: profit_closed_ratio_fromstart = profit_closed_coin_sum / starting_balance profit_all_ratio_fromstart = profit_all_coin_sum / starting_balance + profit_factor = winning_profit / abs(losing_profit) if losing_profit else float('inf') + + trades_df = DataFrame([{'close_date': trade.close_date.strftime(DATETIME_PRINT_FORMAT), + 'profit_abs': trade.close_profit_abs} + for trade in trades if not trade.is_open]) + max_drawdown_abs = 0.0 + max_drawdown = 0.0 + if len(trades_df) > 0: + try: + (max_drawdown_abs, _, _, _, _, max_drawdown) = calculate_max_drawdown( + trades_df, value_col='profit_abs', starting_balance=starting_balance) + except ValueError: + # ValueError if no losing trade. + pass + profit_all_fiat = self._fiat_converter.convert_amount( profit_all_coin_sum, stake_currency, @@ -569,11 +531,15 @@ class RPC: 'best_pair_profit_ratio': best_pair[1] if best_pair else 0, 'winning_trades': winning_trades, 'losing_trades': losing_trades, + 'profit_factor': profit_factor, + 'max_drawdown': max_drawdown, + 'max_drawdown_abs': max_drawdown_abs, + 'trading_volume': trading_volume, } def _rpc_balance(self, stake_currency: str, fiat_display_currency: str) -> Dict: """ Returns current account balance per crypto """ - currencies = [] + currencies: List[Dict] = [] total = 0.0 try: tickers = self._freqtrade.exchange.get_tickers(cached=True) @@ -608,13 +574,12 @@ class RPC: except (ExchangeError): logger.warning(f" Could not get rate for pair {coin}.") continue - total = total + (est_stake or 0) + total = total + est_stake currencies.append({ 'currency': coin, - # TODO: The below can be simplified if we don't assign None to values. - 'free': balance.free if balance.free is not None else 0, - 'balance': balance.total if balance.total is not None else 0, - 'used': balance.used if balance.used is not None else 0, + 'free': balance.free, + 'balance': balance.total, + 'used': balance.used, 'est_stake': est_stake or 0, 'stake': stake_currency, 'side': 'long', @@ -644,7 +609,6 @@ class RPC: total, stake_currency, fiat_display_currency) if self._fiat_converter else 0 trade_count = len(Trade.get_trades_proxy()) - starting_capital_ratio = 0.0 starting_capital_ratio = (total / starting_capital) - 1 if starting_capital else 0.0 starting_cap_fiat_ratio = (value / starting_cap_fiat) - 1 if starting_cap_fiat else 0.0 @@ -932,7 +896,7 @@ class RPC: else: errors[pair] = { 'error_msg': f"Pair {pair} is not in the current blacklist." - } + } resp = self._rpc_blacklist() resp['errors'] = errors return resp diff --git a/freqtrade/rpc/rpc_manager.py b/freqtrade/rpc/rpc_manager.py index d97d1df5f..66e84029f 100644 --- a/freqtrade/rpc/rpc_manager.py +++ b/freqtrade/rpc/rpc_manager.py @@ -27,6 +27,12 @@ class RPCManager: from freqtrade.rpc.telegram import Telegram self.registered_modules.append(Telegram(self._rpc, config)) + # Enable discord + if config.get('discord', {}).get('enabled', False): + logger.info('Enabling rpc.discord ...') + from freqtrade.rpc.discord import Discord + self.registered_modules.append(Discord(self._rpc, config)) + # Enable Webhook if config.get('webhook', {}).get('enabled', False): logger.info('Enabling rpc.webhook ...') diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 81fb206cc..8393ecc43 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -6,6 +6,7 @@ This module manage Telegram communication import json import logging import re +from dataclasses import dataclass from datetime import date, datetime, timedelta from functools import partial from html import escape @@ -37,6 +38,15 @@ logger.debug('Included module rpc.telegram ...') MAX_TELEGRAM_MESSAGE_LENGTH = 4096 +@dataclass +class TimeunitMappings: + header: str + message: str + message2: str + callback: str + default: int + + def authorized_only(command_handler: Callable[..., None]) -> Callable[..., Any]: """ Decorator to check if the message comes from the correct chat_id @@ -225,6 +235,14 @@ class Telegram(RPCHandler): # This can take up to `timeout` from the call to `start_polling`. self._updater.stop() + def _exchange_from_msg(self, msg: Dict[str, Any]) -> str: + """ + Extracts the exchange name from the given message. + :param msg: The message to extract the exchange name from. + :return: The exchange name. + """ + return f"{msg['exchange']}{' (dry)' if self._config['dry_run'] else ''}" + def _format_entry_msg(self, msg: Dict[str, Any]) -> str: if self._rpc._fiat_converter: msg['stake_amount_fiat'] = self._rpc._fiat_converter.convert_amount( @@ -237,7 +255,7 @@ class Telegram(RPCHandler): entry_side = ({'enter': 'Long', 'entered': 'Longed'} if msg['direction'] == 'Long' else {'enter': 'Short', 'entered': 'Shorted'}) message = ( - f"{emoji} *{msg['exchange']}:*" + f"{emoji} *{self._exchange_from_msg(msg)}:*" f" {entry_side['entered'] if is_fill else entry_side['enter']} {msg['pair']}" f" (#{msg['trade_id']})\n" ) @@ -286,7 +304,7 @@ class Telegram(RPCHandler): msg['profit_extra'] = '' is_fill = msg['type'] == RPCMessageType.EXIT_FILL message = ( - f"{msg['emoji']} *{msg['exchange']}:* " + f"{msg['emoji']} *{self._exchange_from_msg(msg)}:* " f"{'Exited' if is_fill else 'Exiting'} {msg['pair']} (#{msg['trade_id']})\n" f"*{'Profit' if is_fill else 'Unrealized Profit'}:* " f"`{msg['profit_ratio']:.2%}{msg['profit_extra']}`\n" @@ -316,33 +334,33 @@ class Telegram(RPCHandler): elif msg_type in (RPCMessageType.ENTRY_CANCEL, RPCMessageType.EXIT_CANCEL): msg['message_side'] = 'enter' if msg_type in [RPCMessageType.ENTRY_CANCEL] else 'exit' - message = ("\N{WARNING SIGN} *{exchange}:* " - "Cancelling {message_side} Order for {pair} (#{trade_id}). " - "Reason: {reason}.".format(**msg)) + message = (f"\N{WARNING SIGN} *{self._exchange_from_msg(msg)}:* " + f"Cancelling {msg['message_side']} Order for {msg['pair']} " + f"(#{msg['trade_id']}). Reason: {msg['reason']}.") elif msg_type == RPCMessageType.PROTECTION_TRIGGER: message = ( - "*Protection* triggered due to {reason}. " - "`{pair}` will be locked until `{lock_end_time}`." - ).format(**msg) + f"*Protection* triggered due to {msg['reason']}. " + f"`{msg['pair']}` will be locked until `{msg['lock_end_time']}`." + ) elif msg_type == RPCMessageType.PROTECTION_TRIGGER_GLOBAL: message = ( - "*Protection* triggered due to {reason}. " - "*All pairs* will be locked until `{lock_end_time}`." - ).format(**msg) + f"*Protection* triggered due to {msg['reason']}. " + f"*All pairs* will be locked until `{msg['lock_end_time']}`." + ) elif msg_type == RPCMessageType.STATUS: - message = '*Status:* `{status}`'.format(**msg) + message = f"*Status:* `{msg['status']}`" elif msg_type == RPCMessageType.WARNING: - message = '\N{WARNING SIGN} *Warning:* `{status}`'.format(**msg) + message = f"\N{WARNING SIGN} *Warning:* `{msg['status']}`" elif msg_type == RPCMessageType.STARTUP: - message = '{status}'.format(**msg) + message = f"{msg['status']}" else: - raise NotImplementedError('Unknown message type: {}'.format(msg_type)) + raise NotImplementedError(f"Unknown message type: {msg_type}") return message def send_msg(self, msg: Dict[str, Any]) -> None: @@ -396,7 +414,7 @@ class Telegram(RPCHandler): first_avg = filled_orders[0]["safe_price"] for x, order in enumerate(filled_orders): - if not order['ft_is_entry']: + if not order['ft_is_entry'] or order['is_open'] is True: continue cur_entry_datetime = arrow.get(order["order_filled_date"]) cur_entry_amount = order["amount"] @@ -563,6 +581,60 @@ class Telegram(RPCHandler): except RPCException as e: self._send_msg(str(e)) + @authorized_only + def _timeunit_stats(self, update: Update, context: CallbackContext, unit: str) -> None: + """ + Handler for /daily + Returns a daily profit (in BTC) over the last n days. + :param bot: telegram bot + :param update: message update + :return: None + """ + + vals = { + 'days': TimeunitMappings('Day', 'Daily', 'days', 'update_daily', 7), + 'weeks': TimeunitMappings('Monday', 'Weekly', 'weeks (starting from Monday)', + 'update_weekly', 8), + 'months': TimeunitMappings('Month', 'Monthly', 'months', 'update_monthly', 6), + } + val = vals[unit] + + stake_cur = self._config['stake_currency'] + fiat_disp_cur = self._config.get('fiat_display_currency', '') + try: + timescale = int(context.args[0]) if context.args else val.default + except (TypeError, ValueError, IndexError): + timescale = val.default + try: + stats = self._rpc._rpc_timeunit_profit( + timescale, + stake_cur, + fiat_disp_cur, + unit + ) + stats_tab = tabulate( + [[f"{period['date']} ({period['trade_count']})", + f"{round_coin_value(period['abs_profit'], stats['stake_currency'])}", + f"{period['fiat_value']:.2f} {stats['fiat_display_currency']}", + f"{period['rel_profit']:.2%}", + ] for period in stats['data']], + headers=[ + f"{val.header} (count)", + f'{stake_cur}', + f'{fiat_disp_cur}', + 'Profit %', + 'Trades', + ], + tablefmt='simple') + message = ( + f'{val.message} Profit over the last {timescale} {val.message2}:\n' + f'
{stats_tab}
' + ) + self._send_msg(message, parse_mode=ParseMode.HTML, reload_able=True, + callback_path=val.callback, query=update.callback_query) + except RPCException as e: + self._send_msg(str(e)) + @authorized_only def _daily(self, update: Update, context: CallbackContext) -> None: """ @@ -572,35 +644,7 @@ class Telegram(RPCHandler): :param update: message update :return: None """ - stake_cur = self._config['stake_currency'] - fiat_disp_cur = self._config.get('fiat_display_currency', '') - try: - timescale = int(context.args[0]) if context.args else 7 - except (TypeError, ValueError, IndexError): - timescale = 7 - try: - stats = self._rpc._rpc_daily_profit( - timescale, - stake_cur, - fiat_disp_cur - ) - stats_tab = tabulate( - [[day['date'], - f"{round_coin_value(day['abs_profit'], stats['stake_currency'])}", - f"{day['fiat_value']:.3f} {stats['fiat_display_currency']}", - f"{day['trade_count']} trades"] for day in stats['data']], - headers=[ - 'Day', - f'Profit {stake_cur}', - f'Profit {fiat_disp_cur}', - 'Trades', - ], - tablefmt='simple') - message = f'Daily Profit over the last {timescale} days:\n
{stats_tab}
' - self._send_msg(message, parse_mode=ParseMode.HTML, reload_able=True, - callback_path="update_daily", query=update.callback_query) - except RPCException as e: - self._send_msg(str(e)) + self._timeunit_stats(update, context, 'days') @authorized_only def _weekly(self, update: Update, context: CallbackContext) -> None: @@ -611,36 +655,7 @@ class Telegram(RPCHandler): :param update: message update :return: None """ - stake_cur = self._config['stake_currency'] - fiat_disp_cur = self._config.get('fiat_display_currency', '') - try: - timescale = int(context.args[0]) if context.args else 8 - except (TypeError, ValueError, IndexError): - timescale = 8 - try: - stats = self._rpc._rpc_weekly_profit( - timescale, - stake_cur, - fiat_disp_cur - ) - stats_tab = tabulate( - [[week['date'], - f"{round_coin_value(week['abs_profit'], stats['stake_currency'])}", - f"{week['fiat_value']:.3f} {stats['fiat_display_currency']}", - f"{week['trade_count']} trades"] for week in stats['data']], - headers=[ - 'Monday', - f'Profit {stake_cur}', - f'Profit {fiat_disp_cur}', - 'Trades', - ], - tablefmt='simple') - message = f'Weekly Profit over the last {timescale} weeks ' \ - f'(starting from Monday):\n
{stats_tab}
' - self._send_msg(message, parse_mode=ParseMode.HTML, reload_able=True, - callback_path="update_weekly", query=update.callback_query) - except RPCException as e: - self._send_msg(str(e)) + self._timeunit_stats(update, context, 'weeks') @authorized_only def _monthly(self, update: Update, context: CallbackContext) -> None: @@ -651,36 +666,7 @@ class Telegram(RPCHandler): :param update: message update :return: None """ - stake_cur = self._config['stake_currency'] - fiat_disp_cur = self._config.get('fiat_display_currency', '') - try: - timescale = int(context.args[0]) if context.args else 6 - except (TypeError, ValueError, IndexError): - timescale = 6 - try: - stats = self._rpc._rpc_monthly_profit( - timescale, - stake_cur, - fiat_disp_cur - ) - stats_tab = tabulate( - [[month['date'], - f"{round_coin_value(month['abs_profit'], stats['stake_currency'])}", - f"{month['fiat_value']:.3f} {stats['fiat_display_currency']}", - f"{month['trade_count']} trades"] for month in stats['data']], - headers=[ - 'Month', - f'Profit {stake_cur}', - f'Profit {fiat_disp_cur}', - 'Trades', - ], - tablefmt='simple') - message = f'Monthly Profit over the last {timescale} months' \ - f':\n
{stats_tab}
' - self._send_msg(message, parse_mode=ParseMode.HTML, reload_able=True, - callback_path="update_monthly", query=update.callback_query) - except RPCException as e: - self._send_msg(str(e)) + self._timeunit_stats(update, context, 'months') @authorized_only def _profit(self, update: Update, context: CallbackContext) -> None: @@ -744,12 +730,18 @@ class Telegram(RPCHandler): f"*Total Trade Count:* `{trade_count}`\n" f"*{'First Trade opened' if not timescale else 'Showing Profit since'}:* " f"`{first_trade_date}`\n" - f"*Latest Trade opened:* `{latest_trade_date}\n`" + f"*Latest Trade opened:* `{latest_trade_date}`\n" f"*Win / Loss:* `{stats['winning_trades']} / {stats['losing_trades']}`" ) if stats['closed_trade_count'] > 0: - markdown_msg += (f"\n*Avg. Duration:* `{avg_duration}`\n" - f"*Best Performing:* `{best_pair}: {best_pair_profit_ratio:.2%}`") + markdown_msg += ( + f"\n*Avg. Duration:* `{avg_duration}`\n" + f"*Best Performing:* `{best_pair}: {best_pair_profit_ratio:.2%}`\n" + f"*Trading volume:* `{round_coin_value(stats['trading_volume'], stake_cur)}`\n" + f"*Profit factor:* `{stats['profit_factor']:.2f}`\n" + f"*Max Drawdown:* `{stats['max_drawdown']:.2%} " + f"({round_coin_value(stats['max_drawdown_abs'], stake_cur)})`" + ) self._send_msg(markdown_msg, reload_able=True, callback_path="update_profit", query=update.callback_query) @@ -785,7 +777,7 @@ class Telegram(RPCHandler): headers=['Exit Reason', 'Exits', 'Wins', 'Losses'] ) if len(exit_reasons_tabulate) > 25: - self._send_msg(exit_reasons_msg, ParseMode.MARKDOWN) + self._send_msg(f"```\n{exit_reasons_msg}```", ParseMode.MARKDOWN) exit_reasons_msg = '' durations = stats['durations'] @@ -889,7 +881,7 @@ class Telegram(RPCHandler): :return: None """ msg = self._rpc._rpc_start() - self._send_msg('Status: `{status}`'.format(**msg)) + self._send_msg(f"Status: `{msg['status']}`") @authorized_only def _stop(self, update: Update, context: CallbackContext) -> None: @@ -901,7 +893,7 @@ class Telegram(RPCHandler): :return: None """ msg = self._rpc._rpc_stop() - self._send_msg('Status: `{status}`'.format(**msg)) + self._send_msg(f"Status: `{msg['status']}`") @authorized_only def _reload_config(self, update: Update, context: CallbackContext) -> None: @@ -913,7 +905,7 @@ class Telegram(RPCHandler): :return: None """ msg = self._rpc._rpc_reload_config() - self._send_msg('Status: `{status}`'.format(**msg)) + self._send_msg(f"Status: `{msg['status']}`") @authorized_only def _stopbuy(self, update: Update, context: CallbackContext) -> None: @@ -925,7 +917,7 @@ class Telegram(RPCHandler): :return: None """ msg = self._rpc._rpc_stopbuy() - self._send_msg('Status: `{status}`'.format(**msg)) + self._send_msg(f"Status: `{msg['status']}`") @authorized_only def _force_exit(self, update: Update, context: CallbackContext) -> None: @@ -1087,9 +1079,9 @@ class Telegram(RPCHandler): trade_id = int(context.args[0]) msg = self._rpc._rpc_delete(trade_id) self._send_msg(( - '`{result_msg}`\n' + f"`{msg['result_msg']}`\n" 'Please make sure to take care of this asset on the exchange manually.' - ).format(**msg)) + )) except RPCException as e: self._send_msg(str(e)) @@ -1417,7 +1409,7 @@ class Telegram(RPCHandler): "*/stopbuy:* `Stops buying, but handles open trades gracefully` \n" "*/forceexit |all:* `Instantly exits the given trade or all trades, " "regardless of profit`\n" - "*/fe |all:* `Alias to /forceexit`\n" + "*/fx |all:* `Alias to /forceexit`\n" f"{force_enter_text if self._config.get('force_entry_enable', False) else ''}" "*/delete :* `Instantly delete the given trade in the database`\n" "*/whitelist:* `Show current whitelist` \n" diff --git a/freqtrade/strategy/__init__.py b/freqtrade/strategy/__init__.py index 2ea0ad2b4..2d23bcd4d 100644 --- a/freqtrade/strategy/__init__.py +++ b/freqtrade/strategy/__init__.py @@ -1,9 +1,9 @@ # flake8: noqa: F401 from freqtrade.exchange import (timeframe_to_minutes, timeframe_to_msecs, timeframe_to_next_date, timeframe_to_prev_date, timeframe_to_seconds) -from freqtrade.strategy.hyper import (BooleanParameter, CategoricalParameter, DecimalParameter, - IntParameter, RealParameter) from freqtrade.strategy.informative_decorator import informative from freqtrade.strategy.interface import IStrategy +from freqtrade.strategy.parameters import (BooleanParameter, CategoricalParameter, DecimalParameter, + IntParameter, RealParameter) from freqtrade.strategy.strategy_helper import (merge_informative_pair, stoploss_from_absolute, stoploss_from_open) diff --git a/freqtrade/strategy/hyper.py b/freqtrade/strategy/hyper.py index 278954bb2..cdcfc969e 100644 --- a/freqtrade/strategy/hyper.py +++ b/freqtrade/strategy/hyper.py @@ -3,295 +3,18 @@ IHyperStrategy interface, hyperoptable Parameter class. This module defines a base class for auto-hyperoptable strategies. """ import logging -from abc import ABC, abstractmethod -from contextlib import suppress from pathlib import Path -from typing import Any, Dict, Iterator, List, Optional, Sequence, Tuple, Union +from typing import Any, Dict, Iterator, List, Tuple, Type, Union +from freqtrade.exceptions import OperationalException from freqtrade.misc import deep_merge_dicts, json_load from freqtrade.optimize.hyperopt_tools import HyperoptTools - - -with suppress(ImportError): - from skopt.space import Integer, Real, Categorical - from freqtrade.optimize.space import SKDecimal - -from freqtrade.enums import RunMode -from freqtrade.exceptions import OperationalException +from freqtrade.strategy.parameters import BaseParameter logger = logging.getLogger(__name__) -class BaseParameter(ABC): - """ - Defines a parameter that can be optimized by hyperopt. - """ - category: Optional[str] - default: Any - value: Any - in_space: bool = False - name: str - - def __init__(self, *, default: Any, space: Optional[str] = None, - optimize: bool = True, load: bool = True, **kwargs): - """ - Initialize hyperopt-optimizable parameter. - :param space: A parameter category. Can be 'buy' or 'sell'. This parameter is optional if - parameter field - name is prefixed with 'buy_' or 'sell_'. - :param optimize: Include parameter in hyperopt optimizations. - :param load: Load parameter value from {space}_params. - :param kwargs: Extra parameters to skopt.space.(Integer|Real|Categorical). - """ - if 'name' in kwargs: - raise OperationalException( - 'Name is determined by parameter field name and can not be specified manually.') - self.category = space - self._space_params = kwargs - self.value = default - self.optimize = optimize - self.load = load - - def __repr__(self): - return f'{self.__class__.__name__}({self.value})' - - @abstractmethod - def get_space(self, name: str) -> Union['Integer', 'Real', 'SKDecimal', 'Categorical']: - """ - Get-space - will be used by Hyperopt to get the hyperopt Space - """ - - -class NumericParameter(BaseParameter): - """ Internal parameter used for Numeric purposes """ - float_or_int = Union[int, float] - default: float_or_int - value: float_or_int - - def __init__(self, low: Union[float_or_int, Sequence[float_or_int]], - high: Optional[float_or_int] = None, *, default: float_or_int, - space: Optional[str] = None, optimize: bool = True, load: bool = True, **kwargs): - """ - Initialize hyperopt-optimizable numeric parameter. - Cannot be instantiated, but provides the validation for other numeric parameters - :param low: Lower end (inclusive) of optimization space or [low, high]. - :param high: Upper end (inclusive) of optimization space. - Must be none of entire range is passed first parameter. - :param default: A default value. - :param space: A parameter category. Can be 'buy' or 'sell'. This parameter is optional if - parameter fieldname is prefixed with 'buy_' or 'sell_'. - :param optimize: Include parameter in hyperopt optimizations. - :param load: Load parameter value from {space}_params. - :param kwargs: Extra parameters to skopt.space.*. - """ - if high is not None and isinstance(low, Sequence): - raise OperationalException(f'{self.__class__.__name__} space invalid.') - if high is None or isinstance(low, Sequence): - if not isinstance(low, Sequence) or len(low) != 2: - raise OperationalException(f'{self.__class__.__name__} space must be [low, high]') - self.low, self.high = low - else: - self.low = low - self.high = high - - super().__init__(default=default, space=space, optimize=optimize, - load=load, **kwargs) - - -class IntParameter(NumericParameter): - default: int - value: int - - def __init__(self, low: Union[int, Sequence[int]], high: Optional[int] = None, *, default: int, - space: Optional[str] = None, optimize: bool = True, load: bool = True, **kwargs): - """ - Initialize hyperopt-optimizable integer parameter. - :param low: Lower end (inclusive) of optimization space or [low, high]. - :param high: Upper end (inclusive) of optimization space. - Must be none of entire range is passed first parameter. - :param default: A default value. - :param space: A parameter category. Can be 'buy' or 'sell'. This parameter is optional if - parameter fieldname is prefixed with 'buy_' or 'sell_'. - :param optimize: Include parameter in hyperopt optimizations. - :param load: Load parameter value from {space}_params. - :param kwargs: Extra parameters to skopt.space.Integer. - """ - - super().__init__(low=low, high=high, default=default, space=space, optimize=optimize, - load=load, **kwargs) - - def get_space(self, name: str) -> 'Integer': - """ - Create skopt optimization space. - :param name: A name of parameter field. - """ - return Integer(low=self.low, high=self.high, name=name, **self._space_params) - - @property - def range(self): - """ - Get each value in this space as list. - Returns a List from low to high (inclusive) in Hyperopt mode. - Returns a List with 1 item (`value`) in "non-hyperopt" mode, to avoid - calculating 100ds of indicators. - """ - if self.in_space and self.optimize: - # Scikit-optimize ranges are "inclusive", while python's "range" is exclusive - return range(self.low, self.high + 1) - else: - return range(self.value, self.value + 1) - - -class RealParameter(NumericParameter): - default: float - value: float - - def __init__(self, low: Union[float, Sequence[float]], high: Optional[float] = None, *, - default: float, space: Optional[str] = None, optimize: bool = True, - load: bool = True, **kwargs): - """ - Initialize hyperopt-optimizable floating point parameter with unlimited precision. - :param low: Lower end (inclusive) of optimization space or [low, high]. - :param high: Upper end (inclusive) of optimization space. - Must be none if entire range is passed first parameter. - :param default: A default value. - :param space: A parameter category. Can be 'buy' or 'sell'. This parameter is optional if - parameter fieldname is prefixed with 'buy_' or 'sell_'. - :param optimize: Include parameter in hyperopt optimizations. - :param load: Load parameter value from {space}_params. - :param kwargs: Extra parameters to skopt.space.Real. - """ - super().__init__(low=low, high=high, default=default, space=space, optimize=optimize, - load=load, **kwargs) - - def get_space(self, name: str) -> 'Real': - """ - Create skopt optimization space. - :param name: A name of parameter field. - """ - return Real(low=self.low, high=self.high, name=name, **self._space_params) - - -class DecimalParameter(NumericParameter): - default: float - value: float - - def __init__(self, low: Union[float, Sequence[float]], high: Optional[float] = None, *, - default: float, decimals: int = 3, space: Optional[str] = None, - optimize: bool = True, load: bool = True, **kwargs): - """ - Initialize hyperopt-optimizable decimal parameter with a limited precision. - :param low: Lower end (inclusive) of optimization space or [low, high]. - :param high: Upper end (inclusive) of optimization space. - Must be none if entire range is passed first parameter. - :param default: A default value. - :param decimals: A number of decimals after floating point to be included in testing. - :param space: A parameter category. Can be 'buy' or 'sell'. This parameter is optional if - parameter fieldname is prefixed with 'buy_' or 'sell_'. - :param optimize: Include parameter in hyperopt optimizations. - :param load: Load parameter value from {space}_params. - :param kwargs: Extra parameters to skopt.space.Integer. - """ - self._decimals = decimals - default = round(default, self._decimals) - - super().__init__(low=low, high=high, default=default, space=space, optimize=optimize, - load=load, **kwargs) - - def get_space(self, name: str) -> 'SKDecimal': - """ - Create skopt optimization space. - :param name: A name of parameter field. - """ - return SKDecimal(low=self.low, high=self.high, decimals=self._decimals, name=name, - **self._space_params) - - @property - def range(self): - """ - Get each value in this space as list. - Returns a List from low to high (inclusive) in Hyperopt mode. - Returns a List with 1 item (`value`) in "non-hyperopt" mode, to avoid - calculating 100ds of indicators. - """ - if self.in_space and self.optimize: - low = int(self.low * pow(10, self._decimals)) - high = int(self.high * pow(10, self._decimals)) + 1 - return [round(n * pow(0.1, self._decimals), self._decimals) for n in range(low, high)] - else: - return [self.value] - - -class CategoricalParameter(BaseParameter): - default: Any - value: Any - opt_range: Sequence[Any] - - def __init__(self, categories: Sequence[Any], *, default: Optional[Any] = None, - space: Optional[str] = None, optimize: bool = True, load: bool = True, **kwargs): - """ - Initialize hyperopt-optimizable parameter. - :param categories: Optimization space, [a, b, ...]. - :param default: A default value. If not specified, first item from specified space will be - used. - :param space: A parameter category. Can be 'buy' or 'sell'. This parameter is optional if - parameter field - name is prefixed with 'buy_' or 'sell_'. - :param optimize: Include parameter in hyperopt optimizations. - :param load: Load parameter value from {space}_params. - :param kwargs: Extra parameters to skopt.space.Categorical. - """ - if len(categories) < 2: - raise OperationalException( - 'CategoricalParameter space must be [a, b, ...] (at least two parameters)') - self.opt_range = categories - super().__init__(default=default, space=space, optimize=optimize, - load=load, **kwargs) - - def get_space(self, name: str) -> 'Categorical': - """ - Create skopt optimization space. - :param name: A name of parameter field. - """ - return Categorical(self.opt_range, name=name, **self._space_params) - - @property - def range(self): - """ - Get each value in this space as list. - Returns a List of categories in Hyperopt mode. - Returns a List with 1 item (`value`) in "non-hyperopt" mode, to avoid - calculating 100ds of indicators. - """ - if self.in_space and self.optimize: - return self.opt_range - else: - return [self.value] - - -class BooleanParameter(CategoricalParameter): - - def __init__(self, *, default: Optional[Any] = None, - space: Optional[str] = None, optimize: bool = True, load: bool = True, **kwargs): - """ - Initialize hyperopt-optimizable Boolean Parameter. - It's a shortcut to `CategoricalParameter([True, False])`. - :param default: A default value. If not specified, first item from specified space will be - used. - :param space: A parameter category. Can be 'buy' or 'sell'. This parameter is optional if - parameter field - name is prefixed with 'buy_' or 'sell_'. - :param optimize: Include parameter in hyperopt optimizations. - :param load: Load parameter value from {space}_params. - :param kwargs: Extra parameters to skopt.space.Categorical. - """ - - categories = [True, False] - super().__init__(categories=categories, default=default, space=space, optimize=optimize, - load=load, **kwargs) - - class HyperStrategyMixin: """ A helper base class which allows HyperOptAuto class to reuse implementations of buy/sell @@ -307,7 +30,10 @@ class HyperStrategyMixin: self.ft_sell_params: List[BaseParameter] = [] self.ft_protection_params: List[BaseParameter] = [] - self._load_hyper_params(config.get('runmode') == RunMode.HYPEROPT) + params = self.load_params_from_file() + params = params.get('params', {}) + self._ft_params_from_file = params + # Init/loading of parameters is done as part of ft_bot_start(). def enumerate_parameters(self, category: str = None) -> Iterator[Tuple[str, BaseParameter]]: """ @@ -327,28 +53,13 @@ class HyperStrategyMixin: for par in params: yield par.name, par - @classmethod - def detect_parameters(cls, category: str) -> Iterator[Tuple[str, BaseParameter]]: - """ Detect all parameters for 'category' """ - for attr_name in dir(cls): - if not attr_name.startswith('__'): # Ignore internals, not strictly necessary. - attr = getattr(cls, attr_name) - if issubclass(attr.__class__, BaseParameter): - if (attr_name.startswith(category + '_') - and attr.category is not None and attr.category != category): - raise OperationalException( - f'Inconclusive parameter name {attr_name}, category: {attr.category}.') - if (category == attr.category or - (attr_name.startswith(category + '_') and attr.category is None)): - yield attr_name, attr - @classmethod def detect_all_parameters(cls) -> Dict: """ Detect all parameters and return them as a list""" - params: Dict = { - 'buy': list(cls.detect_parameters('buy')), - 'sell': list(cls.detect_parameters('sell')), - 'protection': list(cls.detect_parameters('protection')), + params: Dict[str, Any] = { + 'buy': list(detect_parameters(cls, 'buy')), + 'sell': list(detect_parameters(cls, 'sell')), + 'protection': list(detect_parameters(cls, 'protection')), } params.update({ 'count': len(params['buy'] + params['sell'] + params['protection']) @@ -356,21 +67,49 @@ class HyperStrategyMixin: return params - def _load_hyper_params(self, hyperopt: bool = False) -> None: + def ft_load_params_from_file(self) -> None: + """ + Load Parameters from parameter file + Should/must run before config values are loaded in strategy_resolver. + """ + if self._ft_params_from_file: + # Set parameters from Hyperopt results file + params = self._ft_params_from_file + self.minimal_roi = params.get('roi', getattr(self, 'minimal_roi', {})) + + self.stoploss = params.get('stoploss', {}).get( + 'stoploss', getattr(self, 'stoploss', -0.1)) + trailing = params.get('trailing', {}) + self.trailing_stop = trailing.get( + 'trailing_stop', getattr(self, 'trailing_stop', False)) + self.trailing_stop_positive = trailing.get( + 'trailing_stop_positive', getattr(self, 'trailing_stop_positive', None)) + self.trailing_stop_positive_offset = trailing.get( + 'trailing_stop_positive_offset', + getattr(self, 'trailing_stop_positive_offset', 0)) + self.trailing_only_offset_is_reached = trailing.get( + 'trailing_only_offset_is_reached', + getattr(self, 'trailing_only_offset_is_reached', 0.0)) + + def ft_load_hyper_params(self, hyperopt: bool = False) -> None: """ Load Hyperoptable parameters + Prevalence: + * Parameters from parameter file + * Parameters defined in parameters objects (buy_params, sell_params, ...) + * Parameter defaults """ - params = self.load_params_from_file() - params = params.get('params', {}) - self._ft_params_from_file = params - buy_params = deep_merge_dicts(params.get('buy', {}), getattr(self, 'buy_params', {})) - sell_params = deep_merge_dicts(params.get('sell', {}), getattr(self, 'sell_params', {})) - protection_params = deep_merge_dicts(params.get('protection', {}), + + buy_params = deep_merge_dicts(self._ft_params_from_file.get('buy', {}), + getattr(self, 'buy_params', {})) + sell_params = deep_merge_dicts(self._ft_params_from_file.get('sell', {}), + getattr(self, 'sell_params', {})) + protection_params = deep_merge_dicts(self._ft_params_from_file.get('protection', {}), getattr(self, 'protection_params', {})) - self._load_params(buy_params, 'buy', hyperopt) - self._load_params(sell_params, 'sell', hyperopt) - self._load_params(protection_params, 'protection', hyperopt) + self._ft_load_params(buy_params, 'buy', hyperopt) + self._ft_load_params(sell_params, 'sell', hyperopt) + self._ft_load_params(protection_params, 'protection', hyperopt) def load_params_from_file(self) -> Dict: filename_str = getattr(self, '__file__', '') @@ -393,7 +132,7 @@ class HyperStrategyMixin: return {} - def _load_params(self, params: Dict, space: str, hyperopt: bool = False) -> None: + def _ft_load_params(self, params: Dict, space: str, hyperopt: bool = False) -> None: """ Set optimizable parameter values. :param params: Dictionary with new parameter values. @@ -402,7 +141,7 @@ class HyperStrategyMixin: logger.info(f"No params for {space} found, using default values.") param_container: List[BaseParameter] = getattr(self, f"ft_{space}_params") - for attr_name, attr in self.detect_parameters(space): + for attr_name, attr in detect_parameters(self, space): attr.name = attr_name attr.in_space = hyperopt and HyperoptTools.has_space(self.config, space) if not attr.category: @@ -424,7 +163,7 @@ class HyperStrategyMixin: """ Returns list of Parameters that are not part of the current optimize job """ - params = { + params: Dict[str, Dict] = { 'buy': {}, 'sell': {}, 'protection': {}, @@ -433,3 +172,25 @@ class HyperStrategyMixin: if not p.optimize or not p.in_space: params[p.category][name] = p.value return params + + +def detect_parameters( + obj: Union[HyperStrategyMixin, Type[HyperStrategyMixin]], + category: str + ) -> Iterator[Tuple[str, BaseParameter]]: + """ + Detect all parameters for 'category' for "obj" + :param obj: Strategy object or class + :param category: category - usually `'buy', 'sell', 'protection',... + """ + for attr_name in dir(obj): + if not attr_name.startswith('__'): # Ignore internals, not strictly necessary. + attr = getattr(obj, attr_name) + if issubclass(attr.__class__, BaseParameter): + if (attr_name.startswith(category + '_') + and attr.category is not None and attr.category != category): + raise OperationalException( + f'Inconclusive parameter name {attr_name}, category: {attr.category}.') + if (category == attr.category or + (attr_name.startswith(category + '_') and attr.category is None)): + yield attr_name, attr diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 57afbf32a..d4ccfc5db 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -14,9 +14,10 @@ from freqtrade.constants import ListPairsWithTimeframes from freqtrade.data.dataprovider import DataProvider from freqtrade.enums import (CandleType, ExitCheckTuple, ExitType, SignalDirection, SignalTagType, SignalType, TradingMode) +from freqtrade.enums.runmode import RunMode from freqtrade.exceptions import OperationalException, StrategyError from freqtrade.exchange import timeframe_to_minutes, timeframe_to_next_date, timeframe_to_seconds -from freqtrade.persistence import LocalTrade, Order, PairLocks, Trade +from freqtrade.persistence import Order, PairLocks, Trade from freqtrade.strategy.hyper import HyperStrategyMixin from freqtrade.strategy.informative_decorator import (InformativeData, PopulateIndicators, _create_and_merge_informative_pair, @@ -82,7 +83,7 @@ class IStrategy(ABC, HyperStrategyMixin): } # run "populate_indicators" only for new candle - process_only_new_candles: bool = False + process_only_new_candles: bool = True use_exit_signal: bool exit_profit_only: bool @@ -144,6 +145,15 @@ class IStrategy(ABC, HyperStrategyMixin): informative_data.candle_type = config['candle_type_def'] self._ft_informative.append((informative_data, cls_method)) + def ft_bot_start(self, **kwargs) -> None: + """ + Strategy init - runs after dataprovider has been added. + Must call bot_start() + """ + strategy_safe_wrapper(self.bot_start)() + + self.ft_load_hyper_params(self.config.get('runmode') == RunMode.HYPEROPT) + @abstractmethod def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ @@ -277,8 +287,9 @@ class IStrategy(ABC, HyperStrategyMixin): :param pair: Pair that's about to be bought/shorted. :param order_type: Order type (as configured in order_types). usually limit or market. - :param amount: Amount in target (quote) currency that's going to be traded. + :param amount: Amount in target (base) currency that's going to be traded. :param rate: Rate that's going to be used when using limit orders + or current rate for market orders. :param time_in_force: Time in force. Defaults to GTC (Good-til-cancelled). :param current_time: datetime object, containing the current datetime :param entry_tag: Optional entry_tag (buy_tag) if provided with the buy signal. @@ -304,8 +315,9 @@ class IStrategy(ABC, HyperStrategyMixin): :param pair: Pair for trade that's about to be exited. :param trade: trade object. :param order_type: Order type (as configured in order_types). usually limit or market. - :param amount: Amount in quote currency. + :param amount: Amount in base currency. :param rate: Rate that's going to be used when using limit orders + or current rate for market orders. :param time_in_force: Time in force. Defaults to GTC (Good-til-cancelled). :param exit_reason: Exit reason. Can be any of ['roi', 'stop_loss', 'stoploss_on_exchange', 'trailing_stop_loss', @@ -429,7 +441,7 @@ class IStrategy(ABC, HyperStrategyMixin): return self.custom_sell(pair, trade, current_time, current_rate, current_profit, **kwargs) def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float, - proposed_stake: float, min_stake: float, max_stake: float, + proposed_stake: float, min_stake: Optional[float], max_stake: float, entry_tag: Optional[str], side: str, **kwargs) -> float: """ Customize stake size for each new trade. @@ -447,8 +459,9 @@ class IStrategy(ABC, HyperStrategyMixin): return proposed_stake def adjust_trade_position(self, trade: Trade, current_time: datetime, - current_rate: float, current_profit: float, min_stake: float, - max_stake: float, **kwargs) -> Optional[float]: + current_rate: float, current_profit: float, + min_stake: Optional[float], max_stake: float, + **kwargs) -> Optional[float]: """ Custom trade adjustment logic, returning the stake amount that a trade should be increased. This means extra buy orders with additional fees. @@ -498,8 +511,8 @@ class IStrategy(ABC, HyperStrategyMixin): return current_order_rate def leverage(self, pair: str, current_time: datetime, current_rate: float, - proposed_leverage: float, max_leverage: float, side: str, - **kwargs) -> float: + proposed_leverage: float, max_leverage: float, entry_tag: Optional[str], + side: str, **kwargs) -> float: """ Customize leverage for each new trade. This method is only called in futures mode. @@ -508,6 +521,7 @@ class IStrategy(ABC, HyperStrategyMixin): :param current_rate: Rate, calculated based on pricing settings in exit_pricing. :param proposed_leverage: A leverage proposed by the bot. :param max_leverage: Max leverage allowed on this pair + :param entry_tag: Optional entry_tag (buy_tag) if provided with the buy signal. :param side: 'long' or 'short' - indicating the direction of the proposed trade :return: A leverage amount, which is between 1.0 and max_leverage. """ @@ -878,16 +892,16 @@ class IStrategy(ABC, HyperStrategyMixin): def should_exit(self, trade: Trade, rate: float, current_time: datetime, *, enter: bool, exit_: bool, low: float = None, high: float = None, - force_stoploss: float = 0) -> ExitCheckTuple: + force_stoploss: float = 0) -> List[ExitCheckTuple]: """ This function evaluates if one of the conditions required to trigger an exit order has been reached, which can either be a stop-loss, ROI or exit-signal. :param low: Only used during backtesting to simulate (long)stoploss/(short)ROI :param high: Only used during backtesting, to simulate (short)stoploss/(long)ROI :param force_stoploss: Externally provided stoploss - :return: True if trade should be exited, False otherwise + :return: List of exit reasons - or empty list. """ - + exits: List[ExitCheckTuple] = [] current_rate = rate current_profit = trade.calc_profit_ratio(current_rate) @@ -917,19 +931,20 @@ class IStrategy(ABC, HyperStrategyMixin): if exit_ and not enter: exit_signal = ExitType.EXIT_SIGNAL else: - custom_reason = strategy_safe_wrapper(self.custom_exit, default_retval=False)( + reason_cust = strategy_safe_wrapper(self.custom_exit, default_retval=False)( pair=trade.pair, trade=trade, current_time=current_time, current_rate=current_rate, current_profit=current_profit) - if custom_reason: + if reason_cust: exit_signal = ExitType.CUSTOM_EXIT - if isinstance(custom_reason, str): - if len(custom_reason) > CUSTOM_EXIT_MAX_LENGTH: + if isinstance(reason_cust, str): + custom_reason = reason_cust + if len(reason_cust) > CUSTOM_EXIT_MAX_LENGTH: logger.warning(f'Custom exit reason returned from ' f'custom_exit is too long and was trimmed' f'to {CUSTOM_EXIT_MAX_LENGTH} characters.') - custom_reason = custom_reason[:CUSTOM_EXIT_MAX_LENGTH] + custom_reason = reason_cust[:CUSTOM_EXIT_MAX_LENGTH] else: - custom_reason = None + custom_reason = '' if ( exit_signal == ExitType.CUSTOM_EXIT or (exit_signal == ExitType.EXIT_SIGNAL @@ -938,24 +953,29 @@ class IStrategy(ABC, HyperStrategyMixin): logger.debug(f"{trade.pair} - Sell signal received. " f"exit_type=ExitType.{exit_signal.name}" + (f", custom_reason={custom_reason}" if custom_reason else "")) - return ExitCheckTuple(exit_type=exit_signal, exit_reason=custom_reason) + exits.append(ExitCheckTuple(exit_type=exit_signal, exit_reason=custom_reason)) # Sequence: # Exit-signal - # ROI (if not stoploss) # Stoploss - if roi_reached and stoplossflag.exit_type != ExitType.STOP_LOSS: - logger.debug(f"{trade.pair} - Required profit reached. exit_type=ExitType.ROI") - return ExitCheckTuple(exit_type=ExitType.ROI) + # ROI + # Trailing stoploss - if stoplossflag.exit_flag: + if stoplossflag.exit_type == ExitType.STOP_LOSS: logger.debug(f"{trade.pair} - Stoploss hit. exit_type={stoplossflag.exit_type}") - return stoplossflag + exits.append(stoplossflag) - # This one is noisy, commented out... - # logger.debug(f"{trade.pair} - No exit signal.") - return ExitCheckTuple(exit_type=ExitType.NONE) + if roi_reached: + logger.debug(f"{trade.pair} - Required profit reached. exit_type=ExitType.ROI") + exits.append(ExitCheckTuple(exit_type=ExitType.ROI)) + + if stoplossflag.exit_type == ExitType.TRAILING_STOP_LOSS: + + logger.debug(f"{trade.pair} - Trailing stoploss hit.") + exits.append(stoplossflag) + + return exits def stop_loss_reached(self, current_rate: float, trade: Trade, current_time: datetime, current_profit: float, @@ -1070,7 +1090,7 @@ class IStrategy(ABC, HyperStrategyMixin): else: return current_profit > roi - def ft_check_timed_out(self, trade: LocalTrade, order: Order, + def ft_check_timed_out(self, trade: Trade, order: Order, current_time: datetime) -> bool: """ FT Internal method. diff --git a/freqtrade/strategy/parameters.py b/freqtrade/strategy/parameters.py new file mode 100644 index 000000000..83dd41de9 --- /dev/null +++ b/freqtrade/strategy/parameters.py @@ -0,0 +1,289 @@ +""" +IHyperStrategy interface, hyperoptable Parameter class. +This module defines a base class for auto-hyperoptable strategies. +""" +import logging +from abc import ABC, abstractmethod +from contextlib import suppress +from typing import Any, Optional, Sequence, Union + + +with suppress(ImportError): + from skopt.space import Integer, Real, Categorical + from freqtrade.optimize.space import SKDecimal + +from freqtrade.exceptions import OperationalException + + +logger = logging.getLogger(__name__) + + +class BaseParameter(ABC): + """ + Defines a parameter that can be optimized by hyperopt. + """ + category: Optional[str] + default: Any + value: Any + in_space: bool = False + name: str + + def __init__(self, *, default: Any, space: Optional[str] = None, + optimize: bool = True, load: bool = True, **kwargs): + """ + Initialize hyperopt-optimizable parameter. + :param space: A parameter category. Can be 'buy' or 'sell'. This parameter is optional if + parameter field + name is prefixed with 'buy_' or 'sell_'. + :param optimize: Include parameter in hyperopt optimizations. + :param load: Load parameter value from {space}_params. + :param kwargs: Extra parameters to skopt.space.(Integer|Real|Categorical). + """ + if 'name' in kwargs: + raise OperationalException( + 'Name is determined by parameter field name and can not be specified manually.') + self.category = space + self._space_params = kwargs + self.value = default + self.optimize = optimize + self.load = load + + def __repr__(self): + return f'{self.__class__.__name__}({self.value})' + + @abstractmethod + def get_space(self, name: str) -> Union['Integer', 'Real', 'SKDecimal', 'Categorical']: + """ + Get-space - will be used by Hyperopt to get the hyperopt Space + """ + + +class NumericParameter(BaseParameter): + """ Internal parameter used for Numeric purposes """ + float_or_int = Union[int, float] + default: float_or_int + value: float_or_int + + def __init__(self, low: Union[float_or_int, Sequence[float_or_int]], + high: Optional[float_or_int] = None, *, default: float_or_int, + space: Optional[str] = None, optimize: bool = True, load: bool = True, **kwargs): + """ + Initialize hyperopt-optimizable numeric parameter. + Cannot be instantiated, but provides the validation for other numeric parameters + :param low: Lower end (inclusive) of optimization space or [low, high]. + :param high: Upper end (inclusive) of optimization space. + Must be none of entire range is passed first parameter. + :param default: A default value. + :param space: A parameter category. Can be 'buy' or 'sell'. This parameter is optional if + parameter fieldname is prefixed with 'buy_' or 'sell_'. + :param optimize: Include parameter in hyperopt optimizations. + :param load: Load parameter value from {space}_params. + :param kwargs: Extra parameters to skopt.space.*. + """ + if high is not None and isinstance(low, Sequence): + raise OperationalException(f'{self.__class__.__name__} space invalid.') + if high is None or isinstance(low, Sequence): + if not isinstance(low, Sequence) or len(low) != 2: + raise OperationalException(f'{self.__class__.__name__} space must be [low, high]') + self.low, self.high = low + else: + self.low = low + self.high = high + + super().__init__(default=default, space=space, optimize=optimize, + load=load, **kwargs) + + +class IntParameter(NumericParameter): + default: int + value: int + low: int + high: int + + def __init__(self, low: Union[int, Sequence[int]], high: Optional[int] = None, *, default: int, + space: Optional[str] = None, optimize: bool = True, load: bool = True, **kwargs): + """ + Initialize hyperopt-optimizable integer parameter. + :param low: Lower end (inclusive) of optimization space or [low, high]. + :param high: Upper end (inclusive) of optimization space. + Must be none of entire range is passed first parameter. + :param default: A default value. + :param space: A parameter category. Can be 'buy' or 'sell'. This parameter is optional if + parameter fieldname is prefixed with 'buy_' or 'sell_'. + :param optimize: Include parameter in hyperopt optimizations. + :param load: Load parameter value from {space}_params. + :param kwargs: Extra parameters to skopt.space.Integer. + """ + + super().__init__(low=low, high=high, default=default, space=space, optimize=optimize, + load=load, **kwargs) + + def get_space(self, name: str) -> 'Integer': + """ + Create skopt optimization space. + :param name: A name of parameter field. + """ + return Integer(low=self.low, high=self.high, name=name, **self._space_params) + + @property + def range(self): + """ + Get each value in this space as list. + Returns a List from low to high (inclusive) in Hyperopt mode. + Returns a List with 1 item (`value`) in "non-hyperopt" mode, to avoid + calculating 100ds of indicators. + """ + if self.in_space and self.optimize: + # Scikit-optimize ranges are "inclusive", while python's "range" is exclusive + return range(self.low, self.high + 1) + else: + return range(self.value, self.value + 1) + + +class RealParameter(NumericParameter): + default: float + value: float + + def __init__(self, low: Union[float, Sequence[float]], high: Optional[float] = None, *, + default: float, space: Optional[str] = None, optimize: bool = True, + load: bool = True, **kwargs): + """ + Initialize hyperopt-optimizable floating point parameter with unlimited precision. + :param low: Lower end (inclusive) of optimization space or [low, high]. + :param high: Upper end (inclusive) of optimization space. + Must be none if entire range is passed first parameter. + :param default: A default value. + :param space: A parameter category. Can be 'buy' or 'sell'. This parameter is optional if + parameter fieldname is prefixed with 'buy_' or 'sell_'. + :param optimize: Include parameter in hyperopt optimizations. + :param load: Load parameter value from {space}_params. + :param kwargs: Extra parameters to skopt.space.Real. + """ + super().__init__(low=low, high=high, default=default, space=space, optimize=optimize, + load=load, **kwargs) + + def get_space(self, name: str) -> 'Real': + """ + Create skopt optimization space. + :param name: A name of parameter field. + """ + return Real(low=self.low, high=self.high, name=name, **self._space_params) + + +class DecimalParameter(NumericParameter): + default: float + value: float + + def __init__(self, low: Union[float, Sequence[float]], high: Optional[float] = None, *, + default: float, decimals: int = 3, space: Optional[str] = None, + optimize: bool = True, load: bool = True, **kwargs): + """ + Initialize hyperopt-optimizable decimal parameter with a limited precision. + :param low: Lower end (inclusive) of optimization space or [low, high]. + :param high: Upper end (inclusive) of optimization space. + Must be none if entire range is passed first parameter. + :param default: A default value. + :param decimals: A number of decimals after floating point to be included in testing. + :param space: A parameter category. Can be 'buy' or 'sell'. This parameter is optional if + parameter fieldname is prefixed with 'buy_' or 'sell_'. + :param optimize: Include parameter in hyperopt optimizations. + :param load: Load parameter value from {space}_params. + :param kwargs: Extra parameters to skopt.space.Integer. + """ + self._decimals = decimals + default = round(default, self._decimals) + + super().__init__(low=low, high=high, default=default, space=space, optimize=optimize, + load=load, **kwargs) + + def get_space(self, name: str) -> 'SKDecimal': + """ + Create skopt optimization space. + :param name: A name of parameter field. + """ + return SKDecimal(low=self.low, high=self.high, decimals=self._decimals, name=name, + **self._space_params) + + @property + def range(self): + """ + Get each value in this space as list. + Returns a List from low to high (inclusive) in Hyperopt mode. + Returns a List with 1 item (`value`) in "non-hyperopt" mode, to avoid + calculating 100ds of indicators. + """ + if self.in_space and self.optimize: + low = int(self.low * pow(10, self._decimals)) + high = int(self.high * pow(10, self._decimals)) + 1 + return [round(n * pow(0.1, self._decimals), self._decimals) for n in range(low, high)] + else: + return [self.value] + + +class CategoricalParameter(BaseParameter): + default: Any + value: Any + opt_range: Sequence[Any] + + def __init__(self, categories: Sequence[Any], *, default: Optional[Any] = None, + space: Optional[str] = None, optimize: bool = True, load: bool = True, **kwargs): + """ + Initialize hyperopt-optimizable parameter. + :param categories: Optimization space, [a, b, ...]. + :param default: A default value. If not specified, first item from specified space will be + used. + :param space: A parameter category. Can be 'buy' or 'sell'. This parameter is optional if + parameter field + name is prefixed with 'buy_' or 'sell_'. + :param optimize: Include parameter in hyperopt optimizations. + :param load: Load parameter value from {space}_params. + :param kwargs: Extra parameters to skopt.space.Categorical. + """ + if len(categories) < 2: + raise OperationalException( + 'CategoricalParameter space must be [a, b, ...] (at least two parameters)') + self.opt_range = categories + super().__init__(default=default, space=space, optimize=optimize, + load=load, **kwargs) + + def get_space(self, name: str) -> 'Categorical': + """ + Create skopt optimization space. + :param name: A name of parameter field. + """ + return Categorical(self.opt_range, name=name, **self._space_params) + + @property + def range(self): + """ + Get each value in this space as list. + Returns a List of categories in Hyperopt mode. + Returns a List with 1 item (`value`) in "non-hyperopt" mode, to avoid + calculating 100ds of indicators. + """ + if self.in_space and self.optimize: + return self.opt_range + else: + return [self.value] + + +class BooleanParameter(CategoricalParameter): + + def __init__(self, *, default: Optional[Any] = None, + space: Optional[str] = None, optimize: bool = True, load: bool = True, **kwargs): + """ + Initialize hyperopt-optimizable Boolean Parameter. + It's a shortcut to `CategoricalParameter([True, False])`. + :param default: A default value. If not specified, first item from specified space will be + used. + :param space: A parameter category. Can be 'buy' or 'sell'. This parameter is optional if + parameter field + name is prefixed with 'buy_' or 'sell_'. + :param optimize: Include parameter in hyperopt optimizations. + :param load: Load parameter value from {space}_params. + :param kwargs: Extra parameters to skopt.space.Categorical. + """ + + categories = [True, False] + super().__init__(categories=categories, default=default, space=space, optimize=optimize, + load=load, **kwargs) diff --git a/freqtrade/strategy/strategy_wrapper.py b/freqtrade/strategy/strategy_wrapper.py index 9aead8395..8cb0bde15 100644 --- a/freqtrade/strategy/strategy_wrapper.py +++ b/freqtrade/strategy/strategy_wrapper.py @@ -1,5 +1,7 @@ import logging from copy import deepcopy +from functools import wraps +from typing import Any, Callable, TypeVar, cast from freqtrade.exceptions import StrategyError @@ -7,12 +9,16 @@ from freqtrade.exceptions import StrategyError logger = logging.getLogger(__name__) -def strategy_safe_wrapper(f, message: str = "", default_retval=None, supress_error=False): +F = TypeVar('F', bound=Callable[..., Any]) + + +def strategy_safe_wrapper(f: F, message: str = "", default_retval=None, supress_error=False) -> F: """ Wrapper around user-provided methods and functions. Caches all exceptions and returns either the default_retval (if it's not None) or raises a StrategyError exception, which then needs to be handled by the calling method. """ + @wraps(f) def wrapper(*args, **kwargs): try: if 'trade' in kwargs: @@ -37,4 +43,4 @@ def strategy_safe_wrapper(f, message: str = "", default_retval=None, supress_err raise StrategyError(str(error)) from error return default_retval - return wrapper + return cast(F, wrapper) diff --git a/freqtrade/templates/base_strategy.py.j2 b/freqtrade/templates/base_strategy.py.j2 index 9e7e1fe50..610a7a96e 100644 --- a/freqtrade/templates/base_strategy.py.j2 +++ b/freqtrade/templates/base_strategy.py.j2 @@ -6,7 +6,7 @@ import numpy as np # noqa import pandas as pd # noqa from pandas import DataFrame # noqa from datetime import datetime # noqa -from typing import Optional # noqa +from typing import Optional, Union # noqa from freqtrade.strategy import (BooleanParameter, CategoricalParameter, DecimalParameter, IStrategy, IntParameter) @@ -64,7 +64,7 @@ class {{ strategy }}(IStrategy): # trailing_stop_positive_offset = 0.0 # Disabled / not configured # Run "populate_indicators()" only for new candle. - process_only_new_candles = False + process_only_new_candles = True # These values can be overridden in the config. use_exit_signal = True diff --git a/freqtrade/templates/sample_strategy.py b/freqtrade/templates/sample_strategy.py index f0ae6c10d..1b375714a 100644 --- a/freqtrade/templates/sample_strategy.py +++ b/freqtrade/templates/sample_strategy.py @@ -62,7 +62,7 @@ class SampleStrategy(IStrategy): timeframe = '5m' # Run "populate_indicators()" only for new candle. - process_only_new_candles = False + process_only_new_candles = True # These values can be overridden in the config. use_exit_signal = True diff --git a/freqtrade/templates/subtemplates/strategy_methods_advanced.j2 b/freqtrade/templates/subtemplates/strategy_methods_advanced.j2 index 317602da9..815ca7cd3 100644 --- a/freqtrade/templates/subtemplates/strategy_methods_advanced.j2 +++ b/freqtrade/templates/subtemplates/strategy_methods_advanced.j2 @@ -13,7 +13,7 @@ def bot_loop_start(self, **kwargs) -> None: pass def custom_entry_price(self, pair: str, current_time: 'datetime', proposed_rate: float, - entry_tag: Optional[str], **kwargs) -> float: + entry_tag: 'Optional[str]', side: str, **kwargs) -> float: """ Custom entry price logic, returning the new entry price. @@ -80,8 +80,8 @@ def custom_exit_price(self, pair: str, trade: 'Trade', return proposed_rate def custom_stake_amount(self, pair: str, current_time: 'datetime', current_rate: float, - proposed_stake: float, min_stake: float, max_stake: float, - side: str, entry_tag: Optional[str], **kwargs) -> float: + proposed_stake: float, min_stake: Optional[float], max_stake: float, + entry_tag: 'Optional[str]', side: str, **kwargs) -> float: """ Customize stake size for each new trade. @@ -159,8 +159,9 @@ def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: f :param pair: Pair that's about to be bought/shorted. :param order_type: Order type (as configured in order_types). usually limit or market. - :param amount: Amount in target (quote) currency that's going to be traded. + :param amount: Amount in target (base) currency that's going to be traded. :param rate: Rate that's going to be used when using limit orders + or current rate for market orders. :param time_in_force: Time in force. Defaults to GTC (Good-til-cancelled). :param current_time: datetime object, containing the current datetime :param entry_tag: Optional entry_tag (buy_tag) if provided with the buy signal. @@ -175,7 +176,7 @@ def confirm_trade_exit(self, pair: str, trade: 'Trade', order_type: str, amount: rate: float, time_in_force: str, exit_reason: str, current_time: 'datetime', **kwargs) -> bool: """ - Called right before placing a regular sell order. + Called right before placing a regular exit order. Timing for this function is critical, so avoid doing heavy computations or network requests in this method. @@ -183,18 +184,19 @@ def confirm_trade_exit(self, pair: str, trade: 'Trade', order_type: str, amount: When not implemented by a strategy, returns True (always confirming). - :param pair: Pair that's currently analyzed + :param pair: Pair for trade that's about to be exited. :param trade: trade object. :param order_type: Order type (as configured in order_types). usually limit or market. - :param amount: Amount in quote currency. + :param amount: Amount in base currency. :param rate: Rate that's going to be used when using limit orders + or current rate for market orders. :param time_in_force: Time in force. Defaults to GTC (Good-til-cancelled). :param exit_reason: Exit reason. Can be any of ['roi', 'stop_loss', 'stoploss_on_exchange', 'trailing_stop_loss', 'exit_signal', 'force_exit', 'emergency_exit'] :param current_time: datetime object, containing the current datetime :param **kwargs: Ensure to keep this here so updates to this won't break your strategy. - :return bool: When True is returned, then the exit-order is placed on the exchange. + :return bool: When True, then the exit-order is placed on the exchange. False aborts the process """ return True @@ -244,8 +246,8 @@ def check_exit_timeout(self, pair: str, trade: 'Trade', order: 'Order', return False def adjust_trade_position(self, trade: 'Trade', current_time: 'datetime', - current_rate: float, current_profit: float, min_stake: float, - max_stake: float, **kwargs) -> Optional[float]: + current_rate: float, current_profit: float, min_stake: Optional[float], + max_stake: float, **kwargs) -> 'Optional[float]': """ Custom trade adjustment logic, returning the stake amount that a trade should be increased. This means extra buy orders with additional fees. @@ -267,8 +269,8 @@ def adjust_trade_position(self, trade: 'Trade', current_time: 'datetime', return None def leverage(self, pair: str, current_time: datetime, current_rate: float, - proposed_leverage: float, max_leverage: float, side: str, - **kwargs) -> float: + proposed_leverage: float, max_leverage: float, entry_tag: Optional[str], + side: str, **kwargs) -> float: """ Customize leverage for each new trade. This method is only called in futures mode. @@ -277,6 +279,7 @@ def leverage(self, pair: str, current_time: datetime, current_rate: float, :param current_rate: Rate, calculated based on pricing settings in exit_pricing. :param proposed_leverage: A leverage proposed by the bot. :param max_leverage: Max leverage allowed on this pair + :param entry_tag: Optional entry_tag (buy_tag) if provided with the buy signal. :param side: 'long' or 'short' - indicating the direction of the proposed trade :return: A leverage amount, which is between 1.0 and max_leverage. """ diff --git a/pyproject.toml b/pyproject.toml index e8d5ed47e..8020b0636 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,28 @@ skip_glob = ["**/.env*", "**/env/*", "**/.venv/*", "**/docs/*", "**/user_data/*" [tool.pytest.ini_options] asyncio_mode = "auto" +[tool.mypy] +ignore_missing_imports = true +warn_unused_ignores = true +exclude = [ + '^build_helpers\.py$' +] + +[[tool.mypy.overrides]] +module = "tests.*" +ignore_errors = true + [build-system] requires = ["setuptools >= 46.4.0", "wheel"] build-backend = "setuptools.build_meta" + +[tool.pyright] +include = ["freqtrade"] +exclude = [ + "**/__pycache__", + "build_helpers/*.py", +] +ignore = ["freqtrade/vendor/**"] + +# Align pyright to mypy config +strictParameterNoneValue = false diff --git a/requirements-dev.txt b/requirements-dev.txt index c7167cc8b..53c85f176 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,7 +7,7 @@ coveralls==3.3.1 flake8==4.0.1 flake8-tidy-imports==4.8.0 -mypy==0.950 +mypy==0.961 pre-commit==2.19.0 pytest==7.1.2 pytest-asyncio==0.18.3 @@ -22,8 +22,8 @@ time-machine==2.7.0 nbconvert==6.5.0 # mypy types -types-cachetools==5.0.1 -types-filelock==3.2.5 -types-requests==2.27.25 +types-cachetools==5.0.2 +types-filelock==3.2.7 +types-requests==2.27.30 types-tabulate==0.8.9 -types-python-dateutil==2.8.15 +types-python-dateutil==2.8.17 diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index 0b91636f1..94e59ec15 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -2,8 +2,8 @@ -r requirements.txt # Required for hyperopt -scipy==1.8.0 -scikit-learn==1.1.0 +scipy==1.8.1 +scikit-learn==1.1.1 scikit-optimize==0.9.0 -filelock==3.7.0 +filelock==3.7.1 progressbar2==4.0.0 diff --git a/requirements-plot.txt b/requirements-plot.txt index e17efbc71..a2a894c57 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.8.0 +plotly==5.8.2 diff --git a/requirements.txt b/requirements.txt index 90ddcd1b6..b62238024 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,18 +1,18 @@ -numpy==1.22.3 +numpy==1.23.0 pandas==1.4.2 pandas-ta==0.3.14b -ccxt==1.82.61 +ccxt==1.88.15 # Pin cryptography for now due to rust build errors with piwheels cryptography==37.0.2 aiohttp==3.8.1 -SQLAlchemy==1.4.36 -python-telegram-bot==13.11 +SQLAlchemy==1.4.37 +python-telegram-bot==13.12 arrow==1.2.2 cachetools==4.2.2 -requests==2.27.1 +requests==2.28.0 urllib3==1.26.9 -jsonschema==4.5.1 +jsonschema==4.6.0 TA-Lib==0.4.24 technical==1.3.0 tabulate==0.8.9 @@ -28,7 +28,7 @@ py_find_1st==1.1.5 # Load ticker files 30% faster python-rapidjson==1.6 # Properly format api responses -orjson==3.6.8 +orjson==3.7.2 # Notify systemd sdnotify==0.3.2 @@ -38,10 +38,10 @@ fastapi==0.78.0 uvicorn==0.17.6 pyjwt==2.4.0 aiofiles==0.8.0 -psutil==5.9.0 +psutil==5.9.1 # Support for colorized terminal output -colorama==0.4.4 +colorama==0.4.5 # Building config files interactively questionary==1.10.0 prompt-toolkit==3.0.29 diff --git a/scripts/rest_client.py b/scripts/rest_client.py index ecbb65253..e5d358c98 100755 --- a/scripts/rest_client.py +++ b/scripts/rest_client.py @@ -261,7 +261,7 @@ class FtRestClient(): } return self._post("forcebuy", data=data) - def force_enter(self, pair, side, price=None): + def forceenter(self, pair, side, price=None): """Force entering a trade :param pair: Pair to buy (ETH/BTC) @@ -273,7 +273,7 @@ class FtRestClient(): "side": side, "price": price, } - return self._post("force_enter", data=data) + return self._post("forceenter", data=data) def forceexit(self, tradeid): """Force-exit a trade. diff --git a/setup.cfg b/setup.cfg index 042517ec9..d711534d9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -50,13 +50,3 @@ exclude = .eggs, user_data, -[mypy] -ignore_missing_imports = True -warn_unused_ignores = True -exclude = (?x)( - ^build_helpers\.py$ - ) - - -[mypy-tests.*] -ignore_errors = True diff --git a/setup.py b/setup.py index fadd4629f..7aa56bf81 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ setup( ], install_requires=[ # from requirements.txt - 'ccxt>=1.80.67', + 'ccxt>=1.83.12', 'SQLAlchemy', 'python-telegram-bot>=13.4', 'arrow>=0.17.0', diff --git a/setup.sh b/setup.sh index bb51c3a2f..202cb70c7 100755 --- a/setup.sh +++ b/setup.sh @@ -87,6 +87,10 @@ function updateenv() { echo "Failed installing Freqtrade" exit 1 fi + + echo "Installing freqUI" + freqtrade install-ui + echo "pip install completed" echo if [[ $dev =~ ^[Yy]$ ]]; then diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index b37edf9c7..d6e80675e 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -1495,7 +1495,7 @@ def test_start_convert_db(mocker, fee, tmpdir, caplog): ] assert not db_src_file.is_file() - init_db(db_from, False) + init_db(db_from) create_mock_trades(fee) diff --git a/tests/conftest.py b/tests/conftest.py index cc07de1de..e9161d77e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -78,9 +78,21 @@ def get_args(args): # Source: https://stackoverflow.com/questions/29881236/how-to-mock-asyncio-coroutines -def get_mock_coro(return_value): +# TODO: This should be replaced with AsyncMock once support for python 3.7 is dropped. +def get_mock_coro(return_value=None, side_effect=None): async def mock_coro(*args, **kwargs): - return return_value + if side_effect: + if isinstance(side_effect, list): + effect = side_effect.pop(0) + else: + effect = side_effect + if isinstance(effect, Exception): + raise effect + if callable(effect): + return effect(*args, **kwargs) + return effect + else: + return return_value return Mock(wraps=mock_coro) @@ -325,7 +337,7 @@ def create_mock_trades_with_leverage(fee, use_db: bool = True): Trade.query.session.flush() -def create_mock_trades_usdt(fee, use_db: bool = True): +def create_mock_trades_usdt(fee, is_short: Optional[bool] = False, use_db: bool = True): """ Create some fake trades ... """ @@ -335,26 +347,29 @@ def create_mock_trades_usdt(fee, use_db: bool = True): else: LocalTrade.add_bt_trade(trade) + is_short1 = is_short if is_short is not None else True + is_short2 = is_short if is_short is not None else False + # Simulate dry_run entries - trade = mock_trade_usdt_1(fee) + trade = mock_trade_usdt_1(fee, is_short1) add_trade(trade) - trade = mock_trade_usdt_2(fee) + trade = mock_trade_usdt_2(fee, is_short1) add_trade(trade) - trade = mock_trade_usdt_3(fee) + trade = mock_trade_usdt_3(fee, is_short1) add_trade(trade) - trade = mock_trade_usdt_4(fee) + trade = mock_trade_usdt_4(fee, is_short2) add_trade(trade) - trade = mock_trade_usdt_5(fee) + trade = mock_trade_usdt_5(fee, is_short2) add_trade(trade) - trade = mock_trade_usdt_6(fee) + trade = mock_trade_usdt_6(fee, is_short1) add_trade(trade) - trade = mock_trade_usdt_7(fee) + trade = mock_trade_usdt_7(fee, is_short1) add_trade(trade) if use_db: Trade.commit() @@ -384,7 +399,7 @@ def patch_coingekko(mocker) -> None: @pytest.fixture(scope='function') def init_persistence(default_conf): - init_db(default_conf['db_url'], default_conf['dry_run']) + init_db(default_conf['db_url']) @pytest.fixture(scope="function") @@ -1616,6 +1631,7 @@ def limit_buy_order_open(): 'datetime': arrow.utcnow().isoformat(), 'price': 0.00001099, 'amount': 90.99181073, + 'average': None, 'filled': 0.0, 'cost': 0.0009999, 'remaining': 90.99181073, diff --git a/tests/conftest_trades.py b/tests/conftest_trades.py index 006eab98f..1a8cf3183 100644 --- a/tests/conftest_trades.py +++ b/tests/conftest_trades.py @@ -29,6 +29,7 @@ def mock_order_1(is_short: bool): 'average': 0.123, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.129, 'remaining': 0.0, } @@ -65,6 +66,7 @@ def mock_order_2(is_short: bool): 'price': 0.123, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.129, 'remaining': 0.0, } @@ -79,6 +81,7 @@ def mock_order_2_sell(is_short: bool): 'price': 0.128, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.129, 'remaining': 0.0, } @@ -126,6 +129,7 @@ def mock_order_3(is_short: bool): 'price': 0.05, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.129, 'remaining': 0.0, } @@ -141,6 +145,7 @@ def mock_order_3_sell(is_short: bool): 'average': 0.06, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.129, 'remaining': 0.0, } @@ -186,6 +191,7 @@ def mock_order_4(is_short: bool): 'price': 0.123, 'amount': 123.0, 'filled': 0.0, + 'cost': 15.129, 'remaining': 123.0, } @@ -225,6 +231,7 @@ def mock_order_5(is_short: bool): 'price': 0.123, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.129, 'remaining': 0.0, } @@ -239,6 +246,7 @@ def mock_order_5_stoploss(is_short: bool): 'price': 0.123, 'amount': 123.0, 'filled': 0.0, + 'cost': 0.0, 'remaining': 123.0, } @@ -281,6 +289,7 @@ def mock_order_6(is_short: bool): 'price': 0.15, 'amount': 2.0, 'filled': 2.0, + 'cost': 0.3, 'remaining': 0.0, } @@ -295,6 +304,7 @@ def mock_order_6_sell(is_short: bool): 'price': 0.15 if is_short else 0.20, 'amount': 2.0, 'filled': 0.0, + 'cost': 0.0, 'remaining': 2.0, } @@ -337,6 +347,7 @@ def short_order(): 'price': 0.123, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.129, 'remaining': 0.0, } @@ -351,6 +362,7 @@ def exit_short_order(): 'price': 0.128, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.744, 'remaining': 0.0, } @@ -424,6 +436,7 @@ def leverage_order(): 'amount': 123.0, 'filled': 123.0, 'remaining': 0.0, + 'cost': 15.129, 'leverage': 5.0 } @@ -439,6 +452,7 @@ def leverage_order_sell(): 'amount': 123.0, 'filled': 123.0, 'remaining': 0.0, + 'cost': 15.744, 'leverage': 5.0 } diff --git a/tests/conftest_trades_usdt.py b/tests/conftest_trades_usdt.py index 59e7f0457..41d705c01 100644 --- a/tests/conftest_trades_usdt.py +++ b/tests/conftest_trades_usdt.py @@ -6,47 +6,84 @@ from freqtrade.persistence.models import Order, Trade MOCK_TRADE_COUNT = 6 -def mock_order_usdt_1(): +def entry_side(is_short: bool): + return "sell" if is_short else "buy" + + +def exit_side(is_short: bool): + return "buy" if is_short else "sell" + + +def direc(is_short: bool): + return "short" if is_short else "long" + + +def mock_order_usdt_1(is_short: bool): return { - 'id': '1234', - 'symbol': 'ADA/USDT', + 'id': f'prod_entry_1_{direc(is_short)}', + 'symbol': 'LTC/USDT', 'status': 'closed', - 'side': 'buy', + 'side': entry_side(is_short), 'type': 'limit', - 'price': 2.0, - 'amount': 10.0, - 'filled': 10.0, + 'price': 10.0, + 'amount': 2.0, + 'filled': 2.0, 'remaining': 0.0, } -def mock_trade_usdt_1(fee): +def mock_order_usdt_1_exit(is_short: bool): + return { + 'id': f'prod_exit_1_{direc(is_short)}', + 'symbol': 'LTC/USDT', + 'status': 'closed', + 'side': exit_side(is_short), + 'type': 'limit', + 'price': 8.0, + 'amount': 2.0, + 'filled': 2.0, + 'remaining': 0.0, + } + + +def mock_trade_usdt_1(fee, is_short: bool): + """ + Simulate prod entry with open sell order + """ trade = Trade( - pair='ADA/USDT', + pair='LTC/USDT', stake_amount=20.0, - amount=10.0, - amount_requested=10.0, + amount=2.0, + amount_requested=2.0, + open_date=datetime.now(tz=timezone.utc) - timedelta(days=2, minutes=20), + close_date=datetime.now(tz=timezone.utc) - timedelta(days=2, minutes=5), fee_open=fee.return_value, fee_close=fee.return_value, - is_open=True, - open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=17), - open_rate=2.0, + is_open=False, + open_rate=10.0, + close_rate=8.0, + close_profit=-0.2, + close_profit_abs=-4.0, exchange='binance', - open_order_id='dry_run_buy_12345', - strategy='StrategyTestV2', + strategy='SampleStrategy', + open_order_id=f'prod_exit_1_{direc(is_short)}', timeframe=5, + is_short=is_short, ) - o = Order.parse_from_ccxt_object(mock_order_usdt_1(), 'ADA/USDT', 'buy') + o = Order.parse_from_ccxt_object(mock_order_usdt_1(is_short), 'LTC/USDT', entry_side(is_short)) + trade.orders.append(o) + o = Order.parse_from_ccxt_object(mock_order_usdt_1_exit(is_short), + 'LTC/USDT', exit_side(is_short)) trade.orders.append(o) return trade -def mock_order_usdt_2(): +def mock_order_usdt_2(is_short: bool): return { - 'id': '1235', + 'id': f'1235_{direc(is_short)}', 'symbol': 'ETC/USDT', 'status': 'closed', - 'side': 'buy', + 'side': entry_side(is_short), 'type': 'limit', 'price': 2.0, 'amount': 100.0, @@ -55,12 +92,12 @@ def mock_order_usdt_2(): } -def mock_order_usdt_2_sell(): +def mock_order_usdt_2_exit(is_short: bool): return { - 'id': '12366', + 'id': f'12366_{direc(is_short)}', 'symbol': 'ETC/USDT', 'status': 'closed', - 'side': 'sell', + 'side': exit_side(is_short), 'type': 'limit', 'price': 2.05, 'amount': 100.0, @@ -69,7 +106,7 @@ def mock_order_usdt_2_sell(): } -def mock_trade_usdt_2(fee): +def mock_trade_usdt_2(fee, is_short: bool): """ Closed trade... """ @@ -82,30 +119,33 @@ def mock_trade_usdt_2(fee): fee_close=fee.return_value, open_rate=2.0, close_rate=2.05, - close_profit=5.0, + close_profit=0.05, close_profit_abs=3.9875, exchange='binance', is_open=False, - open_order_id='dry_run_sell_12345', + open_order_id=f'12366_{direc(is_short)}', strategy='StrategyTestV2', timeframe=5, - exit_reason='sell_signal', + enter_tag='TEST1', + exit_reason='exit_signal', open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=20), close_date=datetime.now(tz=timezone.utc) - timedelta(minutes=2), + is_short=is_short, ) - o = Order.parse_from_ccxt_object(mock_order_usdt_2(), 'ETC/USDT', 'buy') + o = Order.parse_from_ccxt_object(mock_order_usdt_2(is_short), 'ETC/USDT', entry_side(is_short)) trade.orders.append(o) - o = Order.parse_from_ccxt_object(mock_order_usdt_2_sell(), 'ETC/USDT', 'sell') + o = Order.parse_from_ccxt_object( + mock_order_usdt_2_exit(is_short), 'ETC/USDT', exit_side(is_short)) trade.orders.append(o) return trade -def mock_order_usdt_3(): +def mock_order_usdt_3(is_short: bool): return { - 'id': '41231a12a', + 'id': f'41231a12a_{direc(is_short)}', 'symbol': 'XRP/USDT', 'status': 'closed', - 'side': 'buy', + 'side': entry_side(is_short), 'type': 'limit', 'price': 1.0, 'amount': 30.0, @@ -114,12 +154,12 @@ def mock_order_usdt_3(): } -def mock_order_usdt_3_sell(): +def mock_order_usdt_3_exit(is_short: bool): return { - 'id': '41231a666a', + 'id': f'41231a666a_{direc(is_short)}', 'symbol': 'XRP/USDT', 'status': 'closed', - 'side': 'sell', + 'side': exit_side(is_short), 'type': 'stop_loss_limit', 'price': 1.1, 'average': 1.1, @@ -129,7 +169,7 @@ def mock_order_usdt_3_sell(): } -def mock_trade_usdt_3(fee): +def mock_trade_usdt_3(fee, is_short: bool): """ Closed trade """ @@ -142,29 +182,32 @@ def mock_trade_usdt_3(fee): fee_close=fee.return_value, open_rate=1.0, close_rate=1.1, - close_profit=10.0, + close_profit=0.1, close_profit_abs=9.8425, exchange='binance', is_open=False, strategy='StrategyTestV2', timeframe=5, + enter_tag='TEST3', exit_reason='roi', open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=20), close_date=datetime.now(tz=timezone.utc), + is_short=is_short, ) - o = Order.parse_from_ccxt_object(mock_order_usdt_3(), 'XRP/USDT', 'buy') + o = Order.parse_from_ccxt_object(mock_order_usdt_3(is_short), 'XRP/USDT', entry_side(is_short)) trade.orders.append(o) - o = Order.parse_from_ccxt_object(mock_order_usdt_3_sell(), 'XRP/USDT', 'sell') + o = Order.parse_from_ccxt_object(mock_order_usdt_3_exit(is_short), + 'XRP/USDT', exit_side(is_short)) trade.orders.append(o) return trade -def mock_order_usdt_4(): +def mock_order_usdt_4(is_short: bool): return { - 'id': 'prod_buy_12345', + 'id': f'prod_buy_12345_{direc(is_short)}', 'symbol': 'ETC/USDT', 'status': 'open', - 'side': 'buy', + 'side': entry_side(is_short), 'type': 'limit', 'price': 2.0, 'amount': 10.0, @@ -173,7 +216,7 @@ def mock_order_usdt_4(): } -def mock_trade_usdt_4(fee): +def mock_trade_usdt_4(fee, is_short: bool): """ Simulate prod entry """ @@ -188,21 +231,22 @@ def mock_trade_usdt_4(fee): is_open=True, open_rate=2.0, exchange='binance', - open_order_id='prod_buy_12345', + open_order_id=f'prod_buy_12345_{direc(is_short)}', strategy='StrategyTestV2', timeframe=5, + is_short=is_short, ) - o = Order.parse_from_ccxt_object(mock_order_usdt_4(), 'ETC/USDT', 'buy') + o = Order.parse_from_ccxt_object(mock_order_usdt_4(is_short), 'ETC/USDT', entry_side(is_short)) trade.orders.append(o) return trade -def mock_order_usdt_5(): +def mock_order_usdt_5(is_short: bool): return { - 'id': 'prod_buy_3455', + 'id': f'prod_buy_3455_{direc(is_short)}', 'symbol': 'XRP/USDT', 'status': 'closed', - 'side': 'buy', + 'side': entry_side(is_short), 'type': 'limit', 'price': 2.0, 'amount': 10.0, @@ -211,12 +255,12 @@ def mock_order_usdt_5(): } -def mock_order_usdt_5_stoploss(): +def mock_order_usdt_5_stoploss(is_short: bool): return { - 'id': 'prod_stoploss_3455', + 'id': f'prod_stoploss_3455_{direc(is_short)}', 'symbol': 'XRP/USDT', 'status': 'open', - 'side': 'sell', + 'side': exit_side(is_short), 'type': 'stop_loss_limit', 'price': 2.0, 'amount': 10.0, @@ -225,7 +269,7 @@ def mock_order_usdt_5_stoploss(): } -def mock_trade_usdt_5(fee): +def mock_trade_usdt_5(fee, is_short: bool): """ Simulate prod entry with stoploss """ @@ -241,22 +285,23 @@ def mock_trade_usdt_5(fee): open_rate=2.0, exchange='binance', strategy='SampleStrategy', - stoploss_order_id='prod_stoploss_3455', + stoploss_order_id=f'prod_stoploss_3455_{direc(is_short)}', timeframe=5, + is_short=is_short, ) - o = Order.parse_from_ccxt_object(mock_order_usdt_5(), 'XRP/USDT', 'buy') + o = Order.parse_from_ccxt_object(mock_order_usdt_5(is_short), 'XRP/USDT', entry_side(is_short)) trade.orders.append(o) - o = Order.parse_from_ccxt_object(mock_order_usdt_5_stoploss(), 'XRP/USDT', 'stoploss') + o = Order.parse_from_ccxt_object(mock_order_usdt_5_stoploss(is_short), 'XRP/USDT', 'stoploss') trade.orders.append(o) return trade -def mock_order_usdt_6(): +def mock_order_usdt_6(is_short: bool): return { - 'id': 'prod_buy_6', + 'id': f'prod_entry_6_{direc(is_short)}', 'symbol': 'LTC/USDT', 'status': 'closed', - 'side': 'buy', + 'side': entry_side(is_short), 'type': 'limit', 'price': 10.0, 'amount': 2.0, @@ -265,12 +310,12 @@ def mock_order_usdt_6(): } -def mock_order_usdt_6_sell(): +def mock_order_usdt_6_exit(is_short: bool): return { - 'id': 'prod_sell_6', + 'id': f'prod_exit_6_{direc(is_short)}', 'symbol': 'LTC/USDT', 'status': 'open', - 'side': 'sell', + 'side': exit_side(is_short), 'type': 'limit', 'price': 12.0, 'amount': 2.0, @@ -279,7 +324,7 @@ def mock_order_usdt_6_sell(): } -def mock_trade_usdt_6(fee): +def mock_trade_usdt_6(fee, is_short: bool): """ Simulate prod entry with open sell order """ @@ -295,69 +340,49 @@ def mock_trade_usdt_6(fee): open_rate=10.0, exchange='binance', strategy='SampleStrategy', - open_order_id="prod_sell_6", + open_order_id=f'prod_exit_6_{direc(is_short)}', timeframe=5, + is_short=is_short, ) - o = Order.parse_from_ccxt_object(mock_order_usdt_6(), 'LTC/USDT', 'buy') + o = Order.parse_from_ccxt_object(mock_order_usdt_6(is_short), 'LTC/USDT', entry_side(is_short)) trade.orders.append(o) - o = Order.parse_from_ccxt_object(mock_order_usdt_6_sell(), 'LTC/USDT', 'sell') + o = Order.parse_from_ccxt_object(mock_order_usdt_6_exit(is_short), + 'LTC/USDT', exit_side(is_short)) trade.orders.append(o) return trade -def mock_order_usdt_7(): +def mock_order_usdt_7(is_short: bool): return { - 'id': 'prod_buy_7', - 'symbol': 'LTC/USDT', + 'id': f'1234_{direc(is_short)}', + 'symbol': 'ADA/USDT', 'status': 'closed', - 'side': 'buy', + 'side': entry_side(is_short), 'type': 'limit', - 'price': 10.0, - 'amount': 2.0, - 'filled': 2.0, + 'price': 2.0, + 'amount': 10.0, + 'filled': 10.0, 'remaining': 0.0, } -def mock_order_usdt_7_sell(): - return { - 'id': 'prod_sell_7', - 'symbol': 'LTC/USDT', - 'status': 'closed', - 'side': 'sell', - 'type': 'limit', - 'price': 8.0, - 'amount': 2.0, - 'filled': 2.0, - 'remaining': 0.0, - } - - -def mock_trade_usdt_7(fee): - """ - Simulate prod entry with open sell order - """ +def mock_trade_usdt_7(fee, is_short: bool): trade = Trade( - pair='LTC/USDT', + pair='ADA/USDT', stake_amount=20.0, - amount=2.0, - amount_requested=2.0, - open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=20), - close_date=datetime.now(tz=timezone.utc) - timedelta(minutes=5), + amount=10.0, + amount_requested=10.0, fee_open=fee.return_value, fee_close=fee.return_value, - is_open=False, - open_rate=10.0, - close_rate=8.0, - close_profit=-0.2, - close_profit_abs=-4.0, + is_open=True, + open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=17), + open_rate=2.0, exchange='binance', - strategy='SampleStrategy', - open_order_id="prod_sell_6", + open_order_id=f'1234_{direc(is_short)}', + strategy='StrategyTestV2', timeframe=5, + is_short=is_short, ) - o = Order.parse_from_ccxt_object(mock_order_usdt_7(), 'LTC/USDT', 'buy') - trade.orders.append(o) - o = Order.parse_from_ccxt_object(mock_order_usdt_7_sell(), 'LTC/USDT', 'sell') + o = Order.parse_from_ccxt_object(mock_order_usdt_7(is_short), 'ADA/USDT', entry_side(is_short)) trade.orders.append(o) return trade diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index 4157bd899..977140ebb 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -85,7 +85,7 @@ def test_load_backtest_data_new_format(testdatadir): filename = testdatadir / "backtest_results/backtest-result_new.json" bt_data = load_backtest_data(filename) assert isinstance(bt_data, DataFrame) - assert set(bt_data.columns) == set(BT_DATA_COLUMNS + ['close_timestamp', 'open_timestamp']) + assert set(bt_data.columns) == set(BT_DATA_COLUMNS) assert len(bt_data) == 179 # Test loading from string (must yield same result) @@ -110,7 +110,7 @@ def test_load_backtest_data_multi(testdatadir): bt_data = load_backtest_data(filename, strategy=strategy) assert isinstance(bt_data, DataFrame) assert set(bt_data.columns) == set( - BT_DATA_COLUMNS + ['close_timestamp', 'open_timestamp']) + BT_DATA_COLUMNS) assert len(bt_data) == 179 # Test loading from string (must yield same result) diff --git a/tests/data/test_entryexitanalysis.py b/tests/data/test_entryexitanalysis.py new file mode 100755 index 000000000..09fbe9957 --- /dev/null +++ b/tests/data/test_entryexitanalysis.py @@ -0,0 +1,191 @@ +import logging +from unittest.mock import MagicMock, PropertyMock + +import pandas as pd +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.optimize.backtesting import Backtesting +from tests.conftest import get_args, patch_exchange, patched_configuration_load_config_file + + +@pytest.fixture(autouse=True) +def entryexitanalysis_cleanup() -> None: + yield None + + Backtesting.cleanup() + + +def test_backtest_analysis_nomock(default_conf, mocker, caplog, testdatadir, tmpdir, capsys): + caplog.set_level(logging.INFO) + + 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, + ExitType.EXIT_SIGNAL, + ExitType.STOP_LOSS, + ExitType.TRAILING_STOP_LOSS] + }) + + 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(tmpdir), + '--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(tmpdir), + ] + + # test group 0 and indicator list + args = get_args(base_args + + ['--analysis-groups', "0", + '--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 '-3.5' in captured.out + assert '50' in captured.out + assert '0' in captured.out + assert '0.01616' in captured.out + assert '34.049' in captured.out + assert '0.104104' in captured.out + assert '47.0996' 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 diff --git a/tests/exchange/test_binance.py b/tests/exchange/test_binance.py index 5c8d7d3b0..45f8a3817 100644 --- a/tests/exchange/test_binance.py +++ b/tests/exchange/test_binance.py @@ -154,6 +154,7 @@ def test_stoploss_adjust_binance(mocker, default_conf, sl1, sl2, sl3, side): order = { 'type': 'stop_loss_limit', 'price': 1500, + 'stopPrice': 1500, 'info': {'stopPrice': 1500}, } assert exchange.stoploss_adjust(sl1, order, side=side) @@ -490,11 +491,11 @@ def test_fill_leverage_tiers_binance_dryrun(default_conf, mocker, leverage_tiers default_conf['margin_mode'] = MarginMode.ISOLATED exchange = get_patched_exchange(mocker, default_conf, api_mock, id="binance") exchange.fill_leverage_tiers() - - leverage_tiers = leverage_tiers - + assert len(exchange._leverage_tiers.keys()) > 100 for key, value in leverage_tiers.items(): - assert exchange._leverage_tiers[key] == value + v = exchange._leverage_tiers[key] + assert isinstance(v, list) + assert len(v) == len(value) def test__set_leverage_binance(mocker, default_conf): diff --git a/tests/exchange/test_ccxt_compat.py b/tests/exchange/test_ccxt_compat.py index e016873cb..50154bcaf 100644 --- a/tests/exchange/test_ccxt_compat.py +++ b/tests/exchange/test_ccxt_compat.py @@ -199,8 +199,13 @@ class TestCCXTExchange(): l2 = exchange.fetch_l2_order_book(pair) assert 'asks' in l2 assert 'bids' in l2 + assert len(l2['asks']) >= 1 + assert len(l2['bids']) >= 1 l2_limit_range = exchange._ft_has['l2_limit_range'] l2_limit_range_required = exchange._ft_has['l2_limit_range_required'] + if exchangename == 'gateio': + # TODO: Gateio is unstable here at the moment, ignoring the limit partially. + return for val in [1, 2, 5, 25, 100]: l2 = exchange.fetch_l2_order_book(pair, val) if not l2_limit_range or val in l2_limit_range: diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 53e6cc3f3..708a0e889 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -2155,6 +2155,8 @@ async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_ @pytest.mark.asyncio async def test__async_kucoin_get_candle_history(default_conf, mocker, caplog): + from freqtrade.exchange.common import _reset_logging_mixin + _reset_logging_mixin() caplog.set_level(logging.INFO) api_mock = MagicMock() api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.DDoSProtection( @@ -2808,6 +2810,7 @@ def test_get_historic_trades_notsupported(default_conf, mocker, caplog, exchange until=trades_history[-1][0]) +@pytest.mark.usefixtures("init_persistence") @pytest.mark.parametrize("exchange_name", EXCHANGES) def test_cancel_order_dry_run(default_conf, mocker, exchange_name): default_conf['dry_run'] = True @@ -2973,6 +2976,7 @@ def test_cancel_stoploss_order_with_result(default_conf, mocker, exchange_name): exchange.cancel_stoploss_order_with_result(order_id='_', pair='TKN/BTC', amount=123) +@pytest.mark.usefixtures("init_persistence") @pytest.mark.parametrize("exchange_name", EXCHANGES) def test_fetch_order(default_conf, mocker, exchange_name, caplog): default_conf['dry_run'] = True @@ -3025,6 +3029,7 @@ def test_fetch_order(default_conf, mocker, exchange_name, caplog): order_id='_', pair='TKN/BTC') +@pytest.mark.usefixtures("init_persistence") @pytest.mark.parametrize("exchange_name", EXCHANGES) def test_fetch_stoploss_order(default_conf, mocker, exchange_name): # Don't test FTX here - that needs a separate test @@ -3814,6 +3819,7 @@ def test_validate_trading_mode_and_margin_mode( ("bibox", "spot", {"has": {"fetchCurrencies": False}}), ("bibox", "margin", {"has": {"fetchCurrencies": False}, "options": {"defaultType": "margin"}}), ("bibox", "futures", {"has": {"fetchCurrencies": False}, "options": {"defaultType": "swap"}}), + ("bybit", "spot", {"options": {"defaultType": "spot"}}), ("bybit", "futures", {"options": {"defaultType": "linear"}}), ("ftx", "futures", {"options": {"defaultType": "swap"}}), ("gateio", "futures", {"options": {"defaultType": "swap"}}), @@ -3912,6 +3918,70 @@ def test_calculate_funding_fees( ) == kraken_fee +@pytest.mark.parametrize( + 'mark_price,funding_rate,futures_funding_rate', [ + (1000, 0.001, None), + (1000, 0.001, 0.01), + (1000, 0.001, 0.0), + (1000, 0.001, -0.01), + ]) +def test_combine_funding_and_mark( + default_conf, + mocker, + funding_rate, + mark_price, + futures_funding_rate, +): + exchange = get_patched_exchange(mocker, default_conf) + prior2_date = timeframe_to_prev_date('1h', datetime.now(timezone.utc) - timedelta(hours=2)) + prior_date = timeframe_to_prev_date('1h', datetime.now(timezone.utc) - timedelta(hours=1)) + trade_date = timeframe_to_prev_date('1h', datetime.now(timezone.utc)) + funding_rates = DataFrame([ + {'date': prior2_date, 'open': funding_rate}, + {'date': prior_date, 'open': funding_rate}, + {'date': trade_date, 'open': funding_rate}, + ]) + mark_rates = DataFrame([ + {'date': prior2_date, 'open': mark_price}, + {'date': prior_date, 'open': mark_price}, + {'date': trade_date, 'open': mark_price}, + ]) + + df = exchange.combine_funding_and_mark(funding_rates, mark_rates, futures_funding_rate) + assert 'open_mark' in df.columns + assert 'open_fund' in df.columns + assert len(df) == 3 + + funding_rates = DataFrame([ + {'date': trade_date, 'open': funding_rate}, + ]) + mark_rates = DataFrame([ + {'date': prior2_date, 'open': mark_price}, + {'date': prior_date, 'open': mark_price}, + {'date': trade_date, 'open': mark_price}, + ]) + df = exchange.combine_funding_and_mark(funding_rates, mark_rates, futures_funding_rate) + + if futures_funding_rate is not None: + assert len(df) == 3 + assert df.iloc[0]['open_fund'] == futures_funding_rate + assert df.iloc[1]['open_fund'] == futures_funding_rate + assert df.iloc[2]['open_fund'] == funding_rate + else: + assert len(df) == 1 + + # Empty funding rates + funding_rates = DataFrame([], columns=['date', 'open']) + df = exchange.combine_funding_and_mark(funding_rates, mark_rates, futures_funding_rate) + if futures_funding_rate is not None: + assert len(df) == 3 + assert df.iloc[0]['open_fund'] == futures_funding_rate + assert df.iloc[1]['open_fund'] == futures_funding_rate + assert df.iloc[2]['open_fund'] == futures_funding_rate + else: + assert len(df) == 0 + + def test_get_or_calculate_liquidation_price(mocker, default_conf): api_mock = MagicMock() diff --git a/tests/exchange/test_ftx.py b/tests/exchange/test_ftx.py index 0f16d4433..5a83b964a 100644 --- a/tests/exchange/test_ftx.py +++ b/tests/exchange/test_ftx.py @@ -174,6 +174,7 @@ def test_stoploss_adjust_ftx(mocker, default_conf, sl1, sl2, sl3, side): assert not exchange.stoploss_adjust(sl3, order, side=side) +@pytest.mark.usefixtures("init_persistence") def test_fetch_stoploss_order_ftx(default_conf, mocker, limit_sell_order, limit_buy_order): default_conf['dry_run'] = True order = MagicMock() diff --git a/tests/exchange/test_gateio.py b/tests/exchange/test_gateio.py index ad30a7d86..cbd4776fb 100644 --- a/tests/exchange/test_gateio.py +++ b/tests/exchange/test_gateio.py @@ -33,7 +33,14 @@ def test_validate_order_types_gateio(default_conf, mocker): match=r'Exchange .* does not support market orders.'): ExchangeResolver.load_exchange('gateio', default_conf, True) + # market-orders supported on futures markets. + default_conf['trading_mode'] = 'futures' + default_conf['margin_mode'] = 'isolated' + ex = ExchangeResolver.load_exchange('gateio', default_conf, True) + assert ex + +@pytest.mark.usefixtures("init_persistence") def test_fetch_stoploss_order_gateio(default_conf, mocker): exchange = get_patched_exchange(mocker, default_conf, id='gateio') diff --git a/tests/exchange/test_kucoin.py b/tests/exchange/test_kucoin.py index 8af1e83a3..ebaf5ae81 100644 --- a/tests/exchange/test_kucoin.py +++ b/tests/exchange/test_kucoin.py @@ -123,5 +123,5 @@ def test_stoploss_adjust_kucoin(mocker, default_conf): assert exchange.stoploss_adjust(1501, order, 'sell') assert not exchange.stoploss_adjust(1499, order, 'sell') # Test with invalid order case - order['info']['stop'] = None - assert not exchange.stoploss_adjust(1501, order, 'sell') + order['stopPrice'] = None + assert exchange.stoploss_adjust(1501, order, 'sell') diff --git a/tests/exchange/test_okx.py b/tests/exchange/test_okx.py index 19c09ad9e..91c4a3368 100644 --- a/tests/exchange/test_okx.py +++ b/tests/exchange/test_okx.py @@ -6,7 +6,7 @@ import pytest from freqtrade.enums import MarginMode, TradingMode from freqtrade.enums.candletype import CandleType from freqtrade.exchange.exchange import timeframe_to_minutes -from tests.conftest import get_patched_exchange +from tests.conftest import get_mock_coro, get_patched_exchange from tests.exchange.test_exchange import ccxt_exceptionhandlers @@ -273,7 +273,7 @@ def test_load_leverage_tiers_okx(default_conf, mocker, markets): 'fetchLeverageTiers': False, 'fetchMarketLeverageTiers': True, }) - api_mock.fetch_market_leverage_tiers = MagicMock(side_effect=[ + api_mock.fetch_market_leverage_tiers = get_mock_coro(side_effect=[ [ { 'tier': 1, diff --git a/tests/optimize/test_backtest_detail.py b/tests/optimize/test_backtest_detail.py index 4b4c446e0..a18196507 100644 --- a/tests/optimize/test_backtest_detail.py +++ b/tests/optimize/test_backtest_detail.py @@ -7,6 +7,7 @@ import pytest from freqtrade.data.history import get_timerange from freqtrade.enums import ExitType from freqtrade.optimize.backtesting import Backtesting +from freqtrade.persistence.trade_model import LocalTrade from tests.conftest import patch_exchange from tests.optimize import (BTContainer, BTrade, _build_backtest_dataframe, _get_frame_time_from_offset, tests_timeframe) @@ -964,5 +965,7 @@ def test_backtest_results(default_conf, fee, mocker, caplog, data: BTContainer) assert res.open_date == _get_frame_time_from_offset(trade.open_tick) assert res.close_date == _get_frame_time_from_offset(trade.close_tick) assert res.is_short == trade.is_short + assert len(LocalTrade.trades) == len(data.trades) + assert len(LocalTrade.trades_open) == 0 backtesting.cleanup() del backtesting diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index f169e0a35..6912184aa 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -795,10 +795,27 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None: 'is_open': [False, False], 'enter_tag': [None, None], "is_short": [False, False], + 'open_timestamp': [1517251200000, 1517283000000], + 'close_timestamp': [1517265300000, 1517285400000], + 'orders': [ + [ + {'amount': 0.00957442, 'safe_price': 0.104445, 'ft_order_side': 'buy', + 'order_filled_timestamp': 1517251200000, 'ft_is_entry': True}, + {'amount': 0.00957442, 'safe_price': 0.10496853383458644, 'ft_order_side': 'sell', + 'order_filled_timestamp': 1517265300000, 'ft_is_entry': False} + ], [ + {'amount': 0.0097064, 'safe_price': 0.10302485, 'ft_order_side': 'buy', + 'order_filled_timestamp': 1517283000000, 'ft_is_entry': True}, + {'amount': 0.0097064, 'safe_price': 0.10354126528822055, 'ft_order_side': 'sell', + 'order_filled_timestamp': 1517285400000, 'ft_is_entry': False} + ] + ] }) pd.testing.assert_frame_equal(results, expected) + assert 'orders' in results.columns data_pair = processed[pair] for _, t in results.iterrows(): + assert len(t['orders']) == 2 ln = data_pair.loc[data_pair["date"] == t["open_date"]] # Check open trade rate alignes to open rate assert ln is not None diff --git a/tests/optimize/test_backtesting_adjust_position.py b/tests/optimize/test_backtesting_adjust_position.py index 5babfb548..fca9c01b2 100644 --- a/tests/optimize/test_backtesting_adjust_position.py +++ b/tests/optimize/test_backtesting_adjust_position.py @@ -22,7 +22,7 @@ def test_backtest_position_adjustment(default_conf, fee, mocker, testdatadir) -> default_conf.update({ "stake_amount": 100.0, "dry_run_wallet": 1000.0, - "strategy": "StrategyTestV2" + "strategy": "StrategyTestV3" }) backtesting = Backtesting(default_conf) backtesting._set_strategy(backtesting.strategylist[0]) @@ -70,9 +70,14 @@ def test_backtest_position_adjustment(default_conf, fee, mocker, testdatadir) -> 'is_open': [False, False], 'enter_tag': [None, None], 'is_short': [False, False], + 'open_timestamp': [1517251200000, 1517283000000], + 'close_timestamp': [1517265300000, 1517285400000], }) - pd.testing.assert_frame_equal(results, expected) + pd.testing.assert_frame_equal(results.drop(columns=['orders']), expected) data_pair = processed[pair] + assert len(results.iloc[0]['orders']) == 6 + assert len(results.iloc[1]['orders']) == 2 + for _, t in results.iterrows(): ln = data_pair.loc[data_pair["date"] == t["open_date"]] # Check open trade rate alignes to open rate diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index dcc1ddeea..9f3c5845f 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -17,7 +17,7 @@ from freqtrade.optimize.hyperopt_auto import HyperOptAuto from freqtrade.optimize.hyperopt_tools import HyperoptTools from freqtrade.optimize.optimize_reports import generate_strategy_stats from freqtrade.optimize.space import SKDecimal -from freqtrade.strategy.hyper import IntParameter +from freqtrade.strategy import IntParameter from tests.conftest import (CURRENT_TEST_STRATEGY, get_args, log_has, log_has_re, patch_exchange, patched_configuration_load_config_file) @@ -509,7 +509,6 @@ def test_generate_optimizer(mocker, hyperopt_conf) -> None: hyperopt.min_date = Arrow(2017, 12, 10) hyperopt.max_date = Arrow(2017, 12, 13) hyperopt.init_spaces() - hyperopt.dimensions = hyperopt.dimensions generate_optimizer_value = hyperopt.generate_optimizer(list(optimizer_param.values())) assert generate_optimizer_value == response_expected diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 997c0436e..562e12820 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -171,7 +171,7 @@ def test_generate_backtest_stats(default_conf, testdatadir, tmpdir): _backup_file(filename_last, copy_file=True) assert not filename.is_file() - store_backtest_stats(filename, stats) + store_backtest_stats(filename, stats, '2022_01_01_15_05_13') # get real Filename (it's btresult-.json) last_fn = get_latest_backtest_filename(filename_last.parent) @@ -194,7 +194,7 @@ def test_store_backtest_stats(testdatadir, mocker): dump_mock = mocker.patch('freqtrade.optimize.optimize_reports.file_dump_json') - store_backtest_stats(testdatadir, {'metadata': {}}) + store_backtest_stats(testdatadir, {'metadata': {}}, '2022_01_01_15_05_13') assert dump_mock.call_count == 3 assert isinstance(dump_mock.call_args_list[0][0][0], Path) @@ -202,7 +202,7 @@ def test_store_backtest_stats(testdatadir, mocker): dump_mock.reset_mock() filename = testdatadir / 'testresult.json' - store_backtest_stats(filename, {'metadata': {}}) + store_backtest_stats(filename, {'metadata': {}}, '2022_01_01_15_05_13') assert dump_mock.call_count == 3 assert isinstance(dump_mock.call_args_list[0][0][0], Path) # result will be testdatadir / testresult-.json @@ -216,7 +216,7 @@ def test_store_backtest_candles(testdatadir, mocker): candle_dict = {'DefStrat': {'UNITTEST/BTC': pd.DataFrame()}} # mock directory exporting - store_backtest_signal_candles(testdatadir, candle_dict) + store_backtest_signal_candles(testdatadir, candle_dict, '2022_01_01_15_05_13') assert dump_mock.call_count == 1 assert isinstance(dump_mock.call_args_list[0][0][0], Path) @@ -225,7 +225,7 @@ def test_store_backtest_candles(testdatadir, mocker): dump_mock.reset_mock() # mock file exporting filename = Path(testdatadir / 'testresult') - store_backtest_signal_candles(filename, candle_dict) + store_backtest_signal_candles(filename, candle_dict, '2022_01_01_15_05_13') assert dump_mock.call_count == 1 assert isinstance(dump_mock.call_args_list[0][0][0], Path) # result will be testdatadir / testresult-_signals.pkl @@ -238,7 +238,7 @@ def test_write_read_backtest_candles(tmpdir): candle_dict = {'DefStrat': {'UNITTEST/BTC': pd.DataFrame()}} # test directory exporting - stored_file = store_backtest_signal_candles(Path(tmpdir), candle_dict) + stored_file = store_backtest_signal_candles(Path(tmpdir), candle_dict, '2022_01_01_15_05_13') scp = open(stored_file, "rb") pickled_signal_candles = joblib.load(scp) scp.close() @@ -252,7 +252,7 @@ def test_write_read_backtest_candles(tmpdir): # test file exporting filename = Path(tmpdir / 'testresult') - stored_file = store_backtest_signal_candles(filename, candle_dict) + stored_file = store_backtest_signal_candles(filename, candle_dict, '2022_01_01_15_05_13') scp = open(stored_file, "rb") pickled_signal_candles = joblib.load(scp) scp.close() diff --git a/tests/plugins/test_pairlist.py b/tests/plugins/test_pairlist.py index c29e619b1..c56f405e2 100644 --- a/tests/plugins/test_pairlist.py +++ b/tests/plugins/test_pairlist.py @@ -762,8 +762,8 @@ def test_PerformanceFilter_keep_mid_order(mocker, default_conf_usdt, fee, caplog with time_machine.travel("2021-09-01 05:00:00 +00:00") as t: create_mock_trades_usdt(fee) pm.refresh_pairlist() - assert pm.whitelist == ['XRP/USDT', 'ETC/USDT', 'ETH/USDT', - 'NEO/USDT', 'TKN/USDT', 'ADA/USDT', 'LTC/USDT'] + assert pm.whitelist == ['XRP/USDT', 'ETC/USDT', 'ETH/USDT', 'LTC/USDT', + 'NEO/USDT', 'TKN/USDT', 'ADA/USDT', ] # assert log_has_re(r'Removing pair .* since .* is below .*', caplog) # Move to "outside" of lookback window, so original sorting is restored. diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index 95645c8ba..d20646e60 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -11,11 +11,11 @@ from freqtrade.edge import PairInfo from freqtrade.enums import SignalDirection, State, TradingMode from freqtrade.exceptions import ExchangeError, InvalidOrderException, TemporaryError from freqtrade.persistence import Trade -from freqtrade.persistence.models import Order from freqtrade.persistence.pairlock_middleware import PairLocks from freqtrade.rpc import RPC, RPCException from freqtrade.rpc.fiat_convert import CryptoToFiatConverter -from tests.conftest import create_mock_trades, get_patched_freqtradebot, patch_get_signal +from tests.conftest import (create_mock_trades, create_mock_trades_usdt, get_patched_freqtradebot, + patch_get_signal) # Functions for recurrent object patching @@ -284,8 +284,8 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: assert isnan(fiat_profit_sum) -def test_rpc_daily_profit(default_conf, update, ticker, fee, - limit_buy_order, limit_sell_order, markets, mocker) -> None: +def test__rpc_timeunit_profit(default_conf_usdt, ticker, fee, + limit_buy_order, limit_sell_order, markets, mocker) -> None: mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -294,45 +294,35 @@ def test_rpc_daily_profit(default_conf, update, ticker, fee, markets=PropertyMock(return_value=markets) ) - freqtradebot = get_patched_freqtradebot(mocker, default_conf) - patch_get_signal(freqtradebot) - stake_currency = default_conf['stake_currency'] - fiat_display_currency = default_conf['fiat_display_currency'] + freqtradebot = get_patched_freqtradebot(mocker, default_conf_usdt) + create_mock_trades_usdt(fee) + + stake_currency = default_conf_usdt['stake_currency'] + fiat_display_currency = default_conf_usdt['fiat_display_currency'] rpc = RPC(freqtradebot) rpc._fiat_converter = CryptoToFiatConverter() - # Create some test data - freqtradebot.enter_positions() - trade = Trade.query.first() - assert trade - - # Simulate buy & sell - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy') - trade.update_trade(oobj) - oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') - trade.update_trade(oobj) - trade.close_date = datetime.utcnow() - trade.is_open = False # Try valid data - update.message.text = '/daily 2' - days = rpc._rpc_daily_profit(7, stake_currency, fiat_display_currency) + days = rpc._rpc_timeunit_profit(7, stake_currency, fiat_display_currency) assert len(days['data']) == 7 - assert days['stake_currency'] == default_conf['stake_currency'] - assert days['fiat_display_currency'] == default_conf['fiat_display_currency'] + assert days['stake_currency'] == default_conf_usdt['stake_currency'] + assert days['fiat_display_currency'] == default_conf_usdt['fiat_display_currency'] for day in days['data']: - # [datetime.date(2018, 1, 11), '0.00000000 BTC', '0.000 USD'] - assert (day['abs_profit'] == 0.0 or - day['abs_profit'] == 0.00006217) - - assert (day['fiat_value'] == 0.0 or - day['fiat_value'] == 0.76748865) + # {'date': datetime.date(2022, 6, 11), 'abs_profit': 13.8299999, + # 'starting_balance': 1055.37, 'rel_profit': 0.0131044, + # 'fiat_value': 0.0, 'trade_count': 2} + assert day['abs_profit'] in (0.0, pytest.approx(13.8299999), pytest.approx(-4.0)) + assert day['rel_profit'] in (0.0, pytest.approx(0.01310441), pytest.approx(-0.00377583)) + assert day['trade_count'] in (0, 1, 2) + assert day['starting_balance'] in (pytest.approx(1059.37), pytest.approx(1055.37)) + assert day['fiat_value'] in (0.0, ) # ensure first day is current date assert str(days['data'][0]['date']) == str(datetime.utcnow().date()) # Try invalid data with pytest.raises(RPCException, match=r'.*must be an integer greater than 0*'): - rpc._rpc_daily_profit(0, stake_currency, fiat_display_currency) + rpc._rpc_timeunit_profit(0, stake_currency, fiat_display_currency) @pytest.mark.parametrize('is_short', [True, False]) @@ -416,13 +406,8 @@ def test_rpc_delete_trade(mocker, default_conf, fee, markets, caplog, is_short): assert stoploss_mock.call_count == 0 -def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, - limit_buy_order, limit_sell_order, mocker) -> None: - mocker.patch.multiple( - 'freqtrade.rpc.fiat_convert.CoinGeckoAPI', - get_price=MagicMock(return_value={'bitcoin': {'usd': 15000.0}}), - ) - mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0) +def test_rpc_trade_statistics(default_conf_usdt, ticker, fee, mocker) -> None: + mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=1.1) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -430,10 +415,9 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, get_fee=fee, ) - freqtradebot = get_patched_freqtradebot(mocker, default_conf) - patch_get_signal(freqtradebot) - stake_currency = default_conf['stake_currency'] - fiat_display_currency = default_conf['fiat_display_currency'] + freqtradebot = get_patched_freqtradebot(mocker, default_conf_usdt) + stake_currency = default_conf_usdt['stake_currency'] + fiat_display_currency = default_conf_usdt['fiat_display_currency'] rpc = RPC(freqtradebot) rpc._fiat_converter = CryptoToFiatConverter() @@ -446,75 +430,40 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, assert res['latest_trade_timestamp'] == 0 # Create some test data - freqtradebot.enter_positions() - trade = Trade.query.first() - # Simulate fulfilled LIMIT_BUY order for trade - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'sell') - trade.update_trade(oobj) - - # Update the ticker with a market going up - mocker.patch.multiple( - 'freqtrade.exchange.Exchange', - fetch_ticker=ticker_sell_up - ) - oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') - trade.update_trade(oobj) - trade.close_date = datetime.utcnow() - trade.is_open = False - - freqtradebot.enter_positions() - trade = Trade.query.first() - # Simulate fulfilled LIMIT_BUY order for trade - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy') - trade.update_trade(oobj) - - # Update the ticker with a market going up - mocker.patch.multiple( - 'freqtrade.exchange.Exchange', - fetch_ticker=ticker_sell_up - ) - oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') - trade.update_trade(oobj) - trade.close_date = datetime.utcnow() - trade.is_open = False + create_mock_trades_usdt(fee) stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency) - assert prec_satoshi(stats['profit_closed_coin'], 6.217e-05) - assert prec_satoshi(stats['profit_closed_percent_mean'], 6.2) - assert prec_satoshi(stats['profit_closed_fiat'], 0.93255) - assert prec_satoshi(stats['profit_all_coin'], 5.802e-05) - assert prec_satoshi(stats['profit_all_percent_mean'], 2.89) - assert prec_satoshi(stats['profit_all_fiat'], 0.8703) - assert stats['trade_count'] == 2 - assert stats['first_trade_date'] == 'just now' - assert stats['latest_trade_date'] == 'just now' - assert stats['avg_duration'] in ('0:00:00', '0:00:01', '0:00:02') - assert stats['best_pair'] == 'ETH/BTC' - assert prec_satoshi(stats['best_rate'], 6.2) + assert pytest.approx(stats['profit_closed_coin']) == 9.83 + assert pytest.approx(stats['profit_closed_percent_mean']) == -1.67 + assert pytest.approx(stats['profit_closed_fiat']) == 10.813 + assert pytest.approx(stats['profit_all_coin']) == -77.45964918 + assert pytest.approx(stats['profit_all_percent_mean']) == -57.86 + assert pytest.approx(stats['profit_all_fiat']) == -85.205614098 + assert stats['trade_count'] == 7 + assert stats['first_trade_date'] == '2 days ago' + assert stats['latest_trade_date'] == '17 minutes ago' + assert stats['avg_duration'] in ('0:17:40') + assert stats['best_pair'] == 'XRP/USDT' + assert stats['best_rate'] == 10.0 # Test non-available pair mocker.patch('freqtrade.exchange.Exchange.get_rate', - MagicMock(side_effect=ExchangeError("Pair 'ETH/BTC' not available"))) + MagicMock(side_effect=ExchangeError("Pair 'XRP/USDT' not available"))) stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency) - assert stats['trade_count'] == 2 - assert stats['first_trade_date'] == 'just now' - assert stats['latest_trade_date'] == 'just now' - assert stats['avg_duration'] in ('0:00:00', '0:00:01', '0:00:02') - assert stats['best_pair'] == 'ETH/BTC' - assert prec_satoshi(stats['best_rate'], 6.2) + assert stats['trade_count'] == 7 + assert stats['first_trade_date'] == '2 days ago' + assert stats['latest_trade_date'] == '17 minutes ago' + assert stats['avg_duration'] in ('0:17:40') + assert stats['best_pair'] == 'XRP/USDT' + assert stats['best_rate'] == 10.0 assert isnan(stats['profit_all_coin']) # Test that rpc_trade_statistics can handle trades that lacks # trade.open_rate (it is set to None) -def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee, - ticker_sell_up, limit_buy_order, limit_sell_order): - mocker.patch.multiple( - 'freqtrade.rpc.fiat_convert.CoinGeckoAPI', - get_price=MagicMock(return_value={'bitcoin': {'usd': 15000.0}}), - ) +def test_rpc_trade_statistics_closed(mocker, default_conf_usdt, ticker, fee): mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter._find_price', - return_value=15000.0) + return_value=1.1) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -522,46 +471,32 @@ def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee, get_fee=fee, ) - freqtradebot = get_patched_freqtradebot(mocker, default_conf) + freqtradebot = get_patched_freqtradebot(mocker, default_conf_usdt) patch_get_signal(freqtradebot) - stake_currency = default_conf['stake_currency'] - fiat_display_currency = default_conf['fiat_display_currency'] + stake_currency = default_conf_usdt['stake_currency'] + fiat_display_currency = default_conf_usdt['fiat_display_currency'] rpc = RPC(freqtradebot) # Create some test data - freqtradebot.enter_positions() - trade = Trade.query.first() - # Simulate fulfilled LIMIT_BUY order for trade - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy') - trade.update_trade(oobj) - # Update the ticker with a market going up - mocker.patch.multiple( - 'freqtrade.exchange.Exchange', - fetch_ticker=ticker_sell_up, - get_fee=fee - ) - oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') - trade.update_trade(oobj) - trade.close_date = datetime.utcnow() - trade.is_open = False + create_mock_trades_usdt(fee) for trade in Trade.query.order_by(Trade.id).all(): trade.open_rate = None stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency) - assert prec_satoshi(stats['profit_closed_coin'], 0) - assert prec_satoshi(stats['profit_closed_percent_mean'], 0) - assert prec_satoshi(stats['profit_closed_fiat'], 0) - assert prec_satoshi(stats['profit_all_coin'], 0) - assert prec_satoshi(stats['profit_all_percent_mean'], 0) - assert prec_satoshi(stats['profit_all_fiat'], 0) - assert stats['trade_count'] == 1 - assert stats['first_trade_date'] == 'just now' - assert stats['latest_trade_date'] == 'just now' + assert stats['profit_closed_coin'] == 0 + assert stats['profit_closed_percent_mean'] == 0 + assert stats['profit_closed_fiat'] == 0 + assert stats['profit_all_coin'] == 0 + assert stats['profit_all_percent_mean'] == 0 + assert stats['profit_all_fiat'] == 0 + assert stats['trade_count'] == 7 + assert stats['first_trade_date'] == '2 days ago' + assert stats['latest_trade_date'] == '17 minutes ago' assert stats['avg_duration'] == '0:00:00' - assert stats['best_pair'] == 'ETH/BTC' - assert prec_satoshi(stats['best_rate'], 6.2) + assert stats['best_pair'] == 'XRP/USDT' + assert stats['best_rate'] == 10.0 def test_rpc_balance_handle_error(default_conf, mocker): @@ -913,8 +848,7 @@ def test_rpc_force_exit(default_conf, ticker, fee, mocker) -> None: assert cancel_order_mock.call_count == 3 -def test_performance_handle(default_conf, ticker, limit_buy_order, fee, - limit_sell_order, mocker) -> None: +def test_performance_handle(default_conf_usdt, ticker, fee, mocker) -> None: mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -923,34 +857,21 @@ def test_performance_handle(default_conf, ticker, limit_buy_order, fee, get_fee=fee, ) - freqtradebot = get_patched_freqtradebot(mocker, default_conf) + freqtradebot = get_patched_freqtradebot(mocker, default_conf_usdt) patch_get_signal(freqtradebot) rpc = RPC(freqtradebot) - # Create some test data - freqtradebot.enter_positions() - trade = Trade.query.first() - assert trade + create_mock_trades_usdt(fee) - # Simulate fulfilled LIMIT_BUY order for trade - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy') - trade.update_trade(oobj) - - # Simulate fulfilled LIMIT_SELL order for trade - oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') - trade.update_trade(oobj) - - trade.close_date = datetime.utcnow() - trade.is_open = False res = rpc._rpc_performance() - assert len(res) == 1 - assert res[0]['pair'] == 'ETH/BTC' + assert len(res) == 3 + assert res[0]['pair'] == 'XRP/USDT' assert res[0]['count'] == 1 - assert prec_satoshi(res[0]['profit_pct'], 6.2) + assert res[0]['profit_pct'] == 10.0 -def test_enter_tag_performance_handle(default_conf, ticker, limit_buy_order, fee, - limit_sell_order, mocker) -> None: +def test_enter_tag_performance_handle(default_conf, ticker, fee, mocker) -> None: + mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -964,34 +885,22 @@ def test_enter_tag_performance_handle(default_conf, ticker, limit_buy_order, fee rpc = RPC(freqtradebot) # Create some test data + create_mock_trades_usdt(fee) freqtradebot.enter_positions() - trade = Trade.query.first() - assert trade - # Simulate fulfilled LIMIT_BUY order for trade - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy') - trade.update_trade(oobj) - - # Simulate fulfilled LIMIT_SELL order for trade - oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') - trade.update_trade(oobj) - - trade.close_date = datetime.utcnow() - trade.is_open = False res = rpc._rpc_enter_tag_performance(None) - assert len(res) == 1 - assert res[0]['enter_tag'] == 'Other' + assert len(res) == 3 + assert res[0]['enter_tag'] == 'TEST3' assert res[0]['count'] == 1 - assert prec_satoshi(res[0]['profit_pct'], 6.2) + assert res[0]['profit_pct'] == 10.0 - trade.enter_tag = "TEST_TAG" res = rpc._rpc_enter_tag_performance(None) - assert len(res) == 1 - assert res[0]['enter_tag'] == 'TEST_TAG' + assert len(res) == 3 + assert res[0]['enter_tag'] == 'TEST3' assert res[0]['count'] == 1 - assert prec_satoshi(res[0]['profit_pct'], 6.2) + assert res[0]['profit_pct'] == 10.0 def test_enter_tag_performance_handle_2(mocker, default_conf, markets, fee): @@ -1023,8 +932,7 @@ def test_enter_tag_performance_handle_2(mocker, default_conf, markets, fee): assert prec_satoshi(res[0]['profit_pct'], 0.5) -def test_exit_reason_performance_handle(default_conf, ticker, limit_buy_order, fee, - limit_sell_order, mocker) -> None: +def test_exit_reason_performance_handle(default_conf_usdt, ticker, fee, mocker) -> None: mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -1033,39 +941,22 @@ def test_exit_reason_performance_handle(default_conf, ticker, limit_buy_order, f get_fee=fee, ) - freqtradebot = get_patched_freqtradebot(mocker, default_conf) + freqtradebot = get_patched_freqtradebot(mocker, default_conf_usdt) patch_get_signal(freqtradebot) rpc = RPC(freqtradebot) # Create some test data - freqtradebot.enter_positions() - trade = Trade.query.first() - assert trade + create_mock_trades_usdt(fee) - # Simulate fulfilled LIMIT_BUY order for trade - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy') - trade.update_trade(oobj) - - # Simulate fulfilled LIMIT_SELL order for trade - oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') - trade.update_trade(oobj) - - trade.close_date = datetime.utcnow() - trade.is_open = False res = rpc._rpc_exit_reason_performance(None) - assert len(res) == 1 - assert res[0]['exit_reason'] == 'Other' + assert len(res) == 3 + assert res[0]['exit_reason'] == 'roi' assert res[0]['count'] == 1 - assert prec_satoshi(res[0]['profit_pct'], 6.2) + assert res[0]['profit_pct'] == 10.0 - trade.exit_reason = "TEST1" - res = rpc._rpc_exit_reason_performance(None) - - assert len(res) == 1 - assert res[0]['exit_reason'] == 'TEST1' - assert res[0]['count'] == 1 - assert prec_satoshi(res[0]['profit_pct'], 6.2) + assert res[1]['exit_reason'] == 'exit_signal' + assert res[2]['exit_reason'] == 'Other' def test_exit_reason_performance_handle_2(mocker, default_conf, markets, fee): @@ -1097,8 +988,7 @@ def test_exit_reason_performance_handle_2(mocker, default_conf, markets, fee): assert prec_satoshi(res[0]['profit_pct'], 0.5) -def test_mix_tag_performance_handle(default_conf, ticker, limit_buy_order, fee, - limit_sell_order, mocker) -> None: +def test_mix_tag_performance_handle(default_conf, ticker, fee, mocker) -> None: mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -1112,35 +1002,14 @@ def test_mix_tag_performance_handle(default_conf, ticker, limit_buy_order, fee, rpc = RPC(freqtradebot) # Create some test data - freqtradebot.enter_positions() - trade = Trade.query.first() - assert trade + create_mock_trades_usdt(fee) - # Simulate fulfilled LIMIT_BUY order for trade - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy') - trade.update_trade(oobj) - - # Simulate fulfilled LIMIT_SELL order for trade - oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') - trade.update_trade(oobj) - - trade.close_date = datetime.utcnow() - trade.is_open = False res = rpc._rpc_mix_tag_performance(None) - assert len(res) == 1 - assert res[0]['mix_tag'] == 'Other Other' + assert len(res) == 3 + assert res[0]['mix_tag'] == 'TEST3 roi' assert res[0]['count'] == 1 - assert prec_satoshi(res[0]['profit_pct'], 6.2) - - trade.enter_tag = "TESTBUY" - trade.exit_reason = "TESTSELL" - res = rpc._rpc_mix_tag_performance(None) - - assert len(res) == 1 - assert res[0]['mix_tag'] == 'TESTBUY TESTSELL' - assert res[0]['count'] == 1 - assert prec_satoshi(res[0]['profit_pct'], 6.2) + assert res[0]['profit_pct'] == 10.0 def test_mix_tag_performance_handle_2(mocker, default_conf, markets, fee): diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index ac2f1c3ec..c0de54c6d 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -578,9 +578,10 @@ def test_api_trades(botclient, mocker, fee, markets, is_short): ) rc = client_get(client, f"{BASE_URI}/trades") assert_response(rc) - assert len(rc.json()) == 3 + assert len(rc.json()) == 4 assert rc.json()['trades_count'] == 0 assert rc.json()['total_trades'] == 0 + assert rc.json()['offset'] == 0 create_mock_trades(fee, is_short=is_short) Trade.query.session.flush() @@ -724,7 +725,9 @@ def test_api_edge_disabled(botclient, mocker, ticker, fee, markets): 'profit_closed_fiat': -83.19455985, 'profit_closed_ratio_mean': -0.0075, 'profit_closed_percent_mean': -0.75, 'profit_closed_ratio_sum': -0.015, 'profit_closed_percent_sum': -1.5, 'profit_closed_ratio': -6.739057628404269e-06, - 'profit_closed_percent': -0.0, 'winning_trades': 0, 'losing_trades': 2} + 'profit_closed_percent': -0.0, 'winning_trades': 0, 'losing_trades': 2, + 'profit_factor': 0.0, 'trading_volume': 91.074, + } ), ( False, @@ -737,7 +740,9 @@ def test_api_edge_disabled(botclient, mocker, ticker, fee, markets): 'profit_closed_fiat': 9.124559849999999, 'profit_closed_ratio_mean': 0.0075, 'profit_closed_percent_mean': 0.75, 'profit_closed_ratio_sum': 0.015, 'profit_closed_percent_sum': 1.5, 'profit_closed_ratio': 7.391275897987988e-07, - 'profit_closed_percent': 0.0, 'winning_trades': 2, 'losing_trades': 0} + 'profit_closed_percent': 0.0, 'winning_trades': 2, 'losing_trades': 0, + 'profit_factor': None, 'trading_volume': 91.074, + } ), ( None, @@ -750,7 +755,9 @@ def test_api_edge_disabled(botclient, mocker, ticker, fee, markets): 'profit_closed_fiat': -67.02260985, 'profit_closed_ratio_mean': 0.0025, 'profit_closed_percent_mean': 0.25, 'profit_closed_ratio_sum': 0.005, 'profit_closed_percent_sum': 0.5, 'profit_closed_ratio': -5.429078808526421e-06, - 'profit_closed_percent': -0.0, 'winning_trades': 1, 'losing_trades': 1} + 'profit_closed_percent': -0.0, 'winning_trades': 1, 'losing_trades': 1, + 'profit_factor': 0.02775724835771106, 'trading_volume': 91.074, + } ) ]) def test_api_profit(botclient, mocker, ticker, fee, markets, is_short, expected): @@ -803,6 +810,10 @@ def test_api_profit(botclient, mocker, ticker, fee, markets, is_short, expected) 'closed_trade_count': 2, 'winning_trades': expected['winning_trades'], 'losing_trades': expected['losing_trades'], + 'profit_factor': expected['profit_factor'], + 'max_drawdown': ANY, + 'max_drawdown_abs': ANY, + 'trading_volume': expected['trading_volume'], } @@ -852,8 +863,8 @@ def test_api_performance(botclient, fee): close_rate=0.265441, ) - trade.close_profit = trade.calc_profit_ratio() - trade.close_profit_abs = trade.calc_profit() + trade.close_profit = trade.calc_profit_ratio(trade.close_rate) + trade.close_profit_abs = trade.calc_profit(trade.close_rate) Trade.query.session.add(trade) trade = Trade( @@ -868,8 +879,8 @@ def test_api_performance(botclient, fee): fee_open=fee.return_value, close_rate=0.391 ) - trade.close_profit = trade.calc_profit_ratio() - trade.close_profit_abs = trade.calc_profit() + trade.close_profit = trade.calc_profit_ratio(trade.close_rate) + trade.close_profit_abs = trade.calc_profit(trade.close_rate) Trade.query.session.add(trade) Trade.commit() @@ -972,6 +983,7 @@ def test_api_status(botclient, mocker, ticker, fee, markets, is_short, 'exchange': 'binance', 'leverage': 1.0, 'interest_rate': 0.0, + 'liquidation_price': None, 'funding_fees': None, 'trading_mode': ANY, 'orders': [ANY], @@ -1175,6 +1187,7 @@ def test_api_force_entry(botclient, mocker, fee, endpoint): 'exchange': 'binance', 'leverage': None, 'interest_rate': None, + 'liquidation_price': None, 'funding_fees': None, 'trading_mode': 'spot', 'orders': [], @@ -1382,12 +1395,14 @@ def test_api_strategies(botclient): rc = client_get(client, f"{BASE_URI}/strategies") assert_response(rc) + assert rc.json() == {'strategies': [ 'HyperoptableStrategy', 'InformativeDecoratorTest', 'StrategyTestV2', 'StrategyTestV3', - 'StrategyTestV3Futures', + 'StrategyTestV3Analysis', + 'StrategyTestV3Futures' ]} diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index 2bc4fc5c3..e36d98083 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -27,8 +27,9 @@ from freqtrade.persistence.models import Order from freqtrade.rpc import RPC from freqtrade.rpc.rpc import RPCException from freqtrade.rpc.telegram import Telegram, authorized_only -from tests.conftest import (CURRENT_TEST_STRATEGY, create_mock_trades, get_patched_freqtradebot, - log_has, log_has_re, patch_exchange, patch_get_signal, patch_whitelist) +from tests.conftest import (CURRENT_TEST_STRATEGY, create_mock_trades, create_mock_trades_usdt, + get_patched_freqtradebot, log_has, log_has_re, patch_exchange, + patch_get_signal, patch_whitelist) class DummyCls(Telegram): @@ -404,12 +405,10 @@ def test_status_table_handle(default_conf, update, ticker, fee, mocker) -> None: assert msg_mock.call_count == 1 -def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee, - limit_sell_order, mocker) -> None: - default_conf['max_open_trades'] = 1 +def test_daily_handle(default_conf_usdt, update, ticker, fee, mocker, time_machine) -> None: mocker.patch( 'freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', - return_value=15000.0 + return_value=1.1 ) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -417,25 +416,12 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee, get_fee=fee, ) - telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf) - - patch_get_signal(freqtradebot) + telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf_usdt) + # Move date to within day + time_machine.move_to('2022-06-11 08:00:00+00:00') # Create some test data - freqtradebot.enter_positions() - trade = Trade.query.first() - assert trade - - # Simulate fulfilled LIMIT_BUY order for trade - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy') - trade.update_trade(oobj) - - # Simulate fulfilled LIMIT_SELL order for trade - oobjs = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') - trade.update_trade(oobjs) - - trade.close_date = datetime.utcnow() - trade.is_open = False + create_mock_trades_usdt(fee) # Try valid data # /daily 2 @@ -446,10 +432,11 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee, assert "Daily Profit over the last 2 days:" in msg_mock.call_args_list[0][0][0] assert 'Day ' in msg_mock.call_args_list[0][0][0] assert str(datetime.utcnow().date()) in msg_mock.call_args_list[0][0][0] - assert str(' 0.00006217 BTC') in msg_mock.call_args_list[0][0][0] - assert str(' 0.933 USD') in msg_mock.call_args_list[0][0][0] - assert str(' 1 trade') in msg_mock.call_args_list[0][0][0] - assert str(' 0 trade') in msg_mock.call_args_list[0][0][0] + assert ' 13.83 USDT' in msg_mock.call_args_list[0][0][0] + assert ' 15.21 USD' in msg_mock.call_args_list[0][0][0] + assert '(2)' in msg_mock.call_args_list[0][0][0] + assert '(2) 13.83 USDT 15.21 USD 1.31%' in msg_mock.call_args_list[0][0][0] + assert '(0)' in msg_mock.call_args_list[0][0][0] # Reset msg_mock msg_mock.reset_mock() @@ -458,32 +445,23 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee, assert msg_mock.call_count == 1 assert "Daily Profit over the last 7 days:" in msg_mock.call_args_list[0][0][0] assert str(datetime.utcnow().date()) in msg_mock.call_args_list[0][0][0] - assert str(' 0.00006217 BTC') in msg_mock.call_args_list[0][0][0] - assert str(' 0.933 USD') in msg_mock.call_args_list[0][0][0] - assert str(' 1 trade') in msg_mock.call_args_list[0][0][0] - assert str(' 0 trade') in msg_mock.call_args_list[0][0][0] + assert str((datetime.utcnow() - timedelta(days=5)).date()) in msg_mock.call_args_list[0][0][0] + assert ' 13.83 USDT' in msg_mock.call_args_list[0][0][0] + assert ' 15.21 USD' in msg_mock.call_args_list[0][0][0] + assert '(2)' in msg_mock.call_args_list[0][0][0] + assert '(1)' in msg_mock.call_args_list[0][0][0] + assert '(0)' in msg_mock.call_args_list[0][0][0] # Reset msg_mock msg_mock.reset_mock() - freqtradebot.config['max_open_trades'] = 2 - # Add two other trades - n = freqtradebot.enter_positions() - assert n == 2 - - trades = Trade.query.all() - for trade in trades: - trade.update_trade(oobj) - trade.update_trade(oobjs) - trade.close_date = datetime.utcnow() - trade.is_open = False # /daily 1 context = MagicMock() context.args = ["1"] telegram._daily(update=update, context=context) - assert str(' 0.00018651 BTC') in msg_mock.call_args_list[0][0][0] - assert str(' 2.798 USD') in msg_mock.call_args_list[0][0][0] - assert str(' 3 trades') in msg_mock.call_args_list[0][0][0] + assert ' 13.83 USDT' in msg_mock.call_args_list[0][0][0] + assert ' 15.21 USD' in msg_mock.call_args_list[0][0][0] + assert '(2)' in msg_mock.call_args_list[0][0][0] def test_daily_wrong_input(default_conf, update, ticker, mocker) -> None: @@ -512,15 +490,14 @@ def test_daily_wrong_input(default_conf, update, ticker, mocker) -> None: context = MagicMock() context.args = ["today"] telegram._daily(update=update, context=context) - assert str('Daily Profit over the last 7 days:') in msg_mock.call_args_list[0][0][0] + assert 'Daily Profit over the last 7 days:' in msg_mock.call_args_list[0][0][0] -def test_weekly_handle(default_conf, update, ticker, limit_buy_order, fee, - limit_sell_order, mocker) -> None: - default_conf['max_open_trades'] = 1 +def test_weekly_handle(default_conf_usdt, update, ticker, fee, mocker, time_machine) -> None: + default_conf_usdt['max_open_trades'] = 1 mocker.patch( 'freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', - return_value=15000.0 + return_value=1.1 ) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -528,25 +505,10 @@ def test_weekly_handle(default_conf, update, ticker, limit_buy_order, fee, get_fee=fee, ) - telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf) - - patch_get_signal(freqtradebot) - - # Create some test data - freqtradebot.enter_positions() - trade = Trade.query.first() - assert trade - - # Simulate fulfilled LIMIT_BUY order for trade - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy') - trade.update_trade(oobj) - - # Simulate fulfilled LIMIT_SELL order for trade - oobjs = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') - trade.update_trade(oobjs) - - trade.close_date = datetime.utcnow() - trade.is_open = False + telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf_usdt) + # Move to saturday - so all trades are within that week + time_machine.move_to('2022-06-11') + create_mock_trades_usdt(fee) # Try valid data # /weekly 2 @@ -560,10 +522,10 @@ def test_weekly_handle(default_conf, update, ticker, limit_buy_order, fee, today = datetime.utcnow().date() first_iso_day_of_current_week = today - timedelta(days=today.weekday()) assert str(first_iso_day_of_current_week) in msg_mock.call_args_list[0][0][0] - assert str(' 0.00006217 BTC') in msg_mock.call_args_list[0][0][0] - assert str(' 0.933 USD') in msg_mock.call_args_list[0][0][0] - assert str(' 1 trade') in msg_mock.call_args_list[0][0][0] - assert str(' 0 trade') in msg_mock.call_args_list[0][0][0] + assert ' 9.83 USDT' in msg_mock.call_args_list[0][0][0] + assert ' 10.81 USD' in msg_mock.call_args_list[0][0][0] + assert '(3)' in msg_mock.call_args_list[0][0][0] + assert '(0)' in msg_mock.call_args_list[0][0][0] # Reset msg_mock msg_mock.reset_mock() @@ -573,44 +535,10 @@ def test_weekly_handle(default_conf, update, ticker, limit_buy_order, fee, assert "Weekly Profit over the last 8 weeks (starting from Monday):" \ in msg_mock.call_args_list[0][0][0] assert 'Weekly' in msg_mock.call_args_list[0][0][0] - assert str(' 0.00006217 BTC') in msg_mock.call_args_list[0][0][0] - assert str(' 0.933 USD') in msg_mock.call_args_list[0][0][0] - assert str(' 1 trade') in msg_mock.call_args_list[0][0][0] - assert str(' 0 trade') in msg_mock.call_args_list[0][0][0] - - # Reset msg_mock - msg_mock.reset_mock() - freqtradebot.config['max_open_trades'] = 2 - # Add two other trades - n = freqtradebot.enter_positions() - assert n == 2 - - trades = Trade.query.all() - for trade in trades: - trade.update_trade(oobj) - trade.update_trade(oobjs) - trade.close_date = datetime.utcnow() - trade.is_open = False - - # /weekly 1 - # By default, the 8 previous weeks are shown - # So the previous modified trade should be excluded from the stats - context = MagicMock() - context.args = ["1"] - telegram._weekly(update=update, context=context) - assert str(' 0.00018651 BTC') in msg_mock.call_args_list[0][0][0] - assert str(' 2.798 USD') in msg_mock.call_args_list[0][0][0] - assert str(' 3 trades') in msg_mock.call_args_list[0][0][0] - - -def test_weekly_wrong_input(default_conf, update, ticker, mocker) -> None: - mocker.patch.multiple( - 'freqtrade.exchange.Exchange', - fetch_ticker=ticker - ) - - telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf) - patch_get_signal(freqtradebot) + assert ' 9.83 USDT' in msg_mock.call_args_list[0][0][0] + assert ' 10.81 USD' in msg_mock.call_args_list[0][0][0] + assert '(3)' in msg_mock.call_args_list[0][0][0] + assert '(0)' in msg_mock.call_args_list[0][0][0] # Try invalid data msg_mock.reset_mock() @@ -629,16 +557,17 @@ def test_weekly_wrong_input(default_conf, update, ticker, mocker) -> None: context = MagicMock() context.args = ["this week"] telegram._weekly(update=update, context=context) - assert str('Weekly Profit over the last 8 weeks (starting from Monday):') \ + assert ( + 'Weekly Profit over the last 8 weeks (starting from Monday):' in msg_mock.call_args_list[0][0][0] + ) -def test_monthly_handle(default_conf, update, ticker, limit_buy_order, fee, - limit_sell_order, mocker) -> None: - default_conf['max_open_trades'] = 1 +def test_monthly_handle(default_conf_usdt, update, ticker, fee, mocker, time_machine) -> None: + default_conf_usdt['max_open_trades'] = 1 mocker.patch( 'freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', - return_value=15000.0 + return_value=1.1 ) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -646,25 +575,10 @@ def test_monthly_handle(default_conf, update, ticker, limit_buy_order, fee, get_fee=fee, ) - telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf) - - patch_get_signal(freqtradebot) - - # Create some test data - freqtradebot.enter_positions() - trade = Trade.query.first() - assert trade - - # Simulate fulfilled LIMIT_BUY order for trade - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy') - trade.update_trade(oobj) - - # Simulate fulfilled LIMIT_SELL order for trade - oobjs = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') - trade.update_trade(oobjs) - - trade.close_date = datetime.utcnow() - trade.is_open = False + telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf_usdt) + # Move to day within the month so all mock trades fall into this week. + time_machine.move_to('2022-06-11') + create_mock_trades_usdt(fee) # Try valid data # /monthly 2 @@ -677,10 +591,10 @@ def test_monthly_handle(default_conf, update, ticker, limit_buy_order, fee, today = datetime.utcnow().date() current_month = f"{today.year}-{today.month:02} " assert current_month in msg_mock.call_args_list[0][0][0] - assert str(' 0.00006217 BTC') in msg_mock.call_args_list[0][0][0] - assert str(' 0.933 USD') in msg_mock.call_args_list[0][0][0] - assert str(' 1 trade') in msg_mock.call_args_list[0][0][0] - assert str(' 0 trade') in msg_mock.call_args_list[0][0][0] + assert ' 9.83 USDT' in msg_mock.call_args_list[0][0][0] + assert ' 10.81 USD' in msg_mock.call_args_list[0][0][0] + assert '(3)' in msg_mock.call_args_list[0][0][0] + assert '(0)' in msg_mock.call_args_list[0][0][0] # Reset msg_mock msg_mock.reset_mock() @@ -691,24 +605,13 @@ def test_monthly_handle(default_conf, update, ticker, limit_buy_order, fee, assert 'Monthly Profit over the last 6 months:' in msg_mock.call_args_list[0][0][0] assert 'Month ' in msg_mock.call_args_list[0][0][0] assert current_month in msg_mock.call_args_list[0][0][0] - assert str(' 0.00006217 BTC') in msg_mock.call_args_list[0][0][0] - assert str(' 0.933 USD') in msg_mock.call_args_list[0][0][0] - assert str(' 1 trade') in msg_mock.call_args_list[0][0][0] - assert str(' 0 trade') in msg_mock.call_args_list[0][0][0] + assert ' 9.83 USDT' in msg_mock.call_args_list[0][0][0] + assert ' 10.81 USD' in msg_mock.call_args_list[0][0][0] + assert '(3)' in msg_mock.call_args_list[0][0][0] + assert '(0)' in msg_mock.call_args_list[0][0][0] # Reset msg_mock msg_mock.reset_mock() - freqtradebot.config['max_open_trades'] = 2 - # Add two other trades - n = freqtradebot.enter_positions() - assert n == 2 - - trades = Trade.query.all() - for trade in trades: - trade.update_trade(oobj) - trade.update_trade(oobjs) - trade.close_date = datetime.utcnow() - trade.is_open = False # /monthly 12 context = MagicMock() @@ -716,24 +619,14 @@ def test_monthly_handle(default_conf, update, ticker, limit_buy_order, fee, telegram._monthly(update=update, context=context) assert msg_mock.call_count == 1 assert 'Monthly Profit over the last 12 months:' in msg_mock.call_args_list[0][0][0] - assert str(' 0.00018651 BTC') in msg_mock.call_args_list[0][0][0] - assert str(' 2.798 USD') in msg_mock.call_args_list[0][0][0] - assert str(' 3 trades') in msg_mock.call_args_list[0][0][0] + assert ' 9.83 USDT' in msg_mock.call_args_list[0][0][0] + assert ' 10.81 USD' in msg_mock.call_args_list[0][0][0] + assert '(3)' in msg_mock.call_args_list[0][0][0] # The one-digit months should contain a zero, Eg: September 2021 = "2021-09" # Since we loaded the last 12 months, any month should appear assert str('-09') in msg_mock.call_args_list[0][0][0] - -def test_monthly_wrong_input(default_conf, update, ticker, mocker) -> None: - mocker.patch.multiple( - 'freqtrade.exchange.Exchange', - fetch_ticker=ticker - ) - - telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf) - patch_get_signal(freqtradebot) - # Try invalid data msg_mock.reset_mock() freqtradebot.state = State.RUNNING @@ -754,16 +647,16 @@ def test_monthly_wrong_input(default_conf, update, ticker, mocker) -> None: assert str('Monthly Profit over the last 6 months:') in msg_mock.call_args_list[0][0][0] -def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee, - limit_buy_order, limit_sell_order, mocker) -> None: - mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0) +def test_profit_handle(default_conf_usdt, update, ticker_usdt, ticker_sell_up, fee, + limit_sell_order_usdt, mocker) -> None: + mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=1.1) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - fetch_ticker=ticker, + fetch_ticker=ticker_usdt, get_fee=fee, ) - telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf) + telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf_usdt) patch_get_signal(freqtradebot) telegram._profit(update=update, context=MagicMock()) @@ -775,10 +668,6 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee, freqtradebot.enter_positions() trade = Trade.query.first() - # Simulate fulfilled LIMIT_BUY order for trade - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy') - trade.update_trade(oobj) - context = MagicMock() # Test with invalid 2nd argument (should silently pass) context.args = ["aaa"] @@ -786,15 +675,16 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee, assert msg_mock.call_count == 1 assert 'No closed trade' in msg_mock.call_args_list[-1][0][0] assert '*ROI:* All trades' in msg_mock.call_args_list[-1][0][0] - mocker.patch('freqtrade.wallets.Wallets.get_starting_balance', return_value=0.01) - assert ('∙ `-0.000005 BTC (-0.50%) (-0.0 \N{GREEK CAPITAL LETTER SIGMA}%)`' + mocker.patch('freqtrade.wallets.Wallets.get_starting_balance', return_value=1000) + assert ('∙ `0.298 USDT (0.50%) (0.03 \N{GREEK CAPITAL LETTER SIGMA}%)`' in msg_mock.call_args_list[-1][0][0]) msg_mock.reset_mock() # Update the ticker with a market going up mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', ticker_sell_up) # Simulate fulfilled LIMIT_SELL order for trade - oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') + oobj = Order.parse_from_ccxt_object( + limit_sell_order_usdt, limit_sell_order_usdt['symbol'], 'sell') trade.update_trade(oobj) trade.close_date = datetime.now(timezone.utc) @@ -805,20 +695,22 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee, telegram._profit(update=update, context=context) assert msg_mock.call_count == 1 assert '*ROI:* Closed trades' in msg_mock.call_args_list[-1][0][0] - assert ('∙ `0.00006217 BTC (6.20%) (0.62 \N{GREEK CAPITAL LETTER SIGMA}%)`' + assert ('∙ `5.685 USDT (9.45%) (0.57 \N{GREEK CAPITAL LETTER SIGMA}%)`' in msg_mock.call_args_list[-1][0][0]) - assert '∙ `0.933 USD`' in msg_mock.call_args_list[-1][0][0] + assert '∙ `6.253 USD`' in msg_mock.call_args_list[-1][0][0] assert '*ROI:* All trades' in msg_mock.call_args_list[-1][0][0] - assert ('∙ `0.00006217 BTC (6.20%) (0.62 \N{GREEK CAPITAL LETTER SIGMA}%)`' + assert ('∙ `5.685 USDT (9.45%) (0.57 \N{GREEK CAPITAL LETTER SIGMA}%)`' in msg_mock.call_args_list[-1][0][0]) - assert '∙ `0.933 USD`' in msg_mock.call_args_list[-1][0][0] + assert '∙ `6.253 USD`' in msg_mock.call_args_list[-1][0][0] - assert '*Best Performing:* `ETH/BTC: 6.20%`' in msg_mock.call_args_list[-1][0][0] + assert '*Best Performing:* `ETH/USDT: 9.45%`' in msg_mock.call_args_list[-1][0][0] + assert '*Max Drawdown:*' in msg_mock.call_args_list[-1][0][0] + assert '*Profit factor:*' in msg_mock.call_args_list[-1][0][0] + assert '*Trading volume:* `60 USDT`' in msg_mock.call_args_list[-1][0][0] @pytest.mark.parametrize('is_short', [True, False]) -def test_telegram_stats(default_conf, update, ticker, ticker_sell_up, fee, - limit_buy_order, limit_sell_order, mocker, is_short) -> None: +def test_telegram_stats(default_conf, update, ticker, fee, mocker, is_short) -> None: mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -1350,71 +1242,43 @@ def test_force_enter_no_pair(default_conf, update, mocker) -> None: assert fbuy_mock.call_count == 1 -def test_telegram_performance_handle(default_conf, update, ticker, fee, - limit_buy_order, limit_sell_order, mocker) -> None: +def test_telegram_performance_handle(default_conf_usdt, update, ticker, fee, mocker) -> None: mocker.patch.multiple( 'freqtrade.exchange.Exchange', fetch_ticker=ticker, get_fee=fee, ) - telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf) - patch_get_signal(freqtradebot) + telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf_usdt) # Create some test data - freqtradebot.enter_positions() - trade = Trade.query.first() - assert trade + create_mock_trades_usdt(fee) - # Simulate fulfilled LIMIT_BUY order for trade - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy') - trade.update_trade(oobj) - - # Simulate fulfilled LIMIT_SELL order for trade - oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') - trade.update_trade(oobj) - - trade.close_date = datetime.utcnow() - trade.is_open = False telegram._performance(update=update, context=MagicMock()) assert msg_mock.call_count == 1 assert 'Performance' in msg_mock.call_args_list[0][0][0] - assert 'ETH/BTC\t0.00006217 BTC (6.20%) (1)' in msg_mock.call_args_list[0][0][0] + assert 'XRP/USDT\t9.842 USDT (10.00%) (1)' in msg_mock.call_args_list[0][0][0] def test_telegram_entry_tag_performance_handle( - default_conf, update, ticker, fee, limit_buy_order, limit_sell_order, mocker) -> None: + default_conf_usdt, update, ticker, fee, mocker) -> None: mocker.patch.multiple( 'freqtrade.exchange.Exchange', fetch_ticker=ticker, get_fee=fee, ) - telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf) + telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf_usdt) patch_get_signal(freqtradebot) - # Create some test data - freqtradebot.enter_positions() - trade = Trade.query.first() - assert trade + create_mock_trades_usdt(fee) - # Simulate fulfilled LIMIT_BUY order for trade - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy') - trade.update_trade(oobj) - - trade.enter_tag = "TESTBUY" - # Simulate fulfilled LIMIT_SELL order for trade - oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') - trade.update_trade(oobj) - - trade.close_date = datetime.utcnow() - trade.is_open = False context = MagicMock() telegram._enter_tag_performance(update=update, context=context) assert msg_mock.call_count == 1 assert 'Entry Tag Performance' in msg_mock.call_args_list[0][0][0] - assert 'TESTBUY\t0.00006217 BTC (6.20%) (1)' in msg_mock.call_args_list[0][0][0] + assert 'TEST1\t3.987 USDT (5.00%) (1)' in msg_mock.call_args_list[0][0][0] - context.args = [trade.pair] + context.args = ['XRP/USDT'] telegram._enter_tag_performance(update=update, context=context) assert msg_mock.call_count == 2 @@ -1427,37 +1291,24 @@ def test_telegram_entry_tag_performance_handle( assert "Error" in msg_mock.call_args_list[0][0][0] -def test_telegram_exit_reason_performance_handle(default_conf, update, ticker, fee, - limit_buy_order, limit_sell_order, mocker) -> None: +def test_telegram_exit_reason_performance_handle(default_conf_usdt, update, ticker, fee, + mocker) -> None: mocker.patch.multiple( 'freqtrade.exchange.Exchange', fetch_ticker=ticker, get_fee=fee, ) - telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf) + telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf_usdt) patch_get_signal(freqtradebot) - # Create some test data - freqtradebot.enter_positions() - trade = Trade.query.first() - assert trade - trade.exit_reason = 'TESTSELL' - # Simulate fulfilled LIMIT_BUY order for trade - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy') - trade.update_trade(oobj) + create_mock_trades_usdt(fee) - # Simulate fulfilled LIMIT_SELL order for trade - oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') - trade.update_trade(oobj) - - trade.close_date = datetime.utcnow() - trade.is_open = False context = MagicMock() telegram._exit_reason_performance(update=update, context=context) assert msg_mock.call_count == 1 assert 'Exit Reason Performance' in msg_mock.call_args_list[0][0][0] - assert 'TESTSELL\t0.00006217 BTC (6.20%) (1)' in msg_mock.call_args_list[0][0][0] - context.args = [trade.pair] + assert 'roi\t9.842 USDT (10.00%) (1)' in msg_mock.call_args_list[0][0][0] + context.args = ['XRP/USDT'] telegram._exit_reason_performance(update=update, context=context) assert msg_mock.call_count == 2 @@ -1471,43 +1322,27 @@ def test_telegram_exit_reason_performance_handle(default_conf, update, ticker, f assert "Error" in msg_mock.call_args_list[0][0][0] -def test_telegram_mix_tag_performance_handle(default_conf, update, ticker, fee, - limit_buy_order, limit_sell_order, mocker) -> None: +def test_telegram_mix_tag_performance_handle(default_conf_usdt, update, ticker, fee, + mocker) -> None: mocker.patch.multiple( 'freqtrade.exchange.Exchange', fetch_ticker=ticker, get_fee=fee, ) - telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf) + telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf_usdt) patch_get_signal(freqtradebot) # Create some test data - freqtradebot.enter_positions() - trade = Trade.query.first() - assert trade - - trade.enter_tag = "TESTBUY" - trade.exit_reason = "TESTSELL" - - # Simulate fulfilled LIMIT_BUY order for trade - oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy') - trade.update_trade(oobj) - - # Simulate fulfilled LIMIT_SELL order for trade - oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell') - trade.update_trade(oobj) - - trade.close_date = datetime.utcnow() - trade.is_open = False + create_mock_trades_usdt(fee) context = MagicMock() telegram._mix_tag_performance(update=update, context=context) assert msg_mock.call_count == 1 assert 'Mix Tag Performance' in msg_mock.call_args_list[0][0][0] - assert ('TESTBUY TESTSELL\t0.00006217 BTC (6.20%) (1)' + assert ('TEST3 roi\t9.842 USDT (10.00%) (1)' in msg_mock.call_args_list[0][0][0]) - context.args = [trade.pair] + context.args = ['XRP/USDT'] telegram._mix_tag_performance(update=update, context=context) assert msg_mock.call_count == 2 @@ -1847,7 +1682,7 @@ def test_send_msg_buy_notification(default_conf, mocker, caplog, message_type, leverage_text = f'*Leverage:* `{leverage}`\n' if leverage and leverage != 1.0 else '' assert msg_mock.call_args[0][0] == ( - f'\N{LARGE BLUE CIRCLE} *Binance:* {enter} ETH/BTC (#1)\n' + f'\N{LARGE BLUE CIRCLE} *Binance (dry):* {enter} ETH/BTC (#1)\n' f'*Enter Tag:* `{enter_signal}`\n' '*Amount:* `1333.33333333`\n' f'{leverage_text}' @@ -1887,7 +1722,7 @@ def test_send_msg_buy_cancel_notification(default_conf, mocker, message_type, en 'pair': 'ETH/BTC', 'reason': CANCEL_REASON['TIMEOUT'] }) - assert (msg_mock.call_args[0][0] == '\N{WARNING SIGN} *Binance:* ' + assert (msg_mock.call_args[0][0] == '\N{WARNING SIGN} *Binance (dry):* ' 'Cancelling enter Order for ETH/BTC (#1). ' 'Reason: cancelled due to timeout.') @@ -1949,7 +1784,7 @@ def test_send_msg_entry_fill_notification(default_conf, mocker, message_type, en }) leverage_text = f'*Leverage:* `{leverage}`\n' if leverage != 1.0 else '' assert msg_mock.call_args[0][0] == ( - f'\N{CHECK MARK} *Binance:* {entered}ed ETH/BTC (#1)\n' + f'\N{CHECK MARK} *Binance (dry):* {entered}ed ETH/BTC (#1)\n' f'*Enter Tag:* `{enter_signal}`\n' '*Amount:* `1333.33333333`\n' f"{leverage_text}" @@ -1987,7 +1822,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None: 'close_date': arrow.utcnow(), }) assert msg_mock.call_args[0][0] == ( - '\N{WARNING SIGN} *Binance:* Exiting KEY/ETH (#1)\n' + '\N{WARNING SIGN} *Binance (dry):* Exiting KEY/ETH (#1)\n' '*Unrealized Profit:* `-57.41% (loss: -0.05746268 ETH / -24.812 USD)`\n' '*Enter Tag:* `buy_signal1`\n' '*Exit Reason:* `stop_loss`\n' @@ -2021,7 +1856,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None: 'close_date': arrow.utcnow(), }) assert msg_mock.call_args[0][0] == ( - '\N{WARNING SIGN} *Binance:* Exiting KEY/ETH (#1)\n' + '\N{WARNING SIGN} *Binance (dry):* Exiting KEY/ETH (#1)\n' '*Unrealized Profit:* `-57.41%`\n' '*Enter Tag:* `buy_signal1`\n' '*Exit Reason:* `stop_loss`\n' @@ -2050,10 +1885,12 @@ def test_send_msg_sell_cancel_notification(default_conf, mocker) -> None: 'reason': 'Cancelled on exchange' }) assert msg_mock.call_args[0][0] == ( - '\N{WARNING SIGN} *Binance:* Cancelling exit Order for KEY/ETH (#1).' + '\N{WARNING SIGN} *Binance (dry):* Cancelling exit Order for KEY/ETH (#1).' ' Reason: Cancelled on exchange.') msg_mock.reset_mock() + # Test with live mode (no dry appendix) + telegram._config['dry_run'] = False telegram.send_msg({ 'type': RPCMessageType.EXIT_CANCEL, 'trade_id': 1, @@ -2102,7 +1939,7 @@ def test_send_msg_sell_fill_notification(default_conf, mocker, direction, leverage_text = f'*Leverage:* `{leverage}`\n' if leverage and leverage != 1.0 else '' assert msg_mock.call_args[0][0] == ( - '\N{WARNING SIGN} *Binance:* Exited KEY/ETH (#1)\n' + '\N{WARNING SIGN} *Binance (dry):* Exited KEY/ETH (#1)\n' '*Profit:* `-57.41%`\n' f'*Enter Tag:* `{enter_signal}`\n' '*Exit Reason:* `stop_loss`\n' @@ -2158,6 +1995,7 @@ def test_send_msg_unknown_type(default_conf, mocker) -> None: def test_send_msg_buy_notification_no_fiat( default_conf, mocker, message_type, enter, enter_signal, leverage) -> None: del default_conf['fiat_display_currency'] + default_conf['dry_run'] = False telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf) telegram.send_msg({ @@ -2227,7 +2065,7 @@ def test_send_msg_sell_notification_no_fiat( leverage_text = f'*Leverage:* `{leverage}`\n' if leverage and leverage != 1.0 else '' assert msg_mock.call_args[0][0] == ( - '\N{WARNING SIGN} *Binance:* Exiting KEY/ETH (#1)\n' + '\N{WARNING SIGN} *Binance (dry):* Exiting KEY/ETH (#1)\n' '*Unrealized Profit:* `-57.41%`\n' f'*Enter Tag:* `{enter_signal}`\n' '*Exit Reason:* `stop_loss`\n' diff --git a/tests/rpc/test_rpc_webhook.py b/tests/rpc/test_rpc_webhook.py index db357f80f..4d65b4966 100644 --- a/tests/rpc/test_rpc_webhook.py +++ b/tests/rpc/test_rpc_webhook.py @@ -1,5 +1,6 @@ # pragma pylint: disable=missing-docstring, C0103, protected-access +from datetime import datetime, timedelta from unittest.mock import MagicMock import pytest @@ -7,6 +8,7 @@ from requests import RequestException from freqtrade.enums import ExitType, RPCMessageType from freqtrade.rpc import RPC +from freqtrade.rpc.discord import Discord from freqtrade.rpc.webhook import Webhook from tests.conftest import get_patched_freqtradebot, log_has @@ -406,3 +408,42 @@ def test__send_msg_with_raw_format(default_conf, mocker, caplog): webhook._send_msg(msg) assert post.call_args[1] == {'data': msg['data'], 'headers': {'Content-Type': 'text/plain'}} + + +def test_send_msg_discord(default_conf, mocker): + + default_conf["discord"] = { + 'enabled': True, + 'webhook_url': "https://webhookurl..." + } + msg_mock = MagicMock() + mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) + discord = Discord(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf) + + msg = { + 'type': RPCMessageType.EXIT_FILL, + 'trade_id': 1, + 'exchange': 'Binance', + 'pair': 'ETH/BTC', + 'direction': 'Long', + 'gain': "profit", + 'close_rate': 0.005, + 'amount': 0.8, + 'order_type': 'limit', + 'open_date': datetime.now() - timedelta(days=1), + 'close_date': datetime.now(), + 'open_rate': 0.004, + 'current_rate': 0.005, + 'profit_amount': 0.001, + 'profit_ratio': 0.20, + 'stake_currency': 'BTC', + 'enter_tag': 'enter_tagggg', + 'exit_reason': ExitType.STOP_LOSS.value, + } + discord.send_msg(msg=msg) + + assert msg_mock.call_count == 1 + assert 'embeds' in msg_mock.call_args_list[0][0][0] + assert 'title' in msg_mock.call_args_list[0][0][0]['embeds'][0] + assert 'color' in msg_mock.call_args_list[0][0][0]['embeds'][0] + assert 'fields' in msg_mock.call_args_list[0][0][0]['embeds'][0] diff --git a/tests/strategy/strats/hyperoptable_strategy.py b/tests/strategy/strats/hyperoptable_strategy.py index f4dcf1a05..28ecf617a 100644 --- a/tests/strategy/strats/hyperoptable_strategy.py +++ b/tests/strategy/strats/hyperoptable_strategy.py @@ -27,7 +27,6 @@ class HyperoptableStrategy(StrategyTestV2): 'sell_minusdi': 0.4 } - buy_rsi = IntParameter([0, 50], default=30, space='buy') buy_plusdi = RealParameter(low=0, high=1, default=0.5, space='buy') sell_rsi = IntParameter(low=50, high=100, default=70, space='sell') sell_minusdi = DecimalParameter(low=0, high=1, default=0.5001, decimals=3, space='sell', @@ -45,6 +44,12 @@ class HyperoptableStrategy(StrategyTestV2): }) return prot + def bot_start(self, **kwargs) -> None: + """ + Parameters can also be defined here ... + """ + self.buy_rsi = IntParameter([0, 50], default=30, space='buy') + def informative_pairs(self): """ Define additional, informative pair/interval combinations to be cached from the exchange. diff --git a/tests/strategy/strats/strategy_test_v2.py b/tests/strategy/strats/strategy_test_v2.py index 85ff856e1..9e1c47575 100644 --- a/tests/strategy/strats/strategy_test_v2.py +++ b/tests/strategy/strats/strategy_test_v2.py @@ -1,12 +1,9 @@ # pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement -from datetime import datetime - import talib.abstract as ta from pandas import DataFrame import freqtrade.vendor.qtpylib.indicators as qtpylib -from freqtrade.persistence import Trade from freqtrade.strategy import IStrategy @@ -149,12 +146,3 @@ class StrategyTestV2(IStrategy): ), 'sell'] = 1 return dataframe - - def adjust_trade_position(self, trade: Trade, current_time: datetime, current_rate: float, - current_profit: float, min_stake: float, max_stake: float, **kwargs): - - if current_profit < -0.0075: - orders = trade.select_filled_orders('buy') - return round(orders[0].cost, 0) - - return None diff --git a/tests/strategy/strats/strategy_test_v3.py b/tests/strategy/strats/strategy_test_v3.py index df83d3663..2c7ccbdf2 100644 --- a/tests/strategy/strats/strategy_test_v3.py +++ b/tests/strategy/strats/strategy_test_v3.py @@ -1,6 +1,7 @@ # pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement from datetime import datetime +from typing import Optional import talib.abstract as ta from pandas import DataFrame @@ -177,15 +178,16 @@ class StrategyTestV3(IStrategy): return dataframe def leverage(self, pair: str, current_time: datetime, current_rate: float, - proposed_leverage: float, max_leverage: float, side: str, - **kwargs) -> float: + proposed_leverage: float, max_leverage: float, entry_tag: Optional[str], + side: str, **kwargs) -> float: # Return 3.0 in all cases. # Bot-logic must make sure it's an allowed leverage and eventually adjust accordingly. return 3.0 def adjust_trade_position(self, trade: Trade, current_time: datetime, current_rate: float, - current_profit: float, min_stake: float, max_stake: float, **kwargs): + current_profit: float, + min_stake: Optional[float], max_stake: float, **kwargs): if current_profit < -0.0075: orders = trade.select_filled_orders(trade.entry_side) diff --git a/tests/strategy/strats/strategy_test_v3_analysis.py b/tests/strategy/strats/strategy_test_v3_analysis.py new file mode 100644 index 000000000..290fef156 --- /dev/null +++ b/tests/strategy/strats/strategy_test_v3_analysis.py @@ -0,0 +1,175 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +import talib.abstract as ta +from pandas import DataFrame + +import freqtrade.vendor.qtpylib.indicators as qtpylib +from freqtrade.strategy import (BooleanParameter, DecimalParameter, IntParameter, IStrategy, + RealParameter) + + +class StrategyTestV3Analysis(IStrategy): + """ + Strategy used by tests freqtrade bot. + Please do not modify this strategy, it's intended for internal use only. + Please look at the SampleStrategy in the user_data/strategy directory + or strategy repository https://github.com/freqtrade/freqtrade-strategies + for samples and inspiration. + """ + INTERFACE_VERSION = 3 + + # Minimal ROI designed for the strategy + minimal_roi = { + "40": 0.0, + "30": 0.01, + "20": 0.02, + "0": 0.04 + } + + # Optimal stoploss designed for the strategy + stoploss = -0.10 + + # Optimal timeframe for the strategy + timeframe = '5m' + + # Optional order type mapping + order_types = { + 'entry': 'limit', + 'exit': 'limit', + 'stoploss': 'limit', + 'stoploss_on_exchange': False + } + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 20 + + # Optional time in force for orders + order_time_in_force = { + 'entry': 'gtc', + 'exit': 'gtc', + } + + buy_params = { + 'buy_rsi': 35, + # Intentionally not specified, so "default" is tested + # 'buy_plusdi': 0.4 + } + + sell_params = { + 'sell_rsi': 74, + 'sell_minusdi': 0.4 + } + + buy_rsi = IntParameter([0, 50], default=30, space='buy') + buy_plusdi = RealParameter(low=0, high=1, default=0.5, space='buy') + sell_rsi = IntParameter(low=50, high=100, default=70, space='sell') + sell_minusdi = DecimalParameter(low=0, high=1, default=0.5001, decimals=3, space='sell', + load=False) + protection_enabled = BooleanParameter(default=True) + protection_cooldown_lookback = IntParameter([0, 50], default=30) + + # TODO: Can this work with protection tests? (replace HyperoptableStrategy implicitly ... ) + # @property + # def protections(self): + # prot = [] + # if self.protection_enabled.value: + # prot.append({ + # "method": "CooldownPeriod", + # "stop_duration_candles": self.protection_cooldown_lookback.value + # }) + # return prot + + bot_started = False + + def bot_start(self): + self.bot_started = True + + def informative_pairs(self): + + return [] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + + # Momentum Indicator + # ------------------------------------ + + # ADX + dataframe['adx'] = ta.ADX(dataframe) + + # MACD + macd = ta.MACD(dataframe) + dataframe['macd'] = macd['macd'] + dataframe['macdsignal'] = macd['macdsignal'] + dataframe['macdhist'] = macd['macdhist'] + + # Minus Directional Indicator / Movement + dataframe['minus_di'] = ta.MINUS_DI(dataframe) + + # Plus Directional Indicator / Movement + dataframe['plus_di'] = ta.PLUS_DI(dataframe) + + # RSI + dataframe['rsi'] = ta.RSI(dataframe) + + # Stoch fast + stoch_fast = ta.STOCHF(dataframe) + dataframe['fastd'] = stoch_fast['fastd'] + dataframe['fastk'] = stoch_fast['fastk'] + + # Bollinger bands + bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) + dataframe['bb_lowerband'] = bollinger['lower'] + dataframe['bb_middleband'] = bollinger['mid'] + dataframe['bb_upperband'] = bollinger['upper'] + + # EMA - Exponential Moving Average + dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10) + + return dataframe + + def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + + dataframe.loc[ + ( + (dataframe['rsi'] < self.buy_rsi.value) & + (dataframe['fastd'] < 35) & + (dataframe['adx'] > 30) & + (dataframe['plus_di'] > self.buy_plusdi.value) + ) | + ( + (dataframe['adx'] > 65) & + (dataframe['plus_di'] > self.buy_plusdi.value) + ), + ['enter_long', 'enter_tag']] = 1, 'enter_tag_long' + + dataframe.loc[ + ( + qtpylib.crossed_below(dataframe['rsi'], self.sell_rsi.value) + ), + ['enter_short', 'enter_tag']] = 1, 'enter_tag_short' + + return dataframe + + def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + dataframe.loc[ + ( + ( + (qtpylib.crossed_above(dataframe['rsi'], self.sell_rsi.value)) | + (qtpylib.crossed_above(dataframe['fastd'], 70)) + ) & + (dataframe['adx'] > 10) & + (dataframe['minus_di'] > 0) + ) | + ( + (dataframe['adx'] > 70) & + (dataframe['minus_di'] > self.sell_minusdi.value) + ), + ['exit_long', 'exit_tag']] = 1, 'exit_tag_long' + + dataframe.loc[ + ( + qtpylib.crossed_above(dataframe['rsi'], self.buy_rsi.value) + ), + ['exit_long', 'exit_tag']] = 1, 'exit_tag_short' + + return dataframe diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index 6e57a3182..dca87e724 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -16,10 +16,12 @@ from freqtrade.exceptions import OperationalException, StrategyError from freqtrade.optimize.space import SKDecimal from freqtrade.persistence import PairLocks, Trade from freqtrade.resolvers import StrategyResolver -from freqtrade.strategy.hyper import (BaseParameter, BooleanParameter, CategoricalParameter, - DecimalParameter, IntParameter, RealParameter) +from freqtrade.strategy.hyper import detect_parameters +from freqtrade.strategy.parameters import (BaseParameter, BooleanParameter, CategoricalParameter, + DecimalParameter, IntParameter, RealParameter) from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper -from tests.conftest import CURRENT_TEST_STRATEGY, TRADE_SIDES, log_has, log_has_re +from tests.conftest import (CURRENT_TEST_STRATEGY, TRADE_SIDES, create_mock_trades, log_has, + log_has_re) from .strats.strategy_test_v3 import StrategyTestV3 @@ -495,37 +497,113 @@ def test_custom_exit(default_conf, fee, caplog) -> None: enter=False, exit_=False, low=None, high=None) - assert res.exit_flag is False - assert res.exit_type == ExitType.NONE + assert res == [] strategy.custom_exit = MagicMock(return_value=True) res = strategy.should_exit(trade, 1, now, enter=False, exit_=False, low=None, high=None) - assert res.exit_flag is True - assert res.exit_type == ExitType.CUSTOM_EXIT - assert res.exit_reason == 'custom_exit' + assert res[0].exit_flag is True + assert res[0].exit_type == ExitType.CUSTOM_EXIT + assert res[0].exit_reason == 'custom_exit' strategy.custom_exit = MagicMock(return_value='hello world') res = strategy.should_exit(trade, 1, now, enter=False, exit_=False, low=None, high=None) - assert res.exit_type == ExitType.CUSTOM_EXIT - assert res.exit_flag is True - assert res.exit_reason == 'hello world' + assert res[0].exit_type == ExitType.CUSTOM_EXIT + assert res[0].exit_flag is True + assert res[0].exit_reason == 'hello world' caplog.clear() strategy.custom_exit = MagicMock(return_value='h' * 100) res = strategy.should_exit(trade, 1, now, enter=False, exit_=False, low=None, high=None) - assert res.exit_type == ExitType.CUSTOM_EXIT - assert res.exit_flag is True - assert res.exit_reason == 'h' * 64 + assert res[0].exit_type == ExitType.CUSTOM_EXIT + assert res[0].exit_flag is True + assert res[0].exit_reason == 'h' * 64 assert log_has_re('Custom exit reason returned from custom_exit is too long.*', caplog) +def test_should_sell(default_conf, fee) -> None: + + strategy = StrategyResolver.load_strategy(default_conf) + trade = Trade( + pair='ETH/BTC', + stake_amount=0.01, + amount=1, + open_date=arrow.utcnow().shift(hours=-1).datetime, + fee_open=fee.return_value, + fee_close=fee.return_value, + exchange='binance', + open_rate=1, + ) + now = arrow.utcnow().datetime + res = strategy.should_exit(trade, 1, now, + enter=False, exit_=False, + low=None, high=None) + + assert res == [] + strategy.min_roi_reached = MagicMock(return_value=True) + + res = strategy.should_exit(trade, 1, now, + enter=False, exit_=False, + low=None, high=None) + assert len(res) == 1 + assert res == [ExitCheckTuple(exit_type=ExitType.ROI)] + + strategy.min_roi_reached = MagicMock(return_value=True) + strategy.stop_loss_reached = MagicMock( + return_value=ExitCheckTuple(exit_type=ExitType.STOP_LOSS)) + + res = strategy.should_exit(trade, 1, now, + enter=False, exit_=False, + low=None, high=None) + assert len(res) == 2 + assert res == [ + ExitCheckTuple(exit_type=ExitType.STOP_LOSS), + ExitCheckTuple(exit_type=ExitType.ROI), + ] + + strategy.custom_exit = MagicMock(return_value='hello world') + # custom-exit and exit-signal is first + res = strategy.should_exit(trade, 1, now, + enter=False, exit_=False, + low=None, high=None) + assert len(res) == 3 + assert res == [ + ExitCheckTuple(exit_type=ExitType.CUSTOM_EXIT, exit_reason='hello world'), + ExitCheckTuple(exit_type=ExitType.STOP_LOSS), + ExitCheckTuple(exit_type=ExitType.ROI), + ] + + strategy.stop_loss_reached = MagicMock( + return_value=ExitCheckTuple(exit_type=ExitType.TRAILING_STOP_LOSS)) + # Regular exit signal + res = strategy.should_exit(trade, 1, now, + enter=False, exit_=True, + low=None, high=None) + assert len(res) == 3 + assert res == [ + ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL), + ExitCheckTuple(exit_type=ExitType.ROI), + ExitCheckTuple(exit_type=ExitType.TRAILING_STOP_LOSS), + ] + + # Regular exit signal, no ROI + strategy.min_roi_reached = MagicMock(return_value=False) + res = strategy.should_exit(trade, 1, now, + enter=False, exit_=True, + low=None, high=None) + assert len(res) == 2 + assert res == [ + ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL), + ExitCheckTuple(exit_type=ExitType.TRAILING_STOP_LOSS), + ] + + @pytest.mark.parametrize('side', TRADE_SIDES) def test_leverage_callback(default_conf, side) -> None: default_conf['strategy'] = 'StrategyTestV2' @@ -538,6 +616,7 @@ def test_leverage_callback(default_conf, side) -> None: proposed_leverage=1.0, max_leverage=5.0, side=side, + entry_tag=None, ) == 1 default_conf['strategy'] = CURRENT_TEST_STRATEGY @@ -549,6 +628,7 @@ def test_leverage_callback(default_conf, side) -> None: proposed_leverage=1.0, max_leverage=5.0, side=side, + entry_tag='entry_tag_test', ) == 3 @@ -733,6 +813,28 @@ def test_strategy_safe_wrapper(value): assert ret == value +@pytest.mark.usefixtures("init_persistence") +def test_strategy_safe_wrapper_trade_copy(fee): + create_mock_trades(fee) + + def working_method(trade): + assert len(trade.orders) > 0 + assert trade.orders + trade.orders = [] + assert len(trade.orders) == 0 + return trade + + trade = Trade.get_open_trades()[0] + # Don't assert anything before strategy_wrapper. + # This ensures that relationship loading works correctly. + ret = strategy_safe_wrapper(working_method, message='DeadBeef')(trade=trade) + assert isinstance(ret, Trade) + assert id(trade) != id(ret) + # Did not modify the original order + assert len(trade.orders) > 0 + assert len(ret.orders) == 0 + + def test_hyperopt_parameters(): from skopt.space import Categorical, Integer, Real with pytest.raises(OperationalException, match=r"Name is determined.*"): @@ -817,7 +919,7 @@ def test_auto_hyperopt_interface(default_conf): default_conf.update({'strategy': 'HyperoptableStrategy'}) PairLocks.timeframe = default_conf['timeframe'] strategy = StrategyResolver.load_strategy(default_conf) - + strategy.ft_bot_start() with pytest.raises(OperationalException): next(strategy.enumerate_parameters('deadBeef')) @@ -832,15 +934,18 @@ def test_auto_hyperopt_interface(default_conf): assert strategy.sell_minusdi.value == 0.5 all_params = strategy.detect_all_parameters() assert isinstance(all_params, dict) - assert len(all_params['buy']) == 2 + # Only one buy param at class level + assert len(all_params['buy']) == 1 + # Running detect params at instance level reveals both parameters. + assert len(list(detect_parameters(strategy, 'buy'))) == 2 assert len(all_params['sell']) == 2 # Number of Hyperoptable parameters - assert all_params['count'] == 6 + assert all_params['count'] == 5 strategy.__class__.sell_rsi = IntParameter([0, 10], default=5, space='buy') with pytest.raises(OperationalException, match=r"Inconclusive parameter.*"): - [x for x in strategy.detect_parameters('sell')] + [x for x in detect_parameters(strategy, 'sell')] def test_auto_hyperopt_interface_loadparams(default_conf, mocker, caplog): diff --git a/tests/strategy/test_strategy_loading.py b/tests/strategy/test_strategy_loading.py index 3ed1eb0ce..666ae2b05 100644 --- a/tests/strategy/test_strategy_loading.py +++ b/tests/strategy/test_strategy_loading.py @@ -34,7 +34,7 @@ def test_search_all_strategies_no_failed(): directory = Path(__file__).parent / "strats" strategies = StrategyResolver.search_all_objects(directory, enum_failed=False) assert isinstance(strategies, list) - assert len(strategies) == 5 + assert len(strategies) == 6 assert isinstance(strategies[0], dict) @@ -42,10 +42,10 @@ def test_search_all_strategies_with_failed(): directory = Path(__file__).parent / "strats" strategies = StrategyResolver.search_all_objects(directory, enum_failed=True) assert isinstance(strategies, list) - assert len(strategies) == 6 + assert len(strategies) == 7 # with enum_failed=True search_all_objects() shall find 2 good strategies # and 1 which fails to load - assert len([x for x in strategies if x['class'] is not None]) == 5 + assert len([x for x in strategies if x['class'] is not None]) == 6 assert len([x for x in strategies if x['class'] is None]) == 1 @@ -224,12 +224,12 @@ def test_strategy_override_process_only_new_candles(caplog, default_conf): default_conf.update({ 'strategy': CURRENT_TEST_STRATEGY, - 'process_only_new_candles': True + 'process_only_new_candles': False }) strategy = StrategyResolver.load_strategy(default_conf) - assert strategy.process_only_new_candles - assert log_has("Override strategy 'process_only_new_candles' with value in config file: True.", + assert not strategy.process_only_new_candles + assert log_has("Override strategy 'process_only_new_candles' with value in config file: False.", caplog) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index e19d5f36a..4f3d5f667 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -210,13 +210,14 @@ def test_edge_overrides_stoploss(limit_order, fee, caplog, mocker, # # mocking the ticker: price is falling ... enter_price = limit_order['buy']['price'] + ticker_val = { + 'bid': enter_price, + 'ask': enter_price, + 'last': enter_price, + } mocker.patch.multiple( 'freqtrade.exchange.Exchange', - fetch_ticker=MagicMock(return_value={ - 'bid': enter_price * buy_price_mult, - 'ask': enter_price * buy_price_mult, - 'last': enter_price * buy_price_mult, - }), + fetch_ticker=MagicMock(return_value=ticker_val), get_fee=fee, ) ############################################# @@ -229,9 +230,12 @@ def test_edge_overrides_stoploss(limit_order, fee, caplog, mocker, freqtrade.enter_positions() trade = Trade.query.first() caplog.clear() - oobj = Order.parse_from_ccxt_object(limit_order['buy'], 'ADA/USDT', 'buy') - trade.update_trade(oobj) ############################################# + ticker_val.update({ + 'bid': enter_price * buy_price_mult, + 'ask': enter_price * buy_price_mult, + 'last': enter_price * buy_price_mult, + }) # stoploss shoud be hit assert freqtrade.handle_trade(trade) is not ignore_strat_sl @@ -1775,9 +1779,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, 'type': 'stop_loss_limit', 'price': 3, 'average': 2, - 'info': { - 'stopPrice': '2.178' - } + 'stopPrice': '2.178' }) mocker.patch('freqtrade.exchange.Exchange.fetch_stoploss_order', stoploss_order_hanging) @@ -2149,7 +2151,7 @@ def test_handle_trade( assert trade.close_rate == 2.0 if is_short else 2.2 assert trade.close_profit == close_profit - assert trade.calc_profit() == 5.685 + assert trade.calc_profit(trade.close_rate) == 5.685 assert trade.close_date is not None assert trade.exit_reason == 'sell_signal1' @@ -2574,6 +2576,7 @@ def test_check_handle_cancelled_buy( get_fee=fee ) freqtrade = FreqtradeBot(default_conf_usdt) + open_trade.orders = [] open_trade.is_short = is_short Trade.query.session.add(open_trade) @@ -2956,6 +2959,7 @@ def test_handle_cancel_enter(mocker, caplog, default_conf_usdt, limit_order, is_ freqtrade = FreqtradeBot(default_conf_usdt) freqtrade._notify_enter_cancel = MagicMock() + # TODO: Convert to real trade trade = MagicMock() trade.pair = 'LTC/USDT' trade.open_rate = 200 @@ -2963,6 +2967,7 @@ def test_handle_cancel_enter(mocker, caplog, default_conf_usdt, limit_order, is_ trade.entry_side = "buy" l_order['filled'] = 0.0 l_order['status'] = 'open' + trade.nr_of_successful_entries = 0 reason = CANCEL_REASON['TIMEOUT'] assert freqtrade.handle_cancel_enter(trade, l_order, reason) assert cancel_order_mock.call_count == 1 @@ -3005,7 +3010,9 @@ def test_handle_cancel_enter_exchanges(mocker, caplog, default_conf_usdt, is_sho freqtrade = FreqtradeBot(default_conf_usdt) reason = CANCEL_REASON['TIMEOUT'] + # TODO: Convert to real trade trade = MagicMock() + trade.nr_of_successful_entries = 0 trade.pair = 'LTC/ETH' trade.entry_side = "sell" if is_short else "buy" assert freqtrade.handle_cancel_enter(trade, limit_buy_order_canceled_empty, reason) @@ -3038,12 +3045,14 @@ def test_handle_cancel_enter_corder_empty(mocker, default_conf_usdt, limit_order freqtrade = FreqtradeBot(default_conf_usdt) freqtrade._notify_enter_cancel = MagicMock() - + # TODO: Convert to real trade trade = MagicMock() trade.pair = 'LTC/USDT' trade.entry_side = "buy" trade.open_rate = 200 trade.entry_side = "buy" + trade.open_order_id = "open_order_noop" + trade.nr_of_successful_entries = 0 l_order['filled'] = 0.0 l_order['status'] = 'open' reason = CANCEL_REASON['TIMEOUT'] @@ -3581,7 +3590,7 @@ def test_may_execute_trade_exit_after_stoploss_on_exchange_hit( assert rpc_mock.call_count == 3 assert rpc_mock.call_args_list[0][0][0]['type'] == RPCMessageType.ENTRY assert rpc_mock.call_args_list[1][0][0]['type'] == RPCMessageType.ENTRY_FILL - assert rpc_mock.call_args_list[2][0][0]['type'] == RPCMessageType.EXIT + assert rpc_mock.call_args_list[2][0][0]['type'] == RPCMessageType.EXIT_FILL @pytest.mark.parametrize( @@ -3766,6 +3775,7 @@ def test_exit_profit_only( trade = Trade.query.first() assert trade.is_short == is_short oobj = Order.parse_from_ccxt_object(limit_order[eside], limit_order[eside]['symbol'], eside) + trade.update_order(limit_order[eside]) trade.update_trade(oobj) freqtrade.wallets.update() if profit_only: @@ -4054,6 +4064,7 @@ def test_trailing_stop_loss_positive( trade = Trade.query.first() assert trade.is_short == is_short oobj = Order.parse_from_ccxt_object(limit_order[eside], limit_order[eside]['symbol'], eside) + trade.update_order(limit_order[eside]) trade.update_trade(oobj) caplog.set_level(logging.DEBUG) # stop-loss not reached @@ -4786,9 +4797,6 @@ def test_startup_update_open_orders(mocker, default_conf_usdt, fee, caplog, is_s freqtrade.config['dry_run'] = False freqtrade.startup_update_open_orders() - assert log_has_re(r"Error updating Order .*", caplog) - caplog.clear() - assert len(Order.get_open_orders()) == 3 matching_buy_order = mock_order_4(is_short=is_short) matching_buy_order.update({ @@ -4799,6 +4807,20 @@ def test_startup_update_open_orders(mocker, default_conf_usdt, fee, caplog, is_s # Only stoploss and sell orders are kept open assert len(Order.get_open_orders()) == 2 + caplog.clear() + mocker.patch('freqtrade.exchange.Exchange.fetch_order', side_effect=ExchangeError) + freqtrade.startup_update_open_orders() + assert log_has_re(r"Error updating Order .*", caplog) + + mocker.patch('freqtrade.exchange.Exchange.fetch_order', side_effect=InvalidOrderException) + hto_mock = mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_timedout_order') + # Orders which are no longer found after X days should be assumed as canceled. + freqtrade.startup_update_open_orders() + assert log_has_re(r"Order is older than \d days.*", caplog) + assert hto_mock.call_count == 2 + assert hto_mock.call_args_list[0][0][0]['status'] == 'canceled' + assert hto_mock.call_args_list[1][0][0]['status'] == 'canceled' + @pytest.mark.usefixtures("init_persistence") @pytest.mark.parametrize("is_short", [False, True]) diff --git a/tests/test_integration.py b/tests/test_integration.py index d2ad8c981..83f54becb 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -52,8 +52,8 @@ def test_may_execute_exit_stoploss_on_exchange_multi(default_conf, ticker, fee, side_effect=[stoploss_order_closed, stoploss_order_open, stoploss_order_open]) # Sell 3rd trade (not called for the first trade) should_sell_mock = MagicMock(side_effect=[ - ExitCheckTuple(exit_type=ExitType.NONE), - ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL)] + [], + [ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL)]] ) cancel_order_mock = MagicMock() mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss) @@ -160,11 +160,11 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, mocker, balance_rati _notify_exit=MagicMock(), ) should_sell_mock = MagicMock(side_effect=[ - ExitCheckTuple(exit_type=ExitType.NONE), - ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL), - ExitCheckTuple(exit_type=ExitType.NONE), - ExitCheckTuple(exit_type=ExitType.NONE), - ExitCheckTuple(exit_type=ExitType.NONE)] + [], + [ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL)], + [], + [], + []] ) mocker.patch("freqtrade.strategy.interface.IStrategy.should_exit", should_sell_mock) diff --git a/tests/test_persistence.py b/tests/test_persistence.py index d84415938..c52e06c82 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -13,7 +13,7 @@ from sqlalchemy import create_engine, text from freqtrade import constants from freqtrade.enums import TradingMode from freqtrade.exceptions import DependencyException, OperationalException -from freqtrade.persistence import LocalTrade, Order, Trade, clean_dry_run_db, init_db +from freqtrade.persistence import LocalTrade, Order, Trade, init_db from freqtrade.persistence.migrations import get_last_sequence_ids, set_sequence_ids from freqtrade.persistence.models import PairLock from tests.conftest import create_mock_trades, create_mock_trades_with_leverage, log_has, log_has_re @@ -24,7 +24,7 @@ spot, margin, futures = TradingMode.SPOT, TradingMode.MARGIN, TradingMode.FUTURE def test_init_create_session(default_conf): # Check if init create a session - init_db(default_conf['db_url'], default_conf['dry_run']) + init_db(default_conf['db_url']) assert hasattr(Trade, '_session') assert 'scoped_session' in type(Trade._session).__name__ @@ -36,7 +36,7 @@ def test_init_custom_db_url(default_conf, tmpdir): default_conf.update({'db_url': f'sqlite:///{filename}'}) - init_db(default_conf['db_url'], default_conf['dry_run']) + init_db(default_conf['db_url']) assert Path(filename).is_file() r = Trade._session.execute(text("PRAGMA journal_mode")) assert r.first() == ('wal',) @@ -45,10 +45,10 @@ def test_init_custom_db_url(default_conf, tmpdir): def test_init_invalid_db_url(): # Update path to a value other than default, but still in-memory with pytest.raises(OperationalException, match=r'.*no valid database URL*'): - init_db('unknown:///some.url', True) + init_db('unknown:///some.url') with pytest.raises(OperationalException, match=r'Bad db-url.*For in-memory database, pl.*'): - init_db('sqlite:///', True) + init_db('sqlite:///') def test_init_prod_db(default_conf, mocker): @@ -57,7 +57,7 @@ def test_init_prod_db(default_conf, mocker): create_engine_mock = mocker.patch('freqtrade.persistence.models.create_engine', MagicMock()) - init_db(default_conf['db_url'], default_conf['dry_run']) + init_db(default_conf['db_url']) assert create_engine_mock.call_count == 1 assert create_engine_mock.mock_calls[0][1][0] == 'sqlite:///tradesv3.sqlite' @@ -70,7 +70,7 @@ def test_init_dryrun_db(default_conf, tmpdir): 'db_url': f'sqlite:///{filename}' }) - init_db(default_conf['db_url'], default_conf['dry_run']) + init_db(default_conf['db_url']) assert Path(filename).is_file() @@ -606,9 +606,9 @@ def test_calc_open_close_trade_price( trade.close_rate = 2.2 trade.recalc_open_trade_value() assert isclose(trade._calc_open_trade_value(), open_value) - assert isclose(trade.calc_close_trade_value(), close_value) - assert isclose(trade.calc_profit(), round(profit, 8)) - assert pytest.approx(trade.calc_profit_ratio()) == profit_ratio + assert isclose(trade.calc_close_trade_value(trade.close_rate), close_value) + assert isclose(trade.calc_profit(trade.close_rate), round(profit, 8)) + assert pytest.approx(trade.calc_profit_ratio(trade.close_rate)) == profit_ratio @pytest.mark.usefixtures("init_persistence") @@ -660,7 +660,7 @@ def test_calc_close_trade_price_exception(limit_buy_order_usdt, fee): trade.open_order_id = 'something' oobj = Order.parse_from_ccxt_object(limit_buy_order_usdt, 'ADA/USDT', 'buy') trade.update_trade(oobj) - assert trade.calc_close_trade_value() == 0.0 + assert trade.calc_close_trade_value(trade.close_rate) == 0.0 @pytest.mark.usefixtures("init_persistence") @@ -813,7 +813,7 @@ def test_calc_close_trade_price( funding_fees=funding_fees ) trade.open_order_id = 'close_trade' - assert round(trade.calc_close_trade_value(rate=close_rate, fee=fee_rate), 8) == result + assert round(trade.calc_close_trade_value(rate=close_rate), 8) == result @pytest.mark.parametrize( @@ -884,6 +884,17 @@ def test_calc_close_trade_price( ('binance', False, 3, 2.2, 0.0025, 4.684999, 0.23366583, futures, -1), ('binance', True, 1, 2.2, 0.0025, -7.315, -0.12222222, futures, -1), ('binance', True, 3, 2.2, 0.0025, -7.315, -0.36666666, futures, -1), + + # FUTURES, funding_fee=0 + ('binance', False, 1, 2.1, 0.0025, 2.6925, 0.04476309, futures, 0), + ('binance', False, 3, 2.1, 0.0025, 2.6925, 0.13428928, futures, 0), + ('binance', True, 1, 2.1, 0.0025, -3.3074999, -0.05526316, futures, 0), + ('binance', True, 3, 2.1, 0.0025, -3.3074999, -0.16578947, futures, 0), + + ('binance', False, 1, 1.9, 0.0025, -3.2925, -0.05473815, futures, 0), + ('binance', False, 3, 1.9, 0.0025, -3.2925, -0.16421446, futures, 0), + ('binance', True, 1, 1.9, 0.0025, 2.7075, 0.0452381, futures, 0), + ('binance', True, 3, 1.9, 0.0025, 2.7075, 0.13571429, futures, 0), ]) @pytest.mark.usefixtures("init_persistence") def test_calc_profit( @@ -1129,56 +1140,6 @@ def test_calc_profit( assert pytest.approx(trade.calc_profit_ratio(rate=close_rate)) == round(profit_ratio, 8) -@pytest.mark.usefixtures("init_persistence") -def test_clean_dry_run_db(default_conf, fee): - - # Simulate dry_run entries - trade = Trade( - pair='ADA/USDT', - stake_amount=0.001, - amount=123.0, - fee_open=fee.return_value, - fee_close=fee.return_value, - open_rate=0.123, - exchange='binance', - open_order_id='dry_run_buy_12345' - ) - Trade.query.session.add(trade) - - trade = Trade( - pair='ETC/BTC', - stake_amount=0.001, - amount=123.0, - fee_open=fee.return_value, - fee_close=fee.return_value, - open_rate=0.123, - exchange='binance', - open_order_id='dry_run_sell_12345' - ) - Trade.query.session.add(trade) - - # Simulate prod entry - trade = Trade( - pair='ETC/BTC', - stake_amount=0.001, - amount=123.0, - fee_open=fee.return_value, - fee_close=fee.return_value, - open_rate=0.123, - exchange='binance', - open_order_id='prod_buy_12345' - ) - Trade.query.session.add(trade) - - # We have 3 entries: 2 dry_run, 1 prod - assert len(Trade.query.filter(Trade.open_order_id.isnot(None)).all()) == 3 - - clean_dry_run_db() - - # We have now only the prod - assert len(Trade.query.filter(Trade.open_order_id.isnot(None)).all()) == 1 - - def test_migrate_new(mocker, default_conf, fee, caplog): """ Test Database migration (starting with new pairformat) @@ -1310,7 +1271,7 @@ def test_migrate_new(mocker, default_conf, fee, caplog): connection.execute(text("create table trades_bak1 as select * from trades")) # Run init to test migration - init_db(default_conf['db_url'], default_conf['dry_run']) + init_db(default_conf['db_url']) assert len(Trade.query.filter(Trade.id == 1).all()) == 1 trade = Trade.query.filter(Trade.id == 1).first() @@ -1393,7 +1354,7 @@ def test_migrate_too_old(mocker, default_conf, fee, caplog): # Run init to test migration with pytest.raises(OperationalException, match=r'Your database seems to be very old'): - init_db(default_conf['db_url'], default_conf['dry_run']) + init_db(default_conf['db_url']) def test_migrate_get_last_sequence_ids(): @@ -1467,7 +1428,7 @@ def test_migrate_pairlocks(mocker, default_conf, fee, caplog): connection.execute(text(create_index2)) connection.execute(text(create_index3)) - init_db(default_conf['db_url'], default_conf['dry_run']) + init_db(default_conf['db_url']) assert len(PairLock.query.all()) == 2 assert len(PairLock.query.filter(PairLock.pair == '*').all()) == 1 @@ -2114,6 +2075,24 @@ def test_get_trades_proxy(fee, use_db, is_short): Trade.use_db = True +@pytest.mark.usefixtures("init_persistence") +@pytest.mark.parametrize('is_short', [True, False]) +def test_get_trades__query(fee, is_short): + query = Trade.get_trades([]) + # without orders there should be no join issued. + query1 = Trade.get_trades([], include_orders=False) + + assert "JOIN orders" in str(query) + assert "JOIN orders" not in str(query1) + + create_mock_trades(fee, is_short) + query = Trade.get_trades([]) + query1 = Trade.get_trades([], include_orders=False) + + assert "JOIN orders" in str(query) + assert "JOIN orders" not in str(query1) + + def test_get_trades_backtest(): Trade.use_db = False with pytest.raises(NotImplementedError, match=r"`Trade.get_trades\(\)` not .*"): @@ -2308,6 +2287,7 @@ def test_Trade_object_idem(): 'get_exit_reason_performance', 'get_enter_tag_performance', 'get_mix_tag_performance', + 'get_trading_volume', ) @@ -2721,3 +2701,23 @@ def test_select_filled_orders(fee): orders = trades[4].select_filled_orders('sell') assert orders is not None assert len(orders) == 0 + + +@pytest.mark.usefixtures("init_persistence") +def test_order_to_ccxt(limit_buy_order_open): + + order = Order.parse_from_ccxt_object(limit_buy_order_open, 'mocked', 'buy') + order.query.session.add(order) + Order.query.session.commit() + + order_resp = Order.order_by_id(limit_buy_order_open['id']) + assert order_resp + + raw_order = order_resp.to_ccxt_object() + del raw_order['fee'] + del raw_order['datetime'] + del raw_order['info'] + assert raw_order['stopPrice'] is None + del raw_order['stopPrice'] + del limit_buy_order_open['datetime'] + assert raw_order == limit_buy_order_open