ccxt
Version:
1,092 lines (1,090 loc) • 244 kB
JavaScript
'use strict';
var bitmart$1 = require('./abstract/bitmart.js');
var errors = require('./base/errors.js');
var Precise = require('./base/Precise.js');
var number = require('./base/functions/number.js');
var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
// ----------------------------------------------------------------------------
// ---------------------------------------------------------------------------
/**
* @class bitmart
* @augments Exchange
*/
class bitmart extends bitmart$1 {
describe() {
return this.deepExtend(super.describe(), {
'id': 'bitmart',
'name': 'BitMart',
'countries': ['US', 'CN', 'HK', 'KR'],
// 150 per 5 seconds = 30 per second
// rateLimit = 1000ms / 30 ~= 33.334
'rateLimit': 33.34,
'version': 'v2',
'certified': true,
'pro': true,
'has': {
'CORS': undefined,
'spot': true,
'margin': true,
'swap': true,
'future': false,
'option': false,
'borrowCrossMargin': false,
'borrowIsolatedMargin': true,
'cancelAllOrders': true,
'cancelOrder': true,
'cancelOrders': true,
'createMarketBuyOrderWithCost': true,
'createMarketOrderWithCost': false,
'createMarketSellOrderWithCost': false,
'createOrder': true,
'createOrders': true,
'createPostOnlyOrder': true,
'createStopLimitOrder': false,
'createStopMarketOrder': false,
'createStopOrder': false,
'createTrailingPercentOrder': true,
'fetchBalance': true,
'fetchBorrowInterest': true,
'fetchBorrowRateHistories': false,
'fetchBorrowRateHistory': false,
'fetchCanceledOrders': true,
'fetchClosedOrders': true,
'fetchCrossBorrowRate': false,
'fetchCrossBorrowRates': false,
'fetchCurrencies': true,
'fetchDeposit': true,
'fetchDepositAddress': true,
'fetchDepositAddresses': false,
'fetchDepositAddressesByNetwork': false,
'fetchDeposits': true,
'fetchDepositWithdrawFee': true,
'fetchDepositWithdrawFees': false,
'fetchFundingHistory': true,
'fetchFundingRate': true,
'fetchFundingRateHistory': false,
'fetchFundingRates': false,
'fetchIsolatedBorrowRate': true,
'fetchIsolatedBorrowRates': true,
'fetchLedger': true,
'fetchLiquidations': false,
'fetchMarginMode': false,
'fetchMarkets': true,
'fetchMyLiquidations': true,
'fetchMyTrades': true,
'fetchOHLCV': true,
'fetchOpenInterest': true,
'fetchOpenInterestHistory': false,
'fetchOpenOrders': true,
'fetchOrder': true,
'fetchOrderBook': true,
'fetchOrders': false,
'fetchOrderTrades': true,
'fetchPosition': true,
'fetchPositionMode': false,
'fetchPositions': true,
'fetchStatus': true,
'fetchTicker': true,
'fetchTickers': true,
'fetchTime': true,
'fetchTrades': true,
'fetchTradingFee': true,
'fetchTradingFees': false,
'fetchTransactionFee': true,
'fetchTransactionFees': false,
'fetchTransfer': false,
'fetchTransfers': true,
'fetchWithdrawAddressesByNetwork': false,
'fetchWithdrawal': true,
'fetchWithdrawals': true,
'reduceMargin': false,
'repayCrossMargin': false,
'repayIsolatedMargin': true,
'setLeverage': true,
'setMarginMode': false,
'transfer': true,
'withdraw': true,
},
'hostname': 'bitmart.com',
'urls': {
'logo': 'https://github.com/user-attachments/assets/0623e9c4-f50e-48c9-82bd-65c3908c3a14',
'api': {
'spot': 'https://api-cloud.{hostname}',
'swap': 'https://api-cloud-v2.{hostname}', // bitmart.info for Hong Kong users
},
'www': 'https://www.bitmart.com/',
'doc': 'https://developer-pro.bitmart.com/',
'referral': {
'url': 'http://www.bitmart.com/?r=rQCFLh',
'discount': 0.3,
},
'fees': 'https://www.bitmart.com/fee/en',
},
'requiredCredentials': {
'apiKey': true,
'secret': true,
'uid': true,
},
'api': {
'public': {
'get': {
'system/time': 3,
'system/service': 3,
// spot markets
'spot/v1/currencies': 7.5,
'spot/v1/symbols': 7.5,
'spot/v1/symbols/details': 5,
'spot/quotation/v3/tickers': 6,
'spot/quotation/v3/ticker': 4,
'spot/quotation/v3/lite-klines': 5,
'spot/quotation/v3/klines': 7,
'spot/quotation/v3/books': 4,
'spot/quotation/v3/trades': 4,
'spot/v1/ticker': 5,
'spot/v2/ticker': 30,
'spot/v1/ticker_detail': 5,
'spot/v1/steps': 30,
'spot/v1/symbols/kline': 6,
'spot/v1/symbols/book': 5,
'spot/v1/symbols/trades': 5,
// contract markets
'contract/v1/tickers': 15,
'contract/public/details': 5,
'contract/public/depth': 5,
'contract/public/open-interest': 30,
'contract/public/funding-rate': 30,
'contract/public/funding-rate-history': 30,
'contract/public/kline': 6,
'account/v1/currencies': 30,
},
},
'private': {
'get': {
// sub-account
'account/sub-account/v1/transfer-list': 7.5,
'account/sub-account/v1/transfer-history': 7.5,
'account/sub-account/main/v1/wallet': 5,
'account/sub-account/main/v1/subaccount-list': 7.5,
'account/contract/sub-account/main/v1/wallet': 5,
'account/contract/sub-account/main/v1/transfer-list': 7.5,
'account/contract/sub-account/v1/transfer-history': 7.5,
// account
'account/v1/wallet': 5,
'account/v1/currencies': 30,
'spot/v1/wallet': 5,
'account/v1/deposit/address': 30,
'account/v1/withdraw/charge': 32,
'account/v2/deposit-withdraw/history': 7.5,
'account/v1/deposit-withdraw/detail': 7.5,
// order
'spot/v1/order_detail': 1,
'spot/v2/orders': 5,
'spot/v1/trades': 5,
// newer order endpoint
'spot/v2/trades': 4,
'spot/v3/orders': 5,
'spot/v2/order_detail': 1,
// margin
'spot/v1/margin/isolated/borrow_record': 1,
'spot/v1/margin/isolated/repay_record': 1,
'spot/v1/margin/isolated/pairs': 30,
'spot/v1/margin/isolated/account': 5,
'spot/v1/trade_fee': 30,
'spot/v1/user_fee': 30,
// broker
'spot/v1/broker/rebate': 1,
// contract
'contract/private/assets-detail': 5,
'contract/private/order': 1.2,
'contract/private/order-history': 10,
'contract/private/position': 10,
'contract/private/get-open-orders': 1.2,
'contract/private/current-plan-order': 1.2,
'contract/private/trades': 10,
'contract/private/position-risk': 10,
'contract/private/affilate/rebate-list': 10,
'contract/private/affilate/trade-list': 10,
'contract/private/transaction-history': 10,
},
'post': {
// sub-account endpoints
'account/sub-account/main/v1/sub-to-main': 30,
'account/sub-account/sub/v1/sub-to-main': 30,
'account/sub-account/main/v1/main-to-sub': 30,
'account/sub-account/sub/v1/sub-to-sub': 30,
'account/sub-account/main/v1/sub-to-sub': 30,
'account/contract/sub-account/main/v1/sub-to-main': 7.5,
'account/contract/sub-account/main/v1/main-to-sub': 7.5,
'account/contract/sub-account/sub/v1/sub-to-main': 7.5,
// account
'account/v1/withdraw/apply': 7.5,
// transaction and trading
'spot/v1/submit_order': 1,
'spot/v1/batch_orders': 1,
'spot/v2/cancel_order': 1,
'spot/v1/cancel_orders': 15,
'spot/v4/query/order': 1,
'spot/v4/query/client-order': 1,
'spot/v4/query/open-orders': 5,
'spot/v4/query/history-orders': 5,
'spot/v4/query/trades': 5,
'spot/v4/query/order-trades': 5,
'spot/v4/cancel_orders': 3,
'spot/v4/cancel_all': 90,
'spot/v4/batch_orders': 3,
// newer endpoint
'spot/v3/cancel_order': 1,
'spot/v2/batch_orders': 1,
'spot/v2/submit_order': 1,
// margin
'spot/v1/margin/submit_order': 1,
'spot/v1/margin/isolated/borrow': 30,
'spot/v1/margin/isolated/repay': 30,
'spot/v1/margin/isolated/transfer': 30,
// contract
'account/v1/transfer-contract-list': 60,
'account/v1/transfer-contract': 60,
'contract/private/submit-order': 2.5,
'contract/private/cancel-order': 1.5,
'contract/private/cancel-orders': 30,
'contract/private/submit-plan-order': 2.5,
'contract/private/cancel-plan-order': 1.5,
'contract/private/submit-leverage': 2.5,
'contract/private/submit-tp-sl-order': 2.5,
'contract/private/modify-plan-order': 2.5,
'contract/private/modify-preset-plan-order': 2.5,
'contract/private/modify-tp-sl-order': 2.5,
},
},
},
'timeframes': {
'1m': 1,
'3m': 3,
'5m': 5,
'15m': 15,
'30m': 30,
'45m': 45,
'1h': 60,
'2h': 120,
'3h': 180,
'4h': 240,
'1d': 1440,
'1w': 10080,
'1M': 43200,
},
'fees': {
'trading': {
'tierBased': true,
'percentage': true,
'taker': this.parseNumber('0.0040'),
'maker': this.parseNumber('0.0035'),
'tiers': {
'taker': [
[this.parseNumber('0'), this.parseNumber('0.0020')],
[this.parseNumber('10'), this.parseNumber('0.18')],
[this.parseNumber('50'), this.parseNumber('0.0016')],
[this.parseNumber('250'), this.parseNumber('0.0014')],
[this.parseNumber('1000'), this.parseNumber('0.0012')],
[this.parseNumber('5000'), this.parseNumber('0.0010')],
[this.parseNumber('25000'), this.parseNumber('0.0008')],
[this.parseNumber('50000'), this.parseNumber('0.0006')],
],
'maker': [
[this.parseNumber('0'), this.parseNumber('0.001')],
[this.parseNumber('10'), this.parseNumber('0.0009')],
[this.parseNumber('50'), this.parseNumber('0.0008')],
[this.parseNumber('250'), this.parseNumber('0.0007')],
[this.parseNumber('1000'), this.parseNumber('0.0006')],
[this.parseNumber('5000'), this.parseNumber('0.0005')],
[this.parseNumber('25000'), this.parseNumber('0.0004')],
[this.parseNumber('50000'), this.parseNumber('0.0003')],
],
},
},
},
'precisionMode': number.TICK_SIZE,
'exceptions': {
'exact': {
// general errors
'30000': errors.ExchangeError,
'30001': errors.AuthenticationError,
'30002': errors.AuthenticationError,
'30003': errors.AccountSuspended,
'30004': errors.AuthenticationError,
'30005': errors.AuthenticationError,
'30006': errors.AuthenticationError,
'30007': errors.AuthenticationError,
'30008': errors.AuthenticationError,
'30010': errors.PermissionDenied,
'30011': errors.AuthenticationError,
'30012': errors.AuthenticationError,
'30013': errors.RateLimitExceeded,
'30014': errors.ExchangeNotAvailable,
'30016': errors.OnMaintenance,
'30017': errors.RateLimitExceeded,
'30018': errors.BadRequest,
'30019': errors.PermissionDenied,
// funding account & sub account errors
'60000': errors.BadRequest,
'60001': errors.BadRequest,
'60002': errors.BadRequest,
'60003': errors.ExchangeError,
'60004': errors.ExchangeError,
'60005': errors.ExchangeError,
'60006': errors.ExchangeError,
'60007': errors.InvalidAddress,
'60008': errors.InsufficientFunds,
'60009': errors.ExchangeError,
'60010': errors.ExchangeError,
'60011': errors.InvalidAddress,
'60012': errors.ExchangeError,
'60020': errors.PermissionDenied,
'60021': errors.PermissionDenied,
'60022': errors.PermissionDenied,
'60026': errors.PermissionDenied,
'60027': errors.PermissionDenied,
'60028': errors.AccountSuspended,
'60029': errors.AccountSuspended,
'60030': errors.BadRequest,
'60031': errors.BadRequest,
'60050': errors.ExchangeError,
'60051': errors.ExchangeError,
'61001': errors.InsufficientFunds,
'61003': errors.BadRequest,
'61004': errors.BadRequest,
'61005': errors.BadRequest,
'61006': errors.NotSupported,
'61007': errors.ExchangeError,
'61008': errors.ExchangeError,
// spot public errors
'70000': errors.ExchangeError,
'70001': errors.BadRequest,
'70002': errors.BadSymbol,
'70003': errors.NetworkError,
'71001': errors.BadRequest,
'71002': errors.BadRequest,
'71003': errors.BadRequest,
'71004': errors.BadRequest,
'71005': errors.BadRequest,
// spot & margin errors
'50000': errors.BadRequest,
'50001': errors.BadSymbol,
'50002': errors.BadRequest,
'50003': errors.BadRequest,
'50004': errors.BadRequest,
'50005': errors.OrderNotFound,
'50006': errors.InvalidOrder,
'50007': errors.InvalidOrder,
'50008': errors.InvalidOrder,
'50009': errors.InvalidOrder,
'50010': errors.InvalidOrder,
'50011': errors.InvalidOrder,
'50012': errors.InvalidOrder,
'50013': errors.InvalidOrder,
'50014': errors.BadRequest,
'50015': errors.BadRequest,
'50016': errors.BadRequest,
'50017': errors.BadRequest,
'50018': errors.BadRequest,
'50019': errors.ExchangeError,
'50020': errors.InsufficientFunds,
'50021': errors.BadRequest,
'50022': errors.ExchangeNotAvailable,
'50023': errors.BadSymbol,
'50024': errors.BadRequest,
'50025': errors.BadRequest,
'50026': errors.BadRequest,
'50027': errors.BadRequest,
'50028': errors.BadRequest,
'50029': errors.InvalidOrder,
'50030': errors.OrderNotFound,
'50031': errors.OrderNotFound,
'50032': errors.OrderNotFound,
'50033': errors.InvalidOrder,
// below Error codes used interchangeably for both failed postOnly and IOC orders depending on market price and order side
'50034': errors.InvalidOrder,
'50035': errors.InvalidOrder,
'50036': errors.ExchangeError,
'50037': errors.BadRequest,
'50038': errors.BadRequest,
'50039': errors.BadRequest,
'50040': errors.BadSymbol,
'50041': errors.ExchangeError,
'50042': errors.BadRequest,
'51000': errors.BadSymbol,
'51001': errors.ExchangeError,
'51002': errors.ExchangeError,
'51003': errors.ExchangeError,
'51004': errors.InsufficientFunds,
'51005': errors.InvalidOrder,
'51006': errors.InvalidOrder,
'51007': errors.BadRequest,
'51008': errors.ExchangeError,
'51009': errors.InvalidOrder,
'51010': errors.InvalidOrder,
'51011': errors.InvalidOrder,
'51012': errors.InvalidOrder,
'51013': errors.InvalidOrder,
'51014': errors.InvalidOrder,
'51015': errors.InvalidOrder,
'52000': errors.BadRequest,
'52001': errors.BadRequest,
'52002': errors.BadRequest,
'52003': errors.BadRequest,
'52004': errors.BadRequest,
'53000': errors.AccountSuspended,
'53001': errors.AccountSuspended,
'53002': errors.PermissionDenied,
'53003': errors.PermissionDenied,
'53005': errors.PermissionDenied,
'53006': errors.PermissionDenied,
'53007': errors.PermissionDenied,
'53008': errors.PermissionDenied,
'53009': errors.PermissionDenied,
'53010': errors.PermissionDenied,
'57001': errors.BadRequest,
'58001': errors.BadRequest,
'59001': errors.ExchangeError,
'59002': errors.ExchangeError,
'59003': errors.ExchangeError,
'59004': errors.ExchangeError,
'59005': errors.PermissionDenied,
'59006': errors.ExchangeError,
'59007': errors.ExchangeError,
'59008': errors.ExchangeError,
'59009': errors.ExchangeError,
'59010': errors.InsufficientFunds,
'59011': errors.ExchangeError,
// contract errors
'40001': errors.ExchangeError,
'40002': errors.ExchangeError,
'40003': errors.ExchangeError,
'40004': errors.ExchangeError,
'40005': errors.ExchangeError,
'40006': errors.PermissionDenied,
'40007': errors.BadRequest,
'40008': errors.InvalidNonce,
'40009': errors.BadRequest,
'40010': errors.BadRequest,
'40011': errors.BadRequest,
'40012': errors.ExchangeError,
'40013': errors.ExchangeError,
'40014': errors.BadSymbol,
'40015': errors.BadSymbol,
'40016': errors.InvalidOrder,
'40017': errors.InvalidOrder,
'40018': errors.InvalidOrder,
'40019': errors.ExchangeError,
'40020': errors.InvalidOrder,
'40021': errors.ExchangeError,
'40022': errors.ExchangeError,
'40023': errors.ExchangeError,
'40024': errors.ExchangeError,
'40025': errors.ExchangeError,
'40026': errors.ExchangeError,
'40027': errors.InsufficientFunds,
'40028': errors.PermissionDenied,
'40029': errors.InvalidOrder,
'40030': errors.InvalidOrder,
'40031': errors.InvalidOrder,
'40032': errors.InvalidOrder,
'40033': errors.InvalidOrder,
'40034': errors.BadSymbol,
'40035': errors.OrderNotFound,
'40036': errors.InvalidOrder,
'40037': errors.OrderNotFound,
'40038': errors.BadRequest,
'40039': errors.BadRequest,
'40040': errors.InvalidOrder,
'40041': errors.InvalidOrder,
'40042': errors.InvalidOrder,
'40043': errors.InvalidOrder,
'40044': errors.InvalidOrder,
'40045': errors.InvalidOrder,
'40046': errors.PermissionDenied,
'40047': errors.PermissionDenied,
'40048': errors.InvalidOrder,
'40049': errors.InvalidOrder,
'40050': errors.InvalidOrder, // 403, Client OrderId duplicated with existing orders
},
'broad': {
'You contract account available balance not enough': errors.InsufficientFunds,
'you contract account available balance not enough': errors.InsufficientFunds,
},
},
'commonCurrencies': {
'$GM': 'GOLDMINER',
'$HERO': 'Step Hero',
'$PAC': 'PAC',
'BP': 'BEYOND',
'GDT': 'Gorilla Diamond',
'GLD': 'Goldario',
'MVP': 'MVP Coin',
'TRU': 'Truebit', // conflict with TrueFi
},
'options': {
'defaultNetworks': {
'USDT': 'TRC20',
'BTC': 'BTC',
'ETH': 'ERC20',
},
'timeDifference': 0,
'adjustForTimeDifference': false,
'networks': {
'ERC20': 'ERC20',
'SOL': 'SOL',
'BTC': 'BTC',
'TRC20': 'TRC20',
// todo: should be TRX after unification
// 'TRC20': [ 'TRC20', 'trc20', 'TRON' ], // todo: after unification i.e. TRON is returned from fetchDepositAddress
// 'ERC20': [ 'ERC20', 'ERC-20', 'ERC20 ' ], // todo: after unification
'OMNI': 'OMNI',
'XLM': 'XLM',
'EOS': 'EOS',
'NEO': 'NEO',
'BTM': 'BTM',
'BCH': 'BCH',
'LTC': 'LTC',
'BSV': 'BSV',
'XRP': 'XRP',
// 'VECHAIN': [ 'VET', 'Vechain' ], // todo: after unification
'PLEX': 'PLEX',
'XCH': 'XCH',
// 'AVALANCHE_C': [ 'AVAX', 'AVAX-C' ], // todo: after unification
'NEAR': 'NEAR',
'FIO': 'FIO',
'SCRT': 'SCRT',
'IOTX': 'IOTX',
'ALGO': 'ALGO',
'ATOM': 'ATOM',
'DOT': 'DOT',
'ADA': 'ADA',
'DOGE': 'DOGE',
'XYM': 'XYM',
'GLMR': 'GLMR',
'MOVR': 'MOVR',
'ZIL': 'ZIL',
'INJ': 'INJ',
'KSM': 'KSM',
'ZEC': 'ZEC',
'NAS': 'NAS',
'POLYGON': 'MATIC',
'HRC20': 'HECO',
'XDC': 'XDC',
'ONE': 'ONE',
'LAT': 'LAT',
'CSPR': 'Casper',
'ICP': 'Computer',
'XTZ': 'XTZ',
'MINA': 'MINA',
'BEP20': 'BSC_BNB',
'THETA': 'THETA',
'AKT': 'AKT',
'AR': 'AR',
'CELO': 'CELO',
'FIL': 'FIL',
'NULS': 'NULS',
'ETC': 'ETC',
'DASH': 'DASH',
'DGB': 'DGB',
'BEP2': 'BEP2',
'GRIN': 'GRIN',
'WAVES': 'WAVES',
'ABBC': 'ABBC',
'ACA': 'ACA',
'QTUM': 'QTUM',
'PAC': 'PAC',
// 'TERRACLASSIC': 'LUNC', // TBD
// 'TERRA': 'Terra', // TBD
// 'HEDERA': [ 'HBAR', 'Hedera', 'Hedera Mainnet' ], // todo: after unification
'TLOS': 'TLOS',
'KARDIA': 'KardiaChain',
'FUSE': 'FUSE',
'TRC10': 'TRC10',
'FIRO': 'FIRO',
'FTM': 'Fantom',
// 'KLAYTN': [ 'klaytn', 'KLAY', 'Klaytn' ], // todo: after unification
// 'ELROND': [ 'EGLD', 'Elrond eGold', 'MultiversX' ], // todo: after unification
'EVER': 'EVER',
'KAVA': 'KAVA',
'HYDRA': 'HYDRA',
'PLCU': 'PLCU',
'BRISE': 'BRISE',
// 'CRC20': [ 'CRO', 'CRO_Chain' ], // todo: after unification
// 'CONFLUX': [ 'CFX eSpace', 'CFX' ], // todo: after unification
'OPTIMISM': 'OPTIMISM',
'REEF': 'REEF',
'SYS': 'SYS',
'VITE': 'VITE',
'STX': 'STX',
'SXP': 'SXP',
'BITCI': 'BITCI',
// 'ARBITRUM': [ 'ARBI', 'Arbitrum' ], // todo: after unification
'XRD': 'XRD',
'ASTR': 'ASTAR',
'ZEN': 'HORIZEN',
'LTO': 'LTO',
'ETHW': 'ETHW',
'ETHF': 'ETHF',
'IOST': 'IOST',
// 'CHILIZ': [ 'CHZ', 'CHILIZ' ], // todo: after unification
'APT': 'APT',
// 'FLOW': [ 'FLOW', 'Flow' ], // todo: after unification
'ONT': 'ONT',
'EVMOS': 'EVMOS',
'XMR': 'XMR',
'OASYS': 'OAS',
'OSMO': 'OSMO',
'OMAX': 'OMAX Chain',
'DESO': 'DESO',
'BFIC': 'BFIC',
'OHO': 'OHO',
'CS': 'CS',
'CHEQ': 'CHEQ',
'NODL': 'NODL',
'NEM': 'XEM',
'FRA': 'FRA',
'ERGO': 'ERG',
// todo: below will be uncommented after unification
// 'BITCOINHD': 'BHD',
// 'CRUST': 'CRU',
// 'MINTME': 'MINTME',
// 'ZENITH': 'ZENITH',
// 'ZENIQ': 'ZENIQ', // "ZEN-20" is different
// 'BITCOINVAULT': 'BTCV',
// 'MOBILECOIN': 'MBX',
// 'PINETWORK': 'PI',
// 'PI': 'PI',
// 'REBUS': 'REBUS',
// 'XODEX': 'XODEX',
// 'ULTRONGLOW': 'UTG'
// 'QIBLOCKCHAIN': 'QIE',
// 'XIDEN': 'XDEN',
// 'PHAETON': 'PHAE',
// 'REDLIGHT': 'REDLC',
// 'VERITISE': 'VTS',
// 'VERIBLOCK': 'VBK',
// 'RAMESTTA': 'RAMA',
// 'BITICA': 'BDCC',
// 'CROWNSOVEREIGN': 'CSOV',
// 'DRAC': 'DRC20',
// 'QCHAIN': 'QDT',
// 'KINGARU': 'KRU',
// 'PROOFOFMEMES': 'POM',
// 'CUBE': 'CUBE',
// 'CADUCEUS': 'CMP',
// 'VEIL': 'VEIL',
// 'ENERGYWEB': 'EWT',
// 'CYPHERIUM': 'CPH',
// 'LBRY': 'LBC',
// 'ETHERCOIN': 'ETE',
// undetermined chains:
// LEX (for LexThum), TAYCAN (for TRICE), SFL (probably TAYCAN), OMNIA (for APEX), NAC (for NAC), KAG (Kinesis), CEM (crypto emergency), XVM (for Venidium), NEVM (for NEVM), IGT20 (for IGNITE), FILM (FILMCredits), CC (CloudCoin), MERGE (MERGE), LTNM (Bitcoin latinum), PLUGCN ( PlugChain), DINGO (dingo), LED (LEDGIS), AVAT (AVAT), VSOL (Vsolidus), EPIC (EPIC cash), NFC (netflowcoin), mrx (Metrix Coin), Idena (idena network), PKT (PKT Cash), BondDex (BondDex), XBN (XBN), KALAM (Kalamint), REV (RChain), KRC20 (MyDeFiPet), ARC20 (Hurricane Token), GMD (Coop network), BERS (Berith), ZEBI (Zebi), BRC (Baer Chain), DAPS (DAPS Coin), APL (Gold Secured Currency), NDAU (NDAU), WICC (WICC), UPG (Unipay God), TSL (TreasureSL), MXW (Maxonrow), CLC (Cifculation), SMH (SMH Coin), XIN (CPCoin), RDD (ReddCoin), OK (Okcash), KAR (KAR), CCX (ConcealNetwork),
},
'networksById': {
'ETH': 'ERC20',
'Ethereum': 'ERC20',
'USDT': 'OMNI',
'Bitcoin': 'BTC',
},
'defaultType': 'spot',
'fetchBalance': {
'type': 'spot', // 'spot', 'swap', 'account'
},
'accountsByType': {
'spot': 'spot',
'swap': 'swap',
},
'createMarketBuyOrderRequiresPrice': true,
'brokerId': 'CCXTxBitmart000',
},
'features': {
'default': {
'sandbox': false,
'createOrder': {
'marginMode': true,
'triggerPrice': false,
'triggerPriceType': undefined,
'triggerDirection': false,
'stopLossPrice': false,
'takeProfitPrice': false,
'attachedStopLossTakeProfit': undefined,
'timeInForce': {
'IOC': true,
'FOK': false,
'PO': true,
'GTD': false,
},
'hedged': false,
'trailing': false,
'marketBuyRequiresPrice': false,
'marketBuyByCost': true,
'leverage': true,
'selfTradePrevention': false,
'iceberg': false,
},
'createOrders': {
'max': 10,
},
'fetchMyTrades': {
'marginMode': true,
'limit': 200,
'daysBack': undefined,
'untilDays': 99999,
'symbolRequired': false,
},
'fetchOrder': {
'marginMode': false,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOpenOrders': {
'marginMode': true,
'limit': 200,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOrders': undefined,
'fetchClosedOrders': {
'marginMode': true,
'limit': 200,
'daysBack': undefined,
'daysBackCanceled': undefined,
'untilDays': undefined,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOHLCV': {
'limit': 1000, // variable timespans for recent endpoint, 200 for historical
},
},
'forDerivatives': {
'extends': 'default',
'createOrder': {
'marginMode': true,
'triggerPrice': true,
'triggerPriceType': {
'last': true,
'mark': true,
'index': false,
},
'triggerDirection': true,
'stopLossPrice': true,
'takeProfitPrice': true,
'attachedStopLossTakeProfit': {
'triggerPriceType': {
'last': true,
'mark': true,
'index': false,
},
'price': false,
},
'timeInForce': {
'IOC': true,
'FOK': true,
'PO': true,
'GTD': false,
},
'hedged': false,
'trailing': true,
'marketBuyRequiresPrice': true,
'marketBuyByCost': true,
// exchange-supported features
// 'selfTradePrevention': true,
// 'twap': false,
// 'iceberg': false,
// 'oco': false,
},
'fetchMyTrades': {
'marginMode': true,
'limit': undefined,
'daysBack': undefined,
'untilDays': 99999,
},
'fetchOrder': {
'marginMode': false,
'trigger': false,
'trailing': true,
},
'fetchOpenOrders': {
'marginMode': false,
'limit': 100,
'trigger': true,
'trailing': false,
},
'fetchClosedOrders': {
'marginMode': true,
'limit': 200,
'daysBack': undefined,
'daysBackCanceled': undefined,
'untilDays': undefined,
'trigger': false,
'trailing': false,
},
'fetchOHLCV': {
'limit': 500,
},
},
'spot': {
'extends': 'default',
},
'swap': {
'linear': {
'extends': 'forDerivatives',
},
'inverse': {
'extends': 'forDerivatives',
},
},
'future': {
'linear': undefined,
'inverse': undefined,
},
},
});
}
/**
* @method
* @name bitmart#fetchTime
* @description fetches the current integer timestamp in milliseconds from the exchange server
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {int} the current integer timestamp in milliseconds from the exchange server
*/
async fetchTime(params = {}) {
const response = await this.publicGetSystemTime(params);
//
// {
// "message":"OK",
// "code":1000,
// "trace":"c4e5e5b7-fe9f-4191-89f7-53f6c5bf9030",
// "data":{
// "server_time":1599843709578
// }
// }
//
const data = this.safeDict(response, 'data', {});
return this.safeInteger(data, 'server_time');
}
/**
* @method
* @name bitmart#fetchStatus
* @description the latest known information on the availability of the exchange API
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
*/
async fetchStatus(params = {}) {
const options = this.safeDict(this.options, 'fetchStatus', {});
const defaultType = this.safeString(this.options, 'defaultType');
let type = this.safeString(options, 'type', defaultType);
type = this.safeString(params, 'type', type);
params = this.omit(params, 'type');
const response = await this.publicGetSystemService(params);
//
// {
// "message": "OK",
// "code": 1000,
// "trace": "1d3f28b0-763e-4f78-90c4-5e3ad19dc595",
// "data": {
// "service": [
// {
// "title": "Spot API Stop",
// "service_type": "spot",
// "status": 2,
// "start_time": 1648639069125,
// "end_time": 1648639069125
// },
// {
// "title": "Contract API Stop",
// "service_type": "contract",
// "status": 2,
// "start_time": 1648639069125,
// "end_time": 1648639069125
// }
// ]
// }
// }
//
const data = this.safeDict(response, 'data', {});
const services = this.safeList(data, 'service', []);
const servicesByType = this.indexBy(services, 'service_type');
if (type === 'swap') {
type = 'contract';
}
const service = this.safeString(servicesByType, type);
let status = undefined;
let eta = undefined;
if (service !== undefined) {
const statusCode = this.safeInteger(service, 'status');
if (statusCode === 2) {
status = 'ok';
}
else {
status = 'maintenance';
eta = this.safeInteger(service, 'end_time');
}
}
return {
'status': status,
'updated': undefined,
'eta': eta,
'url': undefined,
'info': response,
};
}
async fetchSpotMarkets(params = {}) {
const response = await this.publicGetSpotV1SymbolsDetails(params);
//
// {
// "message":"OK",
// "code":1000,
// "trace":"a67c9146-086d-4d3f-9897-5636a9bb26e1",
// "data":{
// "symbols":[
// {
// "symbol": "BTC_USDT",
// "symbol_id": 53,
// "base_currency": "BTC",
// "quote_currency": "USDT",
// "base_min_size": "0.000010000000000000000000000000",
// "base_max_size": "100000000.000000000000000000000000000000",
// "price_min_precision": -1,
// "price_max_precision": 2,
// "quote_increment": "0.00001", // Api docs says "The minimum order quantity is also the minimum order quantity increment", however I think they mistakenly use the term 'order quantity'
// "expiration": "NA",
// "min_buy_amount": "5.000000000000000000000000000000",
// "min_sell_amount": "5.000000000000000000000000000000",
// "trade_status": "trading"
// },
// ]
// }
// }
//
const data = this.safeDict(response, 'data', {});
const symbols = this.safeList(data, 'symbols', []);
const result = [];
const fees = this.fees['trading'];
for (let i = 0; i < symbols.length; i++) {
const market = symbols[i];
const id = this.safeString(market, 'symbol');
const numericId = this.safeInteger(market, 'symbol_id');
const baseId = this.safeString(market, 'base_currency');
const quoteId = this.safeString(market, 'quote_currency');
const base = this.safeCurrencyCode(baseId);
const quote = this.safeCurrencyCode(quoteId);
const symbol = base + '/' + quote;
const minBuyCost = this.safeString(market, 'min_buy_amount');
const minSellCost = this.safeString(market, 'min_sell_amount');
const minCost = Precise["default"].stringMax(minBuyCost, minSellCost);
const baseMinSize = this.safeNumber(market, 'base_min_size');
result.push(this.safeMarketStructure({
'id': id,
'numericId': numericId,
'symbol': symbol,
'base': base,
'quote': quote,
'settle': undefined,
'baseId': baseId,
'quoteId': quoteId,
'settleId': undefined,
'type': 'spot',
'spot': true,
'margin': false,
'swap': false,
'future': false,
'option': false,
'active': true,
'contract': false,
'linear': undefined,
'inverse': undefined,
'contractSize': undefined,
'expiry': undefined,
'expiryDatetime': undefined,
'strike': undefined,
'optionType': undefined,
'maker': fees['maker'],
'taker': fees['taker'],
'precision': {
'amount': baseMinSize,
'price': this.parseNumber(this.parsePrecision(this.safeString(market, 'price_max_precision'))),
},
'limits': {
'leverage': {
'min': undefined,
'max': undefined,
},
'amount': {
'min': baseMinSize,
'max': this.safeNumber(market, 'base_max_size'),
},
'price': {
'min': undefined,
'max': undefined,
},
'cost': {
'min': this.parseNumber(minCost),
'max': undefined,
},
},
'created': undefined,
'info': market,
}));
}
return result;
}
async fetchContractMarkets(params = {}) {
const response = await this.publicGetContractPublicDetails(params);
//
// {
// "code": 1000,
// "message": "Ok",
// "data": {
// "symbols": [
// {
// "symbol": "BTCUSDT",
// "product_type": 1,
// "open_timestamp": 1645977600000,
// "expire_timestamp": 0,
// "settle_timestamp": 0,
// "base_currency": "BTC",
// "quote_currency": "USDT",
// "last_price": "63547.4",
// "volume_24h": "110938430",
// "turnover_24h": "7004836342.6944",
// "index_price": "63587.85404255",
// "index_name": "BTCUSDT",
// "contract_size": "0.001",
// "min_leverage": "1",
// "max_leverage": "100",
// "price_precision": "0.1",
// "vol_precision": "1",
// "max_volume": "1000000",
// "min_volume": "1",
// "funding_rate": "0.0000801",
// "expected_funding_rate": "-0.0000035",
// "open_interest": "278214",
// "open_interest_value": "17555316.9355496",
// "high_24h": "64109.4",
// "low_24h": "61857.6",
// "change_24h": "0.0239264900886327",
// "funding_time": 1726819200000
// },
// ]
// }
// }
//
const data = this.safeDict(response, 'data', {});
const symbols = this.safeList(data, 'symbols', []);
const result = [];
const fees = this.fees['trading'];
for (let i = 0; i < symbols.length; i++) {
const market = symbols[i];
const id = this.safeString(market, 'symbol');
const baseId = this.safeString(market, 'base_currency');
const quoteId = this.safeString(market, 'quote_currency');
const base = this.safeCurrencyCode(baseId);
const quote = this.safeCurrencyCode(quoteId);
const settleId = 'USDT'; // this is bitmart's ID for usdt
const settle = this.safeCurren