UNPKG

@jalmonter/ccxt

Version:

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

1,187 lines 84.4 kB
// --------------------------------------------------------------------------- import Exchange from './abstract/bigone.js'; import { ExchangeError, AuthenticationError, InsufficientFunds, PermissionDenied, BadRequest, BadSymbol, RateLimitExceeded, InvalidOrder, ArgumentsRequired, NotSupported } from './base/errors.js'; import { TICK_SIZE } from './base/functions/number.js'; import { jwt } from './base/functions/rsa.js'; import { sha256 } from './static_dependencies/noble-hashes/sha256.js'; import { Precise } from './base/Precise.js'; // --------------------------------------------------------------------------- /** * @class bigone * @augments Exchange */ export default class bigone extends Exchange { describe() { return this.deepExtend(super.describe(), { 'id': 'bigone', 'name': 'BigONE', 'countries': ['CN'], 'version': 'v3', 'rateLimit': 1200, 'has': { 'CORS': undefined, 'spot': true, 'margin': undefined, 'swap': undefined, 'future': undefined, 'option': undefined, 'cancelAllOrders': true, 'cancelOrder': true, 'createMarketBuyOrderWithCost': true, 'createMarketOrderWithCost': false, 'createMarketSellOrderWithCost': false, 'createOrder': true, 'createPostOnlyOrder': true, 'createStopLimitOrder': true, 'createStopMarketOrder': true, 'createStopOrder': true, 'fetchBalance': true, 'fetchClosedOrders': true, 'fetchCurrencies': true, 'fetchDepositAddress': true, 'fetchDeposits': true, 'fetchMarkets': true, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenOrders': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchOrders': true, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': true, 'fetchTrades': true, 'fetchTradingFee': false, 'fetchTradingFees': false, 'fetchTransactionFees': false, 'fetchWithdrawals': true, 'transfer': true, 'withdraw': true, }, 'timeframes': { '1m': 'min1', '5m': 'min5', '15m': 'min15', '30m': 'min30', '1h': 'hour1', '3h': 'hour3', '4h': 'hour4', '6h': 'hour6', '12h': 'hour12', '1d': 'day1', '1w': 'week1', '1M': 'month1', }, 'hostname': 'big.one', 'urls': { 'logo': 'https://user-images.githubusercontent.com/1294454/69354403-1d532180-0c91-11ea-88ed-44c06cefdf87.jpg', 'api': { 'public': 'https://{hostname}/api/v3', 'private': 'https://{hostname}/api/v3/viewer', 'webExchange': 'https://{hostname}/api/', }, 'www': 'https://big.one', 'doc': 'https://open.big.one/docs/api.html', 'fees': 'https://bigone.zendesk.com/hc/en-us/articles/115001933374-BigONE-Fee-Policy', 'referral': 'https://b1.run/users/new?code=D3LLBVFT', }, 'api': { 'public': { 'get': [ 'ping', 'asset_pairs', 'asset_pairs/{asset_pair_name}/depth', 'asset_pairs/{asset_pair_name}/trades', 'asset_pairs/{asset_pair_name}/ticker', 'asset_pairs/{asset_pair_name}/candles', 'asset_pairs/tickers', ], }, 'private': { 'get': [ 'accounts', 'fund/accounts', 'assets/{asset_symbol}/address', 'orders', 'orders/{id}', 'orders/multi', 'trades', 'withdrawals', 'deposits', ], 'post': [ 'orders', 'orders/{id}/cancel', 'orders/cancel', 'withdrawals', 'transfer', ], }, 'webExchange': { 'get': [ 'uc/v2/assets', ], }, }, 'fees': { 'trading': { 'maker': this.parseNumber('0.001'), 'taker': this.parseNumber('0.001'), }, 'funding': { 'withdraw': {}, }, }, 'options': { 'createMarketBuyOrderRequiresPrice': true, 'accountsByType': { 'spot': 'SPOT', 'fund': 'FUND', 'funding': 'FUND', 'future': 'CONTRACT', 'swap': 'CONTRACT', }, 'transfer': { 'fillResponseFromRequest': true, }, 'exchangeMillisecondsCorrection': -100, 'fetchCurrencies': { 'webApiEnable': true, 'webApiRetries': 5, 'webApiMuteFailure': true, }, 'defaultNetwork': 'ERC20', 'defaultNetworks': { 'USDT': 'TRC20', }, 'networks': { 'ABBC': 'ABBC', 'ACA': 'Acala', 'AE': 'Aeternity', 'ALGO': 'Algorand', 'APT': 'Aptos', 'AR': 'Arweave', 'ASTR': 'Astar', 'AVAXC': 'Avax', 'AVAXX': 'AvaxChain', 'BEAM': 'Beam', 'BEP20': 'BinanceSmartChain', 'BITCI': 'BitciChain', 'BTC': 'Bitcoin', 'BCH': 'BitcoinCash', 'BSV': 'BitcoinSV', 'CELO': 'Celo', 'CKKB': 'CKB', 'ATOM': 'Cosmos', 'CRC20': 'CRO', 'DASH': 'Dash', 'DOGE': 'Dogecoin', 'XEC': 'ECash', 'EOS': 'EOS', 'ETH': 'Ethereum', 'ETC': 'EthereumClassic', 'ETHW': 'EthereumPow', 'FTM': 'Fantom', 'FIL': 'Filecoin', 'FSN': 'Fusion', 'GRIN': 'Grin', 'ONE': 'Harmony', 'HRC20': 'Hecochain', 'HBAR': 'Hedera', 'HNT': 'Helium', 'ZEN': 'Horizen', 'IOST': 'IOST', 'IRIS': 'IRIS', 'KLAY': 'Klaytn', 'KSM': 'Kusama', 'LTC': 'Litecoin', 'XMR': 'Monero', 'GLMR': 'Moonbeam', 'NEAR': 'Near', 'NEO': 'Neo', 'NEON3': 'NeoN3', 'OASIS': 'Oasis', 'OKC': 'Okexchain', 'ONT': 'Ontology', 'OPTIMISM': 'Optimism', 'DOT': 'Polkadot', 'MATIC': 'Polygon', 'QTUM': 'Qtum', 'REI': 'REI', 'XRP': 'Ripple', 'SGB': 'SGB', 'SDN': 'Shiden', 'SOL': 'Solana', 'XLM': 'Stellar', 'TERA': 'Tera', 'XTZ': 'Tezos', 'TRC20': 'Tron', 'VET': 'Vechain', 'VSYS': 'VSystems', 'WAX': 'WAX', 'ZEC': 'Zcash', // todo: uncomment after consensus // 'BITSHARES_OLD': 'Bitshares', // 'BITSHARES_NEW': 'NewBitshares', // 'MOBILECOIN': 'Mobilecoin', // 'LBRY': 'Lbry', // 'ZEEPIN': 'Zeepin', // 'WAYFCOIN': 'Wayfcoin', // 'UCACOIN': 'Ucacoin', // 'VANILLACASH': 'Vcash', // 'LAMDEN': 'Lamden', // 'GXSHARES': 'Gxshares', // 'ICP': 'Dfinity', // 'CLOVER': 'Clover', // 'CLASSZZ': 'Classzz', // 'CLASSZZ_V2': 'ClasszzV2', // 'CHAINX_V2': 'ChainxV2', // 'BITCOINDIAMON': 'BitcoinDiamond', // 'BITCOINGOLD': 'BitcoinGold', // 'BUTTRUSTSYSTEM': 'BitTrustSystem', // 'BYTOM_V2': 'BytomV2', // 'LIBONOMY': 'Libonomy', // 'TERRACLASSIC': 'Terra', // 'TERRA': 'Terra2', // 'SUPERBITCOIN': 'SuperBitcoin', // 'SIACLASSIC': 'Sia', // 'SIACOIN': 'SiaCore', // 'PARALLELFINANCE': 'Parallel', // 'PLCULTIMA': 'Plcu', // 'PLCULTIMA2': 'Plcu2', // undetermined: XinFin, YAS, Ycash }, }, 'precisionMode': TICK_SIZE, 'exceptions': { 'exact': { '10001': BadRequest, '10005': ExchangeError, "Amount's scale must greater than AssetPair's base scale": InvalidOrder, "Price mulit with amount should larger than AssetPair's min_quote_value": InvalidOrder, '10007': BadRequest, '10011': ExchangeError, '10013': BadSymbol, '10014': InsufficientFunds, '10403': PermissionDenied, '10429': RateLimitExceeded, '40004': AuthenticationError, '40103': AuthenticationError, '40104': AuthenticationError, '40301': PermissionDenied, '40302': ExchangeError, '40601': ExchangeError, '40602': ExchangeError, '40603': InsufficientFunds, '40604': InvalidOrder, '40605': InvalidOrder, '40120': InvalidOrder, '40121': InvalidOrder, '60100': BadSymbol, // {"code":60100,"message":"Asset pair is suspended"} }, 'broad': {}, }, 'commonCurrencies': { 'CRE': 'Cybereits', 'FXT': 'FXTTOKEN', 'FREE': 'FreeRossDAO', 'MBN': 'Mobilian Coin', 'ONE': 'BigONE Token', }, }); } async fetchCurrencies(params = {}) { /** * @method * @name bigone#fetchCurrencies * @description fetches all available currencies on an exchange * @param {dict} [params] extra parameters specific to the exchange API endpoint * @returns {dict} an associative dictionary of currencies */ // we use undocumented link (possible, less informative alternative is : https://big.one/api/uc/v3/assets/accounts) const data = await this.fetchWebEndpoint('fetchCurrencies', 'webExchangeGetUcV2Assets', true); if (data === undefined) { return undefined; } // // { // "code": "0", // "message": "", // "data": [ // { // "name": "TetherUS", // "symbol": "USDT", // "contract_address": "31", // "is_deposit_enabled": true, // "is_withdrawal_enabled": true, // "is_stub": false, // "withdrawal_fee": "5.0", // "is_fiat": false, // "is_memo_required": false, // "logo": { // "default": "https://assets.peatio.com/assets/v1/color/normal/usdt.png", // "white": "https://assets.peatio.com/assets/v1/white/normal/usdt.png", // }, // "info_link": null, // "scale": "12", // "default_gateway": ..., // one object from "gateways" // "gateways": [ // { // "uuid": "f0fa5a85-7f65-428a-b7b7-13aad55c2837", // "name": "Mixin", // "kind": "CHAIN", // "required_confirmations": "0", // }, // { // "uuid": "b75446c6-1446-4c8d-b3d1-39f385b0a926", // "name": "Ethereum", // "kind": "CHAIN", // "required_confirmations": "18", // }, // { // "uuid": "fe9b1b0b-e55c-4017-b5ce-16f524df5fc0", // "name": "Tron", // "kind": "CHAIN", // "required_confirmations": "1", // }, // ... // ], // "payments": [], // "uuid": "17082d1c-0195-4fb6-8779-2cdbcb9eeb3c", // "binding_gateways": [ // { // "guid": "07efc37f-d1ec-4bc9-8339-a745256ea2ba", // "contract_address": "0xdac17f958d2ee523a2206206994597c13d831ec7", // "is_deposit_enabled": true, // "display_name": "Ethereum(ERC20)", // "gateway_name": "Ethereum", // "min_withdrawal_amount": "0.000001", // "min_internal_withdrawal_amount": "0.00000001", // "withdrawal_fee": "14", // "is_withdrawal_enabled": true, // "min_deposit_amount": "0.000001", // "is_memo_required": false, // "withdrawal_scale": "2", // "gateway": { // "uuid": "b75446c6-1446-4c8d-b3d1-39f385b0a926", // "name": "Ethereum", // "kind": "CHAIN", // "required_confirmations": "18", // }, // "scale": "12", // }, // { // "guid": "b80a4d13-cac7-4319-842d-b33c3bfab8ec", // "contract_address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", // "is_deposit_enabled": true, // "display_name": "Tron(TRC20)", // "gateway_name": "Tron", // "min_withdrawal_amount": "0.000001", // "min_internal_withdrawal_amount": "0.00000001", // "withdrawal_fee": "1", // "is_withdrawal_enabled": true, // "min_deposit_amount": "0.000001", // "is_memo_required": false, // "withdrawal_scale": "6", // "gateway": { // "uuid": "fe9b1b0b-e55c-4017-b5ce-16f524df5fc0", // "name": "Tron", // "kind": "CHAIN", // "required_confirmations": "1", // }, // "scale": "12", // }, // ... // ], // }, // ... // ], // } // const currenciesData = this.safeValue(data, 'data', []); const result = {}; for (let i = 0; i < currenciesData.length; i++) { const currency = currenciesData[i]; const id = this.safeString(currency, 'symbol'); const code = this.safeCurrencyCode(id); const name = this.safeString(currency, 'name'); const type = this.safeValue(currency, 'is_fiat') ? 'fiat' : 'crypto'; const networks = {}; const chains = this.safeValue(currency, 'binding_gateways', []); let currencyMaxPrecision = this.parsePrecision(this.safeString2(currency, 'withdrawal_scale', 'scale')); let currencyDepositEnabled = undefined; let currencyWithdrawEnabled = undefined; for (let j = 0; j < chains.length; j++) { const chain = chains[j]; const networkId = this.safeString(chain, 'gateway_name'); const networkCode = this.networkIdToCode(networkId); const deposit = this.safeValue(chain, 'is_deposit_enabled'); const withdraw = this.safeValue(chain, 'is_withdrawal_enabled'); const isActive = (deposit && withdraw); const minDepositAmount = this.safeString(chain, 'min_deposit_amount'); const minWithdrawalAmount = this.safeString(chain, 'min_withdrawal_amount'); const withdrawalFee = this.safeString(chain, 'withdrawal_fee'); const precision = this.parsePrecision(this.safeString2(chain, 'withdrawal_scale', 'scale')); networks[networkCode] = { 'id': networkId, 'network': networkCode, 'margin': undefined, 'deposit': deposit, 'withdraw': withdraw, 'active': isActive, 'fee': this.parseNumber(withdrawalFee), 'precision': this.parseNumber(precision), 'limits': { 'deposit': { 'min': minDepositAmount, 'max': undefined, }, 'withdraw': { 'min': minWithdrawalAmount, 'max': undefined, }, }, 'info': chain, }; // fill global values currencyDepositEnabled = (currencyDepositEnabled === undefined) || deposit ? deposit : currencyDepositEnabled; currencyWithdrawEnabled = (currencyWithdrawEnabled === undefined) || withdraw ? withdraw : currencyWithdrawEnabled; currencyMaxPrecision = (currencyMaxPrecision === undefined) || Precise.stringGt(currencyMaxPrecision, precision) ? precision : currencyMaxPrecision; } result[code] = { 'id': id, 'code': code, 'info': currency, 'name': name, 'type': type, 'active': undefined, 'deposit': currencyDepositEnabled, 'withdraw': currencyWithdrawEnabled, 'fee': undefined, 'precision': this.parseNumber(currencyMaxPrecision), 'limits': { 'amount': { 'min': undefined, 'max': undefined, }, 'withdraw': { 'min': undefined, 'max': undefined, }, }, 'networks': networks, }; } return result; } async fetchMarkets(params = {}) { /** * @method * @name bigone#fetchMarkets * @description retrieves data on all markets for bigone * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ const response = await this.publicGetAssetPairs(params); // // { // "code":0, // "data":[ // { // "id":"01e48809-b42f-4a38-96b1-c4c547365db1", // "name":"PCX-BTC", // "quote_scale":7, // "quote_asset":{ // "id":"0df9c3c3-255a-46d7-ab82-dedae169fba9", // "symbol":"BTC", // "name":"Bitcoin", // }, // "base_asset":{ // "id":"405484f7-4b03-4378-a9c1-2bd718ecab51", // "symbol":"PCX", // "name":"ChainX", // }, // "base_scale":3, // "min_quote_value":"0.0001", // "max_quote_value":"35" // }, // ] // } // const markets = this.safeValue(response, 'data', []); return this.parseMarkets(markets); } parseMarket(market) { const id = this.safeString(market, 'name'); const baseAsset = this.safeValue(market, 'base_asset', {}); const quoteAsset = this.safeValue(market, 'quote_asset', {}); const baseId = this.safeString(baseAsset, 'symbol'); const quoteId = this.safeString(quoteAsset, 'symbol'); const base = this.safeCurrencyCode(baseId); const quote = this.safeCurrencyCode(quoteId); return { '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': true, 'contract': false, 'linear': undefined, 'inverse': undefined, 'contractSize': undefined, 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'amount': this.parseNumber(this.parsePrecision(this.safeString(market, 'base_scale'))), 'price': this.parseNumber(this.parsePrecision(this.safeString(market, 'quote_scale'))), }, 'limits': { 'leverage': { 'min': undefined, 'max': undefined, }, 'amount': { 'min': undefined, 'max': undefined, }, 'price': { 'min': undefined, 'max': undefined, }, 'cost': { 'min': this.safeNumber(market, 'min_quote_value'), 'max': this.safeNumber(market, 'max_quote_value'), }, }, 'created': undefined, 'info': market, }; } parseTicker(ticker, market = undefined) { // // { // "asset_pair_name":"ETH-BTC", // "bid":{"price":"0.021593","order_count":1,"quantity":"0.20936"}, // "ask":{"price":"0.021613","order_count":1,"quantity":"2.87064"}, // "open":"0.021795", // "high":"0.021795", // "low":"0.021471", // "close":"0.021613", // "volume":"117078.90431", // "daily_change":"-0.000182" // } // const marketId = this.safeString(ticker, 'asset_pair_name'); const symbol = this.safeSymbol(marketId, market, '-'); const timestamp = undefined; const close = this.safeString(ticker, 'close'); const bid = this.safeValue(ticker, 'bid', {}); const ask = this.safeValue(ticker, 'ask', {}); return this.safeTicker({ 'symbol': symbol, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'high': this.safeString(ticker, 'high'), 'low': this.safeString(ticker, 'low'), 'bid': this.safeString(bid, 'price'), 'bidVolume': this.safeString(bid, 'quantity'), 'ask': this.safeString(ask, 'price'), 'askVolume': this.safeString(ask, 'quantity'), 'vwap': undefined, 'open': this.safeString(ticker, 'open'), 'close': close, 'last': close, 'previousClose': undefined, 'change': this.safeString(ticker, 'daily_change'), 'percentage': undefined, 'average': undefined, 'baseVolume': this.safeString(ticker, 'volume'), 'quoteVolume': undefined, 'info': ticker, }, market); } async fetchTicker(symbol, params = {}) { /** * @method * @name bigone#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 exchange API endpoint * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ await this.loadMarkets(); const market = this.market(symbol); const request = { 'asset_pair_name': market['id'], }; const response = await this.publicGetAssetPairsAssetPairNameTicker(this.extend(request, params)); // // { // "code":0, // "data":{ // "asset_pair_name":"ETH-BTC", // "bid":{"price":"0.021593","order_count":1,"quantity":"0.20936"}, // "ask":{"price":"0.021613","order_count":1,"quantity":"2.87064"}, // "open":"0.021795", // "high":"0.021795", // "low":"0.021471", // "close":"0.021613", // "volume":"117078.90431", // "daily_change":"-0.000182" // } // } // const ticker = this.safeValue(response, 'data', {}); return this.parseTicker(ticker, market); } async fetchTickers(symbols = undefined, params = {}) { /** * @method * @name bigone#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for 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 exchange API endpoint * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ await this.loadMarkets(); const request = {}; symbols = this.marketSymbols(symbols); if (symbols !== undefined) { const ids = this.marketIds(symbols); request['pair_names'] = ids.join(','); } const response = await this.publicGetAssetPairsTickers(this.extend(request, params)); // // { // "code":0, // "data":[ // { // "asset_pair_name":"PCX-BTC", // "bid":{"price":"0.000234","order_count":1,"quantity":"0.518"}, // "ask":{"price":"0.0002348","order_count":1,"quantity":"2.348"}, // "open":"0.0002343", // "high":"0.0002348", // "low":"0.0002162", // "close":"0.0002348", // "volume":"12887.016", // "daily_change":"0.0000005" // }, // { // "asset_pair_name":"GXC-USDT", // "bid":{"price":"0.5054","order_count":1,"quantity":"40.53"}, // "ask":{"price":"0.5055","order_count":1,"quantity":"38.53"}, // "open":"0.5262", // "high":"0.5323", // "low":"0.5055", // "close":"0.5055", // "volume":"603963.05", // "daily_change":"-0.0207" // } // ] // } // const tickers = this.safeValue(response, 'data', []); const result = {}; for (let i = 0; i < tickers.length; i++) { const ticker = this.parseTicker(tickers[i]); const symbol = ticker['symbol']; result[symbol] = ticker; } return this.filterByArrayTickers(result, 'symbol', symbols); } async fetchTime(params = {}) { /** * @method * @name bigone#fetchTime * @description fetches the current integer timestamp in milliseconds from the exchange server * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {int} the current integer timestamp in milliseconds from the exchange server */ const response = await this.publicGetPing(params); // // { // "data": { // "timestamp": 1527665262168391000 // } // } // const data = this.safeValue(response, 'data', {}); const timestamp = this.safeInteger(data, 'Timestamp'); return this.parseToInt(timestamp / 1000000); } async fetchOrderBook(symbol, limit = undefined, params = {}) { /** * @method * @name bigone#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} [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 */ await this.loadMarkets(); const market = this.market(symbol); const request = { 'asset_pair_name': market['id'], }; if (limit !== undefined) { request['limit'] = limit; // default 50, max 200 } const response = await this.publicGetAssetPairsAssetPairNameDepth(this.extend(request, params)); // // { // "code":0, // "data": { // "asset_pair_name": "EOS-BTC", // "bids": [ // { "price": "42", "order_count": 4, "quantity": "23.33363711" } // ], // "asks": [ // { "price": "45", "order_count": 2, "quantity": "4193.3283464" } // ] // } // } // const orderbook = this.safeValue(response, 'data', {}); return this.parseOrderBook(orderbook, market['symbol'], undefined, 'bids', 'asks', 'price', 'quantity'); } parseTrade(trade, market = undefined) { // // fetchTrades (public) // // { // "id": 38199941, // "price": "3378.67", // "amount": "0.019812", // "taker_side": "ASK", // "created_at": "2019-01-29T06:05:56Z" // } // // fetchMyTrades (private) // // { // "id": 10854280, // "asset_pair_name": "XIN-USDT", // "price": "70", // "amount": "1", // "taker_side": "ASK", // "maker_order_id": 58284908, // "taker_order_id": 58284909, // "maker_fee": "0.0008", // "taker_fee": "0.07", // "side": "SELF_TRADING", // "inserted_at": "2019-04-16T12:00:01Z" // }, // // { // "id": 10854263, // "asset_pair_name": "XIN-USDT", // "price": "75.7", // "amount": "12.743149", // "taker_side": "BID", // "maker_order_id": null, // "taker_order_id": 58284888, // "maker_fee": null, // "taker_fee": "0.0025486298", // "side": "BID", // "inserted_at": "2019-04-15T06:20:57Z" // } // const timestamp = this.parse8601(this.safeString2(trade, 'created_at', 'inserted_at')); const priceString = this.safeString(trade, 'price'); const amountString = this.safeString(trade, 'amount'); const marketId = this.safeString(trade, 'asset_pair_name'); market = this.safeMarket(marketId, market, '-'); let side = this.safeString(trade, 'side'); const takerSide = this.safeString(trade, 'taker_side'); let takerOrMaker = undefined; if ((takerSide !== undefined) && (side !== undefined) && (side !== 'SELF_TRADING')) { takerOrMaker = (takerSide === side) ? 'taker' : 'maker'; } if (side === undefined) { // taker side is not related to buy/sell side // the following code is probably a mistake side = (takerSide === 'ASK') ? 'sell' : 'buy'; } else { if (side === 'BID') { side = 'buy'; } else if (side === 'ASK') { side = 'sell'; } } const makerOrderId = this.safeString(trade, 'maker_order_id'); const takerOrderId = this.safeString(trade, 'taker_order_id'); let orderId = undefined; if (makerOrderId !== undefined) { orderId = makerOrderId; } else if (takerOrderId !== undefined) { orderId = takerOrderId; } const id = this.safeString(trade, 'id'); const result = { 'id': id, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'symbol': market['symbol'], 'order': orderId, 'type': 'limit', 'side': side, 'takerOrMaker': takerOrMaker, 'price': priceString, 'amount': amountString, 'cost': undefined, 'info': trade, }; let makerCurrencyCode = undefined; let takerCurrencyCode = undefined; if (takerOrMaker !== undefined) { if (side === 'buy') { if (takerOrMaker === 'maker') { makerCurrencyCode = market['base']; takerCurrencyCode = market['quote']; } else { makerCurrencyCode = market['quote']; takerCurrencyCode = market['base']; } } else { if (takerOrMaker === 'maker') { makerCurrencyCode = market['quote']; takerCurrencyCode = market['base']; } else { makerCurrencyCode = market['base']; takerCurrencyCode = market['quote']; } } } else if (side === 'SELF_TRADING') { if (takerSide === 'BID') { makerCurrencyCode = market['quote']; takerCurrencyCode = market['base']; } else if (takerSide === 'ASK') { makerCurrencyCode = market['base']; takerCurrencyCode = market['quote']; } } const makerFeeCost = this.safeString(trade, 'maker_fee'); const takerFeeCost = this.safeString(trade, 'taker_fee'); if (makerFeeCost !== undefined) { if (takerFeeCost !== undefined) { result['fees'] = [ { 'cost': makerFeeCost, 'currency': makerCurrencyCode }, { 'cost': takerFeeCost, 'currency': takerCurrencyCode }, ]; } else { result['fee'] = { 'cost': makerFeeCost, 'currency': makerCurrencyCode }; } } else if (takerFeeCost !== undefined) { result['fee'] = { 'cost': takerFeeCost, 'currency': takerCurrencyCode }; } else { result['fee'] = undefined; } return this.safeTrade(result, market); } async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) { /** * @method * @name bigone#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} [since] timestamp in ms of the earliest trade to fetch * @param {int} [limit] the maximum amount of trades to fetch * @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} */ await this.loadMarkets(); const market = this.market(symbol); const request = { 'asset_pair_name': market['id'], }; const response = await this.publicGetAssetPairsAssetPairNameTrades(this.extend(request, params)); // // { // "code": 0, // "data": [ // { // "id": 38199941, // "price": "3378.67", // "amount": "0.019812", // "taker_side": "ASK", // "created_at": "2019-01-29T06:05:56Z" // }, // { // "id": 38199934, // "price": "3376.14", // "amount": "0.019384", // "taker_side": "ASK", // "created_at": "2019-01-29T06:05:40Z" // } // ] // } // const trades = this.safeValue(response, 'data', []); return this.parseTrades(trades, market, since, limit); } parseOHLCV(ohlcv, market = undefined) { // // { // "close": "0.021562", // "high": "0.021563", // "low": "0.02156", // "open": "0.021563", // "time": "2019-11-21T07:54:00Z", // "volume": "59.84376" // } // return [ this.parse8601(this.safeString(ohlcv, 'time')), this.safeNumber(ohlcv, 'open'), this.safeNumber(ohlcv, 'high'), this.safeNumber(ohlcv, 'low'), this.safeNumber(ohlcv, 'close'), this.safeNumber(ohlcv, 'volume'), ]; } async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) { /** * @method * @name bigone#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @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 * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ await this.loadMarkets(); const market = this.market(symbol); if (limit === undefined) { limit = 100; // default 100, max 500 } const request = { 'asset_pair_name': market['id'], 'period': this.safeString(this.timeframes, timeframe, timeframe), 'limit': limit, }; if (since !== undefined) { // const start = this.parseToInt (since / 1000); const duration = this.parseTimeframe(timeframe); const end = this.sum(since, limit * duration * 1000); request['time'] = this.iso8601(end); } const response = await this.publicGetAssetPairsAssetPairNameCandles(this.extend(request, params)); // // { // "code": 0, // "data": [ // { // "close": "0.021656", // "high": "0.021658", // "low": "0.021652", // "open": "0.021652", // "time": "2019-11-21T09:30:00Z", // "volume": "53.08664" // }, // { // "close": "0.021652", // "high": "0.021656", // "low": "0.021652", // "open": "0.021656", // "time": "2019-11-21T09:29:00Z", // "volume": "88.39861" // }, // ] // } // const data = this.safeValue(response, 'data', []); return this.parseOHLCVs(data, market, timeframe, since, limit); } parseBalance(response) { const result = { 'info': response, 'timestamp': undefined, 'datetime': undefined, }; const balances = this.safeValue(response, 'data', []); for (let i = 0; i < balances.length; i++) { const balance = balances[i]; const symbol = this.safeString(balance, 'asset_symbol'); const code = this.safeCurrencyCode(symbol); const account = this.account(); account['total'] = this.safeString(balance, 'balance'); account['used'] = this.safeString(balance, 'locked_balance'); result[code] = account; } return this.safeBalance(result); } async fetchBalance(params = {}) { /** * @method * @name bigone#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} */ await this.loadMarkets(); const type = this.safeString(params, 'type', ''); params = this.omit(params, 'type'); let response = undefined; if (type === 'funding' || type === 'fund') { response = await this.privateGetFundAccounts(params); } else { response = await this.privateGetAccounts(params); } // // { // "code":0, // "data":[ // {"asset_symbol":"NKC","balance":"0","locked_balance":"0"}, // {"asset_symbol":"UBTC","balance":"0","locked_balance":"0"}, // {"asset_symbol":"READ","balance":"0","locked_balance":"0"}, // ], // } // return this.parseBalance(response); } parseType(type) { const types = { 'STOP_LIMIT': 'limit', 'STOP_MARKET': 'market', 'LIMIT': 'limit', 'MARKET': 'market', }; return this.safeString(types, type, type); } parseOrder(order, market = undefined) { // // { // "id": "42154072251", // "asset_pair_name": "SOL-USDT", // "price": "20", // "amount": "0.5", // "filled_amount": "0", // "avg_deal_price": "0", // "side": "ASK", // "state": "PENDING", // "created_at": "2023-09-13T03:42:00Z", // "updated_at": "2023-09-13T03:42:00Z", // "type": "LIMIT", // "stop_price": "0", // "immediate_or_cancel": false, // "post_only": false, // "client_order_id": '' // } // const id = this.safeString(order, 'id'); const marketId = this.safeString(order, 'asset_pair_name'); const symbol = this.safeSymbol(marketId, market, '-'); const timestamp = this.parse8601(this.safeString(order, 'created_at')); let side = this.safeString(order, 'side'); if (side === 'BID') { side = 'buy'; } else { side = 'sell'; } let triggerPrice = this.safeString(order, 'stop_price'); if (Precise.stringEq(triggerPrice, '0')) { triggerPrice = undefined; } const immediateOrCancel = this.safeValue(order, 'immediate_or_cancel'); let timeInForce = undefined; if (immediateOrCancel) { timeInForce = 'IOC'; } const type = this.parseType(this.safeString(order, 'type')); const price = this.safeString(order, 'price'); let amount = undefined; let filled = undefined; let cost = undefined; if (type === 'market' && side === 'buy') { cost = this.safeString(order, 'filled_amount'); } else { amount = this.safeString(order, 'amount'); filled = this.safeString(order, 'filled_amount'); } return this.safeOrder({ 'info': order, 'id': id, 'clientOrderId': this.safeString(order, 'client_order_id'), 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'lastTradeTimestamp': this.parse8601(this.safeString(order, 'updated_at')), 'symbol': symbol, 'type': type, 'timeInForce': timeInForce, 'postOnly': this.safeValue(order, 'post_only'), 'side': side, 'price': price, 'stopPrice': triggerPrice, 'triggerPrice': triggerPrice, 'amount': amount, 'cost': cost, 'average': this.safeString(order, 'avg_deal_price'), 'filled': filled, 'remaining': undefined, 'status': this.parseOrderStatus(this.safeString(order, 'state')), 'fee': undefined, 'trades': undefined, }, market); } async createMarketBuyOrderWithCost(symbol, cost, params = {}) { /** * @method * @name bigone#createMarketBuyOrderWithCost * @description create a market buy order by providing the symbol and cost * @see https://open.big.one/docs/spot_orders.html#create-order * @param {string} symbol unified symbol of the market to create an order in * @param {float} cost how much you want to trade in units of the quote currency * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ await this.loadMarkets(); const market = this.market(symbol); if (!market['spot']) { throw new NotSupported(this.id + ' createMarketBuyOrderWithCost() supports spot orders only'); } params['createMarketBuyOrderRequiresPrice'] = false; return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params); } async createOrder(symbol, type, side, amount, price = undefined, params = {}) { /** * @method * @name bigone#createOrder * @description create a trade order * @see https://open.big.one/docs/spot_orders.html#create-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} [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 exchange API endpoint * @param {float} [params.triggerPrice] the price at which a trigger order is triggered at * @param {bool} [params.postOn