@kraken-crypto/ccxt
Version:
A cryptocurrency trading API with more than 100 exchanges in JavaScript / TypeScript / Python / C# / PHP / Go
1,176 lines • 135 kB
JavaScript
// ---------------------------------------------------------------------------
import Exchange from './abstract/deepcoin.js';
import { TICK_SIZE } from './base/functions/number.js';
import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
import { Precise } from './base/Precise.js';
import { ArgumentsRequired, BadRequest, ExchangeError, InsufficientFunds, InvalidOrder, OrderNotFound, NotSupported, NullResponse } from '../ccxt.js';
// ---------------------------------------------------------------------------
/**
* @class deepcoin
* @augments Exchange
*/
export default class deepcoin extends Exchange {
describe() {
return this.deepExtend(super.describe(), {
'id': 'deepcoin',
'name': 'DeepCoin',
'countries': ['SG'],
'rateLimit': 200,
'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/671bd35c-770e-4935-9070-f8fb114f79c4',
'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',
'IOC': 'IOC',
'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,
'31': InsufficientFunds,
'36': InsufficientFunds,
'44': BadRequest,
'49': InvalidOrder,
'194': InvalidOrder,
'195': InvalidOrder,
'199': BadRequest,
'100010': InsufficientFunds,
'unsupportedAction': BadRequest,
'localIDNotExist': BadRequest,
},
'broad': {
'no available': NotSupported,
'field is required': ArgumentsRequired,
'not in acceptable range': BadRequest,
'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');
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': spot && (Precise.stringGt(maxLeverage, '1')),
'swap': swap,
'future': false,
'option': false,
'active': state === 'live',
'contract': swap,
'linear': isLinear,
'inverse': swap ? (!isLinear) : undefined,
'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) {
markets = super.setMarkets(markets, currencies);
const symbols = Object.keys(markets);
for (let i = 0; i < symbols.length; i++) {
const symbol = symbols[i];
const market = markets[symbol];
if (market['swap']) {
const additionalId = market['baseId'] + market['quoteId'];
this.markets_by_id[additionalId] = [market]; // some endpoints return swap market id as base+quote
}
}
return this.markets;
}
/**
* @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} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
*/
async fetchOrderBook(symbol, limit = undefined, params = {}) {
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 = {}) {
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 canlculate 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 = {}) {
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 = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const request = {
'instId': market['id'],
};
if (limit !== undefined) {
request['limit'] = limit; // default 100, max 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 (market['swap']) {
if (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 = {}) {
await this.loadMarkets();
let marketType = 'spot';
[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 = {}) {
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 = {}) {
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);
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 = {}) {
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",
// "state": 1,
// "remind": "Only support deposits and withdrawals via TRC20 network. If you send it via other address by mistake, it will not be credited and will result in the permanent loss of your deposit.",
// "inNotice": "",
// "actLogo": "",
// "address": "TNJYDW9Bk87VwfA6s7FtxURLEMHesQbYgF",
// "hasMemo": false,
// "memo": "",
// "estimatedTime": 1,
// "fastConfig": {
// "fastLimitNum": 0,
// "fastBlock": 10,
// "realBlock": 1
// }
// }
// ]
// }
// }
//
const data = this.safeDict(response, 'data', {});
const list = this.safeList(data, 'list', []);
const additionalParams = {
'currency': code,
};
return this.parseDepositAddresses(list, codes, false, additionalParams);
}
/**
* @method
* @name deepcoin#fetchDepositAddress
* @description fetch the deposit address for a currency associated with this account
* @see https://www.deepcoin.com/docs/assets/chainlist
* @param {string} code unified currency code
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {string} [params.network] unified network code for deposit chain
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
*/
async fetchDepositAddress(code, params = {}) {
await this.loadMarkets();
let network = this.safeString(params, 'network');
const defaultNetworks = this.safeDict(this.options, 'defaultNetworks', {});
const defaultNetwork = this.safeString(defaultNetworks, code);
network = network ? network : defaultNetwork;
if (network !== undefined) {
params = this.omit(params, 'network');
}
const addressess = await this.fetchDepositAddresses([code], params);
const length = addressess.length;
let address = this.safeDict(addre