diff --git a/.github/workflows/binance-lev-tier-update.yml b/.github/workflows/binance-lev-tier-update.yml index 844a6c8f5..ba1999fd6 100644 --- a/.github/workflows/binance-lev-tier-update.yml +++ b/.github/workflows/binance-lev-tier-update.yml @@ -16,6 +16,8 @@ jobs: name: develop steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - uses: actions/setup-python@v5 with: @@ -42,6 +44,7 @@ jobs: branch: update/binance-leverage-tiers title: Update Binance Leverage Tiers commit-message: "chore: update pre-commit hooks" - committer: Freqtrade Bot + committer: Freqtrade Bot <154552126+freqtrade-bot@users.noreply.github.com> + author: Freqtrade Bot <154552126+freqtrade-bot@users.noreply.github.com> body: Update binance leverage tiers. delete-branch: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 94867b0a4..cc0c8a5d7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,11 +24,13 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ "ubuntu-20.04", "ubuntu-22.04", "ubuntu-24.04" ] + os: [ "ubuntu-22.04", "ubuntu-24.04" ] python-version: ["3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Set up Python uses: actions/setup-python@v5 @@ -157,6 +159,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Set up Python uses: actions/setup-python@v5 @@ -281,6 +285,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Set up Python uses: actions/setup-python@v5 @@ -366,6 +372,8 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Set up Python uses: actions/setup-python@v5 @@ -381,6 +389,8 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - uses: actions/setup-python@v5 with: @@ -391,6 +401,8 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Documentation syntax run: | @@ -420,6 +432,8 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Set up Python uses: actions/setup-python@v5 @@ -506,6 +520,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Set up Python uses: actions/setup-python@v5 @@ -551,6 +567,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Download artifact 📦 uses: actions/download-artifact@v4 @@ -578,6 +596,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Download artifact 📦 uses: actions/download-artifact@v4 @@ -598,6 +618,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Set up Python uses: actions/setup-python@v5 @@ -633,7 +655,9 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Available platforms - run: echo ${{ steps.buildx.outputs.platforms }} + run: echo ${PLATFORMS} + env: + PLATFORMS: ${{ steps.buildx.outputs.platforms }} - name: Build and test and push docker images env: @@ -652,6 +676,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Extract branch name id: extract-branch diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index c97934a51..6577bf38b 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -20,6 +20,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + persist-credentials: true - name: Set up Python uses: actions/setup-python@v5 @@ -43,12 +45,16 @@ jobs: - name: Build and push Mike if: ${{ github.event_name == 'push' }} run: | - mike deploy ${{ github.ref_name }} latest --push --update-aliases + mike deploy ${REF_NAME} latest --push --update-aliases + env: + REF_NAME: ${{ github.ref_name }} - name: Build and push Mike - Release if: ${{ github.event_name == 'release' }} run: | - mike deploy ${{ github.ref_name }} stable --push --update-aliases + mike deploy ${REF_NAME} stable --push --update-aliases + env: + REF_NAME: ${{ github.ref_name }} - name: Show mike versions run: | diff --git a/.github/workflows/devcontainer-build.yml b/.github/workflows/devcontainer-build.yml index e3b510b03..12b55c6ed 100644 --- a/.github/workflows/devcontainer-build.yml +++ b/.github/workflows/devcontainer-build.yml @@ -17,29 +17,26 @@ concurrency: group: "${{ github.workflow }}" cancel-in-progress: true -permissions: - packages: write jobs: build-and-push: + permissions: + packages: write runs-on: ubuntu-latest steps: - - - name: Checkout - id: checkout - uses: actions/checkout@v4 - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Pre-build dev container image - uses: devcontainers/ci@v0.3 - with: - subFolder: .github - imageName: ghcr.io/${{ github.repository }}-devcontainer - cacheFrom: ghcr.io/${{ github.repository }}-devcontainer - push: always + - uses: actions/checkout@v4 + with: + persist-credentials: false + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Pre-build dev container image + uses: devcontainers/ci@v0.3 + with: + subFolder: .github + imageName: ghcr.io/${{ github.repository }}-devcontainer + cacheFrom: ghcr.io/${{ github.repository }}-devcontainer + push: always diff --git a/.github/workflows/docker-update-readme.yml b/.github/workflows/docker-update-readme.yml index 95ab5b6ca..7f00c01c0 100644 --- a/.github/workflows/docker-update-readme.yml +++ b/.github/workflows/docker-update-readme.yml @@ -4,11 +4,16 @@ on: branches: - stable +# disable permissions for all of the available permissions +permissions: {} + jobs: dockerHubDescription: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Docker Hub Description uses: peter-evans/dockerhub-description@v4 diff --git a/.github/workflows/pre-commit-update.yml b/.github/workflows/pre-commit-update.yml index 5d71f513f..5996dddf9 100644 --- a/.github/workflows/pre-commit-update.yml +++ b/.github/workflows/pre-commit-update.yml @@ -14,6 +14,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - uses: actions/setup-python@v5 with: @@ -36,6 +38,7 @@ jobs: branch: update/pre-commit-hooks title: Update pre-commit hooks commit-message: "chore: update pre-commit hooks" - committer: Freqtrade Bot + committer: Freqtrade Bot <154552126+freqtrade-bot@users.noreply.github.com> + author: Freqtrade Bot <154552126+freqtrade-bot@users.noreply.github.com> body: Update versions of pre-commit hooks to latest version. delete-branch: true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a7b9d4316..21c285ec2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,14 +2,14 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pycqa/flake8 - rev: "7.1.1" + rev: "7.1.2" hooks: - id: flake8 additional_dependencies: [Flake8-pyproject] # stages: [push] - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v1.14.1" + rev: "v1.15.0" hooks: - id: mypy exclude: build_helpers @@ -19,11 +19,11 @@ repos: - types-requests==2.32.0.20241016 - types-tabulate==0.9.0.20241207 - types-python-dateutil==2.9.0.20241206 - - SQLAlchemy==2.0.37 + - SQLAlchemy==2.0.38 # stages: [push] - repo: https://github.com/pycqa/isort - rev: "6.0.0" + rev: "6.0.1" hooks: - id: isort name: isort (python) @@ -31,7 +31,7 @@ repos: - repo: https://github.com/charliermarsh/ruff-pre-commit # Ruff version. - rev: 'v0.9.3' + rev: 'v0.9.7' hooks: - id: ruff - id: ruff-format @@ -57,13 +57,19 @@ repos: )$ - repo: https://github.com/stefmolin/exif-stripper - rev: 0.6.1 + rev: 0.6.2 hooks: - id: strip-exif - repo: https://github.com/codespell-project/codespell - rev: v2.4.0 + rev: v2.4.1 hooks: - id: codespell additional_dependencies: - tomli + + # Ensure github actions remain safe + - repo: https://github.com/woodruffw/zizmor-pre-commit + rev: v1.4.1 + hooks: + - id: zizmor diff --git a/Dockerfile b/Dockerfile index 13be64923..15636ed71 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.12.7-slim-bookworm as base +FROM python:3.12.9-slim-bookworm as base # Setup env ENV LANG C.UTF-8 diff --git a/build_helpers/pyarrow-19.0.0-cp311-cp311-linux_armv7l.whl b/build_helpers/pyarrow-19.0.1-cp311-cp311-linux_armv7l.whl similarity index 65% rename from build_helpers/pyarrow-19.0.0-cp311-cp311-linux_armv7l.whl rename to build_helpers/pyarrow-19.0.1-cp311-cp311-linux_armv7l.whl index dbd6ba991..0a730939a 100644 Binary files a/build_helpers/pyarrow-19.0.0-cp311-cp311-linux_armv7l.whl and b/build_helpers/pyarrow-19.0.1-cp311-cp311-linux_armv7l.whl differ diff --git a/build_helpers/ta_lib-0.4.34-cp311-cp311-win_amd64.whl b/build_helpers/ta_lib-0.4.38-cp310-cp310-win_amd64.whl similarity index 67% rename from build_helpers/ta_lib-0.4.34-cp311-cp311-win_amd64.whl rename to build_helpers/ta_lib-0.4.38-cp310-cp310-win_amd64.whl index 3513df4ba..00610d687 100644 Binary files a/build_helpers/ta_lib-0.4.34-cp311-cp311-win_amd64.whl and b/build_helpers/ta_lib-0.4.38-cp310-cp310-win_amd64.whl differ diff --git a/build_helpers/ta_lib-0.4.34-cp311-cp311-linux_armv7l.whl b/build_helpers/ta_lib-0.4.38-cp311-cp311-linux_armv7l.whl similarity index 50% rename from build_helpers/ta_lib-0.4.34-cp311-cp311-linux_armv7l.whl rename to build_helpers/ta_lib-0.4.38-cp311-cp311-linux_armv7l.whl index 581361925..a255164d0 100644 Binary files a/build_helpers/ta_lib-0.4.34-cp311-cp311-linux_armv7l.whl and b/build_helpers/ta_lib-0.4.38-cp311-cp311-linux_armv7l.whl differ diff --git a/build_helpers/ta_lib-0.4.34-cp310-cp310-win_amd64.whl b/build_helpers/ta_lib-0.4.38-cp311-cp311-win_amd64.whl similarity index 67% rename from build_helpers/ta_lib-0.4.34-cp310-cp310-win_amd64.whl rename to build_helpers/ta_lib-0.4.38-cp311-cp311-win_amd64.whl index 32bb10e4f..7237604ba 100644 Binary files a/build_helpers/ta_lib-0.4.34-cp310-cp310-win_amd64.whl and b/build_helpers/ta_lib-0.4.38-cp311-cp311-win_amd64.whl differ diff --git a/build_helpers/ta_lib-0.4.34-cp312-cp312-win_amd64.whl b/build_helpers/ta_lib-0.4.38-cp312-cp312-win_amd64.whl similarity index 67% rename from build_helpers/ta_lib-0.4.34-cp312-cp312-win_amd64.whl rename to build_helpers/ta_lib-0.4.38-cp312-cp312-win_amd64.whl index 212668e58..fe37c8468 100644 Binary files a/build_helpers/ta_lib-0.4.34-cp312-cp312-win_amd64.whl and b/build_helpers/ta_lib-0.4.38-cp312-cp312-win_amd64.whl differ diff --git a/docker/Dockerfile.armhf b/docker/Dockerfile.armhf index 1ee0ded9e..94049101b 100644 --- a/docker/Dockerfile.armhf +++ b/docker/Dockerfile.armhf @@ -1,4 +1,4 @@ -FROM python:3.11.10-slim-bookworm as base +FROM python:3.11.11-slim-bookworm as base # Setup env ENV LANG C.UTF-8 @@ -34,7 +34,7 @@ COPY build_helpers/* /tmp/ # Install dependencies COPY --chown=ftuser:ftuser requirements.txt /freqtrade/ USER ftuser -RUN pip install --user --no-cache-dir numpy \ +RUN pip install --user --no-cache-dir "numpy<2" \ && pip install --user --no-index --find-links /tmp/ pyarrow TA-Lib \ && pip install --user --no-cache-dir -r requirements.txt diff --git a/docs/bot-basics.md b/docs/bot-basics.md index 1c88559c0..ff73aecde 100644 --- a/docs/bot-basics.md +++ b/docs/bot-basics.md @@ -54,11 +54,13 @@ By default, the bot loop runs every few seconds (`internals.process_throttle_sec * Check timeouts for open orders. * Calls `check_entry_timeout()` strategy callback for open entry orders. * Calls `check_exit_timeout()` strategy callback for open exit orders. - * Calls `adjust_entry_price()` strategy callback for open entry orders. + * Calls `adjust_order_price()` strategy callback for open orders. + * Calls `adjust_entry_price()` strategy callback for open entry orders. *only called when `adjust_order_price()` is not implemented* + * Calls `adjust_exit_price()` strategy callback for open exit orders. *only called when `adjust_order_price()` is not implemented* * Verifies existing positions and eventually places exit orders. * Considers stoploss, ROI and exit-signal, `custom_exit()` and `custom_stoploss()`. * Determine exit-price based on `exit_pricing` configuration setting or by using the `custom_exit_price()` callback. - * Before a exit order is placed, `confirm_trade_exit()` strategy callback is called. + * Before an exit order is placed, `confirm_trade_exit()` strategy callback is called. * Check position adjustments for open trades if enabled by calling `adjust_trade_position()` and place additional order if required. * Check if trade-slots are still available (if `max_open_trades` is reached). * Verifies entry signal trying to enter new positions. @@ -80,7 +82,9 @@ This loop will be repeated again and again until the bot is stopped. * Loops per candle simulating entry and exit points. * Calls `bot_loop_start()` strategy callback. * Check for Order timeouts, either via the `unfilledtimeout` configuration, or via `check_entry_timeout()` / `check_exit_timeout()` strategy callbacks. - * Calls `adjust_entry_price()` strategy callback for open entry orders. + * Calls `adjust_order_price()` strategy callback for open orders. + * Calls `adjust_entry_price()` strategy callback for open entry orders. *only called when `adjust_order_price()` is not implemented!* + * Calls `adjust_exit_price()` strategy callback for open exit orders. *only called when `adjust_order_price()` is not implemented!* * Check for trade entry signals (`enter_long` / `enter_short` columns). * Confirm trade entry / exits (calls `confirm_trade_entry()` and `confirm_trade_exit()` if implemented in the strategy). * Call `custom_entry_price()` (if implemented in the strategy) to determine entry price (Prices are moved to be within the opening candle). diff --git a/docs/includes/pairlists.md b/docs/includes/pairlists.md index 7e4659807..c1da08516 100644 --- a/docs/includes/pairlists.md +++ b/docs/includes/pairlists.md @@ -377,6 +377,9 @@ If an incorrect category string is chosen, the plugin will print the available c !!! Warning "Many categories" Each added category corresponds to one API call to CoinGecko. The more categories you add, the longer the pairlist generation will take, potentially causing rate limit issues. +!!! Danger "Duplicate symbols in coingecko" + Coingecko often has duplicate symbols, where the same symbol is used for different coins. Freqtrade will use the symbol as is and try to search for it on the exchange. If the symbol exists - it will be used. Freqtrade will however not check if the _intended_ symbol is the one coingecko meant. This can sometimes lead to unexpected results, especially on low volume coins or with meme coin categories. + #### AgeFilter Removes pairs that have been listed on the exchange for less than `min_days_listed` days (defaults to `10`) or more than `max_days_listed` days (defaults `None` mean infinity). diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index 333e4d08d..12385669b 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,7 +1,7 @@ markdown==3.7 mkdocs==1.6.1 -mkdocs-material==9.5.50 +mkdocs-material==9.6.5 mdx_truly_sane_lists==1.3 -pymdown-extensions==10.14.1 +pymdown-extensions==10.14.3 jinja2==3.1.5 mike==2.1.3 diff --git a/docs/stoploss.md b/docs/stoploss.md index 69c69626f..7fbe6dabc 100644 --- a/docs/stoploss.md +++ b/docs/stoploss.md @@ -154,10 +154,10 @@ For example, simplified math: In summary: The stoploss will be adjusted to be always be -10% of the highest observed price. -### Trailing stop loss, custom positive loss +### Trailing stop loss, different positive loss -You could also have a default stop loss when you are in the red with your buy (buy - fee), but once you hit a positive result (or an offset you define) the system will utilize a new stop loss, which can have a different value. -For example, your default stop loss is -10%, but once you have more than 0% profit (example 0.1%) a different trailing stoploss will be used. +You could also have a default stop loss when you are in the red with your buy (buy - fee), but once you hit a positive result (or an offset you define) the system will utilize a new stop loss, with a different value. +For example, your default stop loss is -10%, but once you have reached profitability (example 0.1%) a different trailing stoploss will be used. !!! Note If you want the stoploss to only be changed when you break even of making a profit (what most users want) please refer to next section with [offset enabled](#trailing-stop-loss-only-once-the-trade-has-reached-a-certain-offset). @@ -208,7 +208,9 @@ Before this, `stoploss` is used for the trailing stoploss. You can also keep a static stoploss until the offset is reached, and then trail the trade to take profits once the market turns. -If `trailing_only_offset_is_reached = True` then the trailing stoploss is only activated once the offset is reached. Until then, the stoploss remains at the configured `stoploss`. +If `trailing_only_offset_is_reached = True` then the trailing stoploss is only activated once the offset is reached. Until then, the stoploss remains at the configured `stoploss` and is not trailing. +Leaving this value as `trailing_only_offset_is_reached=False` will allow the trailing stoploss to start trailing as soon as the asset price increases above the initial entry price. + This option can be used with or without `trailing_stop_positive`, but uses `trailing_stop_positive_offset` as offset. Configuration (offset is buy-price + 3%): diff --git a/docs/strategy-101.md b/docs/strategy-101.md index e7618d90f..9226537e1 100644 --- a/docs/strategy-101.md +++ b/docs/strategy-101.md @@ -79,6 +79,8 @@ import talib.abstract as ta class MyStrategy(IStrategy): + timeframe = '15m' + # set the initial stoploss to -10% stoploss = -0.10 diff --git a/docs/strategy-callbacks.md b/docs/strategy-callbacks.md index 64f7987f6..8c9dd1a2e 100644 --- a/docs/strategy-callbacks.md +++ b/docs/strategy-callbacks.md @@ -934,28 +934,25 @@ class DigDeeperStrategy(IStrategy): The total profit for this trade was 950$ on a 3350$ investment (`100@8$ + 100@9$ + 150@11$`). As such - the final relative profit is 28.35% (`950 / 3350`). -## Adjust Entry Price +## Adjust order Price -The `adjust_entry_price()` callback may be used by strategy developer to refresh/replace limit orders upon arrival of new candles. +The `adjust_order_price()` callback may be used by strategy developer to refresh/replace limit orders upon arrival of new candles. This callback is called once every iteration unless the order has been (re)placed within the current candle - limiting the maximum (re)placement of each order to once per candle. This also means that the first call will be at the start of the next candle after the initial order was placed. -Be aware that `custom_entry_price()` is still the one dictating initial entry limit order price target at the time of entry trigger. +Be aware that `custom_entry_price()`/`custom_exit_price()` is still the one dictating initial limit order price target at the time of the signal. Orders can be cancelled out of this callback by returning `None`. Returning `current_order_rate` will keep the order on the exchange "as is". Returning any other price will cancel the existing order, and replace it with a new order. -The trade open-date (`trade.open_date_utc`) will remain at the time of the very first order placed. -Please make sure to be aware of this - and eventually adjust your logic in other callbacks to account for this, and use the date of the first filled order instead. - If the cancellation of the original order fails, then the order will not be replaced - though the order will most likely have been canceled on exchange. Having this happen on initial entries will result in the deletion of the order, while on position adjustment orders, it'll result in the trade size remaining as is. -If the order has been partially filled, the order will not be replaced. You can however use [`adjust_trade_position()`](#adjust-trade-position) to adjust the trade size to the full, expected position size, should this be necessary / desired. +If the order has been partially filled, the order will not be replaced. You can however use [`adjust_trade_position()`](#adjust-trade-position) to adjust the trade size to the expected position size, should this be necessary / desired. !!! Warning "Regular timeout" - Entry `unfilledtimeout` mechanism (as well as `check_entry_timeout()`) takes precedence over this. - Entry Orders that are cancelled via the above methods will not have this callback called. Be sure to update timeout values to match your expectations. + Entry `unfilledtimeout` mechanism (as well as `check_entry_timeout()`/`check_exit_timeout()`) takes precedence over this callback. + Orders that are cancelled via the above methods will not have this callback called. Be sure to update timeout values to match your expectations. ```python # Default imports @@ -964,14 +961,26 @@ class AwesomeStrategy(IStrategy): # ... populate_* methods - def adjust_entry_price(self, trade: Trade, order: Order | None, pair: str, - current_time: datetime, proposed_rate: float, current_order_rate: float, - entry_tag: str | None, side: str, **kwargs) -> float: + def adjust_order_price( + self, + trade: Trade, + order: Order | None, + pair: str, + current_time: datetime, + proposed_rate: float, + current_order_rate: float, + entry_tag: str | None, + side: str, + is_entry: bool, + **kwargs, + ) -> float: """ - Entry price re-adjustment logic, returning the user desired limit price. + Exit and entry order price re-adjustment logic, returning the user desired limit price. This only executes when a order was already placed, still open (unfilled fully or partially) and not timed out on subsequent candles after entry trigger. + For full documentation please go to https://www.freqtrade.io/en/latest/strategy-callbacks/ + When not implemented by a strategy, returns current_order_rate as default. If current_order_rate is returned then the existing order is maintained. If None is returned then order gets canceled but not replaced by a new one. @@ -983,14 +992,16 @@ class AwesomeStrategy(IStrategy): :param proposed_rate: Rate, calculated based on pricing settings in entry_pricing. :param current_order_rate: Rate of the existing order in place. :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 side: 'long' or 'short' - indicating the direction of the proposed trade + :param is_entry: True if the order is an entry order, False if it's an exit order. :param **kwargs: Ensure to keep this here so updates to this won't break your strategy. :return float: New entry price value if provided - """ - # Limit orders to use and follow SMA200 as price target for the first 10 minutes since entry trigger for BTC/USDT pair. + + # Limit entry orders to use and follow SMA200 as price target for the first 10 minutes since entry trigger for BTC/USDT pair. if ( - pair == "BTC/USDT" + is_entry + and pair == "BTC/USDT" and entry_tag == "long_sma200" and side == "long" and (current_time - timedelta(minutes=10)) <= trade.open_date_utc @@ -1007,6 +1018,26 @@ class AwesomeStrategy(IStrategy): return current_order_rate ``` +!!! danger "Incompatibility with `adjust_*_price()`" + If you have both `adjust_order_price()` and `adjust_entry_price()`/`adjust_exit_price()` implemented, only `adjust_order_price()` will be used. + If you need to adjust entry/exit prices, you can either implement the logic in `adjust_order_price()`, or use the split `adjust_entry_price()` / `adjust_exit_price()` callbacks, but not both. + Mixing these is not supported and will raise an error during bot startup. + +### Adjust Entry Price + +The `adjust_entry_price()` callback may be used by strategy developer to refresh/replace entry limit orders upon arrival. +It's a sub-set of `adjust_order_price()` and is called only for entry orders. +All remaining behavior is identical to `adjust_order_price()`. + +The trade open-date (`trade.open_date_utc`) will remain at the time of the very first order placed. +Please make sure to be aware of this - and eventually adjust your logic in other callbacks to account for this, and use the date of the first filled order instead. + +### Adjust Exit Price + +The `adjust_exit_price()` callback may be used by strategy developer to refresh/replace exit limit orders upon arrival. +It's a sub-set of `adjust_order_price()` and is called only for exit orders. +All remaining behavior is identical to `adjust_order_price()`. + ## Leverage Callback When trading in markets that allow leverage, this method must return the desired Leverage (Defaults to 1 -> No leverage). diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 11b71caa9..df8ba4c97 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -513,7 +513,7 @@ By default, freqtrade will attempt to load strategies from all `.py` files withi Assuming your strategy is called `AwesomeStrategy`, stored in the file `user_data/strategies/AwesomeStrategy.py`, then you can start freqtrade in dry (or live, depending on your configuration) mode with: ```bash - freqtrade trade --strategy AwesomeStrategy` +freqtrade trade --strategy AwesomeStrategy ``` Note that we're using the class name, not the file name. diff --git a/freqtrade/__init__.py b/freqtrade/__init__.py index 9f9eeffc2..a788fb370 100644 --- a/freqtrade/__init__.py +++ b/freqtrade/__init__.py @@ -1,6 +1,6 @@ """Freqtrade bot""" -__version__ = "2025.1" +__version__ = "2025.2" if "dev" in __version__: from pathlib import Path diff --git a/freqtrade/data/history/history_utils.py b/freqtrade/data/history/history_utils.py index 47c323152..806fd49da 100644 --- a/freqtrade/data/history/history_utils.py +++ b/freqtrade/data/history/history_utils.py @@ -18,8 +18,7 @@ from freqtrade.enums import CandleType, TradingMode from freqtrade.exceptions import OperationalException from freqtrade.exchange import Exchange from freqtrade.plugins.pairlist.pairlist_helpers import dynamic_expand_pairlist -from freqtrade.util import dt_now, dt_ts, format_ms_time -from freqtrade.util.datetime_helpers import format_ms_time_det +from freqtrade.util import dt_now, dt_ts, format_ms_time, format_ms_time_det from freqtrade.util.migrations import migrate_data from freqtrade.util.progress_tracker import CustomProgress, retrieve_progress_tracker diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index 0d1176b35..01f9d93ed 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -10,7 +10,6 @@ from freqtrade.exchange.bitmart import Bitmart from freqtrade.exchange.bitpanda import Bitpanda from freqtrade.exchange.bitvavo import Bitvavo from freqtrade.exchange.bybit import Bybit -from freqtrade.exchange.coinbasepro import Coinbasepro from freqtrade.exchange.cryptocom import Cryptocom from freqtrade.exchange.exchange_utils import ( ROUND_DOWN, diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 797bce034..e9c44a41e 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -29,7 +29,6 @@ class Binance(Exchange): "stop_price_prop": "stopPrice", "stoploss_order_types": {"limit": "stop_loss_limit"}, "order_time_in_force": ["GTC", "FOK", "IOC", "PO"], - "ohlcv_candle_limit": 1000, "trades_pagination": "id", "trades_pagination_arg": "fromId", "trades_has_history": True, @@ -37,6 +36,7 @@ class Binance(Exchange): "ws_enabled": True, } _ft_has_futures: FtHas = { + "funding_fee_candle_limit": 1000, "stoploss_order_types": {"limit": "stop", "market": "stop_market"}, "order_time_in_force": ["GTC", "FOK", "IOC"], "tickers_have_price": False, @@ -140,9 +140,10 @@ class Binance(Exchange): :param candle_type: Any of the enum CandleType (must match trading mode!) """ if is_new_pair: - x = self.loop.run_until_complete( - self._async_get_candle_history(pair, timeframe, candle_type, 0) - ) + with self._loop_lock: + x = self.loop.run_until_complete( + self._async_get_candle_history(pair, timeframe, candle_type, 0) + ) if x and x[3] and x[3][0] and x[3][0][0] > since_ms: # Set starting date to first available candle. since_ms = x[3][0][0] @@ -201,16 +202,17 @@ class Binance(Exchange): """ Fastly fetch OHLCV data by leveraging https://data.binance.vision. """ - df = self.loop.run_until_complete( - download_archive_ohlcv( - candle_type=candle_type, - pair=pair, - timeframe=timeframe, - since_ms=since_ms, - until_ms=until_ms, - markets=self.markets, + with self._loop_lock: + df = self.loop.run_until_complete( + download_archive_ohlcv( + candle_type=candle_type, + pair=pair, + timeframe=timeframe, + since_ms=since_ms, + until_ms=until_ms, + markets=self.markets, + ) ) - ) # download the remaining data from rest API if df.empty: diff --git a/freqtrade/exchange/binance_leverage_tiers.json b/freqtrade/exchange/binance_leverage_tiers.json index 77233313b..ba6f21db3 100644 --- a/freqtrade/exchange/binance_leverage_tiers.json +++ b/freqtrade/exchange/binance_leverage_tiers.json @@ -7,10 +7,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -24,10 +24,10 @@ "minNotional": 5000.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "10000", "notionalFloor": "5000", "maintMarginRatio": "0.015", @@ -41,10 +41,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.02", @@ -58,10 +58,10 @@ "minNotional": 30000.0, "maxNotional": 60000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "60000", "notionalFloor": "30000", "maintMarginRatio": "0.025", @@ -75,10 +75,10 @@ "minNotional": 60000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "300000", "notionalFloor": "60000", "maintMarginRatio": "0.05", @@ -141,13 +141,13 @@ "symbol": "1000000MOG/USDT:USDT", "currency": "USDT", "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "3000000", + "notionalCap": "2000000", "notionalFloor": "1500000", "maintMarginRatio": "0.5", "cum": "500475.0" @@ -383,13 +383,13 @@ "symbol": "1000BONK/USDT:USDT", "currency": "USDT", "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "maxNotional": 6000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "10000000", + "notionalCap": "6000000", "notionalFloor": "5000000", "maintMarginRatio": "0.1", "cum": "278050.0" @@ -399,51 +399,51 @@ "tier": 7.0, "symbol": "1000BONK/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 12500000.0, + "minNotional": 6000000.0, + "maxNotional": 7000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "12500000", - "notionalFloor": "10000000", + "notionalCap": "7000000", + "notionalFloor": "6000000", "maintMarginRatio": "0.125", - "cum": "528050.0" + "cum": "428050.0" } }, { "tier": 8.0, "symbol": "1000BONK/USDT:USDT", "currency": "USDT", - "minNotional": 12500000.0, - "maxNotional": 25000000.0, + "minNotional": 7000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "25000000", - "notionalFloor": "12500000", + "notionalCap": "8000000", + "notionalFloor": "7000000", "maintMarginRatio": "0.25", - "cum": "2090550.0" + "cum": "1303050.0" } }, { "tier": 9.0, "symbol": "1000BONK/USDT:USDT", "currency": "USDT", - "minNotional": 25000000.0, - "maxNotional": 50000000.0, + "minNotional": 8000000.0, + "maxNotional": 9000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "50000000", - "notionalFloor": "25000000", + "notionalCap": "9000000", + "notionalFloor": "8000000", "maintMarginRatio": "0.5", - "cum": "8340550.0" + "cum": "3303050.0" } } ], @@ -610,10 +610,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "1", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -627,10 +627,10 @@ "minNotional": 5000.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "2", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "10000", "notionalFloor": "5000", "maintMarginRatio": "0.015", @@ -644,10 +644,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 15.0, + "maxLeverage": 8.0, "info": { "bracket": "3", - "initialLeverage": "15", + "initialLeverage": "8", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.02", @@ -661,10 +661,10 @@ "minNotional": 30000.0, "maxNotional": 60000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 10.0, + "maxLeverage": 7.0, "info": { "bracket": "4", - "initialLeverage": "10", + "initialLeverage": "7", "notionalCap": "60000", "notionalFloor": "30000", "maintMarginRatio": "0.025", @@ -678,10 +678,10 @@ "minNotional": 60000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 8.0, + "maxLeverage": 6.0, "info": { "bracket": "5", - "initialLeverage": "8", + "initialLeverage": "6", "notionalCap": "300000", "notionalFloor": "60000", "maintMarginRatio": "0.05", @@ -848,13 +848,13 @@ "symbol": "1000FLOKI/USDT:USDT", "currency": "USDT", "minNotional": 3000000.0, - "maxNotional": 6000000.0, + "maxNotional": 3500000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "6000000", + "notionalCap": "3500000", "notionalFloor": "3000000", "maintMarginRatio": "0.1", "cum": "166850.0" @@ -864,51 +864,51 @@ "tier": 7.0, "symbol": "1000FLOKI/USDT:USDT", "currency": "USDT", - "minNotional": 6000000.0, - "maxNotional": 7500000.0, + "minNotional": 3500000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "7500000", - "notionalFloor": "6000000", + "notionalCap": "4000000", + "notionalFloor": "3500000", "maintMarginRatio": "0.125", - "cum": "316850.0" + "cum": "254350.0" } }, { "tier": 8.0, "symbol": "1000FLOKI/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 15000000.0, + "minNotional": 4000000.0, + "maxNotional": 4500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "15000000", - "notionalFloor": "7500000", + "notionalCap": "4500000", + "notionalFloor": "4000000", "maintMarginRatio": "0.25", - "cum": "1254350.0" + "cum": "754350.0" } }, { "tier": 9.0, "symbol": "1000FLOKI/USDT:USDT", "currency": "USDT", - "minNotional": 15000000.0, - "maxNotional": 30000000.0, + "minNotional": 4500000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "30000000", - "notionalFloor": "15000000", + "notionalCap": "5000000", + "notionalFloor": "4500000", "maintMarginRatio": "0.5", - "cum": "5004350.0" + "cum": "1879350.0" } } ], @@ -1279,13 +1279,13 @@ "symbol": "1000PEPE/USDT:USDT", "currency": "USDT", "minNotional": 15000000.0, - "maxNotional": 30000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "7", "initialLeverage": "5", - "notionalCap": "30000000", + "notionalCap": "20000000", "notionalFloor": "15000000", "maintMarginRatio": "0.1", "cum": "835070.0" @@ -1295,51 +1295,51 @@ "tier": 8.0, "symbol": "1000PEPE/USDT:USDT", "currency": "USDT", - "minNotional": 30000000.0, - "maxNotional": 37500000.0, + "minNotional": 20000000.0, + "maxNotional": 25000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "8", "initialLeverage": "4", - "notionalCap": "37500000", - "notionalFloor": "30000000", + "notionalCap": "25000000", + "notionalFloor": "20000000", "maintMarginRatio": "0.125", - "cum": "1585070.0" + "cum": "1335070.0" } }, { "tier": 9.0, "symbol": "1000PEPE/USDT:USDT", "currency": "USDT", - "minNotional": 37500000.0, - "maxNotional": 75000000.0, + "minNotional": 25000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "9", "initialLeverage": "2", - "notionalCap": "75000000", - "notionalFloor": "37500000", + "notionalCap": "30000000", + "notionalFloor": "25000000", "maintMarginRatio": "0.25", - "cum": "6272570.0" + "cum": "4460070.0" } }, { "tier": 10.0, "symbol": "1000PEPE/USDT:USDT", "currency": "USDT", - "minNotional": 75000000.0, - "maxNotional": 150000000.0, + "minNotional": 30000000.0, + "maxNotional": 35000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "10", "initialLeverage": "1", - "notionalCap": "150000000", - "notionalFloor": "75000000", + "notionalCap": "35000000", + "notionalFloor": "30000000", "maintMarginRatio": "0.5", - "cum": "25022570.0" + "cum": "11960070.0" } } ], @@ -1606,13 +1606,13 @@ "symbol": "1000SATS/USDT:USDT", "currency": "USDT", "minNotional": 6000000.0, - "maxNotional": 7500000.0, + "maxNotional": 7000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "7500000", + "notionalCap": "7000000", "notionalFloor": "6000000", "maintMarginRatio": "0.125", "cum": "316850.0" @@ -1622,34 +1622,34 @@ "tier": 8.0, "symbol": "1000SATS/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 15000000.0, + "minNotional": 7000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "15000000", - "notionalFloor": "7500000", + "notionalCap": "8000000", + "notionalFloor": "7000000", "maintMarginRatio": "0.25", - "cum": "1254350.0" + "cum": "1191850.0" } }, { "tier": 9.0, "symbol": "1000SATS/USDT:USDT", "currency": "USDT", - "minNotional": 15000000.0, - "maxNotional": 16000000.0, + "minNotional": 8000000.0, + "maxNotional": 9000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "16000000", - "notionalFloor": "15000000", + "notionalCap": "9000000", + "notionalFloor": "8000000", "maintMarginRatio": "0.5", - "cum": "5004350.0" + "cum": "3191850.0" } } ], @@ -1899,13 +1899,13 @@ "symbol": "1000SHIB/USDT:USDT", "currency": "USDT", "minNotional": 1600000.0, - "maxNotional": 8000000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "6", "initialLeverage": "10", - "notionalCap": "8000000", + "notionalCap": "3000000", "notionalFloor": "1600000", "maintMarginRatio": "0.05", "cum": "45837.5" @@ -1915,68 +1915,68 @@ "tier": 7.0, "symbol": "1000SHIB/USDT:USDT", "currency": "USDT", - "minNotional": 8000000.0, - "maxNotional": 16000000.0, + "minNotional": 3000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "7", "initialLeverage": "5", - "notionalCap": "16000000", - "notionalFloor": "8000000", + "notionalCap": "5000000", + "notionalFloor": "3000000", "maintMarginRatio": "0.1", - "cum": "445837.5" + "cum": "195837.5" } }, { "tier": 8.0, "symbol": "1000SHIB/USDT:USDT", "currency": "USDT", - "minNotional": 16000000.0, - "maxNotional": 20000000.0, + "minNotional": 5000000.0, + "maxNotional": 6000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "8", "initialLeverage": "4", - "notionalCap": "20000000", - "notionalFloor": "16000000", + "notionalCap": "6000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.125", - "cum": "845837.5" + "cum": "320837.5" } }, { "tier": 9.0, "symbol": "1000SHIB/USDT:USDT", "currency": "USDT", - "minNotional": 20000000.0, - "maxNotional": 40000000.0, + "minNotional": 6000000.0, + "maxNotional": 7000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "9", "initialLeverage": "2", - "notionalCap": "40000000", - "notionalFloor": "20000000", + "notionalCap": "7000000", + "notionalFloor": "6000000", "maintMarginRatio": "0.25", - "cum": "3345837.5" + "cum": "1070837.5" } }, { "tier": 10.0, "symbol": "1000SHIB/USDT:USDT", "currency": "USDT", - "minNotional": 40000000.0, - "maxNotional": 80000000.0, + "minNotional": 7000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "10", "initialLeverage": "1", - "notionalCap": "80000000", - "notionalFloor": "40000000", + "notionalCap": "8000000", + "notionalFloor": "7000000", "maintMarginRatio": "0.5", - "cum": "13345837.5" + "cum": "2820837.5" } } ], @@ -1988,10 +1988,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -2005,10 +2005,10 @@ "minNotional": 5000.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "10000", "notionalFloor": "5000", "maintMarginRatio": "0.015", @@ -2022,10 +2022,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.02", @@ -2039,10 +2039,10 @@ "minNotional": 30000.0, "maxNotional": 60000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "60000", "notionalFloor": "30000", "maintMarginRatio": "0.025", @@ -2056,10 +2056,10 @@ "minNotional": 60000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "300000", "notionalFloor": "60000", "maintMarginRatio": "0.05", @@ -2105,13 +2105,13 @@ "symbol": "1000WHY/USDT:USDT", "currency": "USDT", "minNotional": 750000.0, - "maxNotional": 1500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "1500000", + "notionalCap": "1000000", "notionalFloor": "750000", "maintMarginRatio": "0.25", "cum": "125475.0" @@ -2121,17 +2121,17 @@ "tier": 9.0, "symbol": "1000WHY/USDT:USDT", "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "minNotional": 1000000.0, + "maxNotional": 1500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "3000000", - "notionalFloor": "1500000", + "notionalCap": "1500000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", - "cum": "500475.0" + "cum": "375475.0" } } ], @@ -2143,10 +2143,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -2160,10 +2160,10 @@ "minNotional": 5000.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "10000", "notionalFloor": "5000", "maintMarginRatio": "0.015", @@ -2177,10 +2177,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.02", @@ -2194,10 +2194,10 @@ "minNotional": 30000.0, "maxNotional": 60000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "60000", "notionalFloor": "30000", "maintMarginRatio": "0.025", @@ -2211,10 +2211,10 @@ "minNotional": 60000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "300000", "notionalFloor": "60000", "maintMarginRatio": "0.05", @@ -2243,13 +2243,13 @@ "symbol": "1000X/USDT:USDT", "currency": "USDT", "minNotional": 600000.0, - "maxNotional": 750000.0, + "maxNotional": 700000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "750000", + "notionalCap": "700000", "notionalFloor": "600000", "maintMarginRatio": "0.125", "cum": "31725.0" @@ -2259,34 +2259,34 @@ "tier": 8.0, "symbol": "1000X/USDT:USDT", "currency": "USDT", - "minNotional": 750000.0, - "maxNotional": 1500000.0, + "minNotional": 700000.0, + "maxNotional": 800000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "1500000", - "notionalFloor": "750000", + "notionalCap": "800000", + "notionalFloor": "700000", "maintMarginRatio": "0.25", - "cum": "125475.0" + "cum": "119225.0" } }, { "tier": 9.0, "symbol": "1000X/USDT:USDT", "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "minNotional": 800000.0, + "maxNotional": 900000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "3000000", - "notionalFloor": "1500000", + "notionalCap": "900000", + "notionalFloor": "800000", "maintMarginRatio": "0.5", - "cum": "500475.0" + "cum": "319225.0" } } ], @@ -3194,10 +3194,10 @@ "minNotional": 0.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -3211,10 +3211,10 @@ "minNotional": 10000.0, "maxNotional": 80000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "80000", "notionalFloor": "10000", "maintMarginRatio": "0.015", @@ -3228,10 +3228,10 @@ "minNotional": 80000.0, "maxNotional": 400000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "400000", "notionalFloor": "80000", "maintMarginRatio": "0.02", @@ -3245,10 +3245,10 @@ "minNotional": 400000.0, "maxNotional": 800000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "800000", "notionalFloor": "400000", "maintMarginRatio": "0.025", @@ -3262,10 +3262,10 @@ "minNotional": 800000.0, "maxNotional": 4000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "4000000", "notionalFloor": "800000", "maintMarginRatio": "0.05", @@ -3294,13 +3294,13 @@ "symbol": "ACT/USDT:USDT", "currency": "USDT", "minNotional": 8000000.0, - "maxNotional": 10000000.0, + "maxNotional": 8500000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "10000000", + "notionalCap": "8500000", "notionalFloor": "8000000", "maintMarginRatio": "0.125", "cum": "422450.0" @@ -3310,34 +3310,34 @@ "tier": 8.0, "symbol": "ACT/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 20000000.0, + "minNotional": 8500000.0, + "maxNotional": 9000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "20000000", - "notionalFloor": "10000000", + "notionalCap": "9000000", + "notionalFloor": "8500000", "maintMarginRatio": "0.25", - "cum": "1672450.0" + "cum": "1484950.0" } }, { "tier": 9.0, "symbol": "ACT/USDT:USDT", "currency": "USDT", - "minNotional": 20000000.0, - "maxNotional": 21000000.0, + "minNotional": 9000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "21000000", - "notionalFloor": "20000000", + "notionalCap": "10000000", + "notionalFloor": "9000000", "maintMarginRatio": "0.5", - "cum": "6672450.0" + "cum": "3734950.0" } } ], @@ -3831,10 +3831,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -3848,10 +3848,10 @@ "minNotional": 5000.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "10000", "notionalFloor": "5000", "maintMarginRatio": "0.015", @@ -3865,10 +3865,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.02", @@ -3882,10 +3882,10 @@ "minNotional": 30000.0, "maxNotional": 60000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "60000", "notionalFloor": "30000", "maintMarginRatio": "0.025", @@ -3899,10 +3899,10 @@ "minNotional": 60000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "300000", "notionalFloor": "60000", "maintMarginRatio": "0.05", @@ -3965,13 +3965,13 @@ "symbol": "AERO/USDT:USDT", "currency": "USDT", "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "3000000", + "notionalCap": "2000000", "notionalFloor": "1500000", "maintMarginRatio": "0.5", "cum": "500475.0" @@ -5003,10 +5003,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -5020,10 +5020,10 @@ "minNotional": 5000.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "10000", "notionalFloor": "5000", "maintMarginRatio": "0.015", @@ -5037,10 +5037,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.02", @@ -5054,10 +5054,10 @@ "minNotional": 30000.0, "maxNotional": 60000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "60000", "notionalFloor": "30000", "maintMarginRatio": "0.025", @@ -5071,10 +5071,10 @@ "minNotional": 60000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "300000", "notionalFloor": "60000", "maintMarginRatio": "0.05", @@ -5137,13 +5137,13 @@ "symbol": "ALCH/USDT:USDT", "currency": "USDT", "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "3000000", + "notionalCap": "2000000", "notionalFloor": "1500000", "maintMarginRatio": "0.5", "cum": "500475.0" @@ -5897,15 +5897,15 @@ "symbol": "AMB/USDT:USDT", "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 10.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 8.0, "info": { "bracket": "1", - "initialLeverage": "10", - "notionalCap": "5000", + "initialLeverage": "8", + "notionalCap": "25000", "notionalFloor": "0", - "maintMarginRatio": "0.02", + "maintMarginRatio": "0.025", "cum": "0.0" } }, @@ -5913,38 +5913,21 @@ "tier": 2.0, "symbol": "AMB/USDT:USDT", "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 8.0, - "info": { - "bracket": "2", - "initialLeverage": "8", - "notionalCap": "25000", - "notionalFloor": "5000", - "maintMarginRatio": "0.025", - "cum": "25.0" - } - }, - { - "tier": 3.0, - "symbol": "AMB/USDT:USDT", - "currency": "USDT", "minNotional": 25000.0, "maxNotional": 200000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 6.0, "info": { - "bracket": "3", + "bracket": "2", "initialLeverage": "6", "notionalCap": "200000", "notionalFloor": "25000", "maintMarginRatio": "0.05", - "cum": "650.0" + "cum": "625.0" } }, { - "tier": 4.0, + "tier": 3.0, "symbol": "AMB/USDT:USDT", "currency": "USDT", "minNotional": 200000.0, @@ -5952,63 +5935,63 @@ "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { - "bracket": "4", + "bracket": "3", "initialLeverage": "5", "notionalCap": "500000", "notionalFloor": "200000", "maintMarginRatio": "0.1", - "cum": "10650.0" + "cum": "10625.0" + } + }, + { + "tier": 4.0, + "symbol": "AMB/USDT:USDT", + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "4", + "initialLeverage": "4", + "notionalCap": "600000", + "notionalFloor": "500000", + "maintMarginRatio": "0.125", + "cum": "23125.0" } }, { "tier": 5.0, "symbol": "AMB/USDT:USDT", "currency": "USDT", - "minNotional": 500000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 600000.0, + "maxNotional": 700000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, "info": { "bracket": "5", - "initialLeverage": "4", - "notionalCap": "1000000", - "notionalFloor": "500000", - "maintMarginRatio": "0.125", - "cum": "23150.0" + "initialLeverage": "2", + "notionalCap": "700000", + "notionalFloor": "600000", + "maintMarginRatio": "0.25", + "cum": "98125.0" } }, { "tier": 6.0, "symbol": "AMB/USDT:USDT", "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, - "info": { - "bracket": "6", - "initialLeverage": "2", - "notionalCap": "3000000", - "notionalFloor": "1000000", - "maintMarginRatio": "0.25", - "cum": "148150.0" - } - }, - { - "tier": 7.0, - "symbol": "AMB/USDT:USDT", - "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 3500000.0, + "minNotional": 700000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "7", + "bracket": "6", "initialLeverage": "1", - "notionalCap": "3500000", - "notionalFloor": "3000000", + "notionalCap": "1000000", + "notionalFloor": "700000", "maintMarginRatio": "0.5", - "cum": "898150.0" + "cum": "273125.0" } } ], @@ -6379,13 +6362,13 @@ "symbol": "APE/USDT:USDT", "currency": "USDT", "minNotional": 1000000.0, - "maxNotional": 5000000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "6", "initialLeverage": "10", - "notionalCap": "5000000", + "notionalCap": "3000000", "notionalFloor": "1000000", "maintMarginRatio": "0.05", "cum": "28337.5" @@ -6395,68 +6378,68 @@ "tier": 7.0, "symbol": "APE/USDT:USDT", "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "minNotional": 3000000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "7", "initialLeverage": "5", - "notionalCap": "10000000", - "notionalFloor": "5000000", + "notionalCap": "4000000", + "notionalFloor": "3000000", "maintMarginRatio": "0.1", - "cum": "278337.5" + "cum": "178337.5" } }, { "tier": 8.0, "symbol": "APE/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 12500000.0, + "minNotional": 4000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "8", "initialLeverage": "4", - "notionalCap": "12500000", - "notionalFloor": "10000000", + "notionalCap": "5000000", + "notionalFloor": "4000000", "maintMarginRatio": "0.125", - "cum": "528337.5" + "cum": "278337.5" } }, { "tier": 9.0, "symbol": "APE/USDT:USDT", "currency": "USDT", - "minNotional": 12500000.0, - "maxNotional": 25000000.0, + "minNotional": 5000000.0, + "maxNotional": 6000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "9", "initialLeverage": "2", - "notionalCap": "25000000", - "notionalFloor": "12500000", + "notionalCap": "6000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.25", - "cum": "2090837.5" + "cum": "903337.5" } }, { "tier": 10.0, "symbol": "APE/USDT:USDT", "currency": "USDT", - "minNotional": 25000000.0, - "maxNotional": 50000000.0, + "minNotional": 6000000.0, + "maxNotional": 7000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "10", "initialLeverage": "1", - "notionalCap": "50000000", - "notionalFloor": "25000000", + "notionalCap": "7000000", + "notionalFloor": "6000000", "maintMarginRatio": "0.5", - "cum": "8340837.5" + "cum": "2403337.5" } } ], @@ -6689,13 +6672,13 @@ "symbol": "APT/USDT:USDT", "currency": "USDT", "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "maxNotional": 7000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "10000000", + "notionalCap": "7000000", "notionalFloor": "5000000", "maintMarginRatio": "0.1", "cum": "282550.0" @@ -6705,51 +6688,51 @@ "tier": 7.0, "symbol": "APT/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 12500000.0, + "minNotional": 7000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "12500000", - "notionalFloor": "10000000", + "notionalCap": "8000000", + "notionalFloor": "7000000", "maintMarginRatio": "0.125", - "cum": "532550.0" + "cum": "457550.0" } }, { "tier": 8.0, "symbol": "APT/USDT:USDT", "currency": "USDT", - "minNotional": 12500000.0, - "maxNotional": 25000000.0, + "minNotional": 8000000.0, + "maxNotional": 9000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "25000000", - "notionalFloor": "12500000", + "notionalCap": "9000000", + "notionalFloor": "8000000", "maintMarginRatio": "0.25", - "cum": "2095050.0" + "cum": "1457550.0" } }, { "tier": 9.0, "symbol": "APT/USDT:USDT", "currency": "USDT", - "minNotional": 25000000.0, - "maxNotional": 50000000.0, + "minNotional": 9000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "50000000", - "notionalFloor": "25000000", + "notionalCap": "10000000", + "notionalFloor": "9000000", "maintMarginRatio": "0.5", - "cum": "8345050.0" + "cum": "3707550.0" } } ], @@ -9269,6 +9252,161 @@ } } ], + "B3/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "B3/USDT:USDT", + "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, + "symbol": "B3/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 20.0, + "info": { + "bracket": "2", + "initialLeverage": "20", + "notionalCap": "10000", + "notionalFloor": "5000", + "maintMarginRatio": "0.015", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "B3/USDT:USDT", + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 15.0, + "info": { + "bracket": "3", + "initialLeverage": "15", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "symbol": "B3/USDT:USDT", + "currency": "USDT", + "minNotional": 30000.0, + "maxNotional": 60000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 10.0, + "info": { + "bracket": "4", + "initialLeverage": "10", + "notionalCap": "60000", + "notionalFloor": "30000", + "maintMarginRatio": "0.025", + "cum": "225.0" + } + }, + { + "tier": 5.0, + "symbol": "B3/USDT:USDT", + "currency": "USDT", + "minNotional": 60000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 8.0, + "info": { + "bracket": "5", + "initialLeverage": "8", + "notionalCap": "300000", + "notionalFloor": "60000", + "maintMarginRatio": "0.05", + "cum": "1725.0" + } + }, + { + "tier": 6.0, + "symbol": "B3/USDT:USDT", + "currency": "USDT", + "minNotional": 300000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "600000", + "notionalFloor": "300000", + "maintMarginRatio": "0.1", + "cum": "16725.0" + } + }, + { + "tier": 7.0, + "symbol": "B3/USDT:USDT", + "currency": "USDT", + "minNotional": 600000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "600000", + "maintMarginRatio": "0.125", + "cum": "31725.0" + } + }, + { + "tier": 8.0, + "symbol": "B3/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "125475.0" + } + }, + { + "tier": 9.0, + "symbol": "B3/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "500475.0" + } + } + ], "BADGER/USDT:USDT": [ { "tier": 1.0, @@ -9277,10 +9415,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 10.0, "info": { "bracket": "1", - "initialLeverage": "50", + "initialLeverage": "10", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.015", @@ -9294,10 +9432,10 @@ "minNotional": 5000.0, "maxNotional": 25000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 8.0, "info": { "bracket": "2", - "initialLeverage": "20", + "initialLeverage": "8", "notionalCap": "25000", "notionalFloor": "5000", "maintMarginRatio": "0.025", @@ -9311,10 +9449,10 @@ "minNotional": 25000.0, "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 6.0, "info": { "bracket": "3", - "initialLeverage": "10", + "initialLeverage": "6", "notionalCap": "100000", "notionalFloor": "25000", "maintMarginRatio": "0.05", @@ -9621,15 +9759,15 @@ "symbol": "BAN/USDT:USDT", "currency": "USDT", "minNotional": 0.0, - "maxNotional": 10000.0, - "maintenanceMarginRate": 0.01, - "maxLeverage": 10.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 8.0, "info": { "bracket": "1", - "initialLeverage": "10", - "notionalCap": "10000", + "initialLeverage": "8", + "notionalCap": "30000", "notionalFloor": "0", - "maintMarginRatio": "0.01", + "maintMarginRatio": "0.015", "cum": "0.0" } }, @@ -9637,136 +9775,119 @@ "tier": 2.0, "symbol": "BAN/USDT:USDT", "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 30000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 9.0, + "minNotional": 30000.0, + "maxNotional": 150000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 7.0, "info": { "bracket": "2", - "initialLeverage": "9", - "notionalCap": "30000", - "notionalFloor": "10000", - "maintMarginRatio": "0.015", - "cum": "50.0" + "initialLeverage": "7", + "notionalCap": "150000", + "notionalFloor": "30000", + "maintMarginRatio": "0.02", + "cum": "150.0" } }, { "tier": 3.0, "symbol": "BAN/USDT:USDT", "currency": "USDT", - "minNotional": 30000.0, - "maxNotional": 150000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 8.0, + "minNotional": 150000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 6.0, "info": { "bracket": "3", - "initialLeverage": "8", - "notionalCap": "150000", - "notionalFloor": "30000", - "maintMarginRatio": "0.02", - "cum": "200.0" + "initialLeverage": "6", + "notionalCap": "300000", + "notionalFloor": "150000", + "maintMarginRatio": "0.025", + "cum": "900.0" } }, { "tier": 4.0, "symbol": "BAN/USDT:USDT", "currency": "USDT", - "minNotional": 150000.0, - "maxNotional": 300000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 7.0, + "minNotional": 300000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 5.0, "info": { "bracket": "4", - "initialLeverage": "7", - "notionalCap": "300000", - "notionalFloor": "150000", - "maintMarginRatio": "0.025", - "cum": "950.0" + "initialLeverage": "5", + "notionalCap": "1500000", + "notionalFloor": "300000", + "maintMarginRatio": "0.05", + "cum": "8400.0" } }, { "tier": 5.0, "symbol": "BAN/USDT:USDT", "currency": "USDT", - "minNotional": 300000.0, - "maxNotional": 1500000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 6.0, + "minNotional": 1500000.0, + "maxNotional": 1700000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 4.0, "info": { "bracket": "5", - "initialLeverage": "6", - "notionalCap": "1500000", - "notionalFloor": "300000", - "maintMarginRatio": "0.05", - "cum": "8450.0" + "initialLeverage": "4", + "notionalCap": "1700000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.1", + "cum": "83400.0" } }, { "tier": 6.0, "symbol": "BAN/USDT:USDT", "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, + "minNotional": 1700000.0, + "maxNotional": 1800000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 3.0, "info": { "bracket": "6", - "initialLeverage": "5", - "notionalCap": "3000000", - "notionalFloor": "1500000", - "maintMarginRatio": "0.1", - "cum": "83450.0" + "initialLeverage": "3", + "notionalCap": "1800000", + "notionalFloor": "1700000", + "maintMarginRatio": "0.125", + "cum": "125900.0" } }, { "tier": 7.0, "symbol": "BAN/USDT:USDT", "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 3500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, + "minNotional": 1800000.0, + "maxNotional": 1900000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, "info": { "bracket": "7", - "initialLeverage": "4", - "notionalCap": "3500000", - "notionalFloor": "3000000", - "maintMarginRatio": "0.125", - "cum": "158450.0" + "initialLeverage": "2", + "notionalCap": "1900000", + "notionalFloor": "1800000", + "maintMarginRatio": "0.25", + "cum": "350900.0" } }, { "tier": 8.0, "symbol": "BAN/USDT:USDT", "currency": "USDT", - "minNotional": 3500000.0, - "maxNotional": 4000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, - "info": { - "bracket": "8", - "initialLeverage": "2", - "notionalCap": "4000000", - "notionalFloor": "3500000", - "maintMarginRatio": "0.25", - "cum": "595950.0" - } - }, - { - "tier": 9.0, - "symbol": "BAN/USDT:USDT", - "currency": "USDT", - "minNotional": 4000000.0, - "maxNotional": 4100000.0, + "minNotional": 1900000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "9", + "bracket": "8", "initialLeverage": "1", - "notionalCap": "4100000", - "notionalFloor": "4000000", + "notionalCap": "2000000", + "notionalFloor": "1900000", "maintMarginRatio": "0.5", - "cum": "1595950.0" + "cum": "825900.0" } } ], @@ -10959,6 +11080,161 @@ } } ], + "BERA/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "BERA/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "BERA/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, + "info": { + "bracket": "2", + "initialLeverage": "50", + "notionalCap": "10000", + "notionalFloor": "5000", + "maintMarginRatio": "0.015", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "BERA/USDT:USDT", + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "symbol": "BERA/USDT:USDT", + "currency": "USDT", + "minNotional": 30000.0, + "maxNotional": 60000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "60000", + "notionalFloor": "30000", + "maintMarginRatio": "0.025", + "cum": "225.0" + } + }, + { + "tier": 5.0, + "symbol": "BERA/USDT:USDT", + "currency": "USDT", + "minNotional": 60000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "300000", + "notionalFloor": "60000", + "maintMarginRatio": "0.05", + "cum": "1725.0" + } + }, + { + "tier": 6.0, + "symbol": "BERA/USDT:USDT", + "currency": "USDT", + "minNotional": 300000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "600000", + "notionalFloor": "300000", + "maintMarginRatio": "0.1", + "cum": "16725.0" + } + }, + { + "tier": 7.0, + "symbol": "BERA/USDT:USDT", + "currency": "USDT", + "minNotional": 600000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "600000", + "maintMarginRatio": "0.125", + "cum": "31725.0" + } + }, + { + "tier": 8.0, + "symbol": "BERA/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "125475.0" + } + }, + { + "tier": 9.0, + "symbol": "BERA/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "500475.0" + } + } + ], "BICO/USDT:USDT": [ { "tier": 1.0, @@ -12137,15 +12413,15 @@ "symbol": "BNX/USDT:USDT", "currency": "USDT", "minNotional": 0.0, - "maxNotional": 10000.0, - "maintenanceMarginRate": 0.01, - "maxLeverage": 26.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 6.0, "info": { "bracket": "1", - "initialLeverage": "26", - "notionalCap": "10000", + "initialLeverage": "6", + "notionalCap": "200000", "notionalFloor": "0", - "maintMarginRatio": "0.01", + "maintMarginRatio": "0.025", "cum": "0.0" } }, @@ -12153,136 +12429,85 @@ "tier": 2.0, "symbol": "BNX/USDT:USDT", "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 20000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 25.0, + "minNotional": 200000.0, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 5.0, "info": { "bracket": "2", - "initialLeverage": "25", - "notionalCap": "20000", - "notionalFloor": "10000", - "maintMarginRatio": "0.015", - "cum": "50.0" + "initialLeverage": "5", + "notionalCap": "1000000", + "notionalFloor": "200000", + "maintMarginRatio": "0.05", + "cum": "5000.0" } }, { "tier": 3.0, "symbol": "BNX/USDT:USDT", "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 100000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 20.0, + "minNotional": 1000000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 4.0, "info": { "bracket": "3", - "initialLeverage": "20", - "notionalCap": "100000", - "notionalFloor": "20000", - "maintMarginRatio": "0.02", - "cum": "150.0" + "initialLeverage": "4", + "notionalCap": "2000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.1", + "cum": "55000.0" } }, { "tier": 4.0, "symbol": "BNX/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 200000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 15.0, + "minNotional": 2000000.0, + "maxNotional": 2300000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 3.0, "info": { "bracket": "4", - "initialLeverage": "15", - "notionalCap": "200000", - "notionalFloor": "100000", - "maintMarginRatio": "0.025", - "cum": "650.0" + "initialLeverage": "3", + "notionalCap": "2300000", + "notionalFloor": "2000000", + "maintMarginRatio": "0.125", + "cum": "105000.0" } }, { "tier": 5.0, "symbol": "BNX/USDT:USDT", "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "minNotional": 2300000.0, + "maxNotional": 2400000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, "info": { "bracket": "5", - "initialLeverage": "10", - "notionalCap": "1000000", - "notionalFloor": "200000", - "maintMarginRatio": "0.05", - "cum": "5650.0" + "initialLeverage": "2", + "notionalCap": "2400000", + "notionalFloor": "2300000", + "maintMarginRatio": "0.25", + "cum": "392500.0" } }, { "tier": 6.0, "symbol": "BNX/USDT:USDT", "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, - "info": { - "bracket": "6", - "initialLeverage": "5", - "notionalCap": "2000000", - "notionalFloor": "1000000", - "maintMarginRatio": "0.1", - "cum": "55650.0" - } - }, - { - "tier": 7.0, - "symbol": "BNX/USDT:USDT", - "currency": "USDT", - "minNotional": 2000000.0, + "minNotional": 2400000.0, "maxNotional": 2500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, - "info": { - "bracket": "7", - "initialLeverage": "4", - "notionalCap": "2500000", - "notionalFloor": "2000000", - "maintMarginRatio": "0.125", - "cum": "105650.0" - } - }, - { - "tier": 8.0, - "symbol": "BNX/USDT:USDT", - "currency": "USDT", - "minNotional": 2500000.0, - "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, - "info": { - "bracket": "8", - "initialLeverage": "2", - "notionalCap": "3000000", - "notionalFloor": "2500000", - "maintMarginRatio": "0.25", - "cum": "418150.0" - } - }, - { - "tier": 9.0, - "symbol": "BNX/USDT:USDT", - "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 3500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "9", + "bracket": "6", "initialLeverage": "1", - "notionalCap": "3500000", - "notionalFloor": "3000000", + "notionalCap": "2500000", + "notionalFloor": "2400000", "maintMarginRatio": "0.5", - "cum": "1168150.0" + "cum": "992500.0" } } ], @@ -12498,13 +12723,13 @@ "symbol": "BOME/USDT:USDT", "currency": "USDT", "minNotional": 600000.0, - "maxNotional": 3000000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "3000000", + "notionalCap": "1000000", "notionalFloor": "600000", "maintMarginRatio": "0.05", "cum": "16850.0" @@ -12514,68 +12739,68 @@ "tier": 6.0, "symbol": "BOME/USDT:USDT", "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 6000000.0, + "minNotional": 1000000.0, + "maxNotional": 1500000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "6000000", - "notionalFloor": "3000000", + "notionalCap": "1500000", + "notionalFloor": "1000000", "maintMarginRatio": "0.1", - "cum": "166850.0" + "cum": "66850.0" } }, { "tier": 7.0, "symbol": "BOME/USDT:USDT", "currency": "USDT", - "minNotional": 6000000.0, - "maxNotional": 7500000.0, + "minNotional": 1500000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "7500000", - "notionalFloor": "6000000", + "notionalCap": "2000000", + "notionalFloor": "1500000", "maintMarginRatio": "0.125", - "cum": "316850.0" + "cum": "104350.0" } }, { "tier": 8.0, "symbol": "BOME/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 15000000.0, + "minNotional": 2000000.0, + "maxNotional": 2500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "15000000", - "notionalFloor": "7500000", + "notionalCap": "2500000", + "notionalFloor": "2000000", "maintMarginRatio": "0.25", - "cum": "1254350.0" + "cum": "354350.0" } }, { "tier": 9.0, "symbol": "BOME/USDT:USDT", "currency": "USDT", - "minNotional": 15000000.0, - "maxNotional": 30000000.0, + "minNotional": 2500000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "30000000", - "notionalFloor": "15000000", + "notionalCap": "3000000", + "notionalFloor": "2500000", "maintMarginRatio": "0.5", - "cum": "5004350.0" + "cum": "979350.0" } } ], @@ -14929,13 +15154,13 @@ "symbol": "CFX/USDT:USDT", "currency": "USDT", "minNotional": 600000.0, - "maxNotional": 3000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "3000000", + "notionalCap": "2000000", "notionalFloor": "600000", "maintMarginRatio": "0.05", "cum": "17350.0" @@ -14945,68 +15170,68 @@ "tier": 6.0, "symbol": "CFX/USDT:USDT", "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 6000000.0, + "minNotional": 2000000.0, + "maxNotional": 2500000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "6000000", - "notionalFloor": "3000000", + "notionalCap": "2500000", + "notionalFloor": "2000000", "maintMarginRatio": "0.1", - "cum": "167350.0" + "cum": "117350.0" } }, { "tier": 7.0, "symbol": "CFX/USDT:USDT", "currency": "USDT", - "minNotional": 6000000.0, - "maxNotional": 7500000.0, + "minNotional": 2500000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "7500000", - "notionalFloor": "6000000", + "notionalCap": "3000000", + "notionalFloor": "2500000", "maintMarginRatio": "0.125", - "cum": "317350.0" + "cum": "179850.0" } }, { "tier": 8.0, "symbol": "CFX/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 18000000.0, + "minNotional": 3000000.0, + "maxNotional": 3500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "18000000", - "notionalFloor": "7500000", + "notionalCap": "3500000", + "notionalFloor": "3000000", "maintMarginRatio": "0.25", - "cum": "1254850.0" + "cum": "554850.0" } }, { "tier": 9.0, "symbol": "CFX/USDT:USDT", "currency": "USDT", - "minNotional": 18000000.0, - "maxNotional": 30000000.0, + "minNotional": 3500000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "30000000", - "notionalFloor": "18000000", + "notionalCap": "4000000", + "notionalFloor": "3500000", "maintMarginRatio": "0.5", - "cum": "5754850.0" + "cum": "1429850.0" } } ], @@ -19154,13 +19379,13 @@ "symbol": "DIA/USDT:USDT", "currency": "USDT", "minNotional": 200000.0, - "maxNotional": 1000000.0, + "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "1000000", + "notionalCap": "300000", "notionalFloor": "200000", "maintMarginRatio": "0.05", "cum": "5650.0" @@ -19170,68 +19395,68 @@ "tier": 6.0, "symbol": "DIA/USDT:USDT", "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "minNotional": 300000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "2000000", - "notionalFloor": "1000000", + "notionalCap": "500000", + "notionalFloor": "300000", "maintMarginRatio": "0.1", - "cum": "55650.0" + "cum": "20650.0" } }, { "tier": 7.0, "symbol": "DIA/USDT:USDT", "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 2500000.0, + "minNotional": 500000.0, + "maxNotional": 600000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "2500000", - "notionalFloor": "2000000", + "notionalCap": "600000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", - "cum": "105650.0" + "cum": "33150.0" } }, { "tier": 8.0, "symbol": "DIA/USDT:USDT", "currency": "USDT", - "minNotional": 2500000.0, - "maxNotional": 5000000.0, + "minNotional": 600000.0, + "maxNotional": 700000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "5000000", - "notionalFloor": "2500000", + "notionalCap": "700000", + "notionalFloor": "600000", "maintMarginRatio": "0.25", - "cum": "418150.0" + "cum": "108150.0" } }, { "tier": 9.0, "symbol": "DIA/USDT:USDT", "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "minNotional": 700000.0, + "maxNotional": 800000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "10000000", - "notionalFloor": "5000000", + "notionalCap": "800000", + "notionalFloor": "700000", "maintMarginRatio": "0.5", - "cum": "1668150.0" + "cum": "283150.0" } } ], @@ -19774,13 +19999,13 @@ "symbol": "DOGS/USDT:USDT", "currency": "USDT", "minNotional": 600000.0, - "maxNotional": 3000000.0, + "maxNotional": 1500000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "3000000", + "notionalCap": "1500000", "notionalFloor": "600000", "maintMarginRatio": "0.05", "cum": "16850.0" @@ -19790,68 +20015,68 @@ "tier": 6.0, "symbol": "DOGS/USDT:USDT", "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 6000000.0, + "minNotional": 1500000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "6000000", - "notionalFloor": "3000000", + "notionalCap": "2000000", + "notionalFloor": "1500000", "maintMarginRatio": "0.1", - "cum": "166850.0" + "cum": "91850.0" } }, { "tier": 7.0, "symbol": "DOGS/USDT:USDT", "currency": "USDT", - "minNotional": 6000000.0, - "maxNotional": 7500000.0, + "minNotional": 2000000.0, + "maxNotional": 2500000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "7500000", - "notionalFloor": "6000000", + "notionalCap": "2500000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", - "cum": "316850.0" + "cum": "141850.0" } }, { "tier": 8.0, "symbol": "DOGS/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 15000000.0, + "minNotional": 2500000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "15000000", - "notionalFloor": "7500000", + "notionalCap": "3000000", + "notionalFloor": "2500000", "maintMarginRatio": "0.25", - "cum": "1254350.0" + "cum": "454350.0" } }, { "tier": 9.0, "symbol": "DOGS/USDT:USDT", "currency": "USDT", - "minNotional": 15000000.0, - "maxNotional": 30000000.0, + "minNotional": 3000000.0, + "maxNotional": 3500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "30000000", - "notionalFloor": "15000000", + "notionalCap": "3500000", + "notionalFloor": "3000000", "maintMarginRatio": "0.5", - "cum": "5004350.0" + "cum": "1204350.0" } } ], @@ -20980,13 +21205,13 @@ "symbol": "EIGEN/USDT:USDT", "currency": "USDT", "minNotional": 600000.0, - "maxNotional": 3000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "3000000", + "notionalCap": "2000000", "notionalFloor": "600000", "maintMarginRatio": "0.05", "cum": "16850.0" @@ -20996,68 +21221,68 @@ "tier": 6.0, "symbol": "EIGEN/USDT:USDT", "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 6000000.0, + "minNotional": 2000000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "6000000", - "notionalFloor": "3000000", + "notionalCap": "3000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.1", - "cum": "166850.0" + "cum": "116850.0" } }, { "tier": 7.0, "symbol": "EIGEN/USDT:USDT", "currency": "USDT", - "minNotional": 6000000.0, - "maxNotional": 7500000.0, + "minNotional": 3000000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "7500000", - "notionalFloor": "6000000", + "notionalCap": "4000000", + "notionalFloor": "3000000", "maintMarginRatio": "0.125", - "cum": "316850.0" + "cum": "191850.0" } }, { "tier": 8.0, "symbol": "EIGEN/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 15000000.0, + "minNotional": 4000000.0, + "maxNotional": 4500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "15000000", - "notionalFloor": "7500000", + "notionalCap": "4500000", + "notionalFloor": "4000000", "maintMarginRatio": "0.25", - "cum": "1254350.0" + "cum": "691850.0" } }, { "tier": 9.0, "symbol": "EIGEN/USDT:USDT", "currency": "USDT", - "minNotional": 15000000.0, - "maxNotional": 30000000.0, + "minNotional": 4500000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "30000000", - "notionalFloor": "15000000", + "notionalCap": "5000000", + "notionalFloor": "4500000", "maintMarginRatio": "0.5", - "cum": "5004350.0" + "cum": "1816850.0" } } ], @@ -21755,13 +21980,13 @@ "symbol": "EOS/USDT:USDT", "currency": "USDT", "minNotional": 2000000.0, - "maxNotional": 5000000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "7", "initialLeverage": "5", - "notionalCap": "5000000", + "notionalCap": "3000000", "notionalFloor": "2000000", "maintMarginRatio": "0.1", "cum": "114450.0" @@ -21771,51 +21996,51 @@ "tier": 8.0, "symbol": "EOS/USDT:USDT", "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 20000000.0, + "minNotional": 3000000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "8", "initialLeverage": "4", - "notionalCap": "20000000", - "notionalFloor": "5000000", + "notionalCap": "4000000", + "notionalFloor": "3000000", "maintMarginRatio": "0.125", - "cum": "239450.0" + "cum": "189450.0" } }, { "tier": 9.0, "symbol": "EOS/USDT:USDT", "currency": "USDT", - "minNotional": 20000000.0, - "maxNotional": 30000000.0, + "minNotional": 4000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "9", "initialLeverage": "2", - "notionalCap": "30000000", - "notionalFloor": "20000000", + "notionalCap": "5000000", + "notionalFloor": "4000000", "maintMarginRatio": "0.25", - "cum": "2739450.0" + "cum": "689450.0" } }, { "tier": 10.0, "symbol": "EOS/USDT:USDT", "currency": "USDT", - "minNotional": 30000000.0, - "maxNotional": 50000000.0, + "minNotional": 5000000.0, + "maxNotional": 6000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "10", "initialLeverage": "1", - "notionalCap": "50000000", - "notionalFloor": "30000000", + "notionalCap": "6000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.5", - "cum": "10239450.0" + "cum": "1939450.0" } } ], @@ -21910,13 +22135,13 @@ "symbol": "ETC/USDT:USDT", "currency": "USDT", "minNotional": 800000.0, - "maxNotional": 4000000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "6", "initialLeverage": "10", - "notionalCap": "4000000", + "notionalCap": "3000000", "notionalFloor": "800000", "maintMarginRatio": "0.05", "cum": "22700.0" @@ -21926,68 +22151,68 @@ "tier": 7.0, "symbol": "ETC/USDT:USDT", "currency": "USDT", - "minNotional": 4000000.0, - "maxNotional": 8000000.0, + "minNotional": 3000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "7", "initialLeverage": "5", - "notionalCap": "8000000", - "notionalFloor": "4000000", + "notionalCap": "5000000", + "notionalFloor": "3000000", "maintMarginRatio": "0.1", - "cum": "222700.0" + "cum": "172700.0" } }, { "tier": 8.0, "symbol": "ETC/USDT:USDT", "currency": "USDT", - "minNotional": 8000000.0, - "maxNotional": 20000000.0, + "minNotional": 5000000.0, + "maxNotional": 7000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "8", "initialLeverage": "4", - "notionalCap": "20000000", - "notionalFloor": "8000000", + "notionalCap": "7000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.125", - "cum": "422700.0" + "cum": "297700.0" } }, { "tier": 9.0, "symbol": "ETC/USDT:USDT", "currency": "USDT", - "minNotional": 20000000.0, - "maxNotional": 30000000.0, + "minNotional": 7000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "9", "initialLeverage": "2", - "notionalCap": "30000000", - "notionalFloor": "20000000", + "notionalCap": "8000000", + "notionalFloor": "7000000", "maintMarginRatio": "0.25", - "cum": "2922700.0" + "cum": "1172700.0" } }, { "tier": 10.0, "symbol": "ETC/USDT:USDT", "currency": "USDT", - "minNotional": 30000000.0, - "maxNotional": 50000000.0, + "minNotional": 8000000.0, + "maxNotional": 9000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "10", "initialLeverage": "1", - "notionalCap": "50000000", - "notionalFloor": "30000000", + "notionalCap": "9000000", + "notionalFloor": "8000000", "maintMarginRatio": "0.5", - "cum": "10422700.0" + "cum": "3172700.0" } } ], @@ -23135,10 +23360,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -23152,10 +23377,10 @@ "minNotional": 5000.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "10000", "notionalFloor": "5000", "maintMarginRatio": "0.015", @@ -23169,10 +23394,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.02", @@ -23186,10 +23411,10 @@ "minNotional": 30000.0, "maxNotional": 60000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "60000", "notionalFloor": "30000", "maintMarginRatio": "0.025", @@ -23203,10 +23428,10 @@ "minNotional": 60000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "300000", "notionalFloor": "60000", "maintMarginRatio": "0.05", @@ -23269,13 +23494,13 @@ "symbol": "ETHW/USDT:USDT", "currency": "USDT", "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "3000000", + "notionalCap": "2000000", "notionalFloor": "1500000", "maintMarginRatio": "0.5", "cum": "500475.0" @@ -23511,13 +23736,13 @@ "symbol": "FET/USDT:USDT", "currency": "USDT", "minNotional": 1000000.0, - "maxNotional": 5000000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "5000000", + "notionalCap": "3000000", "notionalFloor": "1000000", "maintMarginRatio": "0.05", "cum": "28050.0" @@ -23527,68 +23752,68 @@ "tier": 6.0, "symbol": "FET/USDT:USDT", "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "minNotional": 3000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "10000000", - "notionalFloor": "5000000", + "notionalCap": "5000000", + "notionalFloor": "3000000", "maintMarginRatio": "0.1", - "cum": "278050.0" + "cum": "178050.0" } }, { "tier": 7.0, "symbol": "FET/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 12500000.0, + "minNotional": 5000000.0, + "maxNotional": 7000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "12500000", - "notionalFloor": "10000000", + "notionalCap": "7000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.125", - "cum": "528050.0" + "cum": "303050.0" } }, { "tier": 8.0, "symbol": "FET/USDT:USDT", "currency": "USDT", - "minNotional": 12500000.0, - "maxNotional": 25000000.0, + "minNotional": 7000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "25000000", - "notionalFloor": "12500000", + "notionalCap": "8000000", + "notionalFloor": "7000000", "maintMarginRatio": "0.25", - "cum": "2090550.0" + "cum": "1178050.0" } }, { "tier": 9.0, "symbol": "FET/USDT:USDT", "currency": "USDT", - "minNotional": 25000000.0, - "maxNotional": 50000000.0, + "minNotional": 8000000.0, + "maxNotional": 9000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "50000000", - "notionalFloor": "25000000", + "notionalCap": "9000000", + "notionalFloor": "8000000", "maintMarginRatio": "0.5", - "cum": "8340550.0" + "cum": "3178050.0" } } ], @@ -25668,10 +25893,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "1", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.015", @@ -25685,10 +25910,10 @@ "minNotional": 5000.0, "maxNotional": 20000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "2", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "20000", "notionalFloor": "5000", "maintMarginRatio": "0.02", @@ -25702,10 +25927,10 @@ "minNotional": 20000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "3", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "30000", "notionalFloor": "20000", "maintMarginRatio": "0.025", @@ -25719,10 +25944,10 @@ "minNotional": 30000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "4", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "300000", "notionalFloor": "30000", "maintMarginRatio": "0.05", @@ -25768,13 +25993,13 @@ "symbol": "GLM/USDT:USDT", "currency": "USDT", "minNotional": 750000.0, - "maxNotional": 1500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "7", "initialLeverage": "2", - "notionalCap": "1500000", + "notionalCap": "1000000", "notionalFloor": "750000", "maintMarginRatio": "0.25", "cum": "124625.0" @@ -25784,17 +26009,17 @@ "tier": 8.0, "symbol": "GLM/USDT:USDT", "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "minNotional": 1000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "8", "initialLeverage": "1", - "notionalCap": "3000000", - "notionalFloor": "1500000", + "notionalCap": "2000000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", - "cum": "499625.0" + "cum": "374625.0" } } ], @@ -26218,13 +26443,13 @@ "symbol": "GOAT/USDT:USDT", "currency": "USDT", "minNotional": 800000.0, - "maxNotional": 4000000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 8.0, "info": { "bracket": "5", "initialLeverage": "8", - "notionalCap": "4000000", + "notionalCap": "3000000", "notionalFloor": "800000", "maintMarginRatio": "0.05", "cum": "22450.0" @@ -26234,68 +26459,189 @@ "tier": 6.0, "symbol": "GOAT/USDT:USDT", "currency": "USDT", - "minNotional": 4000000.0, - "maxNotional": 8000000.0, + "minNotional": 3000000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "8000000", - "notionalFloor": "4000000", + "notionalCap": "4000000", + "notionalFloor": "3000000", "maintMarginRatio": "0.1", - "cum": "222450.0" + "cum": "172450.0" } }, { "tier": 7.0, "symbol": "GOAT/USDT:USDT", "currency": "USDT", - "minNotional": 8000000.0, - "maxNotional": 10000000.0, + "minNotional": 4000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "10000000", - "notionalFloor": "8000000", + "notionalCap": "5000000", + "notionalFloor": "4000000", "maintMarginRatio": "0.125", - "cum": "422450.0" + "cum": "272450.0" } }, { "tier": 8.0, "symbol": "GOAT/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 20000000.0, + "minNotional": 5000000.0, + "maxNotional": 5500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "20000000", - "notionalFloor": "10000000", + "notionalCap": "5500000", + "notionalFloor": "5000000", "maintMarginRatio": "0.25", - "cum": "1672450.0" + "cum": "897450.0" } }, { "tier": 9.0, "symbol": "GOAT/USDT:USDT", "currency": "USDT", - "minNotional": 20000000.0, - "maxNotional": 21000000.0, + "minNotional": 5500000.0, + "maxNotional": 6000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "21000000", - "notionalFloor": "20000000", + "notionalCap": "6000000", + "notionalFloor": "5500000", "maintMarginRatio": "0.5", - "cum": "6672450.0" + "cum": "2272450.0" + } + } + ], + "GPS/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "GPS/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.02", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "GPS/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "2", + "initialLeverage": "20", + "notionalCap": "25000", + "notionalFloor": "5000", + "maintMarginRatio": "0.025", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "GPS/USDT:USDT", + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "650.0" + } + }, + { + "tier": 4.0, + "symbol": "GPS/USDT:USDT", + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "500000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "10650.0" + } + }, + { + "tier": 5.0, + "symbol": "GPS/USDT:USDT", + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "5", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "500000", + "maintMarginRatio": "0.125", + "cum": "23150.0" + } + }, + { + "tier": 6.0, + "symbol": "GPS/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "6", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "116900.0" + } + }, + { + "tier": 7.0, + "symbol": "GPS/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "491900.0" } } ], @@ -26462,10 +26808,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -26479,10 +26825,10 @@ "minNotional": 5000.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "10000", "notionalFloor": "5000", "maintMarginRatio": "0.015", @@ -26496,10 +26842,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.02", @@ -26513,10 +26859,10 @@ "minNotional": 30000.0, "maxNotional": 60000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "60000", "notionalFloor": "30000", "maintMarginRatio": "0.025", @@ -26530,10 +26876,10 @@ "minNotional": 60000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "300000", "notionalFloor": "60000", "maintMarginRatio": "0.05", @@ -27040,6 +27386,161 @@ } } ], + "HEI/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "HEI/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "HEI/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, + "info": { + "bracket": "2", + "initialLeverage": "50", + "notionalCap": "10000", + "notionalFloor": "5000", + "maintMarginRatio": "0.015", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "HEI/USDT:USDT", + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "symbol": "HEI/USDT:USDT", + "currency": "USDT", + "minNotional": 30000.0, + "maxNotional": 60000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "60000", + "notionalFloor": "30000", + "maintMarginRatio": "0.025", + "cum": "225.0" + } + }, + { + "tier": 5.0, + "symbol": "HEI/USDT:USDT", + "currency": "USDT", + "minNotional": 60000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "300000", + "notionalFloor": "60000", + "maintMarginRatio": "0.05", + "cum": "1725.0" + } + }, + { + "tier": 6.0, + "symbol": "HEI/USDT:USDT", + "currency": "USDT", + "minNotional": 300000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "600000", + "notionalFloor": "300000", + "maintMarginRatio": "0.1", + "cum": "16725.0" + } + }, + { + "tier": 7.0, + "symbol": "HEI/USDT:USDT", + "currency": "USDT", + "minNotional": 600000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "600000", + "maintMarginRatio": "0.125", + "cum": "31725.0" + } + }, + { + "tier": 8.0, + "symbol": "HEI/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "125475.0" + } + }, + { + "tier": 9.0, + "symbol": "HEI/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "500475.0" + } + } + ], "HFT/USDT:USDT": [ { "tier": 1.0, @@ -29029,13 +29530,13 @@ "symbol": "INJ/USDT:USDT", "currency": "USDT", "minNotional": 4000000.0, - "maxNotional": 8000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "8000000", + "notionalCap": "5000000", "notionalFloor": "4000000", "maintMarginRatio": "0.1", "cum": "222450.0" @@ -29045,51 +29546,51 @@ "tier": 7.0, "symbol": "INJ/USDT:USDT", "currency": "USDT", - "minNotional": 8000000.0, - "maxNotional": 10000000.0, + "minNotional": 5000000.0, + "maxNotional": 6000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "10000000", - "notionalFloor": "8000000", + "notionalCap": "6000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.125", - "cum": "422450.0" + "cum": "347450.0" } }, { "tier": 8.0, "symbol": "INJ/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 20000000.0, + "minNotional": 6000000.0, + "maxNotional": 7000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "20000000", - "notionalFloor": "10000000", + "notionalCap": "7000000", + "notionalFloor": "6000000", "maintMarginRatio": "0.25", - "cum": "1672450.0" + "cum": "1097450.0" } }, { "tier": 9.0, "symbol": "INJ/USDT:USDT", "currency": "USDT", - "minNotional": 20000000.0, - "maxNotional": 40000000.0, + "minNotional": 7000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "40000000", - "notionalFloor": "20000000", + "notionalCap": "8000000", + "notionalFloor": "7000000", "maintMarginRatio": "0.5", - "cum": "6672450.0" + "cum": "2847450.0" } } ], @@ -29662,6 +30163,144 @@ } } ], + "IP/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "IP/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 8.0, + "info": { + "bracket": "1", + "initialLeverage": "8", + "notionalCap": "10000", + "notionalFloor": "0", + "maintMarginRatio": "0.015", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "IP/USDT:USDT", + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 7.0, + "info": { + "bracket": "2", + "initialLeverage": "7", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "50.0" + } + }, + { + "tier": 3.0, + "symbol": "IP/USDT:USDT", + "currency": "USDT", + "minNotional": 30000.0, + "maxNotional": 60000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 6.0, + "info": { + "bracket": "3", + "initialLeverage": "6", + "notionalCap": "60000", + "notionalFloor": "30000", + "maintMarginRatio": "0.025", + "cum": "200.0" + } + }, + { + "tier": 4.0, + "symbol": "IP/USDT:USDT", + "currency": "USDT", + "minNotional": 60000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "300000", + "notionalFloor": "60000", + "maintMarginRatio": "0.05", + "cum": "1700.0" + } + }, + { + "tier": 5.0, + "symbol": "IP/USDT:USDT", + "currency": "USDT", + "minNotional": 300000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 4.0, + "info": { + "bracket": "5", + "initialLeverage": "4", + "notionalCap": "600000", + "notionalFloor": "300000", + "maintMarginRatio": "0.1", + "cum": "16700.0" + } + }, + { + "tier": 6.0, + "symbol": "IP/USDT:USDT", + "currency": "USDT", + "minNotional": 600000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 3.0, + "info": { + "bracket": "6", + "initialLeverage": "3", + "notionalCap": "750000", + "notionalFloor": "600000", + "maintMarginRatio": "0.125", + "cum": "31700.0" + } + }, + { + "tier": 7.0, + "symbol": "IP/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "7", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "125450.0" + } + }, + { + "tier": 8.0, + "symbol": "IP/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "8", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "500450.0" + } + } + ], "JASMY/USDT:USDT": [ { "tier": 1.0, @@ -30420,6 +31059,161 @@ } } ], + "KAITO/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "KAITO/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "KAITO/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, + "info": { + "bracket": "2", + "initialLeverage": "50", + "notionalCap": "10000", + "notionalFloor": "5000", + "maintMarginRatio": "0.015", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "KAITO/USDT:USDT", + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "symbol": "KAITO/USDT:USDT", + "currency": "USDT", + "minNotional": 30000.0, + "maxNotional": 60000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "60000", + "notionalFloor": "30000", + "maintMarginRatio": "0.025", + "cum": "225.0" + } + }, + { + "tier": 5.0, + "symbol": "KAITO/USDT:USDT", + "currency": "USDT", + "minNotional": 60000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "300000", + "notionalFloor": "60000", + "maintMarginRatio": "0.05", + "cum": "1725.0" + } + }, + { + "tier": 6.0, + "symbol": "KAITO/USDT:USDT", + "currency": "USDT", + "minNotional": 300000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "600000", + "notionalFloor": "300000", + "maintMarginRatio": "0.1", + "cum": "16725.0" + } + }, + { + "tier": 7.0, + "symbol": "KAITO/USDT:USDT", + "currency": "USDT", + "minNotional": 600000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "600000", + "maintMarginRatio": "0.125", + "cum": "31725.0" + } + }, + { + "tier": 8.0, + "symbol": "KAITO/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "125475.0" + } + }, + { + "tier": 9.0, + "symbol": "KAITO/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "500475.0" + } + } + ], "KAS/USDT:USDT": [ { "tier": 1.0, @@ -31118,10 +31912,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -31135,10 +31929,10 @@ "minNotional": 5000.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "10000", "notionalFloor": "5000", "maintMarginRatio": "0.015", @@ -31152,10 +31946,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.02", @@ -31169,10 +31963,10 @@ "minNotional": 30000.0, "maxNotional": 60000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "60000", "notionalFloor": "30000", "maintMarginRatio": "0.025", @@ -31186,10 +31980,10 @@ "minNotional": 60000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "300000", "notionalFloor": "60000", "maintMarginRatio": "0.05", @@ -31235,13 +32029,13 @@ "symbol": "KMNO/USDT:USDT", "currency": "USDT", "minNotional": 750000.0, - "maxNotional": 1500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "1500000", + "notionalCap": "1000000", "notionalFloor": "750000", "maintMarginRatio": "0.25", "cum": "125475.0" @@ -31251,17 +32045,17 @@ "tier": 9.0, "symbol": "KMNO/USDT:USDT", "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "minNotional": 1000000.0, + "maxNotional": 1500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "3000000", - "notionalFloor": "1500000", + "notionalCap": "1500000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", - "cum": "500475.0" + "cum": "375475.0" } } ], @@ -31696,6 +32490,161 @@ } } ], + "LAYER/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "LAYER/USDT:USDT", + "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, + "symbol": "LAYER/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 20.0, + "info": { + "bracket": "2", + "initialLeverage": "20", + "notionalCap": "10000", + "notionalFloor": "5000", + "maintMarginRatio": "0.015", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "LAYER/USDT:USDT", + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 15.0, + "info": { + "bracket": "3", + "initialLeverage": "15", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "symbol": "LAYER/USDT:USDT", + "currency": "USDT", + "minNotional": 30000.0, + "maxNotional": 60000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 10.0, + "info": { + "bracket": "4", + "initialLeverage": "10", + "notionalCap": "60000", + "notionalFloor": "30000", + "maintMarginRatio": "0.025", + "cum": "225.0" + } + }, + { + "tier": 5.0, + "symbol": "LAYER/USDT:USDT", + "currency": "USDT", + "minNotional": 60000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 8.0, + "info": { + "bracket": "5", + "initialLeverage": "8", + "notionalCap": "300000", + "notionalFloor": "60000", + "maintMarginRatio": "0.05", + "cum": "1725.0" + } + }, + { + "tier": 6.0, + "symbol": "LAYER/USDT:USDT", + "currency": "USDT", + "minNotional": 300000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "600000", + "notionalFloor": "300000", + "maintMarginRatio": "0.1", + "cum": "16725.0" + } + }, + { + "tier": 7.0, + "symbol": "LAYER/USDT:USDT", + "currency": "USDT", + "minNotional": 600000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "600000", + "maintMarginRatio": "0.125", + "cum": "31725.0" + } + }, + { + "tier": 8.0, + "symbol": "LAYER/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "125475.0" + } + }, + { + "tier": 9.0, + "symbol": "LAYER/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 2000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "2000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "500475.0" + } + } + ], "LDO/USDT:USDT": [ { "tier": 1.0, @@ -35290,10 +36239,10 @@ "minNotional": 0.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -35307,10 +36256,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.015", @@ -35324,10 +36273,10 @@ "minNotional": 30000.0, "maxNotional": 150000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "150000", "notionalFloor": "30000", "maintMarginRatio": "0.02", @@ -35341,10 +36290,10 @@ "minNotional": 150000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "300000", "notionalFloor": "150000", "maintMarginRatio": "0.025", @@ -35358,10 +36307,10 @@ "minNotional": 300000.0, "maxNotional": 1500000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "1500000", "notionalFloor": "300000", "maintMarginRatio": "0.05", @@ -35390,13 +36339,13 @@ "symbol": "ME/USDT:USDT", "currency": "USDT", "minNotional": 3000000.0, - "maxNotional": 3750000.0, + "maxNotional": 3100000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "3750000", + "notionalCap": "3100000", "notionalFloor": "3000000", "maintMarginRatio": "0.125", "cum": "158450.0" @@ -35406,34 +36355,34 @@ "tier": 8.0, "symbol": "ME/USDT:USDT", "currency": "USDT", - "minNotional": 3750000.0, - "maxNotional": 7500000.0, + "minNotional": 3100000.0, + "maxNotional": 3300000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "7500000", - "notionalFloor": "3750000", + "notionalCap": "3300000", + "notionalFloor": "3100000", "maintMarginRatio": "0.25", - "cum": "627200.0" + "cum": "545950.0" } }, { "tier": 9.0, "symbol": "ME/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 15000000.0, + "minNotional": 3300000.0, + "maxNotional": 3500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "15000000", - "notionalFloor": "7500000", + "notionalCap": "3500000", + "notionalFloor": "3300000", "maintMarginRatio": "0.5", - "cum": "2502200.0" + "cum": "1370950.0" } } ], @@ -35908,13 +36857,13 @@ "symbol": "MEW/USDT:USDT", "currency": "USDT", "minNotional": 600000.0, - "maxNotional": 3000000.0, + "maxNotional": 900000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "3000000", + "notionalCap": "900000", "notionalFloor": "600000", "maintMarginRatio": "0.05", "cum": "16850.0" @@ -35924,68 +36873,68 @@ "tier": 6.0, "symbol": "MEW/USDT:USDT", "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 6000000.0, + "minNotional": 900000.0, + "maxNotional": 1200000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "6000000", - "notionalFloor": "3000000", + "notionalCap": "1200000", + "notionalFloor": "900000", "maintMarginRatio": "0.1", - "cum": "166850.0" + "cum": "61850.0" } }, { "tier": 7.0, "symbol": "MEW/USDT:USDT", "currency": "USDT", - "minNotional": 6000000.0, - "maxNotional": 7500000.0, + "minNotional": 1200000.0, + "maxNotional": 1500000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "7500000", - "notionalFloor": "6000000", + "notionalCap": "1500000", + "notionalFloor": "1200000", "maintMarginRatio": "0.125", - "cum": "316850.0" + "cum": "91850.0" } }, { "tier": 8.0, "symbol": "MEW/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 15000000.0, + "minNotional": 1500000.0, + "maxNotional": 1800000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "15000000", - "notionalFloor": "7500000", + "notionalCap": "1800000", + "notionalFloor": "1500000", "maintMarginRatio": "0.25", - "cum": "1254350.0" + "cum": "279350.0" } }, { "tier": 9.0, "symbol": "MEW/USDT:USDT", "currency": "USDT", - "minNotional": 15000000.0, - "maxNotional": 30000000.0, + "minNotional": 1800000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "30000000", - "notionalFloor": "15000000", + "notionalCap": "2000000", + "notionalFloor": "1800000", "maintMarginRatio": "0.5", - "cum": "5004350.0" + "cum": "729350.0" } } ], @@ -36252,13 +37201,13 @@ "symbol": "MKR/USDT:USDT", "currency": "USDT", "minNotional": 10000000.0, - "maxNotional": 20000000.0, + "maxNotional": 12000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "9", "initialLeverage": "2", - "notionalCap": "20000000", + "notionalCap": "12000000", "notionalFloor": "10000000", "maintMarginRatio": "0.25", "cum": "1672545.0" @@ -36268,17 +37217,17 @@ "tier": 10.0, "symbol": "MKR/USDT:USDT", "currency": "USDT", - "minNotional": 20000000.0, - "maxNotional": 40000000.0, + "minNotional": 12000000.0, + "maxNotional": 14000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "10", "initialLeverage": "1", - "notionalCap": "40000000", - "notionalFloor": "20000000", + "notionalCap": "14000000", + "notionalFloor": "12000000", "maintMarginRatio": "0.5", - "cum": "6672545.0" + "cum": "4672545.0" } } ], @@ -36528,13 +37477,13 @@ "symbol": "MOODENG/USDT:USDT", "currency": "USDT", "minNotional": 4000000.0, - "maxNotional": 8000000.0, + "maxNotional": 4500000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "8000000", + "notionalCap": "4500000", "notionalFloor": "4000000", "maintMarginRatio": "0.1", "cum": "222450.0" @@ -36544,51 +37493,51 @@ "tier": 7.0, "symbol": "MOODENG/USDT:USDT", "currency": "USDT", - "minNotional": 8000000.0, - "maxNotional": 10000000.0, + "minNotional": 4500000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "10000000", - "notionalFloor": "8000000", + "notionalCap": "5000000", + "notionalFloor": "4500000", "maintMarginRatio": "0.125", - "cum": "422450.0" + "cum": "334950.0" } }, { "tier": 8.0, "symbol": "MOODENG/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 20000000.0, + "minNotional": 5000000.0, + "maxNotional": 5500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "20000000", - "notionalFloor": "10000000", + "notionalCap": "5500000", + "notionalFloor": "5000000", "maintMarginRatio": "0.25", - "cum": "1672450.0" + "cum": "959950.0" } }, { "tier": 9.0, "symbol": "MOODENG/USDT:USDT", "currency": "USDT", - "minNotional": 20000000.0, - "maxNotional": 21000000.0, + "minNotional": 5500000.0, + "maxNotional": 6000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "21000000", - "notionalFloor": "20000000", + "notionalCap": "6000000", + "notionalFloor": "5500000", "maintMarginRatio": "0.5", - "cum": "6672450.0" + "cum": "2334950.0" } } ], @@ -36600,10 +37549,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -36617,10 +37566,10 @@ "minNotional": 5000.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "10000", "notionalFloor": "5000", "maintMarginRatio": "0.015", @@ -36634,10 +37583,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.02", @@ -36651,10 +37600,10 @@ "minNotional": 30000.0, "maxNotional": 60000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "60000", "notionalFloor": "30000", "maintMarginRatio": "0.025", @@ -36668,10 +37617,10 @@ "minNotional": 60000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "300000", "notionalFloor": "60000", "maintMarginRatio": "0.05", @@ -36734,13 +37683,13 @@ "symbol": "MORPHO/USDT:USDT", "currency": "USDT", "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "3000000", + "notionalCap": "2000000", "notionalFloor": "1500000", "maintMarginRatio": "0.5", "cum": "500475.0" @@ -37562,13 +38511,13 @@ "symbol": "NEAR/USDT:USDT", "currency": "USDT", "minNotional": 25000000.0, - "maxNotional": 50000000.0, + "maxNotional": 30000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "50000000", + "notionalCap": "30000000", "notionalFloor": "25000000", "maintMarginRatio": "0.25", "cum": "4181100.0" @@ -37578,17 +38527,17 @@ "tier": 9.0, "symbol": "NEAR/USDT:USDT", "currency": "USDT", - "minNotional": 50000000.0, - "maxNotional": 100000000.0, + "minNotional": 30000000.0, + "maxNotional": 35000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "100000000", - "notionalFloor": "50000000", + "notionalCap": "35000000", + "notionalFloor": "30000000", "maintMarginRatio": "0.5", - "cum": "16681100.0" + "cum": "11681100.0" } } ], @@ -37666,13 +38615,13 @@ "symbol": "NEIRO/USDT:USDT", "currency": "USDT", "minNotional": 1600000.0, - "maxNotional": 8000000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "8000000", + "notionalCap": "3000000", "notionalFloor": "1600000", "maintMarginRatio": "0.05", "cum": "44900.0" @@ -37682,68 +38631,68 @@ "tier": 6.0, "symbol": "NEIRO/USDT:USDT", "currency": "USDT", - "minNotional": 8000000.0, - "maxNotional": 16000000.0, + "minNotional": 3000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "16000000", - "notionalFloor": "8000000", + "notionalCap": "5000000", + "notionalFloor": "3000000", "maintMarginRatio": "0.1", - "cum": "444900.0" + "cum": "194900.0" } }, { "tier": 7.0, "symbol": "NEIRO/USDT:USDT", "currency": "USDT", - "minNotional": 16000000.0, - "maxNotional": 20000000.0, + "minNotional": 5000000.0, + "maxNotional": 7000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "20000000", - "notionalFloor": "16000000", + "notionalCap": "7000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.125", - "cum": "844900.0" + "cum": "319900.0" } }, { "tier": 8.0, "symbol": "NEIRO/USDT:USDT", "currency": "USDT", - "minNotional": 20000000.0, - "maxNotional": 40000000.0, + "minNotional": 7000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "40000000", - "notionalFloor": "20000000", + "notionalCap": "8000000", + "notionalFloor": "7000000", "maintMarginRatio": "0.25", - "cum": "3344900.0" + "cum": "1194900.0" } }, { "tier": 9.0, "symbol": "NEIRO/USDT:USDT", "currency": "USDT", - "minNotional": 40000000.0, - "maxNotional": 80000000.0, + "minNotional": 8000000.0, + "maxNotional": 9000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "80000000", - "notionalFloor": "40000000", + "notionalCap": "9000000", + "notionalFloor": "8000000", "maintMarginRatio": "0.5", - "cum": "13344900.0" + "cum": "3194900.0" } } ], @@ -38114,13 +39063,13 @@ "symbol": "NEO/USDT:USDT", "currency": "USDT", "minNotional": 800000.0, - "maxNotional": 2000000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "5", "initialLeverage": "5", - "notionalCap": "2000000", + "notionalCap": "1000000", "notionalFloor": "800000", "maintMarginRatio": "0.1", "cum": "50770.0" @@ -38130,51 +39079,51 @@ "tier": 6.0, "symbol": "NEO/USDT:USDT", "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 5000000.0, + "minNotional": 1000000.0, + "maxNotional": 1500000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "6", "initialLeverage": "4", - "notionalCap": "5000000", - "notionalFloor": "2000000", + "notionalCap": "1500000", + "notionalFloor": "1000000", "maintMarginRatio": "0.125", - "cum": "100770.0" + "cum": "75770.0" } }, { "tier": 7.0, "symbol": "NEO/USDT:USDT", "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 12000000.0, + "minNotional": 1500000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "7", "initialLeverage": "2", - "notionalCap": "12000000", - "notionalFloor": "5000000", + "notionalCap": "2000000", + "notionalFloor": "1500000", "maintMarginRatio": "0.25", - "cum": "725770.0" + "cum": "263270.0" } }, { "tier": 8.0, "symbol": "NEO/USDT:USDT", "currency": "USDT", - "minNotional": 12000000.0, - "maxNotional": 20000000.0, + "minNotional": 2000000.0, + "maxNotional": 2500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "8", "initialLeverage": "1", - "notionalCap": "20000000", - "notionalFloor": "12000000", + "notionalCap": "2500000", + "notionalFloor": "2000000", "maintMarginRatio": "0.5", - "cum": "3725770.0" + "cum": "763270.0" } } ], @@ -38615,13 +39564,13 @@ "symbol": "NOT/USDT:USDT", "currency": "USDT", "minNotional": 600000.0, - "maxNotional": 3000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "3000000", + "notionalCap": "2000000", "notionalFloor": "600000", "maintMarginRatio": "0.05", "cum": "16850.0" @@ -38631,68 +39580,68 @@ "tier": 6.0, "symbol": "NOT/USDT:USDT", "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 6000000.0, + "minNotional": 2000000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "6000000", - "notionalFloor": "3000000", + "notionalCap": "3000000", + "notionalFloor": "2000000", "maintMarginRatio": "0.1", - "cum": "166850.0" + "cum": "116850.0" } }, { "tier": 7.0, "symbol": "NOT/USDT:USDT", "currency": "USDT", - "minNotional": 6000000.0, - "maxNotional": 7500000.0, + "minNotional": 3000000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "7500000", - "notionalFloor": "6000000", + "notionalCap": "4000000", + "notionalFloor": "3000000", "maintMarginRatio": "0.125", - "cum": "316850.0" + "cum": "191850.0" } }, { "tier": 8.0, "symbol": "NOT/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 15000000.0, + "minNotional": 4000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "15000000", - "notionalFloor": "7500000", + "notionalCap": "5000000", + "notionalFloor": "4000000", "maintMarginRatio": "0.25", - "cum": "1254350.0" + "cum": "691850.0" } }, { "tier": 9.0, "symbol": "NOT/USDT:USDT", "currency": "USDT", - "minNotional": 15000000.0, - "maxNotional": 30000000.0, + "minNotional": 5000000.0, + "maxNotional": 6000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "30000000", - "notionalFloor": "15000000", + "notionalCap": "6000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.5", - "cum": "5004350.0" + "cum": "1941850.0" } } ], @@ -39220,15 +40169,15 @@ "symbol": "OM/USDT:USDT", "currency": "USDT", "minNotional": 0.0, - "maxNotional": 10000.0, - "maintenanceMarginRate": 0.01, - "maxLeverage": 10.0, + "maxNotional": 400000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 5.0, "info": { "bracket": "1", - "initialLeverage": "10", - "notionalCap": "10000", + "initialLeverage": "5", + "notionalCap": "400000", "notionalFloor": "0", - "maintMarginRatio": "0.01", + "maintMarginRatio": "0.05", "cum": "0.0" } }, @@ -39236,136 +40185,68 @@ "tier": 2.0, "symbol": "OM/USDT:USDT", "currency": "USDT", - "minNotional": 10000.0, - "maxNotional": 20000.0, - "maintenanceMarginRate": 0.015, - "maxLeverage": 9.0, + "minNotional": 400000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 4.0, "info": { "bracket": "2", - "initialLeverage": "9", - "notionalCap": "20000", - "notionalFloor": "10000", - "maintMarginRatio": "0.015", - "cum": "50.0" + "initialLeverage": "4", + "notionalCap": "1500000", + "notionalFloor": "400000", + "maintMarginRatio": "0.1", + "cum": "20000.0" } }, { "tier": 3.0, "symbol": "OM/USDT:USDT", "currency": "USDT", - "minNotional": 20000.0, - "maxNotional": 100000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 8.0, + "minNotional": 1500000.0, + "maxNotional": 1800000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 3.0, "info": { "bracket": "3", - "initialLeverage": "8", - "notionalCap": "100000", - "notionalFloor": "20000", - "maintMarginRatio": "0.02", - "cum": "150.0" + "initialLeverage": "3", + "notionalCap": "1800000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.125", + "cum": "57500.0" } }, { "tier": 4.0, "symbol": "OM/USDT:USDT", "currency": "USDT", - "minNotional": 100000.0, - "maxNotional": 200000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 7.0, + "minNotional": 1800000.0, + "maxNotional": 1900000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, "info": { "bracket": "4", - "initialLeverage": "7", - "notionalCap": "200000", - "notionalFloor": "100000", - "maintMarginRatio": "0.025", - "cum": "650.0" + "initialLeverage": "2", + "notionalCap": "1900000", + "notionalFloor": "1800000", + "maintMarginRatio": "0.25", + "cum": "282500.0" } }, { "tier": 5.0, "symbol": "OM/USDT:USDT", "currency": "USDT", - "minNotional": 200000.0, - "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.05, - "maxLeverage": 6.0, - "info": { - "bracket": "5", - "initialLeverage": "6", - "notionalCap": "1000000", - "notionalFloor": "200000", - "maintMarginRatio": "0.05", - "cum": "5650.0" - } - }, - { - "tier": 6.0, - "symbol": "OM/USDT:USDT", - "currency": "USDT", - "minNotional": 1000000.0, + "minNotional": 1900000.0, "maxNotional": 2000000.0, - "maintenanceMarginRate": 0.1, - "maxLeverage": 5.0, - "info": { - "bracket": "6", - "initialLeverage": "5", - "notionalCap": "2000000", - "notionalFloor": "1000000", - "maintMarginRatio": "0.1", - "cum": "55650.0" - } - }, - { - "tier": 7.0, - "symbol": "OM/USDT:USDT", - "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 2500000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 4.0, - "info": { - "bracket": "7", - "initialLeverage": "4", - "notionalCap": "2500000", - "notionalFloor": "2000000", - "maintMarginRatio": "0.125", - "cum": "105650.0" - } - }, - { - "tier": 8.0, - "symbol": "OM/USDT:USDT", - "currency": "USDT", - "minNotional": 2500000.0, - "maxNotional": 5000000.0, - "maintenanceMarginRate": 0.25, - "maxLeverage": 2.0, - "info": { - "bracket": "8", - "initialLeverage": "2", - "notionalCap": "5000000", - "notionalFloor": "2500000", - "maintMarginRatio": "0.25", - "cum": "418150.0" - } - }, - { - "tier": 9.0, - "symbol": "OM/USDT:USDT", - "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 5100000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "9", + "bracket": "5", "initialLeverage": "1", - "notionalCap": "5100000", - "notionalFloor": "5000000", + "notionalCap": "2000000", + "notionalFloor": "1900000", "maintMarginRatio": "0.5", - "cum": "1668150.0" + "cum": "757500.0" } } ], @@ -41511,13 +42392,13 @@ "symbol": "PEOPLE/USDT:USDT", "currency": "USDT", "minNotional": 400000.0, - "maxNotional": 2000000.0, + "maxNotional": 1500000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "2000000", + "notionalCap": "1500000", "notionalFloor": "400000", "maintMarginRatio": "0.05", "cum": "11250.0" @@ -41527,68 +42408,68 @@ "tier": 6.0, "symbol": "PEOPLE/USDT:USDT", "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 4000000.0, + "minNotional": 1500000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "4000000", - "notionalFloor": "2000000", + "notionalCap": "2000000", + "notionalFloor": "1500000", "maintMarginRatio": "0.1", - "cum": "111250.0" + "cum": "86250.0" } }, { "tier": 7.0, "symbol": "PEOPLE/USDT:USDT", "currency": "USDT", - "minNotional": 4000000.0, - "maxNotional": 5000000.0, + "minNotional": 2000000.0, + "maxNotional": 2500000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "5000000", - "notionalFloor": "4000000", + "notionalCap": "2500000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", - "cum": "211250.0" + "cum": "136250.0" } }, { "tier": 8.0, "symbol": "PEOPLE/USDT:USDT", "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "minNotional": 2500000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "10000000", - "notionalFloor": "5000000", + "notionalCap": "3000000", + "notionalFloor": "2500000", "maintMarginRatio": "0.25", - "cum": "836250.0" + "cum": "448750.0" } }, { "tier": 9.0, "symbol": "PEOPLE/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 20000000.0, + "minNotional": 3000000.0, + "maxNotional": 3500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "20000000", - "notionalFloor": "10000000", + "notionalCap": "3500000", + "notionalFloor": "3000000", "maintMarginRatio": "0.5", - "cum": "3336250.0" + "cum": "1198750.0" } } ], @@ -42322,13 +43203,13 @@ "symbol": "PNUT/USDT:USDT", "currency": "USDT", "minNotional": 1600000.0, - "maxNotional": 8000000.0, + "maxNotional": 6000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "8000000", + "notionalCap": "6000000", "notionalFloor": "1600000", "maintMarginRatio": "0.05", "cum": "44900.0" @@ -42338,68 +43219,68 @@ "tier": 6.0, "symbol": "PNUT/USDT:USDT", "currency": "USDT", - "minNotional": 8000000.0, - "maxNotional": 16000000.0, + "minNotional": 6000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "16000000", - "notionalFloor": "8000000", + "notionalCap": "10000000", + "notionalFloor": "6000000", "maintMarginRatio": "0.1", - "cum": "444900.0" + "cum": "344900.0" } }, { "tier": 7.0, "symbol": "PNUT/USDT:USDT", "currency": "USDT", - "minNotional": 16000000.0, - "maxNotional": 20000000.0, + "minNotional": 10000000.0, + "maxNotional": 12000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "20000000", - "notionalFloor": "16000000", + "notionalCap": "12000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.125", - "cum": "844900.0" + "cum": "594900.0" } }, { "tier": 8.0, "symbol": "PNUT/USDT:USDT", "currency": "USDT", - "minNotional": 20000000.0, - "maxNotional": 40000000.0, + "minNotional": 12000000.0, + "maxNotional": 14000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "40000000", - "notionalFloor": "20000000", + "notionalCap": "14000000", + "notionalFloor": "12000000", "maintMarginRatio": "0.25", - "cum": "3344900.0" + "cum": "2094900.0" } }, { "tier": 9.0, "symbol": "PNUT/USDT:USDT", "currency": "USDT", - "minNotional": 40000000.0, - "maxNotional": 80000000.0, + "minNotional": 14000000.0, + "maxNotional": 16000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "80000000", - "notionalFloor": "40000000", + "notionalCap": "16000000", + "notionalFloor": "14000000", "maintMarginRatio": "0.5", - "cum": "13344900.0" + "cum": "5594900.0" } } ], @@ -42494,13 +43375,13 @@ "symbol": "POL/USDT:USDT", "currency": "USDT", "minNotional": 3000000.0, - "maxNotional": 6000000.0, + "maxNotional": 3500000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "6000000", + "notionalCap": "3500000", "notionalFloor": "3000000", "maintMarginRatio": "0.1", "cum": "166850.0" @@ -42510,51 +43391,51 @@ "tier": 7.0, "symbol": "POL/USDT:USDT", "currency": "USDT", - "minNotional": 6000000.0, - "maxNotional": 7500000.0, + "minNotional": 3500000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "7500000", - "notionalFloor": "6000000", + "notionalCap": "4000000", + "notionalFloor": "3500000", "maintMarginRatio": "0.125", - "cum": "316850.0" + "cum": "254350.0" } }, { "tier": 8.0, "symbol": "POL/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 15000000.0, + "minNotional": 4000000.0, + "maxNotional": 4500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "15000000", - "notionalFloor": "7500000", + "notionalCap": "4500000", + "notionalFloor": "4000000", "maintMarginRatio": "0.25", - "cum": "1254350.0" + "cum": "754350.0" } }, { "tier": 9.0, "symbol": "POL/USDT:USDT", "currency": "USDT", - "minNotional": 15000000.0, - "maxNotional": 30000000.0, + "minNotional": 4500000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "30000000", - "notionalFloor": "15000000", + "notionalCap": "5000000", + "notionalFloor": "4500000", "maintMarginRatio": "0.5", - "cum": "5004350.0" + "cum": "1879350.0" } } ], @@ -42704,10 +43585,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -42721,10 +43602,10 @@ "minNotional": 5000.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "10000", "notionalFloor": "5000", "maintMarginRatio": "0.015", @@ -42738,10 +43619,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.02", @@ -42755,10 +43636,10 @@ "minNotional": 30000.0, "maxNotional": 60000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "60000", "notionalFloor": "30000", "maintMarginRatio": "0.025", @@ -42772,10 +43653,10 @@ "minNotional": 60000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "300000", "notionalFloor": "60000", "maintMarginRatio": "0.05", @@ -42838,13 +43719,13 @@ "symbol": "PONKE/USDT:USDT", "currency": "USDT", "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "3000000", + "notionalCap": "2000000", "notionalFloor": "1500000", "maintMarginRatio": "0.5", "cum": "500475.0" @@ -42925,13 +43806,13 @@ "symbol": "POPCAT/USDT:USDT", "currency": "USDT", "minNotional": 1000000.0, - "maxNotional": 5000000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 8.0, "info": { "bracket": "5", "initialLeverage": "8", - "notionalCap": "5000000", + "notionalCap": "3000000", "notionalFloor": "1000000", "maintMarginRatio": "0.05", "cum": "28050.0" @@ -42941,68 +43822,68 @@ "tier": 6.0, "symbol": "POPCAT/USDT:USDT", "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "minNotional": 3000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "10000000", - "notionalFloor": "5000000", + "notionalCap": "5000000", + "notionalFloor": "3000000", "maintMarginRatio": "0.1", - "cum": "278050.0" + "cum": "178050.0" } }, { "tier": 7.0, "symbol": "POPCAT/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 12500000.0, + "minNotional": 5000000.0, + "maxNotional": 6000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "12500000", - "notionalFloor": "10000000", + "notionalCap": "6000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.125", - "cum": "528050.0" + "cum": "303050.0" } }, { "tier": 8.0, "symbol": "POPCAT/USDT:USDT", "currency": "USDT", - "minNotional": 12500000.0, - "maxNotional": 25000000.0, + "minNotional": 6000000.0, + "maxNotional": 7000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "25000000", - "notionalFloor": "12500000", + "notionalCap": "7000000", + "notionalFloor": "6000000", "maintMarginRatio": "0.25", - "cum": "2090550.0" + "cum": "1053050.0" } }, { "tier": 9.0, "symbol": "POPCAT/USDT:USDT", "currency": "USDT", - "minNotional": 25000000.0, - "maxNotional": 30000000.0, + "minNotional": 7000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "30000000", - "notionalFloor": "25000000", + "notionalCap": "8000000", + "notionalFloor": "7000000", "maintMarginRatio": "0.5", - "cum": "8340550.0" + "cum": "2803050.0" } } ], @@ -44184,13 +45065,13 @@ "symbol": "RARE/USDT:USDT", "currency": "USDT", "minNotional": 300000.0, - "maxNotional": 1500000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "1500000", + "notionalCap": "500000", "notionalFloor": "300000", "maintMarginRatio": "0.05", "cum": "8450.0" @@ -44200,68 +45081,68 @@ "tier": 6.0, "symbol": "RARE/USDT:USDT", "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "minNotional": 500000.0, + "maxNotional": 600000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "3000000", - "notionalFloor": "1500000", + "notionalCap": "600000", + "notionalFloor": "500000", "maintMarginRatio": "0.1", - "cum": "83450.0" + "cum": "33450.0" } }, { "tier": 7.0, "symbol": "RARE/USDT:USDT", "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 3750000.0, + "minNotional": 600000.0, + "maxNotional": 700000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "3750000", - "notionalFloor": "3000000", + "notionalCap": "700000", + "notionalFloor": "600000", "maintMarginRatio": "0.125", - "cum": "158450.0" + "cum": "48450.0" } }, { "tier": 8.0, "symbol": "RARE/USDT:USDT", "currency": "USDT", - "minNotional": 3750000.0, - "maxNotional": 7500000.0, + "minNotional": 700000.0, + "maxNotional": 800000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "7500000", - "notionalFloor": "3750000", + "notionalCap": "800000", + "notionalFloor": "700000", "maintMarginRatio": "0.25", - "cum": "627200.0" + "cum": "135950.0" } }, { "tier": 9.0, "symbol": "RARE/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 15000000.0, + "minNotional": 800000.0, + "maxNotional": 900000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "15000000", - "notionalFloor": "7500000", + "notionalCap": "900000", + "notionalFloor": "800000", "maintMarginRatio": "0.5", - "cum": "2502200.0" + "cum": "335950.0" } } ], @@ -45530,13 +46411,13 @@ "symbol": "RLC/USDT:USDT", "currency": "USDT", "minNotional": 25000.0, - "maxNotional": 600000.0, + "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "3", "initialLeverage": "10", - "notionalCap": "600000", + "notionalCap": "300000", "notionalFloor": "25000", "maintMarginRatio": "0.05", "cum": "650.0" @@ -45546,68 +46427,68 @@ "tier": 4.0, "symbol": "RLC/USDT:USDT", "currency": "USDT", - "minNotional": 600000.0, - "maxNotional": 1600000.0, + "minNotional": 300000.0, + "maxNotional": 500000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "notionalCap": "1600000", - "notionalFloor": "600000", + "notionalCap": "500000", + "notionalFloor": "300000", "maintMarginRatio": "0.1", - "cum": "30650.0" + "cum": "15650.0" } }, { "tier": 5.0, "symbol": "RLC/USDT:USDT", "currency": "USDT", - "minNotional": 1600000.0, - "maxNotional": 2000000.0, + "minNotional": 500000.0, + "maxNotional": 600000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "notionalCap": "2000000", - "notionalFloor": "1600000", + "notionalCap": "600000", + "notionalFloor": "500000", "maintMarginRatio": "0.125", - "cum": "70650.0" + "cum": "28150.0" } }, { "tier": 6.0, "symbol": "RLC/USDT:USDT", "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 6000000.0, + "minNotional": 600000.0, + "maxNotional": 700000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "6", "initialLeverage": "2", - "notionalCap": "6000000", - "notionalFloor": "2000000", + "notionalCap": "700000", + "notionalFloor": "600000", "maintMarginRatio": "0.25", - "cum": "320650.0" + "cum": "103150.0" } }, { "tier": 7.0, "symbol": "RLC/USDT:USDT", "currency": "USDT", - "minNotional": 6000000.0, - "maxNotional": 10000000.0, + "minNotional": 700000.0, + "maxNotional": 800000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "7", "initialLeverage": "1", - "notionalCap": "10000000", - "notionalFloor": "6000000", + "notionalCap": "800000", + "notionalFloor": "700000", "maintMarginRatio": "0.5", - "cum": "1820650.0" + "cum": "278150.0" } } ], @@ -46205,10 +47086,10 @@ "minNotional": 0.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 10.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "10", "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -46222,10 +47103,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 9.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "9", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.015", @@ -46239,10 +47120,10 @@ "minNotional": 30000.0, "maxNotional": 150000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 8.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "8", "notionalCap": "150000", "notionalFloor": "30000", "maintMarginRatio": "0.02", @@ -46256,10 +47137,10 @@ "minNotional": 150000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 7.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "7", "notionalCap": "300000", "notionalFloor": "150000", "maintMarginRatio": "0.025", @@ -46273,10 +47154,10 @@ "minNotional": 300000.0, "maxNotional": 1500000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 6.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "6", "notionalCap": "1500000", "notionalFloor": "300000", "maintMarginRatio": "0.05", @@ -46288,13 +47169,13 @@ "symbol": "RUNE/USDT:USDT", "currency": "USDT", "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "3000000", + "notionalCap": "2000000", "notionalFloor": "1500000", "maintMarginRatio": "0.1", "cum": "83450.0" @@ -46304,51 +47185,51 @@ "tier": 7.0, "symbol": "RUNE/USDT:USDT", "currency": "USDT", - "minNotional": 3000000.0, - "maxNotional": 3750000.0, + "minNotional": 2000000.0, + "maxNotional": 2200000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "3750000", - "notionalFloor": "3000000", + "notionalCap": "2200000", + "notionalFloor": "2000000", "maintMarginRatio": "0.125", - "cum": "158450.0" + "cum": "133450.0" } }, { "tier": 8.0, "symbol": "RUNE/USDT:USDT", "currency": "USDT", - "minNotional": 3750000.0, - "maxNotional": 7500000.0, + "minNotional": 2200000.0, + "maxNotional": 2500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "7500000", - "notionalFloor": "3750000", + "notionalCap": "2500000", + "notionalFloor": "2200000", "maintMarginRatio": "0.25", - "cum": "627200.0" + "cum": "408450.0" } }, { "tier": 9.0, "symbol": "RUNE/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 15000000.0, + "minNotional": 2500000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "15000000", - "notionalFloor": "7500000", + "notionalCap": "3000000", + "notionalFloor": "2500000", "maintMarginRatio": "0.5", - "cum": "2502200.0" + "cum": "1033450.0" } } ], @@ -47063,13 +47944,13 @@ "symbol": "SAND/USDT:USDT", "currency": "USDT", "minNotional": 3000000.0, - "maxNotional": 6000000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "7", "initialLeverage": "5", - "notionalCap": "6000000", + "notionalCap": "4000000", "notionalFloor": "3000000", "maintMarginRatio": "0.1", "cum": "167250.0" @@ -47079,51 +47960,51 @@ "tier": 8.0, "symbol": "SAND/USDT:USDT", "currency": "USDT", - "minNotional": 6000000.0, - "maxNotional": 7500000.0, + "minNotional": 4000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "8", "initialLeverage": "4", - "notionalCap": "7500000", - "notionalFloor": "6000000", + "notionalCap": "5000000", + "notionalFloor": "4000000", "maintMarginRatio": "0.125", - "cum": "317250.0" + "cum": "267250.0" } }, { "tier": 9.0, "symbol": "SAND/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 15000000.0, + "minNotional": 5000000.0, + "maxNotional": 6000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "9", "initialLeverage": "2", - "notionalCap": "15000000", - "notionalFloor": "7500000", + "notionalCap": "6000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.25", - "cum": "1254750.0" + "cum": "892250.0" } }, { "tier": 10.0, "symbol": "SAND/USDT:USDT", "currency": "USDT", - "minNotional": 15000000.0, - "maxNotional": 30000000.0, + "minNotional": 6000000.0, + "maxNotional": 7000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "10", "initialLeverage": "1", - "notionalCap": "30000000", - "notionalFloor": "15000000", + "notionalCap": "7000000", + "notionalFloor": "6000000", "maintMarginRatio": "0.5", - "cum": "5004750.0" + "cum": "2392250.0" } } ], @@ -47804,13 +48685,13 @@ "symbol": "SEI/USDT:USDT", "currency": "USDT", "minNotional": 10000000.0, - "maxNotional": 12500000.0, + "maxNotional": 11000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "12500000", + "notionalCap": "11000000", "notionalFloor": "10000000", "maintMarginRatio": "0.125", "cum": "528050.0" @@ -47820,34 +48701,34 @@ "tier": 8.0, "symbol": "SEI/USDT:USDT", "currency": "USDT", - "minNotional": 12500000.0, - "maxNotional": 25000000.0, + "minNotional": 11000000.0, + "maxNotional": 12000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "25000000", - "notionalFloor": "12500000", + "notionalCap": "12000000", + "notionalFloor": "11000000", "maintMarginRatio": "0.25", - "cum": "2090550.0" + "cum": "1903050.0" } }, { "tier": 9.0, "symbol": "SEI/USDT:USDT", "currency": "USDT", - "minNotional": 25000000.0, - "maxNotional": 50000000.0, + "minNotional": 12000000.0, + "maxNotional": 13000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "50000000", - "notionalFloor": "25000000", + "notionalCap": "13000000", + "notionalFloor": "12000000", "maintMarginRatio": "0.5", - "cum": "8340550.0" + "cum": "4903050.0" } } ], @@ -47955,6 +48836,127 @@ } } ], + "SHELL/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "SHELL/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "1", + "initialLeverage": "25", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.02", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "SHELL/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "2", + "initialLeverage": "20", + "notionalCap": "25000", + "notionalFloor": "5000", + "maintMarginRatio": "0.025", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "SHELL/USDT:USDT", + "currency": "USDT", + "minNotional": 25000.0, + "maxNotional": 200000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "3", + "initialLeverage": "10", + "notionalCap": "200000", + "notionalFloor": "25000", + "maintMarginRatio": "0.05", + "cum": "650.0" + } + }, + { + "tier": 4.0, + "symbol": "SHELL/USDT:USDT", + "currency": "USDT", + "minNotional": 200000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "4", + "initialLeverage": "5", + "notionalCap": "500000", + "notionalFloor": "200000", + "maintMarginRatio": "0.1", + "cum": "10650.0" + } + }, + { + "tier": 5.0, + "symbol": "SHELL/USDT:USDT", + "currency": "USDT", + "minNotional": 500000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "5", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "500000", + "maintMarginRatio": "0.125", + "cum": "23150.0" + } + }, + { + "tier": 6.0, + "symbol": "SHELL/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "6", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "116900.0" + } + }, + { + "tier": 7.0, + "symbol": "SHELL/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "7", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "491900.0" + } + } + ], "SKL/USDT:USDT": [ { "tier": 1.0, @@ -48118,10 +49120,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -48135,10 +49137,10 @@ "minNotional": 5000.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "10000", "notionalFloor": "5000", "maintMarginRatio": "0.015", @@ -48152,10 +49154,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.02", @@ -48169,10 +49171,10 @@ "minNotional": 30000.0, "maxNotional": 60000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "60000", "notionalFloor": "30000", "maintMarginRatio": "0.025", @@ -48186,10 +49188,10 @@ "minNotional": 60000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "300000", "notionalFloor": "60000", "maintMarginRatio": "0.05", @@ -48235,13 +49237,13 @@ "symbol": "SLERF/USDT:USDT", "currency": "USDT", "minNotional": 750000.0, - "maxNotional": 1500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "1500000", + "notionalCap": "1000000", "notionalFloor": "750000", "maintMarginRatio": "0.25", "cum": "125475.0" @@ -48251,17 +49253,17 @@ "tier": 9.0, "symbol": "SLERF/USDT:USDT", "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "minNotional": 1000000.0, + "maxNotional": 1500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "3000000", - "notionalFloor": "1500000", + "notionalCap": "1500000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", - "cum": "500475.0" + "cum": "375475.0" } } ], @@ -49995,15 +50997,15 @@ "symbol": "STMX/USDT:USDT", "currency": "USDT", "minNotional": 0.0, - "maxNotional": 5000.0, - "maintenanceMarginRate": 0.02, - "maxLeverage": 10.0, + "maxNotional": 25000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 8.0, "info": { "bracket": "1", - "initialLeverage": "10", - "notionalCap": "5000", + "initialLeverage": "8", + "notionalCap": "25000", "notionalFloor": "0", - "maintMarginRatio": "0.02", + "maintMarginRatio": "0.025", "cum": "0.0" } }, @@ -50011,38 +51013,21 @@ "tier": 2.0, "symbol": "STMX/USDT:USDT", "currency": "USDT", - "minNotional": 5000.0, - "maxNotional": 25000.0, - "maintenanceMarginRate": 0.025, - "maxLeverage": 8.0, - "info": { - "bracket": "2", - "initialLeverage": "8", - "notionalCap": "25000", - "notionalFloor": "5000", - "maintMarginRatio": "0.025", - "cum": "25.0" - } - }, - { - "tier": 3.0, - "symbol": "STMX/USDT:USDT", - "currency": "USDT", "minNotional": 25000.0, "maxNotional": 100000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 6.0, "info": { - "bracket": "3", + "bracket": "2", "initialLeverage": "6", "notionalCap": "100000", "notionalFloor": "25000", "maintMarginRatio": "0.05", - "cum": "650.0" + "cum": "625.0" } }, { - "tier": 4.0, + "tier": 3.0, "symbol": "STMX/USDT:USDT", "currency": "USDT", "minNotional": 100000.0, @@ -50050,46 +51035,46 @@ "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { - "bracket": "4", + "bracket": "3", "initialLeverage": "5", "notionalCap": "250000", "notionalFloor": "100000", "maintMarginRatio": "0.1", - "cum": "5650.0" + "cum": "5625.0" + } + }, + { + "tier": 4.0, + "symbol": "STMX/USDT:USDT", + "currency": "USDT", + "minNotional": 250000.0, + "maxNotional": 500000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 2.0, + "info": { + "bracket": "4", + "initialLeverage": "2", + "notionalCap": "500000", + "notionalFloor": "250000", + "maintMarginRatio": "0.125", + "cum": "11875.0" } }, { "tier": 5.0, "symbol": "STMX/USDT:USDT", "currency": "USDT", - "minNotional": 250000.0, + "minNotional": 500000.0, "maxNotional": 1000000.0, - "maintenanceMarginRate": 0.125, - "maxLeverage": 2.0, - "info": { - "bracket": "5", - "initialLeverage": "2", - "notionalCap": "1000000", - "notionalFloor": "250000", - "maintMarginRatio": "0.125", - "cum": "11900.0" - } - }, - { - "tier": 6.0, - "symbol": "STMX/USDT:USDT", - "currency": "USDT", - "minNotional": 1000000.0, - "maxNotional": 1500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { - "bracket": "6", + "bracket": "5", "initialLeverage": "1", - "notionalCap": "1500000", - "notionalFloor": "1000000", + "notionalCap": "1000000", + "notionalFloor": "500000", "maintMarginRatio": "0.5", - "cum": "386900.0" + "cum": "199375.0" } } ], @@ -51481,10 +52466,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -51498,10 +52483,10 @@ "minNotional": 5000.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "10000", "notionalFloor": "5000", "maintMarginRatio": "0.015", @@ -51515,10 +52500,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.02", @@ -51532,10 +52517,10 @@ "minNotional": 30000.0, "maxNotional": 60000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "60000", "notionalFloor": "30000", "maintMarginRatio": "0.025", @@ -51549,10 +52534,10 @@ "minNotional": 60000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "300000", "notionalFloor": "60000", "maintMarginRatio": "0.05", @@ -51615,13 +52600,13 @@ "symbol": "SWARMS/USDT:USDT", "currency": "USDT", "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "3000000", + "notionalCap": "2000000", "notionalFloor": "1500000", "maintMarginRatio": "0.5", "cum": "500475.0" @@ -51636,10 +52621,10 @@ "minNotional": 0.0, "maxNotional": 5000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "5000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -51653,10 +52638,10 @@ "minNotional": 5000.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "10000", "notionalFloor": "5000", "maintMarginRatio": "0.015", @@ -51670,10 +52655,10 @@ "minNotional": 10000.0, "maxNotional": 30000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "30000", "notionalFloor": "10000", "maintMarginRatio": "0.02", @@ -51687,10 +52672,10 @@ "minNotional": 30000.0, "maxNotional": 60000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "60000", "notionalFloor": "30000", "maintMarginRatio": "0.025", @@ -51704,10 +52689,10 @@ "minNotional": 60000.0, "maxNotional": 300000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", + "initialLeverage": "8", "notionalCap": "300000", "notionalFloor": "60000", "maintMarginRatio": "0.05", @@ -51753,13 +52738,13 @@ "symbol": "SWELL/USDT:USDT", "currency": "USDT", "minNotional": 750000.0, - "maxNotional": 1500000.0, + "maxNotional": 1000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "1500000", + "notionalCap": "1000000", "notionalFloor": "750000", "maintMarginRatio": "0.25", "cum": "125475.0" @@ -51769,17 +52754,17 @@ "tier": 9.0, "symbol": "SWELL/USDT:USDT", "currency": "USDT", - "minNotional": 1500000.0, - "maxNotional": 3000000.0, + "minNotional": 1000000.0, + "maxNotional": 1500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "3000000", - "notionalFloor": "1500000", + "notionalCap": "1500000", + "notionalFloor": "1000000", "maintMarginRatio": "0.5", - "cum": "500475.0" + "cum": "375475.0" } } ], @@ -52719,13 +53704,13 @@ "symbol": "THETA/USDT:USDT", "currency": "USDT", "minNotional": 1000000.0, - "maxNotional": 2000000.0, + "maxNotional": 1500000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "4", "initialLeverage": "5", - "notionalCap": "2000000", + "notionalCap": "1500000", "notionalFloor": "1000000", "maintMarginRatio": "0.1", "cum": "57750.0" @@ -52735,68 +53720,68 @@ "tier": 5.0, "symbol": "THETA/USDT:USDT", "currency": "USDT", - "minNotional": 2000000.0, - "maxNotional": 5000000.0, + "minNotional": 1500000.0, + "maxNotional": 2000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "5", "initialLeverage": "4", - "notionalCap": "5000000", - "notionalFloor": "2000000", + "notionalCap": "2000000", + "notionalFloor": "1500000", "maintMarginRatio": "0.125", - "cum": "107750.0" + "cum": "95250.0" } }, { "tier": 6.0, "symbol": "THETA/USDT:USDT", "currency": "USDT", - "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "minNotional": 2000000.0, + "maxNotional": 2500000.0, "maintenanceMarginRate": 0.1665, "maxLeverage": 3.0, "info": { "bracket": "6", "initialLeverage": "3", - "notionalCap": "10000000", - "notionalFloor": "5000000", + "notionalCap": "2500000", + "notionalFloor": "2000000", "maintMarginRatio": "0.1665", - "cum": "315250.0" + "cum": "178250.0" } }, { "tier": 7.0, "symbol": "THETA/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 20000000.0, + "minNotional": 2500000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "7", "initialLeverage": "2", - "notionalCap": "20000000", - "notionalFloor": "10000000", + "notionalCap": "3000000", + "notionalFloor": "2500000", "maintMarginRatio": "0.25", - "cum": "1150250.0" + "cum": "387000.0" } }, { "tier": 8.0, "symbol": "THETA/USDT:USDT", "currency": "USDT", - "minNotional": 20000000.0, - "maxNotional": 30000000.0, + "minNotional": 3000000.0, + "maxNotional": 3500000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "8", "initialLeverage": "1", - "notionalCap": "30000000", - "notionalFloor": "20000000", + "notionalCap": "3500000", + "notionalFloor": "3000000", "maintMarginRatio": "0.5", - "cum": "6150250.0" + "cum": "1137000.0" } } ], @@ -53029,13 +54014,13 @@ "symbol": "TIA/USDT:USDT", "currency": "USDT", "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "maxNotional": 6000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "10000000", + "notionalCap": "6000000", "notionalFloor": "5000000", "maintMarginRatio": "0.1", "cum": "278050.0" @@ -53045,51 +54030,51 @@ "tier": 7.0, "symbol": "TIA/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 12500000.0, + "minNotional": 6000000.0, + "maxNotional": 7000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "12500000", - "notionalFloor": "10000000", + "notionalCap": "7000000", + "notionalFloor": "6000000", "maintMarginRatio": "0.125", - "cum": "528050.0" + "cum": "428050.0" } }, { "tier": 8.0, "symbol": "TIA/USDT:USDT", "currency": "USDT", - "minNotional": 12500000.0, - "maxNotional": 25000000.0, + "minNotional": 7000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "25000000", - "notionalFloor": "12500000", + "notionalCap": "8000000", + "notionalFloor": "7000000", "maintMarginRatio": "0.25", - "cum": "2090550.0" + "cum": "1303050.0" } }, { "tier": 9.0, "symbol": "TIA/USDT:USDT", "currency": "USDT", - "minNotional": 25000000.0, - "maxNotional": 50000000.0, + "minNotional": 8000000.0, + "maxNotional": 9000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "50000000", - "notionalFloor": "25000000", + "notionalCap": "9000000", + "notionalFloor": "8000000", "maintMarginRatio": "0.5", - "cum": "8340550.0" + "cum": "3303050.0" } } ], @@ -53564,13 +54549,13 @@ "symbol": "TON/USDT:USDT", "currency": "USDT", "minNotional": 800000.0, - "maxNotional": 4000000.0, + "maxNotional": 3000000.0, "maintenanceMarginRate": 0.05, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "4000000", + "notionalCap": "3000000", "notionalFloor": "800000", "maintMarginRatio": "0.05", "cum": "22450.0" @@ -53580,68 +54565,68 @@ "tier": 6.0, "symbol": "TON/USDT:USDT", "currency": "USDT", - "minNotional": 4000000.0, - "maxNotional": 8000000.0, + "minNotional": 3000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "8000000", - "notionalFloor": "4000000", + "notionalCap": "5000000", + "notionalFloor": "3000000", "maintMarginRatio": "0.1", - "cum": "222450.0" + "cum": "172450.0" } }, { "tier": 7.0, "symbol": "TON/USDT:USDT", "currency": "USDT", - "minNotional": 8000000.0, - "maxNotional": 10000000.0, + "minNotional": 5000000.0, + "maxNotional": 6000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "10000000", - "notionalFloor": "8000000", + "notionalCap": "6000000", + "notionalFloor": "5000000", "maintMarginRatio": "0.125", - "cum": "422450.0" + "cum": "297450.0" } }, { "tier": 8.0, "symbol": "TON/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 20000000.0, + "minNotional": 6000000.0, + "maxNotional": 7000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "20000000", - "notionalFloor": "10000000", + "notionalCap": "7000000", + "notionalFloor": "6000000", "maintMarginRatio": "0.25", - "cum": "1672450.0" + "cum": "1047450.0" } }, { "tier": 9.0, "symbol": "TON/USDT:USDT", "currency": "USDT", - "minNotional": 20000000.0, - "maxNotional": 40000000.0, + "minNotional": 7000000.0, + "maxNotional": 8000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "40000000", - "notionalFloor": "20000000", + "notionalCap": "8000000", + "notionalFloor": "7000000", "maintMarginRatio": "0.5", - "cum": "6672450.0" + "cum": "2797450.0" } } ], @@ -54101,10 +55086,10 @@ "minNotional": 0.0, "maxNotional": 10000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "1", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "10000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -54118,10 +55103,10 @@ "minNotional": 10000.0, "maxNotional": 20000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 25.0, + "maxLeverage": 18.0, "info": { "bracket": "2", - "initialLeverage": "25", + "initialLeverage": "18", "notionalCap": "20000", "notionalFloor": "10000", "maintMarginRatio": "0.015", @@ -54235,13 +55220,13 @@ "symbol": "TRUMP/USDT:USDT", "currency": "USDT", "minNotional": 5000000.0, - "maxNotional": 10000000.0, + "maxNotional": 6000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "10000000", + "notionalCap": "6000000", "notionalFloor": "5000000", "maintMarginRatio": "0.5", "cum": "1668150.0" @@ -54420,6 +55405,161 @@ } } ], + "TST/USDT:USDT": [ + { + "tier": 1.0, + "symbol": "TST/USDT:USDT", + "currency": "USDT", + "minNotional": 0.0, + "maxNotional": 5000.0, + "maintenanceMarginRate": 0.01, + "maxLeverage": 75.0, + "info": { + "bracket": "1", + "initialLeverage": "75", + "notionalCap": "5000", + "notionalFloor": "0", + "maintMarginRatio": "0.01", + "cum": "0.0" + } + }, + { + "tier": 2.0, + "symbol": "TST/USDT:USDT", + "currency": "USDT", + "minNotional": 5000.0, + "maxNotional": 10000.0, + "maintenanceMarginRate": 0.015, + "maxLeverage": 50.0, + "info": { + "bracket": "2", + "initialLeverage": "50", + "notionalCap": "10000", + "notionalFloor": "5000", + "maintMarginRatio": "0.015", + "cum": "25.0" + } + }, + { + "tier": 3.0, + "symbol": "TST/USDT:USDT", + "currency": "USDT", + "minNotional": 10000.0, + "maxNotional": 30000.0, + "maintenanceMarginRate": 0.02, + "maxLeverage": 25.0, + "info": { + "bracket": "3", + "initialLeverage": "25", + "notionalCap": "30000", + "notionalFloor": "10000", + "maintMarginRatio": "0.02", + "cum": "75.0" + } + }, + { + "tier": 4.0, + "symbol": "TST/USDT:USDT", + "currency": "USDT", + "minNotional": 30000.0, + "maxNotional": 60000.0, + "maintenanceMarginRate": 0.025, + "maxLeverage": 20.0, + "info": { + "bracket": "4", + "initialLeverage": "20", + "notionalCap": "60000", + "notionalFloor": "30000", + "maintMarginRatio": "0.025", + "cum": "225.0" + } + }, + { + "tier": 5.0, + "symbol": "TST/USDT:USDT", + "currency": "USDT", + "minNotional": 60000.0, + "maxNotional": 300000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 10.0, + "info": { + "bracket": "5", + "initialLeverage": "10", + "notionalCap": "300000", + "notionalFloor": "60000", + "maintMarginRatio": "0.05", + "cum": "1725.0" + } + }, + { + "tier": 6.0, + "symbol": "TST/USDT:USDT", + "currency": "USDT", + "minNotional": 300000.0, + "maxNotional": 600000.0, + "maintenanceMarginRate": 0.1, + "maxLeverage": 5.0, + "info": { + "bracket": "6", + "initialLeverage": "5", + "notionalCap": "600000", + "notionalFloor": "300000", + "maintMarginRatio": "0.1", + "cum": "16725.0" + } + }, + { + "tier": 7.0, + "symbol": "TST/USDT:USDT", + "currency": "USDT", + "minNotional": 600000.0, + "maxNotional": 750000.0, + "maintenanceMarginRate": 0.125, + "maxLeverage": 4.0, + "info": { + "bracket": "7", + "initialLeverage": "4", + "notionalCap": "750000", + "notionalFloor": "600000", + "maintMarginRatio": "0.125", + "cum": "31725.0" + } + }, + { + "tier": 8.0, + "symbol": "TST/USDT:USDT", + "currency": "USDT", + "minNotional": 750000.0, + "maxNotional": 1500000.0, + "maintenanceMarginRate": 0.25, + "maxLeverage": 2.0, + "info": { + "bracket": "8", + "initialLeverage": "2", + "notionalCap": "1500000", + "notionalFloor": "750000", + "maintMarginRatio": "0.25", + "cum": "125475.0" + } + }, + { + "tier": 9.0, + "symbol": "TST/USDT:USDT", + "currency": "USDT", + "minNotional": 1500000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.5, + "maxLeverage": 1.0, + "info": { + "bracket": "9", + "initialLeverage": "1", + "notionalCap": "3000000", + "notionalFloor": "1500000", + "maintMarginRatio": "0.5", + "cum": "500475.0" + } + } + ], "TURBO/USDT:USDT": [ { "tier": 1.0, @@ -54511,13 +55651,13 @@ "symbol": "TURBO/USDT:USDT", "currency": "USDT", "minNotional": 3000000.0, - "maxNotional": 6000000.0, + "maxNotional": 3500000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "6000000", + "notionalCap": "3500000", "notionalFloor": "3000000", "maintMarginRatio": "0.1", "cum": "166850.0" @@ -54527,51 +55667,51 @@ "tier": 7.0, "symbol": "TURBO/USDT:USDT", "currency": "USDT", - "minNotional": 6000000.0, - "maxNotional": 7500000.0, + "minNotional": 3500000.0, + "maxNotional": 4000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "7500000", - "notionalFloor": "6000000", + "notionalCap": "4000000", + "notionalFloor": "3500000", "maintMarginRatio": "0.125", - "cum": "316850.0" + "cum": "254350.0" } }, { "tier": 8.0, "symbol": "TURBO/USDT:USDT", "currency": "USDT", - "minNotional": 7500000.0, - "maxNotional": 15000000.0, + "minNotional": 4000000.0, + "maxNotional": 4500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "15000000", - "notionalFloor": "7500000", + "notionalCap": "4500000", + "notionalFloor": "4000000", "maintMarginRatio": "0.25", - "cum": "1254350.0" + "cum": "754350.0" } }, { "tier": 9.0, "symbol": "TURBO/USDT:USDT", "currency": "USDT", - "minNotional": 15000000.0, - "maxNotional": 30000000.0, + "minNotional": 4500000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "30000000", - "notionalFloor": "15000000", + "notionalCap": "5000000", + "notionalFloor": "4500000", "maintMarginRatio": "0.5", - "cum": "5004350.0" + "cum": "1879350.0" } } ], @@ -57687,10 +58827,10 @@ "minNotional": 0.0, "maxNotional": 20000.0, "maintenanceMarginRate": 0.01, - "maxLeverage": 75.0, + "maxLeverage": 25.0, "info": { "bracket": "1", - "initialLeverage": "75", + "initialLeverage": "25", "notionalCap": "20000", "notionalFloor": "0", "maintMarginRatio": "0.01", @@ -57704,10 +58844,10 @@ "minNotional": 20000.0, "maxNotional": 200000.0, "maintenanceMarginRate": 0.015, - "maxLeverage": 50.0, + "maxLeverage": 20.0, "info": { "bracket": "2", - "initialLeverage": "50", + "initialLeverage": "20", "notionalCap": "200000", "notionalFloor": "20000", "maintMarginRatio": "0.015", @@ -57721,10 +58861,10 @@ "minNotional": 200000.0, "maxNotional": 1000000.0, "maintenanceMarginRate": 0.02, - "maxLeverage": 25.0, + "maxLeverage": 15.0, "info": { "bracket": "3", - "initialLeverage": "25", + "initialLeverage": "15", "notionalCap": "1000000", "notionalFloor": "200000", "maintMarginRatio": "0.02", @@ -57738,10 +58878,10 @@ "minNotional": 1000000.0, "maxNotional": 2000000.0, "maintenanceMarginRate": 0.025, - "maxLeverage": 20.0, + "maxLeverage": 10.0, "info": { "bracket": "4", - "initialLeverage": "20", + "initialLeverage": "10", "notionalCap": "2000000", "notionalFloor": "1000000", "maintMarginRatio": "0.025", @@ -57753,13 +58893,13 @@ "symbol": "WIF/USDT:USDT", "currency": "USDT", "minNotional": 2000000.0, - "maxNotional": 10000000.0, + "maxNotional": 5000000.0, "maintenanceMarginRate": 0.05, - "maxLeverage": 10.0, + "maxLeverage": 8.0, "info": { "bracket": "5", - "initialLeverage": "10", - "notionalCap": "10000000", + "initialLeverage": "8", + "notionalCap": "5000000", "notionalFloor": "2000000", "maintMarginRatio": "0.05", "cum": "56100.0" @@ -57769,68 +58909,68 @@ "tier": 6.0, "symbol": "WIF/USDT:USDT", "currency": "USDT", - "minNotional": 10000000.0, - "maxNotional": 20000000.0, + "minNotional": 5000000.0, + "maxNotional": 7500000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "6", "initialLeverage": "5", - "notionalCap": "20000000", - "notionalFloor": "10000000", + "notionalCap": "7500000", + "notionalFloor": "5000000", "maintMarginRatio": "0.1", - "cum": "556100.0" + "cum": "306100.0" } }, { "tier": 7.0, "symbol": "WIF/USDT:USDT", "currency": "USDT", - "minNotional": 20000000.0, - "maxNotional": 25000000.0, + "minNotional": 7500000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "7", "initialLeverage": "4", - "notionalCap": "25000000", - "notionalFloor": "20000000", + "notionalCap": "10000000", + "notionalFloor": "7500000", "maintMarginRatio": "0.125", - "cum": "1056100.0" + "cum": "493600.0" } }, { "tier": 8.0, "symbol": "WIF/USDT:USDT", "currency": "USDT", - "minNotional": 25000000.0, - "maxNotional": 50000000.0, + "minNotional": 10000000.0, + "maxNotional": 12500000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "8", "initialLeverage": "2", - "notionalCap": "50000000", - "notionalFloor": "25000000", + "notionalCap": "12500000", + "notionalFloor": "10000000", "maintMarginRatio": "0.25", - "cum": "4181100.0" + "cum": "1743600.0" } }, { "tier": 9.0, "symbol": "WIF/USDT:USDT", "currency": "USDT", - "minNotional": 50000000.0, - "maxNotional": 100000000.0, + "minNotional": 12500000.0, + "maxNotional": 15000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "9", "initialLeverage": "1", - "notionalCap": "100000000", - "notionalFloor": "50000000", + "notionalCap": "15000000", + "notionalFloor": "12500000", "maintMarginRatio": "0.5", - "cum": "16681100.0" + "cum": "4868600.0" } } ], @@ -58097,13 +59237,13 @@ "symbol": "WLD/USDT:USDT", "currency": "USDT", "minNotional": 8000000.0, - "maxNotional": 16000000.0, + "maxNotional": 10000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { "bracket": "7", "initialLeverage": "5", - "notionalCap": "16000000", + "notionalCap": "10000000", "notionalFloor": "8000000", "maintMarginRatio": "0.1", "cum": "445120.0" @@ -58113,51 +59253,51 @@ "tier": 8.0, "symbol": "WLD/USDT:USDT", "currency": "USDT", - "minNotional": 16000000.0, - "maxNotional": 20000000.0, + "minNotional": 10000000.0, + "maxNotional": 12000000.0, "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { "bracket": "8", "initialLeverage": "4", - "notionalCap": "20000000", - "notionalFloor": "16000000", + "notionalCap": "12000000", + "notionalFloor": "10000000", "maintMarginRatio": "0.125", - "cum": "845120.0" + "cum": "695120.0" } }, { "tier": 9.0, "symbol": "WLD/USDT:USDT", "currency": "USDT", - "minNotional": 20000000.0, - "maxNotional": 40000000.0, + "minNotional": 12000000.0, + "maxNotional": 14000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "9", "initialLeverage": "2", - "notionalCap": "40000000", - "notionalFloor": "20000000", + "notionalCap": "14000000", + "notionalFloor": "12000000", "maintMarginRatio": "0.25", - "cum": "3345120.0" + "cum": "2195120.0" } }, { "tier": 10.0, "symbol": "WLD/USDT:USDT", "currency": "USDT", - "minNotional": 40000000.0, - "maxNotional": 80000000.0, + "minNotional": 14000000.0, + "maxNotional": 16000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "10", "initialLeverage": "1", - "notionalCap": "80000000", - "notionalFloor": "40000000", + "notionalCap": "16000000", + "notionalFloor": "14000000", "maintMarginRatio": "0.5", - "cum": "13345120.0" + "cum": "5695120.0" } } ], @@ -58891,37 +60031,54 @@ "symbol": "XRP/USDC:USDC", "currency": "USDC", "minNotional": 750000.0, - "maxNotional": 3000000.0, - "maintenanceMarginRate": 0.05, + "maxNotional": 1000000.0, + "maintenanceMarginRate": 0.025, "maxLeverage": 10.0, "info": { "bracket": "5", "initialLeverage": "10", - "notionalCap": "3000000", + "notionalCap": "1000000", "notionalFloor": "750000", - "maintMarginRatio": "0.05", - "cum": "23045.0" + "maintMarginRatio": "0.025", + "cum": "4295.0" } }, { "tier": 6.0, "symbol": "XRP/USDC:USDC", "currency": "USDC", + "minNotional": 1000000.0, + "maxNotional": 3000000.0, + "maintenanceMarginRate": 0.05, + "maxLeverage": 8.0, + "info": { + "bracket": "6", + "initialLeverage": "8", + "notionalCap": "3000000", + "notionalFloor": "1000000", + "maintMarginRatio": "0.05", + "cum": "29295.0" + } + }, + { + "tier": 7.0, + "symbol": "XRP/USDC:USDC", + "currency": "USDC", "minNotional": 3000000.0, "maxNotional": 10000000.0, "maintenanceMarginRate": 0.1, "maxLeverage": 5.0, "info": { - "bracket": "6", + "bracket": "7", "initialLeverage": "5", "notionalCap": "10000000", "notionalFloor": "3000000", "maintMarginRatio": "0.1", - "cum": "173045.0" + "cum": "179295.0" } }, { - "tier": 7.0, + "tier": 8.0, "symbol": "XRP/USDC:USDC", "currency": "USDC", "minNotional": 10000000.0, @@ -58929,63 +60086,46 @@ "maintenanceMarginRate": 0.125, "maxLeverage": 4.0, "info": { - "bracket": "7", + "bracket": "8", "initialLeverage": "4", "notionalCap": "12000000", "notionalFloor": "10000000", "maintMarginRatio": "0.125", - "cum": "423045.0" - } - }, - { - "tier": 8.0, - "symbol": "XRP/USDC:USDC", - "currency": "USDC", - "minNotional": 12000000.0, - "maxNotional": 20000000.0, - "maintenanceMarginRate": 0.15, - "maxLeverage": 3.0, - "info": { - "bracket": "8", - "initialLeverage": "3", - "notionalCap": "20000000", - "notionalFloor": "12000000", - "maintMarginRatio": "0.15", - "cum": "723045.0" + "cum": "429295.0" } }, { "tier": 9.0, "symbol": "XRP/USDC:USDC", "currency": "USDC", - "minNotional": 20000000.0, - "maxNotional": 30000000.0, + "minNotional": 12000000.0, + "maxNotional": 15000000.0, "maintenanceMarginRate": 0.25, "maxLeverage": 2.0, "info": { "bracket": "9", "initialLeverage": "2", - "notionalCap": "30000000", - "notionalFloor": "20000000", + "notionalCap": "15000000", + "notionalFloor": "12000000", "maintMarginRatio": "0.25", - "cum": "2723045.0" + "cum": "1929295.0" } }, { "tier": 10.0, "symbol": "XRP/USDC:USDC", "currency": "USDC", - "minNotional": 30000000.0, - "maxNotional": 31000000.0, + "minNotional": 15000000.0, + "maxNotional": 20000000.0, "maintenanceMarginRate": 0.5, "maxLeverage": 1.0, "info": { "bracket": "10", "initialLeverage": "1", - "notionalCap": "31000000", - "notionalFloor": "30000000", + "notionalCap": "20000000", + "notionalFloor": "15000000", "maintMarginRatio": "0.5", - "cum": "10223045.0" + "cum": "5679295.0" } } ], diff --git a/freqtrade/exchange/bybit.py b/freqtrade/exchange/bybit.py index 72cfe52c0..d75aafdc8 100644 --- a/freqtrade/exchange/bybit.py +++ b/freqtrade/exchange/bybit.py @@ -31,7 +31,6 @@ class Bybit(Exchange): unified_account = False _ft_has: FtHas = { - "ohlcv_candle_limit": 1000, "ohlcv_has_history": True, "order_time_in_force": ["GTC", "FOK", "IOC", "PO"], "ws_enabled": True, diff --git a/freqtrade/exchange/coinbasepro.py b/freqtrade/exchange/coinbasepro.py deleted file mode 100644 index cc561e8ce..000000000 --- a/freqtrade/exchange/coinbasepro.py +++ /dev/null @@ -1,24 +0,0 @@ -"""CoinbasePro exchange subclass""" - -import logging - -from freqtrade.exchange import Exchange -from freqtrade.exchange.exchange_types import FtHas - - -logger = logging.getLogger(__name__) - - -class Coinbasepro(Exchange): - """ - CoinbasePro exchange class. Contains adjustments needed for Freqtrade to work - with this exchange. - - Please note that this exchange is not included in the list of exchanges - officially supported by the Freqtrade development team. So some features - may still not work as expected. - """ - - _ft_has: FtHas = { - "ohlcv_candle_limit": 300, - } diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 24656638c..aaf5f2225 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -12,7 +12,7 @@ from copy import deepcopy from datetime import datetime, timedelta, timezone from math import floor, isnan from threading import Lock -from typing import Any, Literal, TypeGuard +from typing import Any, Literal, TypeGuard, TypeVar import ccxt import ccxt.pro as ccxt_pro @@ -113,6 +113,8 @@ from freqtrade.util.periodic_cache import PeriodicCache logger = logging.getLogger(__name__) +T = TypeVar("T") + class Exchange: # Parameters to add directly to buy/sell calls (like agreeing to trading agreement) @@ -131,7 +133,6 @@ class Exchange: "stoploss_order_types": {}, "order_time_in_force": ["GTC"], "ohlcv_params": {}, - "ohlcv_candle_limit": 500, "ohlcv_has_history": True, # Some exchanges (Kraken) don't provide history via ohlcv "ohlcv_partial_candle": True, "ohlcv_require_since": False, @@ -276,6 +277,11 @@ class Exchange: logger.info(f'Using Exchange "{self.name}"') self.required_candle_call_count = 1 + # Converts the interval provided in minutes in config to seconds + self.markets_refresh_interval: int = ( + exchange_conf.get("markets_refresh_interval", 60) * 60 * 1000 + ) + if validate: # Initial markets load self.reload_markets(True, load_leverage_tiers=False) @@ -285,11 +291,6 @@ class Exchange: self._startup_candle_count, config.get("timeframe", "") ) - # Converts the interval provided in minutes in config to seconds - self.markets_refresh_interval: int = ( - exchange_conf.get("markets_refresh_interval", 60) * 60 * 1000 - ) - if self.trading_mode != TradingMode.SPOT and load_leverage_tiers: self.fill_leverage_tiers() self.additional_exchange_init() @@ -466,7 +467,12 @@ class Exchange: :return: Candle limit as integer """ - fallback_val = self._ft_has.get("ohlcv_candle_limit") + ccxt_val = self.features( + "spot" if candle_type == CandleType.SPOT else "futures", "fetchOHLCV", "limit", 500 + ) + if not isinstance(ccxt_val, float | int): + ccxt_val = 500 + fallback_val = self._ft_has.get("ohlcv_candle_limit", ccxt_val) if candle_type == CandleType.FUNDING_RATE: fallback_val = self._ft_has.get("funding_fee_candle_limit", fallback_val) return int( @@ -642,7 +648,8 @@ class Exchange: def _load_async_markets(self, reload: bool = False) -> dict[str, Any]: try: - markets = self.loop.run_until_complete(self._api_reload_markets(reload=reload)) + with self._loop_lock: + markets = self.loop.run_until_complete(self._api_reload_markets(reload=reload)) if isinstance(markets, Exception): raise markets @@ -887,6 +894,24 @@ class Exchange: return self._ft_has["exchange_has_overrides"][endpoint] return endpoint in self._api_async.has and self._api_async.has[endpoint] + def features( + self, market_type: Literal["spot", "futures"], endpoint, attribute, default: T + ) -> T: + """ + Returns the exchange features for the given markettype + https://docs.ccxt.com/#/README?id=features + attributes are in a nested dict, with spot and swap.linear + e.g. spot.fetchOHLCV.limit + swap.linear.fetchOHLCV.limit + """ + feat = ( + self._api_async.features.get("spot", {}) + if market_type == "spot" + else self._api_async.features.get("swap", {}).get("linear", {}) + ) + + return feat.get(endpoint, {}).get(attribute, default) + def get_precision_amount(self, pair: str) -> float | None: """ Returns the amount precision of the exchange. @@ -2318,15 +2343,16 @@ class Exchange: :param until_ms: Timestamp in milliseconds to get history up to :return: Dataframe with candle (OHLCV) data """ - pair, _, _, data, _ = self.loop.run_until_complete( - self._async_get_historic_ohlcv( - pair=pair, - timeframe=timeframe, - since_ms=since_ms, - until_ms=until_ms, - candle_type=candle_type, + with self._loop_lock: + pair, _, _, data, _ = self.loop.run_until_complete( + self._async_get_historic_ohlcv( + pair=pair, + timeframe=timeframe, + since_ms=since_ms, + until_ms=until_ms, + candle_type=candle_type, + ) ) - ) logger.debug(f"Downloaded data for {pair} from ccxt with length {len(data)}.") return ohlcv_to_dataframe(data, timeframe, pair, fill_missing=False, drop_incomplete=True) diff --git a/freqtrade/exchange/exchange_utils.py b/freqtrade/exchange/exchange_utils.py index d20ff13f9..ad92033fb 100644 --- a/freqtrade/exchange/exchange_utils.py +++ b/freqtrade/exchange/exchange_utils.py @@ -4,7 +4,7 @@ Exchange support utils import inspect from datetime import datetime, timedelta, timezone -from math import ceil, floor +from math import ceil, floor, isnan from typing import Any import ccxt @@ -305,7 +305,7 @@ def price_to_precision( :param rounding_mode: rounding mode to use. Defaults to ROUND :return: price rounded up to the precision the Exchange accepts """ - if price_precision is not None and precisionMode is not None: + if price_precision is not None and precisionMode is not None and not isnan(price): if rounding_mode not in (ROUND_UP, ROUND_DOWN): # Use CCXT code where possible. return float( diff --git a/freqtrade/exchange/exchange_ws.py b/freqtrade/exchange/exchange_ws.py index 0181267c6..cbc9772a3 100644 --- a/freqtrade/exchange/exchange_ws.py +++ b/freqtrade/exchange/exchange_ws.py @@ -9,6 +9,8 @@ import ccxt from freqtrade.constants import Config, PairWithTimeframe from freqtrade.enums.candletype import CandleType +from freqtrade.exceptions import TemporaryError +from freqtrade.exchange.common import retrier from freqtrade.exchange.exchange import timeframe_to_seconds from freqtrade.exchange.exchange_types import OHLCVResponse from freqtrade.util import dt_ts, format_ms_time, format_ms_time_det @@ -82,14 +84,21 @@ class ExchangeWS: Remove history for a pair/timeframe combination from ccxt cache """ self._ccxt_object.ohlcvs.get(paircomb[0], {}).pop(paircomb[1], None) + self.klines_last_refresh.pop(paircomb, None) + @retrier(retries=3) def ohlcvs(self, pair: str, timeframe: str) -> list[list]: """ Returns a copy of the klines for a pair/timeframe combination Note: this will only contain the data received from the websocket so the data will build up over time. """ - return deepcopy(self._ccxt_object.ohlcvs.get(pair, {}).get(timeframe, [])) + try: + return deepcopy(self._ccxt_object.ohlcvs.get(pair, {}).get(timeframe, [])) + except RuntimeError as e: + # Capture runtime errors and retry + # TemporaryError does not cause backoff - so we're essentially retrying immediately + raise TemporaryError(f"Error deepcopying: {e}") from e def cleanup_expired(self) -> None: """ @@ -130,6 +139,15 @@ class ExchangeWS: ) ) + async def _unwatch_ohlcv(self, pair: str, timeframe: str, candle_type: CandleType) -> None: + try: + await self._ccxt_object.un_watch_ohlcv_for_symbols([[pair, timeframe]]) + except ccxt.NotSupported as e: + logger.debug("un_watch_ohlcv_for_symbols not supported: %s", e) + pass + except Exception: + logger.exception("Exception in _unwatch_ohlcv") + def _continuous_stopped( self, task: asyncio.Task, pair: str, timeframe: str, candle_type: CandleType ): @@ -142,6 +160,10 @@ class ExchangeWS: result = str(result1) logger.info(f"{pair}, {timeframe}, {candle_type} - Task finished - {result}") + asyncio.run_coroutine_threadsafe( + self._unwatch_ohlcv(pair, timeframe, candle_type), loop=self._loop + ) + self._klines_scheduled.discard((pair, timeframe, candle_type)) self._pop_history((pair, timeframe, candle_type)) diff --git a/freqtrade/exchange/gate.py b/freqtrade/exchange/gate.py index d9473043f..95e1a00ca 100644 --- a/freqtrade/exchange/gate.py +++ b/freqtrade/exchange/gate.py @@ -30,7 +30,6 @@ class Gate(Exchange): unified_account = False _ft_has: FtHas = { - "ohlcv_candle_limit": 1000, "order_time_in_force": ["GTC", "IOC"], "stoploss_on_exchange": True, "stoploss_order_types": {"limit": "limit"}, diff --git a/freqtrade/exchange/htx.py b/freqtrade/exchange/htx.py index ba158d4c5..9b112ff45 100644 --- a/freqtrade/exchange/htx.py +++ b/freqtrade/exchange/htx.py @@ -21,7 +21,6 @@ class Htx(Exchange): "stop_price_param": "stopPrice", "stop_price_prop": "stopPrice", "stoploss_order_types": {"limit": "stop-limit"}, - "ohlcv_candle_limit": 1000, "l2_limit_range": [5, 10, 20], "l2_limit_range_required": False, "ohlcv_candle_limit_per_timeframe": { diff --git a/freqtrade/exchange/hyperliquid.py b/freqtrade/exchange/hyperliquid.py index d417810c8..a75a77892 100644 --- a/freqtrade/exchange/hyperliquid.py +++ b/freqtrade/exchange/hyperliquid.py @@ -22,7 +22,6 @@ class Hyperliquid(Exchange): _ft_has: FtHas = { "ohlcv_has_history": False, - "ohlcv_candle_limit": 5000, "l2_limit_range": [20], "trades_has_history": False, "tickers_have_bid_ask": False, diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index 22828ce20..03c97569a 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -26,7 +26,6 @@ class Kraken(Exchange): "stop_price_prop": "stopLossPrice", "stoploss_order_types": {"limit": "limit", "market": "market"}, "order_time_in_force": ["GTC", "IOC", "PO"], - "ohlcv_candle_limit": 720, "ohlcv_has_history": False, "trades_pagination": "id", "trades_pagination_arg": "since", diff --git a/freqtrade/exchange/kucoin.py b/freqtrade/exchange/kucoin.py index de033dcc0..17afbd63a 100644 --- a/freqtrade/exchange/kucoin.py +++ b/freqtrade/exchange/kucoin.py @@ -28,7 +28,6 @@ class Kucoin(Exchange): "l2_limit_range": [20, 100], "l2_limit_range_required": False, "order_time_in_force": ["GTC", "FOK", "IOC"], - "ohlcv_candle_limit": 1500, } def _get_stop_params(self, side: BuySell, ordertype: str, stop_price: float) -> dict: diff --git a/freqtrade/freqai/base_models/FreqaiMultiOutputRegressor.py b/freqtrade/freqai/base_models/FreqaiMultiOutputRegressor.py index f2d7ff370..15c8db256 100644 --- a/freqtrade/freqai/base_models/FreqaiMultiOutputRegressor.py +++ b/freqtrade/freqai/base_models/FreqaiMultiOutputRegressor.py @@ -6,26 +6,21 @@ from sklearn.utils.validation import has_fit_parameter, validate_data class FreqaiMultiOutputRegressor(MultiOutputRegressor): def fit(self, X, y, sample_weight=None, fit_params=None): """Fit the model to data, separately for each output variable. - Parameters - ---------- - X : {array-like, sparse matrix} of shape (n_samples, n_features) + :param X: {array-like, sparse matrix} of shape (n_samples, n_features) The input data. - y : {array-like, sparse matrix} of shape (n_samples, n_outputs) + :param y: {array-like, sparse matrix} of shape (n_samples, n_outputs) Multi-output targets. An indicator matrix turns on multilabel estimation. - sample_weight : array-like of shape (n_samples,), default=None + :param sample_weight: array-like of shape (n_samples,), default=None Sample weights. If `None`, then samples are equally weighted. Only supported if the underlying regressor supports sample weights. - fit_params : A list of dicts for the fit_params + + :param fit_params: A list of dicts for the fit_params Parameters passed to the ``estimator.fit`` method of each step. Each dict may contain same or different values (e.g. different eval_sets or init_models) - .. versionadded:: 0.23 - Returns - ------- - self : object - Returns a fitted instance. + """ if not hasattr(self.estimator, "fit"): diff --git a/freqtrade/freqai/data_drawer.py b/freqtrade/freqai/data_drawer.py index 4ab13440a..1080b9070 100644 --- a/freqtrade/freqai/data_drawer.py +++ b/freqtrade/freqai/data_drawer.py @@ -33,6 +33,8 @@ LABEL_PIPELINE = "label_pipeline" TRAINDF = "trained_df" METADATA = "metadata" +METADATA_NUMBER_MODE = rapidjson.NM_NATIVE | rapidjson.NM_NAN + class pair_info(TypedDict): model_filename: str @@ -495,7 +497,7 @@ class FreqaiDataDrawer: dk.data["label_list"] = dk.label_list with (save_path / f"{dk.model_filename}_{METADATA}.json").open("w") as fp: - rapidjson.dump(dk.data, fp, default=self.np_encoder, number_mode=rapidjson.NM_NATIVE) + rapidjson.dump(dk.data, fp, default=self.np_encoder, number_mode=METADATA_NUMBER_MODE) return @@ -526,7 +528,7 @@ class FreqaiDataDrawer: dk.data["label_list"] = dk.label_list # store the metadata with (save_path / f"{dk.model_filename}_{METADATA}.json").open("w") as fp: - rapidjson.dump(dk.data, fp, default=self.np_encoder, number_mode=rapidjson.NM_NATIVE) + rapidjson.dump(dk.data, fp, default=self.np_encoder, number_mode=METADATA_NUMBER_MODE) # save the pipelines to pickle files with (save_path / f"{dk.model_filename}_{FEATURE_PIPELINE}.pkl").open("wb") as fp: @@ -563,7 +565,7 @@ class FreqaiDataDrawer: presaved backtesting (prediction file loading). """ with (dk.data_path / f"{dk.model_filename}_{METADATA}.json").open("r") as fp: - dk.data = rapidjson.load(fp, number_mode=rapidjson.NM_NATIVE) + dk.data = rapidjson.load(fp, number_mode=METADATA_NUMBER_MODE) dk.training_features_list = dk.data["training_features_list"] dk.label_list = dk.data["label_list"] @@ -587,7 +589,7 @@ class FreqaiDataDrawer: dk.label_pipeline = self.meta_data_dictionary[coin][LABEL_PIPELINE] else: with (dk.data_path / f"{dk.model_filename}_{METADATA}.json").open("r") as fp: - dk.data = rapidjson.load(fp, number_mode=rapidjson.NM_NATIVE) + dk.data = rapidjson.load(fp, number_mode=METADATA_NUMBER_MODE) with (dk.data_path / f"{dk.model_filename}_{FEATURE_PIPELINE}.pkl").open("rb") as fp: dk.feature_pipeline = cloudpickle.load(fp) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 7d70c6336..8b9d4ed31 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -64,7 +64,7 @@ from freqtrade.rpc.rpc_types import ( ) from freqtrade.strategy.interface import IStrategy from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper -from freqtrade.util import FtPrecise, MeasureTime, dt_from_ts +from freqtrade.util import FtPrecise, MeasureTime, PeriodicCache, dt_from_ts, dt_now from freqtrade.util.migrations.binance_mig import migrate_binance_futures_names from freqtrade.wallets import Wallets @@ -145,7 +145,11 @@ class FreqtradeBot(LoggingMixin): else None ) - self.active_pair_whitelist = self._refresh_active_whitelist() + logger.info("Starting initial pairlist refresh") + with MeasureTime( + lambda duration, _: logger.info(f"Initial Pairlist refresh took {duration:.2f}s"), 0 + ): + self.active_pair_whitelist = self._refresh_active_whitelist() # Set initial bot state from config initial_state = self.config.get("initial_state") @@ -154,6 +158,7 @@ class FreqtradeBot(LoggingMixin): # Protect exit-logic from forcesell and vice versa self._exit_lock = Lock() timeframe_secs = timeframe_to_seconds(self.strategy.timeframe) + self._exit_reason_cache = PeriodicCache(100, ttl=timeframe_secs) LoggingMixin.__init__(self, logger, timeframe_secs) self._schedule = Scheduler() @@ -1374,6 +1379,15 @@ class FreqtradeBot(LoggingMixin): for should_exit in exits: if should_exit.exit_flag: exit_tag1 = exit_tag if should_exit.exit_type == ExitType.EXIT_SIGNAL else None + if trade.has_open_orders: + if prev_eval := self._exit_reason_cache.get( + f"{trade.pair}_{trade.id}_{exit_tag1 or should_exit.exit_reason}", None + ): + logger.debug( + f"Exit reason already seen this candle, first seen at {prev_eval}" + ) + continue + logger.info( f"Exit for {trade.pair} detected. Reason: {should_exit.exit_type}" f"{f' Tag: {exit_tag1}' if exit_tag1 is not None else ''}" @@ -1593,27 +1607,29 @@ class FreqtradeBot(LoggingMixin): self.replace_order(order, open_order, trade) def handle_cancel_order( - self, order: CcxtOrder, order_obj: Order, trade: Trade, reason: str - ) -> None: + self, order: CcxtOrder, order_obj: Order, trade: Trade, reason: str, replacing: bool = False + ) -> bool: """ Check if current analyzed order timed out and cancel if necessary. :param order: Order dict grabbed with exchange.fetch_order() :param order_obj: Order object from the database. :param trade: Trade object. - :return: None + :return: True if the order was canceled, False otherwise. """ if order["side"] == trade.entry_side: - self.handle_cancel_enter(trade, order, order_obj, reason) + return self.handle_cancel_enter(trade, order, order_obj, reason, replacing) else: canceled = self.handle_cancel_exit(trade, order, order_obj, reason) - canceled_count = trade.get_canceled_exit_order_count() - max_timeouts = self.config.get("unfilledtimeout", {}).get("exit_timeout_count", 0) - if canceled and max_timeouts > 0 and canceled_count >= max_timeouts: - logger.warning( - f"Emergency exiting trade {trade}, as the exit order " - f"timed out {max_timeouts} times. force selling {order['amount']}." - ) - self.emergency_exit(trade, order["price"], order["amount"]) + if not replacing: + canceled_count = trade.get_canceled_exit_order_count() + max_timeouts = self.config.get("unfilledtimeout", {}).get("exit_timeout_count", 0) + if canceled and max_timeouts > 0 and canceled_count >= max_timeouts: + logger.warning( + f"Emergency exiting trade {trade}, as the exit order " + f"timed out {max_timeouts} times. force selling {order['amount']}." + ) + self.emergency_exit(trade, order["price"], order["amount"]) + return canceled def emergency_exit( self, trade: Trade, price: float, sub_trade_amt: float | None = None @@ -1649,9 +1665,9 @@ class FreqtradeBot(LoggingMixin): def replace_order(self, order: CcxtOrder, order_obj: Order | None, trade: Trade) -> None: """ Check if current analyzed entry order should be replaced or simply cancelled. - To simply cancel the existing order(no replacement) adjust_entry_price() should return None - To maintain existing order adjust_entry_price() should return order_obj.price - To replace existing order adjust_entry_price() should return desired price for limit order + To simply cancel the existing order(no replacement) adjust_order_price() should return None + To maintain existing order adjust_order_price() should return order_obj.price + To replace existing order adjust_order_price() should return desired price for limit order :param order: Order dict grabbed with exchange.fetch_order() :param order_obj: Order object. :param trade: Trade object. @@ -1665,17 +1681,17 @@ class FreqtradeBot(LoggingMixin): self.strategy.timeframe, latest_candle_open_date ) # Check if new candle - if ( - order_obj - and order_obj.side == trade.entry_side - and latest_candle_close_date > order_obj.order_date_utc - ): + if order_obj and latest_candle_close_date > order_obj.order_date_utc: + is_entry = order_obj.side == trade.entry_side # New candle proposed_rate = self.exchange.get_rate( - trade.pair, side="entry", is_short=trade.is_short, refresh=True + trade.pair, + side="entry" if is_entry else "exit", + is_short=trade.is_short, + refresh=True, ) - adjusted_entry_price = strategy_safe_wrapper( - self.strategy.adjust_entry_price, default_retval=order_obj.safe_placement_price + adjusted_price = strategy_safe_wrapper( + self.strategy.adjust_order_price, default_retval=order_obj.safe_placement_price )( trade=trade, order=order_obj, @@ -1685,36 +1701,51 @@ class FreqtradeBot(LoggingMixin): current_order_rate=order_obj.safe_placement_price, entry_tag=trade.enter_tag, side=trade.trade_direction, + is_entry=is_entry, ) replacing = True cancel_reason = constants.CANCEL_REASON["REPLACE"] - if not adjusted_entry_price: + if not adjusted_price: replacing = False cancel_reason = constants.CANCEL_REASON["USER_CANCEL"] - if order_obj.safe_placement_price != adjusted_entry_price: + + if order_obj.safe_placement_price != adjusted_price: # cancel existing order if new price is supplied or None - res = self.handle_cancel_enter( - trade, order, order_obj, cancel_reason, replacing=replacing + res = self.handle_cancel_order( + order, order_obj, trade, cancel_reason, replacing=replacing ) if not res: self.replace_order_failed( trade, f"Could not fully cancel order for {trade}, therefore not replacing." ) return - if adjusted_entry_price: + if adjusted_price: # place new order only if new price is supplied try: - if not self.execute_entry( - pair=trade.pair, - stake_amount=( - order_obj.safe_remaining * order_obj.safe_price / trade.leverage - ), - price=adjusted_entry_price, - trade=trade, - is_short=trade.is_short, - mode="replace", - ): + if is_entry: + succeeded = self.execute_entry( + pair=trade.pair, + stake_amount=( + order_obj.safe_remaining * order_obj.safe_price / trade.leverage + ), + price=adjusted_price, + trade=trade, + is_short=trade.is_short, + mode="replace", + ) + else: + succeeded = self.execute_trade_exit( + trade, + adjusted_price, + exit_check=ExitCheckTuple( + exit_type=ExitType.CUSTOM_EXIT, + exit_reason=order_obj.ft_order_tag or "order_replaced", + ), + ordertype="limit", + sub_trade_amt=order_obj.safe_remaining, + ) + if not succeeded: self.replace_order_failed( trade, f"Could not replace order for {trade}." ) @@ -1774,7 +1805,7 @@ class FreqtradeBot(LoggingMixin): if trade.has_open_orders: oo = trade.select_order(side, True) if oo is not None: - if (price == oo.price) and (side == oo.side) and (amount == oo.amount): + if price == oo.price and side == oo.side and amount == oo.amount: logger.info( f"A similar open order was found for {trade.pair}. " f"Keeping existing {trade.exit_side} order. {price=}, {amount=}" @@ -2092,6 +2123,7 @@ class FreqtradeBot(LoggingMixin): self.handle_insufficient_funds(trade) return False + self._exit_reason_cache[f"{trade.pair}_{trade.id}_{exit_reason}"] = dt_now() order_obj = Order.parse_from_ccxt_object(order, trade.pair, trade.exit_side, amount, limit) order_obj.ft_order_tag = exit_reason trade.orders.append(order_obj) diff --git a/freqtrade/leverage/liquidation_price.py b/freqtrade/leverage/liquidation_price.py index 5440da64a..af34f43fd 100644 --- a/freqtrade/leverage/liquidation_price.py +++ b/freqtrade/leverage/liquidation_price.py @@ -35,19 +35,20 @@ def update_liquidation_prices( open_trades: list[Trade] = Trade.get_open_trades() for t in open_trades: - # TODO: This should be done in a batch update - t.set_liquidation_price( - exchange.get_liquidation_price( - pair=t.pair, - open_rate=t.open_rate, - is_short=t.is_short, - amount=t.amount, - stake_amount=t.stake_amount, - leverage=t.leverage, - wallet_balance=total_wallet_stake, - open_trades=open_trades, + if t.has_open_position: + # TODO: This should be done in a batch update + t.set_liquidation_price( + exchange.get_liquidation_price( + pair=t.pair, + open_rate=t.open_rate, + is_short=t.is_short, + amount=t.amount, + stake_amount=t.stake_amount, + leverage=t.leverage, + wallet_balance=total_wallet_stake, + open_trades=open_trades, + ) ) - ) elif trade: trade.set_liquidation_price( exchange.get_liquidation_price( diff --git a/freqtrade/loggers/__init__.py b/freqtrade/loggers/__init__.py index e6e2dd18f..69e372a29 100644 --- a/freqtrade/loggers/__init__.py +++ b/freqtrade/loggers/__init__.py @@ -75,8 +75,7 @@ def setup_logging(config: Config) -> None: # config['logfilename']), which defaults to '/dev/log', applicable for most # of the systems. address = (s[1], int(s[2])) if len(s) > 2 else s[1] if len(s) > 1 else "/dev/log" - handler_sl = get_existing_handlers(SysLogHandler) - if handler_sl: + if handler_sl := get_existing_handlers(SysLogHandler): logging.root.removeHandler(handler_sl) handler_sl = SysLogHandler(address=address) # No datetime field for logging into syslog, to allow syslog @@ -92,8 +91,7 @@ def setup_logging(config: Config) -> None: "You need the cysystemd python package be installed in " "order to use logging to journald." ) - handler_jd = get_existing_handlers(JournaldLogHandler) - if handler_jd: + if handler_jd := get_existing_handlers(JournaldLogHandler): logging.root.removeHandler(handler_jd) handler_jd = JournaldLogHandler() # No datetime field for logging into journald, to allow syslog @@ -102,8 +100,7 @@ def setup_logging(config: Config) -> None: handler_jd.setFormatter(Formatter("%(name)s - %(levelname)s - %(message)s")) logging.root.addHandler(handler_jd) else: - handler_rf = get_existing_handlers(RotatingFileHandler) - if handler_rf: + if handler_rf := get_existing_handlers(RotatingFileHandler): logging.root.removeHandler(handler_rf) try: logfile_path = Path(logfile) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 132df1824..ab3e1459b 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -7,7 +7,7 @@ This module contains the backtesting logic import logging from collections import defaultdict from copy import deepcopy -from datetime import datetime, timedelta, timezone +from datetime import datetime, timedelta from typing import Any from numpy import nan @@ -63,7 +63,7 @@ from freqtrade.plugins.protectionmanager import ProtectionManager from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.strategy.interface import IStrategy from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper -from freqtrade.util import FtPrecise +from freqtrade.util import FtPrecise, dt_now from freqtrade.util.migrations import migrate_data from freqtrade.wallets import Wallets @@ -396,6 +396,8 @@ class Backtesting: self.canceled_trade_entries = 0 self.canceled_entry_orders = 0 self.replaced_entry_orders = 0 + self.canceled_exit_orders = 0 + self.replaced_exit_orders = 0 self.dataprovider.clear_cache() if enable_protections: self._load_protections(self.strategy) @@ -1234,8 +1236,8 @@ class Backtesting: for order in [o for o in trade.orders if o.ft_is_open]: if order.side == trade.entry_side: self.canceled_entry_orders += 1 - # elif order.side == trade.exit_side: - # self.canceled_exit_orders += 1 + elif order.side == trade.exit_side: + self.canceled_exit_orders += 1 # canceled orders are removed from the trade del trade.orders[trade.orders.index(order)] @@ -1299,9 +1301,10 @@ class Backtesting: Returns True if the trade should be deleted. """ # only check on new candles for open entry orders - if order.side == trade.entry_side and current_time > order.order_date_utc: + if current_time > order.order_date_utc: + is_entry = order.side == trade.entry_side requested_rate = strategy_safe_wrapper( - self.strategy.adjust_entry_price, default_retval=order.ft_price + self.strategy.adjust_order_price, default_retval=order.ft_price )( trade=trade, # type: ignore[arg-type] order=order, @@ -1311,6 +1314,7 @@ class Backtesting: current_order_rate=order.ft_price, entry_tag=trade.enter_tag, side=trade.trade_direction, + is_entry=is_entry, ) # default value is current order price # cancel existing order whenever a new rate is requested (or None) @@ -1319,22 +1323,35 @@ class Backtesting: return False else: del trade.orders[trade.orders.index(order)] - self.canceled_entry_orders += 1 + if is_entry: + self.canceled_entry_orders += 1 + else: + self.canceled_exit_orders += 1 # place new order if result was not None if requested_rate: - self._enter_trade( - pair=trade.pair, - row=row, - trade=trade, - requested_rate=requested_rate, - requested_stake=(order.safe_remaining * order.ft_price / trade.leverage), - direction="short" if trade.is_short else "long", - ) + if is_entry: + self._enter_trade( + pair=trade.pair, + row=row, + trade=trade, + requested_rate=requested_rate, + requested_stake=(order.safe_remaining * order.ft_price / trade.leverage), + direction="short" if trade.is_short else "long", + ) + self.replaced_entry_orders += 1 + else: + self._exit_trade( + trade=trade, + sell_row=row, + close_rate=requested_rate, + amount=order.safe_remaining, + exit_reason=order.ft_order_tag, + ) + self.replaced_exit_orders += 1 # Delete trade if no successful entries happened (if placing the new order failed) - if not trade.has_open_orders and trade.nr_of_successful_entries == 0: + if not trade.has_open_orders and is_entry and trade.nr_of_successful_entries == 0: return True - self.replaced_entry_orders += 1 else: # assumption: there can't be multiple open entry orders at any given time return trade.nr_of_successful_entries == 0 @@ -1656,7 +1673,7 @@ class Backtesting: self.progress.init_step(BacktestState.ANALYZE, 0) strategy_name = strat.get_strategy_name() logger.info(f"Running backtesting for Strategy {strategy_name}") - backtest_start_time = datetime.now(timezone.utc) + backtest_start_time = dt_now() self._set_strategy(strat) # need to reprocess data every time to populate signals @@ -1683,7 +1700,7 @@ class Backtesting: start_date=min_date, end_date=max_date, ) - backtest_end_time = datetime.now(timezone.utc) + backtest_end_time = dt_now() results.update( { "run_id": self.run_ids.get(strategy_name, ""), @@ -1710,14 +1727,14 @@ class Backtesting: def _get_min_cached_backtest_date(self): min_backtest_date = None backtest_cache_age = self.config.get("backtest_cache", constants.BACKTEST_CACHE_DEFAULT) - if self.timerange.stopts == 0 or self.timerange.stopdt > datetime.now(tz=timezone.utc): + if self.timerange.stopts == 0 or self.timerange.stopdt > dt_now(): logger.warning("Backtest result caching disabled due to use of open-ended timerange.") elif backtest_cache_age == "day": - min_backtest_date = datetime.now(tz=timezone.utc) - timedelta(days=1) + min_backtest_date = dt_now() - timedelta(days=1) elif backtest_cache_age == "week": - min_backtest_date = datetime.now(tz=timezone.utc) - timedelta(weeks=1) + min_backtest_date = dt_now() - timedelta(weeks=1) elif backtest_cache_age == "month": - min_backtest_date = datetime.now(tz=timezone.utc) - timedelta(weeks=4) + min_backtest_date = dt_now() - timedelta(weeks=4) return min_backtest_date def load_prior_backtest(self): diff --git a/freqtrade/optimize/hyperopt/hyperopt.py b/freqtrade/optimize/hyperopt/hyperopt.py index 0af2db4ba..ef71860a5 100644 --- a/freqtrade/optimize/hyperopt/hyperopt.py +++ b/freqtrade/optimize/hyperopt/hyperopt.py @@ -6,7 +6,6 @@ This module contains the hyperopt logic import logging import random -import sys from datetime import datetime from math import ceil from multiprocessing import Manager @@ -15,7 +14,6 @@ from typing import Any import rapidjson from joblib import Parallel, cpu_count, delayed, wrap_non_picklable_objects -from joblib.externals import cloudpickle from freqtrade.constants import FTHYPT_FILEVERSION, LAST_BT_RESULT_FN, Config from freqtrade.enums import HyperoptState @@ -110,17 +108,6 @@ class Hyperopt: logger.info(f"Removing `{p}`.") p.unlink() - def hyperopt_pickle_magic(self, bases) -> None: - """ - Hyperopt magic to allow strategy inheritance across files. - For this to properly work, we need to register the module of the imported class - to pickle as value. - """ - for modules in bases: - if modules.__name__ != "IStrategy": - cloudpickle.register_pickle_by_value(sys.modules[modules.__module__]) - self.hyperopt_pickle_magic(modules.__bases__) - def _save_result(self, epoch: dict) -> None: """ Save hyperopt results to file diff --git a/freqtrade/optimize/hyperopt/hyperopt_optimizer.py b/freqtrade/optimize/hyperopt/hyperopt_optimizer.py index c8d18d224..9e4995aca 100644 --- a/freqtrade/optimize/hyperopt/hyperopt_optimizer.py +++ b/freqtrade/optimize/hyperopt/hyperopt_optimizer.py @@ -114,7 +114,7 @@ class HyperOptimizer: def get_strategy_name(self) -> str: return self.backtesting.strategy.get_strategy_name() - def hyperopt_pickle_magic(self, bases) -> None: + def hyperopt_pickle_magic(self, bases: tuple[type, ...]) -> None: """ Hyperopt magic to allow strategy inheritance across files. For this to properly work, we need to register the module of the imported class @@ -122,7 +122,8 @@ class HyperOptimizer: """ for modules in bases: if modules.__name__ != "IStrategy": - cloudpickle.register_pickle_by_value(sys.modules[modules.__module__]) + if mod := sys.modules.get(modules.__module__): + cloudpickle.register_pickle_by_value(mod) self.hyperopt_pickle_magic(modules.__bases__) def _get_params_dict( diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index c08dcb13b..dce524b0d 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -1535,45 +1535,47 @@ class LocalTrade: :param json_str: json string to parse :return: Trade instance """ + from uuid import uuid4 + import rapidjson data = rapidjson.loads(json_str) trade = cls( __FROM_JSON=True, - id=data["trade_id"], + id=data.get("trade_id"), pair=data["pair"], - base_currency=data["base_currency"], - stake_currency=data["quote_currency"], + base_currency=data.get("base_currency"), + stake_currency=data.get("quote_currency"), is_open=data["is_open"], - exchange=data["exchange"], + exchange=data.get("exchange", "import"), amount=data["amount"], - amount_requested=data["amount_requested"], + amount_requested=data.get("amount_requested", data["amount"]), stake_amount=data["stake_amount"], - strategy=data["strategy"], + strategy=data.get("strategy"), enter_tag=data["enter_tag"], - timeframe=data["timeframe"], + timeframe=data.get("timeframe"), fee_open=data["fee_open"], - fee_open_cost=data["fee_open_cost"], - fee_open_currency=data["fee_open_currency"], + fee_open_cost=data.get("fee_open_cost"), + fee_open_currency=data.get("fee_open_currency"), fee_close=data["fee_close"], - fee_close_cost=data["fee_close_cost"], - fee_close_currency=data["fee_close_currency"], + fee_close_cost=data.get("fee_close_cost"), + fee_close_currency=data.get("fee_close_currency"), open_date=datetime.fromtimestamp(data["open_timestamp"] // 1000, tz=timezone.utc), open_rate=data["open_rate"], - open_rate_requested=data["open_rate_requested"], - open_trade_value=data["open_trade_value"], + open_rate_requested=data.get("open_rate_requested", data["open_rate"]), + open_trade_value=data.get("open_trade_value"), close_date=( datetime.fromtimestamp(data["close_timestamp"] // 1000, tz=timezone.utc) if data["close_timestamp"] else None ), - realized_profit=data["realized_profit"], + realized_profit=data.get("realized_profit", 0), close_rate=data["close_rate"], - close_rate_requested=data["close_rate_requested"], - close_profit=data["close_profit"], - close_profit_abs=data["close_profit_abs"], + close_rate_requested=data.get("close_rate_requested", data["close_rate"]), + close_profit=data.get("close_profit", data.get("profit_ratio")), + close_profit_abs=data.get("close_profit_abs", data.get("profit_abs")), exit_reason=data["exit_reason"], - exit_order_status=data["exit_order_status"], + exit_order_status=data.get("exit_order_status"), stop_loss=data["stop_loss_abs"], stop_loss_pct=data["stop_loss_ratio"], initial_stop_loss=data["initial_stop_loss_abs"], @@ -1581,11 +1583,11 @@ class LocalTrade: min_rate=data["min_rate"], max_rate=data["max_rate"], leverage=data["leverage"], - interest_rate=data["interest_rate"], - liquidation_price=data["liquidation_price"], + interest_rate=data.get("interest_rate"), + liquidation_price=data.get("liquidation_price"), is_short=data["is_short"], - trading_mode=data["trading_mode"], - funding_fees=data["funding_fees"], + trading_mode=data.get("trading_mode"), + funding_fees=data.get("funding_fees"), amount_precision=data.get("amount_precision", None), price_precision=data.get("price_precision", None), precision_mode=data.get("precision_mode", None), @@ -1597,23 +1599,25 @@ class LocalTrade: amount=order["amount"], ft_amount=order["amount"], ft_order_side=order["ft_order_side"], - ft_pair=order["pair"], - ft_is_open=order["is_open"], - order_id=order["order_id"], - status=order["status"], - average=order["average"], + ft_pair=order.get("pair", data["pair"]), + ft_is_open=order.get("is_open", False), + order_id=order.get("order_id", uuid4().hex), + status=order.get("status"), + average=order.get("average", order.get("safe_price")), cost=order["cost"], - filled=order["filled"], - order_date=datetime.strptime(order["order_date"], DATETIME_PRINT_FORMAT), + filled=order.get("filled", order["amount"]), + order_date=datetime.strptime(order["order_date"], DATETIME_PRINT_FORMAT) + if order.get("order_date") + else None, order_filled_date=( datetime.fromtimestamp(order["order_filled_timestamp"] // 1000, tz=timezone.utc) if order["order_filled_timestamp"] else None ), - order_type=order["order_type"], - price=order["price"], - ft_price=order["price"], - remaining=order["remaining"], + order_type=order.get("order_type"), + price=order.get("price", order.get("safe_price")), + ft_price=order.get("price", order.get("safe_price")), + remaining=order.get("remaining", 0.0), funding_fee=order.get("funding_fee", None), ft_order_tag=order.get("ft_order_tag", None), ) diff --git a/freqtrade/resolvers/exchange_resolver.py b/freqtrade/resolvers/exchange_resolver.py index 835c3c0af..e6edfb942 100644 --- a/freqtrade/resolvers/exchange_resolver.py +++ b/freqtrade/resolvers/exchange_resolver.py @@ -9,7 +9,7 @@ from typing import Any import freqtrade.exchange as exchanges from freqtrade.constants import Config, ExchangeConfig from freqtrade.exchange import MAP_EXCHANGE_CHILDCLASS, Exchange -from freqtrade.resolvers import IResolver +from freqtrade.resolvers.iresolver import IResolver logger = logging.getLogger(__name__) diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index 67751b5ae..b56ed8e11 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -16,7 +16,7 @@ from freqtrade.configuration.config_validation import validate_migrated_strategy from freqtrade.constants import REQUIRED_ORDERTIF, REQUIRED_ORDERTYPES, USERPATH_STRATEGIES, Config from freqtrade.enums import TradingMode from freqtrade.exceptions import OperationalException -from freqtrade.resolvers import IResolver +from freqtrade.resolvers.iresolver import IResolver from freqtrade.strategy.interface import IStrategy @@ -242,6 +242,14 @@ class StrategyResolver(IResolver): if has_after_fill: strategy._ft_stop_uses_after_fill = True + if check_override(strategy, IStrategy, "adjust_order_price") and ( + check_override(strategy, IStrategy, "adjust_entry_price") + or check_override(strategy, IStrategy, "adjust_exit_price") + ): + raise OperationalException( + "If you implement `adjust_order_price`, `adjust_entry_price` and " + "`adjust_exit_price` will not be used. Please pick one approach for your strategy." + ) return strategy @staticmethod diff --git a/freqtrade/rpc/api_server/api_backtest.py b/freqtrade/rpc/api_server/api_backtest.py index 7346b22e0..278922b7d 100644 --- a/freqtrade/rpc/api_server/api_backtest.py +++ b/freqtrade/rpc/api_server/api_backtest.py @@ -99,16 +99,18 @@ def __run_backtest_bg(btconfig: Config): ApiBG.bt["data"], ApiBG.bt["bt"].all_results, min_date=min_date, max_date=max_date ) - if btconfig.get("export", "none") == "trades": - combined_res = combined_dataframes_with_rel_mean(ApiBG.bt["data"], min_date, max_date) - fn = store_backtest_results( - btconfig, - ApiBG.bt["bt"].results, - datetime.now().strftime("%Y-%m-%d_%H-%M-%S"), - market_change_data=combined_res, - ) - ApiBG.bt["bt"].results["metadata"][strategy_name]["filename"] = str(fn.stem) - ApiBG.bt["bt"].results["metadata"][strategy_name]["strategy"] = strategy_name + if btconfig.get("export", "none") == "trades": + combined_res = combined_dataframes_with_rel_mean( + ApiBG.bt["data"], min_date, max_date + ) + fn = store_backtest_results( + btconfig, + ApiBG.bt["bt"].results, + datetime.now().strftime("%Y-%m-%d_%H-%M-%S"), + market_change_data=combined_res, + ) + ApiBG.bt["bt"].results["metadata"][strategy_name]["filename"] = str(fn.stem) + ApiBG.bt["bt"].results["metadata"][strategy_name]["strategy"] = strategy_name logger.info("Backtest finished.") diff --git a/freqtrade/rpc/api_server/api_pair_history.py b/freqtrade/rpc/api_server/api_pair_history.py new file mode 100644 index 000000000..31fd86f46 --- /dev/null +++ b/freqtrade/rpc/api_server/api_pair_history.py @@ -0,0 +1,77 @@ +import logging +from copy import deepcopy + +from fastapi import APIRouter, Depends, HTTPException + +from freqtrade.configuration import validate_config_consistency +from freqtrade.rpc.api_server.api_pairlists import handleExchangePayload +from freqtrade.rpc.api_server.api_schemas import PairHistory, PairHistoryRequest +from freqtrade.rpc.api_server.deps import get_config, get_exchange +from freqtrade.rpc.rpc import RPC + + +logger = logging.getLogger(__name__) + +router = APIRouter() + + +@router.get("/pair_history", response_model=PairHistory, tags=["candle data"]) +def pair_history( + pair: str, + timeframe: str, + timerange: str, + strategy: str, + freqaimodel: str | None = None, + config=Depends(get_config), + exchange=Depends(get_exchange), +): + # The initial call to this endpoint can be slow, as it may need to initialize + # the exchange class. + config_loc = deepcopy(config) + config_loc.update( + { + "timeframe": timeframe, + "strategy": strategy, + "timerange": timerange, + "freqaimodel": freqaimodel if freqaimodel else config_loc.get("freqaimodel"), + } + ) + validate_config_consistency(config_loc) + try: + return RPC._rpc_analysed_history_full(config_loc, pair, timeframe, exchange, None, False) + except Exception as e: + raise HTTPException(status_code=502, detail=str(e)) + + +@router.post("/pair_history", response_model=PairHistory, tags=["candle data"]) +def pair_history_filtered(payload: PairHistoryRequest, config=Depends(get_config)): + # The initial call to this endpoint can be slow, as it may need to initialize + # the exchange class. + config_loc = deepcopy(config) + config_loc.update( + { + "timeframe": payload.timeframe, + "strategy": payload.strategy, + "timerange": payload.timerange, + "freqaimodel": ( + payload.freqaimodel if payload.freqaimodel else config_loc.get("freqaimodel") + ), + } + ) + handleExchangePayload(payload, config_loc) + exchange = get_exchange(config_loc) + + validate_config_consistency(config_loc) + + try: + return RPC._rpc_analysed_history_full( + config_loc, + payload.pair, + payload.timeframe, + exchange, + payload.columns, + payload.live_mode, + ) + except Exception as e: + logger.exception("Error in pair_history_filtered") + raise HTTPException(status_code=502, detail=str(e)) diff --git a/freqtrade/rpc/api_server/api_schemas.py b/freqtrade/rpc/api_server/api_schemas.py index 9d3fde7e2..18007f6f2 100644 --- a/freqtrade/rpc/api_server/api_schemas.py +++ b/freqtrade/rpc/api_server/api_schemas.py @@ -524,10 +524,11 @@ class PairCandlesRequest(BaseModel): columns: list[str] | None = None -class PairHistoryRequest(PairCandlesRequest): +class PairHistoryRequest(PairCandlesRequest, ExchangeModePayloadMixin): timerange: str - strategy: str + strategy: str | None = None freqaimodel: str | None = None + live_mode: bool = False class PairHistory(BaseModel): @@ -606,6 +607,24 @@ class BacktestMarketChange(BaseModel): data: list[list[Any]] +class MarketRequest(ExchangeModePayloadMixin, BaseModel): + base: str | None = None + quote: str | None = None + + +class MarketModel(BaseModel): + symbol: str + base: str + quote: str + spot: bool + swap: bool + + +class MarketResponse(BaseModel): + markets: dict[str, MarketModel] + exchange_id: str + + class SysInfo(BaseModel): cpu_pct: list[float] ram_pct: float diff --git a/freqtrade/rpc/api_server/api_v1.py b/freqtrade/rpc/api_server/api_v1.py index 25fd12efd..8aafa04c6 100644 --- a/freqtrade/rpc/api_server/api_v1.py +++ b/freqtrade/rpc/api_server/api_v1.py @@ -1,14 +1,16 @@ import logging from copy import deepcopy +from typing import Annotated from fastapi import APIRouter, Depends, Query from fastapi.exceptions import HTTPException from freqtrade import __version__ from freqtrade.data.history import get_datahandler -from freqtrade.enums import CandleType, State, TradingMode +from freqtrade.enums import CandleType, RunMode, State, TradingMode from freqtrade.exceptions import OperationalException from freqtrade.rpc import RPC +from freqtrade.rpc.api_server.api_pairlists import handleExchangePayload from freqtrade.rpc.api_server.api_schemas import ( AvailablePairs, Balances, @@ -30,11 +32,12 @@ from freqtrade.rpc.api_server.api_schemas import ( Locks, LocksPayload, Logs, + MarketRequest, + MarketResponse, MixTag, OpenTradeSchema, PairCandlesRequest, PairHistory, - PairHistoryRequest, PerformanceEntry, Ping, PlotConfig, @@ -84,7 +87,8 @@ logger = logging.getLogger(__name__) # 2.35: pair_candles and pair_history endpoints as Post variant # 2.40: Add hyperopt-loss endpoint # 2.41: Add download-data endpoint -API_VERSION = 2.41 +# 2.42: Add /pair_history endpoint with live data +API_VERSION = 2.42 # Public API, requires no auth. router_public = APIRouter() @@ -342,58 +346,6 @@ def pair_candles_filtered(payload: PairCandlesRequest, rpc: RPC = Depends(get_rp ) -@router.get("/pair_history", response_model=PairHistory, tags=["candle data"]) -def pair_history( - pair: str, - timeframe: str, - timerange: str, - strategy: str, - freqaimodel: str | None = None, - config=Depends(get_config), - exchange=Depends(get_exchange), -): - # The initial call to this endpoint can be slow, as it may need to initialize - # the exchange class. - config = deepcopy(config) - config.update( - { - "timeframe": timeframe, - "strategy": strategy, - "timerange": timerange, - "freqaimodel": freqaimodel if freqaimodel else config.get("freqaimodel"), - } - ) - try: - return RPC._rpc_analysed_history_full(config, pair, timeframe, exchange, None) - except Exception as e: - raise HTTPException(status_code=502, detail=str(e)) - - -@router.post("/pair_history", response_model=PairHistory, tags=["candle data"]) -def pair_history_filtered( - payload: PairHistoryRequest, config=Depends(get_config), exchange=Depends(get_exchange) -): - # The initial call to this endpoint can be slow, as it may need to initialize - # the exchange class. - config = deepcopy(config) - config.update( - { - "timeframe": payload.timeframe, - "strategy": payload.strategy, - "timerange": payload.timerange, - "freqaimodel": ( - payload.freqaimodel if payload.freqaimodel else config.get("freqaimodel") - ), - } - ) - try: - return RPC._rpc_analysed_history_full( - config, payload.pair, payload.timeframe, exchange, payload.columns - ) - except Exception as e: - raise HTTPException(status_code=502, detail=str(e)) - - @router.get("/plot_config", response_model=PlotConfig, tags=["candle data"]) def plot_config( strategy: str | None = None, @@ -525,6 +477,29 @@ def list_available_pairs( return result +@router.get("/markets", response_model=MarketResponse, tags=["candle data", "webserver"]) +def markets( + query: Annotated[MarketRequest, Query()], + config=Depends(get_config), + rpc: RPC | None = Depends(get_rpc_optional), +): + if not rpc or config["runmode"] == RunMode.WEBSERVER: + # webserver mode + config_loc = deepcopy(config) + handleExchangePayload(query, config_loc) + exchange = get_exchange(config_loc) + else: + exchange = rpc._freqtrade.exchange + + return { + "markets": exchange.get_markets( + base_currencies=[query.base] if query.base else None, + quote_currencies=[query.quote] if query.quote else None, + ), + "exchange_id": exchange.id, + } + + @router.get("/sysinfo", response_model=SysInfo, tags=["info"]) def sysinfo(): return RPC._rpc_sysinfo() diff --git a/freqtrade/rpc/api_server/webserver.py b/freqtrade/rpc/api_server/webserver.py index e06e77e1e..aa81684fc 100644 --- a/freqtrade/rpc/api_server/webserver.py +++ b/freqtrade/rpc/api_server/webserver.py @@ -120,6 +120,7 @@ class ApiServer(RPCHandler): from freqtrade.rpc.api_server.api_background_tasks import router as api_bg_tasks from freqtrade.rpc.api_server.api_backtest import router as api_backtest from freqtrade.rpc.api_server.api_download_data import router as api_download_data + from freqtrade.rpc.api_server.api_pair_history import router as api_pair_history from freqtrade.rpc.api_server.api_pairlists import router as api_pairlists from freqtrade.rpc.api_server.api_v1 import router as api_v1 from freqtrade.rpc.api_server.api_v1 import router_public as api_v1_public @@ -145,6 +146,11 @@ class ApiServer(RPCHandler): prefix="/api/v1", dependencies=[Depends(http_basic_or_jwt_token), Depends(is_webserver_mode)], ) + app.include_router( + api_pair_history, + prefix="/api/v1", + dependencies=[Depends(http_basic_or_jwt_token), Depends(is_webserver_mode)], + ) app.include_router( api_pairlists, prefix="/api/v1", diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index bf7e53836..ea0c3b026 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -6,13 +6,12 @@ import logging from abc import abstractmethod from collections.abc import Generator, Sequence from datetime import date, datetime, timedelta, timezone -from math import isnan from typing import TYPE_CHECKING, Any import psutil from dateutil.relativedelta import relativedelta from dateutil.tz import tzlocal -from numpy import inf, int64, mean, nan +from numpy import inf, int64, isnan, mean, nan from pandas import DataFrame, NaT from sqlalchemy import func, select @@ -31,7 +30,7 @@ from freqtrade.enums import ( TradingMode, ) from freqtrade.exceptions import ExchangeError, PricingError -from freqtrade.exchange import timeframe_to_minutes, timeframe_to_msecs +from freqtrade.exchange import Exchange, timeframe_to_minutes, timeframe_to_msecs from freqtrade.exchange.exchange_utils import price_to_precision from freqtrade.loggers import bufferHandler from freqtrade.persistence import KeyStoreKeys, KeyValueStore, PairLocks, Trade @@ -42,12 +41,13 @@ from freqtrade.rpc.rpc_types import RPCSendMsg from freqtrade.util import ( decimals_per_coin, dt_from_ts, + dt_humanize_delta, dt_now, + dt_ts, dt_ts_def, format_date, shorten_date, ) -from freqtrade.util.datetime_helpers import dt_humanize_delta from freqtrade.wallets import PositionWallet, Wallet @@ -1436,7 +1436,12 @@ class RPC: @staticmethod def _rpc_analysed_history_full( - config: Config, pair: str, timeframe: str, exchange, selected_cols: list[str] | None + config: Config, + pair: str, + timeframe: str, + exchange: Exchange, + selected_cols: list[str] | None, + live: bool, ) -> dict[str, Any]: timerange_parsed = TimeRange.parse_timerange(config.get("timerange")) @@ -1444,31 +1449,53 @@ class RPC: from freqtrade.data.dataprovider import DataProvider from freqtrade.resolvers.strategy_resolver import StrategyResolver - strategy = StrategyResolver.load_strategy(config) - startup_candles = strategy.startup_candle_count + strategy_name = "" + startup_candles = 0 + if config.get("strategy"): + strategy = StrategyResolver.load_strategy(config) + startup_candles = strategy.startup_candle_count + strategy_name = strategy.get_strategy_name() - _data = load_data( - datadir=config["datadir"], - pairs=[pair], - timeframe=timeframe, - timerange=timerange_parsed, - data_format=config["dataformat_ohlcv"], - candle_type=config.get("candle_type_def", CandleType.SPOT), - startup_candles=startup_candles, - ) - if pair not in _data: - raise RPCException( - f"No data for {pair}, {timeframe} in {config.get('timerange')} found." + if live: + data = exchange.get_historic_ohlcv( + pair=pair, + timeframe=timeframe, + since_ms=timerange_parsed.startts * 1000 + if timerange_parsed.startts + else dt_ts(dt_now() - timedelta(days=30)), + is_new_pair=True, # history is never available - so always treat as new pair + candle_type=config.get("candle_type_def", CandleType.SPOT), + until_ms=timerange_parsed.stopts, ) + else: + _data = load_data( + datadir=config["datadir"], + pairs=[pair], + timeframe=timeframe, + timerange=timerange_parsed, + data_format=config["dataformat_ohlcv"], + candle_type=config.get("candle_type_def", CandleType.SPOT), + startup_candles=startup_candles, + ) + if pair not in _data: + raise RPCException( + f"No data for {pair}, {timeframe} in {config.get('timerange')} found." + ) + data = _data[pair] - strategy.dp = DataProvider(config, exchange=exchange, pairlists=None) - strategy.ft_bot_start() + if config.get("strategy"): + strategy.dp = DataProvider(config, exchange=exchange, pairlists=None) + strategy.ft_bot_start() - df_analyzed = strategy.analyze_ticker(_data[pair], {"pair": pair}) - df_analyzed = trim_dataframe(df_analyzed, timerange_parsed, startup_candles=startup_candles) + df_analyzed = strategy.analyze_ticker(data, {"pair": pair}) + df_analyzed = trim_dataframe( + df_analyzed, timerange_parsed, startup_candles=startup_candles + ) + else: + df_analyzed = data return RPC._convert_dataframe_to_dict( - strategy.get_strategy_name(), + strategy_name, pair, timeframe, df_analyzed.copy(), diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 77fe2a84a..79ea094c9 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -690,6 +690,104 @@ class IStrategy(ABC, HyperStrategyMixin): """ return current_order_rate + def adjust_exit_price( + self, + trade: Trade, + order: Order | None, + pair: str, + current_time: datetime, + proposed_rate: float, + current_order_rate: float, + entry_tag: str | None, + side: str, + **kwargs, + ) -> float: + """ + Exit price re-adjustment logic, returning the user desired limit price. + This only executes when a order was already placed, still open (unfilled fully or partially) + and not timed out on subsequent candles after entry trigger. + + For full documentation please go to https://www.freqtrade.io/en/latest/strategy-callbacks/ + + When not implemented by a strategy, returns current_order_rate as default. + If current_order_rate is returned then the existing order is maintained. + If None is returned then order gets canceled but not replaced by a new one. + + :param pair: Pair that's currently analyzed + :param trade: Trade object. + :param order: Order object + :param current_time: datetime object, containing the current datetime + :param proposed_rate: Rate, calculated based on pricing settings in entry_pricing. + :param current_order_rate: Rate of the existing order in place. + :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 float: New entry price value if provided + + """ + return current_order_rate + + def adjust_order_price( + self, + trade: Trade, + order: Order | None, + pair: str, + current_time: datetime, + proposed_rate: float, + current_order_rate: float, + entry_tag: str | None, + side: str, + is_entry: bool, + **kwargs, + ) -> float: + """ + Exit and entry order price re-adjustment logic, returning the user desired limit price. + This only executes when a order was already placed, still open (unfilled fully or partially) + and not timed out on subsequent candles after entry trigger. + + For full documentation please go to https://www.freqtrade.io/en/latest/strategy-callbacks/ + + When not implemented by a strategy, returns current_order_rate as default. + If current_order_rate is returned then the existing order is maintained. + If None is returned then order gets canceled but not replaced by a new one. + + :param pair: Pair that's currently analyzed + :param trade: Trade object. + :param order: Order object + :param current_time: datetime object, containing the current datetime + :param proposed_rate: Rate, calculated based on pricing settings in entry_pricing. + :param current_order_rate: Rate of the existing order in place. + :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 is_entry: True if the order is an entry order, False if it's an exit order. + :param **kwargs: Ensure to keep this here so updates to this won't break your strategy. + :return float: New entry price value if provided + """ + if is_entry: + return self.adjust_entry_price( + trade=trade, + order=order, + pair=pair, + current_time=current_time, + proposed_rate=proposed_rate, + current_order_rate=current_order_rate, + entry_tag=entry_tag, + side=side, + **kwargs, + ) + else: + return self.adjust_exit_price( + trade=trade, + order=order, + pair=pair, + current_time=current_time, + proposed_rate=proposed_rate, + current_order_rate=current_order_rate, + entry_tag=entry_tag, + side=side, + **kwargs, + ) + def leverage( self, pair: str, diff --git a/freqtrade/templates/strategy_subtemplates/strategy_methods_advanced.j2 b/freqtrade/templates/strategy_subtemplates/strategy_methods_advanced.j2 index 84d7f40c8..5ff483243 100644 --- a/freqtrade/templates/strategy_subtemplates/strategy_methods_advanced.j2 +++ b/freqtrade/templates/strategy_subtemplates/strategy_methods_advanced.j2 @@ -40,7 +40,7 @@ def custom_entry_price( """ return proposed_rate -def adjust_entry_price( +def adjust_order_price( self, trade: Trade, order: Order | None, @@ -50,10 +50,11 @@ def adjust_entry_price( current_order_rate: float, entry_tag: str | None, side: str, + is_entry: bool, **kwargs, ) -> float: """ - Entry price re-adjustment logic, returning the user desired limit price. + Exit and entry order price re-adjustment logic, returning the user desired limit price. This only executes when a order was already placed, still open (unfilled fully or partially) and not timed out on subsequent candles after entry trigger. @@ -71,6 +72,7 @@ def adjust_entry_price( :param current_order_rate: Rate of the existing order in place. :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 is_entry: True if the order is an entry order, False if it's an exit order. :param **kwargs: Ensure to keep this here so updates to this won't break your strategy. :return float: New entry price value if provided diff --git a/ft_client/freqtrade_client/__init__.py b/ft_client/freqtrade_client/__init__.py index 9df758a81..5eb4a13be 100644 --- a/ft_client/freqtrade_client/__init__.py +++ b/ft_client/freqtrade_client/__init__.py @@ -1,7 +1,7 @@ from freqtrade_client.ft_rest_client import FtRestClient -__version__ = "2025.1" +__version__ = "2025.2" if "dev" in __version__: from pathlib import Path diff --git a/ft_client/freqtrade_client/ft_rest_client.py b/ft_client/freqtrade_client/ft_rest_client.py index 851583ee0..93e6a2821 100755 --- a/ft_client/freqtrade_client/ft_rest_client.py +++ b/ft_client/freqtrade_client/ft_rest_client.py @@ -23,10 +23,18 @@ PostDataT = dict[str, Any] | list[dict[str, Any]] | None class FtRestClient: def __init__( - self, serverurl, username=None, password=None, *, pool_connections=10, pool_maxsize=10 + self, + serverurl, + username=None, + password=None, + *, + pool_connections=10, + pool_maxsize=10, + timeout=10, ): self._serverurl = serverurl self._session = requests.Session() + self._timeout = timeout # allow configuration of pool adapter = HTTPAdapter(pool_connections=pool_connections, pool_maxsize=pool_maxsize) @@ -50,7 +58,9 @@ class FtRestClient: url = urlunparse((schema, netloc, path, par, query, fragment)) try: - resp = self._session.request(method, url, headers=hd, data=json.dumps(data)) + resp = self._session.request( + method, url, headers=hd, timeout=self._timeout, data=json.dumps(data) + ) # return resp.text return resp.json() except RequestConnectionError: diff --git a/requirements-dev.txt b/requirements-dev.txt index 14006b683..67780a846 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,22 +7,22 @@ -r docs/requirements-docs.txt coveralls==4.0.1 -ruff==0.9.3 -mypy==1.14.1 +ruff==0.9.7 +mypy==1.15.0 pre-commit==4.1.0 pytest==8.3.4 -pytest-asyncio==0.25.2 +pytest-asyncio==0.25.3 pytest-cov==6.0.0 pytest-mock==3.14.0 pytest-random-order==1.1.1 pytest-timeout==2.3.1 pytest-xdist==3.6.1 -isort==5.13.2 +isort==6.0.0 # For datetime mocking time-machine==2.16.0 # Convert jupyter notebooks to markdown documents -nbconvert==7.16.5 +nbconvert==7.16.6 # mypy types types-cachetools==5.5.0.20240820 diff --git a/requirements-freqai-rl.txt b/requirements-freqai-rl.txt index d17e28d33..413feec8f 100644 --- a/requirements-freqai-rl.txt +++ b/requirements-freqai-rl.txt @@ -3,9 +3,11 @@ # Required for freqai-rl torch==2.2.2; sys_platform == 'darwin' and platform_machine == 'x86_64' -torch==2.5.1; sys_platform != 'darwin' or platform_machine != 'x86_64' +torch==2.6.0; sys_platform != 'darwin' or platform_machine != 'x86_64' gymnasium==0.29.1 -stable_baselines3==2.4.1 +# SB3 >=2.5.0 depends on torch 2.3.0 - which implies it dropped support x86 macos +stable_baselines3==2.4.1; sys_platform == 'darwin' and platform_machine == 'x86_64' +stable_baselines3==2.5.0; sys_platform != 'darwin' or platform_machine != 'x86_64' sb3_contrib>=2.2.1 # Progress bar for stable-baselines3 and sb3-contrib tqdm==4.67.1 diff --git a/requirements-freqai.txt b/requirements-freqai.txt index b66b309c6..57c012a8b 100644 --- a/requirements-freqai.txt +++ b/requirements-freqai.txt @@ -6,7 +6,7 @@ scikit-learn==1.6.1 joblib==1.4.2 catboost==1.2.7; 'arm' not in platform_machine -lightgbm==4.5.0 -xgboost==2.1.3 -tensorboard==2.18.0 +lightgbm==4.6.0 +xgboost==2.1.4 +tensorboard==2.19.0 datasieve==0.1.7 diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index 6d193bdc7..d467669d3 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -2,7 +2,7 @@ -r requirements.txt # Required for hyperopt -scipy==1.15.1 +scipy==1.15.2 scikit-learn==1.6.1 ft-scikit-optimize==0.9.2 filelock==3.17.0 diff --git a/requirements-plot.txt b/requirements-plot.txt index a50d56ead..16a162600 100644 --- a/requirements-plot.txt +++ b/requirements-plot.txt @@ -1,4 +1,4 @@ # Include all requirements to run the bot. -r requirements.txt -plotly==5.24.1 +plotly==6.0.0 diff --git a/requirements.txt b/requirements.txt index fe7078f01..0d255bf14 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,27 +4,26 @@ bottleneck==1.4.2 numexpr==2.10.2 pandas-ta==0.3.14b -ccxt==4.4.50 -cryptography==42.0.8; platform_machine == 'armv7l' -cryptography==44.0.0; platform_machine != 'armv7l' -aiohttp==3.10.11 -SQLAlchemy==2.0.37 +ccxt==4.4.62 +cryptography==44.0.1 +aiohttp==3.9.5 +SQLAlchemy==2.0.38 python-telegram-bot==21.10 # can't be hard-pinned due to telegram-bot pinning httpx with ~ httpx>=0.24.1 -humanize==4.11.0 -cachetools==5.5.1 +humanize==4.12.1 +cachetools==5.5.2 requests==2.32.3 urllib3==2.3.0 jsonschema==4.23.0 -TA-Lib==0.4.34 +TA-Lib==0.4.38 technical==1.5.0 tabulate==0.9.0 pycoingecko==3.2.0 jinja2==3.1.5 joblib==1.4.2 rich==13.9.4 -pyarrow==19.0.0; platform_machine != 'armv7l' +pyarrow==19.0.1; platform_machine != 'armv7l' # find first, C search in arrays py_find_1st==1.1.7 @@ -38,25 +37,25 @@ orjson==3.10.15 sdnotify==0.3.2 # API Server -fastapi==0.115.7 +fastapi==0.115.8 pydantic==2.10.6 uvicorn==0.34.0 pyjwt==2.10.1 aiofiles==24.1.0 -psutil==6.1.1 +psutil==7.0.0 # Building config files interactively questionary==2.1.0 prompt-toolkit==3.0.50 # Extensions to datetime library python-dateutil==2.9.0.post0 -pytz==2024.2 +pytz==2025.1 #Futures schedule==1.2.2 #WS Messages -websockets==14.2 +websockets==15.0 janus==2.0.0 ast-comments==1.2.2 diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 4cfa32ed6..58abb141e 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -4436,7 +4436,7 @@ def test_ohlcv_candle_limit(default_conf, mocker, exchange_name): pytest.skip("Tested separately for okx") exchange = get_patched_exchange(mocker, default_conf, exchange=exchange_name) timeframes = ("1m", "5m", "1h") - expected = exchange._ft_has["ohlcv_candle_limit"] + expected = exchange._ft_has.get("ohlcv_candle_limit", 500) for timeframe in timeframes: # if 'ohlcv_candle_limit_per_timeframe' in exchange._ft_has: # expected = exchange._ft_has['ohlcv_candle_limit_per_timeframe'][timeframe] @@ -6259,3 +6259,26 @@ def test_price_to_precision_with_default_conf(default_conf, mocker): prec_price = patched_ex.price_to_precision("XRP/USDT", 1.0000000101) assert prec_price == 1.00000001 assert prec_price == 1.00000001 + + +def test_exchange_features(default_conf, mocker): + conf = copy.deepcopy(default_conf) + exchange = get_patched_exchange(mocker, conf) + exchange._api_async.features = { + "spot": { + "fetchOHLCV": { + "limit": 995, + } + }, + "swap": { + "linear": { + "fetchOHLCV": { + "limit": 997, + } + } + }, + } + assert exchange.features("spot", "fetchOHLCV", "limit", 500) == 995 + assert exchange.features("futures", "fetchOHLCV", "limit", 500) == 997 + # Fall back to default + assert exchange.features("futures", "fetchOHLCV_else", "limit", 601) == 601 diff --git a/tests/exchange/test_exchange_utils.py b/tests/exchange/test_exchange_utils.py index 7fe8cb707..a298599c4 100644 --- a/tests/exchange/test_exchange_utils.py +++ b/tests/exchange/test_exchange_utils.py @@ -1,5 +1,6 @@ # pragma pylint: disable=missing-docstring, protected-access, invalid-name from datetime import datetime, timedelta, timezone +from math import isnan, nan import pytest from ccxt import ( @@ -321,6 +322,7 @@ def test_amount_to_precision( (2.9977, TICK_SIZE, 0.005, 3.0, ROUND), (234.24, TICK_SIZE, 0.5, 234.0, ROUND), (234.26, TICK_SIZE, 0.5, 234.5, ROUND), + (nan, TICK_SIZE, 3, nan, ROUND), # Tests for TRUNCATTE (2.34559, DECIMAL_PLACES, 4, 2.3455, TRUNCATE), (2.34559, DECIMAL_PLACES, 5, 2.34559, TRUNCATE), @@ -359,10 +361,11 @@ def test_amount_to_precision( ], ) def test_price_to_precision(price, precision_mode, precision, expected, rounding_mode): - assert ( - price_to_precision(price, precision, precision_mode, rounding_mode=rounding_mode) - == expected - ) + result = price_to_precision(price, precision, precision_mode, rounding_mode=rounding_mode) + if not isnan(expected): + assert result == expected + else: + assert isnan(result) @pytest.mark.parametrize( diff --git a/tests/exchange/test_exchange_ws.py b/tests/exchange/test_exchange_ws.py index 5f3e676ef..6dee7f339 100644 --- a/tests/exchange/test_exchange_ws.py +++ b/tests/exchange/test_exchange_ws.py @@ -1,9 +1,12 @@ import asyncio +import logging import threading from datetime import timedelta from time import sleep from unittest.mock import AsyncMock, MagicMock +from ccxt import NotSupported + from freqtrade.enums import CandleType from freqtrade.exchange.exchange_ws import ExchangeWS from ft_client.test_client.test_rest_client import log_has_re @@ -61,15 +64,18 @@ def patch_eventloop_threading(exchange): pass -async def test_exchangews_ohlcv(mocker, time_machine): +async def test_exchangews_ohlcv(mocker, time_machine, caplog): config = MagicMock() ccxt_object = MagicMock() + caplog.set_level(logging.DEBUG) async def sleeper(*args, **kwargs): # pass await asyncio.sleep(0.12) return MagicMock() + ccxt_object.un_watch_ohlcv_for_symbols = AsyncMock(side_effect=NotSupported) + ccxt_object.watch_ohlcv = AsyncMock(side_effect=sleeper) ccxt_object.close = AsyncMock() time_machine.move_to("2024-11-01 01:00:02 +00:00") @@ -101,11 +107,14 @@ async def test_exchangews_ohlcv(mocker, time_machine): time_machine.shift(timedelta(minutes=5)) exchange_ws.schedule_ohlcv("ETH/BTC", "1m", CandleType.SPOT) await asyncio.sleep(1) + assert log_has_re("un_watch_ohlcv_for_symbols not supported: ", caplog) # XRP/BTC should be cleaned up. assert exchange_ws._klines_watching == { ("ETH/BTC", "1m", CandleType.SPOT), } + # Cleanup happened. + ccxt_object.un_watch_ohlcv_for_symbols = AsyncMock(side_effect=ValueError) exchange_ws.schedule_ohlcv("ETH/BTC", "1m", CandleType.SPOT) assert exchange_ws._klines_watching == { ("ETH/BTC", "1m", CandleType.SPOT), @@ -117,6 +126,7 @@ async def test_exchangews_ohlcv(mocker, time_machine): finally: # Cleanup exchange_ws.cleanup() + assert log_has_re("Exception in _unwatch_ohlcv", caplog) async def test_exchangews_get_ohlcv(mocker, caplog): diff --git a/tests/exchange_online/conftest.py b/tests/exchange_online/conftest.py index 6c54984a6..8eedcfb01 100644 --- a/tests/exchange_online/conftest.py +++ b/tests/exchange_online/conftest.py @@ -21,6 +21,7 @@ EXCHANGES = { "use_ci_proxy": True, "hasQuoteVolume": True, "timeframe": "1h", + "candle_count": 1000, "futures": True, "futures_pair": "BTC/USDT:USDT", "hasQuoteVolumeFutures": True, @@ -96,6 +97,7 @@ EXCHANGES = { "stake_currency": "USDT", "hasQuoteVolume": True, "timeframe": "1h", + "candle_count": 1000, "futures": False, "skip_ws_tests": True, "sample_order": [ @@ -136,6 +138,7 @@ EXCHANGES = { "stake_currency": "USD", "hasQuoteVolume": True, "timeframe": "1h", + "candle_count": 720, "leverage_tiers_public": False, "leverage_in_spot_market": True, "trades_lookback_hours": 12, @@ -162,6 +165,7 @@ EXCHANGES = { "stake_currency": "USDT", "hasQuoteVolume": True, "timeframe": "1h", + "candle_count": 1500, "leverage_tiers_public": False, "leverage_in_spot_market": True, "sample_order": [ @@ -229,6 +233,7 @@ EXCHANGES = { "stake_currency": "USDT", "hasQuoteVolume": True, "timeframe": "1h", + "candle_count": 1000, "futures": True, "futures_pair": "BTC/USDT:USDT", "hasQuoteVolumeFutures": True, @@ -345,6 +350,7 @@ EXCHANGES = { "stake_currency": "USDT", "hasQuoteVolume": True, "timeframe": "1h", + "candle_count": 300, "futures": True, "futures_pair": "BTC/USDT:USDT", "hasQuoteVolumeFutures": False, @@ -358,6 +364,7 @@ EXCHANGES = { "hasQuoteVolume": True, "use_ci_proxy": True, "timeframe": "1h", + "candle_count": 1000, "futures_pair": "BTC/USDT:USDT", "futures": True, "orderbook_max_entries": 50, @@ -398,6 +405,7 @@ EXCHANGES = { "stake_currency": "USDT", "hasQuoteVolume": True, "timeframe": "1h", + "candle_count": 200, "orderbook_max_entries": 50, }, "htx": { @@ -405,13 +413,14 @@ EXCHANGES = { "stake_currency": "BTC", "hasQuoteVolume": True, "timeframe": "1h", - "futures": False, + "candle_count": 1000, }, "bitvavo": { "pair": "BTC/EUR", "stake_currency": "EUR", "hasQuoteVolume": True, "timeframe": "1h", + "candle_count": 1440, "leverage_tiers_public": False, "leverage_in_spot_market": False, }, @@ -420,6 +429,7 @@ EXCHANGES = { "stake_currency": "USDT", "hasQuoteVolume": True, "timeframe": "1h", + "candle_count": 1000, "futures": False, "sample_order": [ { @@ -482,6 +492,7 @@ EXCHANGES = { "hasQuoteVolume": False, "timeframe": "1h", "futures": True, + "candle_count": 5000, "orderbook_max_entries": 20, "futures_pair": "BTC/USDC:USDC", "hasQuoteVolumeFutures": True, diff --git a/tests/exchange_online/test_ccxt_compat.py b/tests/exchange_online/test_ccxt_compat.py index 42a8862ad..85de9b5ec 100644 --- a/tests/exchange_online/test_ccxt_compat.py +++ b/tests/exchange_online/test_ccxt_compat.py @@ -48,6 +48,22 @@ class TestCCXTExchange: } ) + def test_ohlcv_limit(self, exchange: EXCHANGE_FIXTURE_TYPE): + exch, exchangename = exchange + expected_count = EXCHANGES[exchangename].get("candle_count") + if not expected_count: + pytest.skip("No expected candle count for exchange") + + assert exch.ohlcv_candle_limit("1m", CandleType.SPOT) == expected_count + + def test_ohlcv_limit_futures(self, exchange_futures: EXCHANGE_FIXTURE_TYPE): + exch, exchangename = exchange_futures + expected_count = EXCHANGES[exchangename].get("candle_count") + if not expected_count: + pytest.skip("No expected candle count for exchange") + + assert exch.ohlcv_candle_limit("1m", CandleType.SPOT) == expected_count + def test_load_markets_futures(self, exchange_futures: EXCHANGE_FIXTURE_TYPE): exchange, exchangename = exchange_futures pair = EXCHANGES[exchangename]["pair"] diff --git a/tests/freqtradebot/test_freqtradebot.py b/tests/freqtradebot/test_freqtradebot.py index 02ffcb2e4..e66e5065c 100644 --- a/tests/freqtradebot/test_freqtradebot.py +++ b/tests/freqtradebot/test_freqtradebot.py @@ -3743,8 +3743,9 @@ def test_trailing_stop_loss_positive( @pytest.mark.parametrize("is_short", [False, True]) def test_disable_ignore_roi_if_entry_signal( - default_conf_usdt, limit_order, limit_order_open, is_short, fee, mocker + default_conf_usdt, limit_order, limit_order_open, is_short, fee, mocker, time_machine ) -> None: + time_machine.move_to("2025-01-10 08:00:16 +00:00") patch_RPCManager(mocker) patch_exchange(mocker) eside = entry_side(is_short) @@ -3773,6 +3774,13 @@ def test_disable_ignore_roi_if_entry_signal( patch_get_signal(freqtrade, enter_long=not is_short, enter_short=is_short, exit_short=is_short) assert freqtrade.handle_trade(trade) is True + # Test if entry-signal is absent + patch_get_signal(freqtrade) + # Signal was evaluated already - no action. + assert freqtrade.handle_trade(trade) is False + + # Move to after the candle expired + time_machine.shift(timedelta(hours=5)) # Test if entry-signal is absent patch_get_signal(freqtrade) assert freqtrade.handle_trade(trade) is True diff --git a/tests/freqtradebot/test_integration.py b/tests/freqtradebot/test_integration.py index 9fc580753..2cb4b6aa8 100644 --- a/tests/freqtradebot/test_integration.py +++ b/tests/freqtradebot/test_integration.py @@ -436,6 +436,7 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker) # Replace new order with diff. order at a lower price freqtrade.strategy.adjust_entry_price = MagicMock(return_value=1.95) + freqtrade.strategy.adjust_exit_price = MagicMock(side_effect=ValueError) freqtrade.strategy.adjust_trade_position = MagicMock(return_value=None) freqtrade.process() trade = Trade.get_trades().first() @@ -445,6 +446,8 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker) assert pytest.approx(trade.stake_amount) == 60 assert trade.orders[-1].price == 1.95 assert pytest.approx(trade.orders[-1].cost) == 120 * leverage + assert freqtrade.strategy.adjust_entry_price.call_count == 1 + assert freqtrade.strategy.adjust_exit_price.call_count == 0 # Fill DCA order freqtrade.strategy.adjust_trade_position = MagicMock(return_value=None) @@ -469,6 +472,7 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker) mocker.patch(f"{EXMS}._dry_is_price_crossed", return_value=False) freqtrade.strategy.custom_exit = MagicMock(return_value="Exit now") freqtrade.strategy.adjust_entry_price = MagicMock(return_value=2.02) + freqtrade.strategy.adjust_exit_price = MagicMock(side_effect=ValueError) freqtrade.process() trade = Trade.get_trades().first() assert len(trade.orders) == 5 @@ -478,8 +482,9 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker) assert pytest.approx(trade.amount) == 91.689215 * leverage assert pytest.approx(trade.orders[-1].amount) == 91.689215 * leverage assert freqtrade.strategy.adjust_entry_price.call_count == 0 + assert freqtrade.strategy.adjust_exit_price.call_count == 0 - # Process again, should not adjust entry price + # Process again, should not adjust price freqtrade.process() trade = Trade.get_trades().first() @@ -490,6 +495,21 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker) assert trade.orders[-1].price == 2.02 # Adjust entry price cannot be called - this is an exit order assert freqtrade.strategy.adjust_entry_price.call_count == 0 + assert freqtrade.strategy.adjust_exit_price.call_count == 1 + + freqtrade.strategy.adjust_exit_price = MagicMock(return_value=2.03) + + # Process again, should adjust exit price + freqtrade.process() + trade = Trade.get_trades().first() + + assert trade.orders[-2].status == "canceled" + assert len(trade.orders) == 6 + assert trade.orders[-1].side == trade.exit_side + assert trade.orders[-1].status == "open" + assert trade.orders[-1].price == 2.03 + assert freqtrade.strategy.adjust_entry_price.call_count == 0 + assert freqtrade.strategy.adjust_exit_price.call_count == 1 @pytest.mark.parametrize("leverage", [1, 2]) diff --git a/tests/optimize/__init__.py b/tests/optimize/__init__.py index 3299c6a53..cdc42956f 100644 --- a/tests/optimize/__init__.py +++ b/tests/optimize/__init__.py @@ -45,6 +45,7 @@ class BTContainer(NamedTuple): leverage: float = 1.0 timeout: int | None = None adjust_entry_price: float | None = None + adjust_exit_price: float | None = None adjust_trade_position: list[float] | None = None diff --git a/tests/optimize/test_backtest_detail.py b/tests/optimize/test_backtest_detail.py index 7ba53a1b3..736c4dcab 100644 --- a/tests/optimize/test_backtest_detail.py +++ b/tests/optimize/test_backtest_detail.py @@ -1217,6 +1217,46 @@ tc57 = BTContainer( ], ) +# Test 58: Custom-exit-price short - below all candles +tc58 = BTContainer( + data=[ + # D O H L C V EL XL ES Xs BT + [0, 5000, 5050, 4950, 5000, 6172, 0, 0, 1, 0], + [1, 5000, 5200, 4951, 5000, 6172, 0, 0, 0, 0], # enter trade (signal on last candle) + [2, 4900, 5250, 4900, 5100, 6172, 0, 0, 0, 1], # Exit - delayed + [3, 5100, 5100, 4650, 4750, 6172, 0, 0, 0, 0], # + [4, 4750, 5100, 4350, 4750, 6172, 0, 0, 0, 0], + ], + stop_loss=-0.10, + roi={"0": 1.00}, + profit_perc=-0.01, + use_exit_signal=True, + timeout=1000, + custom_exit_price=4300, + adjust_exit_price=5050, + trades=[BTrade(exit_reason=ExitType.EXIT_SIGNAL, open_tick=1, close_tick=4, is_short=True)], +) + +# Test 59: Custom-exit-price above all candles - readjust order +tc59 = BTContainer( + data=[ + # D O H L C V EL XL ES Xs BT + [0, 5000, 5050, 4950, 5000, 6172, 1, 0], + [1, 5000, 5500, 4951, 5000, 6172, 0, 0], + [2, 4900, 5250, 4500, 5100, 6172, 0, 1], # exit + [3, 5100, 5100, 4650, 4750, 6172, 0, 0], # order readjust + [4, 4750, 4950, 4350, 4750, 6172, 0, 0], + ], + stop_loss=-0.2, + roi={"0": 0.10}, + profit_perc=-0.02, + use_exit_signal=True, + timeout=1000, + custom_exit_price=5300, + adjust_exit_price=4900, + trades=[BTrade(exit_reason=ExitType.EXIT_SIGNAL, open_tick=1, close_tick=4, is_short=False)], +) + TESTS = [ tc0, @@ -1277,6 +1317,8 @@ TESTS = [ tc55, tc56, tc57, + tc58, + tc59, ] @@ -1330,6 +1372,8 @@ def test_backtest_results(default_conf, mocker, caplog, data: BTContainer) -> No ) if data.adjust_entry_price: backtesting.strategy.adjust_entry_price = MagicMock(return_value=data.adjust_entry_price) + if data.adjust_exit_price: + backtesting.strategy.adjust_exit_price = MagicMock(return_value=data.adjust_exit_price) backtesting.strategy.use_custom_stoploss = data.use_custom_stoploss backtesting.strategy.leverage = lambda **kwargs: data.leverage diff --git a/tests/persistence/test_trade_fromjson.py b/tests/persistence/test_trade_fromjson.py index 686667f85..ff717751e 100644 --- a/tests/persistence/test_trade_fromjson.py +++ b/tests/persistence/test_trade_fromjson.py @@ -276,3 +276,67 @@ def test_trade_serialize_load_back(fee): trade3 = LocalTrade.from_json(trade_string) assert len(trade3.orders) == len(t.orders) + + +@pytest.mark.usefixtures("init_persistence") +def test_trade_fromjson_backtesting(): + """ + trade.from_json should be able to load a trade output via backtesting. + """ + trade_string = """ + { + "pair":"XRP/USDT:USDT", + "stake_amount":3015.294001, + "max_stake_amount":60305.88002, + "amount":94612.3, + "open_date":"2024-03-02 10:40:00+00:00", + "close_date":"2024-03-02 11:10:00+00:00", + "open_rate":0.6374, + "close_rate":0.6399, + "fee_open":0.0005, + "fee_close":0.0005, + "trade_duration":30, + "profit_ratio":-0.09853216535933962, + "profit_abs":-296.95489539, + "exit_reason":"trailing_stop_loss", + "initial_stop_loss_abs":0.6689, + "initial_stop_loss_ratio":-0.99, + "stop_loss_abs":0.6399, + "stop_loss_ratio":-0.3368287257705749, + "min_rate":0.6294, + "max_rate":0.6421, + "is_open":false, + "enter_tag":"[0.6373, 0.5993, 0.64]", + "leverage":20, + "is_short":true, + "open_timestamp":1709376000000, + "close_timestamp":1709377800000, + "orders":[ + { + "amount":94612.3, + "safe_price":0.6374, + "ft_order_side":"sell", + "order_filled_timestamp":1709376000000, + "ft_is_entry":true, + "ft_order_tag":"[0.6373, 0.5993, 0.64]", + "cost":60336.032960009994 + }, + { + "amount":94612.3, + "safe_price":0.6399, + "ft_order_side":"buy", + "order_filled_timestamp":1709377800000, + "ft_is_entry":false, + "ft_order_tag":"trailing_stop_loss", + "cost":60572.681975385 + } + ] + } + """ + + trade = Trade.from_json(trade_string) + Trade.session.add(trade) + Trade.commit() + + # Trade-id not given - use first available + assert trade.id == 1 diff --git a/tests/plugins/test_percentchangepairlist.py b/tests/plugins/test_percentchangepairlist.py index 6f399fc9f..7c2f16d76 100644 --- a/tests/plugins/test_percentchangepairlist.py +++ b/tests/plugins/test_percentchangepairlist.py @@ -107,7 +107,7 @@ def test_volume_change_pair_list_init_wrong_lookback_period(mocker, rpl_config): with pytest.raises( OperationalException, match=r"ChangeFilter requires lookback_period to not exceed" - r" exchange max request size \(1000\)", + r" exchange max request size \(\d+\)", ): get_patched_freqtradebot(mocker, rpl_config) diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index ddc097265..af33cd95c 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -36,6 +36,7 @@ from tests.conftest import ( EXMS, create_mock_trades, create_mock_trades_usdt, + generate_test_data, get_mock_coro, get_patched_freqtradebot, log_has, @@ -1914,6 +1915,15 @@ def test_api_pair_history(botclient, tmp_path, mocker): timeframe = "5m" lfm = mocker.patch("freqtrade.strategy.interface.IStrategy.load_freqAI_model") + # Wrong mode + rc = client_get( + client, + f"{BASE_URI}/pair_history?timeframe={timeframe}" + f"&timerange=20180111-20180112&strategy={CURRENT_TEST_STRATEGY}", + ) + assert_response(rc, 503) + _ftbot.config["runmode"] = RunMode.WEBSERVER + # No pair rc = client_get( client, @@ -2025,6 +2035,87 @@ def test_api_pair_history(botclient, tmp_path, mocker): assert_response(rc, 502) assert rc.json()["detail"] == ("No data for UNITTEST/BTC, 5m in 20200111-20200112 found.") + # No strategy + rc = client_post( + client, + f"{BASE_URI}/pair_history", + data={ + "pair": "UNITTEST/BTC", + "timeframe": timeframe, + "timerange": "20180111-20180112", + # "strategy": CURRENT_TEST_STRATEGY, + "columns": ["rsi", "fastd", "fastk"], + }, + ) + assert_response(rc, 200) + result = rc.json() + assert result["length"] == 289 + assert len(result["data"]) == result["length"] + assert "columns" in result + assert "data" in result + # Result without strategy won't have enter_long assigned. + assert "enter_long" not in result["columns"] + assert result["columns"] == ["date", "open", "high", "low", "close", "volume", "__date_ts"] + + +def test_api_pair_history_live_mode(botclient, tmp_path, mocker): + _ftbot, client = botclient + _ftbot.config["user_data_dir"] = tmp_path + _ftbot.config["runmode"] = RunMode.WEBSERVER + + mocker.patch("freqtrade.strategy.interface.IStrategy.load_freqAI_model") + # no strategy, live data + gho = mocker.patch( + "freqtrade.exchange.binance.Binance.get_historic_ohlcv", + return_value=generate_test_data("1h", 100), + ) + rc = client_post( + client, + f"{BASE_URI}/pair_history", + data={ + "pair": "UNITTEST/BTC", + "timeframe": "1h", + "timerange": "20240101-", + # "strategy": CURRENT_TEST_STRATEGY, + "columns": ["rsi", "fastd", "fastk"], + "live_mode": True, + }, + ) + + assert_response(rc, 200) + result = rc.json() + # 100 candles - as in the generate_test_data call above + assert result["length"] == 100 + assert len(result["data"]) == result["length"] + assert result["columns"] == ["date", "open", "high", "low", "close", "volume", "__date_ts"] + assert gho.call_count == 1 + + gho.reset_mock() + rc = client_post( + client, + f"{BASE_URI}/pair_history", + data={ + "pair": "UNITTEST/BTC", + "timeframe": "1h", + "timerange": "20240101-", + "strategy": CURRENT_TEST_STRATEGY, + "columns": ["rsi", "fastd", "fastk"], + "live_mode": True, + }, + ) + + assert_response(rc, 200) + result = rc.json() + # 80 candles - as in the generate_test_data call above - 20 startup candles + assert result["length"] == 100 - 20 + assert len(result["data"]) == result["length"] + + assert "rsi" in result["columns"] + assert "enter_long" in result["columns"] + assert "fastd" in result["columns"] + assert "date" in result["columns"] + assert gho.call_count == 1 + def test_api_plot_config(botclient, mocker, tmp_path): ftbot, client = botclient @@ -2849,7 +2940,7 @@ def test_api_ws_send_msg(default_conf, mocker, caplog): ApiServer.shutdown() -def test_api_download_data(botclient, mocker, tmp_path, caplog): +def test_api_download_data(botclient, mocker, tmp_path): ftbot, client = botclient rc = client_post(client, f"{BASE_URI}/download_data", data={}) @@ -2918,3 +3009,55 @@ def test_api_download_data(botclient, mocker, tmp_path, caplog): assert response["job_category"] == "download_data" assert response["status"] == "failed" assert response["error"] == "Download error" + + +def test_api_markets_live(botclient): + ftbot, client = botclient + + rc = client_get(client, f"{BASE_URI}/markets") + assert_response(rc, 200) + response = rc.json() + assert "markets" in response + assert len(response["markets"]) >= 0 + assert response["markets"]["XRP/USDT"] == { + "base": "XRP", + "quote": "USDT", + "symbol": "XRP/USDT", + "spot": True, + "swap": False, + } + + assert "BTC/USDT" in response["markets"] + assert "XRP/BTC" in response["markets"] + + rc = client_get( + client, + f"{BASE_URI}/markets?base=XRP", + ) + assert_response(rc, 200) + response = rc.json() + assert "XRP/USDT" in response["markets"] + assert "XRP/BTC" in response["markets"] + + assert "BTC/USDT" not in response["markets"] + + +def test_api_markets_webserver(botclient): + # Ensure webserver exchanges are reset + ApiBG.exchanges = {} + ftbot, client = botclient + # Test in webserver mode + ftbot.config["runmode"] = RunMode.WEBSERVER + + rc = client_get(client, f"{BASE_URI}/markets?exchange=binance") + assert_response(rc, 200) + response = rc.json() + assert "markets" in response + assert len(response["markets"]) >= 0 + assert response["exchange_id"] == "binance" + + rc = client_get(client, f"{BASE_URI}/markets?exchange=hyperliquid") + assert_response(rc, 200) + + assert "hyperliquid_spot" in ApiBG.exchanges + assert "binance_spot" in ApiBG.exchanges diff --git a/tests/strategy/strats/broken_strats/broken_futures_strategies.py b/tests/strategy/strats/broken_strats/broken_futures_strategies.py index b2131e63e..a3e51bc50 100644 --- a/tests/strategy/strats/broken_strats/broken_futures_strategies.py +++ b/tests/strategy/strats/broken_strats/broken_futures_strategies.py @@ -21,10 +21,12 @@ class TestStrategyNoImplementSell(TestStrategyNoImplements): return super().populate_entry_trend(dataframe, metadata) -class TestStrategyImplementCustomSell(TestStrategyNoImplementSell): +class TestStrategyImplementEmptyWorking(TestStrategyNoImplementSell): def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: return super().populate_exit_trend(dataframe, metadata) + +class TestStrategyImplementCustomSell(TestStrategyImplementEmptyWorking): def custom_sell( self, pair: str, @@ -55,3 +57,34 @@ class TestStrategyImplementSellTimeout(TestStrategyNoImplementSell): self, pair: str, trade, order: Order, current_time: datetime, **kwargs ) -> bool: return False + + +class TestStrategyAdjustOrderPrice(TestStrategyImplementEmptyWorking): + def adjust_entry_price( + self, + trade, + order, + pair, + current_time, + proposed_rate, + current_order_rate, + entry_tag, + side, + **kwargs, + ): + return proposed_rate + + def adjust_order_price( + self, + trade, + order, + pair, + current_time, + proposed_rate, + current_order_rate, + entry_tag, + side, + is_entry, + **kwargs, + ): + return proposed_rate diff --git a/tests/strategy/test_strategy_loading.py b/tests/strategy/test_strategy_loading.py index 9b143ace6..927f33461 100644 --- a/tests/strategy/test_strategy_loading.py +++ b/tests/strategy/test_strategy_loading.py @@ -460,6 +460,10 @@ def test_missing_implements(default_conf, caplog): ): StrategyResolver.load_strategy(default_conf) + default_conf["strategy"] = "TestStrategyAdjustOrderPrice" + with pytest.raises(OperationalException, match=r"If you implement `adjust_order_price`.*"): + StrategyResolver.load_strategy(default_conf) + def test_call_deprecated_function(default_conf): default_location = Path(__file__).parent / "strats/broken_strats/"