ccxt
Version:
1,156 lines (1,154 loc) • 140 kB
JavaScript
// ----------------------------------------------------------------------------
// 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
// EDIT THE CORRESPONDENT .ts FILE INSTEAD
// ---------------------------------------------------------------------------
import { sha256 } from '@noble/hashes/sha2.js';
import Exchange from './abstract/deepcoin.js';
import { TICK_SIZE } from './base/functions/number.js';
import { Precise } from './base/Precise.js';
import { ArgumentsRequired, BadRequest, ExchangeError, InsufficientFunds, InvalidOrder, OrderNotFound, NotSupported, NullResponse } from './base/errors.js';
// ---------------------------------------------------------------------------
/**
* @class deepcoin
* @augments Exchange
*/
export default class deepcoin extends Exchange {
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': 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': OrderNotFound, // {"code":"0","msg":"","data":{"ordId":"","clOrdId":"","sCode":"24","sMsg":"OrderNotFound:1"}}
'31': InsufficientFunds, // {"code":"0","msg":"","data":{"ordId":"","clOrdId":"","tag":"","sCode":"31","sMsg":"NotEnoughPositionToClose:Position=0"}}
'36': InsufficientFunds, // {"code":"0","msg":"","data":{"ordId":"","clOrdId":"","tag":"","sCode":"36","sMsg":"InsufficientMoney:-0.000004"}}
'44': BadRequest, // {"code":"0","msg":"","data":{"ordId":"","clOrdId":"","tag":"","sCode":"44","sMsg":"VolumeNotOnTick"}}
'49': InvalidOrder, // {"code":"0","msg":"","data":{"ordId":"","clOrdId":"","tag":"","sCode":"49","sMsg":"PriceOutOfUpperLimit:Price\u003eUpperLimitPrice[0.28422]"}}
'194': InvalidOrder, // {"code":"0","msg":"","data":{"ordId":"","clOrdId":"","tag":"","sCode":"194","sMsg":"LessThanMinVolume"}}
'195': InvalidOrder, // {"code":"0","msg":"","data":{"ordId":"","clOrdId":"","tag":"","sCode":"195","sMsg":"PositionLessThanMinVolume"}}
'199': BadRequest, // {"code":"0","msg":"","data":{"instId":"","lever":"","mgnMode":"","mrgPosition":"","sCode":"199","sMsg":"LeverageTooHigh:Amount[10000.0]\u003eLeverage[75.1880]"}}
'100010': InsufficientFunds, // {"code":"0","msg":"","data":{"retCode":100010,"retMsg":"Balance is insufficient, please deposit first.","retData":{}}}
'unsupportedAction': BadRequest,
'localIDNotExist': BadRequest,
},
'broad': {
'no available': NotSupported, // orderbook does not exist: ETHUSD_0.1, no available orderbook data
'field is required': ArgumentsRequired, // {"code":"51","msg":"The productGroup field is required","data":null}
'not in acceptable range': BadRequest, // {"code":"51","msg":"The instType value `spot` is not in acceptable range: SPOT,SWAP","data":null}
'subscription cluster does not "exist"': BadRequest,
'must be equal or lesser than': 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.stringMax(maxLeverage, '1');
const maxMarketSize = this.safeString(market, 'maxMktSz');
const maxLimitSize = this.safeString(market, 'maxLmtSz');
const maxAmount = this.parseNumber(Precise.stringMax(maxMarketSize, maxLimitSize));
const state = this.safeString(market, 'state');
const isMargin = spot && (Precise.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 ArgumentsRequired(this.id + ' fetchDepositAddresses requires a list with one currency code');
}
const length = codes.length;
if (length !== 1) {
throw new 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",
//