UNPKG

@proton/ccxt

Version:

A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 130+ exchanges

920 lines (917 loc) 38.3 kB
// ---------------------------------------------------------------------------- // 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 Exchange from './abstract/btcturk.js'; import { BadRequest, ExchangeError, InsufficientFunds, InvalidOrder } from './base/errors.js'; import { Precise } from './base/Precise.js'; import { TICK_SIZE } from './base/functions/number.js'; import { sha256 } from './static_dependencies/noble-hashes/sha256.js'; // --------------------------------------------------------------------------- export default class btcturk extends Exchange { describe() { return this.deepExtend(super.describe(), { 'id': 'btcturk', 'name': 'BTCTurk', 'countries': ['TR'], 'rateLimit': 100, 'has': { 'CORS': true, 'spot': true, 'margin': false, 'swap': false, 'future': false, 'option': false, 'addMargin': false, 'cancelOrder': true, 'createOrder': true, 'createReduceOnlyOrder': false, 'fetchBalance': true, 'fetchBorrowRate': false, 'fetchBorrowRateHistories': false, 'fetchBorrowRateHistory': false, 'fetchBorrowRates': false, 'fetchBorrowRatesPerSymbol': false, 'fetchFundingHistory': false, 'fetchFundingRate': false, 'fetchFundingRateHistory': false, 'fetchFundingRates': false, 'fetchIndexOHLCV': false, 'fetchLeverage': false, 'fetchMarginMode': false, 'fetchMarkets': true, 'fetchMarkOHLCV': false, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenInterestHistory': false, 'fetchOpenOrders': true, 'fetchOrderBook': true, 'fetchOrders': true, 'fetchPosition': false, 'fetchPositionMode': false, 'fetchPositions': false, 'fetchPositionsRisk': false, 'fetchPremiumIndexOHLCV': false, 'fetchTicker': true, 'fetchTickers': true, 'fetchTrades': true, 'reduceMargin': false, 'setLeverage': false, 'setMarginMode': false, 'setPositionMode': false, }, 'timeframes': { '1m': 1, '15m': 15, '30m': 30, '1h': 60, '4h': 240, '1d': '1 day', '1w': '1 week', '1y': '1 year', }, 'urls': { 'logo': 'https://user-images.githubusercontent.com/51840849/87153926-efbef500-c2c0-11ea-9842-05b63612c4b9.jpg', 'api': { 'public': 'https://api.btcturk.com/api/v2', 'private': 'https://api.btcturk.com/api/v1', 'graph': 'https://graph-api.btcturk.com/v1', }, 'www': 'https://www.btcturk.com', 'doc': 'https://github.com/BTCTrader/broker-api-docs', }, 'api': { 'public': { 'get': { 'orderbook': 1, 'ticker': 0.1, 'trades': 1, 'server/exchangeinfo': 1, }, }, 'private': { 'get': { 'users/balances': 1, 'openOrders': 1, 'allOrders': 1, 'users/transactions/trade': 1, }, 'post': { 'order': 1, 'cancelOrder': 1, }, 'delete': { 'order': 1, }, }, 'graph': { 'get': { 'ohlcs': 1, 'klines/history': 1, }, }, }, 'fees': { 'trading': { 'maker': this.parseNumber('0.0005'), 'taker': this.parseNumber('0.0009'), }, }, 'exceptions': { 'exact': { 'FAILED_ORDER_WITH_OPEN_ORDERS': InsufficientFunds, 'FAILED_LIMIT_ORDER': InvalidOrder, 'FAILED_MARKET_ORDER': InvalidOrder, }, }, 'precisionMode': TICK_SIZE, }); } async fetchMarkets(params = {}) { /** * @method * @name btcturk#fetchMarkets * @description retrieves data on all markets for btcturk * @param {object} params extra parameters specific to the exchange api endpoint * @returns {[object]} an array of objects representing market data */ const response = await this.publicGetServerExchangeinfo(params); // // { // "data": { // "timeZone": "UTC", // "serverTime": "1618826678404", // "symbols": [ // { // "id": "1", // "name": "BTCTRY", // "nameNormalized": "BTC_TRY", // "status": "TRADING", // "numerator": "BTC", // "denominator": "TRY", // "numeratorScale": "8", // "denominatorScale": "2", // "hasFraction": false, // "filters": [ // { // "filterType": "PRICE_FILTER", // "minPrice": "0.0000000000001", // "maxPrice": "10000000", // "tickSize": "10", // "minExchangeValue": "99.91", // "minAmount": null, // "maxAmount": null // } // ], // "orderMethods": [ // "MARKET", // "LIMIT", // "STOP_MARKET", // "STOP_LIMIT" // ], // "displayFormat": "#,###", // "commissionFromNumerator": false, // "order": "1000", // "priceRounding": false // }, // ... // }, // ], // } // const data = this.safeValue(response, 'data'); const markets = this.safeValue(data, 'symbols', []); const result = []; for (let i = 0; i < markets.length; i++) { const entry = markets[i]; const id = this.safeString(entry, 'name'); const baseId = this.safeString(entry, 'numerator'); const quoteId = this.safeString(entry, 'denominator'); const base = this.safeCurrencyCode(baseId); const quote = this.safeCurrencyCode(quoteId); const filters = this.safeValue(entry, 'filters', []); let minPrice = undefined; let maxPrice = undefined; let minAmount = undefined; let maxAmount = undefined; let minCost = undefined; for (let j = 0; j < filters.length; j++) { const filter = filters[j]; const filterType = this.safeString(filter, 'filterType'); if (filterType === 'PRICE_FILTER') { minPrice = this.safeNumber(filter, 'minPrice'); maxPrice = this.safeNumber(filter, 'maxPrice'); minAmount = this.safeNumber(filter, 'minAmount'); maxAmount = this.safeNumber(filter, 'maxAmount'); minCost = this.safeNumber(filter, 'minExchangeValue'); } } const status = this.safeString(entry, 'status'); result.push({ 'id': id, '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': (status === 'TRADING'), 'contract': false, 'linear': undefined, 'inverse': undefined, 'contractSize': undefined, 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'amount': this.parseNumber(this.parsePrecision(this.safeString(entry, 'numeratorScale'))), 'price': this.parseNumber(this.parsePrecision(this.safeString(entry, 'denominatorScale'))), }, 'limits': { 'leverage': { 'min': undefined, 'max': undefined, }, 'amount': { 'min': minAmount, 'max': maxAmount, }, 'price': { 'min': minPrice, 'max': maxPrice, }, 'cost': { 'min': minCost, 'max': undefined, }, }, 'info': entry, }); } return result; } parseBalance(response) { const data = this.safeValue(response, 'data', []); const result = { 'info': response, 'timestamp': undefined, 'datetime': undefined, }; for (let i = 0; i < data.length; i++) { const entry = data[i]; const currencyId = this.safeString(entry, 'asset'); const code = this.safeCurrencyCode(currencyId); const account = this.account(); account['total'] = this.safeString(entry, 'balance'); account['free'] = this.safeString(entry, 'free'); account['used'] = this.safeString(entry, 'locked'); result[code] = account; } return this.safeBalance(result); } async fetchBalance(params = {}) { /** * @method * @name btcturk#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 btcturk api endpoint * @returns {object} a [balance structure]{@link https://docs.ccxt.com/en/latest/manual.html?#balance-structure} */ await this.loadMarkets(); const response = await this.privateGetUsersBalances(params); // // { // "data": [ // { // "asset": "TRY", // "assetname": "Türk Lirası", // "balance": "0", // "locked": "0", // "free": "0", // "orderFund": "0", // "requestFund": "0", // "precision": 2 // } // ] // } // return this.parseBalance(response); } async fetchOrderBook(symbol, limit = undefined, params = {}) { /** * @method * @name btcturk#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @param {string} symbol unified symbol of the market to fetch the order book for * @param {int|undefined} limit the maximum amount of order book entries to return * @param {object} params extra parameters specific to the btcturk api endpoint * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols */ await this.loadMarkets(); const market = this.market(symbol); const request = { 'pairSymbol': market['id'], }; const response = await this.publicGetOrderbook(this.extend(request, params)); // { // "data": { // "timestamp": 1618827901241, // "bids": [ // [ // "460263.00", // "0.04244000" // ] // ] // } // } const data = this.safeValue(response, 'data'); const timestamp = this.safeInteger(data, 'timestamp'); return this.parseOrderBook(data, market['symbol'], timestamp, 'bids', 'asks', 0, 1); } parseTicker(ticker, market = undefined) { // // { // "pair": "BTCTRY", // "pairNormalized": "BTC_TRY", // "timestamp": 1618826361234, // "last": 462485, // "high": 473976, // "low": 444201, // "bid": 461928, // "ask": 462485, // "open": 456915, // "volume": 917.41368645, // "average": 462868.29574589, // "daily": 5570, // "dailyPercent": 1.22, // "denominatorSymbol": "TRY", // "numeratorSymbol": "BTC", // "order": 1000 // } // const marketId = this.safeString(ticker, 'pair'); market = this.safeMarket(marketId, market); const symbol = market['symbol']; const timestamp = this.safeInteger(ticker, 'timestamp'); const last = this.safeString(ticker, 'last'); return this.safeTicker({ 'symbol': symbol, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'high': this.safeString(ticker, 'high'), 'low': this.safeString(ticker, 'low'), 'bid': this.safeString(ticker, 'bid'), 'bidVolume': undefined, 'ask': this.safeString(ticker, 'ask'), 'askVolume': undefined, 'vwap': undefined, 'open': this.safeString(ticker, 'open'), 'close': last, 'last': last, 'previousClose': undefined, 'change': this.safeString(ticker, 'daily'), 'percentage': this.safeString(ticker, 'dailyPercent'), 'average': this.safeString(ticker, 'average'), 'baseVolume': this.safeString(ticker, 'volume'), 'quoteVolume': undefined, 'info': ticker, }, market); } async fetchTickers(symbols = undefined, params = {}) { /** * @method * @name btcturk#fetchTickers * @description fetches price tickers for multiple markets, statistical calculations with the information calculated over the past 24 hours each market * @param {[string]|undefined} 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 btcturk api endpoint * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ await this.loadMarkets(); const response = await this.publicGetTicker(params); const tickers = this.safeValue(response, 'data'); return this.parseTickers(tickers, symbols); } async fetchTicker(symbol, params = {}) { /** * @method * @name btcturk#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @param {string} symbol unified symbol of the market to fetch the ticker for * @param {object} params extra parameters specific to the btcturk api endpoint * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ await this.loadMarkets(); const tickers = await this.fetchTickers([symbol], params); return this.safeValue(tickers, symbol); } parseTrade(trade, market = undefined) { // // fetchTrades // { // "pair": "BTCUSDT", // "pairNormalized": "BTC_USDT", // "numerator": "BTC", // "denominator": "USDT", // "date": "1618916879083", // "tid": "637545136790672520", // "price": "55774", // "amount": "0.27917100", // "side": "buy" // } // // fetchMyTrades // { // "price": "56000", // "numeratorSymbol": "BTC", // "denominatorSymbol": "USDT", // "orderType": "buy", // "orderId": "2606935102", // "id": "320874372", // "timestamp": "1618916479593", // "amount": "0.00020000", // "fee": "0", // "tax": "0" // } // const timestamp = this.safeInteger2(trade, 'date', 'timestamp'); const id = this.safeString2(trade, 'tid', 'id'); const order = this.safeString(trade, 'orderId'); const priceString = this.safeString(trade, 'price'); const amountString = Precise.stringAbs(this.safeString(trade, 'amount')); const marketId = this.safeString(trade, 'pair'); const symbol = this.safeSymbol(marketId, market); const side = this.safeString2(trade, 'side', 'orderType'); let fee = undefined; const feeAmountString = this.safeString(trade, 'fee'); if (feeAmountString !== undefined) { const feeCurrency = this.safeString(trade, 'denominatorSymbol'); fee = { 'cost': Precise.stringAbs(feeAmountString), 'currency': this.safeCurrencyCode(feeCurrency), }; } return this.safeTrade({ 'info': trade, 'id': id, 'order': order, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'symbol': symbol, 'type': undefined, 'side': side, 'takerOrMaker': undefined, 'price': priceString, 'amount': amountString, 'cost': undefined, 'fee': fee, }, market); } async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) { /** * @method * @name btcturk#fetchTrades * @description get the list of most recent trades for a particular symbol * @param {string} symbol unified symbol of the market to fetch trades for * @param {int|undefined} since timestamp in ms of the earliest trade to fetch * @param {int|undefined} limit the maximum amount of trades to fetch * @param {object} params extra parameters specific to the btcturk api endpoint * @returns {[object]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades} */ await this.loadMarkets(); const market = this.market(symbol); // let maxCount = 50; const request = { 'pairSymbol': market['id'], }; if (limit !== undefined) { request['last'] = limit; } const response = await this.publicGetTrades(this.extend(request, params)); // // { // "data": [ // { // "pair": "BTCTRY", // "pairNormalized": "BTC_TRY", // "numerator": "BTC", // "denominator": "TRY", // "date": 1618828421497, // "tid": "637544252214980918", // "price": "462585.00", // "amount": "0.01618411", // "side": "sell" // } // ] // } // const data = this.safeValue(response, 'data'); return this.parseTrades(data, market, since, limit); } parseOHLCV(ohlcv, market = undefined) { // // { // 'timestamp': 1661990400, // 'high': 368388.0, // 'open': 368388.0, // 'low': 368388.0, // 'close': 368388.0, // 'volume': 0.00035208, // } // return [ this.safeTimestamp(ohlcv, 'timestamp'), this.safeNumber(ohlcv, 'open'), this.safeNumber(ohlcv, 'high'), this.safeNumber(ohlcv, 'low'), this.safeNumber(ohlcv, 'close'), this.safeNumber(ohlcv, 'volume'), ]; } async fetchOHLCV(symbol, timeframe = '1h', since = undefined, limit = undefined, params = {}) { /** * @method * @name btcturk#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://docs.btcturk.com/public-endpoints/get-kline-data * @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|undefined} since timestamp in ms of the earliest candle to fetch * @param {int|undefined} limit the maximum amount of candles to fetch * @param {object} params extra parameters specific to the btcturk api endpoint * @param {int|undefined} params.until timestamp in ms of the latest candle to fetch * @returns {[[int]]} A list of candles ordered as timestamp, open, high, low, close, volume */ await this.loadMarkets(); const market = this.market(symbol); const request = { 'symbol': market['id'], 'resolution': this.safeValue(this.timeframes, timeframe, timeframe), // allows the user to pass custom timeframes if needed }; const until = this.safeInteger(params, 'until', this.milliseconds()); request['to'] = this.parseToInt((until / 1000)); if (since !== undefined) { request['from'] = this.parseToInt(since / 1000); } else if (limit === undefined) { // since will also be undefined limit = 100; // default value } if (limit !== undefined) { if (timeframe === '1y') { // difficult with leap years throw new BadRequest(this.id + ' fetchOHLCV () does not accept a limit parameter when timeframe == "1y"'); } const seconds = this.parseTimeframe(timeframe); const limitSeconds = seconds * (limit - 1); if (since !== undefined) { const to = this.parseToInt(since / 1000) + limitSeconds; request['to'] = Math.min(request['to'], to); } else { request['from'] = this.parseToInt(until / 1000) - limitSeconds; } } const response = await this.graphGetKlinesHistory(this.extend(request, params)); // // { // "s": "ok", // "t": [ // 1661990400, // 1661990520, // ... // ], // "h": [ // 368388.0, // 369090.0, // ... // ], // "o": [ // 368388.0, // 368467.0, // ... // ], // "l": [ // 368388.0, // 368467.0, // ... // ], // "c": [ // 368388.0, // 369090.0, // ... // ], // "v": [ // 0.00035208, // 0.2972395, // ... // ] // } // return this.parseOHLCVs(response, market, timeframe, since, limit); } parseOHLCVs(ohlcvs, market = undefined, timeframe = '1m', since = undefined, limit = undefined) { const results = []; const timestamp = this.safeValue(ohlcvs, 't'); const high = this.safeValue(ohlcvs, 'h'); const open = this.safeValue(ohlcvs, 'o'); const low = this.safeValue(ohlcvs, 'l'); const close = this.safeValue(ohlcvs, 'c'); const volume = this.safeValue(ohlcvs, 'v'); for (let i = 0; i < timestamp.length; i++) { const ohlcv = { 'timestamp': this.safeValue(timestamp, i), 'high': this.safeValue(high, i), 'open': this.safeValue(open, i), 'low': this.safeValue(low, i), 'close': this.safeValue(close, i), 'volume': this.safeValue(volume, i), }; results.push(this.parseOHLCV(ohlcv, market)); } const sorted = this.sortBy(results, 0); return this.filterBySinceLimit(sorted, since, limit, 0); } async createOrder(symbol, type, side, amount, price = undefined, params = {}) { /** * @method * @name btcturk#createOrder * @description create a trade order * @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|undefined} price the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders * @param {object} params extra parameters specific to the btcturk api endpoint * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ await this.loadMarkets(); const market = this.market(symbol); const request = { 'orderType': side, 'orderMethod': type, 'pairSymbol': market['id'], 'quantity': this.amountToPrecision(symbol, amount), }; if (type !== 'market') { request['price'] = this.priceToPrecision(symbol, price); } if ('clientOrderId' in params) { request['newClientOrderId'] = params['clientOrderId']; } else if (!('newClientOrderId' in params)) { request['newClientOrderId'] = this.uuid(); } const response = await this.privatePostOrder(this.extend(request, params)); const data = this.safeValue(response, 'data'); return this.parseOrder(data, market); } async cancelOrder(id, symbol = undefined, params = {}) { /** * @method * @name btcturk#cancelOrder * @description cancels an open order * @param {string} id order id * @param {string|undefined} symbol not used by btcturk cancelOrder () * @param {object} params extra parameters specific to the btcturk api endpoint * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ const request = { 'id': id, }; return await this.privateDeleteOrder(this.extend(request, params)); } async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) { /** * @method * @name btcturk#fetchOpenOrders * @description fetch all unfilled currently open orders * @param {string|undefined} symbol unified market symbol * @param {int|undefined} since the earliest time in ms to fetch open orders for * @param {int|undefined} limit the maximum number of open orders structures to retrieve * @param {object} params extra parameters specific to the btcturk api endpoint * @returns {[object]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ await this.loadMarkets(); const request = {}; let market = undefined; if (symbol !== undefined) { market = this.market(symbol); request['pairSymbol'] = market['id']; } const response = await this.privateGetOpenOrders(this.extend(request, params)); const data = this.safeValue(response, 'data'); const bids = this.safeValue(data, 'bids', []); const asks = this.safeValue(data, 'asks', []); return this.parseOrders(this.arrayConcat(bids, asks), market, since, limit); } async fetchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) { /** * @method * @name btcturk#fetchOrders * @description fetches information on multiple orders made by the user * @param {string|undefined} symbol unified market symbol of the market orders were made in * @param {int|undefined} since the earliest time in ms to fetch orders for * @param {int|undefined} limit the maximum number of orde structures to retrieve * @param {object} params extra parameters specific to the btcturk api endpoint * @returns {[object]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ await this.loadMarkets(); const market = this.market(symbol); const request = { 'pairSymbol': market['id'], }; if (limit !== undefined) { // default 100 max 1000 request['last'] = limit; } if (since !== undefined) { request['startTime'] = Math.floor(since / 1000); } const response = await this.privateGetAllOrders(this.extend(request, params)); // { // "data": [ // { // "id": "2606012912", // "price": "55000", // "amount": "0.0003", // "quantity": "0.0003", // "stopPrice": "0", // "pairSymbol": "BTCUSDT", // "pairSymbolNormalized": "BTC_USDT", // "type": "buy", // "method": "limit", // "orderClientId": "2ed187bd-59a8-4875-a212-1b793963b85c", // "time": "1618913189253", // "updateTime": "1618913189253", // "status": "Untouched", // "leftAmount": "0.0003000000000000" // } // ] // } const data = this.safeValue(response, 'data'); return this.parseOrders(data, market, since, limit); } parseOrderStatus(status) { const statuses = { 'Untouched': 'open', 'Partial': 'open', 'Canceled': 'canceled', 'Closed': 'closed', }; return this.safeString(statuses, status, status); } parseOrder(order, market = undefined) { // // fetchOrders / fetchOpenOrders // { // "id": 2605984008, // "price": "55000", // "amount": "0.00050000", // "quantity": "0.00050000", // "stopPrice": "0", // "pairSymbol": "BTCUSDT", // "pairSymbolNormalized": "BTC_USDT", // "type": "buy", // "method": "limit", // "orderClientId": "f479bdb6-0965-4f03-95b5-daeb7aa5a3a5", // "time": 0, // "updateTime": 1618913083543, // "status": "Untouched", // "leftAmount": "0.00050000" // } // // createOrder // { // "id": "2606935102", // "quantity": "0.0002", // "price": "56000", // "stopPrice": null, // "newOrderClientId": "98e5c491-7ed9-462b-9666-93553180fb28", // "type": "buy", // "method": "limit", // "pairSymbol": "BTCUSDT", // "pairSymbolNormalized": "BTC_USDT", // "datetime": "1618916479523" // } // const id = this.safeString(order, 'id'); const price = this.safeString(order, 'price'); const amountString = this.safeString2(order, 'amount', 'quantity'); const amount = Precise.stringAbs(amountString); const remaining = this.safeString(order, 'leftAmount'); const marketId = this.safeString(order, 'pairSymbol'); const symbol = this.safeSymbol(marketId, market); const side = this.safeString(order, 'type'); const type = this.safeString(order, 'method'); const clientOrderId = this.safeString(order, 'orderClientId'); const timestamp = this.safeInteger2(order, 'updateTime', 'datetime'); const rawStatus = this.safeString(order, 'status'); const status = this.parseOrderStatus(rawStatus); return this.safeOrder({ 'info': order, 'id': id, 'price': price, 'amount': amount, 'remaining': remaining, 'filled': undefined, 'cost': undefined, 'average': undefined, 'status': status, 'side': side, 'type': type, 'clientOrderId': clientOrderId, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'symbol': symbol, 'fee': undefined, }, market); } async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) { /** * @method * @name btcturk#fetchMyTrades * @description fetch all trades made by the user * @param {string|undefined} symbol unified market symbol * @param {int|undefined} since the earliest time in ms to fetch trades for * @param {int|undefined} limit the maximum number of trades structures to retrieve * @param {object} params extra parameters specific to the btcturk api endpoint * @returns {[object]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ await this.loadMarkets(); let market = undefined; if (symbol !== undefined) { market = this.market(symbol); } const response = await this.privateGetUsersTransactionsTrade(); // // { // "data": [ // { // "price": "56000", // "numeratorSymbol": "BTC", // "denominatorSymbol": "USDT", // "orderType": "buy", // "orderId": "2606935102", // "id": "320874372", // "timestamp": "1618916479593", // "amount": "0.00020000", // "fee": "0", // "tax": "0" // } // ], // "success": true, // "message": "SUCCESS", // "code": "0" // } // const data = this.safeValue(response, 'data'); return this.parseTrades(data, market, since, limit); } nonce() { return this.milliseconds(); } sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) { if (this.id === 'btctrader') { throw new ExchangeError(this.id + ' is an abstract base API for BTCExchange, BTCTurk'); } let url = this.urls['api'][api] + '/' + path; if ((method === 'GET') || (method === 'DELETE')) { if (Object.keys(params).length) { url += '?' + this.urlencode(params); } } else { body = this.json(params); } if (api === 'private') { this.checkRequiredCredentials(); const nonce = this.nonce().toString(); const secret = this.base64ToBinary(this.secret); const auth = this.apiKey + nonce; headers = { 'X-PCK': this.apiKey, 'X-Stamp': nonce, 'X-Signature': this.hmac(this.encode(auth), secret, sha256, 'base64'), 'Content-Type': 'application/json', }; } return { 'url': url, 'method': method, 'body': body, 'headers': headers }; } handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) { const errorCode = this.safeString(response, 'code', '0'); const message = this.safeString(response, 'message'); const output = (message === undefined) ? body : message; this.throwExactlyMatchedException(this.exceptions['exact'], message, this.id + ' ' + output); if ((errorCode !== '0') && (errorCode !== 'SUCCESS')) { throw new ExchangeError(this.id + ' ' + output); } return undefined; } }