ccxt
Version:
1,066 lines (1,064 loc) • 102 kB
JavaScript
'use strict';
var kuna$1 = require('./abstract/kuna.js');
var errors = require('./base/errors.js');
var number = require('./base/functions/number.js');
var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
var sha512 = require('./static_dependencies/noble-hashes/sha512.js');
var Precise = require('./base/Precise.js');
// ----------------------------------------------------------------------------
// ---------------------------------------------------------------------------
/**
* @class kuna
* @augments Exchange
* @description Use the public-key as your apiKey
*/
class kuna extends kuna$1 {
describe() {
return this.deepExtend(super.describe(), {
'id': 'kuna',
'name': 'Kuna',
'countries': ['UA'],
'rateLimit': 1000,
'version': 'v4',
'has': {
'CORS': undefined,
'spot': true,
'margin': false,
'swap': false,
'future': false,
'option': false,
'addMargin': false,
'cancelOrder': true,
'cancelOrders': true,
'closeAllPositions': false,
'closePosition': false,
'createDepositAddress': true,
'createOrder': true,
'createPostOnlyOrder': false,
'createReduceOnlyOrder': false,
'createStopLimitOrder': true,
'createStopMarketOrder': false,
'createStopOrder': true,
'fetchBalance': true,
'fetchBorrowInterest': false,
'fetchBorrowRateHistories': false,
'fetchBorrowRateHistory': false,
'fetchClosedOrders': true,
'fetchCrossBorrowRate': false,
'fetchCrossBorrowRates': false,
'fetchCurrencies': true,
'fetchDeposit': true,
'fetchDepositAddress': true,
'fetchDepositAddresses': false,
'fetchDepositAddressesByNetwork': false,
'fetchDeposits': true,
'fetchDepositsWithdrawals': false,
'fetchFundingHistory': false,
'fetchFundingRate': false,
'fetchFundingRateHistory': false,
'fetchFundingRates': false,
'fetchIndexOHLCV': false,
'fetchIsolatedBorrowRate': false,
'fetchIsolatedBorrowRates': false,
'fetchIsolatedPositions': false,
'fetchL3OrderBook': true,
'fetchLeverage': false,
'fetchLeverageTiers': false,
'fetchMarginMode': false,
'fetchMarketLeverageTiers': false,
'fetchMarkets': true,
'fetchMarkOHLCV': false,
'fetchMyTrades': true,
'fetchOHLCV': false,
'fetchOpenInterest': false,
'fetchOpenInterestHistory': false,
'fetchOpenOrders': true,
'fetchOrder': true,
'fetchOrderBook': true,
'fetchOrdersByStatus': true,
'fetchPosition': false,
'fetchPositionMode': false,
'fetchPositions': false,
'fetchPositionsForSymbol': false,
'fetchPositionsRisk': false,
'fetchPremiumIndexOHLCV': false,
'fetchTicker': true,
'fetchTickers': true,
'fetchTime': true,
'fetchTrades': true,
'fetchTradingFee': false,
'fetchTradingFees': false,
'fetchTransactions': false,
'fetchTransfers': false,
'fetchWithdrawAddresses': false,
'fetchWithdrawal': true,
'fetchWithdrawals': true,
'reduceMargin': false,
'repayCrossMargin': false,
'repayIsolatedMargin': false,
'setLeverage': false,
'setMargin': false,
'setMarginMode': false,
'setPositionMode': false,
'signIn': false,
'transfer': false,
'withdraw': true,
},
'timeframes': undefined,
'urls': {
'extension': '.json',
'referral': 'https://kuna.io?r=kunaid-gvfihe8az7o4',
'logo': 'https://user-images.githubusercontent.com/51840849/87153927-f0578b80-c2c0-11ea-84b6-74612568e9e1.jpg',
'api': {
'xreserve': 'https://api.xreserve.fund',
'v3': 'https://api.kuna.io',
'v4': 'https://api.kuna.io',
'public': 'https://kuna.io',
'private': 'https://kuna.io', // v2
},
'www': 'https://kuna.io',
'doc': 'https://kuna.io/documents/api',
'fees': 'https://kuna.io/documents/api',
},
'api': {
'xreserve': {
'get': {
'nonce': 1,
'fee': 1,
'delegated-transactions': 1,
},
'post': {
'delegate-transfer': 1,
},
},
'v4': {
'private': {
'get': {
'private/me': 1,
'private/getBalance': 1,
'order/private/active': 1,
'order/private/history': 1,
'order/private/{id}/trades': 1,
'order/private/details/{id}': 1,
'trade/private/history': 1,
'transaction/private/{hash}': 1,
'deposit/private/preRequest': 1,
'deposit/private/crypto/address': 1,
'deposit/private/crypto/getMerchantAddress': 1,
'deposit/private/history': 1,
'deposit/private/details/{depositId}': 1,
'withdraw/private/preRequest': 1,
'withdraw/private/history': 1,
'withdraw/private/details/{withdrawId}': 1,
'kuna-code/{id}': 1,
'kuna-code/{code}/check': 1,
'kuna-code/issued-by-me': 1,
'kuna-code/redeemed-by-me': 1,
},
'post': {
'order/private/create': 1,
'order/private/cancel': 1,
'order/private/cancel/multi': 1,
'deposit/private/crypto/generateAddress': 1,
'deposit/private/crypto/generateMerchantAddress': 1,
'withdraw/private/create': 1,
'kuna-code': 1,
},
'put': {
'kuna-code/redeem': 1,
},
},
'public': {
'get': {
'public/timestamp': 1,
'public/fees': 1,
'public/currencies?type={type}': 1,
'public/currencies': 1,
'markets/public/getAll': 1,
'markets/public/tickers?pairs={pairs}': 1,
'order/public/book/{pairs}': 1,
'trade/public/book/{pairs}': 1,
},
},
},
'v3': {
'public': {
'get': {
'timestamp': 1,
'currencies': 1,
'markets': 1,
'tickers': 1,
'k': 1,
'trades_history': 1,
'fees': 1,
'exchange-rates': 1,
'exchange-rates/currency': 1,
'book/market': 1,
'kuna_codes/code/check': 1,
'landing_page_statistic': 1,
'translations/locale': 1,
'trades/market/hist': 1,
},
'post': {
'http_test': 1,
'deposit_channels': 1,
'withdraw_channels': 1,
'subscription_plans': 1,
'send_to': 1,
'confirm_token': 1,
'kunaid': 1,
'withdraw/prerequest': 1,
'deposit/prerequest': 1,
'deposit/exchange-rates': 1,
},
},
'sign': {
'get': {
'reset_password/token': 1,
},
'post': {
'signup/google': 1,
'signup/resend_confirmation': 1,
'signup': 1,
'signin': 1,
'signin/two_factor': 1,
'signin/resend_confirm_device': 1,
'signin/confirm_device': 1,
'reset_password': 1,
'cool-signin': 1,
},
'put': {
'reset_password/token': 1,
'signup/code/confirm': 1,
},
},
'private': {
'post': {
'auth/w/order/submit': 1,
'auth/r/orders': 1,
'auth/r/orders/market': 1,
'auth/r/orders/markets': 1,
'auth/api_tokens/delete': 1,
'auth/api_tokens/create': 1,
'auth/api_tokens': 1,
'auth/signin_history/uniq': 1,
'auth/signin_history': 1,
'auth/disable_withdraw_confirmation': 1,
'auth/change_password': 1,
'auth/deposit_address': 1,
'auth/announcements/accept': 1,
'auth/announcements/unaccepted': 1,
'auth/otp/deactivate': 1,
'auth/otp/activate': 1,
'auth/otp/secret': 1,
'auth/r/order/market/:order_id/trades': 1,
'auth/r/orders/market/hist': 1,
'auth/r/orders/hist': 1,
'auth/r/orders/hist/markets': 1,
'auth/r/orders/details': 1,
'auth/assets-history': 1,
'auth/assets-history/withdraws': 1,
'auth/assets-history/deposits': 1,
'auth/r/wallets': 1,
'auth/markets/favorites': 1,
'auth/markets/favorites/list': 1,
'auth/me/update': 1,
'auth/me': 1,
'auth/fund_sources': 1,
'auth/fund_sources/list': 1,
'auth/withdraw/resend_confirmation': 1,
'auth/withdraw': 1,
'auth/withdraw/details': 1,
'auth/withdraw/info': 1,
'auth/payment_addresses': 1,
'auth/deposit/prerequest': 1,
'auth/deposit/exchange-rates': 1,
'auth/deposit': 1,
'auth/deposit/details': 1,
'auth/deposit/info': 1,
'auth/kuna_codes/count': 1,
'auth/kuna_codes/details': 1,
'auth/kuna_codes/edit': 1,
'auth/kuna_codes/send-pdf': 1,
'auth/kuna_codes': 1,
'auth/kuna_codes/redeemed-by-me': 1,
'auth/kuna_codes/issued-by-me': 1,
'auth/payment_requests/invoice': 1,
'auth/payment_requests/type': 1,
'auth/referral_program/weekly_earnings': 1,
'auth/referral_program/stats': 1,
'auth/merchant/payout_services': 1,
'auth/merchant/withdraw': 1,
'auth/merchant/payment_services': 1,
'auth/merchant/deposit': 1,
'auth/verification/auth_token': 1,
'auth/kunaid_purchase/create': 1,
'auth/devices/list': 1,
'auth/sessions/list': 1,
'auth/subscriptions/reactivate': 1,
'auth/subscriptions/cancel': 1,
'auth/subscriptions/prolong': 1,
'auth/subscriptions/create': 1,
'auth/subscriptions/list': 1,
'auth/kuna_ids/list': 1,
'order/cancel/multi': 1,
'order/cancel': 1,
},
'put': {
'auth/fund_sources/id': 1,
'auth/kuna_codes/redeem': 1,
},
'delete': {
'auth/markets/favorites': 1,
'auth/fund_sources': 1,
'auth/devices': 1,
'auth/devices/list': 1,
'auth/sessions/list': 1,
'auth/sessions': 1,
},
},
},
'public': {
'get': [
'depth',
'k_with_pending_trades',
'k',
'markets',
'order_book',
'order_book/{market}',
'tickers',
'tickers/{market}',
'timestamp',
'trades',
'trades/{market}',
],
},
'private': {
'get': [
'members/me',
'deposits',
'deposit',
'deposit_address',
'orders',
'order',
'trades/my',
'withdraws',
'withdraw', // Get your cryptocurrency withdraw
],
'post': [
'orders',
'orders/multi',
'orders/clear',
'order/delete',
'withdraw', // Create a withdraw
],
},
},
'features': {
'spot': {
'sandbox': false,
'createOrder': {
'marginMode': false,
'triggerPrice': true,
'triggerPriceType': undefined,
'triggerDirection': false,
'stopLossPrice': false,
'takeProfitPrice': false,
'attachedStopLossTakeProfit': undefined,
'timeInForce': {
'IOC': false,
'FOK': false,
'PO': false,
'GTD': false,
},
'hedged': false,
'selfTradePrevention': false,
'trailing': false,
'leverage': false,
'marketBuyByCost': true,
'marketBuyRequiresPrice': false,
'iceberg': false,
},
'createOrders': undefined,
'fetchMyTrades': undefined,
'fetchOrder': {
'marginMode': false,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOpenOrders': {
'marginMode': false,
'limit': 100,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOrders': undefined,
'fetchClosedOrders': {
'marginMode': false,
'limit': 100,
'daysBack': 100000,
'daysBackCanceled': 1,
'untilDays': 14,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOHLCV': undefined,
},
'swap': {
'linear': undefined,
'inverse': undefined,
},
'future': {
'linear': undefined,
'inverse': undefined,
},
},
'fees': {
'trading': {
'tierBased': false,
'percentage': true,
'taker': this.parseNumber('0.0025'),
'maker': this.parseNumber('0.0025'),
},
'funding': {
'withdraw': {
'UAH': '1%',
'BTC': 0.001,
'BCH': 0.001,
'ETH': 0.01,
'WAVES': 0.01,
'GOL': 0.0,
'GBG': 0.0,
// 'RMC': 0.001 BTC
// 'ARN': 0.01 ETH
// 'R': 0.01 ETH
// 'EVR': 0.01 ETH
},
'deposit': {
// 'UAH': (amount) => amount * 0.001 + 5
},
},
},
'commonCurrencies': {
'PLA': 'Plair',
},
'precisionMode': number.TICK_SIZE,
'exceptions': {
'ARGUMENT_VALIDATION_ERROR': errors.BadRequest,
'PAYMENT_METHOD_NOT_SUPPORTED': errors.BadRequest,
'NOT_FOUND': errors.OrderNotFound,
'INVALID:ORDER_SIZE': errors.InvalidOrder,
'WrongRequestException': errors.BadRequest,
'INSUFFICIENT_FUNDS': errors.InsufficientFunds,
'2002': errors.InsufficientFunds,
'2003': errors.OrderNotFound,
},
'options': {
// 'account': 'pro' // Only for pro accounts
},
});
}
/**
* @method
* @name kuna#fetchTime
* @description fetches the current integer timestamp in milliseconds from the exchange server
* @see https://docs.kuna.io/docs/get-time-on-the-server
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {int} the current integer timestamp in milliseconds from the exchange server
*/
async fetchTime(params = {}) {
const response = await this.v4PublicGetPublicTimestamp(params);
//
// {
// "data": {
// "timestamp": 1686740531,
// "timestamp_miliseconds": 1686740531725,
// }
// }
//
const data = this.safeValue(response, 'data', {});
return this.safeInteger(data, 'timestamp_miliseconds');
}
/**
* @method
* @name kuna#fetchCurrencies
* @description fetches all available currencies on an exchange
* @see https://docs.kuna.io/docs/get-information-about-available-currencies
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} an associative dictionary of currencies
*/
async fetchCurrencies(params = {}) {
const response = await this.v4PublicGetPublicCurrencies(params);
//
// {
// "data": [
// {
// "code": "BTC",
// "name": "Bitcoin",
// "payload": {
// "chart": "https://kuna-pro.kuna.io/bitcoin-chart",
// "icons": {
// "svg": "https://kuna-pro.kuna.io/icon-btc-svg",
// "png2x": "https://kuna-pro.kuna.io/icon-btc-png2x",
// "png3x": "https://kuna-pro.kuna.io/icon-btc-png3x",
// "svgXL": "https://kuna-pro.kuna.io/icon-btc-svg"
// },
// "pngChart": "https://kuna-pro.kuna.io/png-bitcoin-chart"
// },
// "position": 1,
// "precision": 8,
// "tradePrecision": 6,
// "type": "Crypto"
// }
// ]
// }
//
const data = this.safeValue(response, 'data', []);
return this.parseCurrencies(data);
}
parseCurrency(currency) {
//
// {
// "code": "BTC",
// "name": "Bitcoin",
// "payload": {
// "chart": "https://kuna-pro.kuna.io/bitcoin-chart",
// "icons": {
// "svg": "https://kuna-pro.kuna.io/icon-btc-svg",
// "png2x": "https://kuna-pro.kuna.io/icon-btc-png2x",
// "png3x": "https://kuna-pro.kuna.io/icon-btc-png3x",
// "svgXL": "https://kuna-pro.kuna.io/icon-btc-svg"
// },
// "pngChart": "https://kuna-pro.kuna.io/png-bitcoin-chart"
// },
// "position": 1,
// "precision": 8,
// "tradePrecision": 6,
// "type": "Crypto"
// }
//
const currencyId = this.safeString(currency, 'code');
const precision = this.safeString(currency, 'precision');
const tradePrecision = this.safeString(currency, 'tradePrecision');
return this.safeCurrencyStructure({
'info': currency,
'id': currencyId,
'code': this.safeCurrencyCode(currencyId),
'type': undefined,
'margin': undefined,
'name': this.safeString(currency, 'name'),
'active': undefined,
'deposit': undefined,
'withdraw': undefined,
'fee': undefined,
'precision': this.parseNumber(Precise["default"].stringMin(precision, tradePrecision)),
'limits': {
'amount': {
'min': undefined,
'max': undefined,
},
'withdraw': {
'min': undefined,
'max': undefined,
},
},
'networks': {},
});
}
/**
* @method
* @name kuna#fetchMarkets
* @description retrieves data on all markets for kuna
* @see https://docs.kuna.io/docs/get-all-traded-markets
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object[]} an array of objects representing market data
*/
async fetchMarkets(params = {}) {
const response = await this.v4PublicGetMarketsPublicGetAll(params);
//
// {
// "data": [
// {
// "pair": "BTC_USDT", // Traded pair of assets
// "baseAsset": { // The base asset of the traded pair, the one to sell or buy as a result of the trade
// "code": "BTC",
// "precision": 6 // Maximum amount of digits for the decimal part of a number
// },
// "quoteAsset": { // The quoted asset of the traded pair, the one to use to sell or buy the base asset
// "code": "USDT",
// "precision": 2 // Maximum amount of digits for the decimal part of a number
// },
// "tickerPriceChange": "-0.07" // Relative change compared with the last tick
// }
// ]
// }
//
const data = this.safeValue(response, 'data', []);
const markets = [];
for (let i = 0; i < data.length; i++) {
const item = data[i];
const marketId = this.safeString(item, 'pair');
const baseAsset = this.safeValue(item, 'baseAsset');
const quoteAsset = this.safeValue(item, 'quoteAsset');
const baseId = this.safeString(baseAsset, 'code');
const quoteId = this.safeString(quoteAsset, 'code');
const base = this.safeCurrencyCode(baseId);
const quote = this.safeCurrencyCode(quoteId);
const basePrecision = this.safeString(baseAsset, 'precision');
const quotePrecision = this.safeString(quoteAsset, 'precision');
markets.push({
'id': marketId,
'symbol': base + '/' + quote,
'base': base,
'quote': quote,
'settle': undefined,
'baseId': baseId,
'quoteId': quoteId,
'settleId': undefined,
'type': 'spot',
'spot': true,
'margin': false,
'swap': false,
'future': false,
'option': false,
'active': undefined,
'contract': false,
'linear': undefined,
'inverse': undefined,
'contractSize': undefined,
'expiry': undefined,
'expiryDatetime': undefined,
'strike': undefined,
'optionType': undefined,
'precision': {
'amount': this.parseNumber(this.parsePrecision(basePrecision)),
'price': this.parseNumber(this.parsePrecision(quotePrecision)),
},
'limits': {
'leverage': {
'min': undefined,
'max': undefined,
},
'amount': {
'min': undefined,
'max': undefined,
},
'price': {
'min': undefined,
'max': undefined,
},
'cost': {
'min': undefined,
'max': undefined,
},
},
'created': undefined,
'info': item,
});
}
return markets;
}
/**
* @method
* @name kuna#fetchOrderBook
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
* @see https://docs.kuna.io/docs/get-public-orders-book
* @param {string} symbol unified symbol of the market to fetch the order book for
* @param {int} [limit] 5, 10, 20, 50, 100, 500, or 1000 (default)
* @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);
const request = {
'pairs': market['id'],
};
if (limit !== undefined) {
request['level'] = limit;
}
const response = await this.v4PublicGetOrderPublicBookPairs(this.extend(request, params));
//
// {
// "data": {
// "asks": [ // An array of sell orders
// [
// "16950", // Sell price, level 1
// "0.001" // Sell quantity, level 1
// ],
// [
// "17000", // Sell price, level 2
// "0.01" // Sell quantity, level 2
// ]
// ],
// "bids": [ // An array of buy orders
// [
// "16700", // Sell price, level 1
// "0.01" // Sell quantity, level 1
// ],
// [
// "16000", // Sell price, level 2
// "0.001" // Sell quantity, level 2
// ]
// ]
// }
// }
//
const data = this.safeDict(response, 'data', {});
return this.parseOrderBook(data, market['symbol'], undefined, 'bids', 'asks', 0, 1);
}
parseTicker(ticker, market = undefined) {
//
// {
// "pair": "BTC_USDT", // Traded pair
// "percentagePriceChange": "-0.03490931899641581", // Relative price change, in percent
// "price": "27900", // Current median price
// "equivalentPrice": "", // TBD
// "high": "29059.69", // Highest price
// "low": "27900", // Lowest price
// "baseVolume": "2.9008499999999993", // Traded volume as base
// "quoteVolume": "82251.41477976", // Traded volume as quote
// "bestBidPrice": "27926.91", // The best bid price now
// "bestAskPrice": "27970.02", // The best ask price now
// "priceChange": "-973.9700000000012" // Absolute price change
// }
//
const marketId = this.safeString(ticker, 'pair');
return this.safeTicker({
'info': ticker,
'symbol': this.safeSymbol(marketId, market),
'timestamp': undefined,
'datetime': undefined,
'high': this.safeString(ticker, 'high'),
'low': this.safeString(ticker, 'low'),
'bid': this.safeString(ticker, 'bestBidPrice'),
'ask': this.safeString(ticker, 'bestAskPrice'),
'vwap': undefined,
'open': this.safeString(ticker, 'open'),
'close': undefined,
'last': undefined,
'previousClose': undefined,
'change': this.safeString(ticker, 'priceChange'),
'percentage': this.safeString(ticker, 'percentagePriceChange'),
'average': undefined,
'baseVolume': this.safeString(ticker, 'baseVolume'),
'quoteVolume': this.safeString(ticker, 'quoteVolume'),
}, market);
}
/**
* @method
* @name kuna#fetchTickers
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market. The average is not returned in the response, but the median can be accessed via response['info']['price']
* @see https://docs.kuna.io/docs/get-market-info-by-tickers
* @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();
if (symbols === undefined) {
throw new errors.ArgumentsRequired(this.id + ' fetchTickers () requires a symbols argument');
}
symbols = this.marketSymbols(symbols);
const marketIds = this.marketIds(symbols);
const request = {
'pairs': marketIds.join(','),
};
const response = await this.v4PublicGetMarketsPublicTickersPairsPairs(this.extend(request, params));
//
// {
// "data": [
// {
// "pair": "BTC_USDT", // Traded pair
// "percentagePriceChange": "-0.03490931899641581", // Relative price change, in percent
// "price": "27900", // Current median price
// "equivalentPrice": "", // TBD
// "high": "29059.69", // Highest price
// "low": "27900", // Lowest price
// "baseVolume": "2.9008499999999993", // Traded volume as base
// "quoteVolume": "82251.41477976", // Traded volume as quote
// "bestBidPrice": "27926.91", // The best bid price now
// "bestAskPrice": "27970.02", // The best ask price now
// "priceChange": "-973.9700000000012" // Absolute price change
// }
// ...
// ]
// }
//
const data = this.safeList(response, 'data', []);
return this.parseTickers(data, symbols, params);
}
/**
* @method
* @name kuna#fetchTicker
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
* @see https://docs.kuna.io/docs/get-market-info-by-tickers
* @param {string} symbol unified symbol of the market to fetch the ticker for
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
*/
async fetchTicker(symbol, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const request = {
'pairs': market['id'],
};
const response = await this.v4PublicGetMarketsPublicTickersPairsPairs(this.extend(request, params));
//
// {
// "data": [
// {
// "pair": "BTC_USDT", // Traded pair
// "percentagePriceChange": "-0.03490931899641581", // Relative price change, in percent
// "price": "27900", // Current median price
// "equivalentPrice": "", // TBD
// "high": "29059.69", // Highest price
// "low": "27900", // Lowest price
// "baseVolume": "2.9008499999999993", // Traded volume as base
// "quoteVolume": "82251.41477976", // Traded volume as quote
// "bestBidPrice": "27926.91", // The best bid price now
// "bestAskPrice": "27970.02", // The best ask price now
// "priceChange": "-973.9700000000012" // Absolute price change
// }
// ...
// ]
// }
//
const data = this.safeValue(response, 'data', []);
const ticker = this.safeDict(data, 0);
return this.parseTicker(ticker, market);
}
/**
* TODO: double check
* @method
* @name kuna#fetchL3OrderBook
* @description fetches level 3 information on open orders with bid (buy) and ask (sell) prices, volumes and other data
* @param {string} symbol unified market symbol
* @param {int} [limit] max number of orders to return, default is undefined
* @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 fetchL3OrderBook(symbol, limit = undefined, params = {}) {
return await this.fetchOrderBook(symbol, limit, params);
}
/**
* @method
* @name kuna#fetchTrades
* @description get the list of most recent trades for a particular symbol
* @see https://docs.kuna.io/docs/get-public-trades-book
* @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] between 1 and 100, 25 by default
* @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 = {
'pairs': market['id'],
};
if (limit !== undefined) {
request['limit'] = limit;
}
const response = await this.v4PublicGetTradePublicBookPairs(this.extend(request, params));
//
// {
// 'data': [
// {
// 'createdAt': '2024-03-02T00:10:49.385Z',
// 'id': '3b42878a-3688-4bc1-891e-5cc2fc902142',
// 'matchPrice': '62181.31',
// 'matchQuantity': '0.00568',
// 'pair': 'BTC_USDT',
// 'quoteQuantity': '353.1898408',
// 'side': 'Bid'
// },
// ...
// ]
// }
//
const data = this.safeList(response, 'data', []);
return this.parseTrades(data, market, since, limit);
}
parseTrade(trade, market = undefined) {
//
// fetchTrades (public)
//
// {
// "id": "3e5591ba-2778-4d85-8851-54284045ea44", // Unique identifier of a trade
// "pair": "BTC_USDT", // Market pair that is being traded
// "quoteQuantity": "11528.8118", // Qty of the quote asset, USDT in this example
// "matchPrice": "18649", // Exchange price at the moment of execution
// "matchQuantity": "0.6182", // Qty of the base asset, BTC in this example
// "createdAt": "2022-09-23T14:30:41.486Z", // Date-time of trade execution, UTC
// "side": "Ask" // Trade type: `Ask` or `Bid`. Bid for buying base asset, Ask for selling base asset (e.g. for BTC_USDT trading pair, BTC is the base asset).
// }
//
// fetchMyTrades, fetchOrder (private)
//
// {
// "id": "edb17459-c9bf-4148-9ae6-7367d7f55d71", // Unique identifier of a trade
// "orderId": "a80bec3f-4ffa-45c1-9d78-f6301e9748fe", // Unique identifier of an order associated with the trade
// "pair": "BTC_USDT", // Traded pair, base asset first, followed by quoted asset
// "quantity": "1.5862", // Traded quantity of base asset
// "price": "19087", // Price of the trade
// "isTaker": true, // Various fees for Makers and Takers; "Market" orders are always `true`
// "fee": "0.0039655", // Exchange commission fee
// "feeCurrency": "BTC", // Currency of the commission
// "isBuyer": true, // Buy or sell the base asset
// "quoteQuantity": "30275.7994", // Quote asset quantity spent to fulfill the base amount
// "createdAt": "2022-09-29T13:43:53.824Z", // Date-time of trade execution, UTC
// }
//
const datetime = this.safeString(trade, 'createdAt');
const marketId = this.safeString(trade, 'pair');
const isTaker = this.safeValue(trade, 'isMaker');
let side = this.safeStringLower(trade, 'side');
if (side === undefined) {
const isBuyer = this.safeValue(trade, 'isBuyer');
side = isBuyer ? 'buy' : 'sell';
}
return this.safeTrade({
'info': trade,
'id': this.safeString(trade, 'id'),
'symbol': this.safeSymbol(marketId, market),
'timestamp': this.parse8601(datetime),
'datetime': datetime,
'type': undefined,
'side': side,
'order': this.safeString(trade, 'orderId'),
'takerOrMaker': isTaker ? 'taker' : 'maker',
'price': this.safeString2(trade, 'matchPrice', 'price'),
'amount': this.safeString2(trade, 'matchQuantity', 'quantity'),
'cost': this.safeString(trade, 'quoteQuantity'),
'fee': {
'cost': this.safeString(trade, 'fee'),
'currency': this.safeCurrencyCode(this.safeString(trade, 'feeCurrency')),
},
}, market);
}
parseBalance(response) {
//
// [
// {
// "currency": "UAH",
// "balance": "7134.6",
// "lockBalance": "100"
// }
// ...
// ]
//
const result = { 'info': response };
for (let i = 0; i < response.length; i++) {
const balance = response[i];
const currencyId = this.safeString(balance, 'currency');
const code = this.safeCurrencyCode(currencyId);
const account = this.account();
account['free'] = this.safeString(balance, 'balance');
account['used'] = this.safeString(balance, 'lockBalance');
result[code] = account;
}
return this.safeBalance(result);
}
/**
* @method
* @name kuna#fetchBalance
* @description query for balance and get the amount of funds available for trading or funds locked in orders
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
*/
async fetchBalance(params = {}) {
await this.loadMarkets();
const response = await this.v4PrivateGetPrivateGetBalance(params);
//
// {
// "data": [{
// "currency": "UAH", // Wallet currency
// "balance": "7134.6", // Available balance, precision depends on the currency
// "lockBalance": "100" // Minimum amount locked on the balance
// }]
// }
//
const data = this.safeValue(response, 'data', []);
return this.parseBalance(data);
}
/**
* @method
* @name kuna#createOrder
* @description create a trade order
* @see https://docs.kuna.io/docs/create-a-new-order-private
* @param {string} symbol unified symbol of the market to create an order in
* @param {string} type 'market' or 'limit'
* @param {string} side 'buy' or 'sell'
* @param {float} amount how much of currency you want to trade in units of base currency
* @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {float} [params.triggerPrice] the price at which a trigger order is triggered at
*
* EXCHANGE SPECIFIC PARAMETERS
* @param {string} [params.id] id must be a UUID format, if you do not specify id, it will be generated automatically.
* @param {float} [params.quoteQuantity] the max quantity of the quote asset to use for selling/buying
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const triggerPrice = this.safeString2(params, 'triggerPrice', 'stopPrice');
params = this.omit(params, ['triggerPrice', 'stopPrice']);
const capitalizedType = this.capitalize(type);
const request = {
'pair': market['id'],
'orderSide': (side === 'buy') ? 'Bid' : 'Ask',
'quantity': this.numberToString(amount),
'type': capitalizedType,
};
if (capitalizedType === 'Limit') {
request['price'] = this.priceToPrecision(market['symbol'], price);
}
if (triggerPrice !== undefined) {
if (capitalizedType === 'Market') {
throw new errors.BadRequest(this.id + ' createOrder () cannot place trigger market orders, or trigger limit');
}
request['stopPrice'] = this.priceToPrecision(market['symbol'], triggerPrice);
if (capitalizedType !== 'TakeProfitLimit') {
request['type'] = 'StopLossLimit';
}
}
const response = await this.v4PrivatePostOrderPrivateCreate(this.extend(request, params));
//
// {
// "data": {
// "id": "b0fcb54c-2278-4f16-a300-02765faad8b0", // ID of your newly created order
// "type": "Limit", // Type of an order
// "quantity": "0.06", // Original order quantity
// "executedQuantity": "0", // Traded quantity in stock (>0 if traded)
// "pair": "BTC_USDT", // Traded pair
// "price": "26440.46", // Price of the trade
// "status": "Open", // The status of the order
// "createdAt": "2023-07-11T08:01:30.550Z", // Date-time of order creation, UTC
// "updatedAt": "2023-07-11T08:01:30.550Z" // Date-time of the last update of the order, UTC
// }
// }
//
const data = this.safeDict(response, 'data', {});
return this.parseOrder(data, market);
}
/**
* @method
* @name kuna#cancelOrder
* @description cancels an open order
* @param {string} id order id
* @param {string} symbol unified market symbol
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
async cancelOrder(id, symbol = undefined, params = {}) {
await this.loadMarkets();
const request = {
'orderId': id,
};
const response = await this.v4