# -*- coding: utf-8 -*-

# 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

from ccxt.async_support.base.exchange import Exchange
from ccxt.abstract.bitteam import ImplicitAPI
from ccxt.base.types import Balances, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
from typing import List
from ccxt.base.errors import ExchangeError
from ccxt.base.errors import AuthenticationError
from ccxt.base.errors import ArgumentsRequired
from ccxt.base.errors import BadRequest
from ccxt.base.errors import BadSymbol
from ccxt.base.errors import InsufficientFunds
from ccxt.base.errors import OrderNotFound
from ccxt.base.errors import ExchangeNotAvailable
from ccxt.base.decimal_to_precision import DECIMAL_PLACES
from ccxt.base.precise import Precise


class bitteam(Exchange, ImplicitAPI):

    def describe(self):
        return self.deep_extend(super(bitteam, self).describe(), {
            'id': 'bitteam',
            'name': 'BIT.TEAM',
            'countries': ['UK'],
            'version': 'v2.0.6',
            'rateLimit': 1,  # the exchange has no rate limit
            'certified': False,
            'pro': False,
            'has': {
                'CORS': None,
                'spot': True,
                'margin': False,
                'swap': False,
                'future': False,
                'option': False,
                'addMargin': False,
                'borrowMargin': False,
                'cancelAllOrders': True,
                'cancelOrder': True,
                'cancelOrders': False,
                'createDepositAddress': False,
                'createOrder': True,
                'createPostOnlyOrder': False,
                'createReduceOnlyOrder': False,
                'createStopLimitOrder': False,
                'createStopMarketOrder': False,
                'createStopOrder': False,
                'deposit': False,
                'editOrder': False,
                'fetchAccounts': False,
                'fetchBalance': True,
                'fetchBidsAsks': False,
                'fetchBorrowInterest': False,
                'fetchBorrowRateHistories': False,
                'fetchBorrowRateHistory': False,
                'fetchCanceledOrders': True,
                'fetchClosedOrder': False,
                'fetchClosedOrders': True,
                'fetchCrossBorrowRate': False,
                'fetchCrossBorrowRates': False,
                'fetchCurrencies': True,
                'fetchDeposit': False,
                'fetchDepositAddress': False,
                'fetchDepositAddresses': False,
                'fetchDepositAddressesByNetwork': False,
                'fetchDeposits': False,
                'fetchDepositsWithdrawals': True,
                'fetchDepositWithdrawFee': False,
                'fetchDepositWithdrawFees': False,
                'fetchFundingHistory': False,
                'fetchFundingRate': False,
                'fetchFundingRateHistory': False,
                'fetchFundingRates': False,
                'fetchIndexOHLCV': False,
                'fetchIsolatedBorrowRate': False,
                'fetchIsolatedBorrowRates': False,
                'fetchL3OrderBook': False,
                'fetchLedger': False,
                'fetchLeverage': False,
                'fetchLeverageTiers': False,
                'fetchMarketLeverageTiers': False,
                'fetchMarkets': True,
                'fetchMarkOHLCV': False,
                'fetchMyTrades': True,
                'fetchOHLCV': True,
                'fetchOpenInterestHistory': False,
                'fetchOpenOrder': False,
                'fetchOpenOrders': True,
                'fetchOrder': True,
                'fetchOrderBook': True,
                'fetchOrderBooks': False,
                'fetchOrders': True,
                'fetchOrderTrades': False,
                'fetchPosition': False,
                'fetchPositionHistory': False,
                'fetchPositionMode': False,
                'fetchPositions': False,
                'fetchPositionsForSymbol': False,
                'fetchPositionsHistory': False,
                'fetchPositionsRisk': False,
                'fetchPremiumIndexOHLCV': False,
                'fetchStatus': False,
                'fetchTicker': True,
                'fetchTickers': True,
                'fetchTime': False,
                'fetchTrades': True,
                'fetchTradingFee': False,
                'fetchTradingFees': False,
                'fetchTradingLimits': False,
                'fetchTransactionFee': False,
                'fetchTransactionFees': False,
                'fetchTransactions': True,
                'fetchTransfers': False,
                'fetchWithdrawal': False,
                'fetchWithdrawals': False,
                'fetchWithdrawalWhitelist': False,
                'reduceMargin': False,
                'repayMargin': False,
                'setLeverage': False,
                'setMargin': False,
                'setMarginMode': False,
                'setPositionMode': False,
                'signIn': False,
                'transfer': False,
                'withdraw': False,
                'ws': False,
            },
            'timeframes': {
                '1m': '1',
                '5m': '5',
                '15m': '15',
                '1h': '60',
                '1d': '1D',
            },
            'urls': {
                'logo': 'https://github.com/ccxt/ccxt/assets/43336371/cf71fe3d-b8b4-40f2-a906-907661b28793',
                'api': {
                    'history': 'https://history.bit.team',
                    'public': 'https://bit.team',
                    'private': 'https://bit.team',
                },
                'www': 'https://bit.team/',
                'referral': 'https://bit.team/auth/sign-up?ref=bitboy2023',
                'doc': [
                    'https://bit.team/trade/api/documentation',
                ],
            },
            'api': {
                'history': {
                    'get': {
                        'api/tw/history/{pairName}/{resolution}': 1,
                    },
                },
                'public': {
                    'get': {
                        'trade/api/asset': 1,  # not unified
                        'trade/api/currencies': 1,
                        'trade/api/orderbooks/{symbol}': 1,  # not unified
                        'trade/api/orders': 1,  # not unified
                        'trade/api/pair/{name}': 1,
                        'trade/api/pairs': 1,  # not unified
                        'trade/api/pairs/precisions': 1,  # not unified
                        'trade/api/rates': 1,  # not unified
                        'trade/api/trade/{id}': 1,  # not unified
                        'trade/api/trades': 1,  # not unified
                        'trade/api/ccxt/pairs': 1,
                        'trade/api/cmc/assets': 1,
                        'trade/api/cmc/orderbook/{pair}': 1,
                        'trade/api/cmc/summary': 1,
                        'trade/api/cmc/ticker': 1,  # not unified
                        'trade/api/cmc/trades/{pair}': 1,
                    },
                },
                'private': {
                    'get': {
                        'trade/api/ccxt/balance': 1,
                        'trade/api/ccxt/order/{id}': 1,
                        'trade/api/ccxt/ordersOfUser': 1,
                        'trade/api/ccxt/tradesOfUser': 1,
                        'trade/api/transactionsOfUser': 1,
                    },
                    'post': {
                        'trade/api/ccxt/cancel-all-order': 1,
                        'trade/api/ccxt/cancelorder': 1,
                        'trade/api/ccxt/ordercreate': 1,
                    },
                },
            },
            'fees': {
                'trading': {
                    'feeSide': 'get',
                    'tierBased': False,
                    'percentage': True,
                    'taker': self.parse_number('0.002'),
                    'maker': self.parse_number('0.002'),
                },
            },
            'precisionMode': DECIMAL_PLACES,
            # exchange-specific options
            'options': {
                'networksById': {
                    'Ethereum': 'ERC20',
                    'ethereum': 'ERC20',
                    'Tron': 'TRC20',
                    'tron': 'TRC20',
                    'Binance': 'BSC',
                    'binance': 'BSC',
                    'Binance Smart Chain': 'BSC',
                    'bscscan': 'BSC',
                    'Bitcoin': 'BTC',
                    'bitcoin': 'BTC',
                    'Litecoin': 'LTC',
                    'litecoin': 'LTC',
                    'Polygon': 'POLYGON',
                    'polygon': 'POLYGON',
                    'PRIZM': 'PRIZM',
                    'Decimal': 'Decimal',
                    'ufobject': 'ufobject',
                    'tonchain': 'tonchain',
                },
                'currenciesValuedInUsd': {
                    'USDT': True,
                    'BUSD': True,
                },
            },
            'exceptions': {
                'exact': {
                    '400002': BadSymbol,  # {"ok":false,"code":400002,"message":"An order cannot be created on a deactivated pair"}
                    '401000': AuthenticationError,  # {"ok":false,"code":401000,"data": {},"message": "Missing authentication"}
                    '403002': BadRequest,  # {"ok":false,"code":403002,"data":{},"message":"Order cannot be deleted, status does not match"}
                    '404200': BadSymbol,  # {"ok":false,"code":404200,"data":{},"message":"Pair was not found"}
                },
                'broad': {
                    'is not allowed': BadRequest,  # {"message":"\"createdAt\" is not allowed","path":["createdAt"],"type":"object.unknown","context":{"child":"createdAt","label":"createdAt","value":"DESC","key":"createdAt"}}
                    'Insufficient funds': InsufficientFunds,  # {"ok":false,"code":450000,"data":null,"message":"Insufficient funds"}
                    'Invalid request params input': BadRequest,  # {"ok":false,"code":400000,"data":{},"message":"Invalid request params input"}
                    'must be a number': BadRequest,  # [ExchangeError] bitteam {"message":"\"currency\" must be a number","path":["currency"],"type":"number.base","context":{"label":"currency","value":"adsf","key":"currency"}}
                    'must be a string': BadRequest,  # {"message":"\"pairId\" must be a string","path":["pairId"],"type":"string.base","context":{"label":"pairId","value":87,"key":"pairId"}}
                    'must be of type': BadRequest,  # {"message":"\"order\" must be of type object","path":["order"],"type":"object.base","context":{"type":"object","label":"order","value":"107218781","key":"order"}}
                    'must be one of': BadRequest,  # {"message":"\"resolution\" must be one of [1, 5, 15, 60, 1D]","path":["resolution"],"type":"any.only","context":{"valids":["1","5","15","60","1D"],"label":"resolution","value":"1d","key":"resolution"}}
                    'Order not found': OrderNotFound,  # {"ok":false,"code":404300,"data":{},"message":"Order not found"}
                    'Pair with pair name': BadSymbol,  # {"ok":false,"code":404000,"data":{"pairName":"ETH_USasdf"},"msg":"Pair with pair name ETH_USasdf was not found"}
                    'pairName': BadSymbol,  # {"message":"\"pairName\" length must be at least 7 characters long","path":["pairName"],"type":"string.min","context":{"limit":7,"value":"ETH_US","label":"pairName","key":"pairName"}}
                    'Service Unavailable': ExchangeNotAvailable,  # {"message":"Service Unavailable","code":403000,"ok":false}
                    'Symbol ': BadSymbol,  # {"ok":false,"code":404000,"data":{},"message":"Symbol asdfasdfas was not found"}
                },
            },
        })

    async def fetch_markets(self, params={}) -> List[Market]:
        """
        retrieves data on all markets for bitteam
        :see: https://bit.team/trade/api/documentation#/CCXT/getTradeApiCcxtPairs
        :param dict [params]: extra parameters specific to the exchange api endpoint
        :returns dict[]: an array of objects representing market data
        """
        response = await self.publicGetTradeApiCcxtPairs(params)
        #
        #     {
        #         "ok": True,
        #         "result": {
        #             "count": 28,
        #             "pairs": [
        #                 {
        #                     "id": 2,
        #                     "name": "eth_usdt",
        #                     "baseAssetId": 2,
        #                     "quoteAssetId": 3,
        #                     "fullName": "ETH USDT",
        #                     "description": "ETH   USDT",
        #                     "lastBuy": 1964.665001,
        #                     "lastSell": 1959.835005,
        #                     "lastPrice": 1964.665001,
        #                     "change24": 1.41,
        #                     "volume24": 28.22627543,
        #                     "volume24USD": 55662.35636401598,
        #                     "active": True,
        #                     "baseStep": 8,
        #                     "quoteStep": 6,
        #                     "status": 1,
        #                     "settings": {
        #                         "limit_usd": "0.1",
        #                         "price_max": "10000000000000",
        #                         "price_min": "1",
        #                         "price_tick": "1",
        #                         "pricescale": 10000,
        #                         "lot_size_max": "1000000000000000",
        #                         "lot_size_min": "1",
        #                         "lot_size_tick": "1",
        #                         "price_view_min": 6,
        #                         "default_slippage": 10,
        #                         "lot_size_view_min": 6
        #                     },
        #                     "updateId": "50620",
        #                     "timeStart": "2021-01-28T09:19:30.706Z",
        #                     "makerFee": 200,
        #                     "takerFee": 200,
        #                     "quoteVolume24": 54921.93404134529,
        #                     "lowPrice24": 1919.355,
        #                     "highPrice24": 1971.204995
        #                 },
        #                 {
        #                     "id": 27,
        #                     "name": "ltc_usdt",
        #                     "baseAssetId": 13,
        #                     "quoteAssetId": 3,
        #                     "fullName": "LTC USDT",
        #                     "description": "This is LTC USDT",
        #                     "lastBuy": 53.14,
        #                     "lastSell": 53.58,
        #                     "lastPrice": 53.58,
        #                     "change24": -6.72,
        #                     "volume24": 0,
        #                     "volume24USD": null,
        #                     "active": True,
        #                     "baseStep": 8,
        #                     "quoteStep": 6,
        #                     "status": 0,
        #                     "settings": {
        #                         "limit_usd": "0.1",
        #                         "price_max": "1000000000000",
        #                         "price_min": "1",
        #                         "price_tick": "1",
        #                         "pricescale": 10000,
        #                         "lot_size_max": "1000000000000",
        #                         "lot_size_min": "1",
        #                         "lot_size_tick": "1",
        #                         "price_view_min": 6,
        #                         "default_slippage": 10,
        #                         "lot_size_view_min": 6
        #                     },
        #                     "updateId": "30",
        #                     "timeStart": "2021-10-13T12:11:05.359Z",
        #                     "makerFee": 200,
        #                     "takerFee": 200,
        #                     "quoteVolume24": 0,
        #                     "lowPrice24": null,
        #                     "highPrice24": null
        #                 }
        #             ]
        #         }
        #     }
        #
        result = self.safe_value(response, 'result', {})
        markets = self.safe_value(result, 'pairs', [])
        return self.parse_markets(markets)

    def parse_market(self, market) -> Market:
        id = self.safe_string(market, 'name')
        numericId = self.safe_integer(market, 'id')
        parts = id.split('_')
        baseId = self.safe_string(parts, 0)
        quoteId = self.safe_string(parts, 1)
        base = self.safe_currency_code(baseId)
        quote = self.safe_currency_code(quoteId)
        active = self.safe_value(market, 'active')
        amountPrecision = self.safe_integer(market, 'baseStep')
        pricePrecision = self.safe_integer(market, 'quoteStep')
        timeStart = self.safe_string(market, 'timeStart')
        created = self.parse8601(timeStart)
        minCost = None
        currenciesValuedInUsd = self.safe_value(self.options, 'currenciesValuedInUsd', {})
        quoteInUsd = self.safe_bool(currenciesValuedInUsd, quote, False)
        if quoteInUsd:
            settings = self.safe_value(market, 'settings', {})
            minCost = self.safe_number(settings, 'limit_usd')
        return self.safe_market_structure({
            'id': id,
            'numericId': numericId,
            'symbol': base + '/' + quote,
            'base': base,
            'quote': quote,
            'settle': None,
            'baseId': baseId,
            'quoteId': quoteId,
            'settleId': None,
            'type': 'spot',
            'spot': True,
            'margin': False,
            'swap': False,
            'future': False,
            'option': False,
            'active': active,
            'contract': False,
            'linear': None,
            'inverse': None,
            'contractSize': None,
            'expiry': None,
            'expiryDatetime': None,
            'strike': None,
            'optionType': None,
            'precision': {
                'amount': amountPrecision,
                'price': pricePrecision,
            },
            'limits': {
                'leverage': {
                    'min': None,
                    'max': None,
                },
                'amount': {
                    'min': None,
                    'max': None,
                },
                'price': {
                    'min': None,
                    'max': None,
                },
                'cost': {
                    'min': minCost,
                    'max': None,
                },
            },
            'created': created,
            'info': market,
        })

    async def fetch_currencies(self, params={}) -> Currencies:
        """
        fetches all available currencies on an exchange
        :see: https://bit.team/trade/api/documentation#/PUBLIC/getTradeApiCurrencies
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :returns dict: an associative dictionary of currencies
        """
        response = await self.publicGetTradeApiCurrencies(params)
        #
        #     {
        #         "ok": True,
        #         "result": {
        #             "count": 24,
        #             "currencies": [
        #                 {
        #                     "txLimits": {
        #                         "minDeposit": "0.0001",
        #                         "minWithdraw": "0.02",
        #                         "maxWithdraw": "10000",
        #                         "withdrawCommissionPercentage": "NaN",
        #                         "withdrawCommissionFixed": "0.005"
        #                     },
        #                     "id": 2,
        #                     "status": 1,
        #                     "symbol": "eth",
        #                     "title": "Ethereum",
        #                     "logoURL": "https://ethereum.org/static/6b935ac0e6194247347855dc3d328e83/34ca5/eth-diamond-black.png",
        #                     "isDiscount": False,
        #                     "address": "https://ethereum.org/",
        #                     "description": "Ethereum ETH",
        #                     "decimals": 18,
        #                     "blockChain": "Ethereum",
        #                     "precision": 8,
        #                     "currentRate": null,
        #                     "active": True,
        #                     "timeStart": "2021-01-28T08:57:41.719Z",
        #                     "type": "crypto",
        #                     "typeNetwork": "internalGW",
        #                     "idSorting": 2,
        #                     "links": [
        #                         {
        #                             "tx": "https://etherscan.io/tx/",
        #                             "address": "https://etherscan.io/address/",
        #                             "blockChain": "Ethereum"
        #                         }
        #                     ]
        #                 },
        #                 {
        #                     "txLimits": {
        #                         "minDeposit": "0.001",
        #                         "minWithdraw": "1",
        #                         "maxWithdraw": "100000",
        #                         "withdrawCommissionPercentage": "NaN",
        #                         "withdrawCommissionFixed": {
        #                             "Tron": "2",
        #                             "Binance": "2",
        #                             "Ethereum": "20"
        #                         }
        #                     },
        #                     "id": 3,
        #                     "status": 1,
        #                     "symbol": "usdt",
        #                     "title": "Tether USD",
        #                     "logoURL": "https://cryptologos.cc/logos/tether-usdt-logo.png?v=010",
        #                     "isDiscount": False,
        #                     "address": "https://tether.to/",
        #                     "description": "Tether USD",
        #                     "decimals": 6,
        #                     "blockChain": "",
        #                     "precision": 6,
        #                     "currentRate": null,
        #                     "active": True,
        #                     "timeStart": "2021-01-28T09:04:17.170Z",
        #                     "type": "crypto",
        #                     "typeNetwork": "internalGW",
        #                     "idSorting": 0,
        #                     "links": [
        #                         {
        #                             "tx": "https://etherscan.io/tx/",
        #                             "address": "https://etherscan.io/address/",
        #                             "blockChain": "Ethereum"
        #                         },
        #                         {
        #                             "tx": "https://tronscan.org/#/transaction/",
        #                             "address": "https://tronscan.org/#/address/",
        #                             "blockChain": "Tron"
        #                         },
        #                         {
        #                             "tx": "https://bscscan.com/tx/",
        #                             "address": "https://bscscan.com/address/",
        #                             "blockChain": "Binance"
        #                         }
        #                     ]
        #                 }
        #             ]
        #         }
        #     }
        #
        responseResult = self.safe_value(response, 'result', {})
        currencies = self.safe_value(responseResult, 'currencies', [])
        # usding another endpoint to fetch statuses of deposits and withdrawals
        statusesResponse = await self.publicGetTradeApiCmcAssets()
        #
        #     {
        #         "ZNX": {
        #             "name": "ZeNeX Coin",
        #             "unified_cryptoasset_id": 30,
        #             "withdrawStatus": True,
        #             "depositStatus": True,
        #             "min_withdraw": 0.00001,
        #             "max_withdraw": 10000
        #         },
        #         "USDT": {
        #             "name": "Tether USD",
        #             "unified_cryptoasset_id": 3,
        #             "withdrawStatus": True,
        #             "depositStatus": True,
        #             "min_withdraw": 1,
        #             "max_withdraw": 100000
        #         },
        #     }
        #
        statusesResponse = self.index_by(statusesResponse, 'unified_cryptoasset_id')
        result = {}
        for i in range(0, len(currencies)):
            currency = currencies[i]
            id = self.safe_string(currency, 'symbol')
            numericId = self.safe_integer(currency, 'id')
            code = self.safe_currency_code(id)
            active = self.safe_bool(currency, 'active', False)
            precision = self.safe_integer(currency, 'precision')
            txLimits = self.safe_value(currency, 'txLimits', {})
            minWithdraw = self.safe_string(txLimits, 'minWithdraw')
            maxWithdraw = self.safe_string(txLimits, 'maxWithdraw')
            minDeposit = self.safe_string(txLimits, 'minDeposit')
            fee = None
            withdrawCommissionFixed = self.safe_value(txLimits, 'withdrawCommissionFixed', {})
            feesByNetworkId = {}
            blockChain = self.safe_string(currency, 'blockChain')
            # if only one blockChain
            if (blockChain is not None) and (blockChain != ''):
                fee = self.parse_number(withdrawCommissionFixed)
                feesByNetworkId[blockChain] = fee
            else:
                feesByNetworkId = withdrawCommissionFixed
            statuses = self.safe_value(statusesResponse, numericId, {})
            deposit = self.safe_value(statuses, 'depositStatus')
            withdraw = self.safe_value(statuses, 'withdrawStatus')
            networkIds = list(feesByNetworkId.keys())
            networks = {}
            networkPrecision = self.safe_integer(currency, 'decimals')
            for j in range(0, len(networkIds)):
                networkId = networkIds[j]
                networkCode = self.network_id_to_code(networkId, code)
                networkFee = self.safe_number(feesByNetworkId, networkId)
                networks[networkCode] = {
                    'id': networkId,
                    'network': networkCode,
                    'deposit': deposit,
                    'withdraw': withdraw,
                    'active': active,
                    'fee': networkFee,
                    'precision': networkPrecision,
                    'limits': {
                        'amount': {
                            'min': None,
                            'max': None,
                        },
                        'withdraw': {
                            'min': self.parse_number(minWithdraw),
                            'max': self.parse_number(maxWithdraw),
                        },
                        'deposit': {
                            'min': self.parse_number(minDeposit),
                            'max': None,
                        },
                    },
                    'info': currency,
                }
            result[code] = {
                'id': id,
                'numericId': numericId,
                'code': code,
                'name': code,
                'info': currency,
                'active': active,
                'deposit': deposit,
                'withdraw': withdraw,
                'fee': fee,
                'precision': precision,
                'limits': {
                    'amount': {
                        'min': None,
                        'max': None,
                    },
                    'withdraw': {
                        'min': self.parse_number(minWithdraw),
                        'max': self.parse_number(maxWithdraw),
                    },
                    'deposit': {
                        'min': self.parse_number(minDeposit),
                        'max': None,
                    },
                },
                'networks': networks,
            }
        return result

    async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
        """
        fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
        :param str symbol: unified symbol of the market to fetch OHLCV data for
        :param str timeframe: the length of time each candle represents
        :param int [since]: timestamp in ms of the earliest candle to fetch
        :param int [limit]: the maximum amount of candles to fetch
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :returns int[][]: A list of candles ordered, open, high, low, close, volume
        """
        await self.load_markets()
        market = self.market(symbol)
        resolution = self.safe_string(self.timeframes, timeframe, timeframe)
        request = {
            'pairName': market['id'],
            'resolution': resolution,
        }
        response = await self.historyGetApiTwHistoryPairNameResolution(self.extend(request, params))
        #
        #     {
        #         "ok": True,
        #         "result": {
        #             "count": 364,
        #             "data": [
        #                 {
        #                     "t": 1669593600,
        #                     "o": 16211.259266,
        #                     "h": 16476.985001,
        #                     "l": 16023.714999,
        #                     "c": 16430.636894,
        #                     "v": 2.60150368999999
        #                 },
        #                 {
        #                     "t": 1669680000,
        #                     "o": 16430.636894,
        #                     "h": 17065.229582,
        #                     "l": 16346.114155,
        #                     "c": 16882.297736,
        #                     "v": 3.0872548400000115
        #                 },
        #                 ...
        #             ]
        #         }
        #     }
        #
        result = self.safe_value(response, 'result', {})
        data = self.safe_list(result, 'data', [])
        return self.parse_ohlcvs(data, market, timeframe, since, limit)

    def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
        #
        #     {
        #         "t": 1669680000,
        #         "o": 16430.636894,
        #         "h": 17065.229582,
        #         "l": 16346.114155,
        #         "c": 16882.297736,
        #         "v": 3.0872548400000115
        #     },
        #
        return [
            self.safe_timestamp(ohlcv, 't'),
            self.safe_number(ohlcv, 'o'),
            self.safe_number(ohlcv, 'h'),
            self.safe_number(ohlcv, 'l'),
            self.safe_number(ohlcv, 'c'),
            self.safe_number(ohlcv, 'v'),
        ]

    async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
        """
        fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
        :see: https://bit.team/trade/api/documentation#/CMC/getTradeApiCmcOrderbookPair
        :param str symbol: unified symbol of the market to fetch the order book for
        :param int [limit]: the maximum amount of order book entries to return(default 100, max 200)
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :returns dict: A dictionary of `order book structures <https://github.com/ccxt/ccxt/wiki/Manual#order-book-structure>` indexed by market symbols
        """
        await self.load_markets()
        market = self.market(symbol)
        request = {
            'pair': market['id'],
        }
        response = await self.publicGetTradeApiCmcOrderbookPair(self.extend(request, params))
        #
        #     {
        #         "timestamp": 1701166703285,
        #         "bids": [
        #             [
        #                 2019.334988,
        #                 0.09048525
        #             ],
        #             [
        #                 1999.860002,
        #                 0.0225
        #             ],
        #             ...
        #         ],
        #         "asks": [
        #             [
        #                 2019.334995,
        #                 0.00899078
        #             ],
        #             [
        #                 2019.335013,
        #                 0.09833052
        #             ],
        #             ...
        #         ]
        #     }
        #
        timestamp = self.safe_integer(response, 'timestamp')
        orderbook = self.parse_order_book(response, symbol, timestamp)
        return orderbook

    async def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
        """
        fetches information on multiple orders made by the user
        :see: https://bit.team/trade/api/documentation#/PRIVATE/getTradeApiCcxtOrdersofuser
        :param str symbol: unified market symbol of the market orders were made in
        :param int [since]: the earliest time in ms to fetch orders for
        :param int [limit]: the maximum number of  orde structures to retrieve(default 10)
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :param str [params.type]: the status of the order - 'active', 'closed', 'cancelled', 'all', 'history'(default 'all')
        :returns Order[]: a list of `order structures <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
        """
        await self.load_markets()
        type = self.safe_string(params, 'type', 'all')
        request = {
            'type': type,
        }
        market = None
        if symbol is not None:
            market = self.market(symbol)
            request['pair'] = market['id']
        if limit is not None:
            request['limit'] = limit
        response = await self.privateGetTradeApiCcxtOrdersOfUser(self.extend(request, params))
        #
        #     {
        #         "ok": True,
        #         "result": {
        #             "count": 3,
        #             "orders": [
        #                 {
        #                     "id": 106733026,
        #                     "orderId": null,
        #                     "userId": 21639,
        #                     "pair": "btc_usdt",
        #                     "pairId": 22,
        #                     "quantity": "0.00001",
        #                     "price": "40",
        #                     "executedPrice": "0",
        #                     "fee": null,
        #                     "orderCid": null,
        #                     "executed": "0",
        #                     "expires": null,
        #                     "baseDecimals": 8,
        #                     "quoteDecimals": 6,
        #                     "timestamp": 1700594804,
        #                     "status": "inactive",
        #                     "side": "buy",
        #                     "type": "limit",
        #                     "createdAt": "2023-11-21T19:26:43.868Z",
        #                     "updatedAt": "2023-11-21T19:26:43.868Z"
        #                 },
        #                 {
        #                     "id": 106733308,
        #                     "orderId": "13074362",
        #                     "userId": 21639,
        #                     "pair": "btc_usdt",
        #                     "pairId": 22,
        #                     "quantity": "0.00001",
        #                     "price": "50000",
        #                     "executedPrice": "37017.495008",
        #                     "fee": {
        #                         "amount": "0.00000002",
        #                         "symbol": "btc",
        #                         "userId": 21639,
        #                         "decimals": 8,
        #                         "symbolId": 11
        #                     },
        #                     "orderCid": null,
        #                     "executed": "0.00001",
        #                     "expires": null,
        #                     "baseDecimals": 8,
        #                     "quoteDecimals": 6,
        #                     "timestamp": 1700594959,
        #                     "status": "executed",
        #                     "side": "buy",
        #                     "type": "limit",
        #                     "createdAt": "2023-11-21T19:29:19.946Z",
        #                     "updatedAt": "2023-11-21T19:29:19.946Z"
        #                 },
        #                 {
        #                     "id": 106734455,
        #                     "orderId": "13248984",
        #                     "userId": 21639,
        #                     "pair": "eth_usdt",
        #                     "pairId": 2,
        #                     "quantity": "0.001",
        #                     "price": "1750",
        #                     "executedPrice": "0",
        #                     "fee": null,
        #                     "orderCid": null,
        #                     "executed": "0",
        #                     "expires": null,
        #                     "baseDecimals": 18,
        #                     "quoteDecimals": 6,
        #                     "timestamp": 1700595523,
        #                     "status": "accepted",
        #                     "side": "buy",
        #                     "type": "limit",
        #                     "createdAt": "2023-11-21T19:38:43.530Z",
        #                     "updatedAt": "2023-11-21T19:38:43.530Z"
        #                 }
        #             ]
        #         }
        #     }
        #
        result = self.safe_value(response, 'result', {})
        orders = self.safe_list(result, 'orders', [])
        return self.parse_orders(orders, market, since, limit)

    async def fetch_order(self, id: str, symbol: Str = None, params={}) -> Order:
        """
        fetches information on an order
        :see: https://bit.team/trade/api/documentation#/PRIVATE/getTradeApiCcxtOrderId
        :param int|str id: order id
        :param str symbol: not used by bitteam fetchOrder()
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :returns dict: An `order structure <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
        """
        await self.load_markets()
        request = {
            'id': id,
        }
        market = None
        if symbol is not None:
            market = self.market(symbol)
        response = await self.privateGetTradeApiCcxtOrderId(self.extend(request, params))
        #
        #     {
        #         "ok": True,
        #         "result": {
        #             "id": 106494347,
        #             "orderId": "13214332",
        #             "userId": 15912,
        #             "pair": "eth_usdt",
        #             "pairId": 2,
        #             "quantity": "0.00448598",
        #             "price": "2015.644995",
        #             "executedPrice": "2015.644995",
        #             "fee": {
        #                 "amount": "0",
        #                 "symbol": "eth",
        #                 "userId": 15912,
        #                 "decimals": 18,
        #                 "symbolId": 2,
        #                 "discountAmount": "0",
        #                 "discountSymbol": "btt",
        #                 "discountDecimals": 18,
        #                 "discountSymbolId": 5
        #             },
        #             "orderCid": null,
        #             "executed": "0.00448598",
        #             "expires": null,
        #             "baseDecimals": 18,
        #             "quoteDecimals": 6,
        #             "timestamp": 1700470476,
        #             "status": "executed",
        #             "side": "buy",
        #             "type": "limit",
        #             "stopPrice": null,
        #             "slippage": null
        #         }
        #     }
        #
        result = self.safe_dict(response, 'result')
        return self.parse_order(result, market)

    async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
        """
        fetch all unfilled currently open orders
        :see: https://bit.team/trade/api/documentation#/PRIVATE/getTradeApiCcxtOrdersofuser
        :param str symbol: unified market symbol
        :param int [since]: the earliest time in ms to fetch open orders for
        :param int [limit]: the maximum number of open order structures to retrieve(default 10)
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :returns Order[]: a list of `order structures <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
        """
        await self.load_markets()
        request = {
            'type': 'active',
        }
        return await self.fetch_orders(symbol, since, limit, self.extend(request, params))

    async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
        """
        fetches information on multiple closed orders made by the user
        :see: https://bit.team/trade/api/documentation#/PRIVATE/getTradeApiCcxtOrdersofuser
        :param str symbol: unified market symbol of the market orders were made in
        :param int [since]: the earliest time in ms to fetch orders for
        :param int [limit]: the maximum number of closed order structures to retrieve(default 10)
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :returns Order[]: a list of `order structures <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
        """
        await self.load_markets()
        request = {
            'type': 'closed',
        }
        return await self.fetch_orders(symbol, since, limit, self.extend(request, params))

    async def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
        """
        fetches information on multiple canceled orders made by the user
        :see: https://bit.team/trade/api/documentation#/PRIVATE/getTradeApiCcxtOrdersofuser
        :param str symbol: unified market symbol of the market orders were made in
        :param int [since]: the earliest time in ms to fetch orders for
        :param int [limit]: the maximum number of canceled order structures to retrieve(default 10)
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :returns dict: a list of `order structures <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
        """
        await self.load_markets()
        request = {
            'type': 'cancelled',
        }
        return await self.fetch_orders(symbol, since, limit, self.extend(request, params))

    async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
        """
        create a trade order
        :see: https://bit.team/trade/api/documentation#/PRIVATE/postTradeApiCcxtOrdercreate
        :param str symbol: unified symbol of the market to create an order in
        :param str type: 'market' or 'limit'
        :param str side: 'buy' or 'sell'
        :param float amount: how much of currency you want to trade in units of base currency
        :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :returns dict: an `order structure <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
        """
        await self.load_markets()
        market = self.market(symbol)
        request = {
            'pairId': str(market['numericId']),
            'type': type,
            'side': side,
            'amount': self.amount_to_precision(symbol, amount),
        }
        if type == 'limit':
            if price is None:
                raise ArgumentsRequired(self.id + ' createOrder() requires a price argument for a ' + type + ' order')
            else:
                request['price'] = self.price_to_precision(symbol, price)
        response = await self.privatePostTradeApiCcxtOrdercreate(self.extend(request, params))
        #
        #     {
        #         "ok": True,
        #         "result": {
        #             "id": 106733308,
        #             "userId": 21639,
        #             "quantity": "0.00001",
        #             "pair": "btc_usdt",
        #             "side": "buy",
        #             "price": "50000",
        #             "executed": "0",
        #             "executedPrice": "0",
        #             "status": "created",
        #             "baseDecimals": 8,
        #             "quoteDecimals": 6,
        #             "pairId": 22,
        #             "type": "limit",
        #             "stopPrice": null,
        #             "slippage": null,
        #             "timestamp": "1700594959"
        #         }
        #     }
        #
        order = self.safe_dict(response, 'result', {})
        return self.parse_order(order, market)

    async def cancel_order(self, id: str, symbol: Str = None, params={}):
        """
        cancels an open order
        :see: https://bit.team/trade/api/documentation#/PRIVATE/postTradeApiCcxtCancelorder
        :param str id: order id
        :param str symbol: not used by bitteam cancelOrder()
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :returns dict: An `order structure <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
        """
        await self.load_markets()
        request = {
            'id': id,
        }
        response = await self.privatePostTradeApiCcxtCancelorder(self.extend(request, params))
        #
        #     {
        #         "ok": True,
        #         "result": {
        #             "message": "The request to cancel your order was received"
        #         }
        #     }
        #
        result = self.safe_dict(response, 'result', {})
        return self.parse_order(result)

    async def cancel_all_orders(self, symbol: Str = None, params={}):
        """
        cancel open orders of market
        :see: https://bit.team/trade/api/documentation#/PRIVATE/postTradeApiCcxtCancelallorder
        :param str symbol: unified market symbol
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :returns dict[]: a list of `order structures <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
        """
        await self.load_markets()
        market = None
        request = {}
        if symbol is not None:
            market = self.market(symbol)
            request['pairId'] = str(market['numericId'])
        else:
            request['pairId'] = '0'  # '0' for all markets
        response = await self.privatePostTradeApiCcxtCancelAllOrder(self.extend(request, params))
        #
        #     {
        #         "ok": True,
        #         "result": {
        #             "message":"The request to cancel all your orders was received"
        #         }
        #     }
        #
        result = self.safe_value(response, 'result', {})
        orders = [result]
        return self.parse_orders(orders, market)

    def parse_order(self, order, market: Market = None) -> Order:
        #
        # fetchOrders
        #     {
        #         "id": 106733308,
        #         "orderId": "13074362",
        #         "userId": 21639,
        #         "pair": "btc_usdt",
        #         "pairId": 22,
        #         "quantity": "0.00001",
        #         "price": "50000",
        #         "executedPrice": "37017.495008",
        #         "fee": {
        #             "amount": "0.00000002",
        #             "symbol": "btc",
        #             "userId": 21639,
        #             "decimals": 8,
        #             "symbolId": 11
        #         },
        #         "orderCid": null,
        #         "executed": "0.00001",
        #         "expires": null,
        #         "baseDecimals": 8,
        #         "quoteDecimals": 6,
        #         "timestamp": 1700594959,
        #         "status": "executed",
        #         "side": "buy",
        #         "type": "limit",
        #         "createdAt": "2023-11-21T19:29:19.946Z",
        #         "updatedAt": "2023-11-21T19:29:19.946Z"
        #     },
        #
        # fetchOrder
        #     {
        #         "id": 106494347,
        #         "orderId": "13214332",
        #         "userId": 15912,
        #         "pair": "eth_usdt",
        #         "pairId": 2,
        #         "quantity": "0.00448598",
        #         "price": "2015.644995",
        #         "executedPrice": "2015.644995",
        #         "fee": {
        #             "amount": "0",
        #             "symbol": "eth",
        #             "userId": 15912,
        #             "decimals": 18,
        #             "symbolId": 2,
        #             "discountAmount": "0",
        #             "discountSymbol": "btt",
        #             "discountDecimals": 18,
        #             "discountSymbolId": 5
        #         },
        #         "orderCid": null,
        #         "executed": "0.00448598",
        #         "expires": null,
        #         "baseDecimals": 18,
        #         "quoteDecimals": 6,
        #         "timestamp": 1700470476,
        #         "status": "executed",
        #         "side": "buy",
        #         "type": "limit",
        #         "stopPrice": null,
        #         "slippage": null
        #     }
        #
        # createOrder
        #     {
        #         "id": 106733308,
        #         "userId": 21639,
        #         "quantity": "0.00001",
        #         "pair": "btc_usdt",
        #         "side": "buy",
        #         "price": "50000",
        #         "executed": "0",
        #         "executedPrice": "0",
        #         "status": "created",
        #         "baseDecimals": 8,
        #         "quoteDecimals": 6,
        #         "pairId": 22,
        #         "type": "limit",
        #         "stopPrice": null,
        #         "slippage": null,
        #         "timestamp": "1700594959"
        #     }
        #
        id = self.safe_string(order, 'id')
        marketId = self.safe_string(order, 'pair')
        market = self.safe_market(marketId, market)
        clientOrderId = self.safe_string(order, 'orderCid')
        timestamp = None
        createdAt = self.safe_string(order, 'createdAt')
        if createdAt is not None:
            timestamp = self.parse8601(createdAt)
        else:
            timestamp = self.safe_timestamp(order, 'timestamp')
        updatedAt = self.safe_string(order, 'updatedAt')
        lastUpdateTimestamp = self.parse8601(updatedAt)
        status = self.parse_order_status(self.safe_string(order, 'status'))
        type = self.parse_order_type(self.safe_string(order, 'type'))
        side = self.safe_string(order, 'side')
        feeRaw = self.safe_value(order, 'fee')
        price = self.safe_string(order, 'price')
        stopPrice = self.safe_string(order, 'stopPrice')
        amount = self.safe_string(order, 'quantity')
        filled = self.safe_string(order, 'executed')
        fee = None
        if feeRaw is not None:
            feeCost = self.safe_string(feeRaw, 'amount')
            feeCurrencyId = self.safe_string(feeRaw, 'symbol')
            fee = {
                'currency': self.safe_currency_code(feeCurrencyId),
                'cost': feeCost,
                'rate': None,
            }
        return self.safe_order({
            'id': id,
            'clientOrderId': clientOrderId,
            'timestamp': timestamp,
            'datetime': self.iso8601(timestamp),
            'lastTradeTimestamp': None,
            'lastUpdateTimestamp': lastUpdateTimestamp,
            'status': status,
            'symbol': market['symbol'],
            'type': type,
            'timeInForce': 'GTC',
            'side': side,
            'price': price,
            'stopPrice': stopPrice,
            'triggerPrice': stopPrice,
            'average': None,
            'amount': amount,
            'cost': None,
            'filled': filled,
            'remaining': None,
            'fee': fee,
            'trades': None,
            'info': order,
            'postOnly': False,
        }, market)

    def parse_order_status(self, status):
        statuses = {
            'accepted': 'open',
            'executed': 'closed',
            'cancelled': 'canceled',
            'partiallyCancelled': 'canceled',
            'delete': 'rejected',
            'inactive': 'rejected',
            'executing': 'open',
            'created': 'open',
        }
        return self.safe_string(statuses, status, status)

    def parse_order_type(self, status):
        statuses = {
            'market': 'market',
            'limit': 'limit',
        }
        return self.safe_string(statuses, status, status)

    def parse_value_to_pricision(self, valueObject, valueKey, preciseObject, precisionKey):
        valueRawString = self.safe_string(valueObject, valueKey)
        precisionRawString = self.safe_string(preciseObject, precisionKey)
        if valueRawString is None or precisionRawString is None:
            return None
        precisionString = self.parse_precision(precisionRawString)
        return Precise.string_mul(valueRawString, precisionString)

    async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
        """
        fetches price tickers for multiple markets, statistical calculations with the information calculated over the past 24 hours each market
        :see: https://bit.team/trade/api/documentation#/CMC/getTradeApiCmcSummary
        :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :returns dict: a dictionary of `ticker structures <https://github.com/ccxt/ccxt/wiki/Manual#ticker-structure>`
        """
        await self.load_markets()
        response = await self.publicGetTradeApiCmcSummary()
        #
        #     [
        #         {
        #             "trading_pairs": "BTC_USDT",
        #             "base_currency": "BTC",
        #             "quote_currency": "USDT",
        #             "last_price": 37669.955001,
        #             "lowest_ask": 37670.055,
        #             "highest_bid": 37669.955,
        #             "base_volume": 6.81156888,
        #             "quote_volume": 257400.516878529,
        #             "price_change_percent_24h": -0.29,
        #             "highest_price_24h": 38389.994463,
        #             "lowest_price_24h": 37574.894999
        #         },
        #         {
        #             "trading_pairs": "BNB_USDT",
        #             "base_currency": "BNB",
        #             "quote_currency": "USDT",
        #             "last_price": 233.525142,
        #             "lowest_ask": 233.675,
        #             "highest_bid": 233.425,
        #             "base_volume": 245.0199339,
        #             "quote_volume": 57356.91823827642,
        #             "price_change_percent_24h": -0.32,
        #             "highest_price_24h": 236.171123,
        #             "lowest_price_24h": 231.634637
        #         },
        #         ...
        #     ]
        #
        tickers = []
        if not isinstance(response, list):
            response = []
        for i in range(0, len(response)):
            rawTicker = response[i]
            ticker = self.parse_ticker(rawTicker)
            tickers.append(ticker)
        return self.filter_by_array_tickers(tickers, 'symbol', symbols)

    async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
        """
        fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
        :see: https://bit.team/trade/api/documentation#/PUBLIC/getTradeApiPairName
        :param str symbol: unified symbol of the market to fetch the ticker for
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :returns dict: a `ticker structure <https://github.com/ccxt/ccxt/wiki/Manual#ticker-structure>`
        """
        await self.load_markets()
        market = self.market(symbol)
        request = {
            'name': market['id'],
        }
        response = await self.publicGetTradeApiPairName(self.extend(request, params))
        #
        #     {
        #         "ok": True,
        #         "result": {
        #             "pair": {
        #                 "id": 2,
        #                 "name": "eth_usdt",
        #                 "baseAssetId": 2,
        #                 "quoteAssetId": 3,
        #                 "fullName": "ETH USDT",
        #                 "description": "ETH   USDT",
        #                 "lastBuy": "1976.715012",
        #                 "lastSell": "1971.995006",
        #                 "lastPrice": "1976.715012",
        #                 "change24": "1.02",
        #                 "volume24": 24.0796457,
        #                 "volume24USD": 44282.347995912205,
        #                 "active": True,
        #                 "baseStep": 8,
        #                 "quoteStep": 6,
        #                 "status": 1,
        #                 "settings": {
        #                     "limit_usd": "0.1",
        #                     "price_max": "10000000000000",
        #                     "price_min": "1",
        #                     "price_tick": "1",
        #                     "pricescale": 10000,
        #                     "lot_size_max": "1000000000000000",
        #                     "lot_size_min": "1",
        #                     "lot_size_tick": "1",
        #                     "price_view_min": 6,
        #                     "default_slippage": 10,
        #                     "lot_size_view_min": 6
        #                 },
        #                 "asks": [
        #                     {
        #                     "price": "1976.405003",
        #                     "quantity": "0.0051171",
        #                     "amount": "10.1134620408513"
        #                     },
        #                     {
        #                     "price": "1976.405013",
        #                     "quantity": "0.09001559",
        #                     "amount": "177.90726332415267"
        #                     },
        #                     {
        #                     "price": "2010.704988",
        #                     "quantity": "0.00127892",
        #                     "amount": "2.57153082325296"
        #                     }
        #                 ],
        #                 "bids": [
        #                     {
        #                     "price": "1976.404988",
        #                     "quantity": "0.09875861",
        #                     "amount": "195.18700941194668"
        #                     },
        #                     {
        #                     "price": "1905.472973",
        #                     "quantity": "0.00263591",
        #                     "amount": "5.02265526426043"
        #                     },
        #                     {
        #                     "price": "1904.274973",
        #                     "quantity": "0.09425304",
        #                     "amount": "179.48370520116792"
        #                     }
        #                 ],
        #                 "updateId": "78",
        #                 "timeStart": "2021-01-28T09:19:30.706Z",
        #                 "makerFee": 200,
        #                 "takerFee": 200,
        #                 "quoteVolume24": 49125.1374009045,
        #                 "lowPrice24": 1966.704999,
        #                 "highPrice24": 2080.354997,
        #                 "baseCurrency": {
        #                     "id": 2,
        #                     "status": 1,
        #                     "symbol": "eth",
        #                     "title": "Ethereum",
        #                     "logoURL": "https://ethereum.org/static/6b935ac0e6194247347855dc3d328e83/34ca5/eth-diamond-black.png",
        #                     "isDiscount": False,
        #                     "address": "https://ethereum.org/",
        #                     "description": "Ethereum ETH",
        #                     "decimals": 18,
        #                     "blockChain": "Ethereum",
        #                     "precision": 8,
        #                     "currentRate": null,
        #                     "active": True,
        #                     "timeStart": "2021-01-28T08:57:41.719Z",
        #                     "txLimits": {
        #                         "minDeposit": "100000000000000",
        #                         "maxWithdraw": "10000000000000000000000",
        #                         "minWithdraw": "20000000000000000",
        #                         "withdrawCommissionFixed": "5000000000000000",
        #                         "withdrawCommissionPercentage": "NaN"
        #                     },
        #                     "type": "crypto",
        #                     "typeNetwork": "internalGW",
        #                     "icon": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAiIGhlaWdodD0iMzAiIHZpZXdCb3g9IjAgMCAzMCAzMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgMTVDMCA2LjcxNTczIDYuNzE1NzMgMCAxNSAwVjBDMjMuMjg0MyAwIDMwIDYuNzE1NzMgMzAgMTVWMTVDMzAgMjMuMjg0MyAyMy4yODQzIDMwIDE1IDMwVjMwQzYuNzE1NzMgMzAgMCAyMy4yODQzIDAgMTVWMTVaIiBmaWxsPSJibGFjayIvPgo8cGF0aCBkPSJNMTQuOTU1NyAxOS45NzM5TDkgMTYuMzUwOUwxNC45NTIxIDI1TDIwLjkxMDkgMTYuMzUwOUwxNC45NTIxIDE5Ljk3MzlIMTQuOTU1N1pNMTUuMDQ0MyA1TDkuMDkwOTUgMTUuMTg1M0wxNS4wNDQzIDE4LjgxNDZMMjEgMTUuMTg5MUwxNS4wNDQzIDVaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K",
        #                     "idSorting": 2,
        #                     "links": [
        #                         {
        #                             "tx": "https://etherscan.io/tx/",
        #                             "address": "https://etherscan.io/address/",
        #                             "blockChain": "Ethereum"
        #                         }
        #                     ],
        #                     "clientTxLimits": {
        #                         "minDeposit": "0.0001",
        #                         "minWithdraw": "0.02",
        #                         "maxWithdraw": "10000",
        #                         "withdrawCommissionPercentage": "NaN",
        #                         "withdrawCommissionFixed": "0.005"
        #                     }
        #                 },
        #                 "quoteCurrency": {
        #                     "id": 3,
        #                     "status": 1,
        #                     "symbol": "usdt",
        #                     "title": "Tether USD",
        #                     "logoURL": "https://cryptologos.cc/logos/tether-usdt-logo.png?v=010",
        #                     "isDiscount": False,
        #                     "address": "https://tether.to/",
        #                     "description": "Tether USD",
        #                     "decimals": 6,
        #                     "blockChain": "",
        #                     "precision": 6,
        #                     "currentRate": null,
        #                     "active": True,
        #                     "timeStart": "2021-01-28T09:04:17.170Z",
        #                     "txLimits": {
        #                         "minDeposit": "1000",
        #                         "maxWithdraw": "100000000000",
        #                         "minWithdraw": "1000000",
        #                         "withdrawCommissionFixed": {
        #                             "Tron": "2000000",
        #                             "Binance": "2000000000000000000",
        #                             "Ethereum": "20000000"
        #                         },
        #                         "withdrawCommissionPercentage": "NaN"
        #                     },
        #                     "type": "crypto",
        #                     "typeNetwork": "internalGW",
        #                     "icon": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAiIGhlaWdodD0iMzAiIHZpZXdCb3g9IjAgMCAzMCAzMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgMTVDMCA2LjcxNTczIDYuNzE1NzMgMCAxNSAwVjBDMjMuMjg0MyAwIDMwIDYuNzE1NzMgMzAgMTVWMTVDMzAgMjMuMjg0MyAyMy4yODQzIDMwIDE1IDMwVjMwQzYuNzE1NzMgMzAgMCAyMy4yODQzIDAgMTVWMTVaIiBmaWxsPSIjNkZBNjg4Ii8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMjMgN0g3VjExSDEzVjEyLjA2MkM4Ljk5MjAyIDEyLjMxNDYgNiAxMy4zMTAyIDYgMTQuNUM2IDE1LjY4OTggOC45OTIwMiAxNi42ODU0IDEzIDE2LjkzOFYyM0gxN1YxNi45MzhDMjEuMDA4IDE2LjY4NTQgMjQgMTUuNjg5OCAyNCAxNC41QzI0IDEzLjMxMDIgMjEuMDA4IDEyLjMxNDYgMTcgMTIuMDYyVjExSDIzVjdaTTcuNSAxNC41QzcuNSAxMy40NjA2IDkuMzMzMzMgMTIuMzY4IDEzIDEyLjA3NTZWMTUuNUgxN1YxMi4wNzU5QzIwLjkzODQgMTIuMzkyNyAyMi41IDEzLjYzMzkgMjIuNSAxNC41QzIyLjUgMTUuMzIyIDIwLjAwMDggMTUuODA2MSAxNyAxNS45NTI1QzE1LjcwODIgMTYuMDQ2MiAxMy43OTUxIDE1Ljk4MjYgMTMgMTUuOTM5MUM5Ljk5OTIxIDE1Ljc1NTkgNy41IDE1LjE4MDkgNy41IDE0LjVaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K",
        #                     "idSorting": 0,
        #                     "links": [
        #                         {
        #                             "tx": "https://etherscan.io/tx/",
        #                             "address": "https://etherscan.io/address/",
        #                             "blockChain": "Ethereum"
        #                         },
        #                         {
        #                             "tx": "https://tronscan.org/#/transaction/",
        #                             "address": "https://tronscan.org/#/address/",
        #                             "blockChain": "Tron"
        #                         },
        #                         {
        #                             "tx": "https://bscscan.com/tx/",
        #                             "address": "https://bscscan.com/address/",
        #                             "blockChain": "Binance"
        #                         }
        #                     ],
        #                     "clientTxLimits": {
        #                         "minDeposit": "0.001",
        #                         "minWithdraw": "1",
        #                         "maxWithdraw": "100000",
        #                         "withdrawCommissionPercentage": "NaN",
        #                         "withdrawCommissionFixed": {
        #                             "Tron": "2",
        #                             "Binance": "2",
        #                             "Ethereum": "20"
        #                         }
        #                     }
        #                 },
        #                 "quantities": {
        #                     "asks": "5.58760757",
        #                     "bids": "2226.98663823032198"
        #                 }
        #             }
        #         }
        #     }
        #
        result = self.safe_value(response, 'result', {})
        pair = self.safe_dict(result, 'pair', {})
        return self.parse_ticker(pair, market)

    def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
        #
        # fetchTicker
        #     {
        #         "id": 2,
        #         "name": "eth_usdt",
        #         "baseAssetId": 2,
        #         "quoteAssetId": 3,
        #         "fullName": "ETH USDT",
        #         "description": "ETH   USDT",
        #         "lastBuy": "1976.715012",
        #         "lastSell": "1971.995006",
        #         "lastPrice": "1976.715012",
        #         "change24": "1.02",
        #         "volume24": 24.0796457,
        #         "volume24USD": 44282.347995912205,
        #         "active": True,
        #         "baseStep": 8,
        #         "quoteStep": 6,
        #         "status": 1,
        #         "asks": [
        #             {
        #             "price": "1976.405003",
        #             "quantity": "0.0051171",
        #             "amount": "10.1134620408513"
        #             },
        #             {
        #             "price": "1976.405013",
        #             "quantity": "0.09001559",
        #             "amount": "177.90726332415267"
        #             },
        #             {
        #             "price": "2010.704988",
        #             "quantity": "0.00127892",
        #             "amount": "2.57153082325296"
        #             }
        #                ...
        #         ],
        #         "bids": [
        #             {
        #             "price": "1976.404988",
        #             "quantity": "0.09875861",
        #             "amount": "195.18700941194668"
        #             },
        #             {
        #             "price": "1905.472973",
        #             "quantity": "0.00263591",
        #             "amount": "5.02265526426043"
        #             },
        #             {
        #             "price": "1904.274973",
        #             "quantity": "0.09425304",
        #             "amount": "179.48370520116792"
        #             }
        #                ...
        #         ],
        #         "updateId": "78",
        #         "timeStart": "2021-01-28T09:19:30.706Z",
        #         "makerFee": 200,
        #         "takerFee": 200,
        #         "quoteVolume24": 49125.1374009045,
        #         "lowPrice24": 1966.704999,
        #         "highPrice24": 2080.354997,
        #         ...
        #     }
        #
        # fetchTickers
        #     {
        #         "trading_pairs": "BTC_USDT",
        #         "base_currency": "BTC",
        #         "quote_currency": "USDT",
        #         "last_price": 37669.955001,
        #         "lowest_ask": 37670.055,
        #         "highest_bid": 37669.955,
        #         "base_volume": 6.81156888,
        #         "quote_volume": 257400.516878529,
        #         "price_change_percent_24h": -0.29,
        #         "highest_price_24h": 38389.994463,
        #         "lowest_price_24h": 37574.894999
        #     }
        marketId = self.safe_string_lower(ticker, 'trading_pairs')
        market = self.safe_market(marketId, market)
        bestBidPrice = None
        bestAskPrice = None
        bestBidVolume = None
        bestAskVolume = None
        bids = self.safe_value(ticker, 'bids')
        asks = self.safe_value(ticker, 'asks')
        if (bids is not None) and (isinstance(bids, list)) and (asks is not None) and (isinstance(asks, list)):
            bestBid = self.safe_value(bids, 0, {})
            bestBidPrice = self.safe_string(bestBid, 'price')
            bestBidVolume = self.safe_string(bestBid, 'quantity')
            bestAsk = self.safe_value(asks, 0, {})
            bestAskPrice = self.safe_string(bestAsk, 'price')
            bestAskVolume = self.safe_string(bestAsk, 'quantity')
        else:
            bestBidPrice = self.safe_string(ticker, 'highest_bid')
            bestAskPrice = self.safe_string(ticker, 'lowest_ask')
        baseVolume = self.safe_string_2(ticker, 'volume24', 'base_volume')
        quoteVolume = self.safe_string_2(ticker, 'quoteVolume24', 'quote_volume')
        high = self.safe_string_2(ticker, 'highPrice24', 'highest_price_24h')
        low = self.safe_string_2(ticker, 'lowPrice24', 'lowest_price_24h')
        close = self.safe_string_2(ticker, 'lastPrice', 'last_price')
        changePcnt = self.safe_string_2(ticker, 'change24', 'price_change_percent_24h')
        return self.safe_ticker({
            'symbol': market['symbol'],
            'timestamp': None,
            'datetime': None,
            'open': None,
            'high': high,
            'low': low,
            'close': close,
            'bid': bestBidPrice,
            'bidVolume': bestBidVolume,
            'ask': bestAskPrice,
            'askVolume': bestAskVolume,
            'vwap': None,
            'previousClose': None,
            'change': None,
            'percentage': changePcnt,
            'average': None,
            'baseVolume': baseVolume,
            'quoteVolume': quoteVolume,
            'info': ticker,
        }, market)

    async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
        """
        get the list of most recent trades for a particular symbol
        :see: https://bit.team/trade/api/documentation#/CMC/getTradeApiCmcTradesPair
        :param str symbol: unified symbol of the market to fetch trades for
        :param int [since]: timestamp in ms of the earliest trade to fetch
        :param int [limit]: the maximum amount of trades to fetch
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :returns Trade[]: a list of `trade structures <https://github.com/ccxt/ccxt/wiki/Manual#public-trades>`
        """
        await self.load_markets()
        market = self.market(symbol)
        request = {
            'pair': market['id'],
        }
        response = await self.publicGetTradeApiCmcTradesPair(self.extend(request, params))
        #
        #     [
        #         {
        #             "trade_id": 34970337,
        #             "price": 37769.994793,
        #             "base_volume": 0.00119062,
        #             "quote_volume": 44.96971120044166,
        #             "timestamp": 1700827234000,
        #             "type": "buy"
        #         },
        #         {
        #             "trade_id": 34970347,
        #             "price": 37769.634497,
        #             "base_volume": 0.00104009,
        #             "quote_volume": 39.28381914398473,
        #             "timestamp": 1700827248000,
        #             "type": "buy"
        #         },
        #         ...
        #     ]
        #
        return self.parse_trades(response, market, since, limit)

    async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
        """
        fetch all trades made by the user
        :see: https://bit.team/trade/api/documentation#/PRIVATE/getTradeApiCcxtTradesofuser
        :param str symbol: unified market symbol
        :param int [since]: the earliest time in ms to fetch trades for
        :param int [limit]: the maximum number of trades structures to retrieve(default 10)
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :returns Trade[]: a list of `trade structures <https://github.com/ccxt/ccxt/wiki/Manual#trade-structure>`
        """
        await self.load_markets()
        request = {}
        market = None
        if symbol is not None:
            market = self.market(symbol)
            request['pairId'] = market['numericId']
        if limit is not None:
            request['limit'] = limit
        response = await self.privateGetTradeApiCcxtTradesOfUser(self.extend(request, params))
        #
        #     {
        #         "ok": True,
        #         "result": {
        #             "count": 3,
        #             "trades": [
        #                 {
        #                     "id": 34880724,
        #                     "tradeId": "4368041",
        #                     "makerOrderId": 106742914,
        #                     "takerOrderId": 106761614,
        #                     "pairId": 2,
        #                     "quantity": "0.00955449",
        #                     "price": "1993.674994",
        #                     "isBuyerMaker": True,
        #                     "baseDecimals": 18,
        #                     "quoteDecimals": 6,
        #                     "side": "sell",
        #                     "timestamp": 1700615250,
        #                     "rewarded": True,
        #                     "makerUserId": 21639,
        #                     "takerUserId": 15913,
        #                     "baseCurrencyId": 2,
        #                     "quoteCurrencyId": 3,
        #                     "feeMaker": {
        #                         "amount": "0.0000191",
        #                         "symbol": "eth",
        #                         "userId": 21639,
        #                         "decimals": 18,
        #                         "symbolId": 2
        #                     },
        #                     "feeTaker": {
        #                         "amount": "0",
        #                         "symbol": "usdt",
        #                         "userId": 15913,
        #                         "decimals": 6,
        #                         "symbolId": 3,
        #                         "discountAmount": "0",
        #                         "discountSymbol": "btt",
        #                         "discountDecimals": 18,
        #                         "discountSymbolId": 5
        #                     },
        #                     "pair": "eth_usdt",
        #                     "createdAt": "2023-11-22T01:07:30.593Z",
        #                     "updatedAt": "2023-11-22T01:10:00.117Z",
        #                     "isCurrentSide": "maker"
        #                 },
        #                 {
        #                     "id": 34875793,
        #                     "tradeId": "4368010",
        #                     "makerOrderId": 106742914,
        #                     "takerOrderId": 106745926,
        #                     "pairId": 2,
        #                     "quantity": "0.0027193",
        #                     "price": "1993.674994",
        #                     "isBuyerMaker": True,
        #                     "baseDecimals": 18,
        #                     "quoteDecimals": 6,
        #                     "side": "sell",
        #                     "timestamp": 1700602983,
        #                     "rewarded": True,
        #                     "makerUserId": 21639,
        #                     "takerUserId": 15912,
        #                     "baseCurrencyId": 2,
        #                     "quoteCurrencyId": 3,
        #                     "feeMaker": {
        #                         "amount": "0.00000543",
        #                         "symbol": "eth",
        #                         "userId": 21639,
        #                         "decimals": 18,
        #                         "symbolId": 2
        #                     },
        #                     "feeTaker": {
        #                         "amount": "0",
        #                         "symbol": "usdt",
        #                         "userId": 15912,
        #                         "decimals": 6,
        #                         "symbolId": 3,
        #                         "discountAmount": "0",
        #                         "discountSymbol": "btt",
        #                         "discountDecimals": 18,
        #                         "discountSymbolId": 5
        #                     },
        #                     "pair": "eth_usdt",
        #                     "createdAt": "2023-11-21T21:43:02.758Z",
        #                     "updatedAt": "2023-11-21T21:45:00.147Z",
        #                     "isCurrentSide": "maker"
        #                 },
        #                 {
        #                     "id": 34871727,
        #                     "tradeId": "3441840",
        #                     "makerOrderId": 106733299,
        #                     "takerOrderId": 106733308,
        #                     "pairId": 22,
        #                     "quantity": "0.00001",
        #                     "price": "37017.495008",
        #                     "isBuyerMaker": False,
        #                     "baseDecimals": 8,
        #                     "quoteDecimals": 6,
        #                     "side": "buy",
        #                     "timestamp": 1700594960,
        #                     "rewarded": True,
        #                     "makerUserId": 15909,
        #                     "takerUserId": 21639,
        #                     "baseCurrencyId": 11,
        #                     "quoteCurrencyId": 3,
        #                     "feeMaker": {
        #                         "amount": "0",
        #                         "symbol": "usdt",
        #                         "userId": 15909,
        #                         "decimals": 6,
        #                         "symbolId": 3,
        #                         "discountAmount": "0",
        #                         "discountSymbol": "btt",
        #                         "discountDecimals": 18,
        #                         "discountSymbolId": 5
        #                     },
        #                     "feeTaker": {
        #                         "amount": "0.00000002",
        #                         "symbol": "btc",
        #                         "userId": 21639,
        #                         "decimals": 8,
        #                         "symbolId": 11
        #                     },
        #                     "pair": "btc_usdt",
        #                     "createdAt": "2023-11-21T19:29:20.092Z",
        #                     "updatedAt": "2023-11-21T19:30:00.159Z"
        #                     "isCurrentSide": "taker"
        #                 }
        #             ]
        #         }
        #     }
        #
        result = self.safe_value(response, 'result', {})
        trades = self.safe_list(result, 'trades', [])
        return self.parse_trades(trades, market, since, limit)

    def parse_trade(self, trade, market: Market = None) -> Trade:
        #
        # fetchTrades
        #     {
        #         "trade_id": 34970337,
        #         "price": 37769.994793,
        #         "base_volume": 0.00119062,
        #         "quote_volume": 44.96971120044166,
        #         "timestamp": 1700827234000,
        #         "type": "buy"
        #     },
        #
        # fetchMyTrades
        #     {
        #         "id": 34875793,
        #         "tradeId": "4368010",
        #         "makerOrderId": 106742914,
        #         "takerOrderId": 106745926,
        #         "pairId": 2,
        #         "quantity": "0.0027193",
        #         "price": "1993.674994",
        #         "isBuyerMaker": True,
        #         "baseDecimals": 18,
        #         "quoteDecimals": 6,
        #         "side": "sell",
        #         "timestamp": 1700602983,
        #         "rewarded": True,
        #         "makerUserId": 21639,
        #         "takerUserId": 15912,
        #         "baseCurrencyId": 2,
        #         "quoteCurrencyId": 3,
        #         "feeMaker": {
        #             "amount": "0.00000543",
        #             "symbol": "eth",
        #             "userId": 21639,
        #             "decimals": 18,
        #             "symbolId": 2
        #         },
        #         "feeTaker": {
        #             "amount": "0",
        #             "symbol": "usdt",
        #             "userId": 15912,
        #             "decimals": 6,
        #             "symbolId": 3,
        #             "discountAmount": "0",
        #             "discountSymbol": "btt",
        #             "discountDecimals": 18,
        #             "discountSymbolId": 5
        #         },
        #         "pair": "eth_usdt",
        #         "createdAt": "2023-11-21T21:43:02.758Z",
        #         "updatedAt": "2023-11-21T21:45:00.147Z",
        #         "isCurrentSide": "maker"
        #     }
        #
        marketId = self.safe_string(trade, 'pair')
        market = self.safe_market(marketId, market)
        symbol = market['symbol']
        id = self.safe_string_2(trade, 'id', 'trade_id')
        price = self.safe_string(trade, 'price')
        amount = self.safe_string_2(trade, 'quantity', 'base_volume')
        cost = self.safe_string(trade, 'quote_volume')
        takerOrMaker = self.safe_string(trade, 'isCurrentSide')
        timestamp = self.safe_string(trade, 'timestamp')
        if takerOrMaker is not None:
            timestamp = Precise.string_mul(timestamp, '1000')
        # the exchange returns the side of the taker
        side = self.safe_string_2(trade, 'side', 'type')
        feeInfo = None
        order = None
        if takerOrMaker == 'maker':
            if side == 'sell':
                side = 'buy'
            elif side == 'buy':
                side = 'sell'
            order = self.safe_string(trade, 'makerOrderId')
            feeInfo = self.safe_value(trade, 'feeMaker', {})
        elif takerOrMaker == 'taker':
            order = self.safe_string(trade, 'takerOrderId')
            feeInfo = self.safe_value(trade, 'feeTaker', {})
        feeCurrencyId = self.safe_string(feeInfo, 'symbol')
        feeCost = self.safe_string(feeInfo, 'amount')
        fee = {
            'currency': self.safe_currency_code(feeCurrencyId),
            'cost': feeCost,
            'rate': None,
        }
        intTs = self.parse_to_int(timestamp)
        return self.safe_trade({
            'id': id,
            'order': order,
            'timestamp': intTs,
            'datetime': self.iso8601(intTs),
            'symbol': symbol,
            'type': None,
            'side': side,
            'takerOrMaker': takerOrMaker,
            'price': price,
            'amount': amount,
            'cost': cost,
            'fee': fee,
            'info': trade,
        }, market)

    async def fetch_balance(self, params={}) -> Balances:
        """
        query for balance and get the amount of funds available for trading or funds locked in orders
        :see: https://bit.team/trade/api/documentation#/PRIVATE/getTradeApiCcxtBalance
        :param dict [params]: extra parameters specific to the betteam api endpoint
        :returns dict: a `balance structure <https://github.com/ccxt/ccxt/wiki/Manual#balance-structure>`
        """
        await self.load_markets()
        response = await self.privateGetTradeApiCcxtBalance(params)
        return self.parse_balance(response)

    def parse_balance(self, response) -> Balances:
        #
        #     {
        #         "ok": True,
        #         "result": {
        #             "free": {
        #                 "USDT": "0",
        #                 "DEL": "0",
        #                 "BTC": "0",
        #                 ...
        #             },
        #                 "used": {
        #                 "USDT": "0",
        #                 "DEL": "0",
        #                 "BTC": "0",
        #                 ...
        #             },
        #             "total": {
        #                 "USDT": "0",
        #                 "DEL": "0",
        #                 "BTC": "0",
        #                 ...
        #             },
        #             "USDT": {
        #                 "free": "0",
        #                 "used": "0",
        #                 "total": "0",
        #             },
        #             "DEL": {
        #                 "free": "0",
        #                 "used": "0",
        #                 "total": "0",
        #             },
        #             "BTC": {
        #                 "free": "0",
        #                 "used": "0",
        #                 "total": "0",
        #             }
        #             ...
        #         }
        #     }
        #
        timestamp = self.milliseconds()
        balance = {
            'info': response,
            'timestamp': timestamp,
            'datetime': self.iso8601(timestamp),
        }
        result = self.safe_value(response, 'result', {})
        balanceByCurrencies = self.omit(result, ['free', 'used', 'total'])
        rawCurrencyIds = list(balanceByCurrencies.keys())
        for i in range(0, len(rawCurrencyIds)):
            rawCurrencyId = rawCurrencyIds[i]
            currencyBalance = self.safe_value(result, rawCurrencyId)
            free = self.safe_string(currencyBalance, 'free')
            used = self.safe_string(currencyBalance, 'used')
            total = self.safe_string(currencyBalance, 'total')
            currencyCode = self.safe_currency_code(rawCurrencyId.lower())
            balance[currencyCode] = {
                'free': free,
                'used': used,
                'total': total,
            }
        return self.safe_balance(balance)

    async def fetch_deposits_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
        """
        fetch history of deposits and withdrawals from external wallets and between CoinList Pro trading account and CoinList wallet
        :see: https://bit.team/trade/api/documentation#/PRIVATE/getTradeApiTransactionsofuser
        :param str [code]: unified currency code for the currency of the deposit/withdrawals
        :param int [since]: timestamp in ms of the earliest deposit/withdrawal
        :param int [limit]: max number of deposit/withdrawals to return(default 10)
        :param dict [params]: extra parameters specific to the bitteam api endpoint
        :returns dict: a list of `transaction structure <https://github.com/ccxt/ccxt/wiki/Manual#transaction-structure>`
        """
        await self.load_markets()
        currency = None
        request = {}
        if code is not None:
            currency = self.currency(code)
            request['currency'] = currency['numericId']
        if limit is not None:
            request['limit'] = limit
        response = await self.privateGetTradeApiTransactionsOfUser(self.extend(request, params))
        #
        #     {
        #         "ok": True,
        #         "result": {
        #             "count": 2,
        #             "transactions": [
        #                 {
        #                     "id": 1329686,
        #                     "orderId": "2f060ad5-30f7-4f2b-ac5f-1bb8f5fd34dc",
        #                     "transactionCoreId": "561863",
        #                     "userId": 21639,
        #                     "recipient": "0x9050dfA063D1bE7cA711c750b18D51fDD13e90Ee",
        #                     "sender": "0x6894a93B6fea044584649278621723cac51443Cd",
        #                     "symbolId": 2,
        #                     "CommissionId": 17571,
        #                     "amount": "44000000000000000",
        #                     "params": {},
        #                     "reason": null,
        #                     "timestamp": 1700715341743,
        #                     "status": "approving",
        #                     "statusDescription": null,
        #                     "type": "withdraw",
        #                     "message": null,
        #                     "blockChain": "",
        #                     "before": null,
        #                     "after": null,
        #                     "currency": {
        #                         "symbol": "eth",
        #                         "decimals": 18,
        #                         "blockChain": "Ethereum",
        #                         "links": [
        #                             {
        #                                 "tx": "https://etherscan.io/tx/",
        #                                 "address": "https://etherscan.io/address/",
        #                                 "blockChain": "Ethereum"
        #                             }
        #                         ]
        #                     }
        #                 },
        #                 {
        #                     "id": 1329229,
        #                     "orderId": null,
        #                     "transactionCoreId": "561418",
        #                     "userId": 21639,
        #                     "recipient": "0x7d6a797f2406e06b2f9b41d067df324affa315dd",
        #                     "sender": null,
        #                     "symbolId": 3,
        #                     "CommissionId": null,
        #                     "amount": "100000000",
        #                     "params": {
        #                         "tx_id": "0x2253823c828d838acd983fe6a348fb0e034efe3874b081871d8b80da76ec758b"
        #                     },
        #                     "reason": null,
        #                     "timestamp": 1700594180417,
        #                     "status": "success",
        #                     "statusDescription": null,
        #                     "type": "deposit",
        #                     "message": null,
        #                     "blockChain": "Ethereum",
        #                     "before": 0,
        #                     "after": 100000000,
        #                     "currency": {
        #                         "symbol": "usdt",
        #                         "decimals": 6,
        #                         "blockChain": "",
        #                         "links": [
        #                             {
        #                                 "tx": "https://etherscan.io/tx/",
        #                                 "address": "https://etherscan.io/address/",
        #                                 "blockChain": "Ethereum"
        #                             },
        #                             {
        #                                 "tx": "https://tronscan.org/#/transaction/",
        #                                 "address": "https://tronscan.org/#/address/",
        #                                 "blockChain": "Tron"
        #                             },
        #                             {
        #                                 "tx": "https://bscscan.com/tx/",
        #                                 "address": "https://bscscan.com/address/",
        #                                 "blockChain": "Binance"
        #                             }
        #                         ]
        #                     }
        #                 }
        #             ]
        #         }
        #     }
        #
        result = self.safe_value(response, 'result', {})
        transactions = self.safe_list(result, 'transactions', [])
        return self.parse_transactions(transactions, currency, since, limit)

    def parse_transaction(self, transaction, currency: Currency = None) -> Transaction:
        #
        #     {
        #         "id": 1329229,
        #         "orderId": null,
        #         "transactionCoreId": "561418",
        #         "userId": 21639,
        #         "recipient": "0x7d6a797f2406e06b2f9b41d067df324affa315dd",
        #         "sender": null,
        #         "symbolId": 3,
        #         "CommissionId": null,
        #         "amount": "100000000",
        #         "params": {
        #             "tx_id": "0x2253823c828d838acd983fe6a348fb0e034efe3874b081871d8b80da76ec758b"
        #         },
        #         "reason": null,
        #         "timestamp": 1700594180417,
        #         "status": "success",
        #         "statusDescription": null,
        #         "type": "deposit",
        #         "message": null,
        #         "blockChain": "Ethereum",
        #         "before": 0,
        #         "after": 100000000,
        #         "currency": {
        #             "symbol": "usdt",
        #             "decimals": 6,
        #             "blockChain": "",
        #             "links": [
        #                 {
        #                     "tx": "https://etherscan.io/tx/",
        #                     "address": "https://etherscan.io/address/",
        #                     "blockChain": "Ethereum"
        #                 },
        #                 {
        #                     "tx": "https://tronscan.org/#/transaction/",
        #                     "address": "https://tronscan.org/#/address/",
        #                     "blockChain": "Tron"
        #                 },
        #                 {
        #                     "tx": "https://bscscan.com/tx/",
        #                     "address": "https://bscscan.com/address/",
        #                     "blockChain": "Binance"
        #                 }
        #             ]
        #         }
        #     }
        #
        currencyObject = self.safe_value(transaction, 'currency')
        currencyId = self.safe_string(currencyObject, 'symbol')
        code = self.safe_currency_code(currencyId, currency)
        id = self.safe_string(transaction, 'id')
        params = self.safe_value(transaction, 'params')
        txid = self.safe_string(params, 'tx_id')
        timestamp = self.safe_integer(transaction, 'timestamp')
        networkId = self.safe_string(transaction, 'blockChain')
        if networkId is None:
            links = self.safe_value(currencyObject, 'links', [])
            blockChain = self.safe_value(links, 0, {})
            networkId = self.safe_string(blockChain, 'blockChain')
        addressFrom = self.safe_string(transaction, 'sender')
        addressTo = self.safe_string(transaction, 'recipient')
        tag = self.safe_string(transaction, 'message')
        type = self.parse_transaction_type(self.safe_string(transaction, 'type'))
        amount = self.parse_value_to_pricision(transaction, 'amount', currencyObject, 'decimals')
        status = self.parse_transaction_status(self.safe_value(transaction, 'status'))
        return {
            'info': transaction,
            'id': id,
            'txid': txid,
            'timestamp': timestamp,
            'datetime': self.iso8601(timestamp),
            'network': self.network_id_to_code(networkId),
            'addressFrom': addressFrom,
            'address': None,
            'addressTo': addressTo,
            'tagFrom': None,
            'tag': tag,
            'tagTo': None,
            'type': type,
            'amount': self.parse_number(amount),
            'currency': code,
            'status': status,
            'updated': None,
            'fee': None,
            'comment': self.safe_string(transaction, 'description'),
            'internal': False,
        }

    def parse_transaction_type(self, type):
        types = {
            'deposit': 'deposit',
            'withdraw': 'withdrawal',
        }
        return self.safe_string(types, type, type)

    def parse_transaction_status(self, status):
        statuses = {
            'approving': 'pending',
            'success': 'ok',
        }
        return self.safe_string(statuses, status, status)

    def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
        request = self.omit(params, self.extract_params(path))
        endpoint = '/' + self.implode_params(path, params)
        url = self.urls['api'][api] + endpoint
        query = self.urlencode(request)
        if api == 'private':
            self.check_required_credentials()
            if method == 'POST':
                body = self.json(request)
            elif len(query) != 0:
                url += '?' + query
            auth = self.apiKey + ':' + self.secret
            auth64 = self.string_to_base64(auth)
            signature = 'Basic ' + auth64
            headers = {
                'Authorization': signature,
                'Content-Type': 'application/json',
            }
        elif len(query) != 0:
            url += '?' + query
        return {'url': url, 'method': method, 'body': body, 'headers': headers}

    def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
        if response is None:
            return None
        if code != 200:
            if code == 404:
                if (url.find('/ccxt/order/') >= 0) and (method == 'GET'):
                    parts = url.split('/order/')
                    orderId = self.safe_string(parts, 1)
                    raise OrderNotFound(self.id + ' order ' + orderId + ' not found')
                if url.find('/cmc/orderbook/') >= 0:
                    parts = url.split('/cmc/orderbook/')
                    symbolId = self.safe_string(parts, 1)
                    raise BadSymbol(self.id + ' symbolId ' + symbolId + ' not found')
            feedback = self.id + ' ' + body
            message = self.safe_string(response, 'message')
            responseCode = self.safe_string(response, 'code')
            self.throw_broadly_matched_exception(self.exceptions['broad'], message, feedback)
            self.throw_exactly_matched_exception(self.exceptions['exact'], responseCode, feedback)
            raise ExchangeError(feedback)
        return None
