UNPKG

ccxt

Version:

A cryptocurrency trading API with more than 100 exchanges in JavaScript / TypeScript / Python / C# / PHP / Go

1,156 lines (1,153 loc) • 140 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var sha2_js = require('@noble/hashes/sha2.js'); var deepcoin$1 = require('./abstract/deepcoin.js'); var number = require('./base/functions/number.js'); var Precise = require('./base/Precise.js'); var errors = require('./base/errors.js'); // ---------------------------------------------------------------------------- // --------------------------------------------------------------------------- /** * @class deepcoin * @augments Exchange */ class deepcoin extends deepcoin$1["default"] { describe() { return this.deepExtend(super.describe(), { 'id': 'deepcoin', 'name': 'DeepCoin', 'countries': ['SG'], // Singapore 'rateLimit': 200, // 5 times per second 'version': 'v1', 'certified': false, 'pro': true, 'has': { 'CORS': undefined, 'spot': true, 'margin': true, 'swap': true, 'future': false, 'option': false, 'addMargin': false, 'cancelAllOrders': true, 'cancelAllOrdersAfter': false, 'cancelOrder': true, 'cancelOrders': true, 'cancelWithdraw': false, 'closePosition': true, 'createConvertTrade': false, 'createDepositAddress': false, 'createLimitBuyOrder': true, 'createLimitOrder': true, 'createLimitSellOrder': true, 'createMarketBuyOrder': true, 'createMarketBuyOrderWithCost': true, 'createMarketOrder': true, 'createMarketOrderWithCost': true, 'createMarketSellOrder': true, 'createMarketSellOrderWithCost': true, 'createOrder': true, 'createOrders': false, 'createOrderWithTakeProfitAndStopLoss': true, 'createPostOnlyOrder': true, 'createReduceOnlyOrder': true, 'createStopLossOrder': false, 'createTakeProfitOrder': false, 'createTrailingAmountOrder': false, 'createTrailingPercentOrder': false, 'createTriggerOrder': true, 'editOrder': true, 'fetchAccounts': false, 'fetchBalance': true, 'fetchCanceledAndClosedOrders': true, 'fetchCanceledOrders': true, 'fetchClosedOrder': true, 'fetchClosedOrders': true, 'fetchConvertCurrencies': false, 'fetchConvertQuote': false, 'fetchConvertTrade': false, 'fetchConvertTradeHistory': false, 'fetchCurrencies': false, 'fetchDepositAddress': true, 'fetchDepositAddresses': true, 'fetchDeposits': true, 'fetchDepositsWithdrawals': false, 'fetchDepositWithdrawFees': false, 'fetchFundingHistory': false, 'fetchFundingRate': true, 'fetchFundingRateHistory': true, 'fetchFundingRates': true, 'fetchIndexOHLCV': true, 'fetchLedger': true, 'fetchLeverage': false, 'fetchLeverageTiers': false, 'fetchMarginAdjustmentHistory': false, 'fetchMarginMode': false, 'fetchMarkets': true, 'fetchMarkOHLCV': true, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenInterest': false, 'fetchOpenInterestHistory': false, 'fetchOpenOrder': true, 'fetchOpenOrders': true, 'fetchOrder': false, 'fetchOrderBook': true, 'fetchOrders': false, 'fetchOrderTrades': true, 'fetchPosition': true, 'fetchPositionHistory': false, 'fetchPositionMode': false, 'fetchPositions': true, 'fetchPositionsForSymbol': true, 'fetchPositionsHistory': true, 'fetchPremiumIndexOHLCV': false, 'fetchStatus': false, 'fetchTicker': false, 'fetchTickers': true, 'fetchTime': false, 'fetchTrades': true, 'fetchTradingFee': false, 'fetchTradingFees': false, 'fetchTransactions': false, 'fetchTransfers': false, 'fetchWithdrawals': true, 'reduceMargin': false, 'sandbox': false, 'setLeverage': true, 'setMargin': false, 'setMarginMode': false, 'setPositionMode': false, 'transfer': true, 'withdraw': false, }, 'timeframes': { '1m': '1m', '5m': '5m', '15m': '15m', '30m': '30m', '1h': '1H', '4h': '4H', '12h': '12H', '1d': '1D', '1w': '1W', '1M': '1M', '1y': '1Y', }, 'urls': { 'logo': 'https://github.com/user-attachments/assets/ddf3e178-c3b6-409d-8f9f-af8b7cf80454', 'api': { 'public': 'https://api.deepcoin.com', 'private': 'https://api.deepcoin.com', }, 'www': 'https://www.deepcoin.com/', 'doc': 'https://www.deepcoin.com/docs', 'referral': { 'url': 'https://s.deepcoin.com/UzkyODgy', 'discount': 0.1, }, }, 'api': { 'public': { 'get': { 'deepcoin/market/books': 1, 'deepcoin/market/candles': 1, 'deepcoin/market/instruments': 1, 'deepcoin/market/tickers': 1, 'deepcoin/market/index-candles': 1, 'deepcoin/market/trades': 1, 'deepcoin/market/mark-price-candles': 1, 'deepcoin/market/step-margin': 5, 'deepcoin/trade/funding-rate': 5, 'deepcoin/trade/fund-rate/current-funding-rate': 5, 'deepcoin/trade/fund-rate/history': 5, }, }, 'private': { 'get': { 'deepcoin/account/balances': 5, 'deepcoin/account/bills': 5, 'deepcoin/account/positions': 5, 'deepcoin/trade/fills': 5, 'deepcoin/trade/orderByID': 5, 'deepcoin/trade/finishOrderByID': 5, 'deepcoin/trade/orders-history': 5, 'deepcoin/trade/v2/orders-pending': 5, 'deepcoin/trade/trigger-orders-pending': 5, 'deepcoin/trade/trigger-orders-history': 5, 'deepcoin/copytrading/support-contracts': 5, 'deepcoin/copytrading/leader-position': 5, 'deepcoin/copytrading/estimate-profit': 5, 'deepcoin/copytrading/history-profit': 5, 'deepcoin/copytrading/follower-rank': 5, 'deepcoin/internal-transfer/support': 5, 'deepcoin/internal-transfer/history-order': 5, 'deepcoin/rebate/config': 5, 'deepcoin/agents/users': 5, 'deepcoin/agents/users/rebate-list': 5, 'deepcoin/agents/users/rebates': 5, 'deepcoin/asset/deposit-list': 5, 'deepcoin/asset/withdraw-list': 5, 'deepcoin/asset/recharge-chain-list': 5, 'deepcoin/listenkey/acquire': 5, 'deepcoin/listenkey/extend': 5, }, 'post': { 'deepcoin/account/set-leverage': 5, 'deepcoin/trade/order': 5, 'deepcoin/trade/replace-order': 5, 'deepcoin/trade/cancel-order': 5, 'deepcoin/trade/batch-cancel-order': 5, 'deepcoin/trade/cancel-trigger-order': 1 / 6, 'deepcoin/trade/swap/cancel-all': 5, 'deepcoin/trade/trigger-order': 5, 'deepcoin/trade/batch-close-position': 5, 'deepcoin/trade/replace-order-sltp': 5, 'deepcoin/trade/close-position-by-ids': 5, 'deepcoin/copytrading/leader-settings': 5, 'deepcoin/copytrading/set-contracts': 5, 'deepcoin/internal-transfer': 5, 'deepcoin/rebate/config': 5, 'deepcoin/asset/transfer': 5, }, }, }, 'fees': { 'trading': { 'taker': this.parseNumber('0.0015'), 'maker': this.parseNumber('0.0010'), }, }, 'features': { 'spot': { 'sandbox': false, 'createOrder': { 'marginMode': true, 'triggerPrice': true, 'triggerPriceType': { 'last': true, 'mark': false, 'index': false, }, 'triggerDirection': false, 'stopLossPrice': true, 'takeProfitPrice': true, 'attachedStopLossTakeProfit': { 'triggerPriceType': { 'last': false, 'mark': false, 'index': false, }, 'price': true, }, 'timeInForce': { 'IOC': true, 'FOK': true, 'PO': true, 'GTD': false, }, 'hedged': true, 'trailing': false, 'marketBuyRequiresPrice': false, }, 'createOrders': undefined, 'fetchMyTrades': { 'marginMode': false, 'limit': 100, 'daysBack': 60, 'untilDays': undefined, 'symbolRequired': true, }, 'fetchOrder': undefined, 'fetchOpenOrders': { 'marginMode': false, 'limit': 100, 'trigger': true, 'trailing': false, 'symbolRequired': true, }, 'fetchOrders': undefined, 'fetchClosedOrders': { 'marginMode': false, 'limit': 100, 'daysBack': undefined, 'daysBackCanceled': undefined, 'untilDays': undefined, 'trigger': true, 'trailing': false, 'symbolRequired': true, }, 'fetchOHLCV': { 'limit': 300, }, }, 'swap': { 'linear': { 'extends': 'spot', }, 'inverse': { 'extends': 'spot', }, }, }, 'requiredCredentials': { 'apiKey': true, 'secret': true, 'password': true, }, 'precisionMode': number.TICK_SIZE, 'options': { 'recvWindow': 5000, 'defaultNetworks': { 'ETH': 'ERC20', 'USDT': 'TRC20', 'USDC': 'ERC20', }, 'networks': { 'ERC20': 'ERC20', 'TRC20': 'TRC20', 'ARB': 'ARBITRUM', 'BSC': 'BSC(BEP20)', 'SOL': 'SOL', 'BTC': 'Bitcoin', 'ADA': 'Cardano', }, 'networksById': {}, 'fetchMarkets': { 'types': ['spot', 'swap'], // spot, swap, }, 'timeInForce': { 'GTC': 'GTC', // Good Till Cancel 'IOC': 'IOC', // Immediate Or Cancel 'PO': 'PO', // Post Only }, 'exchangeType': { 'spot': 'SPOT', 'swap': 'SWAP', 'SPOT': 'SPOT', 'SWAP': 'SWAP', }, 'accountsByType': { 'spot': 1, 'fund': 2, 'rebate': 3, 'inverse': 5, 'linear': 7, 'demo': 10, }, }, 'commonCurrencies': {}, 'exceptions': { 'exact': { '24': errors.OrderNotFound, // {"code":"0","msg":"","data":{"ordId":"","clOrdId":"","sCode":"24","sMsg":"OrderNotFound:1"}} '31': errors.InsufficientFunds, // {"code":"0","msg":"","data":{"ordId":"","clOrdId":"","tag":"","sCode":"31","sMsg":"NotEnoughPositionToClose:Position=0"}} '36': errors.InsufficientFunds, // {"code":"0","msg":"","data":{"ordId":"","clOrdId":"","tag":"","sCode":"36","sMsg":"InsufficientMoney:-0.000004"}} '44': errors.BadRequest, // {"code":"0","msg":"","data":{"ordId":"","clOrdId":"","tag":"","sCode":"44","sMsg":"VolumeNotOnTick"}} '49': errors.InvalidOrder, // {"code":"0","msg":"","data":{"ordId":"","clOrdId":"","tag":"","sCode":"49","sMsg":"PriceOutOfUpperLimit:Price\u003eUpperLimitPrice[0.28422]"}} '194': errors.InvalidOrder, // {"code":"0","msg":"","data":{"ordId":"","clOrdId":"","tag":"","sCode":"194","sMsg":"LessThanMinVolume"}} '195': errors.InvalidOrder, // {"code":"0","msg":"","data":{"ordId":"","clOrdId":"","tag":"","sCode":"195","sMsg":"PositionLessThanMinVolume"}} '199': errors.BadRequest, // {"code":"0","msg":"","data":{"instId":"","lever":"","mgnMode":"","mrgPosition":"","sCode":"199","sMsg":"LeverageTooHigh:Amount[10000.0]\u003eLeverage[75.1880]"}} '100010': errors.InsufficientFunds, // {"code":"0","msg":"","data":{"retCode":100010,"retMsg":"Balance is insufficient, please deposit first.","retData":{}}} 'unsupportedAction': errors.BadRequest, 'localIDNotExist': errors.BadRequest, }, 'broad': { 'no available': errors.NotSupported, // orderbook does not exist: ETHUSD_0.1, no available orderbook data 'field is required': errors.ArgumentsRequired, // {"code":"51","msg":"The productGroup field is required","data":null} 'not in acceptable range': errors.BadRequest, // {"code":"51","msg":"The instType value `spot` is not in acceptable range: SPOT,SWAP","data":null} 'subscription cluster does not "exist"': errors.BadRequest, 'must be equal or lesser than': errors.BadRequest, // {"code":"51","msg":"The Size value `100` must be equal or lesser than 50","data":null} }, }, }); } handleMarketTypeAndParams(methodName, market = undefined, params = {}, defaultValue = undefined) { const instType = this.safeString(params, 'instType'); params = this.omit(params, 'instType'); const type = this.safeString(params, 'type'); if ((type === undefined) && (instType !== undefined)) { params = this.extend(params, { 'type': instType }); } return super.handleMarketTypeAndParams(methodName, market, params, defaultValue); } convertToInstrumentType(type) { const exchangeTypes = this.safeDict(this.options, 'exchangeType', {}); return this.safeString(exchangeTypes, type, type); } /** * @method * @name deepcoin#fetchMarkets * @see https://www.deepcoin.com/docs/DeepCoinMarket/getBaseInfo * @description retrieves data on all markets for okcoin * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ async fetchMarkets(params = {}) { let types = ['spot', 'swap']; const fetchMarketsOption = this.safeDict(this.options, 'fetchMarkets'); if (fetchMarketsOption !== undefined) { types = this.safeList(fetchMarketsOption, 'types', types); } else { types = this.safeList(this.options, 'fetchMarkets', types); // backward-support } let promises = []; let result = []; for (let i = 0; i < types.length; i++) { promises.push(this.fetchMarketsByType(types[i], params)); } promises = await Promise.all(promises); for (let i = 0; i < promises.length; i++) { result = this.arrayConcat(result, promises[i]); } return result; } async fetchMarketsByType(type, params = {}) { const request = { 'instType': this.convertToInstrumentType(type), }; const response = await this.publicGetDeepcoinMarketInstruments(this.extend(request, params)); // // spot // // { // "code": "0", // "msg": "", // "data": [ // { // "instType": "SPOT", // "instId": "A-USDT", // "uly": "", // "baseCcy": "A", // "quoteCcy": "USDT", // "ctVal": "1", // "ctValCcy": "", // "listTime": "0", // "lever": "1", // "tickSz": "0.0001", // "lotSz": "0.001", // "minSz": "0.5", // "ctType": "", // "alias": "", // "state": "live", // "maxLmtSz": "7692307", // "maxMktSz": "7692307" // } // ] // } // const dataResponse = this.safeList(response, 'data', []); return this.parseMarkets(dataResponse); } parseMarket(market) { // // spot markets // // { // "instType": "SPOT", // "instId": "A-USDT", // "uly": "", // "baseCcy": "A", // "quoteCcy": "USDT", // "ctVal": "1", // "ctValCcy": "", // "listTime": "0", // "lever": "1", // "tickSz": "0.0001", // "lotSz": "0.001", // "minSz": "0.5", // "ctType": "", // "alias": "", // "state": "live", // "maxLmtSz": "7692307", // "maxMktSz": "7692307" // } // // swap markets // // { // "instType": "SWAP", // "instId": "ZORA-USDT-SWAP", // "uly": "", // "baseCcy": "ZORA", // "quoteCcy": "USDT", // "ctVal": "1", // "ctValCcy": "", // "listTime": "0", // "lever": "20", // "tickSz": "0.00001", // "lotSz": "1", // "minSz": "1685", // "ctType": "", // "alias": "", // "state": "live", // "maxLmtSz": "10000000", // "maxMktSz": "10000000" // } // const id = this.safeString(market, 'instId'); const type = this.safeStringLower(market, 'instType'); const spot = (type === 'spot'); const swap = (type === 'swap'); const baseId = this.safeString(market, 'baseCcy'); const quoteId = this.safeString(market, 'quoteCcy', ''); let settleId = undefined; let settle = undefined; const base = this.safeCurrencyCode(baseId); const quote = this.safeCurrencyCode(quoteId); let symbol = base + '/' + quote; let isLinear = undefined; if (swap) { isLinear = (quoteId !== 'USD'); settleId = isLinear ? quoteId : baseId; settle = this.safeCurrencyCode(settleId); symbol = symbol + ':' + settle; } const fees = this.safeDict2(this.fees, type, 'trading', {}); let maxLeverage = this.safeString(market, 'lever', '1'); maxLeverage = Precise["default"].stringMax(maxLeverage, '1'); const maxMarketSize = this.safeString(market, 'maxMktSz'); const maxLimitSize = this.safeString(market, 'maxLmtSz'); const maxAmount = this.parseNumber(Precise["default"].stringMax(maxMarketSize, maxLimitSize)); const state = this.safeString(market, 'state'); const isMargin = spot && (Precise["default"].stringGt(maxLeverage, '1')); const isInverse = swap ? (!isLinear) : undefined; return this.extend(fees, { 'id': id, 'symbol': symbol, 'base': base, 'quote': quote, 'settle': settle, 'baseId': baseId, 'quoteId': quoteId, 'settleId': settleId, 'type': type, 'spot': spot, 'margin': isMargin, 'swap': swap, 'future': false, 'option': false, 'active': state === 'live', 'contract': swap, 'linear': isLinear, 'inverse': isInverse, 'contractSize': swap ? this.safeNumber(market, 'ctVal') : undefined, 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'created': undefined, 'precision': { 'amount': this.safeNumber(market, 'lotSz'), 'price': this.safeNumber(market, 'tickSz'), }, 'limits': { 'leverage': { 'min': this.parseNumber('1'), 'max': this.parseNumber(maxLeverage), }, 'amount': { 'min': this.safeNumber(market, 'minSz'), 'max': maxAmount, }, 'price': { 'min': undefined, 'max': undefined, }, 'cost': { 'min': undefined, 'max': undefined, }, }, 'info': market, }); } setMarkets(markets, currencies = undefined) { const result = super.setMarkets(markets, currencies); const symbols = Object.keys(result); for (let i = 0; i < symbols.length; i++) { const symbol = symbols[i]; const market = result[symbol]; if ((market !== undefined) && market['swap']) { const additionalId = this.safeString(market, 'baseId', '') + this.safeString(market, 'quoteId', ''); if (this.markets_by_id !== undefined) { this.markets_by_id[additionalId] = [market]; // some endpoints return swap market id as base+quote } } } return result; } /** * @method * @name deepcoin#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://www.deepcoin.com/docs/DeepCoinMarket/marketBooks * @param {string} symbol unified symbol of the market to fetch the order book for * @param {int} [limit] the maximum amount of order book entries to return * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [order book structure]{@link https://docs.ccxt.com/?id=order-book-structure} */ async fetchOrderBook(symbol, limit = undefined, params = {}) { if (this.markets === undefined) { await this.loadMarkets(); } const market = this.market(symbol); if (limit === undefined) { limit = 400; } const request = { 'instId': market['id'], 'sz': limit, }; const response = await this.publicGetDeepcoinMarketBooks(this.extend(request, params)); // // { // "code": "0", // "msg": "", // "data": { // "bids": [ // ["3732.21", "99.6"], // ["3732.2", "54.7"] // ], // "asks": [ // ["3732.22", "85.1"], // ["3732.23", "49.4"] // ] // } // } // const data = this.safeDict(response, 'data', {}); return this.parseOrderBook(data, symbol, undefined, 'bids', 'asks', 0, 1); } /** * @method * @name deepcoin#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://www.deepcoin.com/docs/DeepCoinMarket/getKlineData * @see https://www.deepcoin.com/docs/DeepCoinMarket/getIndexKlineData * @see https://www.deepcoin.com/docs/DeepCoinMarket/getMarkKlineData * @param {string} symbol unified symbol of the market to fetch OHLCV data for * @param {string} 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 {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] timestamp in ms of the latest candle to fetch * @param {string} [params.price] "mark" or "index" for mark price and index price candles * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) { if (this.markets === undefined) { await this.loadMarkets(); } const maxLimit = 300; let paginate = false; [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate', false); if (paginate) { params = this.extend(params, { 'calculateUntil': true }); return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimit); } const market = this.market(symbol); const price = this.safeString(params, 'price'); params = this.omit(params, 'price'); const bar = this.safeString(this.timeframes, timeframe, timeframe); const request = { 'instId': market['id'], 'bar': bar, }; if (limit !== undefined) { request['limit'] = limit; } const until = this.safeInteger(params, 'until'); if (until !== undefined) { request['after'] = until; params = this.omit(params, 'until'); } const calculateUntil = this.safeBool(params, 'calculateUntil', false); if (calculateUntil) { params = this.omit(params, 'calculateUntil'); if (since !== undefined) { // the exchange do not have a since param for this endpoint // we calculate until (after) for correct pagination const duration = this.parseTimeframe(timeframe); const numberOfCandles = (limit === undefined) ? maxLimit : limit; let endTime = since + (duration * numberOfCandles) * 1000; if (until !== undefined) { endTime = Math.min(endTime, until); } const now = this.milliseconds(); request['after'] = Math.min(endTime, now); } } let response = undefined; if (price === 'mark') { response = await this.publicGetDeepcoinMarketMarkPriceCandles(this.extend(request, params)); } else if (price === 'index') { response = await this.publicGetDeepcoinMarketIndexCandles(this.extend(request, params)); } else { response = await this.publicGetDeepcoinMarketCandles(this.extend(request, params)); } // // { // "code": "0", // "msg": "", // "data":[ // [ // "1760221800000", // "3739.08", // "3741.95", // "3737.75", // "3740.1", // "2849", // "1065583.744" // ], // [ // "1760221740000", // "3742.36", // "3743.01", // "3736.83", // "3739.08", // "2723", // "1018290.723" // ] // ] // } // const data = this.safeList(response, 'data', []); return this.parseOHLCVs(data, market, timeframe, since, limit); } /** * @method * @name deepcoin#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @see https://www.deepcoin.com/docs/DeepCoinMarket/getMarketTickers * @param {string[]} [symbols] unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/?id=ticker-structure} */ async fetchTickers(symbols = undefined, params = {}) { if (this.markets === undefined) { await this.loadMarkets(); } symbols = this.marketSymbols(symbols); const market = this.getMarketFromSymbols(symbols); let marketType = undefined; [marketType, params] = this.handleMarketTypeAndParams('fetchTickers', market, params); const request = { 'instType': this.convertToInstrumentType(marketType), }; const response = await this.publicGetDeepcoinMarketTickers(this.extend(request, params)); const tickers = this.safeList(response, 'data', []); return this.parseTickers(tickers, symbols); } parseTicker(ticker, market = undefined) { // // { // "instType": "SWAP", // "instId": "BTC-USD-SWAP", // "last": "114113.3", // "lastSz": "", // "askPx": "114113.5", // "askSz": "56280", // "bidPx": "114113.2", // "bidSz": "63220", // "open24h": "113214.7", // "high24h": "116039.2", // "low24h": "113214.7", // "volCcy24h": "73.31475724", // "vol24h": "8406739", // "sodUtc0": "", // "sodUtc8": "", // "ts": "1760367816000" // } // const timestamp = this.safeInteger(ticker, 'ts'); const marketId = this.safeString(ticker, 'instId'); market = this.safeMarket(marketId, market, '-'); const symbol = market['symbol']; const last = this.safeString(ticker, 'last'); const open = this.safeString(ticker, 'open24h'); let quoteVolume = this.safeString(ticker, 'volCcy24h'); let baseVolume = this.safeString(ticker, 'vol24h'); if (market['swap'] && market['inverse']) { const temp = baseVolume; baseVolume = quoteVolume; quoteVolume = temp; } const high = this.safeString(ticker, 'high24h'); const low = this.safeString(ticker, 'low24h'); return this.safeTicker({ 'symbol': symbol, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'high': high, 'low': low, 'bid': this.safeString(ticker, 'bidPx'), 'bidVolume': this.safeString(ticker, 'bidSz'), 'ask': this.safeString(ticker, 'askPx'), 'askVolume': this.safeString(ticker, 'askSz'), 'vwap': undefined, 'open': open, 'close': last, 'last': last, 'previousClose': undefined, 'change': undefined, 'percentage': undefined, 'average': undefined, 'baseVolume': baseVolume, 'quoteVolume': quoteVolume, 'markPrice': undefined, 'indexPrice': undefined, 'info': ticker, }, market); } /** * @method * @name deepcoin#fetchTrades * @description get the list of most recent trades for a particular symbol * @see https://www.deepcoin.com/docs/DeepCoinMarket/getTrades * @param {string} 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 (default 100, max 500) * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=public-trades} */ async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) { if (this.markets === undefined) { await this.loadMarkets(); } const market = this.market(symbol); const request = { 'instId': market['id'], }; if (limit !== undefined) { request['limit'] = Math.min(limit, 500); } const productGroup = this.getProductGroupFromMarket(market); request['productGroup'] = productGroup; const response = await this.publicGetDeepcoinMarketTrades(this.extend(request, params)); const data = this.safeList(response, 'data', []); return this.parseTrades(data, market, since, limit); } getProductGroupFromMarket(market) { let productGroup = 'Spot'; if (this.safeBool(market, 'swap')) { if (this.safeBool(market, 'linear')) { productGroup = 'SwapU'; } else { productGroup = 'Swap'; } } return productGroup; } parseTrade(trade, market = undefined) { // // public fetchTrades // // { // "instId": "ETH-USDT", // "tradeId": "1001056388761321", // "px": "4095.66", // "sz": "0.01311251", // "side": "sell", // "ts": "1760367870000" // } // // private fetchMyTrades // { // "instType": "SPOT", // "instId": "ETH-USDT", // "tradeId": "1001056429613610", // "ordId": "1001435238208686", // "clOrdId": "", // "billId": "10010564296136101", // "tag": "", // "fillPx": "3791.15", // "fillSz": "0.004", // "side": "sell", // "posSide": "", // "execType": "", // "feeCcy": "USDT", // "fee": "0.0151646", // "ts": "1760704540000" // } // const marketId = this.safeString(trade, 'instId'); market = this.safeMarket(marketId, market); const timestamp = this.safeInteger(trade, 'ts'); const side = this.safeString(trade, 'side'); const execType = this.safeString(trade, 'execType'); let fee = undefined; const feeCost = this.safeString(trade, 'fee'); if (feeCost !== undefined) { const feeCurrencyId = this.safeString(trade, 'feeCcy'); const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId); fee = { 'cost': feeCost, 'currency': feeCurrencyCode, }; } return this.safeTrade({ 'info': trade, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'symbol': market['symbol'], 'id': this.safeString(trade, 'tradeId'), 'order': this.safeString(trade, 'ordId'), 'type': undefined, 'takerOrMaker': this.parseTakerOrMaker(execType), 'side': side, 'price': this.safeString2(trade, 'fillPx', 'px'), 'amount': this.safeString2(trade, 'fillSz', 'sz'), 'cost': undefined, 'fee': fee, }, market); } parseTakerOrMaker(execType) { const types = { 'T': 'taker', 'M': 'maker', }; return this.safeString(types, execType, execType); } /** * @method * @name deepcoin#fetchBalance * @description query for balance and get the amount of funds available for trading or funds locked in orders * @see https://www.deepcoin.com/docs/DeepCoinAccount/getAccountBalance * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.type] "spot" or "swap", the market type for the balance * @returns {object} a [balance structure]{@link https://docs.ccxt.com/?id=balance-structure} */ async fetchBalance(params = {}) { if (this.markets === undefined) { await this.loadMarkets(); } let marketType = undefined; [marketType, params] = this.handleMarketTypeAndParams('fetchBalance', undefined, params, marketType); const request = { 'instType': this.convertToInstrumentType(marketType), }; const response = await this.privateGetDeepcoinAccountBalances(this.extend(request, params)); return this.parseBalance(response); } parseBalance(response) { // // { // "code": "0", // "msg": "", // "data": [ // { // "ccy": "USDT", // "bal": "74", // "frozenBal": "0", // "availBal": "74" // } // ] // } // const result = { 'info': response, 'timestamp': undefined, 'datetime': undefined, }; const balances = this.safeList(response, 'data', []); for (let i = 0; i < balances.length; i++) { const balance = balances[i]; const symbol = this.safeString(balance, 'ccy'); const code = this.safeCurrencyCode(symbol); const account = this.account(); account['total'] = this.safeString(balance, 'bal'); account['used'] = this.safeString(balance, 'frozenBal'); account['free'] = this.safeString(balance, 'availBal'); result[code] = account; } return this.safeBalance(result); } /** * @method * @name deepcoin#fetchDeposits * @description fetch all deposits made to an account * @see https://www.deepcoin.com/docs/assets/deposit * @param {string} code unified currency code * @param {int} [since] the earliest time in ms to fetch deposits for * @param {int} [limit] the maximum number of deposits structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] the latest time in ms to fetch entries for * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/?id=transaction-structure} */ async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) { if (this.markets === undefined) { await this.loadMarkets(); } let paginate = false; [paginate, params] = this.handleOptionAndParams(params, 'fetchDeposits', 'paginate', false); if (paginate) { return await this.fetchPaginatedCallCursor('fetchDeposits', code, since, limit, params, 'code', undefined, 1, 50); } const request = {}; let currency = undefined; if (code !== undefined) { currency = this.currency(code); request['coin'] = currency['id']; } if (since !== undefined) { request['startTime'] = since; } if (limit !== undefined) { request['size'] = limit; } const until = this.safeInteger(params, 'until'); if (until !== undefined) { request['endTime'] = until; params = this.omit(params, 'until'); } const response = await this.privateGetDeepcoinAssetDepositList(this.extend(request, params)); const data = this.safeDict(response, 'data', {}); const items = this.safeList(data, 'data', []); const transactionParams = { 'type': 'deposit', }; return this.parseTransactions(items, currency, since, limit, transactionParams); } /** * @method * @name deepcoin#fetchWithdrawals * @description fetch all withdrawals made from an account * @see https://www.deepcoin.com/docs/assets/withdraw * @param {string} code unified currency code of the currency transferred * @param {int} [since] the earliest time in ms to fetch transfers for (default 24 hours ago) * @param {int} [limit] the maximum number of transfer structures to retrieve (default 50, max 200) * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] the latest time in ms to fetch transfers for (default time now) * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/?id=transaction-structure} */ async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) { if (this.markets === undefined) { await this.loadMarkets(); } let paginate = false; [paginate, params] = this.handleOptionAndParams(params, 'fetchDeposits', 'paginate', false); if (paginate) { return await this.fetchPaginatedCallCursor('fetchDeposits', code, since, limit, params, 'code', undefined, 1, 50); } const request = {}; let currency = undefined; if (code !== undefined) { currency = this.currency(code); request['coin'] = currency['id']; } if (since !== undefined) { request['startTime'] = since; } if (limit !== undefined) { request['size'] = limit; } const until = this.safeInteger(params, 'until'); if (until !== undefined) { request['endTime'] = until; params = this.omit(params, 'until'); } const response = await this.privateGetDeepcoinAssetWithdrawList(this.extend(request, params)); const data = this.safeDict(response, 'data', {}); const items = this.safeList(data, 'data', []); const transactionParams = { 'type': 'withdrawal', }; return this.parseTransactions(items, currency, since, limit, transactionParams); } parseTransaction(transaction, currency = undefined) { // // fetchDeposits // { // "createTime": 1760368656, // "txHash": "03fe3244d89e794586222413c61779380da9e9fe5baaa253c38d01a4199a3499", // "chainName": "TRC20", // "amount": "149", // "coin": "USDT", // "status": "succeed" // } // const txid = this.safeString(transaction, 'txHash'); const currencyId = this.safeString(transaction, 'coin'); const code = this.safeCurrencyCode(currencyId, currency); const amount = this.safeNumber(transaction, 'amount'); const timestamp = this.safeTimestamp(transaction, 'createTime'); const networkId = this.safeString(transaction, 'chainName'); const network = this.networkIdToCode(networkId, code); const status = this.parseTransactionStatus(this.safeString(transaction, 'status')); return { 'info': transaction, 'id': undefined, 'currency': code, 'amount': amount, 'network': network, 'addressFrom': undefined, 'addressTo': undefined, 'address': this.safeString(transaction, 'address'), 'tagFrom': undefined, 'tagTo': undefined, 'tag': undefined, 'status': status, 'type': undefined, 'updated': undefined, 'txid': txid, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'internal': undefined, 'comment': undefined, 'fee': { 'currency': undefined, 'cost': undefined, }, }; } parseTransactionStatus(status) { const statuses = { 'confirming': 'pending', 'succeed': 'ok', }; return this.safeString(statuses, status, status); } /** * @method * @name deepcoin#fetchDepositAddresses * @description fetch deposit addresses for multiple currencies and chain types * @see https://www.deepcoin.com/docs/assets/chainlist * @param {string[]|undefined} codes list of unified currency codes, default is undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a list of [address structures]{@link https://docs.ccxt.com/?id=address-structure} */ async fetchDepositAddresses(codes = undefined, params = {}) { if (this.markets === undefined) { await this.loadMarkets(); } if (codes === undefined) { throw new errors.ArgumentsRequired(this.id + ' fetchDepositAddresses requires a list with one currency code'); } const length = codes.length; if (length !== 1) { throw new errors.NotSupported(this.id + ' fetchDepositAddresses requires a list with one currency code'); } const code = codes[0]; const currency = this.currency(code); const request = { 'currency_id': currency['id'], 'lang': 'en', }; const response = await this.privateGetDeepcoinAssetRechargeChainList(this.extend(request, params)); // // { // "code": "0", // "msg": "", // "data": { // "list": [ // { // "chain": "TRC20", // "state": 1, // "remind": "Only support deposits and withdrawals via TRC20 network. If you send it via other address b