@proton/ccxt
Version:
A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 130+ exchanges
1,134 lines (1,131 loc) • 187 kB
JavaScript
// ----------------------------------------------------------------------------
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
// EDIT THE CORRESPONDENT .ts FILE INSTEAD
// ---------------------------------------------------------------------------
import Exchange from './abstract/zb.js';
import { BadRequest, BadSymbol, ExchangeError, ArgumentsRequired, AuthenticationError, InsufficientFunds, NotSupported, OrderNotFound, ExchangeNotAvailable, RateLimitExceeded, PermissionDenied, InvalidOrder, InvalidAddress, OnMaintenance, RequestTimeout, AccountSuspended, NetworkError, DDoSProtection, DuplicateOrderId, BadResponse } 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';
import { sha1 } from './static_dependencies/noble-hashes/sha1.js';
import { md5 } from './static_dependencies/noble-hashes/md5.js';
// ---------------------------------------------------------------------------
export default class zb extends Exchange {
describe() {
return this.deepExtend(super.describe(), {
'id': 'zb',
'name': 'ZB',
'countries': ['CN'],
// previously rateLimit = 100
// Trading and Margin 10 000 per minute (IP) => 10000 / 60 = 166.66666... per second => rateLimit = 1000/166.66666 = 6
// Trade and Margin 60 per second (apiKey) => weight = 166.666 / 60 = 2.778 (2.7777777...)
// Kline 1 per second => weight = 166.667
// v2 Futures API 100 per 2 seconds => 50 per second => weight = 3.334 (3.3333333...)
// for endpoints not mentioned in docs
// previous rateLimit was 100 translating to 10 requests per second => weight = 166.666 / 10 = 16.667 (16.666666...)
'rateLimit': 6,
'version': 'v1',
'pro': true,
'has': {
'CORS': undefined,
'spot': true,
'margin': true,
'swap': true,
'future': undefined,
'option': undefined,
'addMargin': true,
'borrowMargin': true,
'cancelAllOrders': true,
'cancelOrder': true,
'createMarketOrder': false,
'createOrder': true,
'createReduceOnlyOrder': false,
'createStopLimitOrder': true,
'createStopMarketOrder': true,
'createStopOrder': true,
'fetchBalance': true,
'fetchBorrowRate': true,
'fetchBorrowRateHistories': false,
'fetchBorrowRateHistory': false,
'fetchBorrowRates': true,
'fetchCanceledOrders': true,
'fetchClosedOrders': true,
'fetchCurrencies': true,
'fetchDepositAddress': true,
'fetchDepositAddresses': true,
'fetchDeposits': true,
'fetchFundingHistory': false,
'fetchFundingRate': true,
'fetchFundingRateHistory': true,
'fetchFundingRates': true,
'fetchIndexOHLCV': true,
'fetchLedger': true,
'fetchLeverage': false,
'fetchLeverageTiers': false,
'fetchMarketLeverageTiers': false,
'fetchMarkets': true,
'fetchMarkOHLCV': true,
'fetchOHLCV': true,
'fetchOpenOrders': true,
'fetchOrder': true,
'fetchOrderBook': true,
'fetchOrders': true,
'fetchPosition': true,
'fetchPositions': true,
'fetchPositionsRisk': false,
'fetchPremiumIndexOHLCV': false,
'fetchTicker': true,
'fetchTickers': true,
'fetchTrades': true,
'fetchTradingFee': false,
'fetchTradingFees': false,
'fetchWithdrawals': true,
'reduceMargin': true,
'setLeverage': true,
'setMarginMode': false,
'setPositionMode': false,
'transfer': true,
'withdraw': true,
},
'timeframes': {
'1m': '1m',
'3m': '3m',
'5m': '5m',
'15m': '15m',
'30m': '30m',
'1h': '1h',
'2h': '2h',
'4h': '4h',
'6h': '6h',
'12h': '12h',
'1d': '1d',
'3d': '3d',
'5d': '5d',
'1w': '1w',
},
'hostname': 'zb.com',
'urls': {
'logo': 'https://user-images.githubusercontent.com/1294454/32859187-cd5214f0-ca5e-11e7-967d-96568e2e2bd1.jpg',
'api': {
'spot': {
'v1': {
'public': 'https://api.{hostname}/data',
'private': 'https://trade.{hostname}/api',
},
},
'contract': {
'v1': {
'public': 'https://fapi.{hostname}/api/public',
},
'v2': {
'public': 'https://fapi.{hostname}/Server/api',
'private': 'https://fapi.{hostname}/Server/api',
},
},
},
'www': 'https://www.zb.com',
'doc': 'https://www.zb.com/i/developer',
'fees': 'https://www.zb.com/i/rate',
'referral': {
'url': 'https://www.zb.com/en/register?ref=4301lera',
'discount': 0.16,
},
},
'api': {
'spot': {
'v1': {
'public': {
'get': {
'markets': 16.667,
'ticker': 16.667,
'allTicker': 16.667,
'depth': 16.667,
'trades': 16.667,
'kline': 166.667,
'getGroupMarkets': 16.667,
'getFeeInfo': 16.667,
},
},
'private': {
'get': {
// spot API
'order': 1,
'orderMoreV2': 1,
'cancelOrder': 1,
'cancelAllOrdersAfter': 1,
'getOrder': 1,
'getOrders': 1,
'getOrdersNew': 16.667,
'getOrdersIgnoreTradeType': 1,
'getUnfinishedOrdersIgnoreTradeType': 1,
'getFinishedAndPartialOrders': 1,
'getAccountInfo': 16.667,
'getUserAddress': 16.667,
'getPayinAddress': 16.667,
'getWithdrawAddress': 16.667,
'getWithdrawRecord': 16.667,
'getChargeRecord': 16.667,
'getCnyWithdrawRecord': 16.667,
'getCnyChargeRecord': 16.667,
'withdraw': 16.667,
// sub accounts
'addSubUser': 16.667,
'getSubUserList': 16.667,
'doTransferFunds': 16.667,
'createSubUserKey': 16.667,
// leverage API
'getLeverAssetsInfo': 16.667,
'getLeverBills': 16.667,
'transferInLever': 16.667,
'transferOutLever': 16.667,
'loan': 16.667,
'cancelLoan': 16.667,
'getLoans': 16.667,
'getLoanRecords': 16.667,
'borrow': 16.667,
'autoBorrow': 16.667,
'repay': 16.667,
'doAllRepay': 16.667,
'getRepayments': 16.667,
'getFinanceRecords': 16.667,
'changeInvestMark': 16.667,
'changeLoop': 16.667,
// cross API
'getCrossAssets': 16.667,
'getCrossBills': 16.667,
'transferInCross': 16.667,
'transferOutCross': 16.667,
'doCrossLoan': 16.667,
'doCrossRepay': 16.667,
'getCrossRepayRecords': 16.667,
},
},
},
},
'contract': {
'v1': {
'public': {
'get': {
'depth': 16.667,
'fundingRate': 16.667,
'indexKline': 16.667,
'indexPrice': 16.667,
'kline': 16.667,
'markKline': 16.667,
'markPrice': 16.667,
'ticker': 16.667,
'trade': 16.667,
},
},
},
'v2': {
'public': {
'get': {
'allForceOrders': 3.334,
'config/marketList': 3.334,
'topLongShortAccountRatio': 3.334,
'topLongShortPositionRatio': 3.334,
'fundingRate': 3.334,
'premiumIndex': 3.334,
},
},
'private': {
'get': {
'Fund/balance': 3.334,
'Fund/getAccount': 3.334,
'Fund/getBill': 3.334,
'Fund/getBillTypeList': 3.334,
'Fund/marginHistory': 3.334,
'Positions/getPositions': 3.334,
'Positions/getNominalValue': 3.334,
'Positions/marginInfo': 3.334,
'setting/get': 3.334,
'trade/getAllOrders': 3.334,
'trade/getOrder': 3.334,
'trade/getOrderAlgos': 3.334,
'trade/getTradeList': 3.334,
'trade/getUndoneOrders': 3.334,
'trade/tradeHistory': 3.334,
},
'post': {
'activity/buyTicket': 3.334,
'Fund/transferFund': 3.334,
'Positions/setMarginCoins': 3.334,
'Positions/updateAppendUSDValue': 3.334,
'Positions/updateMargin': 3.334,
'setting/setLeverage': 3.334,
'setting/setPositionsMode': 3.334,
'trade/batchOrder': 3.334,
'trade/batchCancelOrder': 3.334,
'trade/cancelAlgos': 3.334,
'trade/cancelAllOrders': 3.334,
'trade/cancelOrder': 3.334,
'trade/order': 3.334,
'trade/orderAlgo': 3.334,
'trade/updateOrderAlgo': 3.334,
},
},
},
},
},
'fees': {
'funding': {
'withdraw': {},
},
'trading': {
'maker': this.parseNumber('0.002'),
'taker': this.parseNumber('0.002'),
},
},
'commonCurrencies': {
'ANG': 'Anagram',
'ENT': 'ENTCash',
'BCHABC': 'BCHABC',
'BCHSV': 'BCHSV', // conflict with BCH / BSV
},
'options': {
'timeframes': {
'spot': {
'1m': '1min',
'3m': '3min',
'5m': '5min',
'15m': '15min',
'30m': '30min',
'1h': '1hour',
'2h': '2hour',
'4h': '4hour',
'6h': '6hour',
'12h': '12hour',
'1d': '1day',
'3d': '3day',
'1w': '1week',
},
'swap': {
'1m': '1M',
'5m': '5M',
'15m': '15M',
'30m': '30M',
'1h': '1H',
'6h': '6H',
'1d': '1D',
'5d': '5D',
},
},
},
'precisionMode': TICK_SIZE,
'exceptions': {
'ws': {
// '1000': ExchangeError, // The call is successful.
'1001': ExchangeError,
'1002': ExchangeError,
'1003': AuthenticationError,
'1004': AuthenticationError,
'1005': AuthenticationError,
'1006': PermissionDenied,
'1007': ExchangeError,
'1009': OnMaintenance,
'1010': ExchangeNotAvailable,
'1012': PermissionDenied,
'1013': ExchangeError,
'1014': ExchangeError,
'2001': InsufficientFunds,
'2002': InsufficientFunds,
'2003': InsufficientFunds,
'2005': InsufficientFunds,
'2006': InsufficientFunds,
'2007': InsufficientFunds,
'2008': InsufficientFunds,
'2009': InsufficientFunds,
'3001': OrderNotFound,
'3002': InvalidOrder,
'3003': InvalidOrder,
'3004': AuthenticationError,
'3005': BadRequest,
'3006': PermissionDenied,
'3007': RequestTimeout,
'3008': ExchangeError,
'3009': InvalidOrder,
'3010': PermissionDenied,
'3011': InvalidOrder,
'3012': InvalidOrder,
'4001': AccountSuspended,
'4002': RateLimitExceeded, // Request too frequently
},
'exact': {
// '1000': 'Successful operation',
'10001': ExchangeError,
'10002': PermissionDenied,
'10003': BadResponse,
'10004': BadResponse,
'10005': PermissionDenied,
'10006': BadRequest,
'10007': ExchangeError,
'10008': ExchangeError,
'10009': ExchangeError,
'1001': ExchangeError,
'10010': AuthenticationError,
'10011': AuthenticationError,
'10012': AccountSuspended,
'10013': AuthenticationError,
'10014': AuthenticationError,
'10015': AuthenticationError,
'10016': AuthenticationError,
'10017': PermissionDenied,
'10018': AccountSuspended,
'10019': RequestTimeout,
'1002': ExchangeError,
'10020': BadRequest,
'10021': BadRequest,
'10022': BadRequest,
'10023': RateLimitExceeded,
'10024': AuthenticationError,
'10025': ExchangeError,
'10026': NetworkError,
'10027': RequestTimeout,
'10028': ExchangeNotAvailable,
'10029': DDoSProtection,
'1003': AuthenticationError,
'10030': BadRequest,
'10031': BadRequest,
'10032': BadRequest,
'10033': BadRequest,
'10034': BadRequest,
'10035': BadRequest,
'10036': BadRequest,
'10037': ArgumentsRequired,
'10038': BadRequest,
'10039': BadResponse,
'1004': AuthenticationError,
'10040': BadResponse,
'10041': BadResponse,
'10042': ExchangeError,
'10043': ExchangeError,
'10044': ExchangeError,
'10045': ExchangeError,
'10046': ExchangeError,
'10047': ExchangeError,
'10048': ExchangeError,
'10049': NetworkError,
'1005': AuthenticationError,
'1006': AuthenticationError,
'1009': ExchangeNotAvailable,
'1010': ExchangeNotAvailable,
'10100': OnMaintenance,
'1012': PermissionDenied,
'1013': ExchangeError,
'1014': ExchangeError,
'11000': ExchangeError,
'11001': ExchangeError,
'110011': ExchangeError,
'11002': ExchangeError,
'11003': ExchangeError,
'11004': InsufficientFunds,
'11005': InvalidOrder,
'11006': InsufficientFunds,
'11007': OrderNotFound,
'11008': ExchangeError,
'11009': ExchangeError,
'110110': ExchangeError,
'11012': InsufficientFunds,
'11013': ExchangeError,
'11014': ExchangeError,
'11015': AuthenticationError,
'11016': AuthenticationError,
'11017': ExchangeError,
'11018': InsufficientFunds,
'11019': ExchangeError,
'11021': InsufficientFunds,
'11023': ExchangeError,
'11030': PermissionDenied,
'11031': ExchangeError,
'11032': ExchangeError,
'11033': ArgumentsRequired,
'11034': ExchangeError,
'12000': InvalidOrder,
'12001': InvalidOrder,
'12002': InvalidOrder,
'12003': InvalidOrder,
'12004': InvalidOrder,
'12005': InvalidOrder,
'12006': InvalidOrder,
'12007': InvalidOrder,
'12008': InvalidOrder,
'12009': InvalidOrder,
'12010': InvalidOrder,
'12011': InvalidOrder,
'12012': OrderNotFound,
'12013': InvalidOrder,
'12014': InvalidOrder,
'12015': InvalidOrder,
'12016': InvalidOrder,
'12017': InvalidOrder,
'12018': InvalidOrder,
'12019': ArgumentsRequired,
'12020': ExchangeError,
'12021': InvalidOrder,
'12022': InvalidOrder,
'12023': OrderNotFound,
'12024': InvalidOrder,
'12025': InvalidOrder,
'12026': DuplicateOrderId,
'12027': ExchangeNotAvailable,
'12028': InvalidOrder,
'12029': InvalidOrder,
'12201': InvalidOrder,
'12202': InvalidOrder,
'12203': InvalidOrder,
'12204': InvalidOrder,
'12205': InvalidOrder,
'12206': InvalidOrder,
'12207': RateLimitExceeded,
'13001': AuthenticationError,
'13002': PermissionDenied,
// '13003': AuthenticationError, // User is locked
'13003': InvalidOrder,
'13004': InvalidOrder,
'13005': RateLimitExceeded,
'13006': ExchangeError,
'13007': ExchangeError,
'13008': ExchangeError,
'13009': ExchangeError,
'14000': ExchangeError,
'14001': AuthenticationError,
'14002': AuthenticationError,
'14003': ExchangeError,
'14100': ExchangeError,
'14101': RateLimitExceeded,
'14200': ArgumentsRequired,
'14300': ExchangeError,
'14301': ExchangeError,
'14302': ExchangeError,
'14303': ExchangeError,
'14305': ExchangeError,
'14306': ExchangeError,
'14307': InvalidOrder,
'14308': InvalidOrder,
'14309': ExchangeError,
'14310': NotSupported,
'14311': NotSupported,
'14312': ExchangeError,
'14313': PermissionDenied,
'14314': ExchangeError,
'2001': InsufficientFunds,
'2002': InsufficientFunds,
'2003': InsufficientFunds,
'2005': InsufficientFunds,
'2006': InsufficientFunds,
'2007': InsufficientFunds,
'2008': InsufficientFunds,
'2009': InsufficientFunds,
'3001': OrderNotFound,
'3002': InvalidOrder,
'3003': InvalidOrder,
'3004': AuthenticationError,
'3005': BadRequest,
'3006': AuthenticationError,
'3007': AuthenticationError,
'3008': OrderNotFound,
'3009': InvalidOrder,
'3010': PermissionDenied,
'3011': InvalidOrder,
'3012': InvalidOrder,
'4001': ExchangeNotAvailable,
'4002': RateLimitExceeded,
'9999': ExchangeError, // Unknown error
},
'broad': {
'提币地址有误, 请先添加提币地址。': InvalidAddress,
'资金不足,无法划账': InsufficientFunds,
'响应超时': RequestTimeout, // {"code":1001,"message":"响应超时"}
},
},
});
}
async fetchMarkets(params = {}) {
/**
* @method
* @name zb#fetchMarkets
* @description retrieves data on all markets for zb
* @param {object} params extra parameters specific to the exchange api endpoint
* @returns {[object]} an array of objects representing market data
*/
//
// {
// "zb_qc":{
// "amountScale":2,
// "minAmount":0.01,
// "minSize":5,
// "priceScale":4,
// },
// }
//
let promises = [this.spotV1PublicGetMarkets(params), this.contractV2PublicGetConfigMarketList(params)];
promises = await Promise.all(promises);
const markets = promises[0];
const contracts = promises[1];
//
// {
// BTC_USDT: {
// symbol: 'BTC_USDT',
// buyerCurrencyId: '6',
// contractType: '1',
// defaultMarginMode: '1',
// marketType: '2',
// historyDBName: 'trade_history_readonly.dbc',
// defaultLeverage: '20',
// id: '100',
// canCancelOrder: true,
// area: '1',
// mixMarginCoinName: 'usdt',
// fundingRateRatio: '0.25',
// marginCurrencyName: 'usdt',
// minTradeMoney: '0.0001',
// enableTime: '1638954000000',
// maxTradeMoney: '10000000',
// canTrade: true,
// maxLeverage: '125',
// defaultPositionsMode: '2',
// onlyWhitelistVisible: false,
// riskWarnRatio: '0.8',
// marginDecimal: '8',
// spot: false,
// status: '1',
// amountDecimal: '3',
// leverage: false,
// minAmount: '0.001',
// canOrder: true,
// duration: '1',
// feeDecimal: '8',
// sellerCurrencyId: '1',
// maxAmount: '1000',
// canOpenPosition: true,
// isSupportMixMargin: false,
// markPriceLimitRate: '0.05',
// marginCurrencyId: '6',
// stopFundingFee: false,
// priceDecimal: '2',
// lightenUpFeeRate: '0',
// futures: true,
// sellerCurrencyName: 'btc',
// marketPriceLimitRate: '0.05',
// canRebate: true,
// marketName: 'BTC_USDT',
// depth: [ 0.01, 0.1, 1 ],
// createTime: '1607590430094',
// mixMarginCoinIds: [ 6 ],
// buyerCurrencyName: 'usdt',
// stopService: false
// },
// }
//
const contractsData = this.safeValue(contracts, 'data', []);
const contractsById = this.indexBy(contractsData, 'marketName');
const dataById = this.deepExtend(contractsById, markets);
const keys = Object.keys(dataById);
const result = [];
for (let i = 0; i < keys.length; i++) {
const id = keys[i];
const market = dataById[id];
const [baseId, quoteId] = id.split('_');
const base = this.safeCurrencyCode(baseId);
const quote = this.safeCurrencyCode(quoteId);
const settleId = this.safeValue(market, 'marginCurrencyName');
const settle = this.safeCurrencyCode(settleId);
const spot = settle === undefined;
const swap = this.safeValue(market, 'futures', false);
const linear = swap ? true : undefined;
let active = true;
let symbol = base + '/' + quote;
if (swap) {
const status = this.safeString(market, 'status');
active = (status === '1');
symbol = base + '/' + quote + ':' + settle;
}
result.push({
'id': id,
'symbol': symbol,
'base': base,
'quote': quote,
'settle': settle,
'baseId': baseId,
'quoteId': quoteId,
'settleId': settleId,
'type': swap ? 'swap' : 'spot',
'spot': spot,
'margin': false,
'swap': swap,
'future': false,
'option': false,
'active': active,
'contract': swap,
'linear': linear,
'inverse': swap ? !linear : undefined,
'contractSize': undefined,
'expiry': undefined,
'expiryDatetime': undefined,
'strike': undefined,
'optionType': undefined,
'precision': {
'amount': this.parseNumber(this.parsePrecision(this.safeString2(market, 'amountScale', 'amountDecimal'))),
'price': this.parseNumber(this.parsePrecision(this.safeString2(market, 'priceScale', 'priceDecimal'))),
},
'limits': {
'leverage': {
'min': undefined,
'max': this.safeNumber(market, 'maxLeverage'),
},
'amount': {
'min': this.safeNumber(market, 'minAmount'),
'max': this.safeNumber(market, 'maxAmount'),
},
'price': {
'min': undefined,
'max': undefined,
},
'cost': {
'min': this.safeNumber2(market, 'minSize', 'minTradeMoney'),
'max': this.safeNumber(market, 'maxTradeMoney'),
},
},
'info': market,
});
}
return result;
}
async fetchCurrencies(params = {}) {
/**
* @method
* @name zb#fetchCurrencies
* @description fetches all available currencies on an exchange
* @param {object} params extra parameters specific to the zb api endpoint
* @returns {object} an associative dictionary of currencies
*/
const response = await this.spotV1PublicGetGetFeeInfo(params);
//
// {
// "code":1000,
// "message":"success",
// "result":{
// "USDT":[
// {
// "chainName":"TRC20",
// "canWithdraw":true,
// "fee":1.0,
// "mainChainName":"TRX",
// "canDeposit":true
// },
// {
// "chainName":"OMNI",
// "canWithdraw":true,
// "fee":5.0,
// "mainChainName":"BTC",
// "canDeposit":true
// },
// {
// "chainName":"ERC20",
// "canWithdraw":true,
// "fee":15.0,
// "mainChainName":"ETH",
// "canDeposit":true
// }
// ],
// }
// }
//
const currencies = this.safeValue(response, 'result', {});
const ids = Object.keys(currencies);
const result = {};
for (let i = 0; i < ids.length; i++) {
const id = ids[i];
const currency = currencies[id];
const code = this.safeCurrencyCode(id);
let isWithdrawEnabled = true;
let isDepositEnabled = true;
const fees = {};
for (let j = 0; j < currency.length; j++) {
const networkItem = currency[j];
const network = this.safeString2(networkItem, 'chainName', 'mainChainName');
// const name = this.safeString (networkItem, 'name');
const withdrawFee = this.safeNumber(networkItem, 'fee');
const depositEnable = this.safeValue(networkItem, 'canDeposit');
const withdrawEnable = this.safeValue(networkItem, 'canWithdraw');
isDepositEnabled = isDepositEnabled || depositEnable;
isWithdrawEnabled = isWithdrawEnabled || withdrawEnable;
fees[network] = withdrawFee;
}
const active = (isWithdrawEnabled && isDepositEnabled);
result[code] = {
'id': id,
'name': undefined,
'code': code,
'precision': undefined,
'info': currency,
'active': active,
'deposit': isDepositEnabled,
'withdraw': isWithdrawEnabled,
'fee': undefined,
'fees': fees,
'limits': this.limits,
};
}
return result;
}
parseBalance(response) {
const balances = this.safeValue(response['result'], 'coins');
const result = {
'info': response,
};
for (let i = 0; i < balances.length; i++) {
const balance = balances[i];
// { enName: "BTC",
// freez: "0.00000000",
// unitDecimal: 8, // always 8
// cnName: "BTC",
// isCanRecharge: true, // TODO: should use this
// unitTag: "฿",
// isCanWithdraw: true, // TODO: should use this
// available: "0.00000000",
// key: "btc" }
const account = this.account();
const currencyId = this.safeString(balance, 'key');
const code = this.safeCurrencyCode(currencyId);
account['free'] = this.safeString(balance, 'available');
account['used'] = this.safeString(balance, 'freez');
result[code] = account;
}
return this.safeBalance(result);
}
parseSwapBalance(response) {
const result = {
'info': response,
};
const data = this.safeValue(response, 'data', {});
for (let i = 0; i < data.length; i++) {
const balance = data[i];
//
// {
// "userId": "6896693805014120448",
// "currencyId": "6",
// "currencyName": "usdt",
// "amount": "30.56585118",
// "freezeAmount": "0",
// "contractType": 1,
// "id": "6899113714763638819",
// "createTime": "1644876888934",
// "modifyTime": "1645787446037",
// "accountBalance": "30.56585118",
// "allMargin": "0",
// "allowTransferOutAmount": "30.56585118"
// },
//
const code = this.safeCurrencyCode(this.safeString(balance, 'currencyName'));
const account = this.account();
account['total'] = this.safeString(balance, 'accountBalance');
account['free'] = this.safeString(balance, 'allowTransferOutAmount');
account['used'] = this.safeString(balance, 'freezeAmount');
result[code] = account;
}
return this.safeBalance(result);
}
parseMarginBalance(response, marginMode) {
const result = {
'info': response,
};
let levers = undefined;
if (marginMode === 'isolated') {
const message = this.safeValue(response, 'message', {});
const data = this.safeValue(message, 'datas', {});
levers = this.safeValue(data, 'levers', []);
}
else {
const crossResponse = this.safeValue(response, 'result', {});
levers = this.safeValue(crossResponse, 'list', []);
}
for (let i = 0; i < levers.length; i++) {
const balance = levers[i];
//
// Isolated Margin
//
// {
// "cNetUSD": "0.00",
// "repayLeverShow": "-",
// "cCanLoanIn": "0.002115400000000",
// "fNetCNY": "147.76081161",
// "fLoanIn": "0.00",
// "repayLevel": 0,
// "level": 1,
// "netConvertCNY": "147.760811613032",
// "cFreeze": "0.00",
// "cUnitTag": "BTC",
// "version": 1646783178609,
// "cAvailableUSD": "0.00",
// "cNetCNY": "0.00",
// "riskRate": "-",
// "fAvailableUSD": "20.49273433",
// "fNetUSD": "20.49273432",
// "cShowName": "BTC",
// "leverMultiple": "5.00",
// "couldTransferOutFiat": "20.49273433",
// "noticeLine": "1.13",
// "fFreeze": "0.00",
// "cUnitDecimal": 8,
// "fCanLoanIn": "81.970937320000000",
// "cAvailable": "0.00",
// "repayLock": false,
// "status": 1,
// "forbidType": 0,
// "totalConvertCNY": "147.760811613032",
// "cAvailableCNY": "0.00",
// "unwindPrice": "0.00",
// "fOverdraft": "0.00",
// "fShowName": "USDT",
// "statusShow": "%E6%AD%A3%E5%B8%B8",
// "cOverdraft": "0.00",
// "netConvertUSD": "20.49273433",
// "cNetBtc": "0.00",
// "loanInConvertCNY": "0.00",
// "fAvailableCNY": "147.760811613032",
// "key": "btcusdt",
// "fNetBtc": "0.0005291",
// "fUnitDecimal": 8,
// "loanInConvertUSD": "0.00",
// "showName": "BTC/USDT",
// "startLine": "1.25",
// "totalConvertUSD": "20.49273433",
// "couldTransferOutCoin": "0.00",
// "cEnName": "BTC",
// "leverMultipleInterest": "3.00",
// "fAvailable": "20.49273433",
// "fEnName": "USDT",
// "forceRepayLine": "1.08",
// "cLoanIn": "0.00"
// }
//
// Cross Margin
//
// [
// {
// "fundType": 2,
// "loanIn": 0,
// "amount": 0,
// "freeze": 0,
// "overdraft": 0,
// "key": "BTC",
// "canTransferOut": 0
// },
// ],
//
const account = this.account();
if (marginMode === 'isolated') {
const code = this.safeCurrencyCode(this.safeString(balance, 'fShowName'));
account['total'] = this.safeString(balance, 'fAvailableUSD'); // total amount in USD
account['free'] = this.safeString(balance, 'couldTransferOutFiat');
account['used'] = this.safeString(balance, 'fFreeze');
result[code] = account;
}
else {
const code = this.safeCurrencyCode(this.safeString(balance, 'key'));
account['total'] = this.safeString(balance, 'amount');
account['free'] = this.safeString(balance, 'canTransferOut');
account['used'] = this.safeString(balance, 'freeze');
result[code] = account;
}
}
return this.safeBalance(result);
}
async fetchBalance(params = {}) {
/**
* @method
* @name zb#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 zb api endpoint
* @param {string} params.marginMode 'cross' or 'isolated'
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/en/latest/manual.html?#balance-structure}
*/
await this.loadMarkets();
const [marketType, marketTypeQuery] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
const [marginMode, query] = this.handleMarginModeAndParams('fetchBalance', marketTypeQuery);
const swap = (marketType === 'swap');
const marginMethod = (marginMode === 'cross') ? 'spotV1PrivateGetGetCrossAssets' : 'spotV1PrivateGetGetLeverAssetsInfo';
let method = this.getSupportedMapping(marketType, {
'spot': 'spotV1PrivateGetGetAccountInfo',
'swap': 'contractV2PrivateGetFundBalance',
'margin': marginMethod,
});
if (marginMode === 'isolated') {
method = 'spotV1PrivateGetGetLeverAssetsInfo';
}
else if (marginMode === 'cross') {
method = 'spotV1PrivateGetGetCrossAssets';
}
const request = {
// 'futuresAccountType': 1, // SWAP
// 'currencyId': currency['id'], // SWAP
// 'currencyName': 'usdt', // SWAP
};
if (swap) {
request['futuresAccountType'] = 1;
}
const response = await this[method](this.extend(request, query));
//
// Spot
//
// {
// "result": {
// "coins": [
// {
// "isCanWithdraw": "true",
// "canLoan": false,
// "fundstype": 51,
// "showName": "ZB",
// "isCanRecharge": "true",
// "cnName": "ZB",
// "enName": "ZB",
// "available": "0",
// "freez": "0",
// "unitTag": "ZB",
// "key": "zb",
// "unitDecimal": 8
// },
// ],
// "version": 1645856691340,
// "base": {
// "auth_google_enabled": true,
// "auth_mobile_enabled": false,
// "trade_password_enabled": true,
// "username": "blank@gmail.com"
// }
// },
// "leverPerm": true,
// "otcPerm": false,
// "assetPerm": true,
// "moneyPerm": true,
// "subUserPerm": true,
// "entrustPerm": true
// }
//
// Swap
//
// {
// "code": 10000,
// "data": [
// {
// "userId": "6896693805014120448",
// "currencyId": "6",
// "currencyName": "usdt",
// "amount": "30.56585118",
// "freezeAmount": "0",
// "contractType": 1,
// "id": "6899113714763638819",
// "createTime": "1644876888934",
// "modifyTime": "1645787446037",
// "accountBalance": "30.56585118",
// "allMargin": "0",
// "allowTransferOutAmount": "30.56585118"
// },
// ],
// "desc": "操作成功"
// }
//
// Isolated Margin
//
// {
// "code": 1000,
// "message": {
// "des": "success",
// "isSuc": true,
// "datas": {
// "leverPerm": true,
// "levers": [
// {
// "cNetUSD": "0.00",
// "repayLeverShow": "-",
// "cCanLoanIn": "0.002115400000000",
// "fNetCNY": "147.76081161",
// "fLoanIn": "0.00",
// "repayLevel": 0,
// "level": 1,
// "netConvertCNY": "147.760811613032",
// "cFreeze": "0.00",
// "cUnitTag": "BTC",
// "version": 1646783178609,
// "cAvailableUSD": "0.00",
// "cNetCNY": "0.00",
// "riskRate": "-",
// "fAvailableUSD": "20.49273433",
// "fNetUSD": "20.49273432",
// "cShowName": "BTC",
// "leverMultiple": "5.00",
// "couldTransferOutFiat": "20.49273433",
// "noticeLine": "1.13",
// "fFreeze": "0.00",
// "cUnitDecimal": 8,
// "fCanLoanIn": "81.970937320000000",
// "cAvailable": "0.00",
// "repayLock": false,
// "status": 1,
// "forbidType": 0,
// "totalConvertCNY": "147.760811613032",
// "cAvailableCNY": "0.00",
// "unwindPrice": "0.00",
// "fOverdraft": "0.00",
// "fShowName": "USDT",
// "statusShow": "%E6%AD%A3%E5%B8%B8",
// "cOverdraft": "0.00",
// "netConvertUSD": "20.49273433",
// "cNetBtc": "0.00",
// "loanInConvertCNY": "0.00",
// "fAvailableCNY": "147.760811613032",
// "key": "btcusdt",
// "fNetBtc": "0.0005291",
// "fUnitDecimal": 8,
// "loanInConvertUSD": "0.00",
// "showName": "BTC/USDT",
// "startLine": "1.25",
// "totalConvertUSD": "20.49273433",
// "couldTransferOutCoin": "0.00",
// "cEnName": "BTC",
// "leverMultipleInterest": "3.00",
// "fAvailable": "20.49273433",
// "fEnName": "USDT",
// "forceRepayLine": "1.08",
// "cLoanIn": "0.00"
// }
// ]
// }
// }
// }
//
// Cross Margin
//
// {
// "code": 1000,
// "message": "操作成功",
// "result": {
// "loanIn": 0,
// "total": 71.167,
// "riskRate": "-",
// "list" :[
// {
// "fundType": 2,
// "loanIn": 0,
// "amount": 0,
// "freeze": 0,
// "overdraft": 0,
// "key": "BTC",
// "canTransferOut": 0
// },
// ],
// "net": 71.167
// }
// }
//
// todo: use this somehow
// let permissions = response['result']['base'];
if (swap) {
return this.parseSwapBalance(response);
}
else if (marginMode !== undefined) {
return this.parseMarginBalance(response, marginMode);
}