Skip to main content

lib/ccxt/exchanges/binance.ex

# -------------------------------------------------------------------------------

# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
#
# Elixir target generator: build/elixirTranspiler.ts
# TypeScript source: ts/src/binance.ts
# Generation manifest: elixir/lib/ccxt/manifest.json

# -------------------------------------------------------------------------------

defmodule Ccxt.Exchanges.Binance do
  @moduledoc false

  alias Ccxt.Raw.Binance, as: Raw
  alias Ccxt.HttpExecutor
  alias Ccxt.RawEndpoint
  alias Ccxt.Transpiled.Runtime

  defstruct id: "binance", options: %{}, markets: nil, markets_by_symbol: %{}, markets_by_id: %{}

  @type params :: map() | keyword()
  @type t :: %__MODULE__{
          id: String.t(),
          options: map(),
          markets: list() | nil,
          markets_by_symbol: map(),
          markets_by_id: map()
        }

  @spec new(map() | keyword()) :: t()
  def new(options \\ %{}) do
    struct!(__MODULE__, options)
  end

  @spec load_markets(t(), boolean(), params(), (RawEndpoint.t(), params() ->
                                                  {:ok, map()} | {:error, term()})) ::
          {:ok, t()} | {:error, term()}
  def load_markets(
        exchange \\ new(),
        reload \\ false,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    if exchange.markets != nil and not reload do
      {:ok, exchange}
    else
      with {:ok, markets} <- fetch_markets(params, fetcher) do
        state = Runtime.markets_state(markets)
        {:ok, struct!(exchange, state)}
      end
    end
  end

  @spec market(t() | map(), String.t()) :: {:ok, map()} | {:error, term()}
  def market(exchange, symbol) when is_map(exchange) do
    try do
      {:ok, market!(exchange, symbol)}
    catch
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec describe((RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def describe(fetcher \\ &default_fetcher/2) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{}}, %{})
    _ = exchange
    _ = fetcher

    try do
      {:ok,
       Runtime.deep_extend(Runtime.base_describe(exchange), %{
         id: "binance",
         name: "Binance",
         countries: [],
         rateLimit: 50,
         certified: true,
         pro: true,
         has: %{
           "CORS" => nil,
           "spot" => true,
           "margin" => true,
           "swap" => true,
           "future" => true,
           "option" => true,
           "addMargin" => true,
           "borrowCrossMargin" => true,
           "borrowIsolatedMargin" => true,
           "cancelAllOrders" => true,
           "cancelOrder" => true,
           "cancelOrders" => true,
           "closeAllPositions" => false,
           "closePosition" => false,
           "createConvertTrade" => true,
           "createDepositAddress" => false,
           "createLimitBuyOrder" => true,
           "createLimitSellOrder" => true,
           "createMarketBuyOrder" => true,
           "createMarketBuyOrderWithCost" => true,
           "createMarketOrderWithCost" => true,
           "createMarketSellOrder" => true,
           "createMarketSellOrderWithCost" => true,
           "createOrder" => true,
           "createOrders" => true,
           "createOrderWithTakeProfitAndStopLoss" => false,
           "createPostOnlyOrder" => true,
           "createReduceOnlyOrder" => true,
           "createStopLimitOrder" => true,
           "createStopLossOrder" => true,
           "createStopMarketOrder" => false,
           "createStopOrder" => true,
           "createTakeProfitOrder" => true,
           "createTrailingPercentOrder" => true,
           "createTriggerOrder" => true,
           "editOrder" => true,
           "editOrders" => true,
           "fetchAccounts" => nil,
           "fetchADLRank" => true,
           "fetchAllGreeks" => true,
           "fetchBalance" => true,
           "fetchBidsAsks" => true,
           "fetchBorrowInterest" => true,
           "fetchBorrowRateHistories" => false,
           "fetchBorrowRateHistory" => true,
           "fetchCanceledAndClosedOrders" => "emulated",
           "fetchCanceledOrders" => "emulated",
           "fetchClosedOrder" => false,
           "fetchClosedOrders" => "emulated",
           "fetchConvertCurrencies" => true,
           "fetchConvertQuote" => true,
           "fetchConvertTrade" => true,
           "fetchConvertTradeHistory" => true,
           "fetchCrossBorrowRate" => true,
           "fetchCrossBorrowRates" => false,
           "fetchCurrencies" => true,
           "fetchDeposit" => false,
           "fetchDepositAddress" => true,
           "fetchDepositAddresses" => false,
           "fetchDepositAddressesByNetwork" => false,
           "fetchDeposits" => true,
           "fetchDepositsWithdrawals" => false,
           "fetchDepositWithdrawFee" => "emulated",
           "fetchDepositWithdrawFees" => true,
           "fetchFundingHistory" => true,
           "fetchFundingInterval" => "emulated",
           "fetchFundingIntervals" => true,
           "fetchFundingRate" => true,
           "fetchFundingRateHistory" => true,
           "fetchFundingRates" => true,
           "fetchGreeks" => true,
           "fetchIndexOHLCV" => true,
           "fetchIsolatedBorrowRate" => "emulated",
           "fetchIsolatedBorrowRates" => true,
           "fetchL3OrderBook" => false,
           "fetchLastPrices" => true,
           "fetchLedger" => true,
           "fetchLedgerEntry" => true,
           "fetchLeverage" => "emulated",
           "fetchLeverages" => true,
           "fetchLeverageTiers" => true,
           "fetchLiquidations" => false,
           "fetchLongShortRatio" => false,
           "fetchLongShortRatioHistory" => true,
           "fetchMarginAdjustmentHistory" => true,
           "fetchMarginMode" => true,
           "fetchMarginModes" => true,
           "fetchMarketLeverageTiers" => "emulated",
           "fetchMarkets" => true,
           "fetchMarkOHLCV" => true,
           "fetchMarkPrice" => true,
           "fetchMarkPrices" => true,
           "fetchMyLiquidations" => true,
           "fetchMySettlementHistory" => true,
           "fetchMyTrades" => true,
           "fetchOHLCV" => true,
           "fetchOpenInterest" => true,
           "fetchOpenInterestHistory" => true,
           "fetchOpenOrder" => true,
           "fetchOpenOrders" => true,
           "fetchOption" => true,
           "fetchOptionChain" => false,
           "fetchOrder" => true,
           "fetchOrderBook" => true,
           "fetchOrderBooks" => false,
           "fetchOrders" => true,
           "fetchOrderTrades" => true,
           "fetchPosition" => true,
           "fetchPositionADLRank" => true,
           "fetchPositionHistory" => false,
           "fetchPositionMode" => true,
           "fetchPositions" => true,
           "fetchPositionsADLRank" => true,
           "fetchPositionsHistory" => false,
           "fetchPositionsRisk" => true,
           "fetchPremiumIndexOHLCV" => true,
           "fetchSettlementHistory" => true,
           "fetchStatus" => true,
           "fetchTicker" => true,
           "fetchTickers" => true,
           "fetchTime" => true,
           "fetchTrades" => true,
           "fetchTradingFee" => true,
           "fetchTradingFees" => true,
           "fetchTradingLimits" => "emulated",
           "fetchTransactionFee" => "emulated",
           "fetchTransactionFees" => true,
           "fetchTransactions" => false,
           "fetchTransfer" => false,
           "fetchTransfers" => true,
           "fetchUnderlyingAssets" => false,
           "fetchVolatilityHistory" => false,
           "fetchWithdrawAddresses" => false,
           "fetchWithdrawal" => false,
           "fetchWithdrawals" => true,
           "fetchWithdrawalWhitelist" => false,
           "reduceMargin" => true,
           "repayCrossMargin" => true,
           "repayIsolatedMargin" => true,
           "sandbox" => true,
           "setLeverage" => true,
           "setMargin" => false,
           "setMarginMode" => true,
           "setPositionMode" => true,
           "signIn" => false,
           "transfer" => true,
           "withdraw" => true
         },
         timeframes: %{
           "1s" => "1s",
           "1m" => "1m",
           "3m" => "3m",
           "5m" => "5m",
           "15m" => "15m",
           "30m" => "30m",
           "1h" => "1h",
           "2h" => "2h",
           "4h" => "4h",
           "6h" => "6h",
           "8h" => "8h",
           "12h" => "12h",
           "1d" => "1d",
           "3d" => "3d",
           "1w" => "1w",
           "1M" => "1M"
         },
         urls: %{
           "logo" =>
             "https://github.com/user-attachments/assets/e9419b93-ccb0-46aa-9bff-c883f096274b",
           "test" => %{
             "dapiPublic" => "https://testnet.binancefuture.com/dapi/v1",
             "dapiPrivate" => "https://testnet.binancefuture.com/dapi/v1",
             "dapiPrivateV2" => "https://testnet.binancefuture.com/dapi/v2",
             "fapiPublic" => "https://testnet.binancefuture.com/fapi/v1",
             "fapiPublicV2" => "https://testnet.binancefuture.com/fapi/v2",
             "fapiPublicV3" => "https://testnet.binancefuture.com/fapi/v3",
             "fapiPrivate" => "https://testnet.binancefuture.com/fapi/v1",
             "fapiPrivateV2" => "https://testnet.binancefuture.com/fapi/v2",
             "fapiPrivateV3" => "https://testnet.binancefuture.com/fapi/v3",
             "public" => "https://testnet.binance.vision/api/v3",
             "private" => "https://testnet.binance.vision/api/v3",
             "v1" => "https://testnet.binance.vision/api/v1"
           },
           "demo" => %{
             "dapiPublic" => "https://demo-dapi.binance.com/dapi/v1",
             "dapiPrivate" => "https://demo-dapi.binance.com/dapi/v1",
             "dapiPrivateV2" => "https://demo-dapi.binance.com/dapi/v2",
             "fapiPublic" => "https://demo-fapi.binance.com/fapi/v1",
             "fapiPublicV2" => "https://demo-fapi.binance.com/fapi/v2",
             "fapiPublicV3" => "https://demo-fapi.binance.com/fapi/v3",
             "fapiPrivate" => "https://demo-fapi.binance.com/fapi/v1",
             "fapiPrivateV2" => "https://demo-fapi.binance.com/fapi/v2",
             "fapiPrivateV3" => "https://demo-fapi.binance.com/fapi/v3",
             "public" => "https://demo-api.binance.com/api/v3",
             "private" => "https://demo-api.binance.com/api/v3",
             "v1" => "https://demo-api.binance.com/api/v1"
           },
           "api" => %{
             "sapi" => "https://api.binance.com/sapi/v1",
             "sapiV2" => "https://api.binance.com/sapi/v2",
             "sapiV3" => "https://api.binance.com/sapi/v3",
             "sapiV4" => "https://api.binance.com/sapi/v4",
             "dapiPublic" => "https://dapi.binance.com/dapi/v1",
             "dapiPrivate" => "https://dapi.binance.com/dapi/v1",
             "eapiPublic" => "https://eapi.binance.com/eapi/v1",
             "eapiPrivate" => "https://eapi.binance.com/eapi/v1",
             "dapiPrivateV2" => "https://dapi.binance.com/dapi/v2",
             "dapiData" => "https://dapi.binance.com/futures/data",
             "fapiPublic" => "https://fapi.binance.com/fapi/v1",
             "fapiPublicV2" => "https://fapi.binance.com/fapi/v2",
             "fapiPublicV3" => "https://fapi.binance.com/fapi/v3",
             "fapiPrivate" => "https://fapi.binance.com/fapi/v1",
             "fapiPrivateV2" => "https://fapi.binance.com/fapi/v2",
             "fapiPrivateV3" => "https://fapi.binance.com/fapi/v3",
             "fapiData" => "https://fapi.binance.com/futures/data",
             "public" => "https://api.binance.com/api/v3",
             "private" => "https://api.binance.com/api/v3",
             "v1" => "https://api.binance.com/api/v1",
             "papi" => "https://papi.binance.com/papi/v1",
             "papiV2" => "https://papi.binance.com/papi/v2"
           },
           "www" => "https://www.binance.com",
           "referral" => %{
             "url" => "https://accounts.binance.com/register?ref=CCXTCOM",
             "discount" => 0.1
           },
           "doc" => ["https://developers.binance.com/en"],
           "api_management" => "https://www.binance.com/en/usercenter/settings/api-management",
           "fees" => "https://www.binance.com/en/fee/schedule"
         },
         api: %{
           "sapi" => %{
             "get" => %{
               "copyTrading/futures/userStatus" => 2,
               "copyTrading/futures/leadSymbol" => 2,
               "system/status" => 0.1,
               "accountSnapshot" => 240,
               "account/info" => 0.1,
               "margin/asset" => 1,
               "margin/pair" => 1,
               "margin/allAssets" => 0.1,
               "margin/allPairs" => 0.1,
               "margin/priceIndex" => 1,
               "spot/delist-schedule" => 10,
               "asset/assetDividend" => 1,
               "asset/dribblet" => 0.1,
               "asset/transfer" => 0.1,
               "asset/assetDetail" => 0.1,
               "asset/tradeFee" => 0.1,
               "asset/ledger-transfer/cloud-mining/queryByPage" => 4.0002,
               "asset/convert-transfer/queryByPage" => 0.033335,
               "asset/wallet/balance" => 6,
               "asset/custody/transfer-history" => 6,
               "margin/borrow-repay" => 1,
               "margin/loan" => 1,
               "margin/repay" => 1,
               "margin/account" => 1,
               "margin/transfer" => 0.1,
               "margin/interestHistory" => 0.1,
               "margin/forceLiquidationRec" => 0.1,
               "margin/order" => 1,
               "margin/openOrders" => 1,
               "margin/allOrders" => 20,
               "margin/myTrades" => 1,
               "margin/maxBorrowable" => 5,
               "margin/maxTransferable" => 5,
               "margin/tradeCoeff" => 1,
               "margin/isolated/transfer" => 0.1,
               "margin/isolated/account" => 1,
               "margin/isolated/pair" => 1,
               "margin/isolated/allPairs" => 1,
               "margin/isolated/accountLimit" => 0.1,
               "margin/interestRateHistory" => 0.1,
               "margin/orderList" => 1,
               "margin/allOrderList" => 20,
               "margin/openOrderList" => 1,
               "margin/crossMarginData" => %{"cost" => 0.1, "noCoin" => 0.5},
               "margin/isolatedMarginData" => %{"cost" => 0.1, "noCoin" => 1},
               "margin/isolatedMarginTier" => 0.1,
               "margin/rateLimit/order" => 2,
               "margin/dribblet" => 0.1,
               "margin/dust" => 20.001,
               "margin/crossMarginCollateralRatio" => 10,
               "margin/exchange-small-liability" => 0.6667,
               "margin/exchange-small-liability-history" => 0.6667,
               "margin/next-hourly-interest-rate" => 0.6667,
               "margin/capital-flow" => 10,
               "margin/delist-schedule" => 10,
               "margin/available-inventory" => 0.3334,
               "margin/leverageBracket" => 0.1,
               "loan/vip/loanable/data" => 40,
               "loan/vip/collateral/data" => 40,
               "loan/vip/request/data" => 2.6668,
               "loan/vip/request/interestRate" => 2.6668,
               "loan/income" => 40.002,
               "loan/ongoing/orders" => 40,
               "loan/ltv/adjustment/history" => 40,
               "loan/borrow/history" => 40,
               "loan/repay/history" => 40,
               "loan/loanable/data" => 40,
               "loan/collateral/data" => 40,
               "loan/repay/collateral/rate" => 600,
               "loan/flexible/ongoing/orders" => 30,
               "loan/flexible/borrow/history" => 40,
               "loan/flexible/repay/history" => 40,
               "loan/flexible/ltv/adjustment/history" => 40,
               "loan/vip/ongoing/orders" => 40,
               "loan/vip/repay/history" => 40,
               "loan/vip/collateral/account" => 600,
               "fiat/orders" => 600.03,
               "fiat/payments" => 0.1,
               "futures/transfer" => 1,
               "futures/histDataLink" => 0.1,
               "rebate/taxQuery" => 80.004,
               "capital/config/getall" => 1,
               "capital/deposit/address" => 1,
               "capital/deposit/address/list" => 1,
               "capital/deposit/hisrec" => 0.1,
               "capital/deposit/subAddress" => 0.1,
               "capital/deposit/subHisrec" => 0.1,
               "capital/withdraw/history" => 2,
               "capital/withdraw/address/list" => 10,
               "capital/contract/convertible-coins" => 4.0002,
               "convert/tradeFlow" => 20.001,
               "convert/exchangeInfo" => 50,
               "convert/assetInfo" => 10,
               "convert/orderStatus" => 0.6667,
               "convert/limit/queryOpenOrders" => 20.001,
               "account/status" => 0.1,
               "account/apiTradingStatus" => 0.1,
               "account/apiRestrictions/ipRestriction" => 0.1,
               "bnbBurn" => 0.1,
               "sub-account/futures/account" => 1,
               "sub-account/futures/accountSummary" => 0.1,
               "sub-account/futures/positionRisk" => 1,
               "sub-account/futures/internalTransfer" => 0.1,
               "sub-account/list" => 0.1,
               "sub-account/margin/account" => 1,
               "sub-account/margin/accountSummary" => 1,
               "sub-account/spotSummary" => 0.1,
               "sub-account/status" => 1,
               "sub-account/sub/transfer/history" => 0.1,
               "sub-account/transfer/subUserHistory" => 0.1,
               "sub-account/universalTransfer" => 0.1,
               "sub-account/apiRestrictions/ipRestriction/thirdPartyList" => 1,
               "sub-account/transaction-statistics" => 0.40002,
               "sub-account/subAccountApi/ipRestriction" => 20.001,
               "managed-subaccount/asset" => 0.1,
               "managed-subaccount/accountSnapshot" => 240,
               "managed-subaccount/queryTransLogForInvestor" => 0.1,
               "managed-subaccount/queryTransLogForTradeParent" => 0.40002,
               "managed-subaccount/fetch-future-asset" => 0.40002,
               "managed-subaccount/marginAsset" => 0.1,
               "managed-subaccount/info" => 0.40002,
               "managed-subaccount/deposit/address" => 0.006667,
               "managed-subaccount/query-trans-log" => 0.40002,
               "lending/daily/product/list" => 0.1,
               "lending/daily/userLeftQuota" => 0.1,
               "lending/daily/userRedemptionQuota" => 0.1,
               "lending/daily/token/position" => 0.1,
               "lending/union/account" => 0.1,
               "lending/union/purchaseRecord" => 0.1,
               "lending/union/redemptionRecord" => 0.1,
               "lending/union/interestHistory" => 0.1,
               "lending/project/list" => 0.1,
               "lending/project/position/list" => 0.1,
               "eth-staking/eth/history/stakingHistory" => 15,
               "eth-staking/eth/history/redemptionHistory" => 15,
               "eth-staking/eth/history/rewardsHistory" => 15,
               "eth-staking/eth/quota" => 15,
               "eth-staking/eth/history/rateHistory" => 15,
               "eth-staking/account" => 15,
               "eth-staking/wbeth/history/wrapHistory" => 15,
               "eth-staking/wbeth/history/unwrapHistory" => 15,
               "eth-staking/eth/history/wbethRewardsHistory" => 15,
               "sol-staking/sol/history/stakingHistory" => 15,
               "sol-staking/sol/history/redemptionHistory" => 15,
               "sol-staking/sol/history/bnsolRewardsHistory" => 15,
               "sol-staking/sol/history/rateHistory" => 15,
               "sol-staking/account" => 15,
               "sol-staking/sol/quota" => 15,
               "mining/pub/algoList" => 0.1,
               "mining/pub/coinList" => 0.1,
               "mining/worker/detail" => 0.5,
               "mining/worker/list" => 0.5,
               "mining/payment/list" => 0.5,
               "mining/statistics/user/status" => 0.5,
               "mining/statistics/user/list" => 0.5,
               "mining/payment/uid" => 0.5,
               "bswap/pools" => 0.1,
               "bswap/liquidity" => %{"cost" => 0.1, "noPoolId" => 1},
               "bswap/liquidityOps" => 20.001,
               "bswap/quote" => 1.00005,
               "bswap/swap" => 20.001,
               "bswap/poolConfigure" => 1.00005,
               "bswap/addLiquidityPreview" => 1.00005,
               "bswap/removeLiquidityPreview" => 1.00005,
               "bswap/unclaimedRewards" => 6.667,
               "bswap/claimedHistory" => 6.667,
               "blvt/tokenInfo" => 0.1,
               "blvt/subscribe/record" => 0.1,
               "blvt/redeem/record" => 0.1,
               "blvt/userLimit" => 0.1,
               "apiReferral/ifNewUser" => 1,
               "apiReferral/customization" => 1,
               "apiReferral/userCustomization" => 1,
               "apiReferral/rebate/recentRecord" => 1,
               "apiReferral/rebate/historicalRecord" => 1,
               "apiReferral/kickback/recentRecord" => 1,
               "apiReferral/kickback/historicalRecord" => 1,
               "broker/subAccountApi" => 1,
               "broker/subAccount" => 1,
               "broker/subAccountApi/commission/futures" => 1,
               "broker/subAccountApi/commission/coinFutures" => 1,
               "broker/info" => 1,
               "broker/transfer" => 1,
               "broker/transfer/futures" => 1,
               "broker/rebate/recentRecord" => 1,
               "broker/rebate/historicalRecord" => 1,
               "broker/subAccount/bnbBurn/status" => 1,
               "broker/subAccount/depositHist" => 1,
               "broker/subAccount/spotSummary" => 1,
               "broker/subAccount/marginSummary" => 1,
               "broker/subAccount/futuresSummary" => 1,
               "broker/rebate/futures/recentRecord" => 1,
               "broker/subAccountApi/ipRestriction" => 1,
               "broker/universalTransfer" => 1,
               "account/apiRestrictions" => 0.1,
               "c2c/orderMatch/listUserOrderHistory" => 0.1,
               "nft/history/transactions" => 20.001,
               "nft/history/deposit" => 20.001,
               "nft/history/withdraw" => 20.001,
               "nft/user/getAsset" => 20.001,
               "pay/transactions" => 20.001,
               "giftcard/verify" => 0.1,
               "giftcard/cryptography/rsa-public-key" => 0.1,
               "giftcard/buyCode/token-limit" => 0.1,
               "algo/spot/openOrders" => 0.1,
               "algo/spot/historicalOrders" => 0.1,
               "algo/spot/subOrders" => 0.1,
               "algo/futures/openOrders" => 0.1,
               "algo/futures/historicalOrders" => 0.1,
               "algo/futures/subOrders" => 0.1,
               "portfolio/account" => 0.1,
               "portfolio/collateralRate" => 5,
               "portfolio/pmLoan" => 3.3335,
               "portfolio/interest-history" => 0.6667,
               "portfolio/asset-index-price" => 0.1,
               "portfolio/repay-futures-switch" => 3,
               "portfolio/margin-asset-leverage" => 5,
               "portfolio/balance" => 2,
               "portfolio/negative-balance-exchange-record" => 2,
               "portfolio/pmloan-history" => 5,
               "portfolio/earn-asset-balance" => 150,
               "portfolio/delta-mode" => 150,
               "staking/productList" => 0.1,
               "staking/position" => 0.1,
               "staking/stakingRecord" => 0.1,
               "staking/personalLeftQuota" => 0.1,
               "lending/auto-invest/target-asset/list" => 0.1,
               "lending/auto-invest/target-asset/roi/list" => 0.1,
               "lending/auto-invest/all/asset" => 0.1,
               "lending/auto-invest/source-asset/list" => 0.1,
               "lending/auto-invest/plan/list" => 0.1,
               "lending/auto-invest/plan/id" => 0.1,
               "lending/auto-invest/history/list" => 0.1,
               "lending/auto-invest/index/info" => 0.1,
               "lending/auto-invest/index/user-summary" => 0.1,
               "lending/auto-invest/one-off/status" => 0.1,
               "lending/auto-invest/redeem/history" => 0.1,
               "lending/auto-invest/rebalance/history" => 0.1,
               "simple-earn/flexible/list" => 15,
               "simple-earn/locked/list" => 15,
               "simple-earn/flexible/personalLeftQuota" => 15,
               "simple-earn/locked/personalLeftQuota" => 15,
               "simple-earn/flexible/subscriptionPreview" => 15,
               "simple-earn/locked/subscriptionPreview" => 15,
               "simple-earn/flexible/history/rateHistory" => 15,
               "simple-earn/flexible/position" => 15,
               "simple-earn/locked/position" => 15,
               "simple-earn/account" => 15,
               "simple-earn/flexible/history/subscriptionRecord" => 15,
               "simple-earn/locked/history/subscriptionRecord" => 15,
               "simple-earn/flexible/history/redemptionRecord" => 15,
               "simple-earn/locked/history/redemptionRecord" => 15,
               "simple-earn/flexible/history/rewardsRecord" => 15,
               "simple-earn/locked/history/rewardsRecord" => 15,
               "simple-earn/flexible/history/collateralRecord" => 0.1,
               "dci/product/list" => 0.1,
               "dci/product/positions" => 0.1,
               "dci/product/accounts" => 0.1,
               "accumulator/product/list" => 0.1,
               "accumulator/product/position/list" => 0.1,
               "accumulator/product/sum-holding" => 0.1
             },
             "post" => %{
               "asset/dust" => 0.06667,
               "asset/dust-btc" => 0.1,
               "asset/transfer" => 6.0003,
               "asset/get-funding-asset" => 0.1,
               "asset/convert-transfer" => 0.033335,
               "account/disableFastWithdrawSwitch" => 0.1,
               "account/enableFastWithdrawSwitch" => 0.1,
               "capital/withdraw/apply" => 4.0002,
               "capital/contract/convertible-coins" => 4.0002,
               "capital/deposit/credit-apply" => 0.1,
               "margin/borrow-repay" => 20.001,
               "margin/transfer" => 4.0002,
               "margin/loan" => 20.001,
               "margin/repay" => 20.001,
               "margin/order" => 0.040002,
               "margin/order/oco" => 0.040002,
               "margin/dust" => 20.001,
               "margin/exchange-small-liability" => 20.001,
               "margin/isolated/transfer" => 4.0002,
               "margin/isolated/account" => 2.0001,
               "margin/max-leverage" => 300,
               "bnbBurn" => 0.1,
               "sub-account/virtualSubAccount" => 0.1,
               "sub-account/margin/transfer" => 4.0002,
               "sub-account/margin/enable" => 0.1,
               "sub-account/futures/enable" => 0.1,
               "sub-account/futures/transfer" => 0.1,
               "sub-account/futures/internalTransfer" => 0.1,
               "sub-account/transfer/subToSub" => 0.1,
               "sub-account/transfer/subToMaster" => 0.1,
               "sub-account/universalTransfer" => 0.1,
               "sub-account/options/enable" => 0.1,
               "managed-subaccount/deposit" => 0.1,
               "managed-subaccount/withdraw" => 0.1,
               "userDataStream" => 0.1,
               "userDataStream/isolated" => 0.1,
               "userListenToken" => 0.1,
               "futures/transfer" => 0.1,
               "lending/customizedFixed/purchase" => 0.1,
               "lending/daily/purchase" => 0.1,
               "lending/daily/redeem" => 0.1,
               "bswap/liquidityAdd" => 60,
               "bswap/liquidityRemove" => 60,
               "bswap/swap" => 60,
               "bswap/claimRewards" => 6.667,
               "blvt/subscribe" => 0.1,
               "blvt/redeem" => 0.1,
               "apiReferral/customization" => 1,
               "apiReferral/userCustomization" => 1,
               "apiReferral/rebate/historicalRecord" => 1,
               "apiReferral/kickback/historicalRecord" => 1,
               "broker/subAccount" => 1,
               "broker/subAccount/margin" => 1,
               "broker/subAccount/futures" => 1,
               "broker/subAccountApi" => 1,
               "broker/subAccountApi/permission" => 1,
               "broker/subAccountApi/commission" => 1,
               "broker/subAccountApi/commission/futures" => 1,
               "broker/subAccountApi/commission/coinFutures" => 1,
               "broker/transfer" => 1,
               "broker/transfer/futures" => 1,
               "broker/rebate/historicalRecord" => 1,
               "broker/subAccount/bnbBurn/spot" => 1,
               "broker/subAccount/bnbBurn/marginInterest" => 1,
               "broker/subAccount/blvt" => 1,
               "broker/subAccountApi/ipRestriction" => 1,
               "broker/subAccountApi/ipRestriction/ipList" => 1,
               "broker/universalTransfer" => 1,
               "broker/subAccountApi/permission/universalTransfer" => 1,
               "broker/subAccountApi/permission/vanillaOptions" => 1,
               "giftcard/createCode" => 0.1,
               "giftcard/redeemCode" => 0.1,
               "giftcard/buyCode" => 0.1,
               "algo/spot/newOrderTwap" => 20.001,
               "algo/futures/newOrderVp" => 20.001,
               "algo/futures/newOrderTwap" => 20.001,
               "staking/purchase" => 0.1,
               "staking/redeem" => 0.1,
               "staking/setAutoStaking" => 0.1,
               "eth-staking/eth/stake" => 15,
               "eth-staking/eth/redeem" => 15,
               "eth-staking/wbeth/wrap" => 15,
               "sol-staking/sol/stake" => 15,
               "sol-staking/sol/redeem" => 15,
               "mining/hash-transfer/config" => 0.5,
               "mining/hash-transfer/config/cancel" => 0.5,
               "portfolio/repay" => 20.001,
               "loan/vip/renew" => 40.002,
               "loan/vip/borrow" => 40.002,
               "loan/borrow" => 40.002,
               "loan/repay" => 40.002,
               "loan/adjust/ltv" => 40.002,
               "loan/customize/margin_call" => 40.002,
               "loan/flexible/repay" => 40.002,
               "loan/flexible/adjust/ltv" => 40.002,
               "loan/vip/repay" => 40.002,
               "convert/getQuote" => 1.3334,
               "convert/acceptQuote" => 3.3335,
               "convert/limit/placeOrder" => 3.3335,
               "convert/limit/cancelOrder" => 1.3334,
               "portfolio/auto-collection" => 150,
               "portfolio/asset-collection" => 6,
               "portfolio/bnb-transfer" => 150,
               "portfolio/repay-futures-switch" => 150,
               "portfolio/repay-futures-negative-balance" => 150,
               "portfolio/mint" => 20,
               "portfolio/redeem" => 20,
               "portfolio/earn-asset-transfer" => 150,
               "portfolio/delta-mode" => 150,
               "lending/auto-invest/plan/add" => 0.1,
               "lending/auto-invest/plan/edit" => 0.1,
               "lending/auto-invest/plan/edit-status" => 0.1,
               "lending/auto-invest/one-off" => 0.1,
               "lending/auto-invest/redeem" => 0.1,
               "simple-earn/flexible/subscribe" => 0.1,
               "simple-earn/locked/subscribe" => 0.1,
               "simple-earn/flexible/redeem" => 0.1,
               "simple-earn/locked/redeem" => 0.1,
               "simple-earn/flexible/setAutoSubscribe" => 15,
               "simple-earn/locked/setAutoSubscribe" => 15,
               "simple-earn/locked/setRedeemOption" => 5,
               "dci/product/subscribe" => 0.1,
               "dci/product/auto_compound/edit" => 0.1,
               "accumulator/product/subscribe" => 0.1
             },
             "put" => %{"userDataStream" => 0.1, "userDataStream/isolated" => 0.1},
             "delete" => %{
               "margin/openOrders" => 0.1,
               "margin/order" => 0.006667,
               "margin/orderList" => 0.006667,
               "margin/isolated/account" => 2.0001,
               "userDataStream" => 0.1,
               "userDataStream/isolated" => 0.1,
               "broker/subAccountApi" => 1,
               "broker/subAccountApi/ipRestriction/ipList" => 1,
               "algo/spot/order" => 0.1,
               "algo/futures/order" => 0.1,
               "sub-account/subAccountApi/ipRestriction/ipList" => 20.001
             }
           },
           "sapiV2" => %{
             "get" => %{
               "eth-staking/account" => 15,
               "sub-account/futures/account" => 0.1,
               "sub-account/futures/accountSummary" => 1,
               "sub-account/futures/positionRisk" => 0.1,
               "loan/flexible/ongoing/orders" => 30,
               "loan/flexible/borrow/history" => 40,
               "loan/flexible/repay/history" => 40,
               "loan/flexible/ltv/adjustment/history" => 40,
               "loan/flexible/loanable/data" => 40,
               "loan/flexible/collateral/data" => 40,
               "portfolio/account" => 2
             },
             "post" => %{
               "eth-staking/eth/stake" => 15,
               "sub-account/subAccountApi/ipRestriction" => 20.001,
               "loan/flexible/borrow" => 40.002,
               "loan/flexible/repay" => 40.002,
               "loan/flexible/adjust/ltv" => 40.002
             }
           },
           "sapiV3" => %{
             "get" => %{"sub-account/assets" => 0.40002},
             "post" => %{"asset/getUserAsset" => 0.5}
           },
           "sapiV4" => %{"get" => %{"sub-account/assets" => 0.40002}},
           "dapiPublic" => %{
             "get" => %{
               "ping" => 1,
               "time" => 1,
               "exchangeInfo" => 1,
               "depth" => %{"cost" => 2, "byLimit" => [[50, 2], [100, 5], [500, 10], [1000, 20]]},
               "trades" => 5,
               "historicalTrades" => 20,
               "aggTrades" => 20,
               "premiumIndex" => 10,
               "fundingRate" => 1,
               "klines" => %{
                 "cost" => 1,
                 "byLimit" => [[99, 1], [499, 2], [1000, 5], [10000, 10]]
               },
               "continuousKlines" => %{
                 "cost" => 1,
                 "byLimit" => [[99, 1], [499, 2], [1000, 5], [10000, 10]]
               },
               "indexPriceKlines" => %{
                 "cost" => 1,
                 "byLimit" => [[99, 1], [499, 2], [1000, 5], [10000, 10]]
               },
               "markPriceKlines" => %{
                 "cost" => 1,
                 "byLimit" => [[99, 1], [499, 2], [1000, 5], [10000, 10]]
               },
               "premiumIndexKlines" => %{
                 "cost" => 1,
                 "byLimit" => [[99, 1], [499, 2], [1000, 5], [10000, 10]]
               },
               "ticker/24hr" => %{"cost" => 1, "noSymbol" => 40},
               "ticker/price" => %{"cost" => 1, "noSymbol" => 2},
               "ticker/bookTicker" => %{"cost" => 2, "noSymbol" => 5},
               "constituents" => 2,
               "openInterest" => 1,
               "fundingInfo" => 1
             }
           },
           "dapiData" => %{
             "get" => %{
               "delivery-price" => 1,
               "openInterestHist" => 1,
               "topLongShortAccountRatio" => 1,
               "topLongShortPositionRatio" => 1,
               "globalLongShortAccountRatio" => 1,
               "takerBuySellVol" => 1,
               "basis" => 1
             }
           },
           "dapiPrivate" => %{
             "get" => %{
               "positionSide/dual" => 30,
               "orderAmendment" => 1,
               "order" => 1,
               "openOrder" => 1,
               "openOrders" => %{"cost" => 1, "noSymbol" => 5},
               "allOrders" => %{"cost" => 20, "noSymbol" => 40},
               "balance" => 1,
               "account" => 5,
               "positionMargin/history" => 1,
               "positionRisk" => 1,
               "userTrades" => %{"cost" => 20, "noSymbol" => 40},
               "income" => 20,
               "leverageBracket" => 1,
               "forceOrders" => %{"cost" => 20, "noSymbol" => 50},
               "adlQuantile" => 5,
               "commissionRate" => 20,
               "income/asyn" => 5,
               "income/asyn/id" => 5,
               "trade/asyn" => 0.5,
               "trade/asyn/id" => 0.5,
               "order/asyn" => 0.5,
               "order/asyn/id" => 0.5,
               "pmExchangeInfo" => 0.5,
               "pmAccountInfo" => 0.5
             },
             "post" => %{
               "positionSide/dual" => 1,
               "order" => 4,
               "batchOrders" => 5,
               "countdownCancelAll" => 10,
               "leverage" => 1,
               "marginType" => 1,
               "positionMargin" => 1,
               "listenKey" => 1
             },
             "put" => %{"listenKey" => 1, "order" => 1, "batchOrders" => 5},
             "delete" => %{
               "order" => 1,
               "allOpenOrders" => 1,
               "batchOrders" => 5,
               "listenKey" => 1
             }
           },
           "dapiPrivateV2" => %{"get" => %{"leverageBracket" => 1}},
           "fapiPublic" => %{
             "get" => %{
               "ping" => 1,
               "time" => 1,
               "exchangeInfo" => 1,
               "depth" => %{"cost" => 2, "byLimit" => [[50, 2], [100, 5], [500, 10], [1000, 20]]},
               "rpiDepth" => 20,
               "trades" => 5,
               "historicalTrades" => 20,
               "aggTrades" => 20,
               "klines" => %{
                 "cost" => 1,
                 "byLimit" => [[99, 1], [499, 2], [1000, 5], [10000, 10]]
               },
               "continuousKlines" => %{
                 "cost" => 1,
                 "byLimit" => [[99, 1], [499, 2], [1000, 5], [10000, 10]]
               },
               "markPriceKlines" => %{
                 "cost" => 1,
                 "byLimit" => [[99, 1], [499, 2], [1000, 5], [10000, 10]]
               },
               "indexPriceKlines" => %{
                 "cost" => 1,
                 "byLimit" => [[99, 1], [499, 2], [1000, 5], [10000, 10]]
               },
               "premiumIndexKlines" => %{
                 "cost" => 1,
                 "byLimit" => [[99, 1], [499, 2], [1000, 5], [10000, 10]]
               },
               "fundingRate" => 1,
               "fundingInfo" => 1,
               "premiumIndex" => 1,
               "ticker/24hr" => %{"cost" => 1, "noSymbol" => 40},
               "ticker/price" => %{"cost" => 1, "noSymbol" => 2},
               "ticker/bookTicker" => %{"cost" => 1, "noSymbol" => 2},
               "openInterest" => 1,
               "indexInfo" => 1,
               "assetIndex" => %{"cost" => 1, "noSymbol" => 10},
               "constituents" => 2,
               "apiTradingStatus" => %{"cost" => 1, "noSymbol" => 10},
               "lvtKlines" => 1,
               "convert/exchangeInfo" => 4,
               "insuranceBalance" => 1,
               "symbolAdlRisk" => 1,
               "tradingSchedule" => 5
             }
           },
           "fapiData" => %{
             "get" => %{
               "delivery-price" => 1,
               "openInterestHist" => 1,
               "topLongShortAccountRatio" => 1,
               "topLongShortPositionRatio" => 1,
               "globalLongShortAccountRatio" => 1,
               "takerlongshortRatio" => 1,
               "basis" => 1
             }
           },
           "fapiPrivate" => %{
             "get" => %{
               "forceOrders" => %{"cost" => 20, "noSymbol" => 50},
               "allOrders" => 5,
               "openOrder" => 1,
               "openOrders" => %{"cost" => 1, "noSymbol" => 40},
               "order" => 1,
               "account" => 5,
               "balance" => 5,
               "leverageBracket" => 1,
               "positionMargin/history" => 1,
               "positionRisk" => 5,
               "positionSide/dual" => 30,
               "userTrades" => 5,
               "income" => 30,
               "commissionRate" => 20,
               "rateLimit/order" => 1,
               "apiTradingStatus" => 1,
               "multiAssetsMargin" => 30,
               "apiReferral/ifNewUser" => 1,
               "apiReferral/customization" => 1,
               "apiReferral/userCustomization" => 1,
               "apiReferral/traderNum" => 1,
               "apiReferral/overview" => 1,
               "apiReferral/tradeVol" => 1,
               "apiReferral/rebateVol" => 1,
               "apiReferral/traderSummary" => 1,
               "adlQuantile" => 5,
               "pmAccountInfo" => 5,
               "orderAmendment" => 1,
               "income/asyn" => 1000,
               "income/asyn/id" => 10,
               "order/asyn" => 1000,
               "order/asyn/id" => 10,
               "trade/asyn" => 1000,
               "trade/asyn/id" => 10,
               "feeBurn" => 1,
               "symbolConfig" => 5,
               "accountConfig" => 5,
               "convert/orderStatus" => 5,
               "algoOrder" => 1,
               "openAlgoOrders" => %{"cost" => 1, "noSymbol" => 40},
               "allAlgoOrders" => 5,
               "stock/contract" => 50
             },
             "post" => %{
               "batchOrders" => 5,
               "positionSide/dual" => 1,
               "positionMargin" => 1,
               "marginType" => 1,
               "order" => 4,
               "order/test" => 1,
               "leverage" => 1,
               "listenKey" => 1,
               "countdownCancelAll" => 10,
               "multiAssetsMargin" => 1,
               "apiReferral/customization" => 1,
               "apiReferral/userCustomization" => 1,
               "feeBurn" => 1,
               "convert/getQuote" => 200,
               "convert/acceptQuote" => 20,
               "algoOrder" => 1
             },
             "put" => %{"listenKey" => 1, "order" => 1, "batchOrders" => 5},
             "delete" => %{
               "batchOrders" => 1,
               "order" => 1,
               "allOpenOrders" => 1,
               "listenKey" => 1,
               "algoOrder" => 1,
               "algoOpenOrders" => 1
             }
           },
           "fapiPublicV2" => %{"get" => %{"ticker/price" => 0}},
           "fapiPrivateV2" => %{"get" => %{"account" => 1, "balance" => 1, "positionRisk" => 1}},
           "fapiPublicV3" => %{"get" => %{}},
           "fapiPrivateV3" => %{"get" => %{"account" => 1, "balance" => 1, "positionRisk" => 1}},
           "eapiPublic" => %{
             "get" => %{
               "ping" => 1,
               "time" => 1,
               "exchangeInfo" => 1,
               "index" => 1,
               "ticker" => 5,
               "mark" => 5,
               "depth" => 1,
               "klines" => 1,
               "trades" => 5,
               "historicalTrades" => 20,
               "exerciseHistory" => 3,
               "openInterest" => 3
             }
           },
           "eapiPrivate" => %{
             "get" => %{
               "account" => 3,
               "position" => 5,
               "openOrders" => %{"cost" => 1, "noSymbol" => 40},
               "historyOrders" => 3,
               "userTrades" => 5,
               "exerciseRecord" => 5,
               "bill" => 1,
               "income/asyn" => 5,
               "income/asyn/id" => 5,
               "marginAccount" => 3,
               "mmp" => 1,
               "countdownCancelAll" => 1,
               "order" => 1,
               "block/order/orders" => 5,
               "block/order/execute" => 5,
               "block/user-trades" => 5,
               "blockTrades" => 5,
               "comission" => 5
             },
             "post" => %{
               "order" => 1,
               "batchOrders" => 5,
               "listenKey" => 1,
               "mmpSet" => 1,
               "mmpReset" => 1,
               "countdownCancelAll" => 1,
               "countdownCancelAllHeartBeat" => 10,
               "block/order/create" => 5,
               "block/order/execute" => 5
             },
             "put" => %{"listenKey" => 1, "block/order/create" => 5},
             "delete" => %{
               "order" => 1,
               "batchOrders" => 1,
               "allOpenOrders" => 1,
               "allOpenOrdersByUnderlying" => 1,
               "listenKey" => 1,
               "block/order/create" => 5
             }
           },
           "public" => %{
             "get" => %{
               "ping" => 0.2,
               "time" => 0.2,
               "depth" => %{
                 "cost" => 1,
                 "byLimit" => [[100, 1], [500, 5], [1000, 10], [5000, 50]]
               },
               "trades" => 2,
               "aggTrades" => 0.4,
               "historicalTrades" => 2,
               "klines" => 0.4,
               "uiKlines" => 0.4,
               "ticker/24hr" => %{"cost" => 0.4, "noSymbol" => 16},
               "ticker" => %{"cost" => 0.4, "noSymbol" => 16},
               "ticker/tradingDay" => 0.8,
               "ticker/price" => %{"cost" => 0.4, "noSymbol" => 0.8},
               "ticker/bookTicker" => %{"cost" => 0.4, "noSymbol" => 0.8},
               "exchangeInfo" => 4,
               "avgPrice" => 0.4
             },
             "put" => %{"userDataStream" => 0.4},
             "post" => %{"userDataStream" => 0.4},
             "delete" => %{"userDataStream" => 0.4}
           },
           "private" => %{
             "get" => %{
               "allOrderList" => 4,
               "openOrderList" => 1.2,
               "orderList" => 0.8,
               "order" => 0.8,
               "openOrders" => %{"cost" => 1.2, "noSymbol" => 16},
               "allOrders" => 4,
               "account" => 4,
               "myTrades" => 4,
               "rateLimit/order" => 8,
               "myPreventedMatches" => 4,
               "myAllocations" => 4,
               "account/commission" => 4
             },
             "post" => %{
               "order/oco" => 0.2,
               "orderList/oco" => 0.2,
               "orderList/oto" => 0.2,
               "orderList/otoco" => 0.2,
               "orderList/opo" => 0.2,
               "orderList/opoco" => 0.2,
               "sor/order" => 0.2,
               "sor/order/test" => 0.2,
               "order" => 0.2,
               "order/cancelReplace" => 0.2,
               "order/test" => 0.2
             },
             "delete" => %{"openOrders" => 0.2, "orderList" => 0.2, "order" => 0.2}
           },
           "papi" => %{
             "get" => %{
               "ping" => 0.2,
               "um/order" => 1,
               "um/openOrder" => 1,
               "um/openOrders" => %{"cost" => 1, "noSymbol" => 40},
               "um/allOrders" => 5,
               "cm/order" => 1,
               "cm/openOrder" => 1,
               "cm/openOrders" => %{"cost" => 1, "noSymbol" => 40},
               "cm/allOrders" => 20,
               "um/conditional/openOrder" => 1,
               "um/conditional/openOrders" => %{"cost" => 1, "noSymbol" => 40},
               "um/conditional/orderHistory" => 1,
               "um/conditional/allOrders" => %{"cost" => 1, "noSymbol" => 40},
               "cm/conditional/openOrder" => 1,
               "cm/conditional/openOrders" => %{"cost" => 1, "noSymbol" => 40},
               "cm/conditional/orderHistory" => 1,
               "cm/conditional/allOrders" => 40,
               "margin/order" => 10,
               "margin/openOrders" => 5,
               "margin/allOrders" => 100,
               "margin/orderList" => 5,
               "margin/allOrderList" => 100,
               "margin/openOrderList" => 5,
               "margin/myTrades" => 5,
               "balance" => 4,
               "account" => 4,
               "margin/maxBorrowable" => 1,
               "margin/maxWithdraw" => 1,
               "um/positionRisk" => 1,
               "cm/positionRisk" => 0.2,
               "um/positionSide/dual" => 6,
               "cm/positionSide/dual" => 6,
               "um/userTrades" => 5,
               "cm/userTrades" => 20,
               "um/leverageBracket" => 0.2,
               "cm/leverageBracket" => 0.2,
               "margin/forceOrders" => 1,
               "um/forceOrders" => %{"cost" => 20, "noSymbol" => 50},
               "cm/forceOrders" => %{"cost" => 20, "noSymbol" => 50},
               "um/apiTradingStatus" => %{"cost" => 0.2, "noSymbol" => 2},
               "um/commissionRate" => 4,
               "cm/commissionRate" => 4,
               "margin/marginLoan" => 2,
               "margin/repayLoan" => 2,
               "margin/marginInterestHistory" => 0.2,
               "portfolio/interest-history" => 10,
               "um/income" => 6,
               "cm/income" => 6,
               "um/account" => 1,
               "cm/account" => 1,
               "repay-futures-switch" => 6,
               "um/adlQuantile" => 5,
               "cm/adlQuantile" => 5,
               "um/trade/asyn" => 300,
               "um/trade/asyn/id" => 2,
               "um/order/asyn" => 300,
               "um/order/asyn/id" => 2,
               "um/income/asyn" => 300,
               "um/income/asyn/id" => 2,
               "um/orderAmendment" => 1,
               "cm/orderAmendment" => 1,
               "um/feeBurn" => 30,
               "um/accountConfig" => 1,
               "um/symbolConfig" => 1,
               "cm/accountConfig" => 1,
               "cm/symbolConfig" => 1,
               "rateLimit/order" => 1
             },
             "post" => %{
               "um/order" => 1,
               "um/conditional/order" => 1,
               "cm/order" => 1,
               "cm/conditional/order" => 1,
               "margin/order" => 1,
               "marginLoan" => 100,
               "repayLoan" => 100,
               "margin/order/oco" => 1,
               "um/leverage" => 0.2,
               "cm/leverage" => 0.2,
               "um/positionSide/dual" => 0.2,
               "cm/positionSide/dual" => 0.2,
               "auto-collection" => 150,
               "bnb-transfer" => 150,
               "repay-futures-switch" => 150,
               "repay-futures-negative-balance" => 150,
               "listenKey" => 0.2,
               "asset-collection" => 6,
               "margin/repay-debt" => 3000,
               "um/feeBurn" => 1,
               "um/stock/contract" => 1
             },
             "put" => %{"listenKey" => 0.2, "um/order" => 1, "cm/order" => 1},
             "delete" => %{
               "um/order" => 1,
               "um/conditional/order" => 1,
               "um/allOpenOrders" => 1,
               "um/conditional/allOpenOrders" => 1,
               "cm/order" => 1,
               "cm/conditional/order" => 1,
               "cm/allOpenOrders" => 1,
               "cm/conditional/allOpenOrders" => 1,
               "margin/order" => 2,
               "margin/allOpenOrders" => 5,
               "margin/orderList" => 2,
               "listenKey" => 0.2
             }
           },
           "papiV2" => %{"get" => %{"um/account" => 1}}
         },
         fees: %{
           "trading" => %{
             "feeSide" => "get",
             "tierBased" => false,
             "percentage" => true,
             "taker" => Runtime.parse_number("0.001"),
             "maker" => Runtime.parse_number("0.001")
           },
           "linear" => %{
             "trading" => %{
               "feeSide" => "quote",
               "tierBased" => true,
               "percentage" => true,
               "taker" => Runtime.parse_number("0.000500"),
               "maker" => Runtime.parse_number("0.000200"),
               "tiers" => %{
                 "taker" => [
                   [Runtime.parse_number("0"), Runtime.parse_number("0.000400")],
                   [Runtime.parse_number("250"), Runtime.parse_number("0.000400")],
                   [Runtime.parse_number("2500"), Runtime.parse_number("0.000350")],
                   [Runtime.parse_number("7500"), Runtime.parse_number("0.000320")],
                   [Runtime.parse_number("22500"), Runtime.parse_number("0.000300")],
                   [Runtime.parse_number("50000"), Runtime.parse_number("0.000270")],
                   [Runtime.parse_number("100000"), Runtime.parse_number("0.000250")],
                   [Runtime.parse_number("200000"), Runtime.parse_number("0.000220")],
                   [Runtime.parse_number("400000"), Runtime.parse_number("0.000200")],
                   [Runtime.parse_number("750000"), Runtime.parse_number("0.000170")]
                 ],
                 "maker" => [
                   [Runtime.parse_number("0"), Runtime.parse_number("0.000200")],
                   [Runtime.parse_number("250"), Runtime.parse_number("0.000160")],
                   [Runtime.parse_number("2500"), Runtime.parse_number("0.000140")],
                   [Runtime.parse_number("7500"), Runtime.parse_number("0.000120")],
                   [Runtime.parse_number("22500"), Runtime.parse_number("0.000100")],
                   [Runtime.parse_number("50000"), Runtime.parse_number("0.000080")],
                   [Runtime.parse_number("100000"), Runtime.parse_number("0.000060")],
                   [Runtime.parse_number("200000"), Runtime.parse_number("0.000040")],
                   [Runtime.parse_number("400000"), Runtime.parse_number("0.000020")],
                   [Runtime.parse_number("750000"), Runtime.parse_number("0")]
                 ]
               }
             }
           },
           "inverse" => %{
             "trading" => %{
               "feeSide" => "base",
               "tierBased" => true,
               "percentage" => true,
               "taker" => Runtime.parse_number("0.000500"),
               "maker" => Runtime.parse_number("0.000100"),
               "tiers" => %{
                 "taker" => [
                   [Runtime.parse_number("0"), Runtime.parse_number("0.000500")],
                   [Runtime.parse_number("250"), Runtime.parse_number("0.000450")],
                   [Runtime.parse_number("2500"), Runtime.parse_number("0.000400")],
                   [Runtime.parse_number("7500"), Runtime.parse_number("0.000300")],
                   [Runtime.parse_number("22500"), Runtime.parse_number("0.000250")],
                   [Runtime.parse_number("50000"), Runtime.parse_number("0.000240")],
                   [Runtime.parse_number("100000"), Runtime.parse_number("0.000240")],
                   [Runtime.parse_number("200000"), Runtime.parse_number("0.000240")],
                   [Runtime.parse_number("400000"), Runtime.parse_number("0.000240")],
                   [Runtime.parse_number("750000"), Runtime.parse_number("0.000240")]
                 ],
                 "maker" => [
                   [Runtime.parse_number("0"), Runtime.parse_number("0.000100")],
                   [Runtime.parse_number("250"), Runtime.parse_number("0.000080")],
                   [Runtime.parse_number("2500"), Runtime.parse_number("0.000050")],
                   [Runtime.parse_number("7500"), Runtime.parse_number("0.0000030")],
                   [Runtime.parse_number("22500"), Runtime.parse_number("0")],
                   [Runtime.parse_number("50000"), Runtime.parse_number("-0.000050")],
                   [Runtime.parse_number("100000"), Runtime.parse_number("-0.000060")],
                   [Runtime.parse_number("200000"), Runtime.parse_number("-0.000070")],
                   [Runtime.parse_number("400000"), Runtime.parse_number("-0.000080")],
                   [Runtime.parse_number("750000"), Runtime.parse_number("-0.000090")]
                 ]
               }
             }
           },
           "option" => %{}
         },
         currencies: %{
           "BNFCR" =>
             Runtime.safe_currency_structure(%{
               "id" => "BNFCR",
               "code" => "BNFCR",
               "precision" => Runtime.parse_number("0.001")
             })
         },
         commonCurrencies: %{"BCC" => "BCC", "YOYO" => "YOYOW"},
         precisionMode: :tick_size,
         options: %{
           "sandboxMode" => false,
           "fetchMargins" => true,
           "fetchMarkets" => %{"types" => ["spot", "linear", "inverse"]},
           "loadAllOptions" => false,
           "fetchCurrencies" => true,
           "defaultTimeInForce" => "GTC",
           "defaultType" => "spot",
           "defaultSubType" => nil,
           "hasAlreadyAuthenticatedSuccessfully" => false,
           "warnOnFetchOpenOrdersWithoutSymbol" => true,
           "currencyToPrecisionRoundingMode" => :truncate,
           "throwMarginModeAlreadySet" => false,
           "fetchPositions" => "positionRisk",
           "recvWindow" => 10 * 1000,
           "timeDifference" => 0,
           "adjustForTimeDifference" => false,
           "newOrderRespType" => %{"market" => "FULL", "limit" => "FULL"},
           "quoteOrderQty" => true,
           "broker" => %{
             "spot" => "x-TKT5PX2F",
             "margin" => "x-TKT5PX2F",
             "future" => "x-cvBPrNm9",
             "delivery" => "x-xcKtGhcu",
             "swap" => "x-cvBPrNm9",
             "option" => "x-xcKtGhcu",
             "inverse" => "x-xcKtGhcu"
           },
           "accountsByType" => %{
             "main" => "MAIN",
             "spot" => "MAIN",
             "funding" => "FUNDING",
             "margin" => "MARGIN",
             "cross" => "MARGIN",
             "future" => "UMFUTURE",
             "delivery" => "CMFUTURE",
             "linear" => "UMFUTURE",
             "swap" => "UMFUTURE",
             "inverse" => "CMFUTURE",
             "option" => "OPTION"
           },
           "accountsById" => %{
             "MAIN" => "spot",
             "FUNDING" => "funding",
             "MARGIN" => "margin",
             "UMFUTURE" => "linear",
             "CMFUTURE" => "inverse",
             "OPTION" => "option"
           },
           "networks" => %{
             "ERC20" => "ETH",
             "ETH" => "ETH",
             "TRC20" => "TRX",
             "TRX" => "TRX",
             "BEP2" => "BNB",
             "BSC" => "BSC",
             "BEP20" => "BSC",
             "EOS" => "EOS",
             "SPL" => "SOL",
             "SOL" => "SOL",
             "ARBONE" => "ARBITRUM",
             "AVAXC" => "AVAXC",
             "MATIC" => "MATIC",
             "BASE" => "BASE",
             "SUI" => "SUI",
             "OP" => "OPTIMISM",
             "OPTIMISM" => "OPTIMISM",
             "NEAR" => "NEAR",
             "APT" => "APT",
             "SCROLL" => "SCROLL",
             "KAVA" => "KAVA",
             "XLM" => "XLM",
             "RSK" => "RSK",
             "SEI" => "SEI",
             "TON" => "TON",
             "ADA" => "ADA",
             "ALGO" => "ALGO",
             "RUNE" => "RUNE",
             "OSMO" => "OSMO",
             "CELO" => "CELO",
             "HBAR" => "HBAR",
             "ZKSYNCERA" => "ZKSYNCERA",
             "KLAY" => "KLAY",
             "ACA" => "ACA",
             "STX" => "STX",
             "XTZ" => "XTZ",
             "METIS" => "METIS",
             "EGLD" => "EGLD",
             "ASTR" => "ASTR",
             "CFX" => "CFX",
             "SCRT" => "SCRT",
             "ONT" => "ONT"
           },
           "networksById" => %{
             "TRX" => "TRC20",
             "BSC" => "BEP20",
             "ETH" => "ERC20",
             "SOL" => "SOL",
             "OPTIMISM" => "OP"
           },
           "impliedNetworks" => %{"ETH" => %{"ERC20" => "ETH"}, "TRX" => %{"TRC20" => "TRX"}},
           "legalMoney" => %{
             "MXN" => true,
             "UGX" => true,
             "SEK" => true,
             "CHF" => true,
             "VND" => true,
             "AED" => true,
             "DKK" => true,
             "KZT" => true,
             "HUF" => true,
             "PEN" => true,
             "PHP" => true,
             "USD" => true,
             "TRY" => true,
             "EUR" => true,
             "NGN" => true,
             "PLN" => true,
             "BRL" => true,
             "ZAR" => true,
             "KES" => true,
             "ARS" => true,
             "RUB" => true,
             "AUD" => true,
             "NOK" => true,
             "CZK" => true,
             "GBP" => true,
             "UAH" => true,
             "GHS" => true,
             "HKD" => true,
             "CAD" => true,
             "INR" => true,
             "JPY" => true,
             "NZD" => true
           },
           "legalMoneyCurrenciesById" => %{"BUSD" => "USD"},
           "defaultWithdrawPrecision" => 1.0e-8,
           "defaultFiatWithdrawPrecision" => 0.01
         },
         features: %{
           "spot" => %{
             "sandbox" => true,
             "fetchCurrencies" => %{"private" => true},
             "createOrder" => %{
               "marginMode" => true,
               "triggerPrice" => true,
               "triggerPriceType" => nil,
               "triggerDirection" => false,
               "stopLossPrice" => true,
               "takeProfitPrice" => true,
               "attachedStopLossTakeProfit" => nil,
               "timeInForce" => %{"IOC" => true, "FOK" => true, "PO" => true, "GTD" => false},
               "hedged" => true,
               "leverage" => false,
               "marketBuyByCost" => true,
               "marketBuyRequiresPrice" => false,
               "selfTradePrevention" => %{
                 "EXPIRE_MAKER" => true,
                 "EXPIRE_TAKER" => true,
                 "EXPIRE_BOTH" => true,
                 "NONE" => true
               },
               "trailing" => false,
               "icebergAmount" => true
             },
             "createOrders" => nil,
             "fetchMyTrades" => %{
               "marginMode" => false,
               "limit" => 1000,
               "daysBack" => nil,
               "untilDays" => 1,
               "symbolRequired" => true
             },
             "fetchOrder" => %{
               "marginMode" => true,
               "trigger" => false,
               "trailing" => false,
               "symbolRequired" => true
             },
             "fetchOpenOrders" => %{
               "marginMode" => true,
               "limit" => nil,
               "trigger" => false,
               "trailing" => false,
               "symbolRequired" => false
             },
             "fetchOrders" => %{
               "marginMode" => true,
               "limit" => 1000,
               "daysBack" => nil,
               "untilDays" => 10000,
               "trigger" => false,
               "trailing" => false,
               "symbolRequired" => true
             },
             "fetchClosedOrders" => %{
               "marginMode" => true,
               "limit" => 1000,
               "daysBack" => nil,
               "daysBackCanceled" => nil,
               "untilDays" => 10000,
               "trigger" => false,
               "trailing" => false,
               "symbolRequired" => true
             },
             "fetchOHLCV" => %{"limit" => 1000}
           },
           "forDerivatives" => %{
             "sandbox" => true,
             "createOrder" => %{
               "marginMode" => false,
               "triggerPrice" => true,
               "triggerPriceType" => %{"mark" => true, "last" => true, "index" => false},
               "stopLossPrice" => true,
               "takeProfitPrice" => true,
               "attachedStopLossTakeProfit" => nil,
               "timeInForce" => %{"IOC" => true, "FOK" => true, "PO" => true, "GTD" => true},
               "hedged" => true,
               "selfTradePrevention" => true,
               "trailing" => true,
               "iceberg" => false,
               "leverage" => false,
               "marketBuyRequiresPrice" => false,
               "marketBuyByCost" => true
             },
             "createOrders" => %{"max" => 5},
             "fetchMyTrades" => %{
               "marginMode" => false,
               "daysBack" => nil,
               "limit" => 1000,
               "untilDays" => 7,
               "symbolRequired" => true
             },
             "fetchOrder" => %{
               "marginMode" => false,
               "trigger" => false,
               "trailing" => false,
               "symbolRequired" => true
             },
             "fetchOpenOrders" => %{
               "marginMode" => true,
               "limit" => 500,
               "trigger" => false,
               "trailing" => false,
               "symbolRequired" => false
             },
             "fetchOrders" => %{
               "marginMode" => true,
               "limit" => 1000,
               "daysBack" => 90,
               "untilDays" => 7,
               "trigger" => false,
               "trailing" => false,
               "symbolRequired" => true
             },
             "fetchClosedOrders" => %{
               "marginMode" => true,
               "limit" => 1000,
               "daysBack" => 90,
               "daysBackCanceled" => 3,
               "untilDays" => 7,
               "trigger" => false,
               "trailing" => false,
               "symbolRequired" => true
             },
             "fetchOHLCV" => %{"limit" => 500}
           },
           "swap" => %{
             "linear" => %{"extends" => "forDerivatives"},
             "inverse" => %{"extends" => "forDerivatives"}
           },
           "future" => %{
             "linear" => %{"extends" => "forDerivatives"},
             "inverse" => %{"extends" => "forDerivatives"}
           }
         },
         exceptions: %{
           "spot" => %{
             "exact" => %{
               "-1004" => :operation_failed,
               "-1008" => :operation_failed,
               "-1099" => :authentication_error,
               "-1108" => :bad_request,
               "-1131" => :bad_request,
               "-1134" => :bad_request,
               "-1135" => :bad_request,
               "-1145" => :bad_request,
               "-1151" => :bad_symbol,
               "-2008" => :authentication_error,
               "-2016" => :operation_rejected,
               "-2021" => :bad_response,
               "-2022" => :bad_response,
               "-2026" => :invalid_order,
               "-3000" => :operation_failed,
               "-3001" => :authentication_error,
               "-3002" => :bad_symbol,
               "-3003" => :bad_request,
               "-3004" => :operation_rejected,
               "-3005" => :bad_request,
               "-3006" => :bad_request,
               "-3007" => :operation_failed,
               "-3008" => :bad_request,
               "-3009" => :operation_rejected,
               "-3010" => :bad_request,
               "-3011" => :bad_request,
               "-3012" => :operation_rejected,
               "-3013" => :bad_request,
               "-3014" => :account_suspended,
               "-3015" => :bad_request,
               "-3016" => :bad_request,
               "-3017" => :operation_rejected,
               "-3018" => :account_suspended,
               "-3019" => :account_suspended,
               "-3020" => :bad_request,
               "-3021" => :bad_request,
               "-3022" => :account_suspended,
               "-3023" => :operation_rejected,
               "-3024" => :operation_rejected,
               "-3025" => :bad_request,
               "-3026" => :bad_request,
               "-3027" => :bad_symbol,
               "-3028" => :bad_symbol,
               "-3029" => :operation_failed,
               "-3036" => :account_suspended,
               "-3037" => :operation_failed,
               "-3038" => :bad_request,
               "-3041" => :insufficient_funds,
               "-3042" => :bad_request,
               "-3043" => :permission_denied,
               "-3044" => :operation_failed,
               "-3045" => :operation_rejected,
               "-3999" => :permission_denied,
               "-4000" => :exchange_error,
               "-4001" => :bad_request,
               "-4002" => :bad_request,
               "-4003" => :bad_request,
               "-4004" => :authentication_error,
               "-4005" => :rate_limit_exceeded,
               "-4006" => :bad_request,
               "-4007" => :permission_denied,
               "-4008" => :permission_denied,
               "-4009" => :exchange_error,
               "-4010" => :permission_denied,
               "-4011" => :bad_request,
               "-4012" => :permission_denied,
               "-4013" => :authentication_error,
               "-4014" => :operation_rejected,
               "-4015" => :permission_denied,
               "-4016" => :permission_denied,
               "-4017" => :permission_denied,
               "-4018" => :bad_symbol,
               "-4019" => :bad_request,
               "-4020" => :exchange_error,
               "-4021" => :bad_request,
               "-4022" => :bad_request,
               "-4023" => :operation_rejected,
               "-4024" => :insufficient_funds,
               "-4025" => :insufficient_funds,
               "-4026" => :insufficient_funds,
               "-4027" => :operation_failed,
               "-4028" => :bad_request,
               "-4029" => :bad_request,
               "-4030" => :bad_response,
               "-4031" => :operation_failed,
               "-4032" => :operation_rejected,
               "-4033" => :bad_request,
               "-4034" => :operation_rejected,
               "-4035" => :permission_denied,
               "-4036" => :permission_denied,
               "-4037" => :operation_failed,
               "-4038" => :operation_failed,
               "-4039" => :permission_denied,
               "-4040" => :operation_rejected,
               "-4041" => :operation_failed,
               "-4042" => :operation_rejected,
               "-4043" => :operation_rejected,
               "-4044" => :permission_denied,
               "-4045" => :operation_failed,
               "-4046" => :authentication_error,
               "-4047" => :bad_request,
               "-4048" => :exchange_error,
               "-4049" => :exchange_error,
               "-4050" => :exchange_error,
               "-4051" => :exchange_error,
               "-4052" => :exchange_error,
               "-4053" => :exchange_error,
               "-4054" => :exchange_error,
               "-4055" => :exchange_error,
               "-4056" => :exchange_error,
               "-4057" => :exchange_error,
               "-4058" => :exchange_error,
               "-4059" => :exchange_error,
               "-4060" => :operation_failed,
               "-4061" => :exchange_error,
               "-4062" => :exchange_error,
               "-4063" => :exchange_error,
               "-4064" => :exchange_error,
               "-4065" => :exchange_error,
               "-4066" => :exchange_error,
               "-4067" => :exchange_error,
               "-4068" => :exchange_error,
               "-4069" => :exchange_error,
               "-4070" => :exchange_error,
               "-4071" => :exchange_error,
               "-4072" => :exchange_error,
               "-4073" => :exchange_error,
               "-4074" => :exchange_error,
               "-4075" => :exchange_error,
               "-4076" => :exchange_error,
               "-4077" => :exchange_error,
               "-4078" => :exchange_error,
               "-4079" => :exchange_error,
               "-4080" => :exchange_error,
               "-4081" => :exchange_error,
               "-4082" => :exchange_error,
               "-4083" => :exchange_error,
               "-4084" => :exchange_error,
               "-4085" => :exchange_error,
               "-4086" => :exchange_error,
               "-4087" => :exchange_error,
               "-4088" => :exchange_error,
               "-4089" => :exchange_error,
               "-4091" => :exchange_error,
               "-4092" => :exchange_error,
               "-4093" => :exchange_error,
               "-4094" => :exchange_error,
               "-4095" => :exchange_error,
               "-4096" => :exchange_error,
               "-4097" => :exchange_error,
               "-4098" => :exchange_error,
               "-4099" => :exchange_error,
               "-4101" => :exchange_error,
               "-4102" => :exchange_error,
               "-4103" => :exchange_error,
               "-4104" => :exchange_error,
               "-4105" => :exchange_error,
               "-4106" => :exchange_error,
               "-4107" => :exchange_error,
               "-4108" => :exchange_error,
               "-4109" => :exchange_error,
               "-4110" => :exchange_error,
               "-4112" => :exchange_error,
               "-4113" => :exchange_error,
               "-4114" => :exchange_error,
               "-4115" => :exchange_error,
               "-4116" => :exchange_error,
               "-4117" => :exchange_error,
               "-4118" => :exchange_error,
               "-4119" => :exchange_error,
               "-4120" => :exchange_error,
               "-4121" => :exchange_error,
               "-4122" => :exchange_error,
               "-4123" => :exchange_error,
               "-4124" => :exchange_error,
               "-4125" => :exchange_error,
               "-4126" => :exchange_error,
               "-4127" => :exchange_error,
               "-4128" => :exchange_error,
               "-4129" => :exchange_error,
               "-4130" => :exchange_error,
               "-4131" => :exchange_error,
               "-4132" => :exchange_error,
               "-4133" => :exchange_error,
               "-4134" => :exchange_error,
               "-4135" => :exchange_error,
               "-4136" => :exchange_error,
               "-4137" => :exchange_error,
               "-4138" => :exchange_error,
               "-4139" => :exchange_error,
               "-4141" => :exchange_error,
               "-4142" => :exchange_error,
               "-4143" => :exchange_error,
               "-4144" => :exchange_error,
               "-4145" => :exchange_error,
               "-4146" => :exchange_error,
               "-4147" => :exchange_error,
               "-4148" => :exchange_error,
               "-4149" => :exchange_error,
               "-4150" => :exchange_error,
               "-5001" => :bad_request,
               "-5002" => :insufficient_funds,
               "-5003" => :insufficient_funds,
               "-5004" => :operation_rejected,
               "-5005" => :operation_rejected,
               "-5006" => :operation_rejected,
               "-5007" => :bad_request,
               "-5008" => :operation_rejected,
               "-5009" => :bad_symbol,
               "-5010" => :operation_failed,
               "-5011" => :bad_request,
               "-5012" => :operation_failed,
               "-5013" => :insufficient_funds,
               "-5021" => :bad_request,
               "-5022" => :bad_request,
               "-6001" => :bad_symbol,
               "-6003" => :permission_denied,
               "-6004" => :bad_request,
               "-6005" => :bad_request,
               "-6006" => :bad_request,
               "-6007" => :operation_rejected,
               "-6008" => :operation_rejected,
               "-6009" => :rate_limit_exceeded,
               "-6011" => :operation_rejected,
               "-6012" => :insufficient_funds,
               "-6013" => :bad_response,
               "-6014" => :operation_rejected,
               "-6015" => :bad_request,
               "-6016" => :bad_request,
               "-6017" => :permission_denied,
               "-6018" => :insufficient_funds,
               "-6019" => :operation_rejected,
               "-6020" => :bad_request,
               "-7001" => :bad_request,
               "-7002" => :bad_request,
               "-10001" => :operation_failed,
               "-10002" => :bad_request,
               "-10005" => :bad_response,
               "-10007" => :bad_request,
               "-10008" => :bad_request,
               "-10009" => :bad_request,
               "-10010" => :bad_request,
               "-10011" => :insufficient_funds,
               "-10012" => :bad_request,
               "-10013" => :insufficient_funds,
               "-10015" => :operation_failed,
               "-10016" => :operation_failed,
               "-10017" => :operation_rejected,
               "-10018" => :bad_request,
               "-10019" => :bad_request,
               "-10020" => :bad_request,
               "-10021" => :invalid_order,
               "-10022" => :bad_request,
               "-10023" => :operation_failed,
               "-10024" => :bad_request,
               "-10025" => :operation_failed,
               "-10026" => :bad_request,
               "-10028" => :bad_request,
               "-10029" => :operation_rejected,
               "-10030" => :operation_rejected,
               "-10031" => :operation_rejected,
               "-10032" => :operation_failed,
               "-10034" => :operation_rejected,
               "-10039" => :operation_rejected,
               "-10040" => :operation_rejected,
               "-10041" => :operation_failed,
               "-10042" => :bad_symbol,
               "-10043" => :operation_rejected,
               "-10044" => :operation_rejected,
               "-10045" => :operation_rejected,
               "-10046" => :operation_rejected,
               "-10047" => :permission_denied,
               "-11008" => :operation_rejected,
               "-12014" => :rate_limit_exceeded,
               "-13000" => :operation_rejected,
               "-13001" => :operation_rejected,
               "-13002" => :operation_rejected,
               "-13003" => :permission_denied,
               "-13004" => :operation_rejected,
               "-13005" => :operation_rejected,
               "-13006" => :operation_rejected,
               "-13007" => :permission_denied,
               "-18002" => :operation_rejected,
               "-18003" => :operation_rejected,
               "-18004" => :operation_rejected,
               "-18005" => :permission_denied,
               "-18006" => :operation_rejected,
               "-18007" => :operation_rejected,
               "-21001" => :bad_request,
               "-21002" => :bad_request,
               "-21003" => :bad_response,
               "-21004" => :operation_rejected,
               "-21005" => :insufficient_funds,
               "-21006" => :operation_failed,
               "-21007" => :operation_failed,
               "-32603" => :bad_request,
               "400002" => :bad_request,
               "100001003" => :authentication_error,
               "200003903" => :authentication_error
             }
           },
           "linear" => %{
             "exact" => %{
               "-1005" => :permission_denied,
               "-1008" => :operation_failed,
               "-1011" => :permission_denied,
               "-1023" => :bad_request,
               "-1099" => :authentication_error,
               "-1109" => :permission_denied,
               "-1110" => :bad_request,
               "-1113" => :bad_request,
               "-1122" => :bad_request,
               "-1126" => :bad_symbol,
               "-1136" => :bad_request,
               "-2012" => :operation_failed,
               "-2016" => :operation_rejected,
               "-2017" => :permission_denied,
               "-2018" => :insufficient_funds,
               "-2019" => :insufficient_funds,
               "-2020" => :operation_failed,
               "-2021" => :order_immediately_fillable,
               "-2022" => :invalid_order,
               "-2023" => :operation_failed,
               "-2024" => :insufficient_funds,
               "-2025" => :operation_rejected,
               "-2026" => :invalid_order,
               "-2027" => :operation_rejected,
               "-2028" => :operation_rejected,
               "-4063" => :bad_request,
               "-4064" => :bad_request,
               "-4065" => :bad_request,
               "-4066" => :bad_request,
               "-4069" => :bad_request,
               "-4070" => :bad_request,
               "-4071" => :bad_request,
               "-4072" => :operation_rejected,
               "-4073" => :bad_request,
               "-4074" => :operation_rejected,
               "-4075" => :bad_request,
               "-4076" => :operation_rejected,
               "-4077" => :operation_rejected,
               "-4078" => :operation_failed,
               "-4079" => :bad_request,
               "-4080" => :permission_denied,
               "-4081" => :bad_request,
               "-4085" => :bad_request,
               "-4087" => :permission_denied,
               "-4088" => :permission_denied,
               "-4114" => :bad_request,
               "-4115" => :bad_request,
               "-4116" => :invalid_order,
               "-4117" => :operation_rejected,
               "-4118" => :operation_rejected,
               "-4131" => :operation_rejected,
               "-4140" => :bad_request,
               "-4141" => :operation_rejected,
               "-4144" => :bad_symbol,
               "-4164" => :invalid_order,
               "-4136" => :invalid_order,
               "-4165" => :bad_request,
               "-4167" => :bad_request,
               "-4168" => :bad_request,
               "-4169" => :operation_rejected,
               "-4170" => :operation_rejected,
               "-4171" => :operation_rejected,
               "-4172" => :operation_rejected,
               "-4183" => :bad_request,
               "-4184" => :bad_request,
               "-4192" => :permission_denied,
               "-4202" => :permission_denied,
               "-4203" => :permission_denied,
               "-4205" => :permission_denied,
               "-4206" => :permission_denied,
               "-4208" => :operation_rejected,
               "-4209" => :operation_rejected,
               "-4210" => :bad_request,
               "-4211" => :bad_request,
               "-4400" => :permission_denied,
               "-4401" => :permission_denied,
               "-4402" => :permission_denied,
               "-4403" => :permission_denied,
               "-5021" => :order_not_fillable,
               "-5022" => :order_not_fillable,
               "-5024" => :operation_rejected,
               "-5025" => :operation_rejected,
               "-5026" => :operation_rejected,
               "-5027" => :operation_rejected,
               "-5028" => :bad_request,
               "-5037" => :bad_request,
               "-5038" => :bad_request,
               "-5039" => :bad_request,
               "-5040" => :bad_request,
               "-5041" => :operation_failed
             }
           },
           "inverse" => %{
             "exact" => %{
               "-1005" => :permission_denied,
               "-1011" => :permission_denied,
               "-1023" => :bad_request,
               "-1109" => :authentication_error,
               "-1110" => :bad_symbol,
               "-1113" => :bad_request,
               "-1128" => :bad_request,
               "-1136" => :bad_request,
               "-2016" => :operation_rejected,
               "-2018" => :insufficient_funds,
               "-2019" => :insufficient_funds,
               "-2020" => :operation_failed,
               "-2021" => :order_immediately_fillable,
               "-2022" => :invalid_order,
               "-2023" => :operation_failed,
               "-2024" => :bad_request,
               "-2025" => :operation_rejected,
               "-2026" => :invalid_order,
               "-2027" => :operation_rejected,
               "-2028" => :operation_rejected,
               "-4086" => :bad_request,
               "-4087" => :bad_symbol,
               "-4088" => :bad_request,
               "-4089" => :permission_denied,
               "-4090" => :permission_denied,
               "-4110" => :bad_request,
               "-4111" => :bad_request,
               "-4112" => :operation_rejected,
               "-4113" => :operation_rejected,
               "-4150" => :operation_rejected,
               "-4151" => :bad_request,
               "-4152" => :bad_request,
               "-4154" => :bad_request,
               "-4155" => :bad_request,
               "-4178" => :bad_request,
               "-4188" => :bad_request,
               "-4192" => :permission_denied,
               "-4194" => :permission_denied,
               "-4195" => :permission_denied,
               "-4196" => :bad_request,
               "-4197" => :operation_rejected,
               "-4198" => :operation_rejected,
               "-4199" => :bad_request,
               "-4200" => :permission_denied,
               "-4201" => :permission_denied,
               "-4202" => :operation_rejected
             }
           },
           "option" => %{
             "exact" => %{
               "-1003" => :exchange_error,
               "-1004" => :exchange_error,
               "-1006" => :exchange_error,
               "-1007" => :exchange_error,
               "-1008" => :rate_limit_exceeded,
               "-1010" => :exchange_error,
               "-1013" => :exchange_error,
               "-1108" => :exchange_error,
               "-1112" => :exchange_error,
               "-1114" => :exchange_error,
               "-1128" => :bad_symbol,
               "-1129" => :bad_symbol,
               "-1131" => :bad_request,
               "-2011" => :exchange_error,
               "-2018" => :insufficient_funds,
               "-2027" => :insufficient_funds,
               "-3029" => :operation_failed,
               "-4006" => :exchange_error,
               "-4007" => :exchange_error,
               "-4008" => :exchange_error,
               "-4009" => :exchange_error,
               "-4010" => :exchange_error,
               "-4011" => :exchange_error,
               "-4012" => :exchange_error,
               "-4014" => :exchange_error,
               "-4015" => :exchange_error,
               "-4016" => :exchange_error,
               "-4017" => :exchange_error,
               "-4018" => :exchange_error,
               "-4019" => :exchange_error,
               "-4020" => :exchange_error,
               "-4021" => :exchange_error,
               "-4022" => :exchange_error,
               "-4023" => :exchange_error,
               "-4024" => :exchange_error,
               "-4025" => :exchange_error,
               "-4026" => :exchange_error,
               "-4027" => :exchange_error,
               "-4028" => :exchange_error,
               "-4031" => :exchange_error,
               "-4032" => :exchange_error,
               "-4033" => :exchange_error,
               "-4034" => :exchange_error,
               "-4035" => :exchange_error,
               "-4036" => :exchange_error,
               "-4037" => :exchange_error,
               "-4038" => :exchange_error,
               "-4039" => :exchange_error,
               "-4040" => :exchange_error,
               "-4041" => :exchange_error,
               "-4042" => :exchange_error,
               "-4043" => :exchange_error,
               "-4044" => :exchange_error,
               "-4045" => :exchange_error,
               "-4046" => :exchange_error,
               "-4047" => :exchange_error,
               "-4048" => :exchange_error,
               "-4049" => :exchange_error,
               "-4050" => :exchange_error,
               "-4051" => :exchange_error,
               "-4052" => :exchange_error,
               "-4053" => :exchange_error,
               "-4054" => :exchange_error,
               "-4056" => :exchange_error,
               "-4057" => :exchange_error,
               "-4058" => :exchange_error,
               "-4059" => :exchange_error,
               "-4060" => :exchange_error,
               "-4061" => :exchange_error,
               "-4062" => :exchange_error,
               "-4063" => :exchange_error,
               "-4064" => :exchange_error,
               "-4065" => :exchange_error,
               "-4066" => :exchange_error,
               "-4067" => :exchange_error,
               "-4068" => :exchange_error,
               "-4069" => :exchange_error,
               "-4070" => :exchange_error,
               "-4071" => :exchange_error,
               "-4072" => :exchange_error,
               "-4073" => :exchange_error,
               "-4074" => :exchange_error,
               "-4075" => :exchange_error,
               "-4076" => :exchange_error,
               "-4077" => :exchange_error,
               "-4078" => :exchange_error,
               "-4079" => :exchange_error,
               "-4080" => :exchange_error,
               "-4081" => :exchange_error,
               "-4082" => :exchange_error,
               "-4083" => :exchange_error,
               "-4084" => :exchange_error,
               "-4085" => :exchange_error,
               "-4086" => :exchange_error,
               "-4087" => :exchange_error,
               "-4088" => :exchange_error,
               "-4089" => :exchange_error,
               "-4091" => :exchange_error,
               "-4092" => :exchange_error,
               "-4093" => :exchange_error,
               "-4094" => :exchange_error,
               "-4095" => :exchange_error,
               "-4096" => :exchange_error,
               "-4097" => :exchange_error,
               "-4098" => :exchange_error,
               "-4099" => :exchange_error,
               "-4101" => :exchange_error,
               "-4102" => :exchange_error,
               "-4103" => :exchange_error,
               "-4104" => :exchange_error,
               "-4105" => :exchange_error,
               "-4106" => :exchange_error,
               "-4107" => :exchange_error,
               "-4108" => :exchange_error,
               "-4109" => :exchange_error,
               "-4110" => :exchange_error,
               "-4112" => :exchange_error,
               "-4113" => :exchange_error,
               "-4114" => :exchange_error,
               "-4115" => :exchange_error,
               "-4116" => :exchange_error,
               "-4117" => :exchange_error,
               "-4118" => :exchange_error,
               "-4119" => :exchange_error,
               "-4120" => :exchange_error,
               "-4121" => :exchange_error,
               "-4122" => :exchange_error,
               "-4123" => :exchange_error,
               "-4124" => :exchange_error,
               "-4125" => :exchange_error,
               "-4126" => :exchange_error,
               "-4127" => :exchange_error,
               "-4128" => :exchange_error,
               "-4129" => :exchange_error,
               "-4130" => :exchange_error,
               "-4131" => :exchange_error,
               "-4132" => :exchange_error,
               "-4133" => :exchange_error,
               "-4134" => :exchange_error,
               "-4135" => :exchange_error,
               "-4136" => :exchange_error,
               "-4137" => :exchange_error,
               "-4138" => :exchange_error,
               "-4139" => :exchange_error,
               "-4141" => :exchange_error,
               "-4142" => :exchange_error,
               "-4143" => :exchange_error,
               "-4144" => :exchange_error,
               "-4145" => :exchange_error,
               "-4146" => :exchange_error,
               "-4147" => :exchange_error,
               "-4148" => :exchange_error,
               "-4149" => :exchange_error,
               "-4150" => :exchange_error,
               "-20121" => :exchange_error,
               "-20124" => :exchange_error,
               "-20130" => :exchange_error,
               "-20132" => :exchange_error,
               "-20194" => :exchange_error,
               "-20195" => :exchange_error,
               "-20196" => :exchange_error,
               "-20198" => :exchange_error,
               "-20204" => :exchange_error
             }
           },
           "portfolioMargin" => %{
             "exact" => %{
               "-1000" => :operation_failed,
               "-1001" => :exchange_error,
               "-1002" => :permission_denied,
               "-1003" => :rate_limit_exceeded,
               "-1004" => :bad_request,
               "-1005" => :permission_denied,
               "-1006" => :bad_response,
               "-1007" => :bad_response,
               "-1008" => :operation_failed,
               "-1010" => :exchange_error,
               "-1011" => :permission_denied,
               "-1013" => :exchange_error,
               "-1014" => :invalid_order,
               "-1015" => :invalid_order,
               "-1016" => :not_supported,
               "-1020" => :not_supported,
               "-1021" => :bad_request,
               "-1022" => :bad_request,
               "-1023" => :bad_request,
               "-1099" => :operation_failed,
               "-1100" => :bad_request,
               "-1101" => :bad_request,
               "-1102" => :bad_request,
               "-1103" => :bad_request,
               "-1104" => :bad_request,
               "-1105" => :bad_request,
               "-1106" => :bad_request,
               "-1108" => :bad_request,
               "-1109" => :bad_request,
               "-1110" => :bad_symbol,
               "-1111" => :bad_request,
               "-1112" => :bad_request,
               "-1113" => :bad_request,
               "-1114" => :bad_request,
               "-1115" => :bad_request,
               "-1116" => :bad_request,
               "-1117" => :bad_request,
               "-1118" => :bad_request,
               "-1119" => :bad_request,
               "-1120" => :bad_request,
               "-1121" => :bad_symbol,
               "-1125" => :bad_request,
               "-1127" => :bad_request,
               "-1128" => :bad_request,
               "-1130" => :bad_request,
               "-1131" => :bad_request,
               "-1134" => :bad_request,
               "-1136" => :bad_request,
               "-1145" => :bad_request,
               "-1151" => :bad_request,
               "-2010" => :invalid_order,
               "-2011" => :operation_rejected,
               "-2013" => :order_not_found,
               "-2014" => :operation_rejected,
               "-2015" => :operation_rejected,
               "-2016" => :operation_failed,
               "-2018" => :operation_failed,
               "-2019" => :operation_failed,
               "-2020" => :order_not_fillable,
               "-2021" => :order_immediately_fillable,
               "-2022" => :invalid_order,
               "-2023" => :operation_failed,
               "-2024" => :operation_rejected,
               "-2025" => :operation_rejected,
               "-2026" => :invalid_order,
               "-2027" => :operation_rejected,
               "-2028" => :operation_rejected,
               "-4000" => :bad_request,
               "-4001" => :bad_request,
               "-4002" => :bad_request,
               "-4003" => :bad_request,
               "-4004" => :bad_request,
               "-4005" => :bad_request,
               "-4006" => :bad_request,
               "-4007" => :bad_request,
               "-4008" => :bad_request,
               "-4009" => :bad_request,
               "-4010" => :bad_request,
               "-4011" => :bad_request,
               "-4012" => :bad_request,
               "-4013" => :bad_request,
               "-4014" => :bad_request,
               "-4015" => :bad_request,
               "-4016" => :bad_request,
               "-4017" => :bad_request,
               "-4018" => :bad_request,
               "-4019" => :bad_request,
               "-4020" => :bad_request,
               "-4021" => :bad_request,
               "-4022" => :bad_request,
               "-4023" => :bad_request,
               "-4024" => :bad_request,
               "-4025" => :bad_request,
               "-4026" => :bad_request,
               "-4027" => :bad_request,
               "-4028" => :bad_request,
               "-4029" => :bad_request,
               "-4030" => :bad_request,
               "-4031" => :bad_request,
               "-4032" => :bad_request,
               "-4033" => :bad_request,
               "-4044" => :bad_request,
               "-4045" => :bad_request,
               "-4046" => :bad_request,
               "-4047" => :bad_request,
               "-4048" => :bad_request,
               "-4049" => :bad_request,
               "-4050" => :bad_request,
               "-4051" => :bad_request,
               "-4052" => :bad_request,
               "-4053" => :bad_request,
               "-4054" => :bad_request,
               "-4055" => :bad_request,
               "-4056" => :permission_denied,
               "-4057" => :permission_denied,
               "-4058" => :bad_request,
               "-4059" => :bad_request,
               "-4060" => :bad_request,
               "-4061" => :invalid_order,
               "-4062" => :bad_request,
               "-4063" => :bad_request,
               "-4064" => :bad_request,
               "-4065" => :bad_request,
               "-4066" => :bad_request,
               "-4067" => :bad_request,
               "-4068" => :bad_request,
               "-4069" => :bad_request,
               "-4070" => :bad_request,
               "-4071" => :bad_request,
               "-4072" => :operation_rejected,
               "-4073" => :bad_request,
               "-4074" => :bad_request,
               "-4075" => :bad_request,
               "-4076" => :operation_rejected,
               "-4077" => :operation_rejected,
               "-4078" => :operation_failed,
               "-4079" => :bad_request,
               "-4080" => :permission_denied,
               "-4081" => :bad_request,
               "-4082" => :bad_request,
               "-4083" => :bad_request,
               "-4084" => :not_supported,
               "-4085" => :bad_request,
               "-4086" => :bad_request,
               "-4087" => :permission_denied,
               "-4088" => :permission_denied,
               "-4104" => :bad_request,
               "-4114" => :bad_request,
               "-4115" => :bad_request,
               "-4118" => :operation_rejected,
               "-4131" => :operation_rejected,
               "-4135" => :bad_request,
               "-4137" => :bad_request,
               "-4138" => :bad_request,
               "-4139" => :bad_request,
               "-4140" => :order_immediately_fillable,
               "-4141" => :bad_request,
               "-4142" => :order_immediately_fillable,
               "-4144" => :bad_symbol,
               "-4161" => :operation_rejected,
               "-4164" => :invalid_order,
               "-4165" => :bad_request,
               "-4183" => :invalid_order,
               "-4184" => :invalid_order,
               "-4408" => :invalid_order,
               "-5021" => :order_not_fillable,
               "-5022" => :order_not_fillable,
               "-5028" => :operation_failed,
               "-5041" => :rate_limit_exceeded
             }
           },
           "exact" => %{
             "-1000" => :operation_failed,
             "-1001" => :operation_failed,
             "-1002" => :authentication_error,
             "-1003" => :rate_limit_exceeded,
             "-1004" => :operation_rejected,
             "-1006" => :operation_failed,
             "-1007" => :request_timeout,
             "-1010" => :operation_failed,
             "-1013" => :bad_request,
             "-1014" => :invalid_order,
             "-1015" => :rate_limit_exceeded,
             "-1016" => :bad_request,
             "-1020" => :bad_request,
             "-1021" => :invalid_nonce,
             "-1022" => :authentication_error,
             "-1100" => :bad_request,
             "-1101" => :bad_request,
             "-1102" => :bad_request,
             "-1103" => :bad_request,
             "-1104" => :bad_request,
             "-1105" => :bad_request,
             "-1106" => :bad_request,
             "-1108" => :bad_symbol,
             "-1111" => :bad_request,
             "-1112" => :operation_failed,
             "-1114" => :bad_request,
             "-1115" => :bad_request,
             "-1116" => :bad_request,
             "-1117" => :bad_request,
             "-1118" => :bad_request,
             "-1119" => :bad_request,
             "-1120" => :bad_request,
             "-1121" => :bad_symbol,
             "-1125" => :authentication_error,
             "-1127" => :bad_request,
             "-1128" => :bad_request,
             "-1130" => :bad_request,
             "-2010" => :invalid_order,
             "-2011" => :order_not_found,
             "-2013" => :order_not_found,
             "-2014" => :authentication_error,
             "-2015" => :authentication_error,
             "-4000" => :invalid_order,
             "-4001" => :bad_request,
             "-4002" => :bad_request,
             "-4003" => :bad_request,
             "-4004" => :bad_request,
             "-4005" => :bad_request,
             "-4006" => :bad_request,
             "-4007" => :bad_request,
             "-4008" => :bad_request,
             "-4009" => :bad_request,
             "-4010" => :bad_request,
             "-4011" => :bad_request,
             "-4012" => :bad_request,
             "-4013" => :bad_request,
             "-4014" => :bad_request,
             "-4015" => :bad_request,
             "-4016" => :bad_request,
             "-4017" => :bad_request,
             "-4018" => :bad_request,
             "-4019" => :operation_rejected,
             "-4020" => :bad_request,
             "-4021" => :bad_request,
             "-4022" => :bad_request,
             "-4023" => :bad_request,
             "-4024" => :bad_request,
             "-4025" => :bad_request,
             "-4026" => :bad_request,
             "-4027" => :bad_request,
             "-4028" => :bad_request,
             "-4029" => :bad_request,
             "-4030" => :bad_request,
             "-4031" => :bad_request,
             "-4032" => :operation_rejected,
             "-4033" => :bad_request,
             "-4044" => :bad_request,
             "-4045" => :operation_rejected,
             "-4046" => :operation_rejected,
             "-4047" => :operation_rejected,
             "-4048" => :operation_rejected,
             "-4049" => :bad_request,
             "-4050" => :insufficient_funds,
             "-4051" => :insufficient_funds,
             "-4052" => :operation_rejected,
             "-4053" => :bad_request,
             "-4054" => :operation_rejected,
             "-4055" => :bad_request,
             "-4056" => :authentication_error,
             "-4057" => :authentication_error,
             "-4058" => :bad_request,
             "-4059" => :operation_rejected,
             "-4060" => :bad_request,
             "-4061" => :operation_rejected,
             "-4062" => :bad_request,
             "-4067" => :operation_rejected,
             "-4068" => :operation_rejected,
             "-4082" => :bad_request,
             "-4083" => :operation_rejected,
             "-4084" => :bad_request,
             "-4086" => :bad_request,
             "-4104" => :bad_request,
             "-4135" => :bad_request,
             "-4137" => :bad_request,
             "-4138" => :bad_request,
             "-4139" => :bad_request,
             "-4142" => :order_immediately_fillable,
             "-20121" => :bad_symbol,
             "-20124" => :bad_request,
             "-20130" => :bad_request,
             "-20132" => :bad_request,
             "-20194" => :bad_request,
             "-20195" => :bad_request,
             "-20196" => :bad_request,
             "-20198" => :operation_rejected,
             "-20204" => :bad_request,
             "System is under maintenance." => :on_maintenance,
             "System abnormality" => :operation_failed,
             "You are not authorized to execute this request." => :permission_denied,
             "API key does not exist" => :authentication_error,
             "Order would trigger immediately." => :order_immediately_fillable,
             "Stop price would trigger immediately." => :order_immediately_fillable,
             "Order would immediately match and take." => :order_immediately_fillable,
             "Account has insufficient balance for requested action." => :insufficient_funds,
             "Rest API trading is not enabled." => :permission_denied,
             "This account may not place or cancel orders." => :permission_denied,
             "You don't have permission." => :permission_denied,
             "Market is closed." => :market_closed,
             "Too many requests. Please try again later." => :rate_limit_exceeded,
             "This action is disabled on this account." => :account_suspended,
             "Limit orders require GTC for this phase." => :bad_request,
             "This order type is not possible in this trading phase." => :bad_request,
             "This type of sub-account exceeds the maximum number limit" => :operation_rejected,
             "This symbol is restricted for this account." => :permission_denied,
             "This symbol is not permitted for this account." => :permission_denied
           },
           "broad" => %{
             "has no operation privilege" => :permission_denied,
             "MAX_POSITION" => :bad_request,
             "PERCENT_PRICE_BY_SIDE" => :invalid_order
           }
         },
         rollingWindowSize: 60000
       })}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec is_inverse(String.t(), String.t() | nil, (RawEndpoint.t(), params() ->
                                                    {:ok, map()} | {:error, term()})) ::
          {:ok, boolean()} | {:error, term()}
  def is_inverse(type, sub_type \\ nil, fetcher \\ &default_fetcher/2) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{}}, %{})
    _ = exchange
    _ = fetcher
    _ = type
    _ = sub_type

    try do
      if Runtime.truthy(sub_type == nil) do
        throw({:ccxt_return, type == "delivery"})
      else
        throw({:ccxt_return, sub_type == "inverse"})
      end
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec is_linear(String.t(), String.t() | nil, (RawEndpoint.t(), params() ->
                                                   {:ok, map()} | {:error, term()})) ::
          {:ok, boolean()} | {:error, term()}
  def is_linear(type, sub_type \\ nil, fetcher \\ &default_fetcher/2) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{}}, %{})
    _ = exchange
    _ = fetcher
    _ = type
    _ = sub_type

    try do
      if Runtime.truthy(sub_type == nil) do
        throw({:ccxt_return, Runtime.truthy(type == "future") or Runtime.truthy(type == "swap")})
      else
        throw({:ccxt_return, sub_type == "linear"})
      end
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec set_sandbox_mode(boolean(), (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def set_sandbox_mode(enable, fetcher \\ &default_fetcher/2) do
    set_sandbox_mode(
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{"sandboxMode" => false, "enableDemoTrading" => false}
        },
        %{
          "isSandboxModeEnabled" => false,
          "urls" => %{
            "api" => %{
              "public" => "https://api.binance.com/api/v3",
              "private" => "https://api.binance.com/api/v3"
            },
            "test" => %{
              "public" => "https://testnet.binance.vision/api/v3",
              "private" => "https://testnet.binance.vision/api/v3"
            }
          }
        }
      ),
      enable,
      fetcher
    )
  end

  @spec set_sandbox_mode(map(), boolean(), (RawEndpoint.t(), params() ->
                                              {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def set_sandbox_mode(exchange, enable, fetcher) when is_map(exchange) do
    exchange =
      Runtime.deep_extend(
        Map.merge(
          %{
            id: "binance",
            has: %{},
            options: %{"sandboxMode" => false, "enableDemoTrading" => false}
          },
          %{
            "isSandboxModeEnabled" => false,
            "urls" => %{
              "api" => %{
                "public" => "https://api.binance.com/api/v3",
                "private" => "https://api.binance.com/api/v3"
              },
              "test" => %{
                "public" => "https://testnet.binance.vision/api/v3",
                "private" => "https://testnet.binance.vision/api/v3"
              }
            }
          }
        ),
        exchange
      )

    _ = exchange
    _ = fetcher
    _ = enable

    try do
      exchange = Runtime.set_sandbox_mode(exchange, enable)
      _ = exchange
      exchange = Runtime.put_value_in(exchange, ["options", "sandboxMode"], enable)
      {:ok, exchange}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec create_expired_option_market(term(), term()) :: term()
  def create_expired_option_market(exchange, symbol) do
    _ = exchange
    _ = symbol

    try do
      settle = "USDT"
      option_parts = Runtime.string_split(symbol, "-")
      symbol_base = Runtime.string_split(symbol, "/")
      base = nil
      _ = base

      {base} =
        if Runtime.truthy(Runtime.index_of(symbol, "/") > -1) do
          base = Runtime.safe_string(symbol_base, 0)
          _ = base

          {base}
        else
          base = Runtime.safe_string(option_parts, 0)
          _ = base

          {base}
        end

      _ = base

      expiry = Runtime.safe_string(option_parts, 1)
      strike = Runtime.safe_integer(option_parts, 2)
      strike_as_string = Runtime.safe_string(option_parts, 2)
      option_type = Runtime.safe_string(option_parts, 3)
      datetime = Runtime.convert_expire_date(expiry)
      timestamp = Runtime.parse8601(datetime)

      throw(
        {:ccxt_return,
         %{
           "id" => base <> "-" <> expiry <> "-" <> strike_as_string <> "-" <> option_type,
           "symbol" =>
             base <>
               "/" <>
               settle <>
               ":" <> settle <> "-" <> expiry <> "-" <> strike_as_string <> "-" <> option_type,
           "base" => base,
           "quote" => settle,
           "baseId" => base,
           "quoteId" => settle,
           "active" => nil,
           "type" => "option",
           "linear" => nil,
           "inverse" => nil,
           "spot" => false,
           "swap" => false,
           "future" => false,
           "option" => true,
           "margin" => false,
           "contract" => true,
           "contractSize" => nil,
           "expiry" => timestamp,
           "expiryDatetime" => datetime,
           "optionType" =>
             if(
               Runtime.truthy(option_type == "C"),
               do: "call",
               else: "put"
             ),
           "strike" => strike,
           "settle" => settle,
           "settleId" => settle,
           "precision" => %{"amount" => nil, "price" => nil},
           "limits" => %{
             "amount" => %{"min" => nil, "max" => nil},
             "price" => %{"min" => nil, "max" => nil},
             "cost" => %{"min" => nil, "max" => nil}
           },
           "info" => nil
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec market!(term(), term()) :: term()
  def market!(exchange, symbol) do
    _ = exchange
    _ = symbol

    try do
      if Runtime.truthy(Runtime.safe_value(exchange, "markets") == nil) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":exchange_error", [
             Runtime.safe_value(exchange, "id") <> " markets not loaded"
           ])}
        )
      end

      default_type = Runtime.safe_string(Runtime.safe_value(exchange, "options"), "defaultType")
      _ = default_type

      default_sub_type =
        Runtime.safe_string(Runtime.safe_value(exchange, "options"), "defaultSubType")

      is_legacy_linear = default_type == "future"
      is_legacy_inverse = default_type == "delivery"
      is_legacy = Runtime.truthy(is_legacy_linear) or Runtime.truthy(is_legacy_inverse)

      {default_type} =
        if Runtime.truthy(Runtime.typeof(symbol) == "string") do
          {default_type} =
            if Runtime.truthy(Runtime.has_key?(Runtime.markets(exchange), symbol)) do
              market = Runtime.safe_value(Runtime.markets(exchange), symbol)

              if Runtime.truthy(
                   Runtime.truthy(is_legacy) and
                     Runtime.truthy(Runtime.safe_value(market, "spot"))
                 ) do
                settle =
                  if(
                    Runtime.truthy(is_legacy_linear),
                    do: Runtime.safe_value(market, "quote"),
                    else: Runtime.safe_value(market, "base")
                  )

                futures_symbol = symbol <> ":" <> settle

                if Runtime.truthy(Runtime.has_key?(Runtime.markets(exchange), futures_symbol)) do
                  throw(
                    {:ccxt_return, Runtime.safe_value(Runtime.markets(exchange), futures_symbol)}
                  )
                end
              else
                throw({:ccxt_return, market})
              end

              {default_type}
            else
              {default_type} =
                if Runtime.truthy(
                     Runtime.has_key?(Runtime.safe_value(exchange, "markets_by_id"), symbol)
                   ) do
                  markets =
                    Runtime.safe_value(Runtime.safe_value(exchange, "markets_by_id"), symbol)

                  {default_type} =
                    if Runtime.truthy(is_legacy_linear) do
                      default_type = "linear"
                      _ = default_type

                      {default_type}
                    else
                      {default_type} =
                        if Runtime.truthy(is_legacy_inverse) do
                          default_type = "inverse"
                          _ = default_type

                          {default_type}
                        else
                          {default_type} =
                            if Runtime.truthy(default_type == nil) do
                              default_type = default_sub_type
                              _ = default_type

                              {default_type}
                            else
                              {default_type}
                            end

                          _ = default_type

                          {default_type}
                        end

                      _ = default_type

                      {default_type}
                    end

                  _ = default_type

                  Enum.each(Runtime.index_range(Runtime.js_length(markets), 0), fn i ->
                    market = Runtime.safe_value(markets, i)

                    if Runtime.truthy(Runtime.safe_value(market, default_type)) do
                      throw({:ccxt_return, market})
                    end
                  end)

                  throw({:ccxt_return, Runtime.safe_value(markets, 0)})
                else
                  if Runtime.truthy(
                       Runtime.truthy(Runtime.index_of(symbol, "/") > -1) and
                         Runtime.truthy(Runtime.index_of(symbol, ":") < 0)
                     ) do
                    if Runtime.truthy(
                         Runtime.truthy(default_type != nil) and
                           Runtime.truthy(default_type != "spot")
                       ) do
                      ccxt_match = Runtime.string_split(symbol, "/")
                      base = Runtime.safe_value(ccxt_match, 0, nil)
                      quote = Runtime.safe_value(ccxt_match, 1, nil)
                      _ = base
                      _ = quote

                      settle =
                        if(
                          Runtime.truthy(quote == "USD"),
                          do: base,
                          else: quote
                        )

                      futures_symbol = symbol <> ":" <> settle

                      if Runtime.truthy(
                           Runtime.has_key?(Runtime.markets(exchange), futures_symbol)
                         ) do
                        throw(
                          {:ccxt_return,
                           Runtime.safe_value(Runtime.markets(exchange), futures_symbol)}
                        )
                      end
                    end
                  else
                    if Runtime.truthy(
                         Runtime.truthy(Runtime.index_of(symbol, "-C") > -1) or
                           Runtime.truthy(Runtime.index_of(symbol, "-P") > -1)
                       ) do
                      throw({:ccxt_return, create_expired_option_market(exchange, symbol)})
                    end
                  end

                  {default_type}
                end

              _ = default_type

              {default_type}
            end

          _ = default_type

          {default_type}
        else
          {default_type}
        end

      _ = default_type

      throw(
        {:ccxt_error,
         Runtime.new_error_reason(":bad_symbol", [
           Runtime.safe_value(exchange, "id") <> " does not have market symbol " <> symbol
         ])}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec safe_market(term(), term(), term(), term(), term()) :: term()
  def safe_market(exchange, market_id \\ nil, market \\ nil, delimiter \\ nil, market_type \\ nil) do
    _ = exchange
    _ = market_id
    _ = market
    _ = delimiter
    _ = market_type

    try do
      is_option =
        Runtime.truthy(market_id != nil) and
          Runtime.truthy(
            Runtime.truthy(Runtime.index_of(market_id, "-C") > -1) or
              Runtime.truthy(Runtime.index_of(market_id, "-P") > -1)
          )

      if Runtime.truthy(
           Runtime.truthy(is_option) and
             Runtime.truthy(
               not Runtime.truthy(
                 Runtime.has_key?(Runtime.safe_value(exchange, "markets_by_id"), market_id)
               )
             )
         ) do
        throw({:ccxt_return, create_expired_option_market(exchange, market_id)})
      end

      throw(
        {:ccxt_return, Runtime.safe_market(exchange, market_id, market, delimiter, market_type)}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec nonce((RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})) ::
          {:ok, integer() | nil} | {:error, term()}
  def nonce(fetcher \\ &default_fetcher/2) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{"timeDifference" => 0}}, %{})
    _ = exchange
    _ = fetcher

    try do
      {:ok,
       Runtime.milliseconds(exchange) -
         Runtime.safe_value(Runtime.safe_value(exchange, "options"), "timeDifference")}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec enable_demo_trading(boolean(), (RawEndpoint.t(), params() ->
                                          {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def enable_demo_trading(enable, fetcher \\ &default_fetcher/2) do
    enable_demo_trading(
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{"sandboxMode" => false, "enableDemoTrading" => false}
        },
        %{
          "isSandboxModeEnabled" => false,
          "urls" => %{
            "api" => %{
              "public" => "https://api.binance.com/api/v3",
              "private" => "https://api.binance.com/api/v3"
            },
            "demo" => %{
              "public" => "https://demo-api.binance.com/api/v3",
              "private" => "https://demo-api.binance.com/api/v3"
            }
          }
        }
      ),
      enable,
      fetcher
    )
  end

  @spec enable_demo_trading(map(), boolean(), (RawEndpoint.t(), params() ->
                                                 {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def enable_demo_trading(exchange, enable, fetcher) when is_map(exchange) do
    exchange =
      Runtime.deep_extend(
        Map.merge(
          %{
            id: "binance",
            has: %{},
            options: %{"sandboxMode" => false, "enableDemoTrading" => false}
          },
          %{
            "isSandboxModeEnabled" => false,
            "urls" => %{
              "api" => %{
                "public" => "https://api.binance.com/api/v3",
                "private" => "https://api.binance.com/api/v3"
              },
              "demo" => %{
                "public" => "https://demo-api.binance.com/api/v3",
                "private" => "https://demo-api.binance.com/api/v3"
              }
            }
          }
        ),
        exchange
      )

    _ = exchange
    _ = fetcher
    _ = enable

    try do
      if Runtime.truthy(Runtime.safe_value(exchange, "isSandboxModeEnabled")) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " demo trading is not supported in the sandbox environment. Please check https://www.binance.com/en/support/faq/detail/9be58f73e5e14338809e3b705b9687dd to see the differences"
           ])}
        )
      end

      {exchange} =
        if Runtime.truthy(enable) do
          exchange =
            Runtime.put_value_in(
              exchange,
              ["urls", "apiBackupDemoTrading"],
              Runtime.safe_value(Runtime.safe_value(exchange, "urls"), "api")
            )

          exchange =
            Runtime.put_value_in(
              exchange,
              ["urls", "api"],
              Runtime.safe_value(Runtime.safe_value(exchange, "urls"), "demo")
            )

          {exchange}
        else
          {exchange} =
            if Runtime.truthy(
                 Runtime.has_key?(Runtime.safe_value(exchange, "urls"), "apiBackupDemoTrading")
               ) do
              exchange =
                Runtime.put_value_in(
                  exchange,
                  ["urls", "api"],
                  Runtime.safe_value(Runtime.safe_value(exchange, "urls"), "apiBackupDemoTrading")
                )

              new_urls =
                Runtime.omit(Runtime.safe_value(exchange, "urls"), "apiBackupDemoTrading")

              exchange = Runtime.put_value(exchange, "urls", new_urls)

              {exchange}
            else
              {exchange}
            end

          _ = exchange

          {exchange}
        end

      _ = exchange

      exchange = Runtime.put_value_in(exchange, ["options", "enableDemoTrading"], enable)
      {:ok, exchange}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_time(params(), (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})) ::
          {:ok, integer() | nil} | {:error, term()}
  def fetch_time(params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{}}, %{})
    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = params

    try do
      default_type =
        Runtime.safe_string2(
          Runtime.safe_value(exchange, "options"),
          "fetchTime",
          "defaultType",
          "spot"
        )

      type = Runtime.safe_string(params, "type", default_type)
      query = Runtime.omit(params, "type")
      sub_type = nil
      _ = sub_type
      ccxt_match = Runtime.handle_sub_type_and_params(exchange, "fetchTime", nil, params)
      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
          response = Runtime.call_raw!(Raw, fetcher, "fapipublic_get_time", [query])
          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
              response = Runtime.call_raw!(Raw, fetcher, "dapipublic_get_time", [query])
              _ = response

              {response}
            else
              response = Runtime.call_raw!(Raw, fetcher, "public_get_time", [query])
              _ = response

              {response}
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, Runtime.safe_integer(response, "serverTime")}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_currencies(params(), (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_currencies(params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchCurrencies" => true,
            "fetchMargins" => false,
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = params

    try do
      fetch_currencies_enabled =
        Runtime.safe_bool(Runtime.safe_value(exchange, "options"), "fetchCurrencies")

      if Runtime.truthy(not Runtime.truthy(fetch_currencies_enabled)) do
        throw({:ccxt_return, %{}})
      end

      if Runtime.truthy(not Runtime.truthy(Runtime.check_required_credentials(exchange, false))) do
        throw({:ccxt_return, %{}})
      end

      api_backup = Runtime.safe_value(Runtime.safe_value(exchange, "urls"), "apiBackup")

      if Runtime.truthy(api_backup != nil) do
        throw({:ccxt_return, %{}})
      end

      if Runtime.truthy(
           Runtime.safe_bool(Runtime.safe_value(exchange, "options"), "enableDemoTrading", false)
         ) do
        throw({:ccxt_return, %{}})
      end

      promises = [Runtime.call_raw!(Raw, fetcher, "sapi_get_capital_config_getall", [params])]
      _ = promises

      fetch_margins =
        Runtime.safe_bool(Runtime.safe_value(exchange, "options"), "fetchMargins", false)

      {promises} =
        if Runtime.truthy(fetch_margins) do
          promises =
            Runtime.push(
              promises,
              Runtime.call_raw!(Raw, fetcher, "sapi_get_margin_allpairs", [params])
            )

          {promises}
        else
          {promises}
        end

      _ = promises

      results = Runtime.promise_all(promises)
      response_currencies = Runtime.safe_value(results, 0)
      marginables_by_id = nil
      _ = marginables_by_id

      {marginables_by_id} =
        if Runtime.truthy(fetch_margins) do
          response_marginables = Runtime.safe_value(results, 1)
          marginables_by_id = Runtime.index_by(response_marginables, "assetName")
          _ = marginables_by_id

          {marginables_by_id}
        else
          {marginables_by_id}
        end

      _ = marginables_by_id

      {:ok,
       Runtime.call_generated!(exchange, __MODULE__, :parse_currencies_custom, [
         response_currencies,
         marginables_by_id
       ])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_currencies_custom(term(), term(), term()) :: term()
  def parse_currencies_custom(exchange, response_currencies, marginables_by_id) do
    _ = exchange
    _ = response_currencies
    _ = marginables_by_id

    try do
      result = %{}
      _ = result

      {result} =
        Enum.reduce_while(
          Runtime.index_range(Runtime.js_length(response_currencies), 0),
          {result},
          fn i, {result} ->
            try do
              parsed =
                Runtime.call_generated!(exchange, __MODULE__, :parse_currency, [
                  Runtime.safe_value(response_currencies, i)
                ])

              _ = parsed
              code = Runtime.safe_value(parsed, "code")

              margin_entry =
                Runtime.safe_dict(marginables_by_id, Runtime.safe_value(parsed, "id"))

              parsed =
                Runtime.put_value(
                  parsed,
                  "margin",
                  Runtime.safe_bool(margin_entry, "isBorrowable")
                )

              result = Runtime.put_value(result, code, parsed)
              {:cont, {result}}
            catch
              :continue -> {:cont, {result}}
              :break -> {:halt, {result}}
            end
          end
        )

      _ = result
      throw({:ccxt_return, result})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec parse_currency(term(), term()) :: term()
  def parse_currency(exchange, raw_currency) do
    _ = exchange
    _ = raw_currency

    try do
      entry = raw_currency
      id = Runtime.safe_string(entry, "coin")
      name = Runtime.safe_string(entry, "name")
      code = Runtime.safe_currency_code(id)
      is_fiat = Runtime.safe_bool(entry, "isLegalMoney")
      network_list = Runtime.safe_list(entry, "networkList", [])
      fees = %{}
      _ = fees
      fee = nil
      _ = fee
      networks = %{}
      _ = networks
      is_etf = false
      _ = is_etf

      {fee, fees, is_etf, networks} =
        Enum.reduce_while(
          Runtime.index_range(Runtime.js_length(network_list), 0),
          {fee, fees, is_etf, networks},
          fn j, {fee, fees, is_etf, networks} ->
            try do
              network_item = Runtime.safe_value(network_list, j)
              network = Runtime.safe_string(network_item, "network")
              network_code = Runtime.network_id_to_code(network, code)
              is_etf = network == "ETF"
              _ = is_etf
              withdraw_fee = Runtime.safe_number(network_item, "withdrawFee")
              deposit_enable = Runtime.safe_bool(network_item, "depositEnable")
              withdraw_enable = Runtime.safe_bool(network_item, "withdrawEnable")
              fees = Runtime.put_value(fees, network, withdraw_fee)
              is_default = Runtime.safe_bool(network_item, "isDefault")

              {fee} =
                if Runtime.truthy(Runtime.truthy(is_default) or Runtime.truthy(fee == nil)) do
                  fee = withdraw_fee
                  _ = fee

                  {fee}
                else
                  {fee}
                end

              _ = fee

              withdraw_precision =
                Runtime.omit_zero(
                  Runtime.safe_string2(
                    network_item,
                    "withdrawIntegerMultiple",
                    "withdrawInternalMin"
                  )
                )

              _ = withdraw_precision

              {withdraw_precision} =
                if Runtime.truthy(
                     Runtime.truthy(withdraw_precision == nil) and Runtime.truthy(is_fiat)
                   ) do
                  withdraw_precision =
                    Runtime.safe_string(
                      Runtime.safe_value(exchange, "options"),
                      "defaultFiatWithdrawPrecision"
                    )

                  _ = withdraw_precision

                  {withdraw_precision}
                else
                  {withdraw_precision}
                end

              _ = withdraw_precision

              networks =
                Runtime.put_value(networks, network_code, %{
                  "info" => network_item,
                  "id" => network,
                  "network" => network_code,
                  "active" => nil,
                  "deposit" => deposit_enable,
                  "withdraw" => withdraw_enable,
                  "fee" => withdraw_fee,
                  "precision" => Runtime.parse_number(withdraw_precision),
                  "limits" => %{
                    "withdraw" => %{
                      "min" => Runtime.safe_number(network_item, "withdrawMin"),
                      "max" => Runtime.safe_number(network_item, "withdrawMax")
                    },
                    "deposit" => %{
                      "min" => Runtime.safe_number(network_item, "depositDust"),
                      "max" => nil
                    }
                  }
                })

              {:cont, {fee, fees, is_etf, networks}}
            catch
              :continue -> {:cont, {fee, fees, is_etf, networks}}
              :break -> {:halt, {fee, fees, is_etf, networks}}
            end
          end
        )

      _ = fee
      _ = fees
      _ = is_etf
      _ = networks
      type = nil
      _ = type

      {type} =
        if Runtime.truthy(is_etf) do
          type = "other"
          _ = type

          {type}
        else
          {type} =
            if Runtime.truthy(is_fiat) do
              type = "fiat"
              _ = type

              {type}
            else
              type = "crypto"
              _ = type

              {type}
            end

          _ = type

          {type}
        end

      _ = type

      trading = Runtime.safe_bool(entry, "trading")

      throw(
        {:ccxt_return,
         Runtime.safe_currency_structure(%{
           "id" => id,
           "name" => name,
           "code" => code,
           "type" => type,
           "precision" => nil,
           "info" => entry,
           "active" => trading,
           "deposit" => nil,
           "withdraw" => nil,
           "networks" => networks,
           "fee" => nil,
           "fees" => fees,
           "limits" => nil
         })}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_markets(params(), (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})) ::
          {:ok, list()} | {:error, term()}
  def fetch_markets(params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse"]},
            "fetchMargins" => false,
            "loadAllOptions" => false,
            "sandboxMode" => false,
            "enableDemoTrading" => false,
            "adjustForTimeDifference" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = params

    try do
      promises_raw = []
      _ = promises_raw
      raw_fetch_markets = nil
      _ = raw_fetch_markets
      default_types = ["spot", "linear", "inverse"]

      fetch_markets_options =
        Runtime.safe_dict(Runtime.safe_value(exchange, "options"), "fetchMarkets")

      {raw_fetch_markets} =
        if Runtime.truthy(fetch_markets_options != nil) do
          raw_fetch_markets = Runtime.safe_list(fetch_markets_options, "types", default_types)
          _ = raw_fetch_markets

          {raw_fetch_markets}
        else
          raw_fetch_markets =
            Runtime.safe_list(
              Runtime.safe_value(exchange, "options"),
              "fetchMarkets",
              default_types
            )

          _ = raw_fetch_markets

          {raw_fetch_markets}
        end

      _ = raw_fetch_markets

      load_all_options =
        Runtime.safe_bool(Runtime.safe_value(exchange, "options"), "loadAllOptions", false)

      {raw_fetch_markets} =
        if Runtime.truthy(load_all_options) do
          {raw_fetch_markets} =
            if Runtime.truthy(not Runtime.truthy(Runtime.in_array("option", raw_fetch_markets))) do
              raw_fetch_markets = Runtime.push(raw_fetch_markets, "option")

              {raw_fetch_markets}
            else
              {raw_fetch_markets}
            end

          _ = raw_fetch_markets

          {raw_fetch_markets}
        else
          {raw_fetch_markets}
        end

      _ = raw_fetch_markets

      sandbox_mode =
        Runtime.safe_bool(Runtime.safe_value(exchange, "options"), "sandboxMode", false)

      demo_mode =
        Runtime.safe_bool(Runtime.safe_value(exchange, "options"), "enableDemoTrading", false)

      is_demo_env = Runtime.truthy(demo_mode) or Runtime.truthy(sandbox_mode)
      fetch_markets = []
      _ = fetch_markets

      {fetch_markets} =
        Enum.reduce_while(
          Runtime.index_range(Runtime.js_length(raw_fetch_markets), 0),
          {fetch_markets},
          fn i, {fetch_markets} ->
            try do
              type = Runtime.safe_value(raw_fetch_markets, i)

              if Runtime.truthy(Runtime.truthy(type == "option") and Runtime.truthy(is_demo_env)) do
                throw(:continue)
              end

              fetch_markets = Runtime.push(fetch_markets, type)
              {:cont, {fetch_markets}}
            catch
              :continue -> {:cont, {fetch_markets}}
              :break -> {:halt, {fetch_markets}}
            end
          end
        )

      _ = fetch_markets

      fetch_margins =
        Runtime.safe_bool(Runtime.safe_value(exchange, "options"), "fetchMargins", false)

      {promises_raw} =
        Enum.reduce_while(
          Runtime.index_range(Runtime.js_length(fetch_markets), 0),
          {promises_raw},
          fn i, {promises_raw} ->
            try do
              market_type = Runtime.safe_value(fetch_markets, i)

              {promises_raw} =
                if Runtime.truthy(market_type == "spot") do
                  promises_raw =
                    Runtime.push(
                      promises_raw,
                      Runtime.call_raw!(Raw, fetcher, "public_get_exchangeinfo", [params])
                    )

                  {promises_raw} =
                    if Runtime.truthy(
                         Runtime.truthy(
                           Runtime.truthy(fetch_margins) and
                             Runtime.truthy(Runtime.check_required_credentials(exchange, false))
                         ) and Runtime.truthy(not Runtime.truthy(is_demo_env))
                       ) do
                      promises_raw =
                        Runtime.push(
                          promises_raw,
                          Runtime.call_raw!(Raw, fetcher, "sapi_get_margin_allpairs", [params])
                        )

                      promises_raw =
                        Runtime.push(
                          promises_raw,
                          Runtime.call_raw!(Raw, fetcher, "sapi_get_margin_isolated_allpairs", [
                            params
                          ])
                        )

                      {promises_raw}
                    else
                      {promises_raw}
                    end

                  _ = promises_raw

                  {promises_raw}
                else
                  {promises_raw} =
                    if Runtime.truthy(market_type == "linear") do
                      promises_raw =
                        Runtime.push(
                          promises_raw,
                          Runtime.call_raw!(Raw, fetcher, "fapipublic_get_exchangeinfo", [params])
                        )

                      {promises_raw}
                    else
                      {promises_raw} =
                        if Runtime.truthy(market_type == "inverse") do
                          promises_raw =
                            Runtime.push(
                              promises_raw,
                              Runtime.call_raw!(Raw, fetcher, "dapipublic_get_exchangeinfo", [
                                params
                              ])
                            )

                          {promises_raw}
                        else
                          {promises_raw} =
                            if Runtime.truthy(market_type == "option") do
                              promises_raw =
                                Runtime.push(
                                  promises_raw,
                                  Runtime.call_raw!(Raw, fetcher, "eapipublic_get_exchangeinfo", [
                                    params
                                  ])
                                )

                              {promises_raw}
                            else
                              throw(
                                {:ccxt_error,
                                 Runtime.new_error_reason(":exchange_error", [
                                   Runtime.safe_value(exchange, "id") <>
                                     " fetchMarkets() this.options fetchMarkets \"" <>
                                     market_type <> "\" is not a supported market type"
                                 ])}
                              )
                            end

                          _ = promises_raw

                          {promises_raw}
                        end

                      _ = promises_raw

                      {promises_raw}
                    end

                  _ = promises_raw

                  {promises_raw}
                end

              _ = promises_raw
              {:cont, {promises_raw}}
            catch
              :continue -> {:cont, {promises_raw}}
              :break -> {:halt, {promises_raw}}
            end
          end
        )

      _ = promises_raw
      results = Runtime.promise_all(promises_raw)
      markets = []
      _ = markets
      exchange = Runtime.put_value_in(exchange, ["options", "crossMarginPairsData"], [])
      exchange = Runtime.put_value_in(exchange, ["options", "isolatedMarginPairsData"], [])

      {exchange, markets} =
        Enum.reduce_while(
          Runtime.index_range(Runtime.js_length(results), 0),
          {exchange, markets},
          fn i, {exchange, markets} ->
            try do
              res = Runtime.safe_value(results, i)

              {exchange, markets} =
                if Runtime.truthy(
                     Runtime.truthy(fetch_margins) and Runtime.truthy(Runtime.is_array(res))
                   ) do
                  keys_list = Runtime.object_keys(Runtime.index_by(res, "symbol"))

                  length =
                    Runtime.js_length(
                      Runtime.safe_value(
                        Runtime.safe_value(exchange, "options"),
                        "crossMarginPairsData"
                      )
                    )

                  {exchange} =
                    if Runtime.truthy(length == 0) do
                      exchange =
                        Runtime.put_value_in(
                          exchange,
                          ["options", "crossMarginPairsData"],
                          keys_list
                        )

                      {exchange}
                    else
                      exchange =
                        Runtime.put_value_in(
                          exchange,
                          ["options", "isolatedMarginPairsData"],
                          keys_list
                        )

                      {exchange}
                    end

                  _ = exchange

                  {exchange, markets}
                else
                  result_markets = Runtime.safe_list2(res, "symbols", "optionSymbols", [])
                  markets = Runtime.array_concat(markets, result_markets)
                  _ = markets

                  {exchange, markets}
                end

              _ = exchange
              _ = markets
              {:cont, {exchange, markets}}
            catch
              :continue -> {:cont, {exchange, markets}}
              :break -> {:halt, {exchange, markets}}
            end
          end
        )

      _ = exchange
      _ = markets

      if Runtime.truthy(
           Runtime.safe_value(Runtime.safe_value(exchange, "options"), "adjustForTimeDifference")
         ) do
        Runtime.load_time_difference()
      end

      result = []
      _ = result

      {result} =
        Enum.reduce_while(Runtime.index_range(Runtime.js_length(markets), 0), {result}, fn i,
                                                                                           {result} ->
          try do
            result =
              Runtime.push(
                result,
                Runtime.call_generated!(exchange, __MODULE__, :parse_market, [
                  Runtime.safe_value(markets, i)
                ])
              )

            {:cont, {result}}
          catch
            :continue -> {:cont, {result}}
            :break -> {:halt, {result}}
          end
        end)

      _ = result
      {:ok, result}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_market(term(), term()) :: term()
  def parse_market(exchange, market) do
    _ = exchange
    _ = market

    try do
      swap = false
      _ = swap
      future = false
      _ = future
      option = false
      _ = option
      underlying = Runtime.safe_string(market, "underlying")
      id = Runtime.safe_string(market, "symbol")
      option_parts = Runtime.string_split(id, "-")
      option_base = Runtime.safe_string(option_parts, 0)
      lowercase_id = Runtime.safe_string_lower(market, "symbol")
      base_id = Runtime.safe_string(market, "baseAsset", option_base)
      quote_id = Runtime.safe_string(market, "quoteAsset")
      base = Runtime.safe_currency_code(base_id)
      quote = Runtime.safe_currency_code(quote_id)
      contract_type = Runtime.safe_string(market, "contractType")
      contract = Runtime.has_key?(market, "contractType")
      _ = contract
      expiry = Runtime.safe_integer2(market, "deliveryDate", "expiryDate")
      _ = expiry
      settle_id = Runtime.safe_string(market, "marginAsset")
      _ = settle_id

      {contract, expiry, future, option, settle_id, swap} =
        if Runtime.truthy(
             Runtime.truthy(contract_type == "PERPETUAL") or
               Runtime.truthy(expiry == 4_133_404_800_000)
           ) do
          expiry = nil
          _ = expiry
          swap = true
          _ = swap

          {contract, expiry, future, option, settle_id, swap}
        else
          {contract, future, option, settle_id} =
            if Runtime.truthy(underlying != nil) do
              contract = true
              _ = contract
              option = true
              _ = option

              settle_id =
                if(
                  Runtime.truthy(settle_id == nil),
                  do: "USDT",
                  else: settle_id
                )

              _ = settle_id

              {contract, future, option, settle_id}
            else
              {future} =
                if Runtime.truthy(expiry != nil) do
                  future = true
                  _ = future

                  {future}
                else
                  {future}
                end

              _ = future

              {contract, future, option, settle_id}
            end

          _ = contract
          _ = future
          _ = option
          _ = settle_id

          {contract, expiry, future, option, settle_id, swap}
        end

      _ = contract
      _ = expiry
      _ = future
      _ = option
      _ = settle_id
      _ = swap

      settle = Runtime.safe_currency_code(settle_id)
      spot = not Runtime.truthy(contract)
      filters = Runtime.safe_list(market, "filters", [])
      filters_by_type = Runtime.index_by(filters, "filterType")
      status = Runtime.safe_string2(market, "status", "contractStatus")
      contract_size = nil
      _ = contract_size
      fees = Runtime.fees(exchange)
      _ = fees
      linear = nil
      _ = linear
      inverse = nil
      _ = inverse
      symbol = base <> "/" <> quote
      _ = symbol
      strike = nil
      _ = strike

      {contract_size, fees, inverse, linear, strike, symbol} =
        if Runtime.truthy(contract) do
          {strike, symbol} =
            if Runtime.truthy(swap) do
              symbol = symbol <> ":" <> settle
              _ = symbol

              {strike, symbol}
            else
              {strike, symbol} =
                if Runtime.truthy(future) do
                  symbol = symbol <> ":" <> settle <> "-" <> Runtime.yymmdd(expiry)
                  _ = symbol

                  {strike, symbol}
                else
                  {strike, symbol} =
                    if Runtime.truthy(option) do
                      strike =
                        Runtime.number_to_string(
                          Runtime.parse_to_numeric(Runtime.safe_string(market, "strikePrice"))
                        )

                      _ = strike

                      symbol =
                        symbol <>
                          ":" <>
                          settle <>
                          "-" <>
                          Runtime.yymmdd(expiry) <>
                          "-" <> strike <> "-" <> Runtime.safe_string(option_parts, 3)

                      _ = symbol

                      {strike, symbol}
                    else
                      {strike, symbol}
                    end

                  _ = strike
                  _ = symbol

                  {strike, symbol}
                end

              _ = strike
              _ = symbol

              {strike, symbol}
            end

          _ = strike
          _ = symbol

          contract_size =
            Runtime.safe_number2(market, "contractSize", "unit", Runtime.parse_number("1"))

          _ = contract_size
          linear = settle == quote
          _ = linear
          inverse = settle == base
          _ = inverse

          fees_type =
            if(
              Runtime.truthy(linear),
              do: "linear",
              else: "inverse"
            )

          fees = Runtime.safe_dict(Runtime.fees(exchange), fees_type, %{})
          _ = fees

          {contract_size, fees, inverse, linear, strike, symbol}
        else
          {contract_size, fees, inverse, linear, strike, symbol}
        end

      _ = contract_size
      _ = fees
      _ = inverse
      _ = linear
      _ = strike
      _ = symbol

      active = status == "TRADING"
      _ = active

      {active} =
        if Runtime.truthy(spot) do
          permissions = Runtime.safe_list(market, "permissions", [])

          {active} =
            Enum.reduce_while(
              Runtime.index_range(Runtime.js_length(permissions), 0),
              {active},
              fn j, {active} ->
                try do
                  {active} =
                    if Runtime.truthy(Runtime.safe_value(permissions, j) == "TRD_GRP_003") do
                      active = false
                      _ = active
                      throw(:break)

                      {active}
                    else
                      {active}
                    end

                  _ = active
                  {:cont, {active}}
                catch
                  :continue -> {:cont, {active}}
                  :break -> {:halt, {active}}
                end
              end
            )

          _ = active

          {active}
        else
          {active}
        end

      _ = active

      is_margin_trading_allowed = Runtime.safe_bool(market, "isMarginTradingAllowed", false)
      margin_modes = nil
      _ = margin_modes

      {margin_modes} =
        if Runtime.truthy(spot) do
          has_cross_margin =
            Runtime.in_array(
              id,
              Runtime.safe_value(Runtime.safe_value(exchange, "options"), "crossMarginPairsData")
            )

          has_isolated_margin =
            Runtime.in_array(
              id,
              Runtime.safe_value(
                Runtime.safe_value(exchange, "options"),
                "isolatedMarginPairsData"
              )
            )

          margin_modes = %{cross: has_cross_margin, isolated: has_isolated_margin}
          _ = margin_modes

          {margin_modes}
        else
          {margin_modes} =
            if Runtime.truthy(Runtime.truthy(linear) or Runtime.truthy(inverse)) do
              margin_modes = %{cross: true, isolated: true}
              _ = margin_modes

              {margin_modes}
            else
              {margin_modes}
            end

          _ = margin_modes

          {margin_modes}
        end

      _ = margin_modes

      unified_type = nil
      _ = unified_type

      {active, unified_type} =
        if Runtime.truthy(spot) do
          unified_type = "spot"
          _ = unified_type

          {active, unified_type}
        else
          {active, unified_type} =
            if Runtime.truthy(swap) do
              unified_type = "swap"
              _ = unified_type

              {active, unified_type}
            else
              {active, unified_type} =
                if Runtime.truthy(future) do
                  unified_type = "future"
                  _ = unified_type

                  {active, unified_type}
                else
                  {active, unified_type} =
                    if Runtime.truthy(option) do
                      unified_type = "option"
                      _ = unified_type
                      active = nil
                      _ = active

                      {active, unified_type}
                    else
                      {active, unified_type}
                    end

                  _ = active
                  _ = unified_type

                  {active, unified_type}
                end

              _ = active
              _ = unified_type

              {active, unified_type}
            end

          _ = active
          _ = unified_type

          {active, unified_type}
        end

      _ = active
      _ = unified_type

      parsed_strike = nil
      _ = parsed_strike

      {parsed_strike} =
        if Runtime.truthy(strike != nil) do
          parsed_strike = Runtime.parse_to_numeric(strike)
          _ = parsed_strike

          {parsed_strike}
        else
          {parsed_strike}
        end

      _ = parsed_strike

      entry = %{
        id: id,
        lowercaseId: lowercase_id,
        symbol: symbol,
        base: base,
        quote: quote,
        settle: settle,
        baseId: base_id,
        quoteId: quote_id,
        settleId: settle_id,
        type: unified_type,
        spot: spot,
        margin: Runtime.truthy(spot) and Runtime.truthy(is_margin_trading_allowed),
        marginModes: margin_modes,
        swap: swap,
        future: future,
        option: option,
        active: active,
        contract: contract,
        linear: linear,
        inverse: inverse,
        taker: Runtime.safe_value(Runtime.safe_value(fees, "trading"), "taker"),
        maker: Runtime.safe_value(Runtime.safe_value(fees, "trading"), "maker"),
        contractSize: contract_size,
        expiry: expiry,
        expiryDatetime: Runtime.iso8601(expiry),
        strike: parsed_strike,
        optionType: Runtime.safe_string_lower(market, "side"),
        precision: %{
          amount:
            Runtime.parse_number(
              Runtime.parse_precision(
                Runtime.safe_string2(market, "quantityPrecision", "quantityScale")
              )
            ),
          price:
            Runtime.parse_number(
              Runtime.parse_precision(
                Runtime.safe_string2(market, "pricePrecision", "priceScale")
              )
            ),
          base:
            Runtime.parse_number(
              Runtime.parse_precision(Runtime.safe_string(market, "baseAssetPrecision"))
            ),
          quote:
            Runtime.parse_number(
              Runtime.parse_precision(Runtime.safe_string(market, "quotePrecision"))
            )
        },
        limits: %{
          leverage: %{min: nil, max: nil},
          amount: %{
            min: Runtime.safe_number(market, "minQty"),
            max: Runtime.safe_number(market, "maxQty")
          },
          price: %{min: nil, max: nil},
          cost: %{min: nil, max: nil}
        },
        info: market,
        created: Runtime.safe_integer(market, "onboardDate")
      }

      _ = entry

      {entry} =
        if Runtime.truthy(Runtime.has_key?(filters_by_type, "PRICE_FILTER")) do
          filter = Runtime.safe_dict(filters_by_type, "PRICE_FILTER", %{})

          entry =
            Runtime.put_value(
              entry,
              :limits,
              Runtime.put_value(Runtime.safe_value(entry, :limits, %{}), :price, %{
                min: Runtime.safe_number(filter, "minPrice"),
                max: Runtime.safe_number(filter, "maxPrice")
              })
            )

          entry =
            Runtime.put_value(
              entry,
              :precision,
              Runtime.put_value(
                Runtime.safe_value(entry, :precision, %{}),
                :price,
                Runtime.safe_number(filter, "tickSize")
              )
            )

          {entry}
        else
          {entry}
        end

      _ = entry

      {entry} =
        if Runtime.truthy(Runtime.has_key?(filters_by_type, "LOT_SIZE")) do
          filter = Runtime.safe_dict(filters_by_type, "LOT_SIZE", %{})

          entry =
            Runtime.put_value(
              entry,
              :precision,
              Runtime.put_value(
                Runtime.safe_value(entry, :precision, %{}),
                :amount,
                Runtime.safe_number(filter, "stepSize")
              )
            )

          entry =
            Runtime.put_value(
              entry,
              :limits,
              Runtime.put_value(Runtime.safe_value(entry, :limits, %{}), :amount, %{
                min: Runtime.safe_number(filter, "minQty"),
                max: Runtime.safe_number(filter, "maxQty")
              })
            )

          {entry}
        else
          {entry}
        end

      _ = entry

      {entry} =
        if Runtime.truthy(Runtime.has_key?(filters_by_type, "MARKET_LOT_SIZE")) do
          filter = Runtime.safe_dict(filters_by_type, "MARKET_LOT_SIZE", %{})

          entry =
            Runtime.put_value(
              entry,
              :limits,
              Runtime.put_value(Runtime.safe_value(entry, :limits, %{}), :market, %{
                min: Runtime.safe_number(filter, "minQty"),
                max: Runtime.safe_number(filter, "maxQty")
              })
            )

          {entry}
        else
          {entry}
        end

      _ = entry

      {entry} =
        if Runtime.truthy(
             Runtime.truthy(Runtime.has_key?(filters_by_type, "MIN_NOTIONAL")) or
               Runtime.truthy(Runtime.has_key?(filters_by_type, "NOTIONAL"))
           ) do
          filter = Runtime.safe_dict2(filters_by_type, "MIN_NOTIONAL", "NOTIONAL", %{})

          entry =
            Runtime.put_value_in(
              entry,
              [:limits, :cost, :min],
              Runtime.safe_number2(filter, "minNotional", "notional")
            )

          entry =
            Runtime.put_value_in(
              entry,
              [:limits, :cost, :max],
              Runtime.safe_number(filter, "maxNotional")
            )

          {entry}
        else
          {entry}
        end

      _ = entry

      throw({:ccxt_return, entry})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec parse_balance_helper(term(), term()) :: term()
  def parse_balance_helper(exchange, entry) do
    _ = exchange
    _ = entry

    try do
      account = Runtime.account()
      _ = account
      account = Runtime.put_value(account, "used", Runtime.safe_string(entry, "locked"))
      account = Runtime.put_value(account, "free", Runtime.safe_string(entry, "free"))
      interest = Runtime.safe_string(entry, "interest")
      debt = Runtime.safe_string(entry, "borrowed")
      account = Runtime.put_value(account, "debt", Runtime.add_number_strings(debt, interest))
      throw({:ccxt_return, account})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec parse_balance_custom(term(), term(), term(), term(), term()) :: term()
  def parse_balance_custom(
        exchange,
        response,
        type \\ nil,
        margin_mode \\ nil,
        is_portfolio_margin \\ false
      ) do
    _ = exchange
    _ = response
    _ = type
    _ = margin_mode
    _ = is_portfolio_margin

    try do
      result = %{info: response}
      _ = result
      timestamp = nil
      _ = timestamp
      isolated = margin_mode == "isolated"
      cross = Runtime.truthy(type == "margin") or Runtime.truthy(margin_mode == "cross")

      {result, timestamp} =
        if Runtime.truthy(is_portfolio_margin) do
          {result} =
            Enum.reduce_while(Runtime.index_range(Runtime.js_length(response), 0), {result}, fn i,
                                                                                                {result} ->
              try do
                entry = Runtime.safe_value(response, i)
                account = Runtime.account()
                _ = account
                currency_id = Runtime.safe_string(entry, "asset")
                code = Runtime.safe_currency_code(currency_id)

                {account} =
                  if Runtime.truthy(type == "linear") do
                    account =
                      Runtime.put_value(
                        account,
                        :free,
                        Runtime.safe_string(entry, "umWalletBalance")
                      )

                    account =
                      Runtime.put_value(
                        account,
                        :used,
                        Runtime.safe_string(entry, "umUnrealizedPNL")
                      )

                    {account}
                  else
                    {account} =
                      if Runtime.truthy(type == "inverse") do
                        account =
                          Runtime.put_value(
                            account,
                            :free,
                            Runtime.safe_string(entry, "cmWalletBalance")
                          )

                        account =
                          Runtime.put_value(
                            account,
                            :used,
                            Runtime.safe_string(entry, "cmUnrealizedPNL")
                          )

                        {account}
                      else
                        {account} =
                          if Runtime.truthy(cross) do
                            borrowed = Runtime.safe_string(entry, "crossMarginBorrowed")
                            interest = Runtime.safe_string(entry, "crossMarginInterest")

                            account =
                              Runtime.put_value(
                                account,
                                :debt,
                                Runtime.add_number_strings(borrowed, interest)
                              )

                            account =
                              Runtime.put_value(
                                account,
                                :free,
                                Runtime.safe_string(entry, "crossMarginFree")
                              )

                            account =
                              Runtime.put_value(
                                account,
                                :used,
                                Runtime.safe_string(entry, "crossMarginLocked")
                              )

                            account =
                              Runtime.put_value(
                                account,
                                :total,
                                Runtime.safe_string(entry, "crossMarginAsset")
                              )

                            {account}
                          else
                            used_linear = Runtime.safe_string(entry, "umUnrealizedPNL")
                            used_inverse = Runtime.safe_string(entry, "cmUnrealizedPNL")
                            total_used = Runtime.add_number_strings(used_linear, used_inverse)

                            total_wallet_balance =
                              Runtime.safe_string(entry, "totalWalletBalance")

                            account =
                              Runtime.put_value(
                                account,
                                :total,
                                Runtime.add_number_strings(total_used, total_wallet_balance)
                              )

                            {account}
                          end

                        _ = account

                        {account}
                      end

                    _ = account

                    {account}
                  end

                _ = account

                result = Runtime.put_value(result, code, account)
                {:cont, {result}}
              catch
                :continue -> {:cont, {result}}
                :break -> {:halt, {result}}
              end
            end)

          _ = result

          {result, timestamp}
        else
          {result, timestamp} =
            if Runtime.truthy(
                 Runtime.truthy(not Runtime.truthy(isolated)) and
                   Runtime.truthy(Runtime.truthy(type == "spot") or Runtime.truthy(cross))
               ) do
              timestamp = Runtime.safe_integer(response, "updateTime")
              _ = timestamp
              balances = Runtime.safe_list2(response, "balances", "userAssets", [])

              {result} =
                Enum.reduce_while(
                  Runtime.index_range(Runtime.js_length(balances), 0),
                  {result},
                  fn i, {result} ->
                    try do
                      balance = Runtime.safe_value(balances, i)
                      currency_id = Runtime.safe_string(balance, "asset")
                      code = Runtime.safe_currency_code(currency_id)
                      account = Runtime.account()
                      _ = account

                      account =
                        Runtime.put_value(account, :free, Runtime.safe_string(balance, "free"))

                      account =
                        Runtime.put_value(account, :used, Runtime.safe_string(balance, "locked"))

                      {account} =
                        if Runtime.truthy(cross) do
                          debt = Runtime.safe_string(balance, "borrowed")
                          interest = Runtime.safe_string(balance, "interest")

                          account =
                            Runtime.put_value(
                              account,
                              :debt,
                              Runtime.add_number_strings(debt, interest)
                            )

                          {account}
                        else
                          {account}
                        end

                      _ = account

                      result = Runtime.put_value(result, code, account)
                      {:cont, {result}}
                    catch
                      :continue -> {:cont, {result}}
                      :break -> {:halt, {result}}
                    end
                  end
                )

              _ = result

              {result, timestamp}
            else
              {result} =
                if Runtime.truthy(isolated) do
                  assets = Runtime.safe_list(response, "assets")

                  {result} =
                    Enum.reduce_while(
                      Runtime.index_range(Runtime.js_length(assets), 0),
                      {result},
                      fn i, {result} ->
                        try do
                          asset = Runtime.safe_value(assets, i)
                          market_id = Runtime.safe_string(asset, "symbol")
                          symbol = Runtime.safe_symbol(exchange, market_id, nil, nil, "spot")
                          base = Runtime.safe_dict(asset, "baseAsset", %{})
                          quote = Runtime.safe_dict(asset, "quoteAsset", %{})

                          base_code =
                            Runtime.safe_currency_code(Runtime.safe_string(base, "asset"))

                          quote_code =
                            Runtime.safe_currency_code(Runtime.safe_string(quote, "asset"))

                          sub_result = %{}
                          _ = sub_result

                          sub_result =
                            Runtime.put_value(
                              sub_result,
                              base_code,
                              parse_balance_helper(exchange, base)
                            )

                          sub_result =
                            Runtime.put_value(
                              sub_result,
                              quote_code,
                              parse_balance_helper(exchange, quote)
                            )

                          result =
                            Runtime.put_value(result, symbol, Runtime.safe_balance(sub_result))

                          {:cont, {result}}
                        catch
                          :continue -> {:cont, {result}}
                          :break -> {:halt, {result}}
                        end
                      end
                    )

                  _ = result

                  {result}
                else
                  {result} =
                    if Runtime.truthy(type == "savings") do
                      position_amount_vos = Runtime.safe_list(response, "positionAmountVos", [])

                      {result} =
                        Enum.reduce_while(
                          Runtime.index_range(Runtime.js_length(position_amount_vos), 0),
                          {result},
                          fn i, {result} ->
                            try do
                              entry = Runtime.safe_value(position_amount_vos, i)
                              currency_id = Runtime.safe_string(entry, "asset")
                              code = Runtime.safe_currency_code(currency_id)
                              account = Runtime.account()
                              _ = account
                              used_and_total = Runtime.safe_string(entry, "amount")
                              account = Runtime.put_value(account, :total, used_and_total)
                              account = Runtime.put_value(account, :used, used_and_total)
                              result = Runtime.put_value(result, code, account)
                              {:cont, {result}}
                            catch
                              :continue -> {:cont, {result}}
                              :break -> {:halt, {result}}
                            end
                          end
                        )

                      _ = result

                      {result}
                    else
                      {result} =
                        if Runtime.truthy(type == "funding") do
                          {result} =
                            Enum.reduce_while(
                              Runtime.index_range(Runtime.js_length(response), 0),
                              {result},
                              fn i, {result} ->
                                try do
                                  entry = Runtime.safe_value(response, i)
                                  account = Runtime.account()
                                  _ = account
                                  currency_id = Runtime.safe_string(entry, "asset")
                                  code = Runtime.safe_currency_code(currency_id)

                                  account =
                                    Runtime.put_value(
                                      account,
                                      :free,
                                      Runtime.safe_string(entry, "free")
                                    )

                                  frozen = Runtime.safe_string(entry, "freeze")
                                  withdrawing = Runtime.safe_string(entry, "withdrawing")
                                  locked = Runtime.safe_string(entry, "locked")

                                  account =
                                    Runtime.put_value(
                                      account,
                                      :used,
                                      Runtime.add_number_strings(
                                        frozen,
                                        Runtime.add_number_strings(locked, withdrawing)
                                      )
                                    )

                                  result = Runtime.put_value(result, code, account)
                                  {:cont, {result}}
                                catch
                                  :continue -> {:cont, {result}}
                                  :break -> {:halt, {result}}
                                end
                              end
                            )

                          _ = result

                          {result}
                        else
                          balances = response
                          _ = balances

                          {balances} =
                            if Runtime.truthy(not Runtime.truthy(Runtime.is_array(response))) do
                              balances = Runtime.safe_list(response, "assets", [])
                              _ = balances

                              {balances}
                            else
                              {balances}
                            end

                          _ = balances

                          {result} =
                            Enum.reduce_while(
                              Runtime.index_range(Runtime.js_length(balances), 0),
                              {result},
                              fn i, {result} ->
                                try do
                                  balance = Runtime.safe_value(balances, i)
                                  currency_id = Runtime.safe_string(balance, "asset")
                                  code = Runtime.safe_currency_code(currency_id)
                                  account = Runtime.account()
                                  _ = account

                                  account =
                                    Runtime.put_value(
                                      account,
                                      :free,
                                      Runtime.safe_string(balance, "availableBalance")
                                    )

                                  account =
                                    Runtime.put_value(
                                      account,
                                      :used,
                                      Runtime.safe_string(balance, "initialMargin")
                                    )

                                  account =
                                    Runtime.put_value(
                                      account,
                                      :total,
                                      Runtime.safe_string2(balance, "marginBalance", "balance")
                                    )

                                  result = Runtime.put_value(result, code, account)
                                  {:cont, {result}}
                                catch
                                  :continue -> {:cont, {result}}
                                  :break -> {:halt, {result}}
                                end
                              end
                            )

                          _ = result

                          {result}
                        end

                      _ = result

                      {result}
                    end

                  _ = result

                  {result}
                end

              _ = result

              {result, timestamp}
            end

          _ = result
          _ = timestamp

          {result, timestamp}
        end

      _ = result
      _ = timestamp

      result = Runtime.put_value(result, :timestamp, timestamp)
      result = Runtime.put_value(result, :datetime, Runtime.iso8601(timestamp))

      throw(
        {:ccxt_return,
         if(
           Runtime.truthy(isolated),
           do: result,
           else: Runtime.safe_balance(result)
         )}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_balance(params(), (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_balance(params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchBalance" => %{"defaultType" => "spot"},
            "defaultType" => "spot",
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange

      default_type =
        Runtime.safe_string2(
          Runtime.safe_value(exchange, "options"),
          "fetchBalance",
          "defaultType",
          "spot"
        )

      type = Runtime.safe_string(params, "type", default_type)
      _ = type
      sub_type = nil
      _ = sub_type
      ccxt_match = Runtime.handle_sub_type_and_params(exchange, "fetchBalance", nil, params)
      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "fetchBalance",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      margin_mode = nil
      _ = margin_mode
      query = nil
      _ = query
      ccxt_match = Runtime.handle_margin_mode_and_params(exchange, "fetchBalance", params)
      margin_mode = Runtime.safe_value(ccxt_match, 0, nil)
      query = Runtime.safe_value(ccxt_match, 1, nil)
      _ = margin_mode
      _ = query
      query = Runtime.omit(query, "type")
      _ = query
      response = nil
      _ = response
      request = %{}
      _ = request

      {is_portfolio_margin, params, query, request, response, type} =
        if Runtime.truthy(Runtime.truthy(is_portfolio_margin) or Runtime.truthy(type == "papi")) do
          {type} =
            if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
              type = "linear"
              _ = type

              {type}
            else
              {type} =
                if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
                  type = "inverse"
                  _ = type

                  {type}
                else
                  {type}
                end

              _ = type

              {type}
            end

          _ = type

          is_portfolio_margin = true
          _ = is_portfolio_margin

          response =
            Runtime.call_raw!(Raw, fetcher, "papi_get_balance", [Runtime.extend(request, query)])

          _ = response

          {is_portfolio_margin, params, query, request, response, type}
        else
          {params, query, request, response, type} =
            if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
              type = "linear"
              _ = type
              use_v2 = nil
              _ = use_v2

              ccxt_match =
                Runtime.handle_option_and_params(exchange, params, "fetchBalance", "useV2", false)

              use_v2 = Runtime.safe_value(ccxt_match, 0, nil)
              params = Runtime.safe_value(ccxt_match, 1, nil)
              _ = use_v2
              _ = params
              params = Runtime.extend(request, query)
              _ = params

              {response} =
                if Runtime.truthy(not Runtime.truthy(use_v2)) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "fapiprivatev3_get_account", [params])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "fapiprivatev2_get_account", [params])

                  _ = response

                  {response}
                end

              _ = response

              {params, query, request, response, type}
            else
              {query, request, response, type} =
                if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
                  type = "inverse"
                  _ = type

                  response =
                    Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_account", [
                      Runtime.extend(request, query)
                    ])

                  _ = response

                  {query, request, response, type}
                else
                  {query, request, response} =
                    if Runtime.truthy(margin_mode == "isolated") do
                      param_symbols = Runtime.safe_list(params, "symbols")
                      query = Runtime.omit(query, "symbols")
                      _ = query

                      {request} =
                        if Runtime.truthy(param_symbols != nil) do
                          symbols = ""
                          _ = symbols

                          {symbols} =
                            if Runtime.truthy(Runtime.is_array(param_symbols)) do
                              symbols =
                                Runtime.market_id(exchange, Runtime.safe_value(param_symbols, 0))

                              _ = symbols

                              {symbols} =
                                Enum.reduce_while(
                                  Runtime.index_range(Runtime.js_length(param_symbols), 1),
                                  {symbols},
                                  fn i, {symbols} ->
                                    try do
                                      symbol = Runtime.safe_value(param_symbols, i)
                                      id = Runtime.market_id(exchange, symbol)
                                      symbols = symbols <> "," <> id
                                      _ = symbols
                                      {:cont, {symbols}}
                                    catch
                                      :continue -> {:cont, {symbols}}
                                      :break -> {:halt, {symbols}}
                                    end
                                  end
                                )

                              _ = symbols

                              {symbols}
                            else
                              symbols = param_symbols
                              _ = symbols

                              {symbols}
                            end

                          _ = symbols

                          request = Runtime.put_value(request, "symbols", symbols)

                          {request}
                        else
                          {request}
                        end

                      _ = request

                      response =
                        Runtime.call_raw!(Raw, fetcher, "sapi_get_margin_isolated_account", [
                          Runtime.extend(request, query)
                        ])

                      _ = response

                      {query, request, response}
                    else
                      {response} =
                        if Runtime.truthy(
                             Runtime.truthy(type == "margin") or
                               Runtime.truthy(margin_mode == "cross")
                           ) do
                          response =
                            Runtime.call_raw!(Raw, fetcher, "sapi_get_margin_account", [
                              Runtime.extend(request, query)
                            ])

                          _ = response

                          {response}
                        else
                          {response} =
                            if Runtime.truthy(type == "savings") do
                              response =
                                Runtime.call_raw!(
                                  Raw,
                                  fetcher,
                                  "sapi_get_lending_union_account",
                                  [Runtime.extend(request, query)]
                                )

                              _ = response

                              {response}
                            else
                              {response} =
                                if Runtime.truthy(type == "funding") do
                                  response =
                                    Runtime.call_raw!(
                                      Raw,
                                      fetcher,
                                      "sapi_post_asset_get_funding_asset",
                                      [Runtime.extend(request, query)]
                                    )

                                  _ = response

                                  {response}
                                else
                                  response =
                                    Runtime.call_raw!(Raw, fetcher, "private_get_account", [
                                      Runtime.extend(request, query)
                                    ])

                                  _ = response

                                  {response}
                                end

                              _ = response

                              {response}
                            end

                          _ = response

                          {response}
                        end

                      _ = response

                      {query, request, response}
                    end

                  _ = query
                  _ = request
                  _ = response

                  {query, request, response, type}
                end

              _ = query
              _ = request
              _ = response
              _ = type

              {params, query, request, response, type}
            end

          _ = params
          _ = query
          _ = request
          _ = response
          _ = type

          {is_portfolio_margin, params, query, request, response, type}
        end

      _ = is_portfolio_margin
      _ = params
      _ = query
      _ = request
      _ = response
      _ = type

      {:ok,
       Runtime.call_generated!(exchange, __MODULE__, :parse_balance_custom, [
         response,
         type,
         margin_mode,
         is_portfolio_margin
       ])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_order_book(String.t(), integer() | nil, params(), (RawEndpoint.t(), params() ->
                                                                   {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_order_book(symbol, limit \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      request = %{"symbol" => Runtime.safe_value(market, "id")}
      _ = request

      {request} =
        if Runtime.truthy(limit != nil) do
          request = Runtime.put_value(request, "limit", limit)

          {request}
        else
          {request}
        end

      _ = request

      response = nil
      _ = response

      {params, request, response} =
        if Runtime.truthy(Runtime.safe_value(market, "option")) do
          response =
            Runtime.call_raw!(Raw, fetcher, "eapipublic_get_depth", [
              Runtime.extend(request, params)
            ])

          _ = response

          {params, request, response}
        else
          {params, request, response} =
            if Runtime.truthy(Runtime.safe_value(market, "linear")) do
              rpi = Runtime.safe_value(params, "rpi", false)
              params = Runtime.omit(params, "rpi")
              _ = params

              {request, response} =
                if Runtime.truthy(rpi) do
                  request = Runtime.put_value(request, "limit", 1000)

                  response =
                    Runtime.call_raw!(Raw, fetcher, "fapipublic_get_rpidepth", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {request, response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "fapipublic_get_depth", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {request, response}
                end

              _ = request
              _ = response

              {params, request, response}
            else
              {response} =
                if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "dapipublic_get_depth", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "public_get_depth", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                end

              _ = response

              {params, request, response}
            end

          _ = params
          _ = request
          _ = response

          {params, request, response}
        end

      _ = params
      _ = request
      _ = response

      timestamp = Runtime.safe_integer(response, "T")
      orderbook = Runtime.parse_order_book(response, symbol, timestamp)
      _ = orderbook

      orderbook =
        Runtime.put_value(
          orderbook,
          "nonce",
          Runtime.safe_integer2(response, "lastUpdateId", "u")
        )

      {:ok, orderbook}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_ticker(term(), term(), term()) :: term()
  def parse_ticker(exchange, ticker, market \\ nil) do
    _ = exchange
    _ = ticker
    _ = market

    try do
      timestamp = Runtime.safe_integer2(ticker, "closeTime", "time")
      market_type = nil
      _ = market_type

      {market_type} =
        if Runtime.truthy(Runtime.has_key?(ticker, "time")) do
          market_type = "contract"
          _ = market_type

          {market_type}
        else
          {market_type}
        end

      _ = market_type

      {market_type} =
        if Runtime.truthy(market_type == nil) do
          market_type =
            if(
              Runtime.truthy(Runtime.has_key?(ticker, "bidQty")),
              do: "spot",
              else: "contract"
            )

          _ = market_type

          {market_type}
        else
          {market_type}
        end

      _ = market_type

      market_id = Runtime.safe_string(ticker, "symbol")
      symbol = Runtime.safe_symbol(exchange, market_id, market, nil, market_type)
      last = Runtime.safe_string(ticker, "lastPrice")
      w_avg = Runtime.safe_string(ticker, "weightedAvgPrice")
      is_coinm = Runtime.has_key?(ticker, "baseVolume")
      base_volume = nil
      _ = base_volume
      quote_volume = nil
      _ = quote_volume

      {base_volume, quote_volume} =
        if Runtime.truthy(is_coinm) do
          base_volume = Runtime.safe_string(ticker, "baseVolume")
          _ = base_volume
          quote_volume = Runtime.multiply_number_string(base_volume, w_avg)
          _ = quote_volume

          {base_volume, quote_volume}
        else
          base_volume = Runtime.safe_string(ticker, "volume")
          _ = base_volume
          quote_volume = Runtime.safe_string2(ticker, "quoteVolume", "amount")
          _ = quote_volume

          {base_volume, quote_volume}
        end

      _ = base_volume
      _ = quote_volume

      throw(
        {:ccxt_return,
         Runtime.safe_ticker(
           %{
             symbol: symbol,
             timestamp: timestamp,
             datetime: Runtime.iso8601(timestamp),
             high: Runtime.safe_string2(ticker, "highPrice", "high"),
             low: Runtime.safe_string2(ticker, "lowPrice", "low"),
             bid: Runtime.safe_string(ticker, "bidPrice"),
             bidVolume: Runtime.safe_string(ticker, "bidQty"),
             ask: Runtime.safe_string(ticker, "askPrice"),
             askVolume: Runtime.safe_string(ticker, "askQty"),
             vwap: w_avg,
             open: Runtime.safe_string2(ticker, "openPrice", "open"),
             close: last,
             last: last,
             previousClose: Runtime.safe_string(ticker, "prevClosePrice"),
             change: Runtime.safe_string(ticker, "priceChange"),
             percentage: Runtime.safe_string(ticker, "priceChangePercent"),
             average: nil,
             baseVolume: base_volume,
             quoteVolume: quote_volume,
             markPrice: Runtime.safe_string(ticker, "markPrice"),
             indexPrice: Runtime.safe_string(ticker, "indexPrice"),
             info: ticker
           },
           market
         )}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_status(params(), (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_status(params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{"sandboxMode" => false, "enableDemoTrading" => false}
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = params

    try do
      response = Runtime.call_raw!(Raw, fetcher, "sapi_get_system_status", [params])
      status_raw = Runtime.safe_string(response, "status")

      {:ok,
       %{
         status:
           Runtime.safe_string(%{"0" => "ok", "1" => "maintenance"}, status_raw, status_raw),
         updated: nil,
         eta: nil,
         url: nil,
         info: response
       }}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_ticker(String.t(), params(), (RawEndpoint.t(), params() ->
                                              {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_ticker(symbol, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse"]},
            "fetchMargins" => false,
            "loadAllOptions" => false,
            "sandboxMode" => false,
            "enableDemoTrading" => false,
            "adjustForTimeDifference" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      request = %{"symbol" => Runtime.safe_value(market, "id")}
      response = nil
      _ = response

      {params, response} =
        if Runtime.truthy(Runtime.safe_value(market, "option")) do
          response =
            Runtime.call_raw!(Raw, fetcher, "eapipublic_get_ticker", [
              Runtime.extend(request, params)
            ])

          _ = response

          {params, response}
        else
          {params, response} =
            if Runtime.truthy(Runtime.safe_value(market, "linear")) do
              response =
                Runtime.call_raw!(Raw, fetcher, "fapipublic_get_ticker_24hr", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {params, response}
            else
              {params, response} =
                if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "dapipublic_get_ticker_24hr", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {params, response}
                else
                  rolling = Runtime.safe_bool(params, "rolling", false)
                  params = Runtime.omit(params, "rolling")
                  _ = params

                  {response} =
                    if Runtime.truthy(rolling) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "public_get_ticker", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "public_get_ticker_24hr", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {params, response}
                end

              _ = params
              _ = response

              {params, response}
            end

          _ = params
          _ = response

          {params, response}
        end

      _ = params
      _ = response

      if Runtime.truthy(Runtime.is_array(response)) do
        first_ticker = Runtime.safe_dict(response, 0, %{})

        throw(
          {:ccxt_return,
           Runtime.call_generated!(exchange, __MODULE__, :parse_ticker, [first_ticker, market])}
        )
      end

      {:ok, Runtime.call_generated!(exchange, __MODULE__, :parse_ticker, [response, market])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_bids_asks(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                             {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_bids_asks(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      symbols = Runtime.market_symbols(exchange, symbols, nil, true, true, true)
      _ = symbols
      market = Runtime.get_market_from_symbols(exchange, symbols)
      type = nil
      _ = type

      ccxt_match =
        Runtime.handle_market_type_and_params(exchange, "fetchBidsAsks", market, params)

      type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = type
      _ = params
      sub_type = nil
      _ = sub_type
      ccxt_match = Runtime.handle_sub_type_and_params(exchange, "fetchBidsAsks", market, params)
      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
          response = Runtime.call_raw!(Raw, fetcher, "fapipublic_get_ticker_bookticker", [params])
          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
              response =
                Runtime.call_raw!(Raw, fetcher, "dapipublic_get_ticker_bookticker", [params])

              _ = response

              {response}
            else
              {response} =
                if Runtime.truthy(type == "spot") do
                  request = %{}
                  _ = request

                  {request} =
                    if Runtime.truthy(symbols != nil) do
                      request =
                        Runtime.put_value(
                          request,
                          "symbols",
                          Runtime.json(exchange, Runtime.market_ids(exchange, symbols))
                        )

                      {request}
                    else
                      {request}
                    end

                  _ = request

                  response =
                    Runtime.call_raw!(Raw, fetcher, "public_get_ticker_bookticker", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                else
                  throw(
                    {:ccxt_error,
                     Runtime.new_error_reason(":not_supported", [
                       Runtime.safe_value(exchange, "id") <>
                         " fetchBidsAsks() does not support " <> type <> " markets yet"
                     ])}
                  )
                end

              _ = response

              {response}
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, Runtime.parse_tickers(exchange, __MODULE__, response, symbols)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_last_prices(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                               {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_last_prices(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      symbols = Runtime.market_symbols(exchange, symbols, nil, true, true, true)
      _ = symbols
      market = Runtime.get_market_from_symbols(exchange, symbols)
      type = nil
      _ = type

      ccxt_match =
        Runtime.handle_market_type_and_params(exchange, "fetchLastPrices", market, params)

      type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = type
      _ = params
      sub_type = nil
      _ = sub_type
      ccxt_match = Runtime.handle_sub_type_and_params(exchange, "fetchLastPrices", market, params)
      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
          response = Runtime.call_raw!(Raw, fetcher, "fapipublicv2_get_ticker_price", [params])
          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
              response = Runtime.call_raw!(Raw, fetcher, "dapipublic_get_ticker_price", [params])
              _ = response

              {response}
            else
              {response} =
                if Runtime.truthy(type == "spot") do
                  response = Runtime.call_raw!(Raw, fetcher, "public_get_ticker_price", [params])
                  _ = response

                  {response}
                else
                  throw(
                    {:ccxt_error,
                     Runtime.new_error_reason(":not_supported", [
                       Runtime.safe_value(exchange, "id") <>
                         " fetchLastPrices() does not support " <> type <> " markets yet"
                     ])}
                  )
                end

              _ = response

              {response}
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, Runtime.parse_last_prices(exchange, response, symbols)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_last_price(params(), params(), (RawEndpoint.t(), params() ->
                                                {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def parse_last_price(entry, market \\ nil, fetcher \\ &default_fetcher/2) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{}}, %{})
    _ = exchange
    _ = fetcher
    _ = entry
    _ = market

    try do
      timestamp = Runtime.safe_integer(entry, "time")

      type =
        if(
          Runtime.truthy(timestamp == nil),
          do: "spot",
          else: "swap"
        )

      market_id = Runtime.safe_string(entry, "symbol")
      market = safe_market(exchange, market_id, market, nil, type)
      _ = market

      {:ok,
       %{
         symbol: Runtime.safe_value(market, "symbol"),
         timestamp: timestamp,
         datetime: Runtime.iso8601(timestamp),
         price: Runtime.safe_number_omit_zero(entry, "price"),
         side: nil,
         info: entry
       }}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_tickers(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                           {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_tickers(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchTickers" => %{"defaultType" => "spot"},
            "defaultType" => "spot",
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      symbols = Runtime.market_symbols(exchange, symbols, nil, true, true, true)
      _ = symbols
      market = Runtime.get_market_from_symbols(exchange, symbols)
      type = nil
      _ = type
      ccxt_match = Runtime.handle_market_type_and_params(exchange, "fetchTickers", market, params)
      type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = type
      _ = params
      sub_type = nil
      _ = sub_type
      ccxt_match = Runtime.handle_sub_type_and_params(exchange, "fetchTickers", market, params)
      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      response = nil
      _ = response

      {params, response, symbols} =
        if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
          response = Runtime.call_raw!(Raw, fetcher, "fapipublic_get_ticker_24hr", [params])
          _ = response

          {params, response, symbols}
        else
          {params, response, symbols} =
            if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
              response = Runtime.call_raw!(Raw, fetcher, "dapipublic_get_ticker_24hr", [params])
              _ = response

              {params, response, symbols}
            else
              {params, response, symbols} =
                if Runtime.truthy(type == "spot") do
                  rolling = Runtime.safe_bool(params, "rolling", false)
                  params = Runtime.omit(params, "rolling")
                  _ = params

                  {response, symbols} =
                    if Runtime.truthy(rolling) do
                      symbols = Runtime.market_symbols(exchange, symbols)
                      _ = symbols

                      request = %{
                        "symbols" => Runtime.json(exchange, Runtime.market_ids(exchange, symbols))
                      }

                      response =
                        Runtime.call_raw!(Raw, fetcher, "public_get_ticker", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      throw(
                        {:ccxt_return, parse_tickers_for_rolling(exchange, response, symbols)}
                      )
                    else
                      request = %{}
                      _ = request

                      {request} =
                        if Runtime.truthy(symbols != nil) do
                          request =
                            Runtime.put_value(
                              request,
                              "symbols",
                              Runtime.json(exchange, Runtime.market_ids(exchange, symbols))
                            )

                          {request}
                        else
                          {request}
                        end

                      _ = request

                      response =
                        Runtime.call_raw!(Raw, fetcher, "public_get_ticker_24hr", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response, symbols}
                    end

                  _ = response
                  _ = symbols

                  {params, response, symbols}
                else
                  {response} =
                    if Runtime.truthy(type == "option") do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "eapipublic_get_ticker", [params])

                      _ = response

                      {response}
                    else
                      throw(
                        {:ccxt_error,
                         Runtime.new_error_reason(":not_supported", [
                           Runtime.safe_value(exchange, "id") <>
                             " fetchTickers() does not support " <> type <> " markets yet"
                         ])}
                      )
                    end

                  _ = response

                  {params, response, symbols}
                end

              _ = params
              _ = response
              _ = symbols

              {params, response, symbols}
            end

          _ = params
          _ = response
          _ = symbols

          {params, response, symbols}
        end

      _ = params
      _ = response
      _ = symbols

      {:ok, Runtime.parse_tickers(exchange, __MODULE__, response, symbols)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_tickers_for_rolling(term(), term(), term()) :: term()
  def parse_tickers_for_rolling(exchange, response, symbols) do
    _ = exchange
    _ = response
    _ = symbols

    try do
      results = []
      _ = results

      {results} =
        Enum.reduce_while(Runtime.index_range(Runtime.js_length(response), 0), {results}, fn i,
                                                                                             {results} ->
          try do
            market_id = Runtime.safe_string(Runtime.safe_value(response, i), "symbol")
            ticker_market = safe_market(exchange, market_id, nil, nil, "spot")

            parsed_ticker =
              Runtime.call_generated!(exchange, __MODULE__, :parse_ticker, [
                Runtime.safe_value(response, i)
              ])

            _ = parsed_ticker

            parsed_ticker =
              Runtime.put_value(
                parsed_ticker,
                "symbol",
                Runtime.safe_value(ticker_market, "symbol")
              )

            results = Runtime.push(results, parsed_ticker)
            {:cont, {results}}
          catch
            :continue -> {:cont, {results}}
            :break -> {:halt, {results}}
          end
        end)

      _ = results
      throw({:ccxt_return, Runtime.filter_by_array(results, "symbol", symbols)})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_mark_price(String.t(), params(), (RawEndpoint.t(), params() ->
                                                  {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_mark_price(symbol, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "swap",
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      type = nil
      _ = type

      ccxt_match =
        Runtime.handle_market_type_and_params(exchange, "fetchMarkPrice", market, params, "swap")

      type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = type
      _ = params
      sub_type = nil
      _ = sub_type

      ccxt_match =
        Runtime.handle_sub_type_and_params(exchange, "fetchMarkPrice", market, params, "linear")

      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      request = %{"symbol" => Runtime.safe_value(market, "id")}
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
          response =
            Runtime.call_raw!(Raw, fetcher, "fapipublic_get_premiumindex", [
              Runtime.extend(request, params)
            ])

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
              response =
                Runtime.call_raw!(Raw, fetcher, "dapipublic_get_premiumindex", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":not_supported", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchMarkPrice() does not support " <> type <> " markets yet"
                 ])}
              )
            end

          _ = response

          {response}
        end

      _ = response

      if Runtime.truthy(Runtime.is_array(response)) do
        throw(
          {:ccxt_return,
           Runtime.call_generated!(exchange, __MODULE__, :parse_ticker, [
             Runtime.safe_dict(response, 0, %{}),
             market
           ])}
        )
      end

      {:ok, Runtime.call_generated!(exchange, __MODULE__, :parse_ticker, [response, market])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_mark_prices(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                               {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_mark_prices(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "swap",
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      symbols = Runtime.market_symbols(exchange, symbols, nil, true, true, true)
      _ = symbols
      market = Runtime.get_market_from_symbols(exchange, symbols)
      type = nil
      _ = type

      ccxt_match =
        Runtime.handle_market_type_and_params(exchange, "fetchMarkPrices", market, params, "swap")

      type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = type
      _ = params
      sub_type = nil
      _ = sub_type

      ccxt_match =
        Runtime.handle_sub_type_and_params(exchange, "fetchMarkPrices", market, params, "linear")

      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
          response = Runtime.call_raw!(Raw, fetcher, "fapipublic_get_premiumindex", [params])
          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
              response = Runtime.call_raw!(Raw, fetcher, "dapipublic_get_premiumindex", [params])
              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":not_supported", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchMarkPrices() does not support " <> type <> " markets yet"
                 ])}
              )
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, Runtime.parse_tickers(exchange, __MODULE__, response, symbols)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_ohlcv(params(), params(), (RawEndpoint.t(), params() ->
                                           {:ok, map()} | {:error, term()})) ::
          {:ok, list()} | {:error, term()}
  def parse_ohlcv(ohlcv, market \\ nil, fetcher \\ &default_fetcher/2) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{}}, %{})
    _ = exchange
    _ = fetcher
    _ = ohlcv
    _ = market

    try do
      inverse = Runtime.safe_bool(market, "inverse")

      volume_index =
        if(
          Runtime.truthy(inverse),
          do: 7,
          else: 5
        )

      {:ok,
       [
         Runtime.safe_integer2(ohlcv, 0, "openTime"),
         Runtime.safe_number2(ohlcv, 1, "open"),
         Runtime.safe_number2(ohlcv, 2, "high"),
         Runtime.safe_number2(ohlcv, 3, "low"),
         Runtime.safe_number2(ohlcv, 4, "close"),
         Runtime.safe_number2(ohlcv, volume_index, "volume")
       ]}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_ohlcv(
          String.t(),
          String.t(),
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_ohlcv(
        symbol,
        timeframe \\ "1m",
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchOHLCV" => %{"paginate" => false},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = timeframe
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      paginate = false
      _ = paginate

      ccxt_match =
        Runtime.handle_option_and_params(exchange, params, "fetchOHLCV", "paginate", false)

      paginate = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = paginate
      _ = params

      if Runtime.truthy(paginate) do
        throw(
          {:ccxt_return,
           Runtime.fetch_paginated_call_deterministic(
             exchange,
             __MODULE__,
             fetcher,
             "fetchOHLCV",
             symbol,
             since,
             limit,
             timeframe,
             params,
             1000
           )}
        )
      end

      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      default_limit = 500
      max_limit = 1000
      price = Runtime.safe_string(params, "price")
      until = Runtime.safe_integer(params, "until")
      params = Runtime.omit(params, ["price", "until"])
      _ = params

      {limit} =
        if Runtime.truthy(
             Runtime.truthy(Runtime.truthy(since != nil) and Runtime.truthy(until != nil)) and
               Runtime.truthy(limit == nil)
           ) do
          limit = max_limit
          _ = limit

          {limit}
        else
          {limit}
        end

      _ = limit

      limit =
        if(
          Runtime.truthy(limit == nil),
          do: default_limit,
          else: min(limit, max_limit)
        )

      _ = limit

      request = %{
        "interval" => Runtime.safe_string(Runtime.timeframes(exchange), timeframe, timeframe),
        "limit" => limit
      }

      _ = request
      market_id = Runtime.safe_value(market, "id")

      {request} =
        if Runtime.truthy(price == "index") do
          parts = Runtime.string_split(market_id, "_")
          pair = Runtime.safe_string(parts, 0)
          request = Runtime.put_value(request, "pair", pair)

          {request}
        else
          request = Runtime.put_value(request, "symbol", market_id)

          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)

          {request} =
            if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
              {request} =
                if Runtime.truthy(since > 0) do
                  duration = Runtime.parse_timeframe(exchange, timeframe)
                  end_time = Runtime.sum(exchange, since, limit * duration * 1000 - 1)
                  now = Runtime.milliseconds(exchange)
                  request = Runtime.put_value(request, "endTime", min(now, end_time))

                  {request}
                else
                  {request}
                end

              _ = request

              {request}
            else
              {request}
            end

          _ = request

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(until != nil) do
          request = Runtime.put_value(request, "endTime", until)

          {request}
        else
          {request}
        end

      _ = request

      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.safe_value(market, "option")) do
          response =
            Runtime.call_raw!(Raw, fetcher, "eapipublic_get_klines", [
              Runtime.extend(request, params)
            ])

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(price == "mark") do
              {response} =
                if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "dapipublic_get_markpriceklines", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "fapipublic_get_markpriceklines", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              {response} =
                if Runtime.truthy(price == "index") do
                  {response} =
                    if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "dapipublic_get_indexpriceklines", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "fapipublic_get_indexpriceklines", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                else
                  {response} =
                    if Runtime.truthy(price == "premiumIndex") do
                      {response} =
                        if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
                          response =
                            Runtime.call_raw!(Raw, fetcher, "dapipublic_get_premiumindexklines", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {response}
                        else
                          response =
                            Runtime.call_raw!(Raw, fetcher, "fapipublic_get_premiumindexklines", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {response}
                        end

                      _ = response

                      {response}
                    else
                      {response} =
                        if Runtime.truthy(Runtime.safe_value(market, "linear")) do
                          response =
                            Runtime.call_raw!(Raw, fetcher, "fapipublic_get_klines", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {response}
                        else
                          {response} =
                            if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
                              response =
                                Runtime.call_raw!(Raw, fetcher, "dapipublic_get_klines", [
                                  Runtime.extend(request, params)
                                ])

                              _ = response

                              {response}
                            else
                              response =
                                Runtime.call_raw!(Raw, fetcher, "public_get_klines", [
                                  Runtime.extend(request, params)
                                ])

                              _ = response

                              {response}
                            end

                          _ = response

                          {response}
                        end

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                end

              _ = response

              {response}
            end

          _ = response

          {response}
        end

      _ = response

      candles = Runtime.parse_ohlcvs(response, market, timeframe, since, limit)
      {:ok, candles}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_trade(term(), term(), term()) :: term()
  def parse_trade(exchange, trade, market \\ nil) do
    _ = exchange
    _ = trade
    _ = market

    try do
      if Runtime.truthy(Runtime.has_key?(trade, "isDustTrade")) do
        throw({:ccxt_return, Runtime.parse_dust_trade(exchange, trade, market)})
      end

      timestamp = Runtime.safe_integer2(trade, "T", "time")
      amount = Runtime.safe_string2(trade, "q", "qty")
      _ = amount
      amount = Runtime.safe_string(trade, "quantity", amount)
      _ = amount
      market_id = Runtime.safe_string(trade, "symbol")

      is_spot_trade =
        Runtime.truthy(
          Runtime.truthy(
            Runtime.truthy(Runtime.has_key?(trade, "isIsolated")) or
              Runtime.truthy(Runtime.has_key?(trade, "M"))
          ) or Runtime.truthy(Runtime.has_key?(trade, "orderListId"))
        ) or Runtime.truthy(Runtime.has_key?(trade, "isMaker"))

      market_type =
        if(
          Runtime.truthy(is_spot_trade),
          do: "spot",
          else: "contract"
        )

      market = safe_market(exchange, market_id, market, nil, market_type)
      _ = market
      symbol = Runtime.safe_value(market, "symbol")
      side = nil
      _ = side
      buyer_maker = Runtime.safe_bool2(trade, "m", "isBuyerMaker")
      taker_or_maker = nil
      _ = taker_or_maker

      {side} =
        if Runtime.truthy(buyer_maker != nil) do
          side =
            if(
              Runtime.truthy(buyer_maker),
              do: "sell",
              else: "buy"
            )

          _ = side

          {side}
        else
          {side} =
            if Runtime.truthy(Runtime.has_key?(trade, "side")) do
              side = Runtime.safe_string_lower(trade, "side")
              _ = side

              {side}
            else
              {side} =
                if Runtime.truthy(Runtime.has_key?(trade, "isBuyer")) do
                  side =
                    if(
                      Runtime.truthy(Runtime.safe_value(trade, "isBuyer")),
                      do: "buy",
                      else: "sell"
                    )

                  _ = side

                  {side}
                else
                  {side}
                end

              _ = side

              {side}
            end

          _ = side

          {side}
        end

      _ = side

      fee = nil
      _ = fee

      {fee} =
        if Runtime.truthy(Runtime.has_key?(trade, "commission")) do
          fee = %{
            cost: Runtime.safe_string(trade, "commission"),
            currency: Runtime.safe_currency_code(Runtime.safe_string(trade, "commissionAsset"))
          }

          _ = fee

          {fee}
        else
          {fee}
        end

      _ = fee

      {taker_or_maker} =
        if Runtime.truthy(Runtime.has_key?(trade, "isMaker")) do
          taker_or_maker =
            if(
              Runtime.truthy(Runtime.safe_value(trade, "isMaker")),
              do: "maker",
              else: "taker"
            )

          _ = taker_or_maker

          {taker_or_maker}
        else
          {taker_or_maker}
        end

      _ = taker_or_maker

      {taker_or_maker} =
        if Runtime.truthy(Runtime.has_key?(trade, "maker")) do
          taker_or_maker =
            if(
              Runtime.truthy(Runtime.safe_value(trade, "maker")),
              do: "maker",
              else: "taker"
            )

          _ = taker_or_maker

          {taker_or_maker}
        else
          {taker_or_maker}
        end

      _ = taker_or_maker

      {amount, fee, side, taker_or_maker} =
        if Runtime.truthy(
             Runtime.truthy(Runtime.has_key?(trade, "optionSide")) or
               Runtime.truthy(Runtime.safe_value(market, "option"))
           ) do
          settle = Runtime.safe_currency_code(Runtime.safe_string(trade, "quoteAsset", "USDT"))
          taker_or_maker = Runtime.safe_string_lower(trade, "liquidity")
          _ = taker_or_maker

          {fee} =
            if Runtime.truthy(Runtime.has_key?(trade, "fee")) do
              fee = %{cost: Runtime.safe_string(trade, "fee"), currency: settle}
              _ = fee

              {fee}
            else
              {fee}
            end

          _ = fee

          {side} =
            if Runtime.truthy(Runtime.truthy(side != "buy") and Runtime.truthy(side != "sell")) do
              side =
                if(
                  Runtime.truthy(side == "1"),
                  do: "buy",
                  else: "sell"
                )

              _ = side

              {side}
            else
              {side}
            end

          _ = side

          {amount} =
            if Runtime.truthy(Runtime.has_key?(trade, "optionSide")) do
              {amount} =
                if Runtime.truthy(side != "buy") do
                  amount = Runtime.multiply_number_string("-1", amount)
                  _ = amount

                  {amount}
                else
                  {amount}
                end

              _ = amount

              {amount}
            else
              {amount}
            end

          _ = amount

          {amount, fee, side, taker_or_maker}
        else
          {amount, fee, side, taker_or_maker}
        end

      _ = amount
      _ = fee
      _ = side
      _ = taker_or_maker

      throw(
        {:ccxt_return,
         Runtime.safe_trade(
           %{
             info: trade,
             timestamp: timestamp,
             datetime: Runtime.iso8601(timestamp),
             symbol: symbol,
             id: Runtime.safe_string_n(trade, ["t", "a", "tradeId", "id"]),
             order: Runtime.safe_string(trade, "orderId"),
             type: Runtime.safe_string_lower(trade, "type"),
             side: side,
             takerOrMaker: taker_or_maker,
             price: Runtime.safe_string2(trade, "p", "price"),
             amount: amount,
             cost: Runtime.safe_string2(trade, "quoteQty", "baseQty"),
             fee: fee
           },
           market
         )}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_trades(String.t(), integer() | nil, integer() | nil, params(), (RawEndpoint.t(),
                                                                              params() ->
                                                                                {:ok, map()}
                                                                                | {:error, term()})) ::
          {:ok, list()} | {:error, term()}
  def fetch_trades(
        symbol,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchTrades" => %{"paginate" => false},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      paginate = false
      _ = paginate
      ccxt_match = Runtime.handle_option_and_params(exchange, params, "fetchTrades", "paginate")
      paginate = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = paginate
      _ = params

      if Runtime.truthy(paginate) do
        throw(
          {:ccxt_return,
           Runtime.fetch_paginated_call_dynamic(
             exchange,
             __MODULE__,
             fetcher,
             "fetchTrades",
             symbol,
             since,
             limit,
             params
           )}
        )
      end

      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      request = %{"symbol" => Runtime.safe_value(market, "id")}
      _ = request

      {request} =
        if Runtime.truthy(not Runtime.truthy(Runtime.safe_value(market, "option"))) do
          {request} =
            if Runtime.truthy(since != nil) do
              request = Runtime.put_value(request, "startTime", since)

              request =
                Runtime.put_value(request, "endTime", Runtime.sum(exchange, since, 3_600_000))

              {request}
            else
              {request}
            end

          _ = request

          until = Runtime.safe_integer(params, "until")

          {request} =
            if Runtime.truthy(until != nil) do
              request = Runtime.put_value(request, "endTime", until)

              {request}
            else
              {request}
            end

          _ = request

          {request}
        else
          {request}
        end

      _ = request

      method = Runtime.safe_string(Runtime.safe_value(exchange, "options"), "fetchTradesMethod")
      _ = method
      method = Runtime.safe_string2(params, "fetchTradesMethod", "method", method)
      _ = method

      {request} =
        if Runtime.truthy(limit != nil) do
          is_future_or_swap =
            Runtime.truthy(Runtime.safe_value(market, "swap")) or
              Runtime.truthy(Runtime.safe_value(market, "future"))

          is_historical_endpoint =
            Runtime.truthy(method != nil) and
              Runtime.truthy(Runtime.index_of(method, "GetHistoricalTrades") >= 0)

          max_limit_for_contract_historical =
            if(
              Runtime.truthy(is_historical_endpoint),
              do: 500,
              else: 1000
            )

          request =
            Runtime.put_value(
              request,
              "limit",
              if(
                Runtime.truthy(is_future_or_swap),
                do: min(limit, max_limit_for_contract_historical),
                else: limit
              )
            )

          {request}
        else
          {request}
        end

      _ = request

      params = Runtime.omit(params, ["until", "fetchTradesMethod"])
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(
             Runtime.truthy(Runtime.safe_value(market, "option")) or
               Runtime.truthy(method == "eapiPublicGetTrades")
           ) do
          response =
            Runtime.call_raw!(Raw, fetcher, "eapipublic_get_trades", [
              Runtime.extend(request, params)
            ])

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(
                 Runtime.truthy(Runtime.safe_value(market, "linear")) or
                   Runtime.truthy(method == "fapiPublicGetAggTrades")
               ) do
              response =
                Runtime.call_raw!(Raw, fetcher, "fapipublic_get_aggtrades", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            else
              {response} =
                if Runtime.truthy(
                     Runtime.truthy(Runtime.safe_value(market, "inverse")) or
                       Runtime.truthy(method == "dapiPublicGetAggTrades")
                   ) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "dapipublic_get_aggtrades", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "public_get_aggtrades", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                end

              _ = response

              {response}
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, Runtime.parse_trades(exchange, __MODULE__, response, market, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec edit_spot_order(
          String.t(),
          String.t(),
          params(),
          params(),
          number(),
          number() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, map()} | {:error, term()}
  def edit_spot_order(
        id,
        symbol,
        type,
        side,
        amount,
        price \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "precisionMode" => "tick_size",
            "paddingMode" => "no_padding",
            "defaultType" => "spot",
            "defaultTimeInForce" => "GTC",
            "quoteOrderQty" => true,
            "newOrderRespType" => %{"market" => "FULL", "limit" => "FULL"},
            "broker" => %{"spot" => "x-TKT5PX2F", "margin" => "x-TKT5PX2F"},
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = id
    _ = symbol
    _ = type
    _ = side
    _ = amount
    _ = price
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

      if Runtime.truthy(not Runtime.truthy(Runtime.safe_value(market, "spot"))) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " editSpotOrder() does not support " <>
               Runtime.safe_value(market, "type") <> " orders"
           ])}
        )
      end

      payload =
        Runtime.call_generated!(exchange, __MODULE__, :edit_spot_order_request, [
          id,
          symbol,
          type,
          side,
          amount,
          price,
          params
        ])

      response = Runtime.call_raw!(Raw, fetcher, "private_post_order_cancelreplace", [payload])
      data = Runtime.safe_dict(response, "newOrderResponse")
      {:ok, Runtime.call_generated!(exchange, __MODULE__, :parse_order, [data, market])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec edit_spot_order_request(term(), term(), term(), term(), term(), term(), term(), term()) ::
          term()
  def edit_spot_order_request(
        exchange,
        id,
        symbol,
        type,
        side,
        amount,
        price \\ nil,
        params \\ %{}
      ) do
    _ = exchange
    _ = id
    _ = symbol
    _ = type
    _ = side
    _ = amount
    _ = price
    _ = params

    try do
      market = Runtime.market!(exchange, symbol)

      client_order_id =
        Runtime.safe_string_n(params, ["newClientOrderId", "clientOrderId", "origClientOrderId"])

      request = %{"symbol" => Runtime.safe_value(market, "id"), "side" => Runtime.upcase(side)}
      _ = request
      initial_uppercase_type = Runtime.upcase(type)
      uppercase_type = initial_uppercase_type
      _ = uppercase_type

      post_only =
        Runtime.is_post_only(
          initial_uppercase_type == "MARKET",
          initial_uppercase_type == "LIMIT_MAKER",
          params
        )

      {uppercase_type} =
        if Runtime.truthy(post_only) do
          uppercase_type = "LIMIT_MAKER"
          _ = uppercase_type

          {uppercase_type}
        else
          {uppercase_type}
        end

      _ = uppercase_type

      trigger_price = Runtime.safe_number2(params, "stopPrice", "triggerPrice")

      {uppercase_type} =
        if Runtime.truthy(trigger_price != nil) do
          {uppercase_type} =
            if Runtime.truthy(uppercase_type == "MARKET") do
              uppercase_type = "STOP_LOSS"
              _ = uppercase_type

              {uppercase_type}
            else
              {uppercase_type} =
                if Runtime.truthy(uppercase_type == "LIMIT") do
                  uppercase_type = "STOP_LOSS_LIMIT"
                  _ = uppercase_type

                  {uppercase_type}
                else
                  {uppercase_type}
                end

              _ = uppercase_type

              {uppercase_type}
            end

          _ = uppercase_type

          {uppercase_type}
        else
          {uppercase_type}
        end

      _ = uppercase_type

      request = Runtime.put_value(request, "type", uppercase_type)
      valid_order_types = Runtime.safe_list(Runtime.safe_value(market, "info"), "orderTypes")

      if Runtime.truthy(not Runtime.truthy(Runtime.in_array(uppercase_type, valid_order_types))) do
        if Runtime.truthy(initial_uppercase_type != uppercase_type) do
          throw(
            {:ccxt_error,
             Runtime.new_error_reason(":invalid_order", [
               Runtime.safe_value(exchange, "id") <>
                 " triggerPrice parameter is not allowed for " <>
                 symbol <> " " <> type <> " orders"
             ])}
          )
        else
          throw(
            {:ccxt_error,
             Runtime.new_error_reason(":invalid_order", [
               Runtime.safe_value(exchange, "id") <>
                 " " <> type <> " is not a valid order type for the " <> symbol <> " market"
             ])}
          )
        end
      end

      {request} =
        if Runtime.truthy(client_order_id == nil) do
          broker = Runtime.safe_dict(Runtime.safe_value(exchange, "options"), "broker")

          {request} =
            if Runtime.truthy(broker != nil) do
              broker_id = Runtime.safe_string(broker, "spot")

              {request} =
                if Runtime.truthy(broker_id != nil) do
                  request =
                    Runtime.put_value(
                      request,
                      "newClientOrderId",
                      Runtime.add_or_concat(broker_id, Runtime.uuid22())
                    )

                  {request}
                else
                  {request}
                end

              _ = request

              {request}
            else
              {request}
            end

          _ = request

          {request}
        else
          request = Runtime.put_value(request, "newClientOrderId", client_order_id)

          {request}
        end

      _ = request

      request =
        Runtime.put_value(
          request,
          "newOrderRespType",
          Runtime.safe_value(
            Runtime.safe_value(Runtime.safe_value(exchange, "options"), "newOrderRespType"),
            type,
            "RESULT"
          )
        )

      time_in_force_is_required = false
      _ = time_in_force_is_required
      price_is_required = false
      _ = price_is_required
      trigger_price_is_required = false
      _ = trigger_price_is_required
      quantity_is_required = false
      _ = quantity_is_required

      {price_is_required, quantity_is_required, request, time_in_force_is_required,
       trigger_price_is_required} =
        if Runtime.truthy(uppercase_type == "MARKET") do
          quote_order_qty =
            Runtime.safe_bool(Runtime.safe_value(exchange, "options"), "quoteOrderQty", true)

          {quantity_is_required, request} =
            if Runtime.truthy(quote_order_qty) do
              quote_order_qty_new = Runtime.safe_value2(params, "quoteOrderQty", "cost")
              precision = Runtime.safe_value(Runtime.safe_value(market, "precision"), "price")

              {quantity_is_required, request} =
                if Runtime.truthy(quote_order_qty_new != nil) do
                  request =
                    Runtime.put_value(
                      request,
                      "quoteOrderQty",
                      Runtime.decimal_to_precision(
                        quote_order_qty_new,
                        :truncate,
                        precision,
                        Runtime.safe_value(exchange, "precisionMode", :tick_size)
                      )
                    )

                  {quantity_is_required, request}
                else
                  {quantity_is_required, request} =
                    if Runtime.truthy(price != nil) do
                      amount_string = Runtime.number_to_string(amount)
                      price_string = Runtime.number_to_string(price)

                      quote_order_quantity =
                        Runtime.multiply_number_string(amount_string, price_string)

                      request =
                        Runtime.put_value(
                          request,
                          "quoteOrderQty",
                          Runtime.decimal_to_precision(
                            quote_order_quantity,
                            :truncate,
                            precision,
                            Runtime.safe_value(exchange, "precisionMode", :tick_size)
                          )
                        )

                      {quantity_is_required, request}
                    else
                      quantity_is_required = true
                      _ = quantity_is_required

                      {quantity_is_required, request}
                    end

                  _ = quantity_is_required
                  _ = request

                  {quantity_is_required, request}
                end

              _ = quantity_is_required
              _ = request

              {quantity_is_required, request}
            else
              quantity_is_required = true
              _ = quantity_is_required

              {quantity_is_required, request}
            end

          _ = quantity_is_required
          _ = request

          {price_is_required, quantity_is_required, request, time_in_force_is_required,
           trigger_price_is_required}
        else
          {price_is_required, quantity_is_required, time_in_force_is_required,
           trigger_price_is_required} =
            if Runtime.truthy(uppercase_type == "LIMIT") do
              price_is_required = true
              _ = price_is_required
              time_in_force_is_required = true
              _ = time_in_force_is_required
              quantity_is_required = true
              _ = quantity_is_required

              {price_is_required, quantity_is_required, time_in_force_is_required,
               trigger_price_is_required}
            else
              {price_is_required, quantity_is_required, time_in_force_is_required,
               trigger_price_is_required} =
                if Runtime.truthy(
                     Runtime.truthy(uppercase_type == "STOP_LOSS") or
                       Runtime.truthy(uppercase_type == "TAKE_PROFIT")
                   ) do
                  trigger_price_is_required = true
                  _ = trigger_price_is_required
                  quantity_is_required = true
                  _ = quantity_is_required

                  {price_is_required, quantity_is_required, time_in_force_is_required,
                   trigger_price_is_required}
                else
                  {price_is_required, quantity_is_required, time_in_force_is_required,
                   trigger_price_is_required} =
                    if Runtime.truthy(
                         Runtime.truthy(uppercase_type == "STOP_LOSS_LIMIT") or
                           Runtime.truthy(uppercase_type == "TAKE_PROFIT_LIMIT")
                       ) do
                      quantity_is_required = true
                      _ = quantity_is_required
                      trigger_price_is_required = true
                      _ = trigger_price_is_required
                      price_is_required = true
                      _ = price_is_required
                      time_in_force_is_required = true
                      _ = time_in_force_is_required

                      {price_is_required, quantity_is_required, time_in_force_is_required,
                       trigger_price_is_required}
                    else
                      {price_is_required, quantity_is_required} =
                        if Runtime.truthy(uppercase_type == "LIMIT_MAKER") do
                          price_is_required = true
                          _ = price_is_required
                          quantity_is_required = true
                          _ = quantity_is_required

                          {price_is_required, quantity_is_required}
                        else
                          {price_is_required, quantity_is_required}
                        end

                      _ = price_is_required
                      _ = quantity_is_required

                      {price_is_required, quantity_is_required, time_in_force_is_required,
                       trigger_price_is_required}
                    end

                  _ = price_is_required
                  _ = quantity_is_required
                  _ = time_in_force_is_required
                  _ = trigger_price_is_required

                  {price_is_required, quantity_is_required, time_in_force_is_required,
                   trigger_price_is_required}
                end

              _ = price_is_required
              _ = quantity_is_required
              _ = time_in_force_is_required
              _ = trigger_price_is_required

              {price_is_required, quantity_is_required, time_in_force_is_required,
               trigger_price_is_required}
            end

          _ = price_is_required
          _ = quantity_is_required
          _ = time_in_force_is_required
          _ = trigger_price_is_required

          {price_is_required, quantity_is_required, request, time_in_force_is_required,
           trigger_price_is_required}
        end

      _ = price_is_required
      _ = quantity_is_required
      _ = request
      _ = time_in_force_is_required
      _ = trigger_price_is_required

      {request} =
        if Runtime.truthy(quantity_is_required) do
          request =
            Runtime.put_value(
              request,
              "quantity",
              Runtime.amount_to_precision(exchange, symbol, amount)
            )

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(price_is_required) do
          if Runtime.truthy(price == nil) do
            throw(
              {:ccxt_error,
               Runtime.new_error_reason(":invalid_order", [
                 Runtime.safe_value(exchange, "id") <>
                   " editOrder() requires a price argument for a " <> type <> " order"
               ])}
            )
          end

          request =
            Runtime.put_value(
              request,
              "price",
              Runtime.price_to_precision(exchange, symbol, price)
            )

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(
             Runtime.truthy(time_in_force_is_required) and
               Runtime.truthy(Runtime.safe_string(params, "timeInForce") == nil)
           ) do
          request =
            Runtime.put_value(
              request,
              "timeInForce",
              Runtime.safe_value(Runtime.safe_value(exchange, "options"), "defaultTimeInForce")
            )

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(trigger_price_is_required) do
          {request} =
            if Runtime.truthy(trigger_price == nil) do
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":invalid_order", [
                   Runtime.safe_value(exchange, "id") <>
                     " editOrder() requires a triggerPrice extra param for a " <> type <> " order"
                 ])}
              )
            else
              request =
                Runtime.put_value(
                  request,
                  "stopPrice",
                  Runtime.price_to_precision(exchange, symbol, trigger_price)
                )

              {request}
            end

          _ = request

          {request}
        else
          {request}
        end

      _ = request

      request = Runtime.put_value(request, "cancelReplaceMode", "STOP_ON_FAILURE")

      cancel_id =
        Runtime.safe_string2(params, "cancelNewClientOrderId", "cancelOrigClientOrderId")

      {request} =
        if Runtime.truthy(cancel_id == nil) do
          request = Runtime.put_value(request, "cancelOrderId", id)

          {request}
        else
          {request}
        end

      _ = request

      {params} =
        if Runtime.truthy(Runtime.safe_string(params, "timeInForce") == "PO") do
          params = Runtime.omit(params, ["timeInForce"])
          _ = params

          {params}
        else
          {params}
        end

      _ = params

      params =
        Runtime.omit(params, [
          "quoteOrderQty",
          "cost",
          "stopPrice",
          "newClientOrderId",
          "clientOrderId",
          "postOnly"
        ])

      _ = params
      throw({:ccxt_return, Runtime.extend(request, params)})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec edit_contract_order_request(
          term(),
          term(),
          term(),
          term(),
          term(),
          term(),
          term(),
          term()
        ) :: term()
  def edit_contract_order_request(
        exchange,
        id,
        symbol,
        type,
        side,
        amount,
        price \\ nil,
        params \\ %{}
      ) do
    _ = exchange
    _ = id
    _ = symbol
    _ = type
    _ = side
    _ = amount
    _ = price
    _ = params

    try do
      market = Runtime.market!(exchange, symbol)

      if Runtime.truthy(not Runtime.truthy(Runtime.safe_value(market, "contract"))) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " editContractOrder() does not support " <>
               Runtime.safe_value(market, "type") <> " orders"
           ])}
        )
      end

      request = %{
        "symbol" => Runtime.safe_value(market, "id"),
        "side" => Runtime.upcase(side),
        "orderId" => id,
        "quantity" => Runtime.amount_to_precision(exchange, symbol, amount)
      }

      _ = request

      client_order_id =
        Runtime.safe_string_n(params, ["newClientOrderId", "clientOrderId", "origClientOrderId"])

      {request} =
        if Runtime.truthy(price != nil) do
          request =
            Runtime.put_value(
              request,
              "price",
              Runtime.price_to_precision(exchange, symbol, price)
            )

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(client_order_id != nil) do
          request = Runtime.put_value(request, "origClientOrderId", client_order_id)

          {request}
        else
          {request}
        end

      _ = request

      params = Runtime.omit(params, ["clientOrderId", "newClientOrderId"])
      _ = params
      throw({:ccxt_return, request})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec edit_contract_order(
          String.t(),
          String.t(),
          params(),
          params(),
          number(),
          number() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, map()} | {:error, term()}
  def edit_contract_order(
        id,
        symbol,
        type,
        side,
        amount,
        price \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = id
    _ = symbol
    _ = type
    _ = side
    _ = amount
    _ = price
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "editContractOrder",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params

      if Runtime.truthy(
           Runtime.truthy(Runtime.safe_value(market, "linear")) or
             Runtime.truthy(is_portfolio_margin)
         ) do
        if Runtime.truthy(
             Runtime.truthy(price == nil) and
               Runtime.truthy(not Runtime.truthy(Runtime.has_key?(params, "priceMatch")))
           ) do
          throw(
            {:ccxt_error,
             Runtime.new_error_reason(":arguments_required", [
               Runtime.safe_value(exchange, "id") <>
                 " editOrder() requires a price argument for portfolio margin and linear orders"
             ])}
          )
        end
      end

      request =
        Runtime.call_generated!(exchange, __MODULE__, :edit_contract_order_request, [
          id,
          symbol,
          type,
          side,
          amount,
          price,
          params
        ])

      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.safe_value(market, "linear")) do
          {response} =
            if Runtime.truthy(is_portfolio_margin) do
              response =
                Runtime.call_raw!(Raw, fetcher, "papi_put_um_order", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            else
              response =
                Runtime.call_raw!(Raw, fetcher, "fapiprivate_put_order", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            end

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "papi_put_cm_order", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "dapiprivate_put_order", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              {response}
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, Runtime.call_generated!(exchange, __MODULE__, :parse_order, [response, market])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec edit_order(
          String.t(),
          String.t(),
          params(),
          params(),
          number() | nil,
          number() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, map()} | {:error, term()}
  def edit_order(
        id,
        symbol,
        type,
        side,
        amount \\ nil,
        price \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "precisionMode" => "tick_size",
            "paddingMode" => "no_padding",
            "defaultType" => "spot",
            "defaultTimeInForce" => "GTC",
            "quoteOrderQty" => true,
            "newOrderRespType" => %{"market" => "FULL", "limit" => "FULL"},
            "broker" => %{
              "spot" => "x-TKT5PX2F",
              "margin" => "x-TKT5PX2F",
              "future" => "x-cvBPrNm9",
              "delivery" => "x-xcKtGhcu",
              "swap" => "x-cvBPrNm9",
              "option" => "x-xcKtGhcu",
              "inverse" => "x-xcKtGhcu"
            },
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = id
    _ = symbol
    _ = type
    _ = side
    _ = amount
    _ = price
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

      if Runtime.truthy(Runtime.safe_value(market, "option")) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " editOrder() does not support " <> Runtime.safe_value(market, "type") <> " orders"
           ])}
        )
      end

      if Runtime.truthy(Runtime.safe_value(market, "spot")) do
        throw(
          {:ccxt_return,
           Runtime.call_generated!(exchange, __MODULE__, :edit_spot_order, [
             id,
             symbol,
             type,
             side,
             amount,
             price,
             params,
             fetcher
           ])}
        )
      else
        throw(
          {:ccxt_return,
           Runtime.call_generated!(exchange, __MODULE__, :edit_contract_order, [
             id,
             symbol,
             type,
             side,
             amount,
             price,
             params,
             fetcher
           ])}
        )
      end
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec edit_orders(params(), params(), (RawEndpoint.t(), params() ->
                                           {:ok, map()} | {:error, term()})) ::
          {:ok, list()} | {:error, term()}
  def edit_orders(orders, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = orders
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      orders_requests = []
      _ = orders_requests
      order_symbols = []
      _ = order_symbols

      {order_symbols, orders_requests} =
        Enum.reduce_while(
          Runtime.index_range(Runtime.js_length(orders), 0),
          {order_symbols, orders_requests},
          fn i, {order_symbols, orders_requests} ->
            try do
              raw_order = Runtime.safe_value(orders, i)
              market_id = Runtime.safe_string(raw_order, "symbol")
              order_symbols = Runtime.push(order_symbols, market_id)
              id = Runtime.safe_string(raw_order, "id")
              type = Runtime.safe_string(raw_order, "type")
              side = Runtime.safe_string(raw_order, "side")
              amount = Runtime.safe_value(raw_order, "amount")
              price = Runtime.safe_value(raw_order, "price")
              order_params = Runtime.safe_dict(raw_order, "params", %{})
              _ = order_params
              is_portfolio_margin = nil
              _ = is_portfolio_margin

              ccxt_match =
                Runtime.handle_option_and_params2(
                  exchange,
                  order_params,
                  "editOrders",
                  "papi",
                  "portfolioMargin",
                  false
                )

              is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
              order_params = Runtime.safe_value(ccxt_match, 1, nil)
              _ = is_portfolio_margin
              _ = order_params

              if Runtime.truthy(is_portfolio_margin) do
                throw(
                  {:ccxt_error,
                   Runtime.new_error_reason(":not_supported", [
                     Runtime.safe_value(exchange, "id") <>
                       " editOrders() does not support portfolio margin orders"
                   ])}
                )
              end

              order_request =
                Runtime.call_generated!(exchange, __MODULE__, :edit_contract_order_request, [
                  id,
                  market_id,
                  type,
                  side,
                  amount,
                  price,
                  order_params
                ])

              orders_requests = Runtime.push(orders_requests, order_request)
              {:cont, {order_symbols, orders_requests}}
            catch
              :continue -> {:cont, {order_symbols, orders_requests}}
              :break -> {:halt, {order_symbols, orders_requests}}
            end
          end
        )

      _ = order_symbols
      _ = orders_requests
      order_symbols = Runtime.market_symbols(exchange, order_symbols, nil, false, true, true)
      _ = order_symbols

      market =
        Runtime.market!(
          Runtime.load_markets!(exchange, __MODULE__, fetcher),
          Runtime.safe_value(order_symbols, 0)
        )

      if Runtime.truthy(
           Runtime.truthy(Runtime.safe_value(market, "spot")) or
             Runtime.truthy(Runtime.safe_value(market, "option"))
         ) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " editOrders() does not support " <>
               Runtime.safe_value(market, "type") <> " orders"
           ])}
        )
      end

      response = nil
      _ = response
      request = %{"batchOrders" => orders_requests}
      _ = request
      request = Runtime.extend(request, params)
      _ = request

      {response} =
        if Runtime.truthy(Runtime.safe_value(market, "linear")) do
          response = Runtime.call_raw!(Raw, fetcher, "fapiprivate_put_batchorders", [request])
          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
              response = Runtime.call_raw!(Raw, fetcher, "dapiprivate_put_batchorders", [request])
              _ = response

              {response}
            else
              {response}
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, Runtime.parse_orders(exchange, __MODULE__, response, nil, nil, nil, nil)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_order_status(String.t(), (RawEndpoint.t(), params() ->
                                          {:ok, map()} | {:error, term()})) ::
          {:ok, String.t() | nil} | {:error, term()}
  def parse_order_status(status, fetcher \\ &default_fetcher/2) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{}}, %{})
    _ = exchange
    _ = fetcher
    _ = status

    try do
      statuses = %{
        "NEW" => "open",
        "PARTIALLY_FILLED" => "open",
        "ACCEPTED" => "open",
        "TRIGGERING" => "open",
        "FILLED" => "closed",
        "TRIGGERED" => "closed",
        "FINISHED" => "closed",
        "CANCELED" => "canceled",
        "CANCELLED" => "canceled",
        "PENDING_CANCEL" => "canceling",
        "REJECTED" => "rejected",
        "EXPIRED" => "expired",
        "EXPIRED_IN_MATCH" => "expired"
      }

      {:ok, Runtime.safe_string(statuses, status, status)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_order_type_by_market(String.t(), String.t(), (RawEndpoint.t(), params() ->
                                                              {:ok, map()} | {:error, term()})) ::
          {:ok, String.t() | nil} | {:error, term()}
  def parse_order_type_by_market(type, market_type, fetcher \\ &default_fetcher/2) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{}}, %{})
    _ = exchange
    _ = fetcher
    _ = type
    _ = market_type

    try do
      types = %{}
      _ = types

      {types} =
        if Runtime.truthy(
             Runtime.truthy(market_type != nil) and Runtime.truthy(market_type == "spot")
           ) do
          types = %{
            "limit_maker" => "limit",
            "stop_loss_limit" => "limit",
            "stop_loss" => "market",
            "take_profit_limit" => "limit",
            "take_profit" => "market"
          }

          _ = types

          {types}
        else
          types = %{
            "limit_maker" => "limit",
            "stop" => "limit",
            "stop_market" => "market",
            "take_profit" => "limit",
            "take_profit_market" => "market",
            "trailing_stop_market" => "market"
          }

          _ = types

          {types}
        end

      _ = types

      {:ok, Runtime.safe_string(types, type, type)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_order(term(), term(), term()) :: term()
  def parse_order(exchange, order, market \\ nil) do
    _ = exchange
    _ = order
    _ = market

    try do
      code = Runtime.safe_string(order, "code")

      if Runtime.truthy(code != nil) do
        msg = Runtime.safe_string(order, "msg")

        if Runtime.truthy(
             Runtime.truthy(code != "200") and
               Runtime.truthy(
                 not Runtime.truthy(
                   Runtime.truthy(msg == "success") or
                     Runtime.truthy(msg == "The operation of cancel all open order is done.")
                 )
               )
           ) do
          throw({:ccxt_return, Runtime.safe_order(%{info: order, status: "rejected"}, market)})
        end
      end

      status =
        Runtime.call_generated!(__MODULE__, :parse_order_status, [
          Runtime.safe_string_n(order, ["status", "strategyStatus", "algoStatus"])
        ])

      market_id = Runtime.safe_string(order, "symbol")

      is_contract =
        Runtime.truthy(Runtime.has_key?(order, "positionSide")) or
          Runtime.truthy(Runtime.has_key?(order, "cumQuote"))

      market_type =
        if(
          Runtime.truthy(is_contract),
          do: "contract",
          else: "spot"
        )

      symbol = Runtime.safe_symbol(exchange, market_id, market, nil, market_type)
      filled = Runtime.safe_string(order, "executedQty", "0")

      timestamp =
        Runtime.safe_integer_n(order, [
          "time",
          "createTime",
          "workingTime",
          "transactTime",
          "updateTime"
        ])

      last_trade_timestamp = nil
      _ = last_trade_timestamp

      {last_trade_timestamp} =
        if Runtime.truthy(
             Runtime.truthy(Runtime.has_key?(order, "transactTime")) or
               Runtime.truthy(Runtime.has_key?(order, "updateTime"))
           ) do
          timestamp_value = Runtime.safe_integer2(order, "updateTime", "transactTime")

          {last_trade_timestamp} =
            if Runtime.truthy(status == "open") do
              {last_trade_timestamp} =
                if Runtime.truthy(Runtime.string_gt?(filled, "0")) do
                  last_trade_timestamp = timestamp_value
                  _ = last_trade_timestamp

                  {last_trade_timestamp}
                else
                  {last_trade_timestamp}
                end

              _ = last_trade_timestamp

              {last_trade_timestamp}
            else
              {last_trade_timestamp} =
                if Runtime.truthy(status == "closed") do
                  last_trade_timestamp = timestamp_value
                  _ = last_trade_timestamp

                  {last_trade_timestamp}
                else
                  {last_trade_timestamp}
                end

              _ = last_trade_timestamp

              {last_trade_timestamp}
            end

          _ = last_trade_timestamp

          {last_trade_timestamp}
        else
          {last_trade_timestamp}
        end

      _ = last_trade_timestamp

      last_update_timestamp = Runtime.safe_integer2(order, "transactTime", "updateTime")
      average = Runtime.safe_string(order, "avgPrice")
      price = Runtime.safe_string(order, "price")
      amount = Runtime.safe_string2(order, "origQty", "quantity")
      cost = Runtime.safe_string2(order, "cummulativeQuoteQty", "cumQuote")
      _ = cost
      cost = Runtime.safe_string(order, "cumBase", cost)
      _ = cost
      type = Runtime.safe_string_lower2(order, "type", "orderType")
      side = Runtime.safe_string_lower(order, "side")
      fills = Runtime.safe_list(order, "fills", [])
      time_in_force = Runtime.safe_string(order, "timeInForce")
      _ = time_in_force

      {time_in_force} =
        if Runtime.truthy(time_in_force == "GTX") do
          time_in_force = "PO"
          _ = time_in_force

          {time_in_force}
        else
          {time_in_force}
        end

      _ = time_in_force

      post_only = Runtime.truthy(type == "limit_maker") or Runtime.truthy(time_in_force == "PO")
      stop_price_string = Runtime.safe_string2(order, "stopPrice", "triggerPrice")
      trigger_price = Runtime.parse_number(Runtime.omit_zero(stop_price_string))
      fee_cost = Runtime.safe_number(order, "fee")
      fee = nil
      _ = fee

      {fee} =
        if Runtime.truthy(fee_cost != nil) do
          fee = %{currency: Runtime.safe_string(order, "quoteAsset"), cost: fee_cost, rate: nil}
          _ = fee

          {fee}
        else
          {fee}
        end

      _ = fee

      throw(
        {:ccxt_return,
         Runtime.safe_order(
           %{
             info: order,
             id: Runtime.safe_string_n(order, ["strategyId", "orderId", "algoId"]),
             clientOrderId:
               Runtime.safe_string_n(order, [
                 "clientOrderId",
                 "newClientStrategyId",
                 "clientAlgoId"
               ]),
             timestamp: timestamp,
             datetime: Runtime.iso8601(timestamp),
             lastTradeTimestamp: last_trade_timestamp,
             lastUpdateTimestamp: last_update_timestamp,
             symbol: symbol,
             type:
               Runtime.call_generated!(__MODULE__, :parse_order_type_by_market, [
                 type,
                 market_type
               ]),
             timeInForce: time_in_force,
             postOnly: post_only,
             reduceOnly: Runtime.safe_bool(order, "reduceOnly"),
             side: side,
             price: price,
             triggerPrice: trigger_price,
             amount: amount,
             cost: cost,
             average: average,
             filled: filled,
             remaining: nil,
             status: status,
             fee: fee,
             trades: fills
           },
           market
         )}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec create_orders(params(), params(), (RawEndpoint.t(), params() ->
                                             {:ok, map()} | {:error, term()})) ::
          {:ok, list()} | {:error, term()}
  def create_orders(orders, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "precisionMode" => "tick_size",
            "paddingMode" => "no_padding",
            "defaultType" => "future",
            "defaultTimeInForce" => "GTC",
            "quoteOrderQty" => true,
            "newOrderRespType" => %{"market" => "FULL", "limit" => "FULL"},
            "broker" => %{
              "spot" => "x-TKT5PX2F",
              "margin" => "x-TKT5PX2F",
              "future" => "x-cvBPrNm9",
              "delivery" => "x-xcKtGhcu",
              "swap" => "x-cvBPrNm9",
              "option" => "x-xcKtGhcu",
              "inverse" => "x-xcKtGhcu"
            },
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = orders
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      orders_requests = []
      _ = orders_requests
      order_symbols = []
      _ = order_symbols

      {order_symbols, orders_requests} =
        Enum.reduce_while(
          Runtime.index_range(Runtime.js_length(orders), 0),
          {order_symbols, orders_requests},
          fn i, {order_symbols, orders_requests} ->
            try do
              raw_order = Runtime.safe_value(orders, i)
              market_id = Runtime.safe_string(raw_order, "symbol")
              order_symbols = Runtime.push(order_symbols, market_id)
              type = Runtime.safe_string(raw_order, "type")
              side = Runtime.safe_string(raw_order, "side")
              amount = Runtime.safe_value(raw_order, "amount")
              price = Runtime.safe_value(raw_order, "price")
              order_params = Runtime.safe_dict(raw_order, "params", %{})

              order_request =
                Runtime.call_generated!(exchange, __MODULE__, :create_order_request, [
                  market_id,
                  type,
                  side,
                  amount,
                  price,
                  order_params
                ])

              orders_requests = Runtime.push(orders_requests, order_request)
              {:cont, {order_symbols, orders_requests}}
            catch
              :continue -> {:cont, {order_symbols, orders_requests}}
              :break -> {:halt, {order_symbols, orders_requests}}
            end
          end
        )

      _ = order_symbols
      _ = orders_requests
      order_symbols = Runtime.market_symbols(exchange, order_symbols, nil, false, true, true)
      _ = order_symbols

      market =
        Runtime.market!(
          Runtime.load_markets!(exchange, __MODULE__, fetcher),
          Runtime.safe_value(order_symbols, 0)
        )

      if Runtime.truthy(Runtime.safe_value(market, "spot")) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " createOrders() does not support " <>
               Runtime.safe_value(market, "type") <> " orders"
           ])}
        )
      end

      response = nil
      _ = response
      request = %{"batchOrders" => orders_requests}
      _ = request
      request = Runtime.extend(request, params)
      _ = request

      {response} =
        if Runtime.truthy(Runtime.safe_value(market, "linear")) do
          response = Runtime.call_raw!(Raw, fetcher, "fapiprivate_post_batchorders", [request])
          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.safe_value(market, "option")) do
              response =
                Runtime.call_raw!(Raw, fetcher, "eapiprivate_post_batchorders", [request])

              _ = response

              {response}
            else
              response =
                Runtime.call_raw!(Raw, fetcher, "dapiprivate_post_batchorders", [request])

              _ = response

              {response}
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, Runtime.parse_orders(exchange, __MODULE__, response, nil, nil, nil, nil)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec create_order(
          String.t(),
          params(),
          params(),
          number(),
          number() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, map()} | {:error, term()}
  def create_order(
        symbol,
        type,
        side,
        amount,
        price \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "precisionMode" => "tick_size",
            "paddingMode" => "no_padding",
            "defaultType" => "spot",
            "defaultTimeInForce" => "GTC",
            "quoteOrderQty" => true,
            "newOrderRespType" => %{"market" => "FULL", "limit" => "FULL"},
            "broker" => %{
              "spot" => "x-TKT5PX2F",
              "margin" => "x-TKT5PX2F",
              "future" => "x-cvBPrNm9",
              "delivery" => "x-xcKtGhcu",
              "swap" => "x-cvBPrNm9",
              "option" => "x-xcKtGhcu",
              "inverse" => "x-xcKtGhcu"
            },
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = type
    _ = side
    _ = amount
    _ = price
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      market_type = Runtime.safe_string(params, "type", Runtime.safe_value(market, "type"))
      margin_mode = Runtime.safe_string(params, "marginMode")

      porfolio_options_value =
        Runtime.safe_bool2(
          Runtime.safe_value(exchange, "options"),
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin =
        Runtime.safe_bool2(params, "papi", "portfolioMargin", porfolio_options_value)

      trigger_price = Runtime.safe_string2(params, "triggerPrice", "stopPrice")
      stop_loss_price = Runtime.safe_string(params, "stopLossPrice")
      take_profit_price = Runtime.safe_string(params, "takeProfitPrice")
      trailing_percent = Runtime.safe_string2(params, "trailingPercent", "callbackRate")
      is_trailing_percent_order = trailing_percent != nil
      is_stop_loss = stop_loss_price != nil
      is_take_profit = take_profit_price != nil

      is_conditional =
        Runtime.truthy(
          Runtime.truthy(
            Runtime.truthy(trigger_price != nil) or Runtime.truthy(is_trailing_percent_order)
          ) or Runtime.truthy(is_stop_loss)
        ) or Runtime.truthy(is_take_profit)

      sor = Runtime.safe_bool2(params, "sor", "SOR", false)
      test = Runtime.safe_bool(params, "test", false)
      params = Runtime.omit(params, ["sor", "SOR", "test"])
      _ = params

      request =
        Runtime.call_generated!(exchange, __MODULE__, :create_order_request, [
          symbol,
          type,
          side,
          amount,
          price,
          params
        ])

      _ = request
      response = nil
      _ = response

      {request, response} =
        if Runtime.truthy(Runtime.safe_value(market, "option")) do
          response = Runtime.call_raw!(Raw, fetcher, "eapiprivate_post_order", [request])
          _ = response

          {request, response}
        else
          {request, response} =
            if Runtime.truthy(sor) do
              {response} =
                if Runtime.truthy(test) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "private_post_sor_order_test", [request])

                  _ = response

                  {response}
                else
                  response = Runtime.call_raw!(Raw, fetcher, "private_post_sor_order", [request])
                  _ = response

                  {response}
                end

              _ = response

              {request, response}
            else
              {request, response} =
                if Runtime.truthy(Runtime.safe_value(market, "linear")) do
                  {request, response} =
                    if Runtime.truthy(is_portfolio_margin) do
                      {response} =
                        if Runtime.truthy(is_conditional) do
                          response =
                            Runtime.call_raw!(Raw, fetcher, "papi_post_um_conditional_order", [
                              request
                            ])

                          _ = response

                          {response}
                        else
                          response =
                            Runtime.call_raw!(Raw, fetcher, "papi_post_um_order", [request])

                          _ = response

                          {response}
                        end

                      _ = response

                      {request, response}
                    else
                      {request, response} =
                        if Runtime.truthy(is_conditional) do
                          request = Runtime.put_value(request, "algoType", "CONDITIONAL")

                          response =
                            Runtime.call_raw!(Raw, fetcher, "fapiprivate_post_algoorder", [
                              request
                            ])

                          _ = response

                          {request, response}
                        else
                          response =
                            Runtime.call_raw!(Raw, fetcher, "fapiprivate_post_order", [request])

                          _ = response

                          {request, response}
                        end

                      _ = request
                      _ = response

                      {request, response}
                    end

                  _ = request
                  _ = response

                  {request, response}
                else
                  {response} =
                    if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
                      {response} =
                        if Runtime.truthy(is_portfolio_margin) do
                          {response} =
                            if Runtime.truthy(is_conditional) do
                              response =
                                Runtime.call_raw!(
                                  Raw,
                                  fetcher,
                                  "papi_post_cm_conditional_order",
                                  [request]
                                )

                              _ = response

                              {response}
                            else
                              response =
                                Runtime.call_raw!(Raw, fetcher, "papi_post_cm_order", [request])

                              _ = response

                              {response}
                            end

                          _ = response

                          {response}
                        else
                          response =
                            Runtime.call_raw!(Raw, fetcher, "dapiprivate_post_order", [request])

                          _ = response

                          {response}
                        end

                      _ = response

                      {response}
                    else
                      {response} =
                        if Runtime.truthy(
                             Runtime.truthy(
                               Runtime.truthy(market_type == "margin") or
                                 Runtime.truthy(margin_mode != nil)
                             ) or Runtime.truthy(is_portfolio_margin)
                           ) do
                          {response} =
                            if Runtime.truthy(is_portfolio_margin) do
                              response =
                                Runtime.call_raw!(Raw, fetcher, "papi_post_margin_order", [
                                  request
                                ])

                              _ = response

                              {response}
                            else
                              response =
                                Runtime.call_raw!(Raw, fetcher, "sapi_post_margin_order", [
                                  request
                                ])

                              _ = response

                              {response}
                            end

                          _ = response

                          {response}
                        else
                          {response} =
                            if Runtime.truthy(test) do
                              response =
                                Runtime.call_raw!(Raw, fetcher, "private_post_order_test", [
                                  request
                                ])

                              _ = response

                              {response}
                            else
                              response =
                                Runtime.call_raw!(Raw, fetcher, "private_post_order", [request])

                              _ = response

                              {response}
                            end

                          _ = response

                          {response}
                        end

                      _ = response

                      {response}
                    end

                  _ = response

                  {request, response}
                end

              _ = request
              _ = response

              {request, response}
            end

          _ = request
          _ = response

          {request, response}
        end

      _ = request
      _ = response

      {:ok, Runtime.call_generated!(exchange, __MODULE__, :parse_order, [response, market])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec create_order_request(term(), term(), term(), term(), term(), term(), term()) :: term()
  def create_order_request(exchange, symbol, type, side, amount, price \\ nil, params \\ %{}) do
    _ = exchange
    _ = symbol
    _ = type
    _ = side
    _ = amount
    _ = price
    _ = params

    try do
      market = Runtime.market!(exchange, symbol)
      market_type = Runtime.safe_string(params, "type", Runtime.safe_value(market, "type"))

      client_order_id =
        Runtime.safe_string_n(params, ["clientAlgoId", "newClientOrderId", "clientOrderId"])

      initial_uppercase_type = Runtime.upcase(type)
      is_market_order = initial_uppercase_type == "MARKET"
      is_limit_order = initial_uppercase_type == "LIMIT"
      upper_case_side = Runtime.upcase(side)
      request = %{"symbol" => Runtime.safe_value(market, "id"), "side" => upper_case_side}
      _ = request
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "createOrder",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      margin_mode = nil
      _ = margin_mode
      ccxt_match = Runtime.handle_margin_mode_and_params(exchange, "createOrder", params)
      margin_mode = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = margin_mode
      _ = params
      reduce_only = Runtime.safe_bool(params, "reduceOnly", false)

      {params, request} =
        if Runtime.truthy(reduce_only) do
          {params, request} =
            if Runtime.truthy(
                 Runtime.truthy(market_type == "margin") or
                   Runtime.truthy(
                     Runtime.truthy(not Runtime.truthy(Runtime.safe_value(market, "contract"))) and
                       Runtime.truthy(margin_mode != nil)
                   )
               ) do
              params = Runtime.omit(params, "reduceOnly")
              _ = params
              request = Runtime.put_value(request, "sideEffectType", "AUTO_REPAY")

              {params, request}
            else
              {params, request}
            end

          _ = params
          _ = request

          {params, request}
        else
          {params, request}
        end

      _ = params
      _ = request

      trigger_price = Runtime.safe_string2(params, "triggerPrice", "stopPrice")
      stop_loss_price = Runtime.safe_string(params, "stopLossPrice", trigger_price)
      take_profit_price = Runtime.safe_string(params, "takeProfitPrice")
      trailing_delta = Runtime.safe_string(params, "trailingDelta")

      trailing_trigger_price =
        Runtime.safe_string2(params, "trailingTriggerPrice", "activationPrice")

      trailing_percent =
        Runtime.safe_string_n(params, ["trailingPercent", "callbackRate", "trailingDelta"])

      price_match = Runtime.safe_string(params, "priceMatch")
      is_trailing_percent_order = trailing_percent != nil

      is_stop_loss =
        Runtime.truthy(stop_loss_price != nil) or Runtime.truthy(trailing_delta != nil)

      is_take_profit = take_profit_price != nil
      is_trigger_order = trigger_price != nil

      is_conditional =
        Runtime.truthy(
          Runtime.truthy(
            Runtime.truthy(is_trigger_order) or Runtime.truthy(is_trailing_percent_order)
          ) or Runtime.truthy(is_stop_loss)
        ) or Runtime.truthy(is_take_profit)

      is_portfolio_margin_conditional =
        Runtime.truthy(is_portfolio_margin) and Runtime.truthy(is_conditional)

      is_price_match = price_match != nil
      price_required_for_trailing = true
      _ = price_required_for_trailing
      uppercase_type = Runtime.upcase(type)
      _ = uppercase_type
      stop_price = nil
      _ = stop_price

      {params, price_required_for_trailing, request, stop_price, uppercase_type} =
        if Runtime.truthy(is_trailing_percent_order) do
          {params, price_required_for_trailing, request, stop_price, uppercase_type} =
            if Runtime.truthy(Runtime.safe_value(market, "swap")) do
              uppercase_type = "TRAILING_STOP_MARKET"
              _ = uppercase_type
              request = Runtime.put_value(request, "callbackRate", trailing_percent)

              {request} =
                if Runtime.truthy(trailing_trigger_price != nil) do
                  request =
                    Runtime.put_value(
                      request,
                      "activationPrice",
                      Runtime.price_to_precision(exchange, symbol, trailing_trigger_price)
                    )

                  {request}
                else
                  {request}
                end

              _ = request

              {params, price_required_for_trailing, request, stop_price, uppercase_type}
            else
              {params, uppercase_type} =
                if Runtime.truthy(
                     Runtime.truthy(
                       Runtime.truthy(
                         Runtime.truthy(uppercase_type != "STOP_LOSS") and
                           Runtime.truthy(uppercase_type != "TAKE_PROFIT")
                       ) and Runtime.truthy(uppercase_type != "STOP_LOSS_LIMIT")
                     ) and Runtime.truthy(uppercase_type != "TAKE_PROFIT_LIMIT")
                   ) do
                  stop_loss_or_take_profit = Runtime.safe_string(params, "stopLossOrTakeProfit")
                  params = Runtime.omit(params, "stopLossOrTakeProfit")
                  _ = params

                  if Runtime.truthy(
                       Runtime.truthy(stop_loss_or_take_profit != "stopLoss") and
                         Runtime.truthy(stop_loss_or_take_profit != "takeProfit")
                     ) do
                    throw(
                      {:ccxt_error,
                       Runtime.new_error_reason(":invalid_order", [
                         Runtime.add_or_concat(Runtime.safe_value(exchange, "id"), symbol) <>
                           " trailingPercent orders require a stopLossOrTakeProfit parameter of either stopLoss or takeProfit"
                       ])}
                    )
                  end

                  {uppercase_type} =
                    if Runtime.truthy(is_market_order) do
                      {uppercase_type} =
                        if Runtime.truthy(stop_loss_or_take_profit == "stopLoss") do
                          uppercase_type = "STOP_LOSS"
                          _ = uppercase_type

                          {uppercase_type}
                        else
                          {uppercase_type} =
                            if Runtime.truthy(stop_loss_or_take_profit == "takeProfit") do
                              uppercase_type = "TAKE_PROFIT"
                              _ = uppercase_type

                              {uppercase_type}
                            else
                              {uppercase_type}
                            end

                          _ = uppercase_type

                          {uppercase_type}
                        end

                      _ = uppercase_type

                      {uppercase_type}
                    else
                      {uppercase_type} =
                        if Runtime.truthy(stop_loss_or_take_profit == "stopLoss") do
                          uppercase_type = "STOP_LOSS_LIMIT"
                          _ = uppercase_type

                          {uppercase_type}
                        else
                          {uppercase_type} =
                            if Runtime.truthy(stop_loss_or_take_profit == "takeProfit") do
                              uppercase_type = "TAKE_PROFIT_LIMIT"
                              _ = uppercase_type

                              {uppercase_type}
                            else
                              {uppercase_type}
                            end

                          _ = uppercase_type

                          {uppercase_type}
                        end

                      _ = uppercase_type

                      {uppercase_type}
                    end

                  _ = uppercase_type

                  {params, uppercase_type}
                else
                  {params, uppercase_type}
                end

              _ = params
              _ = uppercase_type

              {price_required_for_trailing} =
                if Runtime.truthy(
                     Runtime.truthy(uppercase_type == "STOP_LOSS") or
                       Runtime.truthy(uppercase_type == "TAKE_PROFIT")
                   ) do
                  price_required_for_trailing = false
                  _ = price_required_for_trailing

                  {price_required_for_trailing}
                else
                  {price_required_for_trailing}
                end

              _ = price_required_for_trailing

              {stop_price} =
                if Runtime.truthy(trailing_trigger_price != nil) do
                  stop_price =
                    Runtime.price_to_precision(exchange, symbol, trailing_trigger_price)

                  _ = stop_price

                  {stop_price}
                else
                  {stop_price}
                end

              _ = stop_price

              trailing_percent_converted = Runtime.multiply_number_string(trailing_percent, "100")
              request = Runtime.put_value(request, "trailingDelta", trailing_percent_converted)

              {params, price_required_for_trailing, request, stop_price, uppercase_type}
            end

          _ = params
          _ = price_required_for_trailing
          _ = request
          _ = stop_price
          _ = uppercase_type

          {params, price_required_for_trailing, request, stop_price, uppercase_type}
        else
          {stop_price, uppercase_type} =
            if Runtime.truthy(is_stop_loss) do
              stop_price = stop_loss_price
              _ = stop_price

              {uppercase_type} =
                if Runtime.truthy(is_market_order) do
                  uppercase_type =
                    if(
                      Runtime.truthy(Runtime.safe_value(market, "contract")),
                      do: "STOP_MARKET",
                      else: "STOP_LOSS"
                    )

                  _ = uppercase_type

                  {uppercase_type}
                else
                  {uppercase_type} =
                    if Runtime.truthy(is_limit_order) do
                      uppercase_type =
                        if(
                          Runtime.truthy(Runtime.safe_value(market, "contract")),
                          do: "STOP",
                          else: "STOP_LOSS_LIMIT"
                        )

                      _ = uppercase_type

                      {uppercase_type}
                    else
                      {uppercase_type}
                    end

                  _ = uppercase_type

                  {uppercase_type}
                end

              _ = uppercase_type

              {stop_price, uppercase_type}
            else
              {stop_price, uppercase_type} =
                if Runtime.truthy(is_take_profit) do
                  stop_price = take_profit_price
                  _ = stop_price

                  {uppercase_type} =
                    if Runtime.truthy(is_market_order) do
                      uppercase_type =
                        if(
                          Runtime.truthy(Runtime.safe_value(market, "contract")),
                          do: "TAKE_PROFIT_MARKET",
                          else: "TAKE_PROFIT"
                        )

                      _ = uppercase_type

                      {uppercase_type}
                    else
                      {uppercase_type} =
                        if Runtime.truthy(is_limit_order) do
                          uppercase_type =
                            if(
                              Runtime.truthy(Runtime.safe_value(market, "contract")),
                              do: "TAKE_PROFIT",
                              else: "TAKE_PROFIT_LIMIT"
                            )

                          _ = uppercase_type

                          {uppercase_type}
                        else
                          {uppercase_type}
                        end

                      _ = uppercase_type

                      {uppercase_type}
                    end

                  _ = uppercase_type

                  {stop_price, uppercase_type}
                else
                  {stop_price, uppercase_type}
                end

              _ = stop_price
              _ = uppercase_type

              {stop_price, uppercase_type}
            end

          _ = stop_price
          _ = uppercase_type

          {params, price_required_for_trailing, request, stop_price, uppercase_type}
        end

      _ = params
      _ = price_required_for_trailing
      _ = request
      _ = stop_price
      _ = uppercase_type

      if Runtime.truthy(Runtime.safe_value(market, "option")) do
        if Runtime.truthy(type == "market") do
          throw(
            {:ccxt_error,
             Runtime.new_error_reason(":invalid_order", [
               Runtime.safe_value(exchange, "id") <>
                 " " <> type <> " is not a valid order type for the " <> symbol <> " market"
             ])}
          )
        end
      else
        valid_order_types = Runtime.safe_list(Runtime.safe_value(market, "info"), "orderTypes")

        if Runtime.truthy(not Runtime.truthy(Runtime.in_array(uppercase_type, valid_order_types))) do
          if Runtime.truthy(initial_uppercase_type != uppercase_type) do
            throw(
              {:ccxt_error,
               Runtime.new_error_reason(":invalid_order", [
                 Runtime.safe_value(exchange, "id") <>
                   " triggerPrice parameter is not allowed for " <>
                   symbol <> " " <> type <> " orders"
               ])}
            )
          else
            throw(
              {:ccxt_error,
               Runtime.new_error_reason(":invalid_order", [
                 Runtime.safe_value(exchange, "id") <>
                   " " <> type <> " is not a valid order type for the " <> symbol <> " market"
               ])}
            )
          end
        end
      end

      client_order_id_request =
        if(
          Runtime.truthy(is_portfolio_margin_conditional),
          do: "newClientStrategyId",
          else: "newClientOrderId"
        )

      _ = client_order_id_request

      {client_order_id_request} =
        if Runtime.truthy(
             Runtime.truthy(
               Runtime.truthy(
                 Runtime.truthy(Runtime.safe_value(market, "linear")) and
                   Runtime.truthy(Runtime.safe_value(market, "swap"))
               ) and Runtime.truthy(is_conditional)
             ) and Runtime.truthy(not Runtime.truthy(is_portfolio_margin))
           ) do
          client_order_id_request = "clientAlgoId"
          _ = client_order_id_request

          {client_order_id_request}
        else
          {client_order_id_request}
        end

      _ = client_order_id_request

      {request} =
        if Runtime.truthy(client_order_id == nil) do
          broker = Runtime.safe_dict(Runtime.safe_value(exchange, "options"), "broker", %{})

          default_id =
            if(
              Runtime.truthy(Runtime.safe_value(market, "contract")),
              do: "x-xcKtGhcu",
              else: "x-TKT5PX2F"
            )

          id_market_type = "spot"
          _ = id_market_type

          {id_market_type} =
            if Runtime.truthy(Runtime.safe_value(market, "contract")) do
              id_market_type =
                if(
                  Runtime.truthy(
                    Runtime.truthy(Runtime.safe_value(market, "swap")) and
                      Runtime.truthy(Runtime.safe_value(market, "linear"))
                  ),
                  do: "swap",
                  else: "inverse"
                )

              _ = id_market_type

              {id_market_type}
            else
              {id_market_type}
            end

          _ = id_market_type

          broker_id = Runtime.safe_string(broker, id_market_type, default_id)

          request =
            Runtime.put_value(
              request,
              client_order_id_request,
              Runtime.add_or_concat(broker_id, Runtime.uuid22())
            )

          {request}
        else
          request = Runtime.put_value(request, client_order_id_request, client_order_id)

          {request}
        end

      _ = request

      post_only = nil
      _ = post_only

      {post_only, request, uppercase_type} =
        if Runtime.truthy(not Runtime.truthy(is_portfolio_margin)) do
          post_only =
            Runtime.is_post_only(is_market_order, initial_uppercase_type == "LIMIT_MAKER", params)

          _ = post_only

          {request, uppercase_type} =
            if Runtime.truthy(
                 Runtime.truthy(Runtime.safe_value(market, "spot")) or
                   Runtime.truthy(market_type == "margin")
               ) do
              {uppercase_type} =
                if Runtime.truthy(post_only) do
                  uppercase_type = "LIMIT_MAKER"
                  _ = uppercase_type

                  {uppercase_type}
                else
                  {uppercase_type}
                end

              _ = uppercase_type

              {request} =
                if Runtime.truthy(margin_mode == "isolated") do
                  request = Runtime.put_value(request, "isIsolated", true)

                  {request}
                else
                  {request}
                end

              _ = request

              {request, uppercase_type}
            else
              {request, uppercase_type}
            end

          _ = request
          _ = uppercase_type

          {post_only, request, uppercase_type}
        else
          post_only =
            Runtime.is_post_only(is_market_order, initial_uppercase_type == "LIMIT_MAKER", params)

          _ = post_only

          {request, uppercase_type} =
            if Runtime.truthy(post_only) do
              {request, uppercase_type} =
                if Runtime.truthy(not Runtime.truthy(Runtime.safe_value(market, "contract"))) do
                  uppercase_type = "LIMIT_MAKER"
                  _ = uppercase_type

                  {request, uppercase_type}
                else
                  request = Runtime.put_value(request, "timeInForce", "GTX")

                  {request, uppercase_type}
                end

              _ = request
              _ = uppercase_type

              {request, uppercase_type}
            else
              {request, uppercase_type}
            end

          _ = request
          _ = uppercase_type

          {post_only, request, uppercase_type}
        end

      _ = post_only
      _ = request
      _ = uppercase_type

      {request} =
        if Runtime.truthy(
             Runtime.truthy(
               Runtime.truthy(market_type == "spot") or Runtime.truthy(market_type == "margin")
             ) and Runtime.truthy(not Runtime.truthy(is_portfolio_margin))
           ) do
          request =
            Runtime.put_value(
              request,
              "newOrderRespType",
              Runtime.safe_string(
                Runtime.safe_value(Runtime.safe_value(exchange, "options"), "newOrderRespType"),
                type,
                "FULL"
              )
            )

          {request}
        else
          request = Runtime.put_value(request, "newOrderRespType", "RESULT")

          {request}
        end

      _ = request

      type_request =
        if(
          Runtime.truthy(is_portfolio_margin_conditional),
          do: "strategyType",
          else: "type"
        )

      request = Runtime.put_value(request, type_request, uppercase_type)
      close_position = Runtime.safe_bool(params, "closePosition", false)
      time_in_force_is_required = false
      _ = time_in_force_is_required
      price_is_required = false
      _ = price_is_required
      trigger_price_is_required = false
      _ = trigger_price_is_required
      quantity_is_required = false
      _ = quantity_is_required

      {price_is_required, quantity_is_required, request, time_in_force_is_required,
       trigger_price_is_required} =
        if Runtime.truthy(uppercase_type == "MARKET") do
          {quantity_is_required, request} =
            if Runtime.truthy(Runtime.safe_value(market, "spot")) do
              quote_order_qty =
                Runtime.safe_bool(Runtime.safe_value(exchange, "options"), "quoteOrderQty", true)

              {quantity_is_required, request} =
                if Runtime.truthy(quote_order_qty) do
                  quote_order_qty_new = Runtime.safe_string2(params, "quoteOrderQty", "cost")
                  precision = Runtime.safe_value(Runtime.safe_value(market, "precision"), "price")

                  {quantity_is_required, request} =
                    if Runtime.truthy(quote_order_qty_new != nil) do
                      request =
                        Runtime.put_value(
                          request,
                          "quoteOrderQty",
                          Runtime.decimal_to_precision(
                            quote_order_qty_new,
                            :truncate,
                            precision,
                            Runtime.safe_value(exchange, "precisionMode", :tick_size)
                          )
                        )

                      {quantity_is_required, request}
                    else
                      {quantity_is_required, request} =
                        if Runtime.truthy(price != nil) do
                          amount_string = Runtime.number_to_string(amount)
                          price_string = Runtime.number_to_string(price)

                          quote_order_quantity =
                            Runtime.multiply_number_string(amount_string, price_string)

                          request =
                            Runtime.put_value(
                              request,
                              "quoteOrderQty",
                              Runtime.decimal_to_precision(
                                quote_order_quantity,
                                :truncate,
                                precision,
                                Runtime.safe_value(exchange, "precisionMode", :tick_size)
                              )
                            )

                          {quantity_is_required, request}
                        else
                          quantity_is_required = true
                          _ = quantity_is_required

                          {quantity_is_required, request}
                        end

                      _ = quantity_is_required
                      _ = request

                      {quantity_is_required, request}
                    end

                  _ = quantity_is_required
                  _ = request

                  {quantity_is_required, request}
                else
                  quantity_is_required = true
                  _ = quantity_is_required

                  {quantity_is_required, request}
                end

              _ = quantity_is_required
              _ = request

              {quantity_is_required, request}
            else
              quantity_is_required = true
              _ = quantity_is_required

              {quantity_is_required, request}
            end

          _ = quantity_is_required
          _ = request

          {price_is_required, quantity_is_required, request, time_in_force_is_required,
           trigger_price_is_required}
        else
          {price_is_required, quantity_is_required, time_in_force_is_required,
           trigger_price_is_required} =
            if Runtime.truthy(uppercase_type == "LIMIT") do
              price_is_required = true
              _ = price_is_required
              time_in_force_is_required = true
              _ = time_in_force_is_required
              quantity_is_required = true
              _ = quantity_is_required

              {price_is_required, quantity_is_required, time_in_force_is_required,
               trigger_price_is_required}
            else
              {price_is_required, quantity_is_required, time_in_force_is_required,
               trigger_price_is_required} =
                if Runtime.truthy(
                     Runtime.truthy(uppercase_type == "STOP_LOSS") or
                       Runtime.truthy(uppercase_type == "TAKE_PROFIT")
                   ) do
                  trigger_price_is_required = true
                  _ = trigger_price_is_required
                  quantity_is_required = true
                  _ = quantity_is_required

                  {price_is_required} =
                    if Runtime.truthy(
                         Runtime.truthy(
                           Runtime.truthy(Runtime.safe_value(market, "linear")) or
                             Runtime.truthy(Runtime.safe_value(market, "inverse"))
                         ) and Runtime.truthy(price_required_for_trailing)
                       ) do
                      price_is_required = true
                      _ = price_is_required

                      {price_is_required}
                    else
                      {price_is_required}
                    end

                  _ = price_is_required

                  {price_is_required, quantity_is_required, time_in_force_is_required,
                   trigger_price_is_required}
                else
                  {price_is_required, quantity_is_required, time_in_force_is_required,
                   trigger_price_is_required} =
                    if Runtime.truthy(
                         Runtime.truthy(uppercase_type == "STOP_LOSS_LIMIT") or
                           Runtime.truthy(uppercase_type == "TAKE_PROFIT_LIMIT")
                       ) do
                      quantity_is_required = true
                      _ = quantity_is_required
                      trigger_price_is_required = true
                      _ = trigger_price_is_required
                      price_is_required = true
                      _ = price_is_required
                      time_in_force_is_required = true
                      _ = time_in_force_is_required

                      {price_is_required, quantity_is_required, time_in_force_is_required,
                       trigger_price_is_required}
                    else
                      {price_is_required, quantity_is_required, trigger_price_is_required} =
                        if Runtime.truthy(uppercase_type == "LIMIT_MAKER") do
                          price_is_required = true
                          _ = price_is_required
                          quantity_is_required = true
                          _ = quantity_is_required

                          {price_is_required, quantity_is_required, trigger_price_is_required}
                        else
                          {price_is_required, quantity_is_required, trigger_price_is_required} =
                            if Runtime.truthy(uppercase_type == "STOP") do
                              quantity_is_required = true
                              _ = quantity_is_required
                              trigger_price_is_required = true
                              _ = trigger_price_is_required
                              price_is_required = true
                              _ = price_is_required

                              {price_is_required, quantity_is_required, trigger_price_is_required}
                            else
                              {quantity_is_required, trigger_price_is_required} =
                                if Runtime.truthy(
                                     Runtime.truthy(uppercase_type == "STOP_MARKET") or
                                       Runtime.truthy(uppercase_type == "TAKE_PROFIT_MARKET")
                                   ) do
                                  {quantity_is_required} =
                                    if Runtime.truthy(not Runtime.truthy(close_position)) do
                                      quantity_is_required = true
                                      _ = quantity_is_required

                                      {quantity_is_required}
                                    else
                                      {quantity_is_required}
                                    end

                                  _ = quantity_is_required

                                  trigger_price_is_required = true
                                  _ = trigger_price_is_required

                                  {quantity_is_required, trigger_price_is_required}
                                else
                                  {quantity_is_required} =
                                    if Runtime.truthy(uppercase_type == "TRAILING_STOP_MARKET") do
                                      {quantity_is_required} =
                                        if Runtime.truthy(not Runtime.truthy(close_position)) do
                                          quantity_is_required = true
                                          _ = quantity_is_required

                                          {quantity_is_required}
                                        else
                                          {quantity_is_required}
                                        end

                                      _ = quantity_is_required

                                      if Runtime.truthy(trailing_percent == nil) do
                                        throw(
                                          {:ccxt_error,
                                           Runtime.new_error_reason(":invalid_order", [
                                             Runtime.safe_value(exchange, "id") <>
                                               " createOrder() requires a trailingPercent param for a " <>
                                               type <> " order"
                                           ])}
                                        )
                                      end

                                      {quantity_is_required}
                                    else
                                      {quantity_is_required}
                                    end

                                  _ = quantity_is_required

                                  {quantity_is_required, trigger_price_is_required}
                                end

                              _ = quantity_is_required
                              _ = trigger_price_is_required

                              {price_is_required, quantity_is_required, trigger_price_is_required}
                            end

                          _ = price_is_required
                          _ = quantity_is_required
                          _ = trigger_price_is_required

                          {price_is_required, quantity_is_required, trigger_price_is_required}
                        end

                      _ = price_is_required
                      _ = quantity_is_required
                      _ = trigger_price_is_required

                      {price_is_required, quantity_is_required, time_in_force_is_required,
                       trigger_price_is_required}
                    end

                  _ = price_is_required
                  _ = quantity_is_required
                  _ = time_in_force_is_required
                  _ = trigger_price_is_required

                  {price_is_required, quantity_is_required, time_in_force_is_required,
                   trigger_price_is_required}
                end

              _ = price_is_required
              _ = quantity_is_required
              _ = time_in_force_is_required
              _ = trigger_price_is_required

              {price_is_required, quantity_is_required, time_in_force_is_required,
               trigger_price_is_required}
            end

          _ = price_is_required
          _ = quantity_is_required
          _ = time_in_force_is_required
          _ = trigger_price_is_required

          {price_is_required, quantity_is_required, request, time_in_force_is_required,
           trigger_price_is_required}
        end

      _ = price_is_required
      _ = quantity_is_required
      _ = request
      _ = time_in_force_is_required
      _ = trigger_price_is_required

      {request} =
        if Runtime.truthy(quantity_is_required) do
          market_amount_precision =
            Runtime.safe_string(Runtime.safe_value(market, "precision"), "amount")

          is_precision_available = market_amount_precision != nil

          {request} =
            if Runtime.truthy(is_precision_available) do
              request =
                Runtime.put_value(
                  request,
                  "quantity",
                  Runtime.amount_to_precision(exchange, symbol, amount)
                )

              {request}
            else
              request = Runtime.put_value(request, "quantity", Runtime.parse_to_numeric(amount))

              {request}
            end

          _ = request

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(
             Runtime.truthy(price_is_required) and
               Runtime.truthy(not Runtime.truthy(is_price_match))
           ) do
          if Runtime.truthy(price == nil) do
            throw(
              {:ccxt_error,
               Runtime.new_error_reason(":invalid_order", [
                 Runtime.safe_value(exchange, "id") <>
                   " createOrder() requires a price argument for a " <> type <> " order"
               ])}
            )
          end

          price_precision = Runtime.safe_string(Runtime.safe_value(market, "precision"), "price")
          is_price_precision_available = price_precision != nil

          {request} =
            if Runtime.truthy(is_price_precision_available) do
              request =
                Runtime.put_value(
                  request,
                  "price",
                  Runtime.price_to_precision(exchange, symbol, price)
                )

              {request}
            else
              request = Runtime.put_value(request, "price", Runtime.parse_to_numeric(price))

              {request}
            end

          _ = request

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(trigger_price_is_required) do
          if Runtime.truthy(Runtime.safe_value(market, "contract")) do
            if Runtime.truthy(stop_price == nil) do
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":invalid_order", [
                   Runtime.safe_value(exchange, "id") <>
                     " createOrder() requires a triggerPrice extra param for a " <>
                     type <> " order"
                 ])}
              )
            end
          else
            if Runtime.truthy(
                 Runtime.truthy(
                   Runtime.truthy(trailing_delta == nil) and Runtime.truthy(stop_price == nil)
                 ) and Runtime.truthy(trailing_percent == nil)
               ) do
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":invalid_order", [
                   Runtime.safe_value(exchange, "id") <>
                     " createOrder() requires a triggerPrice, trailingDelta or trailingPercent param for a " <>
                     type <> " order"
                 ])}
              )
            end
          end

          {request} =
            if Runtime.truthy(stop_price != nil) do
              {request} =
                if Runtime.truthy(
                     Runtime.truthy(
                       Runtime.truthy(Runtime.safe_value(market, "linear")) and
                         Runtime.truthy(Runtime.safe_value(market, "swap"))
                     ) and Runtime.truthy(not Runtime.truthy(is_portfolio_margin))
                   ) do
                  request =
                    Runtime.put_value(
                      request,
                      "triggerPrice",
                      Runtime.price_to_precision(exchange, symbol, stop_price)
                    )

                  {request}
                else
                  request =
                    Runtime.put_value(
                      request,
                      "stopPrice",
                      Runtime.price_to_precision(exchange, symbol, stop_price)
                    )

                  {request}
                end

              _ = request

              {request}
            else
              {request}
            end

          _ = request

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(
             Runtime.truthy(
               Runtime.truthy(time_in_force_is_required) and
                 Runtime.truthy(Runtime.safe_string(params, "timeInForce") == nil)
             ) and Runtime.truthy(Runtime.safe_string(request, "timeInForce") == nil)
           ) do
          request =
            Runtime.put_value(
              request,
              "timeInForce",
              Runtime.safe_string(Runtime.safe_value(exchange, "options"), "defaultTimeInForce")
            )

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(
             Runtime.truthy(
               Runtime.truthy(not Runtime.truthy(is_portfolio_margin)) and
                 Runtime.truthy(Runtime.safe_value(market, "contract"))
             ) and Runtime.truthy(post_only)
           ) do
          request = Runtime.put_value(request, "timeInForce", "GTX")

          {request}
        else
          {request}
        end

      _ = request

      {params} =
        if Runtime.truthy(Runtime.safe_string(params, "timeInForce") == "PO") do
          params = Runtime.omit(params, "timeInForce")
          _ = params

          {params}
        else
          {params}
        end

      _ = params

      hedged = Runtime.safe_bool(params, "hedged", false)

      {params, request, side} =
        if Runtime.truthy(
             Runtime.truthy(
               Runtime.truthy(not Runtime.truthy(Runtime.safe_value(market, "spot"))) and
                 Runtime.truthy(not Runtime.truthy(Runtime.safe_value(market, "option")))
             ) and Runtime.truthy(hedged)
           ) do
          {params, side} =
            if Runtime.truthy(reduce_only) do
              params = Runtime.omit(params, "reduceOnly")
              _ = params

              side =
                if(
                  Runtime.truthy(side == "buy"),
                  do: "sell",
                  else: "buy"
                )

              _ = side

              {params, side}
            else
              {params, side}
            end

          _ = params
          _ = side

          request =
            Runtime.put_value(
              request,
              "positionSide",
              if(
                Runtime.truthy(side == "buy"),
                do: "LONG",
                else: "SHORT"
              )
            )

          {params, request, side}
        else
          {params, request, side}
        end

      _ = params
      _ = request
      _ = side

      self_trade_prevention = nil
      _ = self_trade_prevention

      ccxt_match =
        Runtime.handle_option_and_params(exchange, params, "createOrder", "selfTradePrevention")

      self_trade_prevention = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = self_trade_prevention
      _ = params

      {request} =
        if Runtime.truthy(self_trade_prevention != nil) do
          {request} =
            if Runtime.truthy(Runtime.safe_value(market, "spot")) do
              request =
                Runtime.put_value(
                  request,
                  "selfTradePreventionMode",
                  Runtime.upcase(self_trade_prevention)
                )

              {request}
            else
              {request}
            end

          _ = request

          {request}
        else
          {request}
        end

      _ = request

      iceberg_amount = Runtime.safe_number(params, "icebergAmount")

      {request} =
        if Runtime.truthy(iceberg_amount != nil) do
          {request} =
            if Runtime.truthy(Runtime.safe_value(market, "spot")) do
              request =
                Runtime.put_value(
                  request,
                  "icebergQty",
                  Runtime.amount_to_precision(exchange, symbol, iceberg_amount)
                )

              {request}
            else
              {request}
            end

          _ = request

          {request}
        else
          {request}
        end

      _ = request

      request_params =
        Runtime.omit(params, [
          "type",
          "newClientOrderId",
          "clientOrderId",
          "postOnly",
          "stopLossPrice",
          "takeProfitPrice",
          "stopPrice",
          "triggerPrice",
          "trailingTriggerPrice",
          "trailingPercent",
          "quoteOrderQty",
          "cost",
          "test",
          "hedged",
          "icebergAmount"
        ])

      throw({:ccxt_return, Runtime.extend(request, request_params)})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec create_market_order_with_cost(String.t(), params(), number(), params(), (RawEndpoint.t(),
                                                                                 params() ->
                                                                                   {:ok, map()}
                                                                                   | {:error,
                                                                                      term()})) ::
          {:ok, map()} | {:error, term()}
  def create_market_order_with_cost(
        symbol,
        side,
        cost,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "precisionMode" => "tick_size",
            "paddingMode" => "no_padding",
            "defaultType" => "spot",
            "defaultTimeInForce" => "GTC",
            "quoteOrderQty" => true,
            "newOrderRespType" => %{"market" => "FULL", "limit" => "FULL"},
            "broker" => %{"spot" => "x-TKT5PX2F", "margin" => "x-TKT5PX2F"},
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = side
    _ = cost
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

      if Runtime.truthy(not Runtime.truthy(Runtime.safe_value(market, "spot"))) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " createMarketOrderWithCost() supports spot orders only"
           ])}
        )
      end

      req = %{"cost" => cost}

      {:ok,
       Runtime.call_generated!(exchange, __MODULE__, :create_order, [
         symbol,
         "market",
         side,
         cost,
         nil,
         Runtime.extend(req, params),
         fetcher
       ])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec create_market_buy_order_with_cost(String.t(), number(), params(), (RawEndpoint.t(),
                                                                           params() ->
                                                                             {:ok, map()}
                                                                             | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def create_market_buy_order_with_cost(
        symbol,
        cost,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "precisionMode" => "tick_size",
            "paddingMode" => "no_padding",
            "defaultType" => "spot",
            "defaultTimeInForce" => "GTC",
            "quoteOrderQty" => true,
            "newOrderRespType" => %{"market" => "FULL", "limit" => "FULL"},
            "broker" => %{"spot" => "x-TKT5PX2F", "margin" => "x-TKT5PX2F"},
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = cost
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

      if Runtime.truthy(not Runtime.truthy(Runtime.safe_value(market, "spot"))) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " createMarketBuyOrderWithCost() supports spot orders only"
           ])}
        )
      end

      req = %{"cost" => cost}

      {:ok,
       Runtime.call_generated!(exchange, __MODULE__, :create_order, [
         symbol,
         "market",
         "buy",
         cost,
         nil,
         Runtime.extend(req, params),
         fetcher
       ])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec create_market_sell_order_with_cost(String.t(), number(), params(), (RawEndpoint.t(),
                                                                            params() ->
                                                                              {:ok, map()}
                                                                              | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def create_market_sell_order_with_cost(
        symbol,
        cost,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "precisionMode" => "tick_size",
            "paddingMode" => "no_padding",
            "defaultType" => "spot",
            "defaultTimeInForce" => "GTC",
            "quoteOrderQty" => true,
            "newOrderRespType" => %{"market" => "FULL", "limit" => "FULL"},
            "broker" => %{"spot" => "x-TKT5PX2F", "margin" => "x-TKT5PX2F"},
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = cost
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

      if Runtime.truthy(not Runtime.truthy(Runtime.safe_value(market, "spot"))) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " createMarketSellOrderWithCost() supports spot orders only"
           ])}
        )
      end

      params = Runtime.put_value(params, "quoteOrderQty", cost)

      {:ok,
       Runtime.call_generated!(exchange, __MODULE__, :create_order, [
         symbol,
         "market",
         "sell",
         cost,
         nil,
         params,
         fetcher
       ])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_order(String.t(), String.t() | nil, params(), (RawEndpoint.t(), params() ->
                                                               {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_order(id, symbol \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchOrder" => %{"defaultType" => "spot"},
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = id
    _ = symbol
    _ = params

    try do
      if Runtime.truthy(symbol == nil) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":arguments_required", [
             Runtime.safe_value(exchange, "id") <> " fetchOrder() requires a symbol argument"
           ])}
        )
      end

      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

      default_type =
        Runtime.safe_string2(
          Runtime.safe_value(exchange, "options"),
          "fetchOrder",
          "defaultType",
          "spot"
        )

      type = Runtime.safe_string(params, "type", default_type)
      margin_mode = nil
      _ = margin_mode
      ccxt_match = Runtime.handle_margin_mode_and_params(exchange, "fetchOrder", params)
      margin_mode = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = margin_mode
      _ = params
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "fetchOrder",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      request = %{"symbol" => Runtime.safe_value(market, "id")}
      _ = request
      is_conditional = Runtime.safe_bool_n(params, ["stop", "trigger", "conditional"])

      client_order_id =
        Runtime.safe_string_n(params, ["origClientOrderId", "clientOrderId", "clientAlgoId"])

      {request} =
        if Runtime.truthy(client_order_id != nil) do
          {request} =
            if Runtime.truthy(Runtime.safe_value(market, "option")) do
              request = Runtime.put_value(request, "clientOrderId", client_order_id)

              {request}
            else
              {request} =
                if Runtime.truthy(
                     Runtime.truthy(
                       Runtime.truthy(
                         Runtime.truthy(Runtime.safe_value(market, "linear")) and
                           Runtime.truthy(Runtime.safe_value(market, "swap"))
                       ) and Runtime.truthy(is_conditional)
                     ) and Runtime.truthy(not Runtime.truthy(is_portfolio_margin))
                   ) do
                  request = Runtime.put_value(request, "clientAlgoId", client_order_id)

                  {request}
                else
                  request = Runtime.put_value(request, "origClientOrderId", client_order_id)

                  {request}
                end

              _ = request

              {request}
            end

          _ = request

          {request}
        else
          {request} =
            if Runtime.truthy(
                 Runtime.truthy(
                   Runtime.truthy(
                     Runtime.truthy(Runtime.safe_value(market, "linear")) and
                       Runtime.truthy(Runtime.safe_value(market, "swap"))
                   ) and Runtime.truthy(is_conditional)
                 ) and Runtime.truthy(not Runtime.truthy(is_portfolio_margin))
               ) do
              request = Runtime.put_value(request, "algoId", id)

              {request}
            else
              request = Runtime.put_value(request, "orderId", id)

              {request}
            end

          _ = request

          {request}
        end

      _ = request

      params =
        Runtime.omit(params, [
          "type",
          "clientOrderId",
          "origClientOrderId",
          "stop",
          "trigger",
          "conditional",
          "clientAlgoId"
        ])

      _ = params
      response = nil
      _ = response

      {request, response} =
        if Runtime.truthy(Runtime.safe_value(market, "option")) do
          response =
            Runtime.call_raw!(Raw, fetcher, "eapiprivate_get_order", [
              Runtime.extend(request, params)
            ])

          _ = response

          {request, response}
        else
          {request, response} =
            if Runtime.truthy(Runtime.safe_value(market, "linear")) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "papi_get_um_order", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                else
                  {response} =
                    if Runtime.truthy(is_conditional) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_algoorder", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_order", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                end

              _ = response

              {request, response}
            else
              {request, response} =
                if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
                  {response} =
                    if Runtime.truthy(is_portfolio_margin) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "papi_get_cm_order", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_order", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {request, response}
                else
                  {request, response} =
                    if Runtime.truthy(
                         Runtime.truthy(
                           Runtime.truthy(type == "margin") or Runtime.truthy(margin_mode != nil)
                         ) or Runtime.truthy(is_portfolio_margin)
                       ) do
                      {request, response} =
                        if Runtime.truthy(is_portfolio_margin) do
                          response =
                            Runtime.call_raw!(Raw, fetcher, "papi_get_margin_order", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {request, response}
                        else
                          {request} =
                            if Runtime.truthy(margin_mode == "isolated") do
                              request = Runtime.put_value(request, "isIsolated", true)

                              {request}
                            else
                              {request}
                            end

                          _ = request

                          response =
                            Runtime.call_raw!(Raw, fetcher, "sapi_get_margin_order", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {request, response}
                        end

                      _ = request
                      _ = response

                      {request, response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "private_get_order", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {request, response}
                    end

                  _ = request
                  _ = response

                  {request, response}
                end

              _ = request
              _ = response

              {request, response}
            end

          _ = request
          _ = response

          {request, response}
        end

      _ = request
      _ = response

      {:ok, Runtime.call_generated!(exchange, __MODULE__, :parse_order, [response, market])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_orders(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_orders(
        symbol \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchOrders" => %{"paginate" => false},
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = since
    _ = limit
    _ = params

    try do
      if Runtime.truthy(symbol == nil) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":arguments_required", [
             Runtime.safe_value(exchange, "id") <> " fetchOrders() requires a symbol argument"
           ])}
        )
      end

      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      paginate = false
      _ = paginate
      ccxt_match = Runtime.handle_option_and_params(exchange, params, "fetchOrders", "paginate")
      paginate = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = paginate
      _ = params

      if Runtime.truthy(paginate) do
        throw(
          {:ccxt_return,
           Runtime.fetch_paginated_call_dynamic(
             exchange,
             __MODULE__,
             fetcher,
             "fetchOrders",
             symbol,
             since,
             limit,
             params
           )}
        )
      end

      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

      default_type =
        Runtime.safe_string2(
          Runtime.safe_value(exchange, "options"),
          "fetchOrders",
          "defaultType",
          Runtime.safe_value(market, "type")
        )

      type = Runtime.safe_string(params, "type", default_type)
      margin_mode = nil
      _ = margin_mode
      ccxt_match = Runtime.handle_margin_mode_and_params(exchange, "fetchOrders", params)
      margin_mode = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = margin_mode
      _ = params
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "fetchOrders",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      is_conditional = Runtime.safe_bool_n(params, ["stop", "trigger", "conditional"])
      params = Runtime.omit(params, ["stop", "trigger", "conditional", "type"])
      _ = params
      request = %{"symbol" => Runtime.safe_value(market, "id")}
      _ = request
      ccxt_match = Runtime.handle_until_option("endTime", request, params)
      request = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = request
      _ = params

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(limit != nil) do
          request = Runtime.put_value(request, "limit", limit)

          {request}
        else
          {request}
        end

      _ = request

      response = nil
      _ = response

      {request, response} =
        if Runtime.truthy(Runtime.safe_value(market, "option")) do
          response =
            Runtime.call_raw!(Raw, fetcher, "eapiprivate_get_historyorders", [
              Runtime.extend(request, params)
            ])

          _ = response

          {request, response}
        else
          {request, response} =
            if Runtime.truthy(Runtime.safe_value(market, "linear")) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  {response} =
                    if Runtime.truthy(is_conditional) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "papi_get_um_conditional_allorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "papi_get_um_allorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                else
                  {response} =
                    if Runtime.truthy(is_conditional) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_allalgoorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_allorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                end

              _ = response

              {request, response}
            else
              {request, response} =
                if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
                  {response} =
                    if Runtime.truthy(is_portfolio_margin) do
                      {response} =
                        if Runtime.truthy(is_conditional) do
                          response =
                            Runtime.call_raw!(Raw, fetcher, "papi_get_cm_conditional_allorders", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {response}
                        else
                          response =
                            Runtime.call_raw!(Raw, fetcher, "papi_get_cm_allorders", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {response}
                        end

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_allorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {request, response}
                else
                  {request, response} =
                    if Runtime.truthy(is_portfolio_margin) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "papi_get_margin_allorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {request, response}
                    else
                      {request, response} =
                        if Runtime.truthy(
                             Runtime.truthy(type == "margin") or
                               Runtime.truthy(margin_mode != nil)
                           ) do
                          {request} =
                            if Runtime.truthy(margin_mode == "isolated") do
                              request = Runtime.put_value(request, "isIsolated", true)

                              {request}
                            else
                              {request}
                            end

                          _ = request

                          response =
                            Runtime.call_raw!(Raw, fetcher, "sapi_get_margin_allorders", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {request, response}
                        else
                          response =
                            Runtime.call_raw!(Raw, fetcher, "private_get_allorders", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {request, response}
                        end

                      _ = request
                      _ = response

                      {request, response}
                    end

                  _ = request
                  _ = response

                  {request, response}
                end

              _ = request
              _ = response

              {request, response}
            end

          _ = request
          _ = response

          {request, response}
        end

      _ = request
      _ = response

      {:ok, Runtime.parse_orders(exchange, __MODULE__, response, market, since, limit, nil)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_open_orders(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_open_orders(
        symbol \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchOpenOrders" => %{"defaultType" => "spot"},
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "warnOnFetchOpenOrdersWithoutSymbol" => false,
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = nil
      _ = market
      type = nil
      _ = type
      request = %{}
      _ = request
      margin_mode = nil
      _ = margin_mode
      ccxt_match = Runtime.handle_margin_mode_and_params(exchange, "fetchOpenOrders", params)
      margin_mode = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = margin_mode
      _ = params
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "fetchOpenOrders",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      is_conditional = Runtime.safe_bool_n(params, ["stop", "trigger", "conditional"])

      {market, request, type} =
        if Runtime.truthy(symbol != nil) do
          market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
          _ = market
          request = Runtime.put_value(request, "symbol", Runtime.safe_value(market, "id"))

          default_type =
            Runtime.safe_string2(
              Runtime.safe_value(exchange, "options"),
              "fetchOpenOrders",
              "defaultType",
              "spot"
            )

          market_type =
            if(
              Runtime.truthy(Runtime.has_key?(market, "type")),
              do: Runtime.safe_value(market, "type"),
              else: default_type
            )

          type = Runtime.safe_string(params, "type", market_type)
          _ = type

          {market, request, type}
        else
          {type} =
            if Runtime.truthy(
                 Runtime.safe_value(
                   Runtime.safe_value(exchange, "options"),
                   "warnOnFetchOpenOrdersWithoutSymbol"
                 )
               ) do
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":exchange_error", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchOpenOrders() WARNING: fetching open orders without specifying a symbol has stricter rate limits (10 times more for spot, 40 times more for other markets) compared to requesting with symbol argument. To acknowledge this warning, set " <>
                     Runtime.safe_value(exchange, "id") <>
                     ".options[\"warnOnFetchOpenOrdersWithoutSymbol\"] = false to suppress this warning message."
                 ])}
              )
            else
              default_type =
                Runtime.safe_string2(
                  Runtime.safe_value(exchange, "options"),
                  "fetchOpenOrders",
                  "defaultType",
                  "spot"
                )

              type = Runtime.safe_string(params, "type", default_type)
              _ = type

              {type}
            end

          _ = type

          {market, request, type}
        end

      _ = market
      _ = request
      _ = type

      sub_type = nil
      _ = sub_type
      ccxt_match = Runtime.handle_sub_type_and_params(exchange, "fetchOpenOrders", market, params)
      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      params = Runtime.omit(params, ["type", "stop", "trigger", "conditional"])
      _ = params
      response = nil
      _ = response

      {request, response} =
        if Runtime.truthy(type == "option") do
          {request} =
            if Runtime.truthy(since != nil) do
              request = Runtime.put_value(request, "startTime", since)

              {request}
            else
              {request}
            end

          _ = request

          {request} =
            if Runtime.truthy(limit != nil) do
              request = Runtime.put_value(request, "limit", limit)

              {request}
            else
              {request}
            end

          _ = request

          response =
            Runtime.call_raw!(Raw, fetcher, "eapiprivate_get_openorders", [
              Runtime.extend(request, params)
            ])

          _ = response

          {request, response}
        else
          {request, response} =
            if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  {response} =
                    if Runtime.truthy(is_conditional) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "papi_get_um_conditional_openorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "papi_get_um_openorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                else
                  {response} =
                    if Runtime.truthy(is_conditional) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_openalgoorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_openorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                end

              _ = response

              {request, response}
            else
              {request, response} =
                if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
                  {response} =
                    if Runtime.truthy(is_portfolio_margin) do
                      {response} =
                        if Runtime.truthy(is_conditional) do
                          response =
                            Runtime.call_raw!(
                              Raw,
                              fetcher,
                              "papi_get_cm_conditional_openorders",
                              [Runtime.extend(request, params)]
                            )

                          _ = response

                          {response}
                        else
                          response =
                            Runtime.call_raw!(Raw, fetcher, "papi_get_cm_openorders", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {response}
                        end

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_openorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {request, response}
                else
                  {request, response} =
                    if Runtime.truthy(
                         Runtime.truthy(
                           Runtime.truthy(type == "margin") or Runtime.truthy(margin_mode != nil)
                         ) or Runtime.truthy(is_portfolio_margin)
                       ) do
                      {request, response} =
                        if Runtime.truthy(is_portfolio_margin) do
                          response =
                            Runtime.call_raw!(Raw, fetcher, "papi_get_margin_openorders", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {request, response}
                        else
                          {request} =
                            if Runtime.truthy(margin_mode == "isolated") do
                              request = Runtime.put_value(request, "isIsolated", true)

                              if Runtime.truthy(symbol == nil) do
                                throw(
                                  {:ccxt_error,
                                   Runtime.new_error_reason(":arguments_required", [
                                     Runtime.safe_value(exchange, "id") <>
                                       " fetchOpenOrders() requires a symbol argument for isolated markets"
                                   ])}
                                )
                              end

                              {request}
                            else
                              {request}
                            end

                          _ = request

                          response =
                            Runtime.call_raw!(Raw, fetcher, "sapi_get_margin_openorders", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {request, response}
                        end

                      _ = request
                      _ = response

                      {request, response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "private_get_openorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {request, response}
                    end

                  _ = request
                  _ = response

                  {request, response}
                end

              _ = request
              _ = response

              {request, response}
            end

          _ = request
          _ = response

          {request, response}
        end

      _ = request
      _ = response

      {:ok, Runtime.parse_orders(exchange, __MODULE__, response, market, since, limit, nil)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_open_order(String.t(), String.t() | nil, params(), (RawEndpoint.t(), params() ->
                                                                    {:ok, map()}
                                                                    | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_open_order(id, symbol \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = id
    _ = symbol
    _ = params

    try do
      if Runtime.truthy(symbol == nil) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":arguments_required", [
             Runtime.safe_value(exchange, "id") <> " fetchOpenOrder() requires a symbol argument"
           ])}
        )
      end

      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      request = %{"symbol" => Runtime.safe_value(market, "id")}
      _ = request
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "fetchOpenOrder",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      is_conditional = Runtime.safe_bool_n(params, ["stop", "trigger", "conditional"])
      params = Runtime.omit(params, ["stop", "trigger", "conditional"])
      _ = params

      is_portfolio_margin_conditional =
        Runtime.truthy(is_portfolio_margin) and Runtime.truthy(is_conditional)

      order_id_request =
        if(
          Runtime.truthy(is_portfolio_margin_conditional),
          do: "strategyId",
          else: "orderId"
        )

      request = Runtime.put_value(request, order_id_request, id)
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.safe_value(market, "linear")) do
          {response} =
            if Runtime.truthy(is_portfolio_margin) do
              {response} =
                if Runtime.truthy(is_conditional) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "papi_get_um_conditional_openorder", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "papi_get_um_openorder", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              response =
                Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_openorder", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            end

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  {response} =
                    if Runtime.truthy(is_conditional) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "papi_get_cm_conditional_openorder", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "papi_get_cm_openorder", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_openorder", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              if Runtime.truthy(Runtime.safe_value(market, "option")) do
                throw(
                  {:ccxt_error,
                   Runtime.new_error_reason(":not_supported", [
                     Runtime.safe_value(exchange, "id") <>
                       " fetchOpenOrder() does not support option markets"
                   ])}
                )
              else
                if Runtime.truthy(Runtime.safe_value(market, "spot")) do
                  throw(
                    {:ccxt_error,
                     Runtime.new_error_reason(":not_supported", [
                       Runtime.safe_value(exchange, "id") <>
                         " fetchOpenOrder() does not support spot markets"
                     ])}
                  )
                end
              end

              {response}
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, Runtime.call_generated!(exchange, __MODULE__, :parse_order, [response, market])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_closed_orders(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_closed_orders(
        symbol \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchOrders" => %{"paginate" => false},
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = since
    _ = limit
    _ = params

    try do
      if Runtime.truthy(symbol == nil) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":arguments_required", [
             Runtime.safe_value(exchange, "id") <>
               " fetchClosedOrders() requires a symbol argument"
           ])}
        )
      end

      orders =
        Runtime.call_generated!(exchange, __MODULE__, :fetch_orders, [
          symbol,
          since,
          nil,
          params,
          fetcher
        ])

      filtered_orders = Runtime.filter_by(orders, "status", "closed")
      {:ok, Runtime.filter_by_since_limit(filtered_orders, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_canceled_orders(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_canceled_orders(
        symbol \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchOrders" => %{"paginate" => false},
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = since
    _ = limit
    _ = params

    try do
      if Runtime.truthy(symbol == nil) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":arguments_required", [
             Runtime.safe_value(exchange, "id") <>
               " fetchCanceledOrders() requires a symbol argument"
           ])}
        )
      end

      orders =
        Runtime.call_generated!(exchange, __MODULE__, :fetch_orders, [
          symbol,
          since,
          nil,
          params,
          fetcher
        ])

      filtered_orders = Runtime.filter_by(orders, "status", "canceled")
      {:ok, Runtime.filter_by_since_limit(filtered_orders, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_canceled_and_closed_orders(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_canceled_and_closed_orders(
        symbol \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchOrders" => %{"paginate" => false},
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = since
    _ = limit
    _ = params

    try do
      if Runtime.truthy(symbol == nil) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":arguments_required", [
             Runtime.safe_value(exchange, "id") <>
               " fetchCanceledAndClosedOrders() requires a symbol argument"
           ])}
        )
      end

      orders =
        Runtime.call_generated!(exchange, __MODULE__, :fetch_orders, [
          symbol,
          since,
          nil,
          params,
          fetcher
        ])

      canceled_orders = Runtime.filter_by(orders, "status", "canceled")
      closed_orders = Runtime.filter_by(orders, "status", "closed")
      filtered_orders = Runtime.array_concat(canceled_orders, closed_orders)
      sorted_orders = Runtime.sort_by(filtered_orders, "timestamp")
      {:ok, Runtime.filter_by_since_limit(sorted_orders, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec cancel_order(String.t(), String.t() | nil, params(), (RawEndpoint.t(), params() ->
                                                                {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def cancel_order(id, symbol \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "cancelOrder" => %{"defaultType" => "spot"},
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = id
    _ = symbol
    _ = params

    try do
      if Runtime.truthy(symbol == nil) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":arguments_required", [
             Runtime.safe_value(exchange, "id") <> " cancelOrder() requires a symbol argument"
           ])}
        )
      end

      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

      default_type =
        Runtime.safe_string2(
          Runtime.safe_value(exchange, "options"),
          "cancelOrder",
          "defaultType",
          "spot"
        )

      type = Runtime.safe_string(params, "type", default_type)
      margin_mode = nil
      _ = margin_mode
      ccxt_match = Runtime.handle_margin_mode_and_params(exchange, "cancelOrder", params)
      margin_mode = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = margin_mode
      _ = params
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "cancelOrder",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      is_conditional = Runtime.safe_bool_n(params, ["stop", "trigger", "conditional"])
      request = %{"symbol" => Runtime.safe_value(market, "id")}
      _ = request

      client_order_id =
        Runtime.safe_string_n(params, [
          "origClientOrderId",
          "clientOrderId",
          "newClientStrategyId",
          "clientAlgoId"
        ])

      {request} =
        if Runtime.truthy(client_order_id != nil) do
          {request} =
            if Runtime.truthy(Runtime.safe_value(market, "option")) do
              request = Runtime.put_value(request, "clientOrderId", client_order_id)

              {request}
            else
              {request} =
                if Runtime.truthy(
                     Runtime.truthy(
                       Runtime.truthy(
                         Runtime.truthy(Runtime.safe_value(market, "linear")) and
                           Runtime.truthy(Runtime.safe_value(market, "swap"))
                       ) and Runtime.truthy(is_conditional)
                     ) and Runtime.truthy(not Runtime.truthy(is_portfolio_margin))
                   ) do
                  request = Runtime.put_value(request, "clientAlgoId", client_order_id)

                  {request}
                else
                  {request} =
                    if Runtime.truthy(
                         Runtime.truthy(is_portfolio_margin) and Runtime.truthy(is_conditional)
                       ) do
                      request = Runtime.put_value(request, "newClientStrategyId", client_order_id)

                      {request}
                    else
                      request = Runtime.put_value(request, "origClientOrderId", client_order_id)

                      {request}
                    end

                  _ = request

                  {request}
                end

              _ = request

              {request}
            end

          _ = request

          {request}
        else
          {request} =
            if Runtime.truthy(
                 Runtime.truthy(is_portfolio_margin) and Runtime.truthy(is_conditional)
               ) do
              request = Runtime.put_value(request, "strategyId", id)

              {request}
            else
              {request} =
                if Runtime.truthy(
                     Runtime.truthy(
                       Runtime.truthy(
                         Runtime.truthy(Runtime.safe_value(market, "linear")) and
                           Runtime.truthy(Runtime.safe_value(market, "swap"))
                       ) and Runtime.truthy(is_conditional)
                     ) and Runtime.truthy(not Runtime.truthy(is_portfolio_margin))
                   ) do
                  request = Runtime.put_value(request, "algoId", id)

                  {request}
                else
                  request = Runtime.put_value(request, "orderId", id)

                  {request}
                end

              _ = request

              {request}
            end

          _ = request

          {request}
        end

      _ = request

      params =
        Runtime.omit(params, [
          "type",
          "origClientOrderId",
          "clientOrderId",
          "newClientStrategyId",
          "stop",
          "trigger",
          "conditional",
          "clientAlgoId"
        ])

      _ = params
      response = nil
      _ = response

      {request, response} =
        if Runtime.truthy(Runtime.safe_value(market, "option")) do
          response =
            Runtime.call_raw!(Raw, fetcher, "eapiprivate_delete_order", [
              Runtime.extend(request, params)
            ])

          _ = response

          {request, response}
        else
          {request, response} =
            if Runtime.truthy(Runtime.safe_value(market, "linear")) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  {response} =
                    if Runtime.truthy(is_conditional) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "papi_delete_um_conditional_order", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "papi_delete_um_order", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                else
                  {response} =
                    if Runtime.truthy(is_conditional) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "fapiprivate_delete_algoorder", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "fapiprivate_delete_order", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                end

              _ = response

              {request, response}
            else
              {request, response} =
                if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
                  {response} =
                    if Runtime.truthy(is_portfolio_margin) do
                      {response} =
                        if Runtime.truthy(is_conditional) do
                          response =
                            Runtime.call_raw!(Raw, fetcher, "papi_delete_cm_conditional_order", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {response}
                        else
                          response =
                            Runtime.call_raw!(Raw, fetcher, "papi_delete_cm_order", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {response}
                        end

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "dapiprivate_delete_order", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {request, response}
                else
                  {request, response} =
                    if Runtime.truthy(
                         Runtime.truthy(
                           Runtime.truthy(type == "margin") or Runtime.truthy(margin_mode != nil)
                         ) or Runtime.truthy(is_portfolio_margin)
                       ) do
                      {request, response} =
                        if Runtime.truthy(is_portfolio_margin) do
                          response =
                            Runtime.call_raw!(Raw, fetcher, "papi_delete_margin_order", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {request, response}
                        else
                          {request} =
                            if Runtime.truthy(margin_mode == "isolated") do
                              request = Runtime.put_value(request, "isIsolated", true)

                              {request}
                            else
                              {request}
                            end

                          _ = request

                          response =
                            Runtime.call_raw!(Raw, fetcher, "sapi_delete_margin_order", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {request, response}
                        end

                      _ = request
                      _ = response

                      {request, response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "private_delete_order", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {request, response}
                    end

                  _ = request
                  _ = response

                  {request, response}
                end

              _ = request
              _ = response

              {request, response}
            end

          _ = request
          _ = response

          {request, response}
        end

      _ = request
      _ = response

      {:ok, Runtime.call_generated!(exchange, __MODULE__, :parse_order, [response, market])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec cancel_all_orders(String.t() | nil, params(), (RawEndpoint.t(), params() ->
                                                         {:ok, map()} | {:error, term()})) ::
          {:ok, list()} | {:error, term()}
  def cancel_all_orders(symbol \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = params

    try do
      if Runtime.truthy(symbol == nil) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":arguments_required", [
             Runtime.safe_value(exchange, "id") <> " cancelAllOrders() requires a symbol argument"
           ])}
        )
      end

      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      request = %{"symbol" => Runtime.safe_value(market, "id")}
      _ = request
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "cancelAllOrders",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      is_conditional = Runtime.safe_bool_n(params, ["stop", "trigger", "conditional"])
      type = Runtime.safe_string(params, "type", Runtime.safe_value(market, "type"))
      params = Runtime.omit(params, ["type", "stop", "trigger", "conditional"])
      _ = params
      margin_mode = nil
      _ = margin_mode
      ccxt_match = Runtime.handle_margin_mode_and_params(exchange, "cancelAllOrders", params)
      margin_mode = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = margin_mode
      _ = params
      response = nil
      _ = response

      {request, response} =
        if Runtime.truthy(Runtime.safe_value(market, "option")) do
          response =
            Runtime.call_raw!(Raw, fetcher, "eapiprivate_delete_allopenorders", [
              Runtime.extend(request, params)
            ])

          _ = response

          {request, response}
        else
          {request, response} =
            if Runtime.truthy(Runtime.safe_value(market, "linear")) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  {response} =
                    if Runtime.truthy(is_conditional) do
                      response =
                        Runtime.call_raw!(
                          Raw,
                          fetcher,
                          "papi_delete_um_conditional_allopenorders",
                          [Runtime.extend(request, params)]
                        )

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "papi_delete_um_allopenorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                else
                  {response} =
                    if Runtime.truthy(is_conditional) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "fapiprivate_delete_algoopenorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "fapiprivate_delete_allopenorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                end

              _ = response

              {request, response}
            else
              {request, response} =
                if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
                  {response} =
                    if Runtime.truthy(is_portfolio_margin) do
                      {response} =
                        if Runtime.truthy(is_conditional) do
                          response =
                            Runtime.call_raw!(
                              Raw,
                              fetcher,
                              "papi_delete_cm_conditional_allopenorders",
                              [Runtime.extend(request, params)]
                            )

                          _ = response

                          {response}
                        else
                          response =
                            Runtime.call_raw!(Raw, fetcher, "papi_delete_cm_allopenorders", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {response}
                        end

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "dapiprivate_delete_allopenorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {request, response}
                else
                  {request, response} =
                    if Runtime.truthy(
                         Runtime.truthy(
                           Runtime.truthy(type == "margin") or Runtime.truthy(margin_mode != nil)
                         ) or Runtime.truthy(is_portfolio_margin)
                       ) do
                      {request, response} =
                        if Runtime.truthy(is_portfolio_margin) do
                          response =
                            Runtime.call_raw!(Raw, fetcher, "papi_delete_margin_allopenorders", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {request, response}
                        else
                          {request} =
                            if Runtime.truthy(margin_mode == "isolated") do
                              request = Runtime.put_value(request, "isIsolated", true)

                              {request}
                            else
                              {request}
                            end

                          _ = request

                          response =
                            Runtime.call_raw!(Raw, fetcher, "sapi_delete_margin_openorders", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {request, response}
                        end

                      _ = request
                      _ = response

                      {request, response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "private_delete_openorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {request, response}
                    end

                  _ = request
                  _ = response

                  {request, response}
                end

              _ = request
              _ = response

              {request, response}
            end

          _ = request
          _ = response

          {request, response}
        end

      _ = request
      _ = response

      if Runtime.truthy(Runtime.is_array(response)) do
        throw(
          {:ccxt_return,
           Runtime.parse_orders(exchange, __MODULE__, response, market, nil, nil, nil)}
        )
      else
        order = Runtime.safe_order(%{"info" => response})
        throw({:ccxt_return, [order]})
      end
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec cancel_orders(list(String.t()), String.t() | nil, params(), (RawEndpoint.t(), params() ->
                                                                       {:ok, map()}
                                                                       | {:error, term()})) ::
          {:ok, list()} | {:error, term()}
  def cancel_orders(ids, symbol \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = ids
    _ = symbol
    _ = params

    try do
      if Runtime.truthy(symbol == nil) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":arguments_required", [
             Runtime.safe_value(exchange, "id") <> " cancelOrders() requires a symbol argument"
           ])}
        )
      end

      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

      if Runtime.truthy(not Runtime.truthy(Runtime.safe_value(market, "contract"))) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":bad_request", [
             Runtime.safe_value(exchange, "id") <>
               " cancelOrders is only supported for swap markets."
           ])}
        )
      end

      request = %{"symbol" => Runtime.safe_value(market, "id")}
      _ = request

      orig_client_order_id_list =
        Runtime.safe_list2(params, "origClientOrderIdList", "clientOrderIds")

      {params, request} =
        if Runtime.truthy(orig_client_order_id_list != nil) do
          params = Runtime.omit(params, ["clientOrderIds"])
          _ = params
          request = Runtime.put_value(request, "origClientOrderIdList", orig_client_order_id_list)

          {params, request}
        else
          request = Runtime.put_value(request, "orderidlist", ids)

          {params, request}
        end

      _ = params
      _ = request

      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.safe_value(market, "linear")) do
          response =
            Runtime.call_raw!(Raw, fetcher, "fapiprivate_delete_batchorders", [
              Runtime.extend(request, params)
            ])

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
              response =
                Runtime.call_raw!(Raw, fetcher, "dapiprivate_delete_batchorders", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            else
              {response}
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, Runtime.parse_orders(exchange, __MODULE__, response, market, nil, nil, nil)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_order_trades(
          String.t(),
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_order_trades(
        id,
        symbol \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => true
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = id
    _ = symbol
    _ = since
    _ = limit
    _ = params

    try do
      if Runtime.truthy(symbol == nil) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":arguments_required", [
             Runtime.safe_value(exchange, "id") <>
               " fetchOrderTrades() requires a symbol argument"
           ])}
        )
      end

      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      type = Runtime.safe_string(params, "type", Runtime.safe_value(market, "type"))
      params = Runtime.omit(params, "type")
      _ = params

      if Runtime.truthy(type != "spot") do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " fetchOrderTrades() supports spot markets only"
           ])}
        )
      end

      request = %{"orderId" => id}

      {:ok,
       Runtime.call_generated!(exchange, __MODULE__, :fetch_my_trades, [
         symbol,
         since,
         limit,
         Runtime.extend(request, params),
         fetcher
       ])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_my_trades(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_my_trades(
        symbol \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchMyTrades" => %{"paginate" => false},
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      paginate = false
      _ = paginate
      ccxt_match = Runtime.handle_option_and_params(exchange, params, "fetchMyTrades", "paginate")
      paginate = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = paginate
      _ = params

      if Runtime.truthy(paginate) do
        throw(
          {:ccxt_return,
           Runtime.fetch_paginated_call_dynamic(
             exchange,
             __MODULE__,
             fetcher,
             "fetchMyTrades",
             symbol,
             since,
             limit,
             params
           )}
        )
      end

      request = %{}
      _ = request
      market = nil
      _ = market
      type = nil
      _ = type
      margin_mode = nil
      _ = margin_mode

      {market, request} =
        if Runtime.truthy(symbol != nil) do
          market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
          _ = market
          request = Runtime.put_value(request, "symbol", Runtime.safe_value(market, "id"))

          {market, request}
        else
          {market, request}
        end

      _ = market
      _ = request

      ccxt_match =
        Runtime.handle_market_type_and_params(exchange, "fetchMyTrades", market, params)

      type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = type
      _ = params
      end_time = Runtime.safe_integer2(params, "until", "endTime")
      _ = end_time

      {end_time, request} =
        if Runtime.truthy(since != nil) do
          start_time = since
          request = Runtime.put_value(request, "startTime", start_time)
          current_timestamp = Runtime.milliseconds(exchange)
          one_week = 7 * 24 * 60 * 60 * 1000

          {end_time} =
            if Runtime.truthy(current_timestamp - start_time >= one_week) do
              {end_time} =
                if Runtime.truthy(
                     Runtime.truthy(end_time == nil) and
                       Runtime.truthy(Runtime.safe_value(market, "linear"))
                   ) do
                  end_time = Runtime.sum(exchange, start_time, one_week)
                  _ = end_time
                  end_time = min(end_time, current_timestamp)
                  _ = end_time

                  {end_time}
                else
                  {end_time}
                end

              _ = end_time

              {end_time}
            else
              {end_time}
            end

          _ = end_time

          {end_time, request}
        else
          {end_time, request}
        end

      _ = end_time
      _ = request

      {params, request} =
        if Runtime.truthy(end_time != nil) do
          request = Runtime.put_value(request, "endTime", end_time)
          params = Runtime.omit(params, ["endTime", "until"])
          _ = params

          {params, request}
        else
          {params, request}
        end

      _ = params
      _ = request

      {limit, request} =
        if Runtime.truthy(limit != nil) do
          {limit} =
            if Runtime.truthy(
                 Runtime.truthy(type == "option") or
                   Runtime.truthy(Runtime.safe_value(market, "contract"))
               ) do
              limit = min(limit, 1000)
              _ = limit

              {limit}
            else
              {limit}
            end

          _ = limit

          request = Runtime.put_value(request, "limit", limit)

          {limit, request}
        else
          {limit, request}
        end

      _ = limit
      _ = request

      response = nil
      _ = response

      {margin_mode, params, request, response} =
        if Runtime.truthy(type == "option") do
          response =
            Runtime.call_raw!(Raw, fetcher, "eapiprivate_get_usertrades", [
              Runtime.extend(request, params)
            ])

          _ = response

          {margin_mode, params, request, response}
        else
          if Runtime.truthy(symbol == nil) do
            throw(
              {:ccxt_error,
               Runtime.new_error_reason(":arguments_required", [
                 Runtime.safe_value(exchange, "id") <>
                   " fetchMyTrades() requires a symbol argument"
               ])}
            )
          end

          ccxt_match = Runtime.handle_margin_mode_and_params(exchange, "fetchMyTrades", params)
          margin_mode = Runtime.safe_value(ccxt_match, 0, nil)
          params = Runtime.safe_value(ccxt_match, 1, nil)
          _ = margin_mode
          _ = params
          is_portfolio_margin = nil
          _ = is_portfolio_margin

          ccxt_match =
            Runtime.handle_option_and_params2(
              exchange,
              params,
              "fetchMyTrades",
              "papi",
              "portfolioMargin",
              false
            )

          is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
          params = Runtime.safe_value(ccxt_match, 1, nil)
          _ = is_portfolio_margin
          _ = params

          {request, response} =
            if Runtime.truthy(Runtime.truthy(type == "spot") or Runtime.truthy(type == "margin")) do
              {request, response} =
                if Runtime.truthy(is_portfolio_margin) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "papi_get_margin_mytrades", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {request, response}
                else
                  {request, response} =
                    if Runtime.truthy(
                         Runtime.truthy(type == "margin") or Runtime.truthy(margin_mode != nil)
                       ) do
                      {request} =
                        if Runtime.truthy(margin_mode == "isolated") do
                          request = Runtime.put_value(request, "isIsolated", true)

                          {request}
                        else
                          {request}
                        end

                      _ = request

                      response =
                        Runtime.call_raw!(Raw, fetcher, "sapi_get_margin_mytrades", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {request, response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "private_get_mytrades", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {request, response}
                    end

                  _ = request
                  _ = response

                  {request, response}
                end

              _ = request
              _ = response

              {request, response}
            else
              {response} =
                if Runtime.truthy(Runtime.safe_value(market, "linear")) do
                  {response} =
                    if Runtime.truthy(is_portfolio_margin) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "papi_get_um_usertrades", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_usertrades", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                else
                  {response} =
                    if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
                      {response} =
                        if Runtime.truthy(is_portfolio_margin) do
                          response =
                            Runtime.call_raw!(Raw, fetcher, "papi_get_cm_usertrades", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {response}
                        else
                          response =
                            Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_usertrades", [
                              Runtime.extend(request, params)
                            ])

                          _ = response

                          {response}
                        end

                      _ = response

                      {response}
                    else
                      {response}
                    end

                  _ = response

                  {response}
                end

              _ = response

              {request, response}
            end

          _ = request
          _ = response

          {margin_mode, params, request, response}
        end

      _ = margin_mode
      _ = params
      _ = request
      _ = response

      {:ok, Runtime.parse_trades(exchange, __MODULE__, response, market, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_my_dust_trades(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_my_dust_trades(
        symbol \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      request = %{}
      _ = request

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)

          request =
            Runtime.put_value(request, "endTime", Runtime.sum(exchange, since, 7_776_000_000))

          {request}
        else
          {request}
        end

      _ = request

      account_type = Runtime.safe_string_upper(params, "type")
      params = Runtime.omit(params, "type")
      _ = params

      {request} =
        if Runtime.truthy(account_type != nil) do
          request = Runtime.put_value(request, "accountType", account_type)

          {request}
        else
          {request}
        end

      _ = request

      response =
        Runtime.call_raw!(Raw, fetcher, "sapi_get_asset_dribblet", [
          Runtime.extend(request, params)
        ])

      results = Runtime.safe_list(response, "userAssetDribblets", [])
      rows = Runtime.safe_integer(response, "total", 0)
      data = []
      _ = data

      {data} =
        Enum.reduce_while(Runtime.index_range(rows, 0), {data}, fn i, {data} ->
          try do
            logs =
              Runtime.safe_list(Runtime.safe_value(results, i), "userAssetDribbletDetails", [])

            _ = logs

            {data, logs} =
              Enum.reduce_while(
                Runtime.index_range(Runtime.js_length(logs), 0),
                {data, logs},
                fn j, {data, logs} ->
                  try do
                    logs =
                      Runtime.put_value(
                        logs,
                        j,
                        Runtime.put_value(Runtime.safe_value(logs, j, %{}), "isDustTrade", true)
                      )

                    data = Runtime.push(data, Runtime.safe_value(logs, j))
                    {:cont, {data, logs}}
                  catch
                    :continue -> {:cont, {data, logs}}
                    :break -> {:halt, {data, logs}}
                  end
                end
              )

            _ = data
            _ = logs
            {:cont, {data}}
          catch
            :continue -> {:cont, {data}}
            :break -> {:halt, {data}}
          end
        end)

      _ = data
      trades = Runtime.parse_trades(exchange, __MODULE__, data, nil, since, limit)
      {:ok, Runtime.filter_by_since_limit(trades, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_dust_trade(params(), params(), (RawEndpoint.t(), params() ->
                                                {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def parse_dust_trade(trade, market \\ nil, fetcher \\ &default_fetcher/2) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{}}, %{})
    _ = exchange
    _ = fetcher
    _ = trade
    _ = market

    try do
      order_id = Runtime.safe_string(trade, "transId")
      timestamp = Runtime.safe_integer(trade, "operateTime")
      currency_id = Runtime.safe_string(trade, "fromAsset")
      traded_currency = Runtime.safe_currency_code(currency_id)
      bnb = Runtime.currency(exchange, "BNB")
      earned_currency = Runtime.safe_value(bnb, "code")
      applicant_symbol = earned_currency <> "/" <> traded_currency
      traded_currency_is_quote = false
      _ = traded_currency_is_quote

      {traded_currency_is_quote} =
        if Runtime.truthy(Runtime.has_key?(Runtime.markets(exchange), applicant_symbol)) do
          traded_currency_is_quote = true
          _ = traded_currency_is_quote

          {traded_currency_is_quote}
        else
          {traded_currency_is_quote}
        end

      _ = traded_currency_is_quote

      fee_cost_string = Runtime.safe_string(trade, "serviceChargeAmount")
      fee = %{"currency" => earned_currency, "cost" => Runtime.parse_number(fee_cost_string)}
      symbol = nil
      _ = symbol
      amount_string = nil
      _ = amount_string
      cost_string = nil
      _ = cost_string
      side = nil
      _ = side

      {amount_string, cost_string, side, symbol} =
        if Runtime.truthy(traded_currency_is_quote) do
          symbol = applicant_symbol
          _ = symbol
          amount_string = Runtime.safe_string(trade, "transferedAmount")
          _ = amount_string
          cost_string = Runtime.safe_string(trade, "amount")
          _ = cost_string
          side = "buy"
          _ = side

          {amount_string, cost_string, side, symbol}
        else
          symbol = traded_currency <> "/" <> earned_currency
          _ = symbol
          amount_string = Runtime.safe_string(trade, "amount")
          _ = amount_string
          cost_string = Runtime.safe_string(trade, "transferedAmount")
          _ = cost_string
          side = "sell"
          _ = side

          {amount_string, cost_string, side, symbol}
        end

      _ = amount_string
      _ = cost_string
      _ = side
      _ = symbol

      price_string = nil
      _ = price_string

      {price_string} =
        if Runtime.truthy(cost_string != nil) do
          {price_string} =
            if Runtime.truthy(amount_string) do
              price_string = Runtime.divide_number_string(cost_string, amount_string)
              _ = price_string

              {price_string}
            else
              {price_string}
            end

          _ = price_string

          {price_string}
        else
          {price_string}
        end

      _ = price_string

      id = nil
      amount = Runtime.parse_number(amount_string)
      price = Runtime.parse_number(price_string)
      cost = Runtime.parse_number(cost_string)
      type = nil
      taker_or_maker = nil

      {:ok,
       %{
         id: id,
         timestamp: timestamp,
         datetime: Runtime.iso8601(timestamp),
         symbol: symbol,
         order: order_id,
         type: type,
         takerOrMaker: taker_or_maker,
         side: side,
         amount: amount,
         price: price,
         cost: cost,
         fee: fee,
         info: trade
       }}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_deposits(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_deposits(
        code \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchDeposits" => %{"paginate" => false},
            "legalMoney" => %{},
            "legalMoneyCurrenciesById" => %{},
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      paginate = false
      _ = paginate
      ccxt_match = Runtime.handle_option_and_params(exchange, params, "fetchDeposits", "paginate")
      paginate = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = paginate
      _ = params

      if Runtime.truthy(paginate) do
        throw(
          {:ccxt_return,
           Runtime.fetch_paginated_call_dynamic(
             exchange,
             __MODULE__,
             fetcher,
             "fetchDeposits",
             code,
             since,
             limit,
             params
           )}
        )
      end

      currency = nil
      _ = currency
      response = nil
      _ = response
      request = %{}
      _ = request
      legal_money = Runtime.safe_dict(Runtime.safe_value(exchange, "options"), "legalMoney", %{})
      fiat_only = Runtime.safe_bool(params, "fiat", false)
      params = Runtime.omit(params, "fiatOnly")
      _ = params
      until = Runtime.safe_integer(params, "until")
      params = Runtime.omit(params, "until")
      _ = params

      {currency, request, response} =
        if Runtime.truthy(
             Runtime.truthy(fiat_only) or Runtime.truthy(Runtime.has_key?(legal_money, code))
           ) do
          {currency} =
            if Runtime.truthy(code != nil) do
              currency = Runtime.currency(exchange, code)
              _ = currency

              {currency}
            else
              {currency}
            end

          _ = currency

          request = Runtime.put_value(request, "transactionType", 0)

          {request} =
            if Runtime.truthy(since != nil) do
              request = Runtime.put_value(request, "beginTime", since)

              {request}
            else
              {request}
            end

          _ = request

          {request} =
            if Runtime.truthy(until != nil) do
              request = Runtime.put_value(request, "endTime", until)

              {request}
            else
              {request}
            end

          _ = request

          raw =
            Runtime.call_raw!(Raw, fetcher, "sapi_get_fiat_orders", [
              Runtime.extend(request, params)
            ])

          response = Runtime.safe_list(raw, "data", [])
          _ = response

          {currency, request, response}
        else
          {currency, request} =
            if Runtime.truthy(code != nil) do
              currency = Runtime.currency(exchange, code)
              _ = currency
              request = Runtime.put_value(request, "coin", Runtime.safe_value(currency, "id"))

              {currency, request}
            else
              {currency, request}
            end

          _ = currency
          _ = request

          {request} =
            if Runtime.truthy(since != nil) do
              request = Runtime.put_value(request, "startTime", since)
              end_time = Runtime.sum(exchange, since, 7_776_000_000)
              _ = end_time

              {end_time} =
                if Runtime.truthy(until != nil) do
                  end_time = min(end_time, until)
                  _ = end_time

                  {end_time}
                else
                  {end_time}
                end

              _ = end_time

              request = Runtime.put_value(request, "endTime", end_time)

              {request}
            else
              {request}
            end

          _ = request

          {request} =
            if Runtime.truthy(limit != nil) do
              request = Runtime.put_value(request, "limit", limit)

              {request}
            else
              {request}
            end

          _ = request

          response =
            Runtime.call_raw!(Raw, fetcher, "sapi_get_capital_deposit_hisrec", [
              Runtime.extend(request, params)
            ])

          _ = response

          {currency, request, response}
        end

      _ = currency
      _ = request
      _ = response

      {response} =
        Enum.reduce_while(Runtime.index_range(Runtime.js_length(response), 0), {response}, fn i,
                                                                                              {response} ->
          try do
            response =
              Runtime.put_value(
                response,
                i,
                Runtime.put_value(Runtime.safe_value(response, i, %{}), "type", "deposit")
              )

            {:cont, {response}}
          catch
            :continue -> {:cont, {response}}
            :break -> {:halt, {response}}
          end
        end)

      _ = response
      {:ok, Runtime.parse_transactions(exchange, __MODULE__, response, currency, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_withdrawals(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_withdrawals(
        code \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchWithdrawals" => %{"paginate" => false},
            "legalMoney" => %{},
            "legalMoneyCurrenciesById" => %{},
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      paginate = false
      _ = paginate

      ccxt_match =
        Runtime.handle_option_and_params(exchange, params, "fetchWithdrawals", "paginate")

      paginate = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = paginate
      _ = params

      if Runtime.truthy(paginate) do
        throw(
          {:ccxt_return,
           Runtime.fetch_paginated_call_dynamic(
             exchange,
             __MODULE__,
             fetcher,
             "fetchWithdrawals",
             code,
             since,
             limit,
             params
           )}
        )
      end

      legal_money = Runtime.safe_dict(Runtime.safe_value(exchange, "options"), "legalMoney", %{})
      fiat_only = Runtime.safe_bool(params, "fiat", false)
      params = Runtime.omit(params, "fiatOnly")
      _ = params
      request = %{}
      _ = request
      until = Runtime.safe_integer(params, "until")

      {params, request} =
        if Runtime.truthy(until != nil) do
          params = Runtime.omit(params, "until")
          _ = params
          request = Runtime.put_value(request, "endTime", until)

          {params, request}
        else
          {params, request}
        end

      _ = params
      _ = request

      response = nil
      _ = response
      currency = nil
      _ = currency

      {currency, request, response} =
        if Runtime.truthy(
             Runtime.truthy(fiat_only) or Runtime.truthy(Runtime.has_key?(legal_money, code))
           ) do
          {currency} =
            if Runtime.truthy(code != nil) do
              currency = Runtime.currency(exchange, code)
              _ = currency

              {currency}
            else
              {currency}
            end

          _ = currency

          request = Runtime.put_value(request, "transactionType", 1)

          {request} =
            if Runtime.truthy(since != nil) do
              request = Runtime.put_value(request, "beginTime", since)

              {request}
            else
              {request}
            end

          _ = request

          raw =
            Runtime.call_raw!(Raw, fetcher, "sapi_get_fiat_orders", [
              Runtime.extend(request, params)
            ])

          response = Runtime.safe_list(raw, "data", [])
          _ = response

          {currency, request, response}
        else
          {currency, request} =
            if Runtime.truthy(code != nil) do
              currency = Runtime.currency(exchange, code)
              _ = currency
              request = Runtime.put_value(request, "coin", Runtime.safe_value(currency, "id"))

              {currency, request}
            else
              {currency, request}
            end

          _ = currency
          _ = request

          {request} =
            if Runtime.truthy(since != nil) do
              request = Runtime.put_value(request, "startTime", since)

              request =
                Runtime.put_value(request, "endTime", Runtime.sum(exchange, since, 7_776_000_000))

              {request}
            else
              {request}
            end

          _ = request

          {request} =
            if Runtime.truthy(limit != nil) do
              request = Runtime.put_value(request, "limit", limit)

              {request}
            else
              {request}
            end

          _ = request

          response =
            Runtime.call_raw!(Raw, fetcher, "sapi_get_capital_withdraw_history", [
              Runtime.extend(request, params)
            ])

          _ = response

          {currency, request, response}
        end

      _ = currency
      _ = request
      _ = response

      {response} =
        Enum.reduce_while(Runtime.index_range(Runtime.js_length(response), 0), {response}, fn i,
                                                                                              {response} ->
          try do
            response =
              Runtime.put_value(
                response,
                i,
                Runtime.put_value(Runtime.safe_value(response, i, %{}), "type", "withdrawal")
              )

            {:cont, {response}}
          catch
            :continue -> {:cont, {response}}
            :break -> {:halt, {response}}
          end
        end)

      _ = response
      {:ok, Runtime.parse_transactions(exchange, __MODULE__, response, currency, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_transaction_status_by_type(params(), params(), (RawEndpoint.t(), params() ->
                                                                {:ok, map()} | {:error, term()})) ::
          {:ok, String.t() | nil} | {:error, term()}
  def parse_transaction_status_by_type(status, type \\ nil, fetcher \\ &default_fetcher/2) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{}}, %{})
    _ = exchange
    _ = fetcher
    _ = status
    _ = type

    try do
      if Runtime.truthy(type == nil) do
        throw({:ccxt_return, status})
      end

      statuses_by_type = %{
        "deposit" => %{
          "0" => "pending",
          "1" => "ok",
          "6" => "ok",
          "Processing" => "pending",
          "Failed" => "failed",
          "Successful" => "ok",
          "Refunding" => "canceled",
          "Refunded" => "canceled",
          "Refund Failed" => "failed"
        },
        "withdrawal" => %{
          "0" => "pending",
          "1" => "canceled",
          "2" => "pending",
          "3" => "failed",
          "4" => "pending",
          "5" => "failed",
          "6" => "ok",
          "Processing" => "pending",
          "Failed" => "failed",
          "Successful" => "ok",
          "Refunding" => "canceled",
          "Refunded" => "canceled",
          "Refund Failed" => "failed"
        }
      }

      statuses = Runtime.safe_dict(statuses_by_type, type, %{})
      {:ok, Runtime.safe_string(statuses, status, status)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_transaction(term(), term(), term()) :: term()
  def parse_transaction(exchange, transaction, currency \\ nil) do
    _ = exchange
    _ = transaction
    _ = currency

    try do
      id = Runtime.safe_string2(transaction, "id", "orderNo")
      address = Runtime.safe_string(transaction, "address")
      tag = Runtime.safe_string(transaction, "addressTag")
      _ = tag

      {tag} =
        if Runtime.truthy(tag != nil) do
          {tag} =
            if Runtime.truthy(Runtime.js_length(tag) < 1) do
              tag = nil
              _ = tag

              {tag}
            else
              {tag}
            end

          _ = tag

          {tag}
        else
          {tag}
        end

      _ = tag

      txid = Runtime.safe_string(transaction, "txId")
      _ = txid

      {txid} =
        if Runtime.truthy(
             Runtime.truthy(txid != nil) and
               Runtime.truthy(Runtime.index_of(txid, "Internal transfer ") >= 0)
           ) do
          txid = Runtime.slice(txid, 18)
          _ = txid

          {txid}
        else
          {txid}
        end

      _ = txid

      currency_id = Runtime.safe_string2(transaction, "coin", "fiatCurrency")
      code = Runtime.safe_currency_code(currency_id, currency)
      _ = code
      timestamp = nil
      _ = timestamp
      timestamp = Runtime.safe_integer2(transaction, "insertTime", "createTime")
      _ = timestamp

      {timestamp} =
        if Runtime.truthy(timestamp == nil) do
          timestamp = Runtime.parse8601(Runtime.safe_string(transaction, "applyTime"))
          _ = timestamp

          {timestamp}
        else
          {timestamp}
        end

      _ = timestamp

      updated = Runtime.safe_integer2(transaction, "successTime", "updateTime")
      type = Runtime.safe_string(transaction, "type")
      _ = type

      {code, type} =
        if Runtime.truthy(type == nil) do
          tx_type = Runtime.safe_string(transaction, "transactionType")

          {type} =
            if Runtime.truthy(tx_type != nil) do
              type =
                if(
                  Runtime.truthy(tx_type == "0"),
                  do: "deposit",
                  else: "withdrawal"
                )

              _ = type

              {type}
            else
              {type}
            end

          _ = type

          legal_money_currencies_by_id =
            Runtime.safe_dict(Runtime.safe_value(exchange, "options"), "legalMoneyCurrenciesById")

          code = Runtime.safe_string(legal_money_currencies_by_id, code, code)
          _ = code

          {code, type}
        else
          {code, type}
        end

      _ = code
      _ = type

      status =
        Runtime.call_generated!(__MODULE__, :parse_transaction_status_by_type, [
          Runtime.safe_string(transaction, "status"),
          type
        ])

      amount = Runtime.safe_number(transaction, "amount")
      fee_cost = Runtime.safe_number2(transaction, "transactionFee", "totalFee")
      fee = nil
      _ = fee

      {fee} =
        if Runtime.truthy(fee_cost != nil) do
          fee = %{currency: code, cost: fee_cost}
          _ = fee

          {fee}
        else
          {fee}
        end

      _ = fee

      internal_integer = Runtime.safe_integer(transaction, "transferType")
      internal = nil
      _ = internal

      {internal} =
        if Runtime.truthy(internal_integer != nil) do
          internal =
            if(
              Runtime.truthy(internal_integer != 0),
              do: true,
              else: false
            )

          _ = internal

          {internal}
        else
          {internal}
        end

      _ = internal

      network_id = Runtime.safe_string(transaction, "network")
      network = Runtime.network_id_to_code(network_id, code)

      throw(
        {:ccxt_return,
         %{
           info: transaction,
           id: id,
           txid: txid,
           timestamp: timestamp,
           datetime: Runtime.iso8601(timestamp),
           network: network,
           address: address,
           addressTo: address,
           addressFrom: nil,
           tag: tag,
           tagTo: tag,
           tagFrom: nil,
           type: type,
           amount: amount,
           currency: code,
           status: status,
           updated: updated,
           internal: internal,
           comment: nil,
           fee: fee
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec parse_transfer_status(String.t(), (RawEndpoint.t(), params() ->
                                             {:ok, map()} | {:error, term()})) ::
          {:ok, String.t() | nil} | {:error, term()}
  def parse_transfer_status(status, fetcher \\ &default_fetcher/2) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{}}, %{})
    _ = exchange
    _ = fetcher
    _ = status

    try do
      statuses = %{"CONFIRMED" => "ok"}
      {:ok, Runtime.safe_string(statuses, status, status)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_transfer(params(), params(), (RawEndpoint.t(), params() ->
                                              {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def parse_transfer(transfer, currency \\ nil, fetcher \\ &default_fetcher/2) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{}}, %{})
    _ = exchange
    _ = fetcher
    _ = transfer
    _ = currency

    try do
      id = Runtime.safe_string2(transfer, "tranId", "transactionId")
      currency_id = Runtime.safe_string2(transfer, "asset", "currency")
      code = Runtime.safe_currency_code(currency_id, currency)
      amount = Runtime.safe_number(transfer, "amount")
      type = Runtime.safe_string(transfer, "type")
      from_account = nil
      _ = from_account
      to_account = nil
      _ = to_account

      accounts_by_id =
        Runtime.safe_dict(Runtime.safe_value(exchange, "options"), "accountsById", %{})

      {from_account, to_account} =
        if Runtime.truthy(type != nil) do
          parts = Runtime.string_split(type, "_")
          from_account = Runtime.safe_value(parts, 0)
          _ = from_account
          to_account = Runtime.safe_value(parts, 1)
          _ = to_account
          from_account = Runtime.safe_string(accounts_by_id, from_account, from_account)
          _ = from_account
          to_account = Runtime.safe_string(accounts_by_id, to_account, to_account)
          _ = to_account

          {from_account, to_account}
        else
          {from_account, to_account}
        end

      _ = from_account
      _ = to_account

      wallet_type = Runtime.safe_integer(transfer, "walletType")

      {from_account, to_account} =
        if Runtime.truthy(wallet_type != nil) do
          payer = Runtime.safe_dict(transfer, "payerInfo", %{})
          receiver = Runtime.safe_dict(transfer, "receiverInfo", %{})
          from_account = Runtime.safe_string(payer, "accountId")
          _ = from_account
          to_account = Runtime.safe_string(receiver, "accountId")
          _ = to_account

          {from_account, to_account}
        else
          {from_account, to_account}
        end

      _ = from_account
      _ = to_account

      timestamp = Runtime.safe_integer2(transfer, "timestamp", "transactionTime")

      status =
        Runtime.call_generated!(__MODULE__, :parse_transfer_status, [
          Runtime.safe_string(transfer, "status")
        ])

      {:ok,
       %{
         info: transfer,
         id: id,
         timestamp: timestamp,
         datetime: Runtime.iso8601(timestamp),
         currency: code,
         amount: amount,
         fromAccount: from_account,
         toAccount: to_account,
         status: status
       }}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_income(term(), term(), term()) :: term()
  def parse_income(exchange, income, market \\ nil) do
    _ = exchange
    _ = income
    _ = market

    try do
      market_id = Runtime.safe_string(income, "symbol")
      currency_id = Runtime.safe_string(income, "asset")
      timestamp = Runtime.safe_integer(income, "time")

      throw(
        {:ccxt_return,
         %{
           "info" => income,
           "symbol" => Runtime.safe_symbol(exchange, market_id, market, nil, "swap"),
           "code" => Runtime.safe_currency_code(currency_id),
           "timestamp" => timestamp,
           "datetime" => Runtime.iso8601(timestamp),
           "id" => Runtime.safe_string(income, "tranId"),
           "amount" => Runtime.safe_number(income, "income")
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec transfer(String.t(), number(), String.t(), String.t(), params(), (RawEndpoint.t(),
                                                                          params() ->
                                                                            {:ok, map()}
                                                                            | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def transfer(
        code,
        amount,
        from_account,
        to_account,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false,
            "accountsByType" => %{
              "spot" => "MAIN",
              "funding" => "FUNDING",
              "margin" => "MARGIN",
              "cross" => "MARGIN",
              "future" => "UMFUTURE",
              "delivery" => "CMFUTURE",
              "linear" => "UMFUTURE",
              "swap" => "UMFUTURE",
              "inverse" => "CMFUTURE",
              "option" => "OPTION"
            },
            "accountsById" => %{
              "MAIN" => "spot",
              "FUNDING" => "funding",
              "MARGIN" => "margin",
              "UMFUTURE" => "linear",
              "CMFUTURE" => "inverse",
              "OPTION" => "option"
            }
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = amount
    _ = from_account
    _ = to_account
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      currency = Runtime.currency(exchange, code)

      request = %{
        "asset" => Runtime.safe_value(currency, "id"),
        "amount" => Runtime.currency_to_precision(exchange, code, amount)
      }

      _ = request
      request = Runtime.put_value(request, "type", Runtime.safe_string(params, "type"))
      params = Runtime.omit(params, "type")
      _ = params

      {params, request} =
        if Runtime.truthy(Runtime.safe_value(request, "type") == nil) do
          symbol = Runtime.safe_string(params, "symbol")
          market = nil
          _ = market

          {market, params} =
            if Runtime.truthy(symbol != nil) do
              market =
                Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

              _ = market
              params = Runtime.omit(params, "symbol")
              _ = params

              {market, params}
            else
              {market, params}
            end

          _ = market
          _ = params

          from_id = Runtime.upcase(Runtime.convert_type_to_account(exchange, from_account))
          _ = from_id
          to_id = Runtime.upcase(Runtime.convert_type_to_account(exchange, to_account))
          _ = to_id
          isolated_symbol = nil
          _ = isolated_symbol

          {isolated_symbol} =
            if Runtime.truthy(market != nil) do
              isolated_symbol = Runtime.safe_value(market, "id")
              _ = isolated_symbol

              {isolated_symbol}
            else
              {isolated_symbol}
            end

          _ = isolated_symbol

          if Runtime.truthy(from_id == "ISOLATED") do
            if Runtime.truthy(symbol == nil) do
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":arguments_required", [
                   Runtime.safe_value(exchange, "id") <>
                     " transfer () requires params[\"symbol\"] when fromAccount is " <>
                     from_account
                 ])}
              )
            end
          end

          if Runtime.truthy(to_id == "ISOLATED") do
            if Runtime.truthy(symbol == nil) do
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":arguments_required", [
                   Runtime.safe_value(exchange, "id") <>
                     " transfer () requires params[\"symbol\"] when toAccount is " <> to_account
                 ])}
              )
            end
          end

          accounts_by_id =
            Runtime.safe_dict(Runtime.safe_value(exchange, "options"), "accountsById", %{})

          from_isolated = not Runtime.truthy(Runtime.has_key?(accounts_by_id, from_id))
          to_isolated = not Runtime.truthy(Runtime.has_key?(accounts_by_id, to_id))

          {isolated_symbol} =
            if Runtime.truthy(Runtime.truthy(from_isolated) and Runtime.truthy(market == nil)) do
              isolated_symbol = from_id
              _ = isolated_symbol

              {isolated_symbol}
            else
              {isolated_symbol}
            end

          _ = isolated_symbol

          {isolated_symbol} =
            if Runtime.truthy(Runtime.truthy(to_isolated) and Runtime.truthy(market == nil)) do
              isolated_symbol = to_id
              _ = isolated_symbol

              {isolated_symbol}
            else
              {isolated_symbol}
            end

          _ = isolated_symbol

          {from_id, request, to_id} =
            if Runtime.truthy(Runtime.truthy(from_isolated) or Runtime.truthy(to_isolated)) do
              from_future =
                Runtime.truthy(from_id == "UMFUTURE") or Runtime.truthy(from_id == "CMFUTURE")

              to_future =
                Runtime.truthy(to_id == "UMFUTURE") or Runtime.truthy(to_id == "CMFUTURE")

              from_spot = from_id == "MAIN"
              to_spot = to_id == "MAIN"
              funding = Runtime.truthy(from_id == "FUNDING") or Runtime.truthy(to_id == "FUNDING")
              option = Runtime.truthy(from_id == "OPTION") or Runtime.truthy(to_id == "OPTION")

              prohibited_with_isolated =
                Runtime.truthy(
                  Runtime.truthy(Runtime.truthy(from_future) or Runtime.truthy(to_future)) or
                    Runtime.truthy(funding)
                ) or Runtime.truthy(option)

              {from_id, request, to_id} =
                if Runtime.truthy(
                     Runtime.truthy(Runtime.truthy(from_isolated) or Runtime.truthy(to_isolated)) and
                       Runtime.truthy(prohibited_with_isolated)
                   ) do
                  throw(
                    {:ccxt_error,
                     Runtime.new_error_reason(":bad_request", [
                       Runtime.safe_value(exchange, "id") <>
                         " transfer () does not allow transfers between " <>
                         from_account <> " and " <> to_account
                     ])}
                  )
                else
                  {from_id, request, to_id} =
                    if Runtime.truthy(Runtime.truthy(to_spot) and Runtime.truthy(from_isolated)) do
                      from_id = "ISOLATED_MARGIN"
                      _ = from_id
                      request = Runtime.put_value(request, "fromSymbol", isolated_symbol)

                      {from_id, request, to_id}
                    else
                      {from_id, request, to_id} =
                        if Runtime.truthy(
                             Runtime.truthy(from_spot) and Runtime.truthy(to_isolated)
                           ) do
                          to_id = "ISOLATED_MARGIN"
                          _ = to_id
                          request = Runtime.put_value(request, "toSymbol", isolated_symbol)

                          {from_id, request, to_id}
                        else
                          {from_id, request, to_id} =
                            if Runtime.truthy(
                                 Runtime.truthy(from_isolated) and Runtime.truthy(to_isolated)
                               ) do
                              request = Runtime.put_value(request, "fromSymbol", from_id)
                              request = Runtime.put_value(request, "toSymbol", to_id)
                              from_id = "ISOLATEDMARGIN"
                              _ = from_id
                              to_id = "ISOLATEDMARGIN"
                              _ = to_id

                              {from_id, request, to_id}
                            else
                              {from_id, request} =
                                if Runtime.truthy(from_isolated) do
                                  request =
                                    Runtime.put_value(request, "fromSymbol", isolated_symbol)

                                  from_id = "ISOLATEDMARGIN"
                                  _ = from_id

                                  {from_id, request}
                                else
                                  {from_id, request}
                                end

                              _ = from_id
                              _ = request

                              {request, to_id} =
                                if Runtime.truthy(to_isolated) do
                                  request =
                                    Runtime.put_value(request, "toSymbol", isolated_symbol)

                                  to_id = "ISOLATEDMARGIN"
                                  _ = to_id

                                  {request, to_id}
                                else
                                  {request, to_id}
                                end

                              _ = request
                              _ = to_id

                              {from_id, request, to_id}
                            end

                          _ = from_id
                          _ = request
                          _ = to_id

                          {from_id, request, to_id}
                        end

                      _ = from_id
                      _ = request
                      _ = to_id

                      {from_id, request, to_id}
                    end

                  _ = from_id
                  _ = request
                  _ = to_id

                  {from_id, request, to_id}
                end

              _ = from_id
              _ = request
              _ = to_id

              request = Runtime.put_value(request, "type", from_id <> "_" <> to_id)

              {from_id, request, to_id}
            else
              request = Runtime.put_value(request, "type", from_id <> "_" <> to_id)

              {from_id, request, to_id}
            end

          _ = from_id
          _ = request
          _ = to_id

          {params, request}
        else
          {params, request}
        end

      _ = params
      _ = request

      response =
        Runtime.call_raw!(Raw, fetcher, "sapi_post_asset_transfer", [
          Runtime.extend(request, params)
        ])

      {:ok, Runtime.call_generated!(__MODULE__, :parse_transfer, [response, currency])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_transfers(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_transfers(
        code \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchTransfers" => %{"defaultType" => "spot", "paginate" => false},
            "accountsByType" => %{
              "main" => "MAIN",
              "spot" => "MAIN",
              "funding" => "FUNDING",
              "margin" => "MARGIN",
              "cross" => "MARGIN",
              "future" => "UMFUTURE",
              "delivery" => "CMFUTURE",
              "linear" => "UMFUTURE",
              "swap" => "UMFUTURE",
              "inverse" => "CMFUTURE",
              "option" => "OPTION"
            },
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      internal = Runtime.safe_bool(params, "internal")
      params = Runtime.omit(params, "internal")
      _ = params
      paginate = false
      _ = paginate

      ccxt_match =
        Runtime.handle_option_and_params(exchange, params, "fetchTransfers", "paginate")

      paginate = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = paginate
      _ = params

      if Runtime.truthy(Runtime.truthy(paginate) and Runtime.truthy(not Runtime.truthy(internal))) do
        throw(
          {:ccxt_return,
           Runtime.fetch_paginated_call_dynamic(
             exchange,
             __MODULE__,
             fetcher,
             "fetchTransfers",
             code,
             since,
             limit,
             params
           )}
        )
      end

      currency = nil
      _ = currency

      {currency} =
        if Runtime.truthy(code != nil) do
          currency = Runtime.currency(exchange, code)
          _ = currency

          {currency}
        else
          {currency}
        end

      _ = currency

      request = %{}
      _ = request
      limit_key = "limit"
      _ = limit_key

      {limit_key, request} =
        if Runtime.truthy(not Runtime.truthy(internal)) do
          default_type =
            Runtime.safe_string2(
              Runtime.safe_value(exchange, "options"),
              "fetchTransfers",
              "defaultType",
              "spot"
            )

          from_account = Runtime.safe_string(params, "fromAccount", default_type)

          default_to =
            if(
              Runtime.truthy(from_account == "future"),
              do: "spot",
              else: "future"
            )

          to_account = Runtime.safe_string(params, "toAccount", default_to)
          type = Runtime.safe_string(params, "type")
          _ = type

          accounts_by_type =
            Runtime.safe_dict(Runtime.safe_value(exchange, "options"), "accountsByType", %{})

          from_id = Runtime.safe_string(accounts_by_type, from_account)
          to_id = Runtime.safe_string(accounts_by_type, to_account)

          {type} =
            if Runtime.truthy(type == nil) do
              if Runtime.truthy(from_id == nil) do
                keys = Runtime.object_keys(accounts_by_type)

                throw(
                  {:ccxt_error,
                   Runtime.new_error_reason(":exchange_error", [
                     Runtime.safe_value(exchange, "id") <>
                       " fromAccount parameter must be one of " <> Runtime.join(keys, ", ")
                   ])}
                )
              end

              if Runtime.truthy(to_id == nil) do
                keys = Runtime.object_keys(accounts_by_type)

                throw(
                  {:ccxt_error,
                   Runtime.new_error_reason(":exchange_error", [
                     Runtime.safe_value(exchange, "id") <>
                       " toAccount parameter must be one of " <> Runtime.join(keys, ", ")
                   ])}
                )
              end

              type = from_id <> "_" <> to_id
              _ = type

              {type}
            else
              {type}
            end

          _ = type

          request = Runtime.put_value(request, "type", type)
          limit_key = "size"
          _ = limit_key

          {limit_key, request}
        else
          {limit_key, request}
        end

      _ = limit_key
      _ = request

      {request} =
        if Runtime.truthy(limit != nil) do
          request = Runtime.put_value(request, limit_key, limit)

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)

          {request}
        else
          {request}
        end

      _ = request

      until = Runtime.safe_integer(params, "until")

      {params, request} =
        if Runtime.truthy(until != nil) do
          params = Runtime.omit(params, "until")
          _ = params
          request = Runtime.put_value(request, "endTime", until)

          {params, request}
        else
          {params, request}
        end

      _ = params
      _ = request

      response = nil
      _ = response

      {response} =
        if Runtime.truthy(internal) do
          response =
            Runtime.call_raw!(Raw, fetcher, "sapi_get_pay_transactions", [
              Runtime.extend(request, params)
            ])

          _ = response

          {response}
        else
          response =
            Runtime.call_raw!(Raw, fetcher, "sapi_get_asset_transfer", [
              Runtime.extend(request, params)
            ])

          _ = response

          {response}
        end

      _ = response

      rows = Runtime.safe_list2(response, "rows", "data", [])
      {:ok, Runtime.parse_transfers(exchange, __MODULE__, rows, currency, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_deposit_address(String.t(), params(), (RawEndpoint.t(), params() ->
                                                       {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_deposit_address(code, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      currency = Runtime.currency(exchange, code)
      request = %{"coin" => Runtime.safe_value(currency, "id")}
      _ = request
      network_code = nil
      _ = network_code
      ccxt_match = Runtime.handle_network_code_and_params(params)
      network_code = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = network_code
      _ = params

      {request} =
        if Runtime.truthy(network_code != nil) do
          request =
            Runtime.put_value(
              request,
              "network",
              Runtime.network_code_to_id(network_code, Runtime.safe_value(currency, "code"))
            )

          {request}
        else
          {request}
        end

      _ = request

      response =
        Runtime.call_raw!(Raw, fetcher, "sapi_get_capital_deposit_address", [
          Runtime.extend(request, params)
        ])

      {:ok,
       Runtime.call_generated!(exchange, __MODULE__, :parse_deposit_address, [response, currency])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_deposit_address(term(), term(), term()) :: term()
  def parse_deposit_address(exchange, response, currency \\ nil) do
    _ = exchange
    _ = response
    _ = currency

    try do
      url = Runtime.safe_string(response, "url")
      address = Runtime.safe_string(response, "address")
      currency_id = Runtime.safe_string(response, "currency")
      code = Runtime.safe_currency_code(currency_id, currency)
      network_code = Runtime.get_network_code_by_network_url(code, url)
      tag = Runtime.safe_string(response, "tag", "")
      _ = tag

      {tag} =
        if Runtime.truthy(Runtime.js_length(tag) == 0) do
          tag = nil
          _ = tag

          {tag}
        else
          {tag}
        end

      _ = tag

      Runtime.check_address(address)

      throw(
        {:ccxt_return,
         %{info: response, currency: code, network: network_code, address: address, tag: tag}}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_transaction_fees(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                                    {:ok, map()}
                                                                    | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_transaction_fees(codes \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = codes
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      response = Runtime.call_raw!(Raw, fetcher, "sapi_get_capital_config_getall", [params])
      withdraw_fees = %{}
      _ = withdraw_fees

      {withdraw_fees} =
        Enum.reduce_while(
          Runtime.index_range(Runtime.js_length(response), 0),
          {withdraw_fees},
          fn i, {withdraw_fees} ->
            try do
              entry = Runtime.safe_value(response, i)
              currency_id = Runtime.safe_string(entry, "coin")
              code = Runtime.safe_currency_code(currency_id)
              network_list = Runtime.safe_list(entry, "networkList", [])
              withdraw_fees = Runtime.put_value(withdraw_fees, code, %{})

              {withdraw_fees} =
                Enum.reduce_while(
                  Runtime.index_range(Runtime.js_length(network_list), 0),
                  {withdraw_fees},
                  fn j, {withdraw_fees} ->
                    try do
                      network_entry = Runtime.safe_value(network_list, j)
                      network_id = Runtime.safe_string(network_entry, "network")
                      network_code = Runtime.safe_currency_code(network_id)
                      fee = Runtime.safe_number(network_entry, "withdrawFee")

                      withdraw_fees =
                        Runtime.put_value(
                          withdraw_fees,
                          code,
                          Runtime.put_value(
                            Runtime.safe_value(withdraw_fees, code, %{}),
                            network_code,
                            fee
                          )
                        )

                      {:cont, {withdraw_fees}}
                    catch
                      :continue -> {:cont, {withdraw_fees}}
                      :break -> {:halt, {withdraw_fees}}
                    end
                  end
                )

              _ = withdraw_fees
              {:cont, {withdraw_fees}}
            catch
              :continue -> {:cont, {withdraw_fees}}
              :break -> {:halt, {withdraw_fees}}
            end
          end
        )

      _ = withdraw_fees
      {:ok, %{withdraw: withdraw_fees, deposit: %{}, info: response}}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_deposit_withdraw_fees(list(String.t()) | nil, params(), (RawEndpoint.t(),
                                                                       params() ->
                                                                         {:ok, map()}
                                                                         | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_deposit_withdraw_fees(codes \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = codes
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      response = Runtime.call_raw!(Raw, fetcher, "sapi_get_capital_config_getall", [params])
      {:ok, Runtime.parse_deposit_withdraw_fees(exchange, __MODULE__, response, codes, "coin")}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_deposit_withdraw_fee(term(), term(), term()) :: term()
  def parse_deposit_withdraw_fee(exchange, fee, currency \\ nil) do
    _ = exchange
    _ = fee
    _ = currency

    try do
      code = Runtime.safe_string(currency, "code")
      network_list = Runtime.safe_list(fee, "networkList", [])
      result = Runtime.deposit_withdraw_fee(exchange, fee)
      _ = result

      {result} =
        Enum.reduce_while(Runtime.index_range(Runtime.js_length(network_list), 0), {result}, fn j,
                                                                                                {result} ->
          try do
            network_entry = Runtime.safe_value(network_list, j)
            network_id = Runtime.safe_string(network_entry, "network")
            network_code = Runtime.network_id_to_code(network_id, code)
            withdraw_fee = Runtime.safe_number(network_entry, "withdrawFee")
            is_default = Runtime.safe_bool(network_entry, "isDefault")

            {result} =
              if Runtime.truthy(is_default == true) do
                result =
                  Runtime.put_value(result, :withdraw, %{fee: withdraw_fee, percentage: nil})

                {result}
              else
                {result}
              end

            _ = result

            result =
              Runtime.put_value(
                result,
                :networks,
                Runtime.put_value(Runtime.safe_value(result, :networks, %{}), network_code, %{
                  withdraw: %{fee: withdraw_fee, percentage: nil},
                  deposit: %{fee: nil, percentage: nil}
                })
              )

            {:cont, {result}}
          catch
            :continue -> {:cont, {result}}
            :break -> {:halt, {result}}
          end
        end)

      _ = result
      throw({:ccxt_return, result})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec withdraw(String.t(), number(), String.t(), String.t() | nil, params(), (RawEndpoint.t(),
                                                                                params() ->
                                                                                  {:ok, map()}
                                                                                  | {:error,
                                                                                     term()})) ::
          {:ok, map()} | {:error, term()}
  def withdraw(code, amount, address, tag \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = amount
    _ = address
    _ = tag
    _ = params

    try do
      ccxt_match = Runtime.handle_withdraw_tag_and_params(exchange, tag, params)
      tag = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = tag
      _ = params
      Runtime.check_address(address)
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      currency = Runtime.currency(exchange, code)
      request = %{"coin" => Runtime.safe_value(currency, "id"), "address" => address}
      _ = request

      {request} =
        if Runtime.truthy(tag != nil) do
          request = Runtime.put_value(request, "addressTag", tag)

          {request}
        else
          {request}
        end

      _ = request

      network_code = nil
      _ = network_code
      ccxt_match = Runtime.handle_network_code_and_params(params)
      network_code = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = network_code
      _ = params

      {request} =
        if Runtime.truthy(network_code != nil) do
          request =
            Runtime.put_value(
              request,
              "network",
              Runtime.network_code_to_id(network_code, Runtime.safe_value(currency, "code"))
            )

          {request}
        else
          {request}
        end

      _ = request

      request =
        Runtime.put_value(
          request,
          "amount",
          Runtime.currency_to_precision(
            exchange,
            Runtime.safe_value(currency, "code"),
            amount,
            network_code
          )
        )

      response =
        Runtime.call_raw!(Raw, fetcher, "sapi_post_capital_withdraw_apply", [
          Runtime.extend(request, params)
        ])

      {:ok,
       Runtime.call_generated!(exchange, __MODULE__, :parse_transaction, [response, currency])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_trading_fee(term(), term(), term()) :: term()
  def parse_trading_fee(exchange, fee, market \\ nil) do
    _ = exchange
    _ = fee
    _ = market

    try do
      market_id = Runtime.safe_string(fee, "symbol")
      symbol = Runtime.safe_symbol(exchange, market_id, market, nil, "spot")

      throw(
        {:ccxt_return,
         %{
           info: fee,
           symbol: symbol,
           maker: Runtime.safe_number2(fee, "makerCommission", "makerCommissionRate"),
           taker: Runtime.safe_number2(fee, "takerCommission", "takerCommissionRate"),
           percentage: nil,
           tierBased: nil
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_trading_fee(String.t(), params(), (RawEndpoint.t(), params() ->
                                                   {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_trading_fee(symbol, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      type = Runtime.safe_value(market, "type")
      sub_type = nil
      _ = sub_type
      ccxt_match = Runtime.handle_sub_type_and_params(exchange, "fetchTradingFee", market, params)
      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "fetchTradingFee",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      is_linear = Runtime.is_linear(exchange, type, sub_type)
      is_inverse = Runtime.is_inverse(exchange, type, sub_type)
      request = %{"symbol" => Runtime.safe_value(market, "id")}
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(is_linear) do
          {response} =
            if Runtime.truthy(is_portfolio_margin) do
              response =
                Runtime.call_raw!(Raw, fetcher, "papi_get_um_commissionrate", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            else
              response =
                Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_commissionrate", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            end

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(is_inverse) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "papi_get_cm_commissionrate", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_commissionrate", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              response =
                Runtime.call_raw!(Raw, fetcher, "sapi_get_asset_tradefee", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            end

          _ = response

          {response}
        end

      _ = response

      data = response
      _ = data

      {data} =
        if Runtime.truthy(Runtime.is_array(data)) do
          data = Runtime.safe_dict(data, 0, %{})
          _ = data

          {data}
        else
          {data}
        end

      _ = data

      {:ok, Runtime.call_generated!(exchange, __MODULE__, :parse_trading_fee, [data, market])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_trading_fees(params(), (RawEndpoint.t(), params() ->
                                        {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_trading_fees(params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      type = nil
      _ = type

      ccxt_match =
        Runtime.handle_market_type_and_params(exchange, "fetchTradingFees", nil, params)

      type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = type
      _ = params
      sub_type = nil
      _ = sub_type

      ccxt_match =
        Runtime.handle_sub_type_and_params(exchange, "fetchTradingFees", nil, params, "linear")

      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      is_spot_or_margin = Runtime.truthy(type == "spot") or Runtime.truthy(type == "margin")
      is_linear = Runtime.is_linear(exchange, type, sub_type)
      is_inverse = Runtime.is_inverse(exchange, type, sub_type)
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(is_spot_or_margin) do
          response = Runtime.call_raw!(Raw, fetcher, "sapi_get_asset_tradefee", [params])
          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(is_linear) do
              response =
                Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_accountconfig", [params])

              _ = response

              {response}
            else
              {response} =
                if Runtime.truthy(is_inverse) do
                  response = Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_account", [params])
                  _ = response

                  {response}
                else
                  {response}
                end

              _ = response

              {response}
            end

          _ = response

          {response}
        end

      _ = response

      if Runtime.truthy(is_spot_or_margin) do
        result = %{}
        _ = result

        {result} =
          Enum.reduce_while(Runtime.index_range(Runtime.js_length(response), 0), {result}, fn i,
                                                                                              {result} ->
            try do
              fee =
                Runtime.call_generated!(exchange, __MODULE__, :parse_trading_fee, [
                  Runtime.safe_value(response, i)
                ])

              symbol = Runtime.safe_value(fee, "symbol")
              result = Runtime.put_value(result, symbol, fee)
              {:cont, {result}}
            catch
              :continue -> {:cont, {result}}
              :break -> {:halt, {result}}
            end
          end)

        _ = result
        throw({:ccxt_return, result})
      else
        if Runtime.truthy(is_linear) do
          symbols = Runtime.object_keys(Runtime.markets(exchange))
          result = %{}
          _ = result
          fee_tier = Runtime.safe_integer(response, "feeTier")

          fee_tiers =
            Runtime.safe_value(
              Runtime.safe_value(Runtime.safe_value(Runtime.fees(exchange), "linear"), "trading"),
              "tiers"
            )

          maker =
            Runtime.safe_value(
              Runtime.safe_value(Runtime.safe_value(fee_tiers, "maker"), fee_tier),
              1
            )

          taker =
            Runtime.safe_value(
              Runtime.safe_value(Runtime.safe_value(fee_tiers, "taker"), fee_tier),
              1
            )

          {result} =
            Enum.reduce_while(Runtime.index_range(Runtime.js_length(symbols), 0), {result}, fn i,
                                                                                               {result} ->
              try do
                symbol = Runtime.safe_value(symbols, i)
                market = Runtime.safe_value(Runtime.markets(exchange), symbol)

                {result} =
                  if Runtime.truthy(Runtime.safe_value(market, "linear")) do
                    result =
                      Runtime.put_value(result, symbol, %{
                        "info" => %{"feeTier" => fee_tier},
                        "symbol" => symbol,
                        "maker" => maker,
                        "taker" => taker
                      })

                    {result}
                  else
                    {result}
                  end

                _ = result
                {:cont, {result}}
              catch
                :continue -> {:cont, {result}}
                :break -> {:halt, {result}}
              end
            end)

          _ = result
          throw({:ccxt_return, result})
        else
          if Runtime.truthy(is_inverse) do
            symbols = Runtime.object_keys(Runtime.markets(exchange))
            result = %{}
            _ = result
            fee_tier = Runtime.safe_integer(response, "feeTier")

            fee_tiers =
              Runtime.safe_value(
                Runtime.safe_value(
                  Runtime.safe_value(Runtime.fees(exchange), "inverse"),
                  "trading"
                ),
                "tiers"
              )

            maker =
              Runtime.safe_value(
                Runtime.safe_value(Runtime.safe_value(fee_tiers, "maker"), fee_tier),
                1
              )

            taker =
              Runtime.safe_value(
                Runtime.safe_value(Runtime.safe_value(fee_tiers, "taker"), fee_tier),
                1
              )

            {result} =
              Enum.reduce_while(
                Runtime.index_range(Runtime.js_length(symbols), 0),
                {result},
                fn i, {result} ->
                  try do
                    symbol = Runtime.safe_value(symbols, i)
                    market = Runtime.safe_value(Runtime.markets(exchange), symbol)

                    {result} =
                      if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
                        result =
                          Runtime.put_value(result, symbol, %{
                            "info" => %{"feeTier" => fee_tier},
                            "symbol" => symbol,
                            "maker" => maker,
                            "taker" => taker
                          })

                        {result}
                      else
                        {result}
                      end

                    _ = result
                    {:cont, {result}}
                  catch
                    :continue -> {:cont, {result}}
                    :break -> {:halt, {result}}
                  end
                end
              )

            _ = result
            throw({:ccxt_return, result})
          end
        end
      end

      {:ok, nil}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec futures_transfer(String.t(), params(), params(), params(), (RawEndpoint.t(), params() ->
                                                                      {:ok, map()}
                                                                      | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def futures_transfer(code, amount, type, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = amount
    _ = type
    _ = params

    try do
      if Runtime.truthy(Runtime.truthy(type < 1) or Runtime.truthy(type > 4)) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":arguments_required", [
             Runtime.safe_value(exchange, "id") <> " type must be between 1 and 4"
           ])}
        )
      end

      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      currency = Runtime.currency(exchange, code)

      request = %{
        "asset" => Runtime.safe_value(currency, "id"),
        "amount" => amount,
        "type" => type
      }

      response =
        Runtime.call_raw!(Raw, fetcher, "sapi_post_futures_transfer", [
          Runtime.extend(request, params)
        ])

      {:ok, Runtime.call_generated!(__MODULE__, :parse_transfer, [response, currency])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_funding_rate(String.t(), params(), (RawEndpoint.t(), params() ->
                                                    {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_funding_rate(symbol, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      request = %{"symbol" => Runtime.safe_value(market, "id")}
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.safe_value(market, "linear")) do
          response =
            Runtime.call_raw!(Raw, fetcher, "fapipublic_get_premiumindex", [
              Runtime.extend(request, params)
            ])

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
              response =
                Runtime.call_raw!(Raw, fetcher, "dapipublic_get_premiumindex", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":not_supported", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchFundingRate() supports linear and inverse contracts only"
                 ])}
              )
            end

          _ = response

          {response}
        end

      _ = response

      {response} =
        if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
          response = Runtime.safe_value(response, 0)
          _ = response

          {response}
        else
          {response}
        end

      _ = response

      {:ok,
       Runtime.call_generated!(exchange, __MODULE__, :parse_funding_rate, [response, market])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_funding_rate_history(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_funding_rate_history(
        symbol \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "fetchFundingRateHistory" => %{"defaultType" => "future"},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      request = %{}
      _ = request
      paginate = false
      _ = paginate

      ccxt_match =
        Runtime.handle_option_and_params(exchange, params, "fetchFundingRateHistory", "paginate")

      paginate = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = paginate
      _ = params

      if Runtime.truthy(paginate) do
        throw(
          {:ccxt_return,
           Runtime.fetch_paginated_call_deterministic(
             exchange,
             __MODULE__,
             fetcher,
             "fetchFundingRateHistory",
             symbol,
             since,
             limit,
             "8h",
             params
           )}
        )
      end

      default_type =
        Runtime.safe_string2(
          Runtime.safe_value(exchange, "options"),
          "fetchFundingRateHistory",
          "defaultType",
          "future"
        )

      type = Runtime.safe_string(params, "type", default_type)
      market = nil
      _ = market

      {market, request, symbol} =
        if Runtime.truthy(symbol != nil) do
          market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
          _ = market
          symbol = Runtime.safe_value(market, "symbol")
          _ = symbol
          request = Runtime.put_value(request, "symbol", Runtime.safe_value(market, "id"))

          {market, request, symbol}
        else
          {market, request, symbol}
        end

      _ = market
      _ = request
      _ = symbol

      sub_type = nil
      _ = sub_type

      ccxt_match =
        Runtime.handle_sub_type_and_params(
          exchange,
          "fetchFundingRateHistory",
          market,
          params,
          "linear"
        )

      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      params = Runtime.omit(params, "type")
      _ = params

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)

          {request}
        else
          {request}
        end

      _ = request

      until = Runtime.safe_integer(params, "until")
      end_time = Runtime.safe_integer(params, "endTime", until)
      params = Runtime.omit(params, ["endTime", "until"])
      _ = params

      {request} =
        if Runtime.truthy(end_time != nil) do
          request = Runtime.put_value(request, "endTime", end_time)

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(limit != nil) do
          request = Runtime.put_value(request, "limit", limit)

          {request}
        else
          {request}
        end

      _ = request

      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
          response =
            Runtime.call_raw!(Raw, fetcher, "fapipublic_get_fundingrate", [
              Runtime.extend(request, params)
            ])

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
              response =
                Runtime.call_raw!(Raw, fetcher, "dapipublic_get_fundingrate", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":not_supported", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchFundingRateHistory() is not supported for " <> type <> " markets"
                 ])}
              )
            end

          _ = response

          {response}
        end

      _ = response

      {:ok,
       Runtime.parse_funding_rate_histories(exchange, __MODULE__, response, market, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_funding_rate_history(term(), term(), term()) :: term()
  def parse_funding_rate_history(exchange, contract, market \\ nil) do
    _ = exchange
    _ = contract
    _ = market

    try do
      timestamp = Runtime.safe_integer(contract, "fundingTime")

      throw(
        {:ccxt_return,
         %{
           "info" => contract,
           "symbol" =>
             Runtime.safe_symbol(
               exchange,
               Runtime.safe_string(contract, "symbol"),
               nil,
               nil,
               "swap"
             ),
           "fundingRate" => Runtime.safe_number(contract, "fundingRate"),
           "timestamp" => timestamp,
           "datetime" => Runtime.iso8601(timestamp)
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_funding_rates(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                                 {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_funding_rates(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchFundingRates" => %{"defaultType" => "future"},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      symbols = Runtime.market_symbols(exchange, symbols)
      _ = symbols

      default_type =
        Runtime.safe_string2(
          Runtime.safe_value(exchange, "options"),
          "fetchFundingRates",
          "defaultType",
          "future"
        )

      type = Runtime.safe_string(params, "type", default_type)
      sub_type = nil
      _ = sub_type

      ccxt_match =
        Runtime.handle_sub_type_and_params(exchange, "fetchFundingRates", nil, params, "linear")

      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      query = Runtime.omit(params, "type")
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
          response = Runtime.call_raw!(Raw, fetcher, "fapipublic_get_premiumindex", [query])
          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
              response = Runtime.call_raw!(Raw, fetcher, "dapipublic_get_premiumindex", [query])
              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":not_supported", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchFundingRates() supports linear and inverse contracts only"
                 ])}
              )
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, Runtime.parse_funding_rates(exchange, __MODULE__, response, symbols)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_funding_rate(term(), term(), term()) :: term()
  def parse_funding_rate(exchange, contract, market \\ nil) do
    _ = exchange
    _ = contract
    _ = market

    try do
      timestamp = Runtime.safe_integer(contract, "time")
      market_id = Runtime.safe_string(contract, "symbol")
      symbol = Runtime.safe_symbol(exchange, market_id, market, nil, "contract")
      mark_price = Runtime.safe_number(contract, "markPrice")
      index_price = Runtime.safe_number(contract, "indexPrice")
      interest_rate = Runtime.safe_number(contract, "interestRate")
      estimated_settle_price = Runtime.safe_number(contract, "estimatedSettlePrice")
      funding_rate = Runtime.safe_number(contract, "lastFundingRate")
      funding_time = Runtime.safe_integer(contract, "nextFundingTime")
      interval = Runtime.safe_string(contract, "fundingIntervalHours")
      interval_string = nil
      _ = interval_string

      {interval_string} =
        if Runtime.truthy(interval != nil) do
          interval_string = interval <> "h"
          _ = interval_string

          {interval_string}
        else
          {interval_string}
        end

      _ = interval_string

      throw(
        {:ccxt_return,
         %{
           info: contract,
           symbol: symbol,
           markPrice: mark_price,
           indexPrice: index_price,
           interestRate: interest_rate,
           estimatedSettlePrice: estimated_settle_price,
           timestamp: timestamp,
           datetime: Runtime.iso8601(timestamp),
           fundingRate: funding_rate,
           fundingTimestamp: funding_time,
           fundingDatetime: Runtime.iso8601(funding_time),
           nextFundingRate: nil,
           nextFundingTimestamp: nil,
           nextFundingDatetime: nil,
           previousFundingRate: nil,
           previousFundingTimestamp: nil,
           previousFundingDatetime: nil,
           interval: interval_string
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec parse_account_positions(term(), term(), term()) :: term()
  def parse_account_positions(exchange, account, filter_closed \\ false) do
    _ = exchange
    _ = account
    _ = filter_closed

    try do
      positions = Runtime.safe_list(account, "positions")
      assets = Runtime.safe_list(account, "assets", [])
      balances = %{}
      _ = balances

      {balances} =
        Enum.reduce_while(Runtime.index_range(Runtime.js_length(assets), 0), {balances}, fn i,
                                                                                            {balances} ->
          try do
            entry = Runtime.safe_value(assets, i)
            currency_id = Runtime.safe_string(entry, "asset")
            code = Runtime.safe_currency_code(currency_id)
            cross_wallet_balance = Runtime.safe_string(entry, "crossWalletBalance")
            cross_un_pnl = Runtime.safe_string(entry, "crossUnPnl")

            balances =
              Runtime.put_value(balances, code, %{
                "crossMargin" => Runtime.add_number_strings(cross_wallet_balance, cross_un_pnl),
                "crossWalletBalance" => cross_wallet_balance
              })

            {:cont, {balances}}
          catch
            :continue -> {:cont, {balances}}
            :break -> {:halt, {balances}}
          end
        end)

      _ = balances
      result = []
      _ = result

      {result} =
        Enum.reduce_while(Runtime.index_range(Runtime.js_length(positions), 0), {result}, fn i,
                                                                                             {result} ->
          try do
            position = Runtime.safe_value(positions, i)
            market_id = Runtime.safe_string(position, "symbol")
            market = safe_market(exchange, market_id, nil, nil, "contract")

            code =
              if(
                Runtime.truthy(Runtime.safe_value(market, "linear")),
                do: Runtime.safe_value(market, "quote"),
                else: Runtime.safe_value(market, "base")
              )

            maintenance_margin = Runtime.safe_string(position, "maintMargin")

            is_position_open =
              Runtime.truthy(maintenance_margin != "0") and
                Runtime.truthy(maintenance_margin != "0.00000000")

            {result} =
              if Runtime.truthy(
                   Runtime.truthy(not Runtime.truthy(filter_closed)) or
                     Runtime.truthy(is_position_open)
                 ) do
                {result} =
                  if Runtime.truthy(Runtime.has_key?(balances, code)) do
                    parsed =
                      Runtime.call_generated!(exchange, __MODULE__, :parse_account_position, [
                        Runtime.extend(position, %{
                          "crossMargin" =>
                            Runtime.safe_value(Runtime.safe_value(balances, code), "crossMargin"),
                          "crossWalletBalance" =>
                            Runtime.safe_value(
                              Runtime.safe_value(balances, code),
                              "crossWalletBalance"
                            )
                        }),
                        market
                      ])

                    result = Runtime.push(result, parsed)

                    {result}
                  else
                    {result}
                  end

                _ = result

                {result}
              else
                {result}
              end

            _ = result
            {:cont, {result}}
          catch
            :continue -> {:cont, {result}}
            :break -> {:halt, {result}}
          end
        end)

      _ = result
      throw({:ccxt_return, result})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec parse_account_position(term(), term(), term()) :: term()
  def parse_account_position(exchange, position, market \\ nil) do
    _ = exchange
    _ = position
    _ = market

    try do
      market_id = Runtime.safe_string(position, "symbol")
      market = safe_market(exchange, market_id, market, nil, "contract")
      _ = market
      symbol = Runtime.safe_string(market, "symbol")
      leverage_string = Runtime.safe_string(position, "leverage")

      leverage =
        if(
          Runtime.truthy(leverage_string != nil),
          do: Runtime.parse_int(leverage_string),
          else: nil
        )

      initial_margin_string = Runtime.safe_string(position, "initialMargin")
      initial_margin = Runtime.parse_number(initial_margin_string)
      initial_margin_percentage_string = nil
      _ = initial_margin_percentage_string

      {initial_margin_percentage_string} =
        if Runtime.truthy(leverage_string != nil) do
          initial_margin_percentage_string = Runtime.divide_number_string("1", leverage_string, 8)
          _ = initial_margin_percentage_string
          rational = Runtime.is_round_number(exchange, rem(1000, leverage))

          {initial_margin_percentage_string} =
            if Runtime.truthy(not Runtime.truthy(rational)) do
              initial_margin_percentage_string =
                Runtime.divide_number_string(
                  Runtime.add_number_strings(initial_margin_percentage_string, "1e-8"),
                  "1",
                  8
                )

              _ = initial_margin_percentage_string

              {initial_margin_percentage_string}
            else
              {initial_margin_percentage_string}
            end

          _ = initial_margin_percentage_string

          {initial_margin_percentage_string}
        else
          {initial_margin_percentage_string}
        end

      _ = initial_margin_percentage_string

      usdm = Runtime.has_key?(position, "notional")
      maintenance_margin_string = Runtime.safe_string(position, "maintMargin")
      maintenance_margin = Runtime.parse_number(maintenance_margin_string)
      entry_price_string = Runtime.safe_string(position, "entryPrice")
      entry_price = Runtime.parse_number(entry_price_string)
      _ = entry_price
      notional_string = Runtime.safe_string2(position, "notional", "notionalValue")
      notional_string_abs = Runtime.abs_number_string(notional_string)
      notional = Runtime.parse_number(notional_string_abs)
      contracts_string = Runtime.safe_string(position, "positionAmt")
      _ = contracts_string
      contracts_string_abs = Runtime.abs_number_string(contracts_string)
      _ = contracts_string_abs

      {contracts_string, contracts_string_abs} =
        if Runtime.truthy(contracts_string == nil) do
          entry_notional =
            Runtime.multiply_number_string(
              Runtime.multiply_number_string(leverage_string, initial_margin_string),
              entry_price_string
            )

          contract_size_new = Runtime.safe_string(market, "contractSize")
          contracts_string = Runtime.divide_number_string(entry_notional, contract_size_new)
          _ = contracts_string

          contracts_string_abs =
            Runtime.divide_number_string(
              Runtime.add_number_strings(contracts_string, "0.5"),
              "1",
              0
            )

          _ = contracts_string_abs

          {contracts_string, contracts_string_abs}
        else
          {contracts_string, contracts_string_abs}
        end

      _ = contracts_string
      _ = contracts_string_abs

      contracts = Runtime.parse_number(contracts_string_abs)

      leverage_brackets =
        Runtime.safe_dict(Runtime.safe_value(exchange, "options"), "leverageBrackets", %{})

      leverage_bracket = Runtime.safe_list(leverage_brackets, symbol, [])
      maintenance_margin_percentage_string = nil
      _ = maintenance_margin_percentage_string

      {maintenance_margin_percentage_string} =
        Enum.reduce_while(
          Runtime.index_range(Runtime.js_length(leverage_bracket), 0),
          {maintenance_margin_percentage_string},
          fn i, {maintenance_margin_percentage_string} ->
            try do
              bracket = Runtime.safe_value(leverage_bracket, i)

              if Runtime.truthy(
                   Runtime.string_lt?(notional_string_abs, Runtime.safe_value(bracket, 0))
                 ) do
                throw(:break)
              end

              maintenance_margin_percentage_string = Runtime.safe_value(bracket, 1)
              _ = maintenance_margin_percentage_string
              {:cont, {maintenance_margin_percentage_string}}
            catch
              :continue -> {:cont, {maintenance_margin_percentage_string}}
              :break -> {:halt, {maintenance_margin_percentage_string}}
            end
          end
        )

      _ = maintenance_margin_percentage_string
      maintenance_margin_percentage = Runtime.parse_number(maintenance_margin_percentage_string)
      unrealized_pnl_string = Runtime.safe_string(position, "unrealizedProfit")
      unrealized_pnl = Runtime.parse_number(unrealized_pnl_string)
      timestamp = Runtime.safe_integer(position, "updateTime")
      _ = timestamp

      {timestamp} =
        if Runtime.truthy(timestamp == 0) do
          timestamp = nil
          _ = timestamp

          {timestamp}
        else
          {timestamp}
        end

      _ = timestamp

      isolated = Runtime.safe_bool(position, "isolated")
      _ = isolated

      {isolated} =
        if Runtime.truthy(isolated == nil) do
          isolated_margin_raw = Runtime.safe_string(position, "isolatedMargin")
          isolated = not Runtime.truthy(Runtime.string_eq?(isolated_margin_raw, "0"))
          _ = isolated

          {isolated}
        else
          {isolated}
        end

      _ = isolated

      margin_mode = nil
      _ = margin_mode
      collateral_string = nil
      _ = collateral_string
      wallet_balance = nil
      _ = wallet_balance

      {collateral_string, margin_mode, wallet_balance} =
        if Runtime.truthy(isolated) do
          margin_mode = "isolated"
          _ = margin_mode
          wallet_balance = Runtime.safe_string(position, "isolatedWallet")
          _ = wallet_balance
          collateral_string = Runtime.add_number_strings(wallet_balance, unrealized_pnl_string)
          _ = collateral_string

          {collateral_string, margin_mode, wallet_balance}
        else
          margin_mode = "cross"
          _ = margin_mode
          wallet_balance = Runtime.safe_string(position, "crossWalletBalance")
          _ = wallet_balance
          collateral_string = Runtime.safe_string(position, "crossMargin")
          _ = collateral_string

          {collateral_string, margin_mode, wallet_balance}
        end

      _ = collateral_string
      _ = margin_mode
      _ = wallet_balance

      collateral = Runtime.parse_number(collateral_string)
      margin_ratio = nil
      _ = margin_ratio
      side = nil
      _ = side
      percentage = nil
      _ = percentage
      liquidation_price_string_raw = nil
      _ = liquidation_price_string_raw
      liquidation_price = nil
      _ = liquidation_price
      contract_size = Runtime.safe_value(market, "contractSize")
      contract_size_string = Runtime.number_to_string(contract_size)

      {entry_price, liquidation_price, liquidation_price_string_raw, margin_ratio, percentage,
       side} =
        if Runtime.truthy(Runtime.string_eq?(notional_string, "0")) do
          entry_price = nil
          _ = entry_price

          {entry_price, liquidation_price, liquidation_price_string_raw, margin_ratio, percentage,
           side}
        else
          side =
            if(
              Runtime.truthy(Runtime.string_lt?(notional_string, "0")),
              do: "short",
              else: "long"
            )

          _ = side

          margin_ratio =
            Runtime.parse_number(
              Runtime.divide_number_string(
                Runtime.add_number_strings(
                  Runtime.divide_number_string(maintenance_margin_string, collateral_string),
                  "5e-5"
                ),
                "1",
                4
              )
            )

          _ = margin_ratio

          percentage =
            Runtime.parse_number(
              Runtime.multiply_number_string(
                Runtime.divide_number_string(unrealized_pnl_string, initial_margin_string, 4),
                "100"
              )
            )

          _ = percentage

          {liquidation_price_string_raw} =
            if Runtime.truthy(usdm) do
              one_plus_maintenance_margin_percentage_string = nil
              _ = one_plus_maintenance_margin_percentage_string
              entry_price_sign_string = entry_price_string
              _ = entry_price_sign_string

              {entry_price_sign_string, one_plus_maintenance_margin_percentage_string} =
                if Runtime.truthy(side == "short") do
                  one_plus_maintenance_margin_percentage_string =
                    Runtime.add_number_strings("1", maintenance_margin_percentage_string)

                  _ = one_plus_maintenance_margin_percentage_string

                  {entry_price_sign_string, one_plus_maintenance_margin_percentage_string}
                else
                  one_plus_maintenance_margin_percentage_string =
                    Runtime.add_number_strings("-1", maintenance_margin_percentage_string)

                  _ = one_plus_maintenance_margin_percentage_string

                  entry_price_sign_string =
                    Runtime.multiply_number_string("-1", entry_price_sign_string)

                  _ = entry_price_sign_string

                  {entry_price_sign_string, one_plus_maintenance_margin_percentage_string}
                end

              _ = entry_price_sign_string
              _ = one_plus_maintenance_margin_percentage_string

              left_side =
                Runtime.divide_number_string(
                  wallet_balance,
                  Runtime.multiply_number_string(
                    contracts_string_abs,
                    one_plus_maintenance_margin_percentage_string
                  )
                )

              right_side =
                Runtime.divide_number_string(
                  entry_price_sign_string,
                  one_plus_maintenance_margin_percentage_string
                )

              liquidation_price_string_raw = Runtime.add_number_strings(left_side, right_side)
              _ = liquidation_price_string_raw

              {liquidation_price_string_raw}
            else
              one_plus_maintenance_margin_percentage_string = nil
              _ = one_plus_maintenance_margin_percentage_string
              entry_price_sign_string = entry_price_string
              _ = entry_price_sign_string

              {entry_price_sign_string, one_plus_maintenance_margin_percentage_string} =
                if Runtime.truthy(side == "short") do
                  one_plus_maintenance_margin_percentage_string =
                    Runtime.subtract_number_strings("1", maintenance_margin_percentage_string)

                  _ = one_plus_maintenance_margin_percentage_string

                  {entry_price_sign_string, one_plus_maintenance_margin_percentage_string}
                else
                  one_plus_maintenance_margin_percentage_string =
                    Runtime.subtract_number_strings("-1", maintenance_margin_percentage_string)

                  _ = one_plus_maintenance_margin_percentage_string

                  entry_price_sign_string =
                    Runtime.multiply_number_string("-1", entry_price_sign_string)

                  _ = entry_price_sign_string

                  {entry_price_sign_string, one_plus_maintenance_margin_percentage_string}
                end

              _ = entry_price_sign_string
              _ = one_plus_maintenance_margin_percentage_string

              size = Runtime.multiply_number_string(contracts_string_abs, contract_size_string)

              left_side =
                Runtime.multiply_number_string(
                  size,
                  one_plus_maintenance_margin_percentage_string
                )

              right_side =
                Runtime.subtract_number_strings(
                  Runtime.multiply_number_string(
                    Runtime.divide_number_string("1", entry_price_sign_string),
                    size
                  ),
                  wallet_balance
                )

              liquidation_price_string_raw = Runtime.divide_number_string(left_side, right_side)
              _ = liquidation_price_string_raw

              {liquidation_price_string_raw}
            end

          _ = liquidation_price_string_raw

          price_precision =
            Runtime.precision_from_string(
              Runtime.safe_string(Runtime.safe_value(market, "precision"), "price")
            )

          price_precision_plus_one = price_precision + 1
          price_precision_plus_one_string = to_string(price_precision_plus_one)
          rounder = Runtime.new_error("precise", ["5e-" <> price_precision_plus_one_string])
          rounder_string = to_string(rounder)

          liquidation_price_rounded_string =
            Runtime.add_number_strings(rounder_string, liquidation_price_string_raw)

          truncated_liquidation_price =
            Runtime.divide_number_string(liquidation_price_rounded_string, "1", price_precision)

          _ = truncated_liquidation_price

          {truncated_liquidation_price} =
            if Runtime.truthy(
                 Runtime.truthy(truncated_liquidation_price != nil) and
                   Runtime.truthy(Runtime.safe_value(truncated_liquidation_price, 0) == "-")
               ) do
              truncated_liquidation_price = nil
              _ = truncated_liquidation_price

              {truncated_liquidation_price}
            else
              {truncated_liquidation_price}
            end

          _ = truncated_liquidation_price

          liquidation_price = Runtime.parse_number(truncated_liquidation_price)
          _ = liquidation_price

          {entry_price, liquidation_price, liquidation_price_string_raw, margin_ratio, percentage,
           side}
        end

      _ = entry_price
      _ = liquidation_price
      _ = liquidation_price_string_raw
      _ = margin_ratio
      _ = percentage
      _ = side

      position_side = Runtime.safe_string(position, "positionSide")
      hedged = position_side != "BOTH"

      throw(
        {:ccxt_return,
         %{
           info: position,
           id: nil,
           symbol: symbol,
           timestamp: timestamp,
           datetime: Runtime.iso8601(timestamp),
           initialMargin: initial_margin,
           initialMarginPercentage: Runtime.parse_number(initial_margin_percentage_string),
           maintenanceMargin: maintenance_margin,
           maintenanceMarginPercentage: maintenance_margin_percentage,
           entryPrice: entry_price,
           notional: notional,
           leverage: Runtime.parse_number(leverage_string),
           unrealizedPnl: unrealized_pnl,
           contracts: contracts,
           contractSize: contract_size,
           marginRatio: margin_ratio,
           liquidationPrice: liquidation_price,
           markPrice: nil,
           collateral: collateral,
           marginMode: margin_mode,
           side: side,
           hedged: hedged,
           percentage: percentage
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec parse_position_risk(term(), term(), term()) :: term()
  def parse_position_risk(exchange, position, market \\ nil) do
    _ = exchange
    _ = position
    _ = market

    try do
      market_id = Runtime.safe_string(position, "symbol")
      market = safe_market(exchange, market_id, market, nil, "contract")
      _ = market
      symbol = Runtime.safe_string(market, "symbol")
      isolated_margin_string = Runtime.safe_string(position, "isolatedMargin")

      leverage_brackets =
        Runtime.safe_dict(Runtime.safe_value(exchange, "options"), "leverageBrackets", %{})

      leverage_bracket = Runtime.safe_list(leverage_brackets, symbol, [])
      notional_string = Runtime.safe_string2(position, "notional", "notionalValue")
      notional_string_abs = Runtime.abs_number_string(notional_string)
      maintenance_margin_percentage_string = nil
      _ = maintenance_margin_percentage_string

      {maintenance_margin_percentage_string} =
        Enum.reduce_while(
          Runtime.index_range(Runtime.js_length(leverage_bracket), 0),
          {maintenance_margin_percentage_string},
          fn i, {maintenance_margin_percentage_string} ->
            try do
              bracket = Runtime.safe_value(leverage_bracket, i)

              if Runtime.truthy(
                   Runtime.string_lt?(notional_string_abs, Runtime.safe_value(bracket, 0))
                 ) do
                throw(:break)
              end

              maintenance_margin_percentage_string = Runtime.safe_value(bracket, 1)
              _ = maintenance_margin_percentage_string
              {:cont, {maintenance_margin_percentage_string}}
            catch
              :continue -> {:cont, {maintenance_margin_percentage_string}}
              :break -> {:halt, {maintenance_margin_percentage_string}}
            end
          end
        )

      _ = maintenance_margin_percentage_string
      notional = Runtime.parse_number(notional_string_abs)
      contracts_abs = Runtime.abs_number_string(Runtime.safe_string(position, "positionAmt"))
      contracts = Runtime.parse_number(contracts_abs)
      unrealized_pnl_string = Runtime.safe_string(position, "unRealizedProfit")
      unrealized_pnl = Runtime.parse_number(unrealized_pnl_string)

      liquidation_price_string =
        Runtime.omit_zero(Runtime.safe_string(position, "liquidationPrice"))

      liquidation_price = Runtime.parse_number(liquidation_price_string)
      collateral_string = nil
      _ = collateral_string
      margin_mode = Runtime.safe_string(position, "marginType")
      _ = margin_mode

      {margin_mode} =
        if Runtime.truthy(
             Runtime.truthy(margin_mode == nil) and Runtime.truthy(isolated_margin_string != nil)
           ) do
          margin_mode =
            if(
              Runtime.truthy(Runtime.string_eq?(isolated_margin_string, "0")),
              do: "cross",
              else: "isolated"
            )

          _ = margin_mode

          {margin_mode}
        else
          {margin_mode}
        end

      _ = margin_mode

      side = nil
      _ = side

      {side} =
        if Runtime.truthy(Runtime.string_gt?(notional_string, "0")) do
          side = "long"
          _ = side

          {side}
        else
          {side} =
            if Runtime.truthy(Runtime.string_lt?(notional_string, "0")) do
              side = "short"
              _ = side

              {side}
            else
              {side}
            end

          _ = side

          {side}
        end

      _ = side

      entry_price_string = Runtime.safe_string(position, "entryPrice")
      entry_price = Runtime.parse_number(entry_price_string)
      contract_size = Runtime.safe_value(market, "contractSize")
      contract_size_string = Runtime.number_to_string(contract_size)
      linear = Runtime.has_key?(position, "notional")

      {collateral_string} =
        if Runtime.truthy(margin_mode == "cross") do
          precision = Runtime.safe_dict(market, "precision", %{})
          base_precision_value = Runtime.safe_string(precision, "base")
          quote_precision_value = Runtime.safe_string2(precision, "quote", "price")

          precision_is_undefined =
            Runtime.truthy(base_precision_value == nil) and
              Runtime.truthy(quote_precision_value == nil)

          {collateral_string} =
            if Runtime.truthy(not Runtime.truthy(precision_is_undefined)) do
              {collateral_string} =
                if Runtime.truthy(linear) do
                  one_plus_maintenance_margin_percentage_string = nil
                  _ = one_plus_maintenance_margin_percentage_string
                  entry_price_sign_string = entry_price_string
                  _ = entry_price_sign_string

                  {entry_price_sign_string, one_plus_maintenance_margin_percentage_string} =
                    if Runtime.truthy(side == "short") do
                      one_plus_maintenance_margin_percentage_string =
                        Runtime.add_number_strings("1", maintenance_margin_percentage_string)

                      _ = one_plus_maintenance_margin_percentage_string

                      entry_price_sign_string =
                        Runtime.multiply_number_string("-1", entry_price_sign_string)

                      _ = entry_price_sign_string

                      {entry_price_sign_string, one_plus_maintenance_margin_percentage_string}
                    else
                      one_plus_maintenance_margin_percentage_string =
                        Runtime.add_number_strings("-1", maintenance_margin_percentage_string)

                      _ = one_plus_maintenance_margin_percentage_string

                      {entry_price_sign_string, one_plus_maintenance_margin_percentage_string}
                    end

                  _ = entry_price_sign_string
                  _ = one_plus_maintenance_margin_percentage_string

                  inner =
                    Runtime.multiply_number_string(
                      liquidation_price_string,
                      one_plus_maintenance_margin_percentage_string
                    )

                  left_side = Runtime.add_number_strings(inner, entry_price_sign_string)

                  quote_precision =
                    Runtime.precision_from_string(
                      Runtime.safe_string2(precision, "quote", "price")
                    )

                  {collateral_string} =
                    if Runtime.truthy(quote_precision != nil) do
                      collateral_string =
                        Runtime.divide_number_string(
                          Runtime.multiply_number_string(left_side, contracts_abs),
                          "1",
                          quote_precision
                        )

                      _ = collateral_string

                      {collateral_string}
                    else
                      {collateral_string}
                    end

                  _ = collateral_string

                  {collateral_string}
                else
                  one_plus_maintenance_margin_percentage_string = nil
                  _ = one_plus_maintenance_margin_percentage_string
                  entry_price_sign_string = entry_price_string
                  _ = entry_price_sign_string

                  {entry_price_sign_string, one_plus_maintenance_margin_percentage_string} =
                    if Runtime.truthy(side == "short") do
                      one_plus_maintenance_margin_percentage_string =
                        Runtime.subtract_number_strings("1", maintenance_margin_percentage_string)

                      _ = one_plus_maintenance_margin_percentage_string

                      {entry_price_sign_string, one_plus_maintenance_margin_percentage_string}
                    else
                      one_plus_maintenance_margin_percentage_string =
                        Runtime.subtract_number_strings(
                          "-1",
                          maintenance_margin_percentage_string
                        )

                      _ = one_plus_maintenance_margin_percentage_string

                      entry_price_sign_string =
                        Runtime.multiply_number_string("-1", entry_price_sign_string)

                      _ = entry_price_sign_string

                      {entry_price_sign_string, one_plus_maintenance_margin_percentage_string}
                    end

                  _ = entry_price_sign_string
                  _ = one_plus_maintenance_margin_percentage_string

                  left_side = Runtime.multiply_number_string(contracts_abs, contract_size_string)

                  right_side =
                    Runtime.subtract_number_strings(
                      Runtime.divide_number_string("1", entry_price_sign_string),
                      Runtime.divide_number_string(
                        one_plus_maintenance_margin_percentage_string,
                        liquidation_price_string
                      )
                    )

                  base_precision =
                    Runtime.precision_from_string(Runtime.safe_string(precision, "base"))

                  {collateral_string} =
                    if Runtime.truthy(base_precision != nil) do
                      collateral_string =
                        Runtime.divide_number_string(
                          Runtime.multiply_number_string(left_side, right_side),
                          "1",
                          base_precision
                        )

                      _ = collateral_string

                      {collateral_string}
                    else
                      {collateral_string}
                    end

                  _ = collateral_string

                  {collateral_string}
                end

              _ = collateral_string

              {collateral_string}
            else
              {collateral_string}
            end

          _ = collateral_string

          {collateral_string}
        else
          collateral_string = Runtime.safe_string(position, "isolatedMargin")
          _ = collateral_string

          {collateral_string}
        end

      _ = collateral_string

      collateral_string =
        if(
          Runtime.truthy(collateral_string == nil),
          do: "0",
          else: collateral_string
        )

      _ = collateral_string
      collateral = Runtime.parse_number(collateral_string)

      mark_price =
        Runtime.parse_number(Runtime.omit_zero(Runtime.safe_string(position, "markPrice")))

      timestamp = Runtime.safe_integer(position, "updateTime")
      _ = timestamp

      {timestamp} =
        if Runtime.truthy(timestamp == 0) do
          timestamp = nil
          _ = timestamp

          {timestamp}
        else
          {timestamp}
        end

      _ = timestamp

      maintenance_margin_percentage = Runtime.parse_number(maintenance_margin_percentage_string)

      maintenance_margin_string =
        Runtime.multiply_number_string(maintenance_margin_percentage_string, notional_string_abs)

      _ = maintenance_margin_string

      {maintenance_margin_string} =
        if Runtime.truthy(maintenance_margin_string == nil) do
          maintenance_margin_string = Runtime.safe_string(position, "maintMargin")
          _ = maintenance_margin_string

          {maintenance_margin_string}
        else
          {maintenance_margin_string}
        end

      _ = maintenance_margin_string

      maintenance_margin = Runtime.parse_number(maintenance_margin_string)
      initial_margin_string = nil
      _ = initial_margin_string
      initial_margin_percentage_string = nil
      _ = initial_margin_percentage_string
      leverage_string = Runtime.safe_string(position, "leverage")

      {initial_margin_percentage_string, initial_margin_string} =
        if Runtime.truthy(leverage_string != nil) do
          leverage = Runtime.parse_int(leverage_string)
          rational = Runtime.is_round_number(exchange, rem(1000, leverage))
          initial_margin_percentage_string = Runtime.divide_number_string("1", leverage_string, 8)
          _ = initial_margin_percentage_string

          {initial_margin_percentage_string} =
            if Runtime.truthy(not Runtime.truthy(rational)) do
              initial_margin_percentage_string =
                Runtime.add_number_strings(initial_margin_percentage_string, "1e-8")

              _ = initial_margin_percentage_string

              {initial_margin_percentage_string}
            else
              {initial_margin_percentage_string}
            end

          _ = initial_margin_percentage_string

          unrounded =
            Runtime.multiply_number_string(notional_string_abs, initial_margin_percentage_string)

          initial_margin_string = Runtime.divide_number_string(unrounded, "1", 8)
          _ = initial_margin_string

          {initial_margin_percentage_string, initial_margin_string}
        else
          initial_margin_string = Runtime.safe_string(position, "initialMargin")
          _ = initial_margin_string
          unrounded = Runtime.multiply_number_string(initial_margin_string, "1")

          initial_margin_percentage_string =
            Runtime.divide_number_string(unrounded, notional_string_abs, 8)

          _ = initial_margin_percentage_string

          {initial_margin_percentage_string, initial_margin_string}
        end

      _ = initial_margin_percentage_string
      _ = initial_margin_string

      margin_ratio = nil
      _ = margin_ratio
      percentage = nil
      _ = percentage

      {margin_ratio, percentage} =
        if Runtime.truthy(not Runtime.truthy(Runtime.string_eq?(collateral_string, "0"))) do
          margin_ratio =
            Runtime.parse_number(
              Runtime.divide_number_string(
                Runtime.add_number_strings(
                  Runtime.divide_number_string(maintenance_margin_string, collateral_string),
                  "5e-5"
                ),
                "1",
                4
              )
            )

          _ = margin_ratio

          percentage =
            Runtime.parse_number(
              Runtime.multiply_number_string(
                Runtime.divide_number_string(unrealized_pnl_string, initial_margin_string, 4),
                "100"
              )
            )

          _ = percentage

          {margin_ratio, percentage}
        else
          {margin_ratio, percentage}
        end

      _ = margin_ratio
      _ = percentage

      position_side = Runtime.safe_string(position, "positionSide")
      hedged = position_side != "BOTH"

      throw(
        {:ccxt_return,
         Runtime.safe_position(exchange, %{
           info: position,
           id: nil,
           symbol: symbol,
           contracts: contracts,
           contractSize: contract_size,
           unrealizedPnl: unrealized_pnl,
           leverage: Runtime.parse_number(leverage_string),
           liquidationPrice: liquidation_price,
           collateral: collateral,
           notional: notional,
           markPrice: mark_price,
           entryPrice: entry_price,
           timestamp: timestamp,
           initialMargin: Runtime.parse_number(initial_margin_string),
           initialMarginPercentage: Runtime.parse_number(initial_margin_percentage_string),
           maintenanceMargin: maintenance_margin,
           maintenanceMarginPercentage: maintenance_margin_percentage,
           marginRatio: margin_ratio,
           datetime: Runtime.iso8601(timestamp),
           marginMode: margin_mode,
           marginType: margin_mode,
           side: side,
           hedged: hedged,
           percentage: percentage,
           stopLossPrice: nil,
           takeProfitPrice: nil
         })}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec load_leverage_brackets(params(), params(), (RawEndpoint.t(), params() ->
                                                      {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def load_leverage_brackets(reload \\ false, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse"]},
            "defaultType" => "future",
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = reload
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange

      leverage_brackets =
        Runtime.safe_dict(Runtime.safe_value(exchange, "options"), "leverageBrackets")

      {exchange, params} =
        if Runtime.truthy(Runtime.truthy(leverage_brackets == nil) or Runtime.truthy(reload)) do
          default_type =
            Runtime.safe_string(Runtime.safe_value(exchange, "options"), "defaultType", "future")

          type = Runtime.safe_string(params, "type", default_type)
          query = Runtime.omit(params, "type")
          sub_type = nil
          _ = sub_type

          ccxt_match =
            Runtime.handle_sub_type_and_params(
              exchange,
              "loadLeverageBrackets",
              nil,
              params,
              "linear"
            )

          sub_type = Runtime.safe_value(ccxt_match, 0, nil)
          params = Runtime.safe_value(ccxt_match, 1, nil)
          _ = sub_type
          _ = params
          is_portfolio_margin = nil
          _ = is_portfolio_margin

          ccxt_match =
            Runtime.handle_option_and_params2(
              exchange,
              params,
              "loadLeverageBrackets",
              "papi",
              "portfolioMargin",
              false
            )

          is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
          params = Runtime.safe_value(ccxt_match, 1, nil)
          _ = is_portfolio_margin
          _ = params
          response = nil
          _ = response

          {response} =
            if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "papi_get_um_leveragebracket", [query])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_leveragebracket", [query])

                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              {response} =
                if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
                  {response} =
                    if Runtime.truthy(is_portfolio_margin) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "papi_get_cm_leveragebracket", [query])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "dapiprivatev2_get_leveragebracket", [
                          query
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                else
                  throw(
                    {:ccxt_error,
                     Runtime.new_error_reason(":not_supported", [
                       Runtime.safe_value(exchange, "id") <>
                         " loadLeverageBrackets() supports linear and inverse contracts only"
                     ])}
                  )
                end

              _ = response

              {response}
            end

          _ = response

          exchange =
            Runtime.put_value_in(
              exchange,
              ["options", "leverageBrackets"],
              Runtime.create_safe_dictionary()
            )

          {exchange} =
            Enum.reduce_while(
              Runtime.index_range(Runtime.js_length(response), 0),
              {exchange},
              fn i, {exchange} ->
                try do
                  entry = Runtime.safe_value(response, i)
                  market_id = Runtime.safe_string(entry, "symbol")
                  symbol = Runtime.safe_symbol(exchange, market_id, nil, nil, "contract")
                  brackets = Runtime.safe_list(entry, "brackets", [])
                  result = []
                  _ = result

                  {result} =
                    Enum.reduce_while(
                      Runtime.index_range(Runtime.js_length(brackets), 0),
                      {result},
                      fn j, {result} ->
                        try do
                          bracket = Runtime.safe_value(brackets, j)
                          floor_value = Runtime.safe_string2(bracket, "notionalFloor", "qtyFloor")

                          maintenance_margin_percentage =
                            Runtime.safe_string(bracket, "maintMarginRatio")

                          result =
                            Runtime.push(result, [floor_value, maintenance_margin_percentage])

                          {:cont, {result}}
                        catch
                          :continue -> {:cont, {result}}
                          :break -> {:halt, {result}}
                        end
                      end
                    )

                  _ = result

                  exchange =
                    Runtime.put_value_in(
                      exchange,
                      ["options", "leverageBrackets", symbol],
                      result
                    )

                  {:cont, {exchange}}
                catch
                  :continue -> {:cont, {exchange}}
                  :break -> {:halt, {exchange}}
                end
              end
            )

          _ = exchange

          {exchange, params}
        else
          {exchange, params}
        end

      _ = exchange
      _ = params

      {:ok, Runtime.safe_value(Runtime.safe_value(exchange, "options"), "leverageBrackets")}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_leverage_tiers(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                                  {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_leverage_tiers(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      type = nil
      _ = type

      ccxt_match =
        Runtime.handle_market_type_and_params(exchange, "fetchLeverageTiers", nil, params)

      type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = type
      _ = params
      sub_type = nil
      _ = sub_type

      ccxt_match =
        Runtime.handle_sub_type_and_params(exchange, "fetchLeverageTiers", nil, params, "linear")

      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "fetchLeverageTiers",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
          {response} =
            if Runtime.truthy(is_portfolio_margin) do
              response = Runtime.call_raw!(Raw, fetcher, "papi_get_um_leveragebracket", [params])
              _ = response

              {response}
            else
              response =
                Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_leveragebracket", [params])

              _ = response

              {response}
            end

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "papi_get_cm_leveragebracket", [params])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "dapiprivatev2_get_leveragebracket", [params])

                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":not_supported", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchLeverageTiers() supports linear and inverse contracts only"
                 ])}
              )
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, Runtime.parse_leverage_tiers(exchange, __MODULE__, response, symbols, "symbol")}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_market_leverage_tiers(term(), term(), term()) :: term()
  def parse_market_leverage_tiers(exchange, info, market \\ nil) do
    _ = exchange
    _ = info
    _ = market

    try do
      market_id = Runtime.safe_string(info, "symbol")
      market = safe_market(exchange, market_id, market, nil, "contract")
      _ = market
      brackets = Runtime.safe_list(info, "brackets", [])
      tiers = []
      _ = tiers

      {tiers} =
        Enum.reduce_while(Runtime.index_range(Runtime.js_length(brackets), 0), {tiers}, fn j,
                                                                                           {tiers} ->
          try do
            bracket = Runtime.safe_value(brackets, j)

            tiers =
              Runtime.push(tiers, %{
                tier: Runtime.safe_number(bracket, "bracket"),
                symbol: Runtime.safe_symbol(exchange, market_id, market),
                currency: Runtime.safe_value(market, "quote"),
                minNotional: Runtime.safe_number2(bracket, "notionalFloor", "qtyFloor"),
                maxNotional: Runtime.safe_number2(bracket, "notionalCap", "qtyCap"),
                maintenanceMarginRate: Runtime.safe_number(bracket, "maintMarginRatio"),
                maxLeverage: Runtime.safe_number(bracket, "initialLeverage"),
                info: bracket
              })

            {:cont, {tiers}}
          catch
            :continue -> {:cont, {tiers}}
            :break -> {:halt, {tiers}}
          end
        end)

      _ = tiers
      throw({:ccxt_return, tiers})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_position(String.t(), params(), (RawEndpoint.t(), params() ->
                                                {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_position(symbol, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "option",
            "fetchMarkets" => %{"types" => ["option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

      if Runtime.truthy(not Runtime.truthy(Runtime.safe_value(market, "option"))) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <> " fetchPosition() supports option markets only"
           ])}
        )
      end

      request = %{"symbol" => Runtime.safe_value(market, "id")}

      response =
        Runtime.call_raw!(Raw, fetcher, "eapiprivate_get_position", [
          Runtime.extend(request, params)
        ])

      {:ok,
       Runtime.call_generated!(exchange, __MODULE__, :parse_option_position, [
         Runtime.safe_value(response, 0),
         market
       ])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_option_positions(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                                    {:ok, map()}
                                                                    | {:error, term()})) ::
          {:ok, list()} | {:error, term()}
  def fetch_option_positions(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "option",
            "fetchMarkets" => %{"types" => ["option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      symbols = Runtime.market_symbols(exchange, symbols)
      _ = symbols
      request = %{}
      _ = request
      market = nil
      _ = market

      {market, request} =
        if Runtime.truthy(symbols != nil) do
          symbol = nil
          _ = symbol

          {symbol} =
            if Runtime.truthy(Runtime.is_array(symbols)) do
              symbols_length = Runtime.js_length(symbols)

              if Runtime.truthy(symbols_length > 1) do
                throw(
                  {:ccxt_error,
                   Runtime.new_error_reason(":bad_request", [
                     Runtime.safe_value(exchange, "id") <>
                       " fetchPositions() symbols argument cannot contain more than 1 symbol"
                   ])}
                )
              end

              symbol = Runtime.safe_value(symbols, 0)
              _ = symbol

              {symbol}
            else
              symbol = symbols
              _ = symbol

              {symbol}
            end

          _ = symbol

          market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
          _ = market
          request = Runtime.put_value(request, "symbol", Runtime.safe_value(market, "id"))

          {market, request}
        else
          {market, request}
        end

      _ = market
      _ = request

      response =
        Runtime.call_raw!(Raw, fetcher, "eapiprivate_get_position", [
          Runtime.extend(request, params)
        ])

      result = []
      _ = result

      {result} =
        Enum.reduce_while(Runtime.index_range(Runtime.js_length(response), 0), {result}, fn i,
                                                                                            {result} ->
          try do
            result =
              Runtime.push(
                result,
                Runtime.call_generated!(exchange, __MODULE__, :parse_option_position, [
                  Runtime.safe_value(response, i),
                  market
                ])
              )

            {:cont, {result}}
          catch
            :continue -> {:cont, {result}}
            :break -> {:halt, {result}}
          end
        end)

      _ = result
      {:ok, Runtime.filter_by_array_positions(result, "symbol", symbols, false)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_option_position(term(), term(), term()) :: term()
  def parse_option_position(exchange, position, market \\ nil) do
    _ = exchange
    _ = position
    _ = market

    try do
      market_id = Runtime.safe_string(position, "symbol")
      market = safe_market(exchange, market_id, market, nil, "swap")
      _ = market
      symbol = Runtime.safe_value(market, "symbol")
      side = Runtime.safe_string_lower(position, "side")
      quantity = Runtime.safe_string(position, "quantity")
      _ = quantity

      {quantity} =
        if Runtime.truthy(side != "long") do
          quantity = Runtime.multiply_number_string("-1", quantity)
          _ = quantity

          {quantity}
        else
          {quantity}
        end

      _ = quantity

      timestamp = Runtime.safe_integer(position, "time")

      throw(
        {:ccxt_return,
         Runtime.safe_position(exchange, %{
           info: position,
           id: nil,
           symbol: symbol,
           entryPrice: Runtime.safe_number(position, "entryPrice"),
           markPrice: Runtime.safe_number(position, "markPrice"),
           notional: Runtime.safe_number(position, "markValue"),
           collateral: Runtime.safe_number(position, "positionCost"),
           unrealizedPnl: Runtime.safe_number(position, "unrealizedPNL"),
           side: side,
           contracts: Runtime.parse_number(quantity),
           contractSize: nil,
           timestamp: timestamp,
           datetime: Runtime.iso8601(timestamp),
           hedged: nil,
           maintenanceMargin: nil,
           maintenanceMarginPercentage: nil,
           initialMargin: nil,
           initialMarginPercentage: nil,
           leverage: nil,
           liquidationPrice: nil,
           marginRatio: nil,
           marginMode: nil,
           percentage: nil
         })}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_positions(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                             {:ok, map()} | {:error, term()})) ::
          {:ok, list()} | {:error, term()}
  def fetch_positions(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchPositions" => %{"method" => "positionRisk"},
            "fetchMarkets" => %{"types" => ["linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      default_method = nil
      _ = default_method
      ccxt_match = Runtime.handle_option_and_params(exchange, params, "fetchPositions", "method")
      default_method = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = default_method
      _ = params

      {default_method} =
        if Runtime.truthy(default_method == nil) do
          options = Runtime.safe_dict(Runtime.safe_value(exchange, "options"), "fetchPositions")

          {default_method} =
            if Runtime.truthy(options == nil) do
              default_method =
                Runtime.safe_string(
                  Runtime.safe_value(exchange, "options"),
                  "fetchPositions",
                  "positionRisk"
                )

              _ = default_method

              {default_method}
            else
              default_method = "positionRisk"
              _ = default_method

              {default_method}
            end

          _ = default_method

          {default_method}
        else
          {default_method}
        end

      _ = default_method

      if Runtime.truthy(default_method == "positionRisk") do
        throw(
          {:ccxt_return,
           Runtime.call_generated!(exchange, __MODULE__, :fetch_positions_risk, [
             symbols,
             params,
             fetcher
           ])}
        )
      else
        if Runtime.truthy(default_method == "account") do
          throw(
            {:ccxt_return,
             Runtime.call_generated!(exchange, __MODULE__, :fetch_account_positions, [
               symbols,
               params,
               fetcher
             ])}
          )
        else
          if Runtime.truthy(default_method == "option") do
            throw(
              {:ccxt_return,
               Runtime.call_generated!(exchange, __MODULE__, :fetch_option_positions, [
                 symbols,
                 params,
                 fetcher
               ])}
            )
          else
            throw(
              {:ccxt_error,
               Runtime.new_error_reason(":not_supported", [
                 Runtime.safe_value(exchange, "id") <>
                   ".options[\"fetchPositions\"][\"method\"] or params[\"method\"] = \"" <>
                   default_method <>
                   "\" is invalid, please choose between \"account\", \"positionRisk\" and \"option\""
               ])}
            )
          end
        end
      end
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_account_positions(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                                     {:ok, map()}
                                                                     | {:error, term()})) ::
          {:ok, list()} | {:error, term()}
  def fetch_account_positions(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      if Runtime.truthy(symbols != nil) do
        if Runtime.truthy(not Runtime.truthy(Runtime.is_array(symbols))) do
          throw(
            {:ccxt_error,
             Runtime.new_error_reason(":arguments_required", [
               Runtime.safe_value(exchange, "id") <>
                 " fetchPositions() requires an array argument for symbols"
             ])}
          )
        end
      end

      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange

      Runtime.call_generated!(exchange, __MODULE__, :load_leverage_brackets, [
        false,
        params,
        fetcher
      ])

      default_type =
        Runtime.safe_string(Runtime.safe_value(exchange, "options"), "defaultType", "future")

      type = Runtime.safe_string(params, "type", default_type)
      params = Runtime.omit(params, "type")
      _ = params
      sub_type = nil
      _ = sub_type

      ccxt_match =
        Runtime.handle_sub_type_and_params(
          exchange,
          "fetchAccountPositions",
          nil,
          params,
          "linear"
        )

      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "fetchAccountPositions",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      response = nil
      _ = response

      {params, response} =
        if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
          {params, response} =
            if Runtime.truthy(is_portfolio_margin) do
              response = Runtime.call_raw!(Raw, fetcher, "papiv2_get_um_account", [params])
              _ = response

              {params, response}
            else
              use_v2 = nil
              _ = use_v2

              ccxt_match =
                Runtime.handle_option_and_params(
                  exchange,
                  params,
                  "fetchAccountPositions",
                  "useV2",
                  false
                )

              use_v2 = Runtime.safe_value(ccxt_match, 0, nil)
              params = Runtime.safe_value(ccxt_match, 1, nil)
              _ = use_v2
              _ = params

              {response} =
                if Runtime.truthy(not Runtime.truthy(use_v2)) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "fapiprivatev3_get_account", [params])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "fapiprivatev2_get_account", [params])

                  _ = response

                  {response}
                end

              _ = response

              {params, response}
            end

          _ = params
          _ = response

          {params, response}
        else
          {response} =
            if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  response = Runtime.call_raw!(Raw, fetcher, "papi_get_cm_account", [params])
                  _ = response

                  {response}
                else
                  response = Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_account", [params])
                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":not_supported", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchPositions() supports linear and inverse contracts only"
                 ])}
              )
            end

          _ = response

          {params, response}
        end

      _ = params
      _ = response

      filter_closed = nil
      _ = filter_closed

      ccxt_match =
        Runtime.handle_option_and_params(
          exchange,
          params,
          "fetchAccountPositions",
          "filterClosed",
          false
        )

      filter_closed = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = filter_closed
      _ = params

      result =
        Runtime.call_generated!(exchange, __MODULE__, :parse_account_positions, [
          response,
          filter_closed
        ])

      symbols = Runtime.market_symbols(exchange, symbols)
      _ = symbols
      {:ok, Runtime.filter_by_array_positions(result, "symbol", symbols, false)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_positions_risk(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                                  {:ok, map()} | {:error, term()})) ::
          {:ok, list()} | {:error, term()}
  def fetch_positions_risk(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      if Runtime.truthy(symbols != nil) do
        if Runtime.truthy(not Runtime.truthy(Runtime.is_array(symbols))) do
          throw(
            {:ccxt_error,
             Runtime.new_error_reason(":arguments_required", [
               Runtime.safe_value(exchange, "id") <>
                 " fetchPositionsRisk() requires an array argument for symbols"
             ])}
          )
        end
      end

      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange

      Runtime.call_generated!(exchange, __MODULE__, :load_leverage_brackets, [
        false,
        params,
        fetcher
      ])

      request = %{}
      default_type = "future"
      _ = default_type

      default_type =
        Runtime.safe_string(Runtime.safe_value(exchange, "options"), "defaultType", default_type)

      _ = default_type
      type = Runtime.safe_string(params, "type", default_type)
      sub_type = nil
      _ = sub_type

      ccxt_match =
        Runtime.handle_sub_type_and_params(exchange, "fetchPositionsRisk", nil, params, "linear")

      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "fetchPositionsRisk",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      params = Runtime.omit(params, "type")
      _ = params
      response = nil
      _ = response

      {params, response} =
        if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
          {params, response} =
            if Runtime.truthy(is_portfolio_margin) do
              response =
                Runtime.call_raw!(Raw, fetcher, "papi_get_um_positionrisk", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {params, response}
            else
              use_v2 = nil
              _ = use_v2

              ccxt_match =
                Runtime.handle_option_and_params(
                  exchange,
                  params,
                  "fetchPositionsRisk",
                  "useV2",
                  false
                )

              use_v2 = Runtime.safe_value(ccxt_match, 0, nil)
              params = Runtime.safe_value(ccxt_match, 1, nil)
              _ = use_v2
              _ = params
              params = Runtime.extend(request, params)
              _ = params

              {response} =
                if Runtime.truthy(not Runtime.truthy(use_v2)) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "fapiprivatev3_get_positionrisk", [params])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "fapiprivatev2_get_positionrisk", [params])

                  _ = response

                  {response}
                end

              _ = response

              {params, response}
            end

          _ = params
          _ = response

          {params, response}
        else
          {response} =
            if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "papi_get_cm_positionrisk", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_positionrisk", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":not_supported", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchPositionsRisk() supports linear and inverse contracts only"
                 ])}
              )
            end

          _ = response

          {params, response}
        end

      _ = params
      _ = response

      result = []
      _ = result

      {result} =
        Enum.reduce_while(Runtime.index_range(Runtime.js_length(response), 0), {result}, fn i,
                                                                                            {result} ->
          try do
            raw_position = Runtime.safe_value(response, i)
            entry_price_string = Runtime.safe_string(raw_position, "entryPrice")

            {result} =
              if Runtime.truthy(Runtime.string_gt?(entry_price_string, "0")) do
                result =
                  Runtime.push(
                    result,
                    Runtime.call_generated!(exchange, __MODULE__, :parse_position_risk, [
                      Runtime.safe_value(response, i)
                    ])
                  )

                {result}
              else
                {result}
              end

            _ = result
            {:cont, {result}}
          catch
            :continue -> {:cont, {result}}
            :break -> {:halt, {result}}
          end
        end)

      _ = result
      symbols = Runtime.market_symbols(exchange, symbols)
      _ = symbols
      {:ok, Runtime.filter_by_array_positions(result, "symbol", symbols, false)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_funding_history(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_funding_history(
        symbol \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchFundingHistory" => %{"defaultType" => "future"},
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => true
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = nil
      _ = market
      request = %{"incomeType" => "FUNDING_FEE"}
      _ = request

      {market, request} =
        if Runtime.truthy(symbol != nil) do
          market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
          _ = market
          request = Runtime.put_value(request, "symbol", Runtime.safe_value(market, "id"))

          if Runtime.truthy(not Runtime.truthy(Runtime.safe_value(market, "swap"))) do
            throw(
              {:ccxt_error,
               Runtime.new_error_reason(":not_supported", [
                 Runtime.safe_value(exchange, "id") <>
                   " fetchFundingHistory() supports swap contracts only"
               ])}
            )
          end

          {market, request}
        else
          {market, request}
        end

      _ = market
      _ = request

      sub_type = nil
      _ = sub_type

      ccxt_match =
        Runtime.handle_sub_type_and_params(
          exchange,
          "fetchFundingHistory",
          market,
          params,
          "linear"
        )

      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "fetchFundingHistory",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      ccxt_match = Runtime.handle_until_option("endTime", request, params)
      request = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = request
      _ = params

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(limit != nil) do
          request = Runtime.put_value(request, "limit", limit)

          {request}
        else
          {request}
        end

      _ = request

      default_type =
        Runtime.safe_string2(
          Runtime.safe_value(exchange, "options"),
          "fetchFundingHistory",
          "defaultType",
          "future"
        )

      type = Runtime.safe_string(params, "type", default_type)
      params = Runtime.omit(params, "type")
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
          {response} =
            if Runtime.truthy(is_portfolio_margin) do
              response =
                Runtime.call_raw!(Raw, fetcher, "papi_get_um_income", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            else
              response =
                Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_income", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            end

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "papi_get_cm_income", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_income", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":not_supported", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchFundingHistory() supports linear and inverse contracts only"
                 ])}
              )
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, Runtime.parse_incomes(exchange, __MODULE__, response, market, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec set_leverage(integer(), String.t() | nil, params(), (RawEndpoint.t(), params() ->
                                                               {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def set_leverage(leverage, symbol \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = leverage
    _ = symbol
    _ = params

    try do
      if Runtime.truthy(symbol == nil) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":arguments_required", [
             Runtime.safe_value(exchange, "id") <> " setLeverage() requires a symbol argument"
           ])}
        )
      end

      if Runtime.truthy(Runtime.truthy(leverage < 1) or Runtime.truthy(leverage > 125)) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":bad_request", [
             Runtime.safe_value(exchange, "id") <> " leverage should be between 1 and 125"
           ])}
        )
      end

      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      request = %{"symbol" => Runtime.safe_value(market, "id"), "leverage" => leverage}
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "setLeverage",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.safe_value(market, "linear")) do
          {response} =
            if Runtime.truthy(is_portfolio_margin) do
              response =
                Runtime.call_raw!(Raw, fetcher, "papi_post_um_leverage", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            else
              response =
                Runtime.call_raw!(Raw, fetcher, "fapiprivate_post_leverage", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            end

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "papi_post_cm_leverage", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "dapiprivate_post_leverage", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":not_supported", [
                   Runtime.safe_value(exchange, "id") <>
                     " setLeverage() supports linear and inverse contracts only"
                 ])}
              )
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, response}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec set_margin_mode(String.t(), String.t() | nil, params(), (RawEndpoint.t(), params() ->
                                                                   {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def set_margin_mode(margin_mode, symbol \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false,
            "throwMarginModeAlreadySet" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = margin_mode
    _ = symbol
    _ = params

    try do
      if Runtime.truthy(symbol == nil) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":arguments_required", [
             Runtime.safe_value(exchange, "id") <> " setMarginMode() requires a symbol argument"
           ])}
        )
      end

      margin_mode = Runtime.upcase(margin_mode)
      _ = margin_mode

      {margin_mode} =
        if Runtime.truthy(margin_mode == "CROSS") do
          margin_mode = "CROSSED"
          _ = margin_mode

          {margin_mode}
        else
          {margin_mode}
        end

      _ = margin_mode

      if Runtime.truthy(
           Runtime.truthy(margin_mode != "ISOLATED") and Runtime.truthy(margin_mode != "CROSSED")
         ) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":bad_request", [
             Runtime.safe_value(exchange, "id") <> " marginMode must be either isolated or cross"
           ])}
        )
      end

      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      request = %{"symbol" => Runtime.safe_value(market, "id"), "marginType" => margin_mode}
      response = nil
      _ = response

      {response} =
        try do
          {response} =
            if Runtime.truthy(Runtime.safe_value(market, "linear")) do
              response =
                Runtime.call_raw!(Raw, fetcher, "fapiprivate_post_margintype", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            else
              {response} =
                if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "dapiprivate_post_margintype", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                else
                  throw(
                    {:ccxt_error,
                     Runtime.new_error_reason(":not_supported", [
                       Runtime.safe_value(exchange, "id") <>
                         " setMarginMode() supports linear and inverse contracts only"
                     ])}
                  )
                end

              _ = response

              {response}
            end

          _ = response

          {response}
        catch
          {:ccxt_error, e} ->
            _ = e

            {response} =
              if Runtime.truthy(Runtime.error_instanceof?(e, ":margin_mode_already_set")) do
                throw_margin_mode_already_set =
                  Runtime.safe_bool(
                    Runtime.safe_value(exchange, "options"),
                    "throwMarginModeAlreadySet",
                    false
                  )

                {response} =
                  if Runtime.truthy(throw_margin_mode_already_set) do
                    throw({:ccxt_error, e})
                  else
                    response = %{"code" => -4046, "msg" => "No need to change margin type."}
                    _ = response

                    {response}
                  end

                _ = response

                {response}
              else
                throw({:ccxt_error, e})
              end

            _ = response

            {response}
        end

      _ = response
      {:ok, response}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec set_position_mode(boolean(), String.t() | nil, params(), (RawEndpoint.t(), params() ->
                                                                    {:ok, map()}
                                                                    | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def set_position_mode(hedged, symbol \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = hedged
    _ = symbol
    _ = params

    try do
      market = nil
      _ = market

      {market} =
        if Runtime.truthy(symbol != nil) do
          market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
          _ = market

          {market}
        else
          {market}
        end

      _ = market

      type = nil
      _ = type

      ccxt_match =
        Runtime.handle_market_type_and_params(exchange, "setPositionMode", market, params)

      type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = type
      _ = params
      sub_type = nil
      _ = sub_type
      ccxt_match = Runtime.handle_sub_type_and_params(exchange, "setPositionMode", market, params)
      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "setPositionMode",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      dual_side_position = nil
      _ = dual_side_position

      {dual_side_position} =
        if Runtime.truthy(hedged) do
          dual_side_position = "true"
          _ = dual_side_position

          {dual_side_position}
        else
          dual_side_position = "false"
          _ = dual_side_position

          {dual_side_position}
        end

      _ = dual_side_position

      request = %{"dualSidePosition" => dual_side_position}
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
          {response} =
            if Runtime.truthy(is_portfolio_margin) do
              response =
                Runtime.call_raw!(Raw, fetcher, "papi_post_cm_positionside_dual", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            else
              response =
                Runtime.call_raw!(Raw, fetcher, "dapiprivate_post_positionside_dual", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            end

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "papi_post_um_positionside_dual", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "fapiprivate_post_positionside_dual", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":bad_request", [
                   Runtime.safe_value(exchange, "id") <>
                     " setPositionMode() supports linear and inverse contracts only"
                 ])}
              )
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, response}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_leverages(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                             {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_leverages(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange

      Runtime.call_generated!(exchange, __MODULE__, :load_leverage_brackets, [
        false,
        params,
        fetcher
      ])

      type = nil
      _ = type
      ccxt_match = Runtime.handle_market_type_and_params(exchange, "fetchLeverages", nil, params)
      type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = type
      _ = params
      sub_type = nil
      _ = sub_type

      ccxt_match =
        Runtime.handle_sub_type_and_params(exchange, "fetchLeverages", nil, params, "linear")

      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "fetchLeverages",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
          {response} =
            if Runtime.truthy(is_portfolio_margin) do
              response = Runtime.call_raw!(Raw, fetcher, "papi_get_um_account", [params])
              _ = response

              {response}
            else
              response = Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_symbolconfig", [params])
              _ = response

              {response}
            end

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  response = Runtime.call_raw!(Raw, fetcher, "papi_get_cm_account", [params])
                  _ = response

                  {response}
                else
                  response = Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_account", [params])
                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":not_supported", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchLeverages() supports linear and inverse contracts only"
                 ])}
              )
            end

          _ = response

          {response}
        end

      _ = response

      leverages = Runtime.safe_list(response, "positions", [])
      _ = leverages

      {leverages} =
        if Runtime.truthy(Runtime.is_array(response)) do
          leverages = response
          _ = leverages

          {leverages}
        else
          {leverages}
        end

      _ = leverages

      {:ok, Runtime.parse_leverages(exchange, __MODULE__, leverages, symbols, "symbol", nil)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_leverage(term(), term(), term()) :: term()
  def parse_leverage(exchange, leverage, market \\ nil) do
    _ = exchange
    _ = leverage
    _ = market

    try do
      market_id = Runtime.safe_string(leverage, "symbol")
      margin_mode_raw = Runtime.safe_bool(leverage, "isolated")
      margin_mode = nil
      _ = margin_mode

      {margin_mode} =
        if Runtime.truthy(margin_mode_raw != nil) do
          margin_mode =
            if(
              Runtime.truthy(margin_mode_raw),
              do: "isolated",
              else: "cross"
            )

          _ = margin_mode

          {margin_mode}
        else
          {margin_mode}
        end

      _ = margin_mode

      margin_type_raw = Runtime.safe_string_lower(leverage, "marginType")

      {margin_mode} =
        if Runtime.truthy(margin_type_raw != nil) do
          margin_mode =
            if(
              Runtime.truthy(margin_type_raw == "crossed"),
              do: "cross",
              else: "isolated"
            )

          _ = margin_mode

          {margin_mode}
        else
          {margin_mode}
        end

      _ = margin_mode

      side = Runtime.safe_string_lower(leverage, "positionSide")
      long_leverage = nil
      _ = long_leverage
      short_leverage = nil
      _ = short_leverage
      leverage_value = Runtime.safe_integer(leverage, "leverage")

      {long_leverage, short_leverage} =
        if Runtime.truthy(Runtime.truthy(side == nil) or Runtime.truthy(side == "both")) do
          long_leverage = leverage_value
          _ = long_leverage
          short_leverage = leverage_value
          _ = short_leverage

          {long_leverage, short_leverage}
        else
          {long_leverage, short_leverage} =
            if Runtime.truthy(side == "long") do
              long_leverage = leverage_value
              _ = long_leverage

              {long_leverage, short_leverage}
            else
              {short_leverage} =
                if Runtime.truthy(side == "short") do
                  short_leverage = leverage_value
                  _ = short_leverage

                  {short_leverage}
                else
                  {short_leverage}
                end

              _ = short_leverage

              {long_leverage, short_leverage}
            end

          _ = long_leverage
          _ = short_leverage

          {long_leverage, short_leverage}
        end

      _ = long_leverage
      _ = short_leverage

      throw(
        {:ccxt_return,
         %{
           info: leverage,
           symbol: Runtime.safe_symbol(exchange, market_id, market),
           marginMode: margin_mode,
           longLeverage: long_leverage,
           shortLeverage: short_leverage
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_settlement_history(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_settlement_history(
        symbol \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "option",
            "fetchMarkets" => %{"types" => ["option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange

      market =
        if(
          Runtime.truthy(symbol == nil),
          do: nil,
          else: Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
        )

      type = nil
      _ = type

      ccxt_match =
        Runtime.handle_market_type_and_params(exchange, "fetchSettlementHistory", market, params)

      type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = type
      _ = params

      if Runtime.truthy(type != "option") do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " fetchSettlementHistory() supports option markets only"
           ])}
        )
      end

      request = %{}
      _ = request

      {request, symbol} =
        if Runtime.truthy(symbol != nil) do
          symbol = Runtime.safe_value(market, "symbol")
          _ = symbol

          request =
            Runtime.put_value(
              request,
              "underlying",
              Runtime.add_or_concat(
                Runtime.safe_value(market, "baseId"),
                Runtime.safe_value(market, "quoteId")
              )
            )

          {request, symbol}
        else
          {request, symbol}
        end

      _ = request
      _ = symbol

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(limit != nil) do
          request = Runtime.put_value(request, "limit", limit)

          {request}
        else
          {request}
        end

      _ = request

      response =
        Runtime.call_raw!(Raw, fetcher, "eapipublic_get_exercisehistory", [
          Runtime.extend(request, params)
        ])

      settlements =
        Runtime.call_generated!(exchange, __MODULE__, :parse_settlements, [response, market])

      sorted = Runtime.sort_by(settlements, "timestamp")
      {:ok, Runtime.filter_by_symbol_since_limit(sorted, symbol, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_my_settlement_history(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_my_settlement_history(
        symbol \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "option",
            "fetchMarkets" => %{"types" => ["option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange

      market =
        if(
          Runtime.truthy(symbol == nil),
          do: nil,
          else: Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
        )

      type = nil
      _ = type

      ccxt_match =
        Runtime.handle_market_type_and_params(
          exchange,
          "fetchMySettlementHistory",
          market,
          params
        )

      type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = type
      _ = params

      if Runtime.truthy(type != "option") do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " fetchMySettlementHistory() supports option markets only"
           ])}
        )
      end

      request = %{}
      _ = request

      {request, symbol} =
        if Runtime.truthy(symbol != nil) do
          request = Runtime.put_value(request, "symbol", Runtime.safe_value(market, "id"))
          symbol = Runtime.safe_value(market, "symbol")
          _ = symbol

          {request, symbol}
        else
          {request, symbol}
        end

      _ = request
      _ = symbol

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(limit != nil) do
          request = Runtime.put_value(request, "limit", limit)

          {request}
        else
          {request}
        end

      _ = request

      response =
        Runtime.call_raw!(Raw, fetcher, "eapiprivate_get_exerciserecord", [
          Runtime.extend(request, params)
        ])

      settlements =
        Runtime.call_generated!(exchange, __MODULE__, :parse_settlements, [response, market])

      sorted = Runtime.sort_by(settlements, "timestamp")
      {:ok, Runtime.filter_by_symbol_since_limit(sorted, symbol, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_settlement(term(), term(), term()) :: term()
  def parse_settlement(exchange, settlement, market) do
    _ = exchange
    _ = settlement
    _ = market

    try do
      timestamp = Runtime.safe_integer2(settlement, "expiryDate", "createDate")
      market_id = Runtime.safe_string(settlement, "symbol")

      throw(
        {:ccxt_return,
         %{
           "info" => settlement,
           "symbol" => Runtime.safe_symbol(exchange, market_id, market),
           "price" => Runtime.safe_number2(settlement, "realStrikePrice", "exercisePrice"),
           "timestamp" => timestamp,
           "datetime" => Runtime.iso8601(timestamp)
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec parse_settlements(term(), term(), term()) :: term()
  def parse_settlements(exchange, settlements, market) do
    _ = exchange
    _ = settlements
    _ = market

    try do
      result = []
      _ = result

      {result} =
        Enum.reduce_while(Runtime.index_range(Runtime.js_length(settlements), 0), {result}, fn i,
                                                                                               {result} ->
          try do
            result =
              Runtime.push(
                result,
                Runtime.call_generated!(exchange, __MODULE__, :parse_settlement, [
                  Runtime.safe_value(settlements, i),
                  market
                ])
              )

            {:cont, {result}}
          catch
            :continue -> {:cont, {result}}
            :break -> {:halt, {result}}
          end
        end)

      _ = result
      throw({:ccxt_return, result})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_ledger_entry(String.t(), String.t() | nil, params(), (RawEndpoint.t(), params() ->
                                                                      {:ok, map()}
                                                                      | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_ledger_entry(id, code \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "option",
            "fetchMarkets" => %{"types" => ["option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = id
    _ = code
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      type = nil
      _ = type

      ccxt_match =
        Runtime.handle_market_type_and_params(exchange, "fetchLedgerEntry", nil, params)

      type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = type
      _ = params

      if Runtime.truthy(type != "option") do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":bad_request", [
             Runtime.safe_value(exchange, "id") <>
               " fetchLedgerEntry() can only be used for type option"
           ])}
        )
      end

      Runtime.check_required_argument(exchange, "fetchLedgerEntry", code, "code")
      currency = Runtime.currency(exchange, code)
      request = %{"recordId" => id, "currency" => Runtime.safe_value(currency, "id")}

      response =
        Runtime.call_raw!(Raw, fetcher, "eapiprivate_get_bill", [Runtime.extend(request, params)])

      first = Runtime.safe_dict(response, 0, response)
      {:ok, Runtime.call_generated!(exchange, __MODULE__, :parse_ledger_entry, [first, currency])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_ledger(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_ledger(
        code \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchLedger" => %{"paginate" => false},
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      paginate = false
      _ = paginate
      ccxt_match = Runtime.handle_option_and_params(exchange, params, "fetchLedger", "paginate")
      paginate = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = paginate
      _ = params

      if Runtime.truthy(paginate) do
        throw(
          {:ccxt_return,
           Runtime.fetch_paginated_call_dynamic(
             exchange,
             __MODULE__,
             fetcher,
             "fetchLedger",
             code,
             since,
             limit,
             params,
             nil,
             false
           )}
        )
      end

      type = nil
      _ = type
      sub_type = nil
      _ = sub_type
      currency = nil
      _ = currency

      {currency} =
        if Runtime.truthy(code != nil) do
          currency = Runtime.currency(exchange, code)
          _ = currency

          {currency}
        else
          {currency}
        end

      _ = currency

      request = %{}
      _ = request
      ccxt_match = Runtime.handle_market_type_and_params(exchange, "fetchLedger", nil, params)
      type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = type
      _ = params
      ccxt_match = Runtime.handle_sub_type_and_params(exchange, "fetchLedger", nil, params)
      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(limit != nil) do
          request = Runtime.put_value(request, "limit", limit)

          {request}
        else
          {request}
        end

      _ = request

      until = Runtime.safe_integer(params, "until")

      {params, request} =
        if Runtime.truthy(until != nil) do
          params = Runtime.omit(params, "until")
          _ = params
          request = Runtime.put_value(request, "endTime", until)

          {params, request}
        else
          {params, request}
        end

      _ = params
      _ = request

      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "fetchLedger",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      response = nil
      _ = response

      {request, response} =
        if Runtime.truthy(type == "option") do
          Runtime.check_required_argument(exchange, "fetchLedger", code, "code")
          request = Runtime.put_value(request, "currency", Runtime.safe_value(currency, "id"))

          response =
            Runtime.call_raw!(Raw, fetcher, "eapiprivate_get_bill", [
              Runtime.extend(request, params)
            ])

          _ = response

          {request, response}
        else
          {response} =
            if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "papi_get_um_income", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_income", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              {response} =
                if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
                  {response} =
                    if Runtime.truthy(is_portfolio_margin) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "papi_get_cm_income", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_income", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                else
                  throw(
                    {:ccxt_error,
                     Runtime.new_error_reason(":not_supported", [
                       Runtime.safe_value(exchange, "id") <>
                         " fetchLedger() supports contract wallets only"
                     ])}
                  )
                end

              _ = response

              {response}
            end

          _ = response

          {request, response}
        end

      _ = request
      _ = response

      {:ok, Runtime.parse_ledger(exchange, __MODULE__, response, currency, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_ledger_entry(term(), term(), term()) :: term()
  def parse_ledger_entry(exchange, item, currency \\ nil) do
    _ = exchange
    _ = item
    _ = currency

    try do
      amount = Runtime.safe_string2(item, "amount", "income")
      _ = amount
      direction = nil
      _ = direction

      {amount, direction} =
        if Runtime.truthy(Runtime.string_lte?(amount, "0")) do
          direction = "out"
          _ = direction
          amount = Runtime.multiply_number_string("-1", amount)
          _ = amount

          {amount, direction}
        else
          direction = "in"
          _ = direction

          {amount, direction}
        end

      _ = amount
      _ = direction

      currency_id = Runtime.safe_string(item, "asset")
      code = Runtime.safe_currency_code(currency_id, currency)
      currency = Runtime.safe_currency(currency_id, currency)
      _ = currency
      timestamp = Runtime.safe_integer2(item, "createDate", "time")
      type = Runtime.safe_string2(item, "type", "incomeType")

      throw(
        {:ccxt_return,
         Runtime.safe_ledger_entry(
           %{
             "info" => item,
             "id" => Runtime.safe_string2(item, "id", "tranId"),
             "direction" => direction,
             "account" => nil,
             "referenceAccount" => nil,
             "referenceId" => Runtime.safe_string(item, "tradeId"),
             "type" =>
               Runtime.call_generated!(exchange, __MODULE__, :parse_ledger_entry_type, [type]),
             "currency" => code,
             "amount" => Runtime.parse_number(amount),
             "timestamp" => timestamp,
             "datetime" => Runtime.iso8601(timestamp),
             "before" => nil,
             "after" => nil,
             "status" => nil,
             "fee" => nil
           },
           currency
         )}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec parse_ledger_entry_type(term(), term()) :: term()
  def parse_ledger_entry_type(exchange, type) do
    _ = exchange
    _ = type

    try do
      ledger_type = %{
        "FEE" => "fee",
        "FUNDING_FEE" => "fee",
        "OPTIONS_PREMIUM_FEE" => "fee",
        "POSITION_LIMIT_INCREASE_FEE" => "fee",
        "CONTRACT" => "trade",
        "REALIZED_PNL" => "trade",
        "TRANSFER" => "transfer",
        "CROSS_COLLATERAL_TRANSFER" => "transfer",
        "INTERNAL_TRANSFER" => "transfer",
        "COIN_SWAP_DEPOSIT" => "deposit",
        "COIN_SWAP_WITHDRAW" => "withdrawal",
        "OPTIONS_SETTLE_PROFIT" => "settlement",
        "DELIVERED_SETTELMENT" => "settlement",
        "WELCOME_BONUS" => "cashback",
        "CONTEST_REWARD" => "cashback",
        "COMMISSION_REBATE" => "rebate",
        "API_REBATE" => "rebate",
        "REFERRAL_KICKBACK" => "referral",
        "COMMISSION" => "commission"
      }

      throw({:ccxt_return, Runtime.safe_string(ledger_type, type, type)})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec get_network_code_by_network_url(term(), term(), term()) :: term()
  def get_network_code_by_network_url(exchange, currency_code, deposit_url \\ nil) do
    _ = exchange
    _ = currency_code
    _ = deposit_url

    try do
      if Runtime.truthy(deposit_url == nil) do
        throw({:ccxt_return, nil})
      end

      network_code = nil
      _ = network_code
      currency = Runtime.currency(exchange, currency_code)
      networks = Runtime.safe_dict(currency, "networks", %{})
      network_codes = Runtime.object_keys(networks)

      {network_code} =
        Enum.reduce_while(
          Runtime.index_range(Runtime.js_length(network_codes), 0),
          {network_code},
          fn i, {network_code} ->
            try do
              current_network_code = Runtime.safe_value(network_codes, i)

              info =
                Runtime.safe_dict(Runtime.safe_value(networks, current_network_code), "info", %{})

              site_url = Runtime.safe_string(info, "contractAddressUrl")

              {network_code} =
                if Runtime.truthy(
                     Runtime.truthy(site_url != nil) and
                       Runtime.truthy(
                         String.starts_with?(
                           deposit_url,
                           get_base_domain_from_url(exchange, site_url)
                         )
                       )
                   ) do
                  network_code = current_network_code
                  _ = network_code

                  {network_code}
                else
                  {network_code}
                end

              _ = network_code
              {:cont, {network_code}}
            catch
              :continue -> {:cont, {network_code}}
              :break -> {:halt, {network_code}}
            end
          end
        )

      _ = network_code
      throw({:ccxt_return, network_code})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec get_base_domain_from_url(term(), term()) :: term()
  def get_base_domain_from_url(exchange, url) do
    _ = exchange
    _ = url

    try do
      if Runtime.truthy(url == nil) do
        throw({:ccxt_return, nil})
      end

      url_parts = Runtime.string_split(url, "/")
      scheme = Runtime.safe_string(url_parts, 0)

      if Runtime.truthy(scheme == nil) do
        throw({:ccxt_return, nil})
      end

      domain = Runtime.safe_string(url_parts, 2)

      if Runtime.truthy(domain == nil) do
        throw({:ccxt_return, nil})
      end

      throw({:ccxt_return, scheme <> "//" <> domain <> "/"})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec sign(params(), params(), params(), params(), params(), params(), (RawEndpoint.t(),
                                                                          params() ->
                                                                            {:ok, map()}
                                                                            | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def sign(
        path,
        api \\ "public",
        method \\ "GET",
        params \\ %{},
        headers \\ nil,
        body \\ nil,
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "timeDifference" => 0,
            "recvWindow" => 10000,
            "broker" => %{
              "spot" => "x-TKT5PX2F",
              "margin" => "x-TKT5PX2F",
              "future" => "x-cvBPrNm9",
              "delivery" => "x-xcKtGhcu",
              "swap" => "x-cvBPrNm9",
              "option" => "x-xcKtGhcu",
              "inverse" => "x-xcKtGhcu"
            },
            "hasAlreadyAuthenticatedSuccessfully" => false,
            "disableFuturesSandboxWarning" => false
          }
        },
        %{
          "urls" => %{
            "test" => %{
              "dapiPublic" => "https://testnet.binancefuture.com/dapi/v1",
              "dapiPrivate" => "https://testnet.binancefuture.com/dapi/v1",
              "dapiPrivateV2" => "https://testnet.binancefuture.com/dapi/v2",
              "fapiPublic" => "https://testnet.binancefuture.com/fapi/v1",
              "fapiPublicV2" => "https://testnet.binancefuture.com/fapi/v2",
              "fapiPublicV3" => "https://testnet.binancefuture.com/fapi/v3",
              "fapiPrivate" => "https://testnet.binancefuture.com/fapi/v1",
              "fapiPrivateV2" => "https://testnet.binancefuture.com/fapi/v2",
              "fapiPrivateV3" => "https://testnet.binancefuture.com/fapi/v3",
              "public" => "https://testnet.binance.vision/api/v3",
              "private" => "https://testnet.binance.vision/api/v3",
              "v1" => "https://testnet.binance.vision/api/v1"
            },
            "demo" => %{
              "dapiPublic" => "https://demo-dapi.binance.com/dapi/v1",
              "dapiPrivate" => "https://demo-dapi.binance.com/dapi/v1",
              "dapiPrivateV2" => "https://demo-dapi.binance.com/dapi/v2",
              "fapiPublic" => "https://demo-fapi.binance.com/fapi/v1",
              "fapiPublicV2" => "https://demo-fapi.binance.com/fapi/v2",
              "fapiPublicV3" => "https://demo-fapi.binance.com/fapi/v3",
              "fapiPrivate" => "https://demo-fapi.binance.com/fapi/v1",
              "fapiPrivateV2" => "https://demo-fapi.binance.com/fapi/v2",
              "fapiPrivateV3" => "https://demo-fapi.binance.com/fapi/v3",
              "public" => "https://demo-api.binance.com/api/v3",
              "private" => "https://demo-api.binance.com/api/v3",
              "v1" => "https://demo-api.binance.com/api/v1"
            },
            "api" => %{
              "sapi" => "https://api.binance.com/sapi/v1",
              "sapiV2" => "https://api.binance.com/sapi/v2",
              "sapiV3" => "https://api.binance.com/sapi/v3",
              "sapiV4" => "https://api.binance.com/sapi/v4",
              "dapiPublic" => "https://dapi.binance.com/dapi/v1",
              "dapiPrivate" => "https://dapi.binance.com/dapi/v1",
              "eapiPublic" => "https://eapi.binance.com/eapi/v1",
              "eapiPrivate" => "https://eapi.binance.com/eapi/v1",
              "dapiPrivateV2" => "https://dapi.binance.com/dapi/v2",
              "dapiData" => "https://dapi.binance.com/futures/data",
              "fapiPublic" => "https://fapi.binance.com/fapi/v1",
              "fapiPublicV2" => "https://fapi.binance.com/fapi/v2",
              "fapiPublicV3" => "https://fapi.binance.com/fapi/v3",
              "fapiPrivate" => "https://fapi.binance.com/fapi/v1",
              "fapiPrivateV2" => "https://fapi.binance.com/fapi/v2",
              "fapiPrivateV3" => "https://fapi.binance.com/fapi/v3",
              "fapiData" => "https://fapi.binance.com/futures/data",
              "public" => "https://api.binance.com/api/v3",
              "private" => "https://api.binance.com/api/v3",
              "v1" => "https://api.binance.com/api/v1",
              "papi" => "https://papi.binance.com/papi/v1",
              "papiV2" => "https://papi.binance.com/papi/v2"
            }
          }
        }
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = path
    _ = api
    _ = method
    _ = params
    _ = headers
    _ = body

    try do
      urls = Runtime.safe_value(exchange, "urls")

      if Runtime.truthy(
           not Runtime.truthy(Runtime.has_key?(Runtime.safe_value(urls, "api"), api))
         ) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " does not have a testnet/sandbox URL for " <> api <> " endpoints"
           ])}
        )
      end

      url =
        Runtime.safe_value(Runtime.safe_value(Runtime.safe_value(exchange, "urls"), "api"), api)

      _ = url
      url = url <> "/" <> path
      _ = url

      {headers} =
        if Runtime.truthy(path == "historicalTrades") do
          {headers} =
            if Runtime.truthy(Runtime.safe_value(exchange, "apiKey")) do
              headers = %{"X-MBX-APIKEY" => Runtime.safe_value(exchange, "apiKey")}
              _ = headers

              {headers}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":authentication_error", [
                   Runtime.safe_value(exchange, "id") <>
                     " historicalTrades endpoint requires `apiKey` credential"
                 ])}
              )
            end

          _ = headers

          {headers}
        else
          {headers}
        end

      _ = headers

      user_data_stream =
        Runtime.truthy(
          Runtime.truthy(path == "userDataStream") or Runtime.truthy(path == "listenKey")
        ) or Runtime.truthy(path == "userListenToken")

      {body, headers, params, url} =
        if Runtime.truthy(user_data_stream) do
          {body, headers} =
            if Runtime.truthy(Runtime.safe_value(exchange, "apiKey")) do
              headers = %{
                "X-MBX-APIKEY" => Runtime.safe_value(exchange, "apiKey"),
                "Content-Type" => "application/x-www-form-urlencoded"
              }

              _ = headers

              {body} =
                if Runtime.truthy(method != "GET") do
                  body = Runtime.urlencode(params)
                  _ = body

                  {body}
                else
                  {body}
                end

              _ = body

              {body, headers}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":authentication_error", [
                   Runtime.safe_value(exchange, "id") <>
                     " userDataStream endpoint requires `apiKey` credential"
                 ])}
              )
            end

          _ = body
          _ = headers

          {body, headers, params, url}
        else
          {body, headers, params, url} =
            if Runtime.truthy(
                 Runtime.truthy(
                   Runtime.truthy(
                     Runtime.truthy(
                       Runtime.truthy(
                         Runtime.truthy(
                           Runtime.truthy(
                             Runtime.truthy(
                               Runtime.truthy(
                                 Runtime.truthy(
                                   Runtime.truthy(
                                     Runtime.truthy(api == "private") or
                                       Runtime.truthy(api == "eapiPrivate")
                                   ) or
                                     Runtime.truthy(
                                       Runtime.truthy(api == "sapi") and
                                         Runtime.truthy(path != "system/status")
                                     )
                                 ) or Runtime.truthy(api == "sapiV2")
                               ) or Runtime.truthy(api == "sapiV3")
                             ) or Runtime.truthy(api == "sapiV4")
                           ) or Runtime.truthy(api == "dapiPrivate")
                         ) or Runtime.truthy(api == "dapiPrivateV2")
                       ) or Runtime.truthy(api == "fapiPrivate")
                     ) or Runtime.truthy(api == "fapiPrivateV2")
                   ) or Runtime.truthy(api == "fapiPrivateV3")
                 ) or
                   Runtime.truthy(
                     Runtime.truthy(api == "papiV2") or
                       Runtime.truthy(
                         Runtime.truthy(api == "papi") and Runtime.truthy(path != "ping")
                       )
                   )
               ) do
              Runtime.check_required_credentials(exchange)

              if Runtime.truthy(
                   Runtime.truthy(
                     Runtime.truthy(Runtime.index_of(url, "testnet.binancefuture.com") > -1) and
                       Runtime.truthy(Runtime.safe_value(exchange, "isSandboxModeEnabled"))
                   ) and
                     Runtime.truthy(
                       not Runtime.truthy(
                         Runtime.safe_bool(
                           Runtime.safe_value(exchange, "options"),
                           "disableFuturesSandboxWarning"
                         )
                       )
                     )
                 ) do
                throw(
                  {:ccxt_error,
                   Runtime.new_error_reason(":not_supported", [
                     Runtime.safe_value(exchange, "id") <>
                       " testnet/sandbox mode is not supported for futures anymore, please check the deprecation announcement https://t.me/ccxt_announcements/92 and consider using the demo trading instead."
                   ])}
                )
              end

              {params} =
                if Runtime.truthy(
                     Runtime.truthy(method == "POST") and
                       Runtime.truthy(
                         Runtime.truthy(path == "order") or Runtime.truthy(path == "sor/order")
                       )
                   ) do
                  new_client_order_id = Runtime.safe_string(params, "newClientOrderId")

                  {params} =
                    if Runtime.truthy(new_client_order_id == nil) do
                      is_spot_or_margin =
                        Runtime.truthy(Runtime.index_of(api, "sapi") > -1) or
                          Runtime.truthy(api == "private")

                      market_type =
                        if(
                          Runtime.truthy(is_spot_or_margin),
                          do: "spot",
                          else: "future"
                        )

                      default_id =
                        if(
                          Runtime.truthy(not Runtime.truthy(is_spot_or_margin)),
                          do: "x-xcKtGhcu",
                          else: "x-TKT5PX2F"
                        )

                      broker =
                        Runtime.safe_dict(Runtime.safe_value(exchange, "options"), "broker", %{})

                      broker_id = Runtime.safe_string(broker, market_type, default_id)

                      params =
                        Runtime.put_value(
                          params,
                          "newClientOrderId",
                          Runtime.add_or_concat(broker_id, Runtime.uuid22())
                        )

                      {params}
                    else
                      {params}
                    end

                  _ = params

                  {params}
                else
                  {params}
                end

              _ = params

              query = nil
              _ = query

              {params} =
                if Runtime.truthy(
                     Runtime.truthy(path == "batchOrders") and
                       Runtime.truthy(
                         Runtime.truthy(method == "POST") or Runtime.truthy(method == "PUT")
                       )
                   ) do
                  batch_orders = Runtime.safe_list(params, "batchOrders")
                  checked_batch_orders = batch_orders
                  _ = checked_batch_orders

                  {checked_batch_orders} =
                    if Runtime.truthy(
                         Runtime.truthy(method == "POST") and Runtime.truthy(api == "fapiPrivate")
                       ) do
                      checked_batch_orders = []
                      _ = checked_batch_orders

                      {checked_batch_orders} =
                        Enum.reduce_while(
                          Runtime.index_range(Runtime.js_length(batch_orders), 0),
                          {checked_batch_orders},
                          fn i, {checked_batch_orders} ->
                            try do
                              batch_order = Runtime.safe_value(batch_orders, i)
                              _ = batch_order

                              new_client_order_id =
                                Runtime.safe_string(batch_order, "newClientOrderId")

                              _ = new_client_order_id

                              {batch_order, new_client_order_id} =
                                if Runtime.truthy(new_client_order_id == nil) do
                                  default_id = "x-xcKtGhcu"

                                  broker =
                                    Runtime.safe_dict(
                                      Runtime.safe_value(exchange, "options"),
                                      "broker",
                                      %{}
                                    )

                                  broker_id = Runtime.safe_string(broker, "future", default_id)

                                  new_client_order_id =
                                    Runtime.add_or_concat(broker_id, Runtime.uuid22())

                                  _ = new_client_order_id

                                  batch_order =
                                    Runtime.put_value(
                                      batch_order,
                                      "newClientOrderId",
                                      new_client_order_id
                                    )

                                  {batch_order, new_client_order_id}
                                else
                                  {batch_order, new_client_order_id}
                                end

                              _ = batch_order
                              _ = new_client_order_id

                              checked_batch_orders =
                                Runtime.push(checked_batch_orders, batch_order)

                              {:cont, {checked_batch_orders}}
                            catch
                              :continue -> {:cont, {checked_batch_orders}}
                              :break -> {:halt, {checked_batch_orders}}
                            end
                          end
                        )

                      _ = checked_batch_orders

                      {checked_batch_orders}
                    else
                      {checked_batch_orders}
                    end

                  _ = checked_batch_orders

                  query_batch = Runtime.json(exchange, checked_batch_orders)
                  params = Runtime.put_value(params, "batchOrders", query_batch)

                  {params}
                else
                  {params}
                end

              _ = params

              default_recv_window =
                Runtime.safe_integer(Runtime.safe_value(exchange, "options"), "recvWindow")

              extended_params = Runtime.extend(%{"timestamp" => nonce(exchange)}, params)
              _ = extended_params

              {extended_params} =
                if Runtime.truthy(default_recv_window != nil) do
                  extended_params =
                    Runtime.put_value(extended_params, "recvWindow", default_recv_window)

                  {extended_params}
                else
                  {extended_params}
                end

              _ = extended_params

              recv_window = Runtime.safe_integer(params, "recvWindow")

              {extended_params} =
                if Runtime.truthy(recv_window != nil) do
                  extended_params = Runtime.put_value(extended_params, "recvWindow", recv_window)

                  {extended_params}
                else
                  {extended_params}
                end

              _ = extended_params

              {extended_params, query} =
                if Runtime.truthy(
                     Runtime.truthy(api == "sapi") and Runtime.truthy(path == "asset/dust")
                   ) do
                  query = Runtime.urlencode_with_array_repeat(extended_params)
                  _ = query

                  {extended_params, query}
                else
                  {extended_params, query} =
                    if Runtime.truthy(
                         Runtime.truthy(
                           Runtime.truthy(
                             Runtime.truthy(
                               Runtime.truthy(path == "batchOrders") or
                                 Runtime.truthy(Runtime.index_of(path, "sub-account") >= 0)
                             ) or Runtime.truthy(path == "capital/withdraw/apply")
                           ) or Runtime.truthy(Runtime.index_of(path, "staking") >= 0)
                         ) or Runtime.truthy(Runtime.index_of(path, "simple-earn") >= 0)
                       ) do
                      {extended_params, query} =
                        if Runtime.truthy(
                             Runtime.truthy(method == "DELETE") and
                               Runtime.truthy(path == "batchOrders")
                           ) do
                          orderidlist = Runtime.safe_list(extended_params, "orderidlist", [])

                          origclientorderidlist =
                            Runtime.safe_list2(
                              extended_params,
                              "origclientorderidlist",
                              "origClientOrderIdList",
                              []
                            )

                          extended_params =
                            Runtime.omit(extended_params, [
                              "orderidlist",
                              "origclientorderidlist",
                              "origClientOrderIdList"
                            ])

                          _ = extended_params

                          {extended_params} =
                            if Runtime.truthy(Runtime.has_key?(extended_params, "symbol")) do
                              extended_params =
                                Runtime.put_value(
                                  extended_params,
                                  "symbol",
                                  Runtime.encode_uri_component(
                                    Runtime.safe_value(extended_params, "symbol")
                                  )
                                )

                              {extended_params}
                            else
                              {extended_params}
                            end

                          _ = extended_params

                          query = Runtime.rawencode(extended_params)
                          _ = query
                          orderidlist_length = Runtime.js_length(orderidlist)
                          origclientorderidlist_length = Runtime.js_length(origclientorderidlist)

                          {query} =
                            if Runtime.truthy(orderidlist_length > 0) do
                              query =
                                query <>
                                  "&" <>
                                  "orderidlist=%5B" <> Runtime.join(orderidlist, "%2C") <> "%5D"

                              _ = query

                              {query}
                            else
                              {query}
                            end

                          _ = query

                          {query} =
                            if Runtime.truthy(origclientorderidlist_length > 0) do
                              new_client_order_ids = []
                              _ = new_client_order_ids

                              {new_client_order_ids} =
                                Enum.reduce_while(
                                  Runtime.index_range(origclientorderidlist_length, 0),
                                  {new_client_order_ids},
                                  fn i, {new_client_order_ids} ->
                                    try do
                                      new_client_order_ids =
                                        Runtime.push(
                                          new_client_order_ids,
                                          "%22" <>
                                            Runtime.safe_value(origclientorderidlist, i) <> "%22"
                                        )

                                      {:cont, {new_client_order_ids}}
                                    catch
                                      :continue -> {:cont, {new_client_order_ids}}
                                      :break -> {:halt, {new_client_order_ids}}
                                    end
                                  end
                                )

                              _ = new_client_order_ids

                              query =
                                query <>
                                  "&" <>
                                  "origclientorderidlist=%5B" <>
                                  Runtime.join(new_client_order_ids, "%2C") <> "%5D"

                              _ = query

                              {query}
                            else
                              {query}
                            end

                          _ = query

                          {extended_params, query}
                        else
                          query = Runtime.rawencode(extended_params)
                          _ = query

                          {extended_params, query}
                        end

                      _ = extended_params
                      _ = query

                      {extended_params, query}
                    else
                      query = Runtime.urlencode(extended_params)
                      _ = query

                      {extended_params, query}
                    end

                  _ = extended_params
                  _ = query

                  {extended_params, query}
                end

              _ = extended_params
              _ = query

              signature = nil
              _ = signature

              {signature} =
                if Runtime.truthy(
                     Runtime.index_of(Runtime.safe_value(exchange, "secret"), "PRIVATE KEY") > -1
                   ) do
                  {signature} =
                    if Runtime.truthy(
                         Runtime.js_length(Runtime.safe_value(exchange, "secret")) > 120
                       ) do
                      signature =
                        Runtime.encode_uri_component(
                          Runtime.rsa(query, Runtime.safe_value(exchange, "secret"), :sha256)
                        )

                      _ = signature

                      {signature}
                    else
                      signature =
                        Runtime.encode_uri_component(
                          Runtime.eddsa(
                            Runtime.encode(query),
                            Runtime.safe_value(exchange, "secret"),
                            :ed25519
                          )
                        )

                      _ = signature

                      {signature}
                    end

                  _ = signature

                  {signature}
                else
                  signature =
                    Runtime.hmac(
                      Runtime.encode(query),
                      Runtime.encode(Runtime.safe_value(exchange, "secret")),
                      :sha256
                    )

                  _ = signature

                  {signature}
                end

              _ = signature

              query = query <> "&" <> "signature=" <> signature
              _ = query
              headers = %{"X-MBX-APIKEY" => Runtime.safe_value(exchange, "apiKey")}
              _ = headers

              {body, headers, url} =
                if Runtime.truthy(
                     Runtime.truthy(method == "GET") or Runtime.truthy(method == "DELETE")
                   ) do
                  url = url <> "?" <> query
                  _ = url

                  {body, headers, url}
                else
                  body = query
                  _ = body

                  headers =
                    Runtime.put_value(
                      headers,
                      "Content-Type",
                      "application/x-www-form-urlencoded"
                    )

                  {body, headers, url}
                end

              _ = body
              _ = headers
              _ = url

              {body, headers, params, url}
            else
              {url} =
                if Runtime.truthy(Runtime.js_length(Runtime.object_keys(params))) do
                  url = url <> "?" <> Runtime.urlencode(params)
                  _ = url

                  {url}
                else
                  {url}
                end

              _ = url

              {body, headers, params, url}
            end

          _ = body
          _ = headers
          _ = params
          _ = url

          {body, headers, params, url}
        end

      _ = body
      _ = headers
      _ = params
      _ = url

      {:ok, %{url: url, method: method, body: body, headers: headers}}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec get_exceptions_by_url(term(), term(), term()) :: term()
  def get_exceptions_by_url(exchange, url, exact_or_broad) do
    _ = exchange
    _ = url
    _ = exact_or_broad

    try do
      market_type = nil
      _ = market_type

      hostname =
        if(
          Runtime.truthy(Runtime.safe_value(exchange, "hostname") != nil),
          do: Runtime.safe_value(exchange, "hostname"),
          else: "binance.com"
        )

      {market_type} =
        if Runtime.truthy(
             Runtime.truthy(
               Runtime.truthy(String.starts_with?(url, "https://api." <> hostname <> "/")) or
                 Runtime.truthy(String.starts_with?(url, "https://demo-api"))
             ) or Runtime.truthy(String.starts_with?(url, "https://testnet.binance.vision"))
           ) do
          market_type = "spot"
          _ = market_type

          {market_type}
        else
          {market_type} =
            if Runtime.truthy(
                 Runtime.truthy(
                   Runtime.truthy(String.starts_with?(url, "https://dapi." <> hostname <> "/")) or
                     Runtime.truthy(String.starts_with?(url, "https://demo-dapi"))
                 ) or
                   Runtime.truthy(
                     String.starts_with?(url, "https://testnet.binancefuture.com/dapi")
                   )
               ) do
              market_type = "inverse"
              _ = market_type

              {market_type}
            else
              {market_type} =
                if Runtime.truthy(
                     Runtime.truthy(
                       Runtime.truthy(
                         String.starts_with?(url, "https://fapi." <> hostname <> "/")
                       ) or Runtime.truthy(String.starts_with?(url, "https://demo-fapi"))
                     ) or
                       Runtime.truthy(
                         String.starts_with?(url, "https://testnet.binancefuture.com/fapi")
                       )
                   ) do
                  market_type = "linear"
                  _ = market_type

                  {market_type}
                else
                  {market_type} =
                    if Runtime.truthy(
                         String.starts_with?(url, "https://eapi." <> hostname <> "/")
                       ) do
                      market_type = "option"
                      _ = market_type

                      {market_type}
                    else
                      {market_type} =
                        if Runtime.truthy(
                             String.starts_with?(url, "https://papi." <> hostname <> "/")
                           ) do
                          market_type = "portfolioMargin"
                          _ = market_type

                          {market_type}
                        else
                          {market_type}
                        end

                      _ = market_type

                      {market_type}
                    end

                  _ = market_type

                  {market_type}
                end

              _ = market_type

              {market_type}
            end

          _ = market_type

          {market_type}
        end

      _ = market_type

      if Runtime.truthy(market_type != nil) do
        exceptions_for_market_type =
          Runtime.safe_dict(Runtime.safe_value(exchange, "exceptions"), market_type, %{})

        throw({:ccxt_return, Runtime.safe_dict(exceptions_for_market_type, exact_or_broad, %{})})
      end

      throw({:ccxt_return, %{}})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec handle_errors(
          integer(),
          String.t(),
          String.t(),
          String.t(),
          params(),
          String.t(),
          params(),
          params(),
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, term()} | {:error, term()}
  def handle_errors(
        code,
        reason,
        url,
        method,
        headers,
        body,
        response,
        request_headers,
        request_body,
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{id: "binance", has: %{}, options: %{"hasAlreadyAuthenticatedSuccessfully" => false}},
        %{}
      )

    _ = exchange
    _ = fetcher
    _ = code
    _ = reason
    _ = url
    _ = method
    _ = headers
    _ = body
    _ = response
    _ = request_headers
    _ = request_body

    try do
      if Runtime.truthy(Runtime.truthy(code == 418) or Runtime.truthy(code == 429)) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":ddos_protection", [
             Runtime.safe_value(exchange, "id") <>
               " " <> to_string(code) <> " " <> reason <> " " <> body
           ])}
        )
      end

      if Runtime.truthy(code >= 400) do
        if Runtime.truthy(Runtime.index_of(body, "Price * QTY is zero or less") >= 0) do
          throw(
            {:ccxt_error,
             Runtime.new_error_reason(":invalid_order", [
               Runtime.safe_value(exchange, "id") <>
                 " order cost = amount * price is zero or less " <> body
             ])}
          )
        end

        if Runtime.truthy(Runtime.index_of(body, "LOT_SIZE") >= 0) do
          throw(
            {:ccxt_error,
             Runtime.new_error_reason(":invalid_order", [
               Runtime.safe_value(exchange, "id") <>
                 " order amount should be evenly divisible by lot size " <> body
             ])}
          )
        end

        if Runtime.truthy(Runtime.index_of(body, "PRICE_FILTER") >= 0) do
          throw(
            {:ccxt_error,
             Runtime.new_error_reason(":invalid_order", [
               Runtime.safe_value(exchange, "id") <>
                 " order price is invalid, i.e. exceeds allowed price precision, exceeds min price or max price limits or is invalid value in general, use this.priceToPrecision (symbol, amount) " <>
                 body
             ])}
          )
        end
      end

      if Runtime.truthy(response == nil) do
        throw({:ccxt_return, nil})
      end

      success = Runtime.safe_bool(response, "success", true)

      {response} =
        if Runtime.truthy(not Runtime.truthy(success)) do
          message_new = Runtime.safe_string(response, "msg")
          parsed_message = nil
          _ = parsed_message

          {parsed_message, response} =
            if Runtime.truthy(message_new != nil) do
              {parsed_message} =
                try do
                  parsed_message = Runtime.json_parse(message_new)
                  _ = parsed_message

                  {parsed_message}
                catch
                  {:ccxt_error, e} ->
                    _ = e
                    parsed_message = nil
                    _ = parsed_message

                    {parsed_message}
                end

              _ = parsed_message

              {response} =
                if Runtime.truthy(parsed_message != nil) do
                  response = parsed_message
                  _ = response

                  {response}
                else
                  {response}
                end

              _ = response

              {parsed_message, response}
            else
              {parsed_message, response}
            end

          _ = parsed_message
          _ = response

          {response}
        else
          {response}
        end

      _ = response

      message = Runtime.safe_string(response, "msg")

      if Runtime.truthy(message != nil) do
        Runtime.throw_exactly_matched_exception(
          get_exceptions_by_url(exchange, url, "exact"),
          message,
          Runtime.safe_value(exchange, "id") <> " " <> message
        )

        Runtime.throw_exactly_matched_exception(
          Runtime.safe_value(Runtime.safe_value(exchange, "exceptions"), "exact"),
          message,
          Runtime.safe_value(exchange, "id") <> " " <> message
        )

        Runtime.throw_broadly_matched_exception(
          get_exceptions_by_url(exchange, url, "broad"),
          message,
          Runtime.safe_value(exchange, "id") <> " " <> message
        )

        Runtime.throw_broadly_matched_exception(
          Runtime.safe_value(Runtime.safe_value(exchange, "exceptions"), "broad"),
          message,
          Runtime.safe_value(exchange, "id") <> " " <> message
        )
      end

      error = Runtime.safe_string(response, "code")

      if Runtime.truthy(error != nil) do
        if Runtime.truthy(
             Runtime.truthy(error == "200") or Runtime.truthy(Runtime.string_eq?(error, "0"))
           ) do
          throw({:ccxt_return, nil})
        end

        if Runtime.truthy(
             Runtime.truthy(error == "-2015") and
               Runtime.truthy(
                 Runtime.safe_value(
                   Runtime.safe_value(exchange, "options"),
                   "hasAlreadyAuthenticatedSuccessfully"
                 )
               )
           ) do
          throw(
            {:ccxt_error,
             Runtime.new_error_reason(":ddos_protection", [
               Runtime.safe_value(exchange, "id") <> " " <> body
             ])}
          )
        end

        feedback = Runtime.safe_value(exchange, "id") <> " " <> body

        if Runtime.truthy(message == "No need to change margin type.") do
          throw({:ccxt_error, Runtime.new_error_reason(":margin_mode_already_set", [feedback])})
        end

        Runtime.throw_exactly_matched_exception(
          get_exceptions_by_url(exchange, url, "exact"),
          error,
          feedback
        )

        Runtime.throw_exactly_matched_exception(
          Runtime.safe_value(Runtime.safe_value(exchange, "exceptions"), "exact"),
          error,
          feedback
        )

        throw({:ccxt_error, Runtime.new_error_reason(":exchange_error", [feedback])})
      end

      if Runtime.truthy(not Runtime.truthy(success)) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":exchange_error", [
             Runtime.safe_value(exchange, "id") <> " " <> body
           ])}
        )
      end

      if Runtime.truthy(Runtime.is_array(response)) do
        array_length = Runtime.js_length(response)

        if Runtime.truthy(array_length == 1) do
          element = Runtime.safe_value(response, 0)
          error_code = Runtime.safe_string(element, "code")

          if Runtime.truthy(error_code != nil) do
            Runtime.throw_exactly_matched_exception(
              get_exceptions_by_url(exchange, url, "exact"),
              error_code,
              Runtime.safe_value(exchange, "id") <> " " <> body
            )

            Runtime.throw_exactly_matched_exception(
              Runtime.safe_value(Runtime.safe_value(exchange, "exceptions"), "exact"),
              error_code,
              Runtime.safe_value(exchange, "id") <> " " <> body
            )
          end
        end
      end

      {:ok, nil}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec calculate_rate_limiter_cost(term(), term(), term(), term(), term(), term()) :: term()
  def calculate_rate_limiter_cost(exchange, api, method, path, params, config \\ %{}) do
    _ = exchange
    _ = api
    _ = method
    _ = path
    _ = params
    _ = config

    try do
      if Runtime.truthy(
           Runtime.truthy(Runtime.has_key?(config, "noCoin")) and
             Runtime.truthy(not Runtime.truthy(Runtime.has_key?(params, "coin")))
         ) do
        throw({:ccxt_return, Runtime.safe_value(config, "noCoin")})
      else
        if Runtime.truthy(
             Runtime.truthy(Runtime.has_key?(config, "noSymbol")) and
               Runtime.truthy(not Runtime.truthy(Runtime.has_key?(params, "symbol")))
           ) do
          throw({:ccxt_return, Runtime.safe_value(config, "noSymbol")})
        else
          if Runtime.truthy(
               Runtime.truthy(Runtime.has_key?(config, "noPoolId")) and
                 Runtime.truthy(not Runtime.truthy(Runtime.has_key?(params, "poolId")))
             ) do
            throw({:ccxt_return, Runtime.safe_value(config, "noPoolId")})
          else
            if Runtime.truthy(
                 Runtime.truthy(Runtime.has_key?(config, "byLimit")) and
                   Runtime.truthy(Runtime.has_key?(params, "limit"))
               ) do
              limit = Runtime.safe_value(params, "limit")
              by_limit = Runtime.safe_value(config, "byLimit")

              Enum.each(Runtime.index_range(Runtime.js_length(by_limit), 0), fn i ->
                entry = Runtime.safe_value(by_limit, i)

                if Runtime.truthy(limit <= Runtime.safe_value(entry, 0)) do
                  throw({:ccxt_return, Runtime.safe_value(entry, 1)})
                end
              end)
            end
          end
        end
      end

      throw({:ccxt_return, Runtime.safe_value(config, "cost", 1)})
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec request(
          params(),
          params(),
          params(),
          params(),
          params(),
          params(),
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, term()} | {:error, term()}
  def request(
        path,
        api \\ "public",
        method \\ "GET",
        params \\ %{},
        headers \\ nil,
        body \\ nil,
        config \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{id: "binance", has: %{}, options: %{"hasAlreadyAuthenticatedSuccessfully" => false}},
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = path
    _ = api
    _ = method
    _ = params
    _ = headers
    _ = body
    _ = config

    try do
      response =
        Runtime.fetch2(
          exchange,
          __MODULE__,
          fetcher,
          path,
          api,
          method,
          params,
          headers,
          body,
          config
        )

      {exchange} =
        if Runtime.truthy(api == "private") do
          exchange =
            Runtime.put_value_in(
              exchange,
              ["options", "hasAlreadyAuthenticatedSuccessfully"],
              true
            )

          {exchange}
        else
          {exchange}
        end

      _ = exchange

      {:ok, response}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec modify_margin_helper(String.t(), params(), params(), params(), (RawEndpoint.t(),
                                                                        params() ->
                                                                          {:ok, map()}
                                                                          | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def modify_margin_helper(
        symbol,
        amount,
        add_or_reduce,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = amount
    _ = add_or_reduce
    _ = params

    try do
      default_type =
        Runtime.safe_string(Runtime.safe_value(exchange, "options"), "defaultType", "future")

      _ = default_type

      {default_type} =
        if Runtime.truthy(default_type == "spot") do
          default_type = "future"
          _ = default_type

          {default_type}
        else
          {default_type}
        end

      _ = default_type

      type = Runtime.safe_string(params, "type", default_type)

      if Runtime.truthy(Runtime.truthy(type == "margin") or Runtime.truthy(type == "spot")) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " add / reduce margin only supported with type future or delivery"
           ])}
        )
      end

      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      amount = Runtime.amount_to_precision(exchange, symbol, amount)
      _ = amount

      request = %{
        "type" => add_or_reduce,
        "symbol" => Runtime.safe_value(market, "id"),
        "amount" => amount
      }

      response = nil
      _ = response
      code = nil
      _ = code

      {code, response} =
        if Runtime.truthy(Runtime.safe_value(market, "linear")) do
          code = Runtime.safe_value(market, "quote")
          _ = code

          response =
            Runtime.call_raw!(Raw, fetcher, "fapiprivate_post_positionmargin", [
              Runtime.extend(request, params)
            ])

          _ = response

          {code, response}
        else
          code = Runtime.safe_value(market, "base")
          _ = code

          response =
            Runtime.call_raw!(Raw, fetcher, "dapiprivate_post_positionmargin", [
              Runtime.extend(request, params)
            ])

          _ = response

          {code, response}
        end

      _ = code
      _ = response

      {:ok,
       Runtime.extend(parse_margin_modification(exchange, response, market), %{"code" => code})}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_margin_modification(term(), term(), term()) :: term()
  def parse_margin_modification(exchange, data, market \\ nil) do
    _ = exchange
    _ = data
    _ = market

    try do
      raw_type = Runtime.safe_integer(data, "type")
      error_code = Runtime.safe_string(data, "code")
      market_id = Runtime.safe_string(data, "symbol")
      timestamp = Runtime.safe_integer(data, "time")
      market = safe_market(exchange, market_id, market, nil, "swap")
      _ = market
      no_error_code = error_code == nil
      success = error_code == "200"

      throw(
        {:ccxt_return,
         %{
           "info" => data,
           "symbol" => Runtime.safe_value(market, "symbol"),
           "type" =>
             if(
               Runtime.truthy(raw_type == 1),
               do: "add",
               else: "reduce"
             ),
           "marginMode" => "isolated",
           "amount" => Runtime.safe_number(data, "amount"),
           "code" => Runtime.safe_string(data, "asset"),
           "total" => nil,
           "status" =>
             if(
               Runtime.truthy(Runtime.truthy(success) or Runtime.truthy(no_error_code)),
               do: "ok",
               else: "failed"
             ),
           "timestamp" => timestamp,
           "datetime" => Runtime.iso8601(timestamp)
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec reduce_margin(String.t(), number(), params(), (RawEndpoint.t(), params() ->
                                                         {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def reduce_margin(symbol, amount, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = amount
    _ = params

    try do
      {:ok,
       Runtime.call_generated!(exchange, __MODULE__, :modify_margin_helper, [
         symbol,
         amount,
         2,
         params,
         fetcher
       ])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec add_margin(String.t(), number(), params(), (RawEndpoint.t(), params() ->
                                                      {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def add_margin(symbol, amount, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = amount
    _ = params

    try do
      {:ok,
       Runtime.call_generated!(exchange, __MODULE__, :modify_margin_helper, [
         symbol,
         amount,
         1,
         params,
         fetcher
       ])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_cross_borrow_rate(String.t(), params(), (RawEndpoint.t(), params() ->
                                                         {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_cross_borrow_rate(code, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{"sandboxMode" => false, "enableDemoTrading" => false}
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      currency = Runtime.currency(exchange, code)
      request = %{"asset" => Runtime.safe_value(currency, "id")}

      response =
        Runtime.call_raw!(Raw, fetcher, "sapi_get_margin_interestratehistory", [
          Runtime.extend(request, params)
        ])

      rate = Runtime.safe_dict(response, 0)
      {:ok, Runtime.call_generated!(exchange, __MODULE__, :parse_borrow_rate, [rate])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_isolated_borrow_rate(String.t(), params(), (RawEndpoint.t(), params() ->
                                                            {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_isolated_borrow_rate(symbol, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{"sandboxMode" => false, "enableDemoTrading" => false}
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = params

    try do
      request = %{"symbol" => symbol}

      borrow_rates =
        Runtime.call_generated!(exchange, __MODULE__, :fetch_isolated_borrow_rates, [
          Runtime.extend(request, params),
          fetcher
        ])

      {:ok, Runtime.safe_dict(borrow_rates, symbol)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_isolated_borrow_rates(params(), (RawEndpoint.t(), params() ->
                                                 {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_isolated_borrow_rates(params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{"sandboxMode" => false, "enableDemoTrading" => false}
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      request = %{}
      _ = request
      symbol = Runtime.safe_string(params, "symbol")
      params = Runtime.omit(params, "symbol")
      _ = params

      {request} =
        if Runtime.truthy(symbol != nil) do
          market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
          request = Runtime.put_value(request, "symbol", Runtime.safe_value(market, "id"))

          {request}
        else
          {request}
        end

      _ = request

      response =
        Runtime.call_raw!(Raw, fetcher, "sapi_get_margin_isolatedmargindata", [
          Runtime.extend(request, params)
        ])

      {:ok, Runtime.parse_isolated_borrow_rates(exchange, __MODULE__, response)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_borrow_rate_history(
          String.t(),
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_borrow_rate_history(
        code,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{"sandboxMode" => false, "enableDemoTrading" => false}
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange

      {limit} =
        if Runtime.truthy(limit == nil) do
          limit = 93
          _ = limit

          {limit}
        else
          if Runtime.truthy(limit > 93) do
            throw(
              {:ccxt_error,
               Runtime.new_error_reason(":bad_request", [
                 Runtime.safe_value(exchange, "id") <>
                   " fetchBorrowRateHistory() limit parameter cannot exceed 92"
               ])}
            )
          end

          {limit}
        end

      _ = limit

      currency = Runtime.currency(exchange, code)
      request = %{"asset" => Runtime.safe_value(currency, "id"), "limit" => limit}
      _ = request

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)
          end_time = Runtime.sum(exchange, since, limit * 86_400_000) - 1
          now = Runtime.milliseconds(exchange)
          request = Runtime.put_value(request, "endTime", min(end_time, now))

          {request}
        else
          {request}
        end

      _ = request

      response =
        Runtime.call_raw!(Raw, fetcher, "sapi_get_margin_interestratehistory", [
          Runtime.extend(request, params)
        ])

      {:ok, Runtime.parse_borrow_rate_history(exchange, __MODULE__, response, code, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_borrow_rate(term(), term(), term()) :: term()
  def parse_borrow_rate(exchange, info, currency \\ nil) do
    _ = exchange
    _ = info
    _ = currency

    try do
      timestamp = Runtime.safe_integer(info, "timestamp")
      currency_id = Runtime.safe_string(info, "asset")

      throw(
        {:ccxt_return,
         %{
           "currency" => Runtime.safe_currency_code(currency_id, currency),
           "rate" => Runtime.safe_number(info, "dailyInterestRate"),
           "period" => 86_400_000,
           "timestamp" => timestamp,
           "datetime" => Runtime.iso8601(timestamp),
           "info" => info
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec parse_isolated_borrow_rate(term(), term(), term()) :: term()
  def parse_isolated_borrow_rate(exchange, info, market \\ nil) do
    _ = exchange
    _ = info
    _ = market

    try do
      market_id = Runtime.safe_string(info, "symbol")
      market = safe_market(exchange, market_id, market, nil, "spot")
      _ = market
      data = Runtime.safe_list(info, "data")
      base_info = Runtime.safe_dict(data, 0)
      quote_info = Runtime.safe_dict(data, 1)

      throw(
        {:ccxt_return,
         %{
           "info" => info,
           "symbol" => Runtime.safe_string(market, "symbol"),
           "base" => Runtime.safe_string(base_info, "coin"),
           "baseRate" => Runtime.safe_number(base_info, "dailyInterest"),
           "quote" => Runtime.safe_string(quote_info, "coin"),
           "quoteRate" => Runtime.safe_number(quote_info, "dailyInterest"),
           "period" => 86_400_000,
           "timestamp" => nil,
           "datetime" => nil
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec create_gift_code(String.t(), params(), params(), (RawEndpoint.t(), params() ->
                                                            {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def create_gift_code(code, amount, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = amount
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      currency = Runtime.currency(exchange, code)
      request = %{"token" => Runtime.safe_value(currency, "id"), "amount" => amount}

      response =
        Runtime.call_raw!(Raw, fetcher, "sapi_post_giftcard_createcode", [
          Runtime.extend(request, params)
        ])

      data = Runtime.safe_dict(response, "data")
      giftcard_code = Runtime.safe_string(data, "code")
      id = Runtime.safe_string(data, "referenceNo")
      {:ok, %{info: response, id: id, code: giftcard_code, currency: code, amount: amount}}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec redeem_gift_code(params(), params(), (RawEndpoint.t(), params() ->
                                                {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def redeem_gift_code(giftcard_code, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = giftcard_code
    _ = params

    try do
      request = %{"code" => giftcard_code}

      response =
        Runtime.call_raw!(Raw, fetcher, "sapi_post_giftcard_redeemcode", [
          Runtime.extend(request, params)
        ])

      {:ok, response}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec verify_gift_code(String.t(), params(), (RawEndpoint.t(), params() ->
                                                  {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def verify_gift_code(id, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = id
    _ = params

    try do
      request = %{"referenceNo" => id}

      response =
        Runtime.call_raw!(Raw, fetcher, "sapi_get_giftcard_verify", [
          Runtime.extend(request, params)
        ])

      {:ok, response}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_borrow_interest(
          String.t() | nil,
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_borrow_interest(
        code \\ nil,
        symbol \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = symbol
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "fetchBorrowInterest",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      request = %{}
      _ = request
      market = nil
      _ = market

      {request} =
        if Runtime.truthy(code != nil) do
          currency = Runtime.currency(exchange, code)
          request = Runtime.put_value(request, "asset", Runtime.safe_value(currency, "id"))

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(limit != nil) do
          request = Runtime.put_value(request, "size", limit)

          {request}
        else
          {request}
        end

      _ = request

      ccxt_match = Runtime.handle_until_option("endTime", request, params)
      request = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = request
      _ = params
      response = nil
      _ = response

      {market, request, response} =
        if Runtime.truthy(is_portfolio_margin) do
          response =
            Runtime.call_raw!(Raw, fetcher, "papi_get_margin_margininteresthistory", [
              Runtime.extend(request, params)
            ])

          _ = response

          {market, request, response}
        else
          {market, request} =
            if Runtime.truthy(symbol != nil) do
              market =
                Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

              _ = market

              request =
                Runtime.put_value(request, "isolatedSymbol", Runtime.safe_value(market, "id"))

              {market, request}
            else
              {market, request}
            end

          _ = market
          _ = request

          response =
            Runtime.call_raw!(Raw, fetcher, "sapi_get_margin_interesthistory", [
              Runtime.extend(request, params)
            ])

          _ = response

          {market, request, response}
        end

      _ = market
      _ = request
      _ = response

      rows = Runtime.safe_list(response, "rows")
      interest = Runtime.parse_borrow_interests(exchange, __MODULE__, rows, market)
      {:ok, Runtime.filter_by_currency_since_limit(interest, code, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_borrow_interest(term(), term(), term()) :: term()
  def parse_borrow_interest(exchange, info, market \\ nil) do
    _ = exchange
    _ = info
    _ = market

    try do
      symbol = Runtime.safe_string(info, "isolatedSymbol")
      timestamp = Runtime.safe_integer(info, "interestAccuredTime")

      margin_mode =
        if(
          Runtime.truthy(symbol == nil),
          do: "cross",
          else: "isolated"
        )

      throw(
        {:ccxt_return,
         %{
           "info" => info,
           "symbol" => symbol,
           "currency" => Runtime.safe_currency_code(Runtime.safe_string(info, "asset")),
           "interest" => Runtime.safe_number(info, "interest"),
           "interestRate" => Runtime.safe_number(info, "interestRate"),
           "amountBorrowed" => Runtime.safe_number(info, "principal"),
           "marginMode" => margin_mode,
           "timestamp" => timestamp,
           "datetime" => Runtime.iso8601(timestamp)
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec repay_cross_margin(String.t(), params(), params(), (RawEndpoint.t(), params() ->
                                                              {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def repay_cross_margin(code, amount, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = amount
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      currency = Runtime.currency(exchange, code)

      request = %{
        "asset" => Runtime.safe_value(currency, "id"),
        "amount" => Runtime.currency_to_precision(exchange, code, amount)
      }

      _ = request
      response = nil
      _ = response
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "repayCrossMargin",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params

      {params, request, response} =
        if Runtime.truthy(is_portfolio_margin) do
          method = nil
          _ = method

          ccxt_match =
            Runtime.handle_option_and_params2(
              exchange,
              params,
              "repayCrossMargin",
              "repayCrossMarginMethod",
              "method"
            )

          method = Runtime.safe_value(ccxt_match, 0, nil)
          params = Runtime.safe_value(ccxt_match, 1, nil)
          _ = method
          _ = params

          {response} =
            if Runtime.truthy(method == "papiPostMarginRepayDebt") do
              response =
                Runtime.call_raw!(Raw, fetcher, "papi_post_margin_repay_debt", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            else
              response =
                Runtime.call_raw!(Raw, fetcher, "papi_post_repayloan", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            end

          _ = response

          {params, request, response}
        else
          request = Runtime.put_value(request, "isIsolated", "FALSE")
          request = Runtime.put_value(request, "type", "REPAY")

          response =
            Runtime.call_raw!(Raw, fetcher, "sapi_post_margin_borrow_repay", [
              Runtime.extend(request, params)
            ])

          _ = response

          {params, request, response}
        end

      _ = params
      _ = request
      _ = response

      {:ok, Runtime.call_generated!(__MODULE__, :parse_margin_loan, [response, currency])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec repay_isolated_margin(String.t(), String.t(), params(), params(), (RawEndpoint.t(),
                                                                           params() ->
                                                                             {:ok, map()}
                                                                             | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def repay_isolated_margin(symbol, code, amount, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = code
    _ = amount
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      currency = Runtime.currency(exchange, code)
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

      request = %{
        "asset" => Runtime.safe_value(currency, "id"),
        "amount" => Runtime.currency_to_precision(exchange, code, amount),
        "symbol" => Runtime.safe_value(market, "id"),
        "isIsolated" => "TRUE",
        "type" => "REPAY"
      }

      response =
        Runtime.call_raw!(Raw, fetcher, "sapi_post_margin_borrow_repay", [
          Runtime.extend(request, params)
        ])

      {:ok, Runtime.call_generated!(__MODULE__, :parse_margin_loan, [response, currency])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec borrow_cross_margin(String.t(), number(), params(), (RawEndpoint.t(), params() ->
                                                               {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def borrow_cross_margin(code, amount, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = amount
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      currency = Runtime.currency(exchange, code)

      request = %{
        "asset" => Runtime.safe_value(currency, "id"),
        "amount" => Runtime.currency_to_precision(exchange, code, amount)
      }

      _ = request
      response = nil
      _ = response
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "borrowCrossMargin",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params

      {request, response} =
        if Runtime.truthy(is_portfolio_margin) do
          response =
            Runtime.call_raw!(Raw, fetcher, "papi_post_marginloan", [
              Runtime.extend(request, params)
            ])

          _ = response

          {request, response}
        else
          request = Runtime.put_value(request, "isIsolated", "FALSE")
          request = Runtime.put_value(request, "type", "BORROW")

          response =
            Runtime.call_raw!(Raw, fetcher, "sapi_post_margin_borrow_repay", [
              Runtime.extend(request, params)
            ])

          _ = response

          {request, response}
        end

      _ = request
      _ = response

      {:ok, Runtime.call_generated!(__MODULE__, :parse_margin_loan, [response, currency])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec borrow_isolated_margin(String.t(), String.t(), number(), params(), (RawEndpoint.t(),
                                                                            params() ->
                                                                              {:ok, map()}
                                                                              | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def borrow_isolated_margin(symbol, code, amount, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = code
    _ = amount
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      currency = Runtime.currency(exchange, code)
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

      request = %{
        "asset" => Runtime.safe_value(currency, "id"),
        "amount" => Runtime.currency_to_precision(exchange, code, amount),
        "symbol" => Runtime.safe_value(market, "id"),
        "isIsolated" => "TRUE",
        "type" => "BORROW"
      }

      response =
        Runtime.call_raw!(Raw, fetcher, "sapi_post_margin_borrow_repay", [
          Runtime.extend(request, params)
        ])

      {:ok, Runtime.call_generated!(__MODULE__, :parse_margin_loan, [response, currency])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_margin_loan(params(), params(), (RawEndpoint.t(), params() ->
                                                 {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def parse_margin_loan(info, currency \\ nil, fetcher \\ &default_fetcher/2) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{}}, %{})
    _ = exchange
    _ = fetcher
    _ = info
    _ = currency

    try do
      currency_id = Runtime.safe_string(info, "asset")
      timestamp = Runtime.safe_integer(info, "updateTime")

      {:ok,
       %{
         id: Runtime.safe_integer(info, "tranId"),
         currency: Runtime.safe_currency_code(currency_id, currency),
         amount: Runtime.safe_number(info, "amount"),
         symbol: nil,
         timestamp: timestamp,
         datetime: Runtime.iso8601(timestamp),
         info: info
       }}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_open_interest_history(
          String.t(),
          params(),
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_open_interest_history(
        symbol,
        timeframe \\ "5m",
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchOpenInterestHistory" => %{"paginate" => false},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = timeframe
    _ = since
    _ = limit
    _ = params

    try do
      if Runtime.truthy(timeframe == "1m") do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":bad_request", [
             Runtime.safe_value(exchange, "id") <>
               " fetchOpenInterestHistory cannot use the 1m timeframe"
           ])}
        )
      end

      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      paginate = false
      _ = paginate

      ccxt_match =
        Runtime.handle_option_and_params(
          exchange,
          params,
          "fetchOpenInterestHistory",
          "paginate",
          false
        )

      paginate = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = paginate
      _ = params

      if Runtime.truthy(paginate) do
        throw(
          {:ccxt_return,
           Runtime.fetch_paginated_call_deterministic(
             exchange,
             __MODULE__,
             fetcher,
             "fetchOpenInterestHistory",
             symbol,
             since,
             limit,
             timeframe,
             params,
             500
           )}
        )
      end

      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

      request = %{
        "period" => Runtime.safe_string(Runtime.timeframes(exchange), timeframe, timeframe)
      }

      _ = request

      {request} =
        if Runtime.truthy(limit != nil) do
          request = Runtime.put_value(request, "limit", limit)

          {request}
        else
          {request}
        end

      _ = request

      symbol_key =
        if(
          Runtime.truthy(Runtime.safe_value(market, "linear")),
          do: "symbol",
          else: "pair"
        )

      request = Runtime.put_value(request, symbol_key, Runtime.safe_value(market, "id"))

      {request} =
        if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
          request =
            Runtime.put_value(
              request,
              "contractType",
              Runtime.safe_string(params, "contractType", "CURRENT_QUARTER")
            )

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)

          {request}
        else
          {request}
        end

      _ = request

      until = Runtime.safe_integer(params, "until")
      end_time = Runtime.safe_integer(params, "endTime", until)
      params = Runtime.omit(params, ["endTime", "until"])
      _ = params

      {limit, request} =
        if Runtime.truthy(end_time) do
          request = Runtime.put_value(request, "endTime", end_time)

          {limit, request}
        else
          {limit, request} =
            if Runtime.truthy(since) do
              {limit} =
                if Runtime.truthy(limit == nil) do
                  limit = 30
                  _ = limit

                  {limit}
                else
                  {limit}
                end

              _ = limit

              duration = Runtime.parse_timeframe(exchange, timeframe)

              request =
                Runtime.put_value(
                  request,
                  "endTime",
                  Runtime.sum(exchange, since, duration * limit * 1000)
                )

              {limit, request}
            else
              {limit, request}
            end

          _ = limit
          _ = request

          {limit, request}
        end

      _ = limit
      _ = request

      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
          response =
            Runtime.call_raw!(Raw, fetcher, "dapidata_get_openinteresthist", [
              Runtime.extend(request, params)
            ])

          _ = response

          {response}
        else
          response =
            Runtime.call_raw!(Raw, fetcher, "fapidata_get_openinteresthist", [
              Runtime.extend(request, params)
            ])

          _ = response

          {response}
        end

      _ = response

      {:ok,
       Runtime.parse_open_interests_history(exchange, __MODULE__, response, market, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_open_interest(String.t(), params(), (RawEndpoint.t(), params() ->
                                                     {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_open_interest(symbol, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse", "option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      request = %{}
      _ = request

      {request} =
        if Runtime.truthy(Runtime.safe_value(market, "option")) do
          request =
            Runtime.put_value(request, "underlyingAsset", Runtime.safe_value(market, "baseId"))

          if Runtime.truthy(Runtime.safe_value(market, "expiry") == nil) do
            throw(
              {:ccxt_error,
               Runtime.new_error_reason(":not_supported", [
                 Runtime.safe_value(exchange, "id") <>
                   " fetchOpenInterest does not support " <> symbol
               ])}
            )
          end

          request =
            Runtime.put_value(
              request,
              "expiration",
              Runtime.yymmdd(Runtime.safe_value(market, "expiry"))
            )

          {request}
        else
          request = Runtime.put_value(request, "symbol", Runtime.safe_value(market, "id"))

          {request}
        end

      _ = request

      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.safe_value(market, "option")) do
          response =
            Runtime.call_raw!(Raw, fetcher, "eapipublic_get_openinterest", [
              Runtime.extend(request, params)
            ])

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
              response =
                Runtime.call_raw!(Raw, fetcher, "dapipublic_get_openinterest", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            else
              response =
                Runtime.call_raw!(Raw, fetcher, "fapipublic_get_openinterest", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            end

          _ = response

          {response}
        end

      _ = response

      {symbol} =
        if Runtime.truthy(Runtime.safe_value(market, "option")) do
          symbol = Runtime.safe_value(market, "symbol")
          _ = symbol
          result = Runtime.parse_open_interests_history(exchange, __MODULE__, response, market)

          Enum.each(Runtime.index_range(Runtime.js_length(result), 0), fn i ->
            item = Runtime.safe_value(result, i)

            if Runtime.truthy(Runtime.safe_value(item, "symbol") == symbol) do
              throw({:ccxt_return, item})
            end
          end)

          {symbol}
        else
          throw(
            {:ccxt_return,
             Runtime.call_generated!(exchange, __MODULE__, :parse_open_interest, [
               response,
               market
             ])}
          )
        end

      _ = symbol

      {:ok, nil}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_open_interest(term(), term(), term()) :: term()
  def parse_open_interest(exchange, interest, market \\ nil) do
    _ = exchange
    _ = interest
    _ = market

    try do
      timestamp = Runtime.safe_integer2(interest, "timestamp", "time")
      id = Runtime.safe_string(interest, "symbol")
      amount = Runtime.safe_number2(interest, "sumOpenInterest", "openInterest")
      value = Runtime.safe_number2(interest, "sumOpenInterestValue", "sumOpenInterestUsd")

      throw(
        {:ccxt_return,
         Runtime.safe_open_interest(
           %{
             symbol: Runtime.safe_symbol(exchange, id, market, nil, "contract"),
             baseVolume:
               if(
                 Runtime.truthy(Runtime.safe_value(market, "inverse")),
                 do: nil,
                 else: amount
               ),
             quoteVolume: value,
             openInterestAmount: amount,
             openInterestValue: value,
             timestamp: timestamp,
             datetime: Runtime.iso8601(timestamp),
             info: interest
           },
           market
         )}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_my_liquidations(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_my_liquidations(
        symbol \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      paginate = false
      _ = paginate

      ccxt_match =
        Runtime.handle_option_and_params(exchange, params, "fetchMyLiquidations", "paginate")

      paginate = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = paginate
      _ = params

      if Runtime.truthy(paginate) do
        throw(
          {:ccxt_return,
           Runtime.fetch_paginated_call_incremental(
             exchange,
             __MODULE__,
             fetcher,
             "fetchMyLiquidations",
             symbol,
             since,
             limit,
             params,
             "current",
             100
           )}
        )
      end

      market = nil
      _ = market

      {market} =
        if Runtime.truthy(symbol != nil) do
          market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
          _ = market

          {market}
        else
          {market}
        end

      _ = market

      type = nil
      _ = type

      ccxt_match =
        Runtime.handle_market_type_and_params(exchange, "fetchMyLiquidations", market, params)

      type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = type
      _ = params
      sub_type = nil
      _ = sub_type

      ccxt_match =
        Runtime.handle_sub_type_and_params(
          exchange,
          "fetchMyLiquidations",
          market,
          params,
          "linear"
        )

      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "fetchMyLiquidations",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      request = %{}
      _ = request

      {request} =
        if Runtime.truthy(type != "spot") do
          request = Runtime.put_value(request, "autoCloseType", "LIQUIDATION")

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(market != nil) do
          symbol_key =
            if(
              Runtime.truthy(Runtime.safe_value(market, "spot")),
              do: "isolatedSymbol",
              else: "symbol"
            )

          {request} =
            if Runtime.truthy(not Runtime.truthy(is_portfolio_margin)) do
              request = Runtime.put_value(request, symbol_key, Runtime.safe_value(market, "id"))

              {request}
            else
              {request}
            end

          _ = request

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(limit != nil) do
          {request} =
            if Runtime.truthy(type == "spot") do
              request = Runtime.put_value(request, "size", limit)

              {request}
            else
              request = Runtime.put_value(request, "limit", limit)

              {request}
            end

          _ = request

          {request}
        else
          {request}
        end

      _ = request

      ccxt_match = Runtime.handle_until_option("endTime", request, params)
      request = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = request
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(type == "spot") do
          {response} =
            if Runtime.truthy(is_portfolio_margin) do
              response =
                Runtime.call_raw!(Raw, fetcher, "papi_get_margin_forceorders", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            else
              response =
                Runtime.call_raw!(Raw, fetcher, "sapi_get_margin_forceliquidationrec", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            end

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(sub_type == "linear") do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  response =
                    Runtime.call_raw!(Raw, fetcher, "papi_get_um_forceorders", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_forceorders", [
                      Runtime.extend(request, params)
                    ])

                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              {response} =
                if Runtime.truthy(sub_type == "inverse") do
                  {response} =
                    if Runtime.truthy(is_portfolio_margin) do
                      response =
                        Runtime.call_raw!(Raw, fetcher, "papi_get_cm_forceorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    else
                      response =
                        Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_forceorders", [
                          Runtime.extend(request, params)
                        ])

                      _ = response

                      {response}
                    end

                  _ = response

                  {response}
                else
                  throw(
                    {:ccxt_error,
                     Runtime.new_error_reason(":not_supported", [
                       Runtime.safe_value(exchange, "id") <>
                         " fetchMyLiquidations() does not support " <>
                         Runtime.safe_value(market, "type") <> " markets"
                     ])}
                  )
                end

              _ = response

              {response}
            end

          _ = response

          {response}
        end

      _ = response

      liquidations = Runtime.safe_list(response, "rows", response)
      {:ok, Runtime.parse_liquidations(exchange, __MODULE__, liquidations, market, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_liquidation(params(), params(), (RawEndpoint.t(), params() ->
                                                 {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def parse_liquidation(liquidation, market \\ nil, fetcher \\ &default_fetcher/2) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{}}, %{})
    _ = exchange
    _ = fetcher
    _ = liquidation
    _ = market

    try do
      market_id = Runtime.safe_string(liquidation, "symbol")
      timestamp = Runtime.safe_integer2(liquidation, "updatedTime", "updateTime")

      {:ok,
       Runtime.safe_liquidation(%{
         info: liquidation,
         symbol: Runtime.safe_symbol(exchange, market_id, market),
         contracts: Runtime.safe_number(liquidation, "executedQty"),
         contractSize: Runtime.safe_number(market, "contractSize"),
         price: Runtime.safe_number(liquidation, "avgPrice"),
         side: Runtime.safe_string_lower(liquidation, "side"),
         baseValue: Runtime.safe_number(liquidation, "cumBase"),
         quoteValue: Runtime.safe_number(liquidation, "cumQuote"),
         timestamp: timestamp,
         datetime: Runtime.iso8601(timestamp)
       })}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_greeks(String.t(), params(), (RawEndpoint.t(), params() ->
                                              {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_greeks(symbol, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "option",
            "fetchMarkets" => %{"types" => ["option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      request = %{"symbol" => Runtime.safe_value(market, "id")}

      response =
        Runtime.call_raw!(Raw, fetcher, "eapipublic_get_mark", [Runtime.extend(request, params)])

      {:ok,
       Runtime.call_generated!(exchange, __MODULE__, :parse_greeks, [
         Runtime.safe_value(response, 0),
         market
       ])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_all_greeks(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                              {:ok, map()} | {:error, term()})) ::
          {:ok, list()} | {:error, term()}
  def fetch_all_greeks(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "option",
            "fetchMarkets" => %{"types" => ["option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      symbols = Runtime.market_symbols(exchange, symbols, nil, true, true, true)
      _ = symbols
      request = %{}
      _ = request
      market = nil
      _ = market

      {market, request} =
        if Runtime.truthy(symbols != nil) do
          symbols_length = Runtime.js_length(symbols)

          {market, request} =
            if Runtime.truthy(symbols_length == 1) do
              market =
                Runtime.market!(
                  Runtime.load_markets!(exchange, __MODULE__, fetcher),
                  Runtime.safe_value(symbols, 0)
                )

              _ = market
              request = Runtime.put_value(request, "symbol", Runtime.safe_value(market, "id"))

              {market, request}
            else
              {market, request}
            end

          _ = market
          _ = request

          {market, request}
        else
          {market, request}
        end

      _ = market
      _ = request

      response =
        Runtime.call_raw!(Raw, fetcher, "eapipublic_get_mark", [Runtime.extend(request, params)])

      {:ok, Runtime.parse_all_greeks(exchange, __MODULE__, response, symbols)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_greeks(term(), term(), term()) :: term()
  def parse_greeks(exchange, greeks, market \\ nil) do
    _ = exchange
    _ = greeks
    _ = market

    try do
      market_id = Runtime.safe_string(greeks, "symbol")
      symbol = Runtime.safe_symbol(exchange, market_id, market)

      throw(
        {:ccxt_return,
         %{
           "symbol" => symbol,
           "timestamp" => nil,
           "datetime" => nil,
           "delta" => Runtime.safe_number(greeks, "delta"),
           "gamma" => Runtime.safe_number(greeks, "gamma"),
           "theta" => Runtime.safe_number(greeks, "theta"),
           "vega" => Runtime.safe_number(greeks, "vega"),
           "rho" => nil,
           "bidSize" => nil,
           "askSize" => nil,
           "bidImpliedVolatility" => Runtime.safe_number(greeks, "bidIV"),
           "askImpliedVolatility" => Runtime.safe_number(greeks, "askIV"),
           "markImpliedVolatility" => Runtime.safe_number(greeks, "markIV"),
           "bidPrice" => nil,
           "askPrice" => nil,
           "markPrice" => Runtime.safe_number(greeks, "markPrice"),
           "lastPrice" => nil,
           "underlyingPrice" => nil,
           "info" => greeks
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_trading_limits(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                                  {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_trading_limits(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      markets = Runtime.call_generated!(exchange, __MODULE__, :fetch_markets, [%{}, fetcher])
      trading_limits = %{}
      _ = trading_limits

      {trading_limits} =
        Enum.reduce_while(
          Runtime.index_range(Runtime.js_length(markets), 0),
          {trading_limits},
          fn i, {trading_limits} ->
            try do
              market = Runtime.safe_value(markets, i)
              symbol = Runtime.safe_value(market, "symbol")

              {trading_limits} =
                if Runtime.truthy(
                     Runtime.truthy(symbols == nil) or
                       Runtime.truthy(Runtime.in_array(symbol, symbols))
                   ) do
                  trading_limits =
                    Runtime.put_value(
                      trading_limits,
                      symbol,
                      Runtime.safe_value(Runtime.safe_value(market, "limits"), "amount")
                    )

                  {trading_limits}
                else
                  {trading_limits}
                end

              _ = trading_limits
              {:cont, {trading_limits}}
            catch
              :continue -> {:cont, {trading_limits}}
              :break -> {:halt, {trading_limits}}
            end
          end
        )

      _ = trading_limits
      {:ok, trading_limits}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_position_mode(String.t() | nil, params(), (RawEndpoint.t(), params() ->
                                                           {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_position_mode(symbol \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "spot",
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = params

    try do
      market = nil
      _ = market

      {market} =
        if Runtime.truthy(symbol != nil) do
          market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
          _ = market

          {market}
        else
          {market}
        end

      _ = market

      sub_type = nil
      _ = sub_type

      ccxt_match =
        Runtime.handle_sub_type_and_params(exchange, "fetchPositionMode", market, params)

      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(sub_type == "linear") do
          response =
            Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_positionside_dual", [params])

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(sub_type == "inverse") do
              response =
                Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_positionside_dual", [params])

              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":bad_request", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchPositionMode requires either a symbol argument or params[\"subType\"]"
                 ])}
              )
            end

          _ = response

          {response}
        end

      _ = response

      dual_side_position = Runtime.safe_bool(response, "dualSidePosition")
      {:ok, %{info: response, hedged: dual_side_position}}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_margin_modes(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                                {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_margin_modes(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = nil
      _ = market

      {market, symbols} =
        if Runtime.truthy(symbols != nil) do
          symbols = Runtime.market_symbols(exchange, symbols)
          _ = symbols

          market =
            Runtime.market!(
              Runtime.load_markets!(exchange, __MODULE__, fetcher),
              Runtime.safe_value(symbols, 0)
            )

          _ = market

          {market, symbols}
        else
          {market, symbols}
        end

      _ = market
      _ = symbols

      sub_type = nil
      _ = sub_type
      ccxt_match = Runtime.handle_sub_type_and_params(exchange, "fetchMarginMode", market, params)
      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(sub_type == "linear") do
          response = Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_symbolconfig", [params])
          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(sub_type == "inverse") do
              response = Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_account", [params])
              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":bad_request", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchMarginModes () supports linear and inverse subTypes only"
                 ])}
              )
            end

          _ = response

          {response}
        end

      _ = response

      assets = Runtime.safe_list(response, "positions", [])
      _ = assets

      {assets} =
        if Runtime.truthy(Runtime.is_array(response)) do
          assets = response
          _ = assets

          {assets}
        else
          {assets}
        end

      _ = assets

      {:ok, Runtime.parse_margin_modes(exchange, __MODULE__, assets, symbols, "symbol", "swap")}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_margin_mode(String.t(), params(), (RawEndpoint.t(), params() ->
                                                   {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_margin_mode(symbol, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      sub_type = nil
      _ = sub_type
      ccxt_match = Runtime.handle_sub_type_and_params(exchange, "fetchMarginMode", market, params)
      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(sub_type == "linear") do
          request = %{"symbol" => Runtime.safe_value(market, "id")}

          response =
            Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_symbolconfig", [
              Runtime.extend(request, params)
            ])

          _ = response

          {response}
        else
          if Runtime.truthy(sub_type == "inverse") do
            fetch_margin_modes_response =
              Runtime.call_generated!(exchange, __MODULE__, :fetch_margin_modes, [
                [symbol],
                params,
                fetcher
              ])

            throw({:ccxt_return, Runtime.safe_value(fetch_margin_modes_response, symbol)})
          else
            throw(
              {:ccxt_error,
               Runtime.new_error_reason(":bad_request", [
                 Runtime.safe_value(exchange, "id") <>
                   " fetchMarginMode () supports linear and inverse subTypes only"
               ])}
            )
          end
        end

      _ = response

      {:ok,
       Runtime.call_generated!(exchange, __MODULE__, :parse_margin_mode, [
         Runtime.safe_value(response, 0),
         market
       ])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_margin_mode(term(), term(), term()) :: term()
  def parse_margin_mode(exchange, margin_mode, market \\ nil) do
    _ = exchange
    _ = margin_mode
    _ = market

    try do
      market_id = Runtime.safe_string(margin_mode, "symbol")
      market = safe_market(exchange, market_id, market, nil, nil)
      _ = market
      margin_mode_raw = Runtime.safe_bool(margin_mode, "isolated")
      re_margin_mode = nil
      _ = re_margin_mode

      {re_margin_mode} =
        if Runtime.truthy(margin_mode_raw != nil) do
          re_margin_mode =
            if(
              Runtime.truthy(margin_mode_raw),
              do: "isolated",
              else: "cross"
            )

          _ = re_margin_mode

          {re_margin_mode}
        else
          {re_margin_mode}
        end

      _ = re_margin_mode

      margin_type_raw = Runtime.safe_string_lower(margin_mode, "marginType")

      {re_margin_mode} =
        if Runtime.truthy(margin_type_raw != nil) do
          re_margin_mode =
            if(
              Runtime.truthy(margin_type_raw == "crossed"),
              do: "cross",
              else: "isolated"
            )

          _ = re_margin_mode

          {re_margin_mode}
        else
          {re_margin_mode}
        end

      _ = re_margin_mode

      throw(
        {:ccxt_return,
         %{
           info: margin_mode,
           symbol: Runtime.safe_value(market, "symbol"),
           marginMode: re_margin_mode
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_option(String.t(), params(), (RawEndpoint.t(), params() ->
                                              {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_option(symbol, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "option",
            "fetchMarkets" => %{"types" => ["option"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      request = %{"symbol" => Runtime.safe_value(market, "id")}

      response =
        Runtime.call_raw!(Raw, fetcher, "eapipublic_get_ticker", [Runtime.extend(request, params)])

      chain = Runtime.safe_dict(response, 0, %{})
      {:ok, Runtime.call_generated!(exchange, __MODULE__, :parse_option, [chain, nil, market])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_option(term(), term(), term(), term()) :: term()
  def parse_option(exchange, chain, currency \\ nil, market \\ nil) do
    _ = exchange
    _ = chain
    _ = currency
    _ = market

    try do
      market_id = Runtime.safe_string(chain, "symbol")
      market = safe_market(exchange, market_id, market, nil, nil)
      _ = market

      throw(
        {:ccxt_return,
         %{
           "info" => chain,
           "currency" => nil,
           "symbol" => Runtime.safe_value(market, "symbol"),
           "timestamp" => nil,
           "datetime" => nil,
           "impliedVolatility" => nil,
           "openInterest" => nil,
           "bidPrice" => Runtime.safe_number(chain, "bidPrice"),
           "askPrice" => Runtime.safe_number(chain, "askPrice"),
           "midPrice" => nil,
           "markPrice" => nil,
           "lastPrice" => Runtime.safe_number(chain, "lastPrice"),
           "underlyingPrice" => Runtime.safe_number(chain, "exercisePrice"),
           "change" => Runtime.safe_number(chain, "priceChange"),
           "percentage" => Runtime.safe_number(chain, "priceChangePercent"),
           "baseVolume" => Runtime.safe_number(chain, "volume"),
           "quoteVolume" => nil
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_margin_adjustment_history(
          String.t() | nil,
          String.t() | nil,
          number() | nil,
          number() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_margin_adjustment_history(
        symbol \\ nil,
        type \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["spot", "linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => true
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = type
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange

      if Runtime.truthy(symbol == nil) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":arguments_required", [
             Runtime.safe_value(exchange, "id") <>
               " fetchMarginAdjustmentHistory () requires a symbol argument"
           ])}
        )
      end

      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      until = Runtime.safe_integer(params, "until")
      params = Runtime.omit(params, "until")
      _ = params
      request = %{"symbol" => Runtime.safe_value(market, "id")}
      _ = request

      {request} =
        if Runtime.truthy(type != nil) do
          request =
            Runtime.put_value(
              request,
              "type",
              if(
                Runtime.truthy(type == "add"),
                do: 1,
                else: 2
              )
            )

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(limit != nil) do
          request = Runtime.put_value(request, "limit", limit)

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(until != nil) do
          request = Runtime.put_value(request, "endTime", until)

          {request}
        else
          {request}
        end

      _ = request

      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.safe_value(market, "linear")) do
          response =
            Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_positionmargin_history", [
              Runtime.extend(request, params)
            ])

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.safe_value(market, "inverse")) do
              response =
                Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_positionmargin_history", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":bad_request", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchMarginAdjustmentHistory () is not supported for markets of type " <>
                     Runtime.safe_value(market, "type")
                 ])}
              )
            end

          _ = response

          {response}
        end

      _ = response

      modifications = Runtime.parse_margin_modifications(exchange, __MODULE__, response)
      {:ok, Runtime.filter_by_symbol_since_limit(modifications, symbol, since, limit)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_convert_currencies(params(), (RawEndpoint.t(), params() ->
                                              {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_convert_currencies(params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      response = Runtime.call_raw!(Raw, fetcher, "sapi_get_convert_assetinfo", [params])
      result = %{}
      _ = result

      {result} =
        Enum.reduce_while(Runtime.index_range(Runtime.js_length(response), 0), {result}, fn i,
                                                                                            {result} ->
          try do
            entry = Runtime.safe_value(response, i)
            id = Runtime.safe_string(entry, "asset")
            code = Runtime.safe_currency_code(id)

            result =
              Runtime.put_value(result, code, %{
                "info" => entry,
                "id" => id,
                "code" => code,
                "networks" => nil,
                "type" => nil,
                "name" => nil,
                "active" => nil,
                "deposit" => nil,
                "withdraw" => nil,
                "fee" => nil,
                "precision" =>
                  Runtime.parse_number(
                    Runtime.parse_precision(Runtime.safe_string(entry, "fraction"))
                  ),
                "limits" => %{
                  "amount" => %{"min" => nil, "max" => nil},
                  "withdraw" => %{"min" => nil, "max" => nil},
                  "deposit" => %{"min" => nil, "max" => nil}
                },
                "created" => nil
              })

            {:cont, {result}}
          catch
            :continue -> {:cont, {result}}
            :break -> {:halt, {result}}
          end
        end)

      _ = result
      {:ok, result}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_convert_quote(String.t(), String.t(), number() | nil, params(), (RawEndpoint.t(),
                                                                               params() ->
                                                                                 {:ok, map()}
                                                                                 | {:error,
                                                                                    term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_convert_quote(
        from_code,
        to_code,
        amount \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = from_code
    _ = to_code
    _ = amount
    _ = params

    try do
      if Runtime.truthy(amount == nil) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":arguments_required", [
             Runtime.safe_value(exchange, "id") <>
               " fetchConvertQuote() requires an amount argument"
           ])}
        )
      end

      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      request = %{"fromAsset" => from_code, "toAsset" => to_code, "fromAmount" => amount}

      response =
        Runtime.call_raw!(Raw, fetcher, "sapi_post_convert_getquote", [
          Runtime.extend(request, params)
        ])

      from_currency = Runtime.currency(exchange, from_code)
      to_currency = Runtime.currency(exchange, to_code)

      {:ok,
       Runtime.call_generated!(__MODULE__, :parse_conversion, [
         response,
         from_currency,
         to_currency
       ])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec create_convert_trade(
          String.t(),
          String.t(),
          String.t(),
          number() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, map()} | {:error, term()}
  def create_convert_trade(
        id,
        from_code,
        to_code,
        amount \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = id
    _ = from_code
    _ = to_code
    _ = amount
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      request = %{}
      _ = request
      response = nil
      _ = response

      {request, response} =
        if Runtime.truthy(
             Runtime.truthy(from_code == "BUSD") or Runtime.truthy(to_code == "BUSD")
           ) do
          if Runtime.truthy(amount == nil) do
            throw(
              {:ccxt_error,
               Runtime.new_error_reason(":arguments_required", [
                 Runtime.safe_value(exchange, "id") <>
                   " createConvertTrade() requires an amount argument"
               ])}
            )
          end

          request = Runtime.put_value(request, "clientTranId", id)
          request = Runtime.put_value(request, "asset", from_code)
          request = Runtime.put_value(request, "targetAsset", to_code)
          request = Runtime.put_value(request, "amount", amount)

          response =
            Runtime.call_raw!(Raw, fetcher, "sapi_post_asset_convert_transfer", [
              Runtime.extend(request, params)
            ])

          _ = response

          {request, response}
        else
          request = Runtime.put_value(request, "quoteId", id)

          response =
            Runtime.call_raw!(Raw, fetcher, "sapi_post_convert_acceptquote", [
              Runtime.extend(request, params)
            ])

          _ = response

          {request, response}
        end

      _ = request
      _ = response

      from_currency = Runtime.currency(exchange, from_code)
      to_currency = Runtime.currency(exchange, to_code)

      {:ok,
       Runtime.call_generated!(__MODULE__, :parse_conversion, [
         response,
         from_currency,
         to_currency
       ])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_convert_trade(String.t(), String.t() | nil, params(), (RawEndpoint.t(), params() ->
                                                                       {:ok, map()}
                                                                       | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_convert_trade(id, code \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = id
    _ = code
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      request = %{}
      _ = request
      response = nil
      _ = response

      {request, response} =
        if Runtime.truthy(code == "BUSD") do
          ms_in_day = 86_400_000
          now = Runtime.milliseconds(exchange)

          {request} =
            if Runtime.truthy(code != nil) do
              currency = Runtime.currency(exchange, code)
              request = Runtime.put_value(request, "asset", Runtime.safe_value(currency, "id"))

              {request}
            else
              {request}
            end

          _ = request

          request = Runtime.put_value(request, "tranId", id)
          request = Runtime.put_value(request, "startTime", now - ms_in_day)
          request = Runtime.put_value(request, "endTime", now)

          response =
            Runtime.call_raw!(Raw, fetcher, "sapi_get_asset_convert_transfer_querybypage", [
              Runtime.extend(request, params)
            ])

          _ = response

          {request, response}
        else
          request = Runtime.put_value(request, "orderId", id)

          response =
            Runtime.call_raw!(Raw, fetcher, "sapi_get_convert_orderstatus", [
              Runtime.extend(request, params)
            ])

          _ = response

          {request, response}
        end

      _ = request
      _ = response

      data = response
      _ = data

      {data} =
        if Runtime.truthy(code == "BUSD") do
          rows = Runtime.safe_list(response, "rows", [])
          data = Runtime.safe_dict(rows, 0, %{})
          _ = data

          {data}
        else
          {data}
        end

      _ = data

      from_currency_id = Runtime.safe_string2(data, "deductedAsset", "fromAsset")
      to_currency_id = Runtime.safe_string2(data, "targetAsset", "toAsset")
      from_currency = nil
      _ = from_currency
      to_currency = nil
      _ = to_currency

      {from_currency} =
        if Runtime.truthy(from_currency_id != nil) do
          from_currency = Runtime.currency(exchange, from_currency_id)
          _ = from_currency

          {from_currency}
        else
          {from_currency}
        end

      _ = from_currency

      {to_currency} =
        if Runtime.truthy(to_currency_id != nil) do
          to_currency = Runtime.currency(exchange, to_currency_id)
          _ = to_currency

          {to_currency}
        else
          {to_currency}
        end

      _ = to_currency

      {:ok,
       Runtime.call_generated!(__MODULE__, :parse_conversion, [data, from_currency, to_currency])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_convert_trade_history(
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_convert_trade_history(
        code \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      request = %{}
      _ = request
      ms_in_thirty_days = 2_592_000_000
      now = Runtime.milliseconds(exchange)

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)

          {request}
        else
          request = Runtime.put_value(request, "startTime", now - ms_in_thirty_days)

          {request}
        end

      _ = request

      end_time = Runtime.safe_integer2(params, "endTime", "until")

      {request} =
        if Runtime.truthy(end_time != nil) do
          request = Runtime.put_value(request, "endTime", end_time)

          {request}
        else
          request = Runtime.put_value(request, "endTime", now)

          {request}
        end

      _ = request

      params = Runtime.omit(params, "until")
      _ = params
      response = nil
      _ = response
      response_query = nil
      _ = response_query
      from_currency_key = nil
      _ = from_currency_key
      to_currency_key = nil
      _ = to_currency_key

      {from_currency_key, request, response, response_query, to_currency_key} =
        if Runtime.truthy(code == "BUSD") do
          currency = Runtime.currency(exchange, code)
          request = Runtime.put_value(request, "asset", Runtime.safe_value(currency, "id"))

          {request} =
            if Runtime.truthy(limit != nil) do
              request = Runtime.put_value(request, "size", limit)

              {request}
            else
              {request}
            end

          _ = request

          from_currency_key = "deductedAsset"
          _ = from_currency_key
          to_currency_key = "targetAsset"
          _ = to_currency_key
          response_query = "rows"
          _ = response_query

          response =
            Runtime.call_raw!(Raw, fetcher, "sapi_get_asset_convert_transfer_querybypage", [
              Runtime.extend(request, params)
            ])

          _ = response

          {from_currency_key, request, response, response_query, to_currency_key}
        else
          if Runtime.truthy(
               Runtime.safe_value(request, "endTime") - Runtime.safe_value(request, "startTime") >
                 ms_in_thirty_days
             ) do
            throw(
              {:ccxt_error,
               Runtime.new_error_reason(":bad_request", [
                 Runtime.safe_value(exchange, "id") <>
                   " fetchConvertTradeHistory () the max interval between startTime and endTime is 30 days."
               ])}
            )
          end

          {request} =
            if Runtime.truthy(limit != nil) do
              request = Runtime.put_value(request, "limit", limit)

              {request}
            else
              {request}
            end

          _ = request

          from_currency_key = "fromAsset"
          _ = from_currency_key
          to_currency_key = "toAsset"
          _ = to_currency_key
          response_query = "list"
          _ = response_query

          response =
            Runtime.call_raw!(Raw, fetcher, "sapi_get_convert_tradeflow", [
              Runtime.extend(request, params)
            ])

          _ = response

          {from_currency_key, request, response, response_query, to_currency_key}
        end

      _ = from_currency_key
      _ = request
      _ = response
      _ = response_query
      _ = to_currency_key

      rows = Runtime.safe_list(response, response_query, [])

      {:ok,
       Runtime.parse_conversions(
         exchange,
         __MODULE__,
         rows,
         code,
         from_currency_key,
         to_currency_key,
         since,
         limit
       )}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_conversion(params(), params(), params(), (RawEndpoint.t(), params() ->
                                                          {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def parse_conversion(
        conversion,
        from_currency \\ nil,
        to_currency \\ nil,
        fetcher \\ &default_fetcher/2
      ) do
    exchange = Map.merge(%{id: "binance", has: %{}, options: %{}}, %{})
    _ = exchange
    _ = fetcher
    _ = conversion
    _ = from_currency
    _ = to_currency

    try do
      timestamp = Runtime.safe_integer_n(conversion, ["time", "validTimestamp", "createTime"])
      from_cur = Runtime.safe_string2(conversion, "deductedAsset", "fromAsset")
      from_code = Runtime.safe_currency_code(from_cur, from_currency)
      to = Runtime.safe_string2(conversion, "targetAsset", "toAsset")
      to_code = Runtime.safe_currency_code(to, to_currency)

      {:ok,
       %{
         info: conversion,
         timestamp: timestamp,
         datetime: Runtime.iso8601(timestamp),
         id: Runtime.safe_string_n(conversion, ["tranId", "orderId", "quoteId"]),
         fromCurrency: from_code,
         fromAmount: Runtime.safe_number2(conversion, "deductedAmount", "fromAmount"),
         toCurrency: to_code,
         toAmount: Runtime.safe_number2(conversion, "targetAmount", "toAmount"),
         price: nil,
         fee: nil
       }}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_funding_intervals(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                                     {:ok, map()}
                                                                     | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_funding_intervals(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = nil
      _ = market

      {market, symbols} =
        if Runtime.truthy(symbols != nil) do
          symbols = Runtime.market_symbols(exchange, symbols)
          _ = symbols

          market =
            Runtime.market!(
              Runtime.load_markets!(exchange, __MODULE__, fetcher),
              Runtime.safe_value(symbols, 0)
            )

          _ = market

          {market, symbols}
        else
          {market, symbols}
        end

      _ = market
      _ = symbols

      type = "swap"
      sub_type = nil
      _ = sub_type

      ccxt_match =
        Runtime.handle_sub_type_and_params(
          exchange,
          "fetchFundingIntervals",
          market,
          params,
          "linear"
        )

      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(Runtime.is_linear(exchange, type, sub_type)) do
          response = Runtime.call_raw!(Raw, fetcher, "fapipublic_get_fundinginfo", [params])
          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(Runtime.is_inverse(exchange, type, sub_type)) do
              response = Runtime.call_raw!(Raw, fetcher, "dapipublic_get_fundinginfo", [params])
              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":not_supported", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchFundingIntervals() supports linear and inverse swap contracts only"
                 ])}
              )
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, Runtime.parse_funding_rates(exchange, __MODULE__, response, symbols)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_long_short_ratio_history(
          String.t() | nil,
          String.t() | nil,
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_long_short_ratio_history(
        symbol \\ nil,
        timeframe \\ nil,
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = timeframe
    _ = since
    _ = limit
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)

      {timeframe} =
        if Runtime.truthy(timeframe == nil) do
          timeframe = "1d"
          _ = timeframe

          {timeframe}
        else
          {timeframe}
        end

      _ = timeframe

      request = %{"period" => timeframe}
      _ = request
      ccxt_match = Runtime.handle_until_option("endTime", request, params)
      request = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = request
      _ = params

      {request} =
        if Runtime.truthy(since != nil) do
          request = Runtime.put_value(request, "startTime", since)

          {request}
        else
          {request}
        end

      _ = request

      {request} =
        if Runtime.truthy(limit != nil) do
          request = Runtime.put_value(request, "limit", limit)

          {request}
        else
          {request}
        end

      _ = request

      sub_type = nil
      _ = sub_type

      ccxt_match =
        Runtime.handle_sub_type_and_params(exchange, "fetchLongShortRatioHistory", market, params)

      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      response = nil
      _ = response

      {request, response} =
        if Runtime.truthy(sub_type == "linear") do
          request = Runtime.put_value(request, "symbol", Runtime.safe_value(market, "id"))

          response =
            Runtime.call_raw!(Raw, fetcher, "fapidata_get_globallongshortaccountratio", [
              Runtime.extend(request, params)
            ])

          _ = response

          {request, response}
        else
          {request, response} =
            if Runtime.truthy(sub_type == "inverse") do
              request =
                Runtime.put_value(
                  request,
                  "pair",
                  Runtime.safe_value(Runtime.safe_value(market, "info"), "pair")
                )

              response =
                Runtime.call_raw!(Raw, fetcher, "dapidata_get_globallongshortaccountratio", [
                  Runtime.extend(request, params)
                ])

              _ = response

              {request, response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":bad_request", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchLongShortRatioHistory() supports linear and inverse subTypes only"
                 ])}
              )
            end

          _ = request
          _ = response

          {request, response}
        end

      _ = request
      _ = response

      {:ok, Runtime.parse_long_short_ratio_history(exchange, __MODULE__, response, market)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_long_short_ratio(term(), term(), term()) :: term()
  def parse_long_short_ratio(exchange, info, market \\ nil) do
    _ = exchange
    _ = info
    _ = market

    try do
      market_id = Runtime.safe_string(info, "symbol")
      timestamp = Runtime.safe_integer_omit_zero(info, "timestamp")

      throw(
        {:ccxt_return,
         %{
           "info" => info,
           "symbol" => Runtime.safe_symbol(exchange, market_id, market, nil, "contract"),
           "timestamp" => timestamp,
           "datetime" => Runtime.iso8601(timestamp),
           "timeframe" => nil,
           "longShortRatio" => Runtime.safe_number(info, "longShortRatio")
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_adl_rank(String.t(), params(), (RawEndpoint.t(), params() ->
                                                {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_adl_rank(symbol, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["linear"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      market = Runtime.market!(Runtime.load_markets!(exchange, __MODULE__, fetcher), symbol)
      request = %{"symbol" => Runtime.safe_value(market, "id")}
      sub_type = nil
      _ = sub_type
      ccxt_match = Runtime.handle_sub_type_and_params(exchange, "fetchADLRank", market, params)
      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(sub_type == "linear") do
          response =
            Runtime.call_raw!(Raw, fetcher, "fapipublic_get_symboladlrisk", [
              Runtime.extend(request, params)
            ])

          _ = response

          {response}
        else
          throw(
            {:ccxt_error,
             Runtime.new_error_reason(":bad_request", [
               Runtime.safe_value(exchange, "id") <>
                 " fetchADLRank() supports linear subTypes only"
             ])}
          )
        end

      _ = response

      {:ok, Runtime.call_generated!(exchange, __MODULE__, :parse_adl_rank, [response, market])}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_positions_adl_rank(list(String.t()) | nil, params(), (RawEndpoint.t(), params() ->
                                                                      {:ok, map()}
                                                                      | {:error, term()})) ::
          {:ok, list()} | {:error, term()}
  def fetch_positions_adl_rank(symbols \\ nil, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbols
    _ = params

    try do
      exchange = Runtime.load_markets!(exchange, __MODULE__, fetcher)
      _ = exchange
      symbols = Runtime.market_symbols(exchange, symbols, nil, true, true, true)
      _ = symbols
      market = Runtime.get_market_from_symbols(exchange, symbols)
      sub_type = nil
      _ = sub_type

      ccxt_match =
        Runtime.handle_sub_type_and_params(exchange, "fetchPositionsADLRank", market, params)

      sub_type = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = sub_type
      _ = params
      is_portfolio_margin = nil
      _ = is_portfolio_margin

      ccxt_match =
        Runtime.handle_option_and_params2(
          exchange,
          params,
          "fetchPositionsADLRank",
          "papi",
          "portfolioMargin",
          false
        )

      is_portfolio_margin = Runtime.safe_value(ccxt_match, 0, nil)
      params = Runtime.safe_value(ccxt_match, 1, nil)
      _ = is_portfolio_margin
      _ = params
      response = nil
      _ = response

      {response} =
        if Runtime.truthy(sub_type == "linear") do
          {response} =
            if Runtime.truthy(is_portfolio_margin) do
              response = Runtime.call_raw!(Raw, fetcher, "papi_get_um_adlquantile", [params])
              _ = response

              {response}
            else
              response = Runtime.call_raw!(Raw, fetcher, "fapiprivate_get_adlquantile", [params])
              _ = response

              {response}
            end

          _ = response

          {response}
        else
          {response} =
            if Runtime.truthy(sub_type == "inverse") do
              {response} =
                if Runtime.truthy(is_portfolio_margin) do
                  response = Runtime.call_raw!(Raw, fetcher, "papi_get_cm_adlquantile", [params])
                  _ = response

                  {response}
                else
                  response =
                    Runtime.call_raw!(Raw, fetcher, "dapiprivate_get_adlquantile", [params])

                  _ = response

                  {response}
                end

              _ = response

              {response}
            else
              throw(
                {:ccxt_error,
                 Runtime.new_error_reason(":bad_request", [
                   Runtime.safe_value(exchange, "id") <>
                     " fetchPositionsADLRank() supports linear and inverse subTypes only"
                 ])}
              )
            end

          _ = response

          {response}
        end

      _ = response

      {:ok, Runtime.parse_adl_ranks(exchange, __MODULE__, response, symbols, %{})}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec parse_adl_rank(term(), term(), term()) :: term()
  def parse_adl_rank(exchange, info, market \\ nil) do
    _ = exchange
    _ = info
    _ = market

    try do
      adl_quantile = Runtime.safe_dict(info, "adlQuantile", %{})
      long_num = Runtime.safe_number(adl_quantile, "LONG")
      short_num = Runtime.safe_number(adl_quantile, "SHORT")
      both = Runtime.safe_number(adl_quantile, "BOTH")
      rank = nil
      _ = rank

      {rank} =
        if Runtime.truthy(both != nil) do
          rank = both
          _ = rank

          {rank}
        else
          {rank} =
            if Runtime.truthy(
                 Runtime.truthy(long_num != nil) and Runtime.truthy(short_num != nil)
               ) do
              {rank} =
                if Runtime.truthy(long_num > short_num) do
                  rank = long_num
                  _ = rank

                  {rank}
                else
                  rank = short_num
                  _ = rank

                  {rank}
                end

              _ = rank

              {rank}
            else
              {rank}
            end

          _ = rank

          {rank}
        end

      _ = rank

      market_id = Runtime.safe_string(info, "symbol")
      timestamp = Runtime.safe_integer2(info, "timestamp", "updateTime")

      throw(
        {:ccxt_return,
         %{
           "info" => info,
           "symbol" => Runtime.safe_symbol(exchange, market_id, market, nil, "contract"),
           "rank" => rank,
           "rating" => Runtime.safe_string_lower(info, "adlRisk"),
           "percentage" => nil,
           "timestamp" => timestamp,
           "datetime" => Runtime.iso8601(timestamp)
         }}
      )
    catch
      {:ccxt_return, value} -> value
    end
  end

  @spec fetch_deposit_withdraw_fee(String.t(), params(), (RawEndpoint.t(), params() ->
                                                            {:ok, map()} | {:error, term()})) ::
          {:ok, map()} | {:error, term()}
  def fetch_deposit_withdraw_fee(code, params \\ %{}, fetcher \\ &default_fetcher/2) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{"fetchDepositWithdrawFees" => true},
          options: %{
            "defaultType" => "spot",
            "fetchMarkets" => %{"types" => ["spot"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = code
    _ = params

    try do
      if Runtime.truthy(
           not Runtime.truthy(
             Runtime.safe_value(Runtime.safe_value(exchange, "has"), "fetchDepositWithdrawFees")
           )
         ) do
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " fetchDepositWithdrawFee() is not supported yet"
           ])}
        )
      end

      fees =
        Runtime.call_generated!(exchange, __MODULE__, :fetch_deposit_withdraw_fees, [
          [code],
          params,
          fetcher
        ])

      {:ok, Runtime.safe_value(fees, code)}
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_mark_ohlcv(
          String.t(),
          String.t(),
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_mark_ohlcv(
        symbol,
        timeframe \\ "1m",
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{"fetchMarkOHLCV" => true},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = timeframe
    _ = since
    _ = limit
    _ = params

    try do
      if Runtime.truthy(Runtime.safe_value(Runtime.safe_value(exchange, "has"), "fetchMarkOHLCV")) do
        request = %{"price" => "mark"}

        throw(
          {:ccxt_return,
           Runtime.call_generated!(exchange, __MODULE__, :fetch_ohlcv, [
             symbol,
             timeframe,
             since,
             limit,
             Runtime.extend(request, params),
             fetcher
           ])}
        )
      else
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <> " fetchMarkOHLCV () is not supported yet"
           ])}
        )
      end
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_index_ohlcv(
          String.t(),
          String.t(),
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_index_ohlcv(
        symbol,
        timeframe \\ "1m",
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{"fetchIndexOHLCV" => true},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = timeframe
    _ = since
    _ = limit
    _ = params

    try do
      if Runtime.truthy(
           Runtime.safe_value(Runtime.safe_value(exchange, "has"), "fetchIndexOHLCV")
         ) do
        request = %{"price" => "index"}

        throw(
          {:ccxt_return,
           Runtime.call_generated!(exchange, __MODULE__, :fetch_ohlcv, [
             symbol,
             timeframe,
             since,
             limit,
             Runtime.extend(request, params),
             fetcher
           ])}
        )
      else
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <> " fetchIndexOHLCV () is not supported yet"
           ])}
        )
      end
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  @spec fetch_premium_index_ohlcv(
          String.t(),
          String.t(),
          integer() | nil,
          integer() | nil,
          params(),
          (RawEndpoint.t(), params() -> {:ok, map()} | {:error, term()})
        ) ::
          {:ok, list()} | {:error, term()}
  def fetch_premium_index_ohlcv(
        symbol,
        timeframe \\ "1m",
        since \\ nil,
        limit \\ nil,
        params \\ %{},
        fetcher \\ &default_fetcher/2
      ) do
    exchange =
      Map.merge(
        %{
          id: "binance",
          has: %{"fetchPremiumIndexOHLCV" => true},
          options: %{
            "defaultType" => "future",
            "fetchMarkets" => %{"types" => ["linear", "inverse"]},
            "sandboxMode" => false,
            "enableDemoTrading" => false
          }
        },
        %{}
      )

    {exchange, params} = Runtime.take_exchange_options(exchange, params)
    _ = exchange
    _ = fetcher
    _ = symbol
    _ = timeframe
    _ = since
    _ = limit
    _ = params

    try do
      if Runtime.truthy(
           Runtime.safe_value(Runtime.safe_value(exchange, "has"), "fetchPremiumIndexOHLCV")
         ) do
        request = %{"price" => "premiumIndex"}

        throw(
          {:ccxt_return,
           Runtime.call_generated!(exchange, __MODULE__, :fetch_ohlcv, [
             symbol,
             timeframe,
             since,
             limit,
             Runtime.extend(request, params),
             fetcher
           ])}
        )
      else
        throw(
          {:ccxt_error,
           Runtime.new_error_reason(":not_supported", [
             Runtime.safe_value(exchange, "id") <>
               " fetchPremiumIndexOHLCV () is not supported yet"
           ])}
        )
      end
    catch
      {:ccxt_return, value} -> {:ok, value}
      {:ccxt_error, reason} -> {:error, reason}
    end
  end

  defp default_fetcher(endpoint, params), do: HttpExecutor.fetch(endpoint, params)
end