ccxt
Version:
1,108 lines (1,106 loc) • 84.6 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/zebpay.js';
import { TICK_SIZE } from './base/functions/number.js';
import { BadRequest, AuthenticationError, NotSupported, RateLimitExceeded, ExchangeNotAvailable, ExchangeError, ArgumentsRequired, InvalidOrder, OrderNotFound, InsufficientFunds } from './base/errors.js';
import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
import { Precise } from './base/Precise.js';
// ---------------------------------------------------------------------------
/**
* @class
* @augments Exchange
*/
export default class zebpay extends Exchange {
describe() {
return this.deepExtend(super.describe(), {
'id': 'zebpay',
'name': 'Zebpay',
'countries': ['IN'],
'rateLimit': 50,
'version': 'v1',
'certified': false,
'pro': false,
'has': {
'CORS': undefined,
'spot': true,
'margin': false,
'swap': true,
'future': false,
'option': undefined,
'addMargin': true,
'borrowCrossMargin': false,
'borrowIsolatedMargin': false,
'borrowMargin': false,
'cancelAllOrders': true,
'cancelOrder': true,
'cancelOrders': false,
'closePosition': true,
'createOrder': true,
'fetchBalance': true,
'fetchBorrowInterest': false,
'fetchBorrowRate': false,
'fetchBorrowRateHistories': false,
'fetchBorrowRateHistory': false,
'fetchBorrowRates': false,
'fetchBorrowRatesPerSymbol': false,
'fetchCrossBorrowRate': false,
'fetchCrossBorrowRates': false,
'fetchCurrencies': true,
'fetchIsolatedBorrowRate': false,
'fetchIsolatedBorrowRates': false,
'fetchLeverage': true,
'fetchLeverages': true,
'fetchMarkets': true,
'fetchMyTrades': true,
'fetchOHLCV': true,
'fetchOpenOrders': true,
'fetchOrder': true,
'fetchOrderBook': true,
'fetchOrderTrades': true,
'fetchPositions': true,
'fetchTicker': true,
'fetchTickers': true,
'fetchTrades': true,
'fetchTradingFee': true,
'reduceMargin': true,
'repayCrossMargin': false,
'repayIsolatedMargin': false,
'setLeverage': true,
},
'timeframes': {
'1m': 1,
'5m': 5,
'15m': 15,
'30m': 30,
'1h': 60,
'2h': 120,
'4h': 480,
'12h': 720,
'1d': 1440,
'1w': 10080,
},
'urls': {
'logo': 'https://github.com/user-attachments/assets/8094e7be-55a7-46f4-a087-0ca31b48ecad',
'api': {
'spot': 'https://sapi.zebpay.com',
'swap': 'https://futuresbe.zebpay.com',
},
'test': {
'spot': 'https://www.zebstage.com',
'swap': 'https://dev-futuresbe.zebstage.com',
},
'www': 'https://www.zebpay.com',
'doc': 'https://github.com/zebpay/zebpay-api-references',
'fees': 'https://zebpay.com/in/features/pricing',
},
'api': {
'public': {
'spot': {
'get': {
'v2/system/time': 10,
'v2/system/status': 10,
'v2/market/orderbook': 10,
'v2/market/trades': 10,
'v2/market/ticker': 10,
'v2/market/allTickers': 10,
'v2/ex/exchangeInfo': 10,
'v2/ex/currencies': 10,
'v2/market/klines': 10,
'v2/ex/tradefees': 10,
},
},
'swap': {
'get': {
'v1/system/time': 10,
'v1/system/status': 10,
'v1/exchange/tradefee': 10,
'v1/exchange/tradefees': 10,
'v1/market/orderBook': 10,
'v1/market/ticker24Hr': 10,
'v1/market/markets': 10,
'v1/market/aggTrade': 10,
},
'post': {
'v1/market/klines': 10,
},
},
},
'private': {
'spot': {
'post': {
'v2/ex/orders': 10,
},
'get': {
'v2/ex/orders': 10,
'v2/account/balance': 10,
'v2/ex/tradefee': 10,
'v2/ex/order': 10,
'v2/ex/order/fills': 10,
},
'delete': {
'v2/ex/order': 10,
'v2/ex/orders': 10,
'v2/ex/orders/cancelAll': 10,
},
},
'swap': {
'get': {
'v1/wallet/balance': 10,
'v1/trade/order': 10,
'v1/trade/order/open-orders': 10,
'v1/trade/userLeverages': 10,
'v1/trade/userLeverage': 10,
'v1/trade/positions': 10,
'v1/trade/history': 10,
},
'post': {
'v1/trade/order': 10,
'v1/trade/order/addTPSL': 10,
'v1/trade/addMargin': 10,
'v1/trade/reduceMargin': 10,
'v1/trade/position/close': 10,
'v1/trade/update/userLeverage': 10,
},
'delete': {
'v1/trade/order': 10,
},
},
},
},
'precisionMode': TICK_SIZE,
'fees': {},
'commonCurrencies': {},
'requiredCredentials': {
'apiKey': true,
'secret': true,
},
'options': {
'fetchMarkets': {
'types': ['spot', 'swap'],
},
'defaultType': 'spot', // 'spot', 'swap'
},
'features': {
'default': {
'fetchOHLCV': {
'limit': 100,
},
},
},
'exceptions': {
'exact': {
'77': InvalidOrder,
'400': BadRequest,
'401': AuthenticationError,
'403': NotSupported,
'404': NotSupported,
'429': RateLimitExceeded,
'500': ExchangeNotAvailable,
'503': ExchangeNotAvailable,
'3013': OrderNotFound,
'Order quantity is out of range': InvalidOrder,
'Invalid trade order type': InvalidOrder,
'Insufficient margin': InsufficientFunds,
'insufficient balance': InsufficientFunds,
'leverage must be in [1,8]': BadRequest,
'the request you sent is invalid': BadRequest,
},
'broad': {
'InvalidOrder': InvalidOrder, // Rate should be in the range of
},
},
});
}
/**
* @method
* @name zebpay#fetchStatus
* @description the latest known information on the availability of the exchange API
* @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#system-status
* @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/system.md#get-system-status
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [status structure]{@link https://docs.ccxt.com/?id=exchange-status-structure}
*/
async fetchStatus(params = {}) {
let type = undefined;
[type, params] = this.handleMarketTypeAndParams('fetchStatus', undefined, params);
const isSpot = (type === 'spot');
let response = undefined;
let data = {};
if (isSpot) {
response = await this.publicSpotGetV2SystemStatus(params);
data = response;
}
else {
response = await this.publicSwapGetV1SystemStatus(params);
data = this.safeDict(response, 'data', {});
}
//
// {
// "statusDescription": "OK",
// "data":
// {
// "systemStatus": "ok"
// }
// "statusCode": 200,
// "customMessage": ["OK"]
// }
//
const status = this.safeString2(data, 'systemStatus', 'status');
return {
'status': status,
'updated': undefined,
'eta': undefined,
'url': undefined,
'info': response,
};
}
/**
* @method
* @name zebpayfutures#fetchTime
* @description fetches the current integer timestamp in milliseconds from the poloniexfutures server
* @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-server-time
* @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/system.md#get-system-time
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {int} the current integer timestamp in milliseconds from the poloniexfutures server
*/
async fetchTime(params = {}) {
let type = undefined;
[type, params] = this.handleMarketTypeAndParams('fetchTime', undefined, params);
const isSpot = (type === 'spot');
let response = undefined;
let data = {};
if (isSpot) {
response = await this.publicSpotGetV2SystemTime(params);
data = response;
}
else {
response = await this.publicSwapGetV1SystemTime(params);
data = this.safeDict(response, 'data', {});
}
//
// {
// "statusDescription": "OK",
// "data":
// {
// "timestamp": 1546837113087
// }
// "statusCode": 200,
// "customMessage": ["OK"]
// }
//
const time = this.safeInteger(data, 'timestamp');
return time;
}
/**
* @method
* @name zebpay#fetchMarkets
* @description retrieves data on all markets for zebpay
* @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-trading-pairs
* @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/market.md#fetch-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 promisesUnresolved = [];
const fetchMarketsOptions = this.safeDict(this.options, 'fetchMarkets');
const defaultMarkets = ['spot', 'swap'];
const types = this.safeList(fetchMarketsOptions, 'types', defaultMarkets);
for (let i = 0; i < types.length; i++) {
const type = types[i];
if (type === 'spot') {
promisesUnresolved.push(this.fetchSpotMarkets(params));
}
else if (type === 'swap') {
promisesUnresolved.push(this.fetchSwapMarkets(params));
}
else {
throw new ExchangeError(this.id + ' fetchMarkets() this.options fetchMarkets "' + type + '" is not a supported market type');
}
}
const promises = await Promise.all(promisesUnresolved);
const spotMarkets = this.safeList(promises, 0, []);
const futureMarkets = this.safeList(promises, 1, []);
return this.arrayConcat(spotMarkets, futureMarkets);
}
/**
* @method
* @name zebpay#fetchCurrencies
* @description fetches all available currencies on an exchange
* @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-coin-settings
* @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.publicSpotGetV2ExCurrencies(params);
//
// {
// "data": [
// {
// "currency": "BTC",
// "name": "BTC",
// "fullName": "150",
// "precision": "0.2",
// "type": "fiat",
// "isDebitEnabled": false,
// "chains": [
// {
// "chainName": "Bitcoin",
// "withdrawalMinSize": "0.000482",
// "depositMinSize": "0.00000001",
// "withdrawalFee": "0.00040000",
// "isWithdrawEnabled": "true",
// "isDepositEnabled": "true",
// "contractAddress": "0x095418A82BC2439703b69fbE1210824F2247D77c",
// "withdrawPrecision": "8",
// "maxWithdraw": "2.43090487000000",
// "maxDeposit": "100.00000000",
// "needTag": "false",
// "chainId": "bitcoin",
// "AddressRegex": "^tb1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{39,59}|m[a-zA-Z0-9]{25,34}|n[a-zA-Z0-9]{25,34}|^2[a-zA-Z0-9]{25,34}$"
// }
// ]
// }
// ]
// }
//
const rows = this.safeList(response, 'data', []);
const result = {};
for (let i = 0; i < rows.length; i++) {
const currency = rows[i];
const currencyId = this.safeString(currency, 'currency');
const code = this.safeCurrencyCode(currencyId);
const name = this.safeString(currency, 'name');
const precision = this.parseNumber(this.parsePrecision(this.safeString(currency, 'precision')));
const chains = this.safeList(currency, 'chains', []);
const networks = {};
let minWithdrawFeeString = undefined;
let minWithdrawString = undefined;
let minDepositString = undefined;
let deposit = false;
let withdraw = false;
for (let j = 0; j < chains.length; j++) {
const chain = chains[j];
const networkId = this.safeString(chain, 'chainId');
const networkCode = this.networkIdToCode(networkId);
const depositAllowed = this.safeBool(chain, 'isDepositEnabled') === true;
deposit = (depositAllowed) ? depositAllowed : deposit;
const withdrawAllowed = this.safeBool(chain, 'isWithdrawEnabled') === true;
withdraw = (withdrawAllowed) ? withdrawAllowed : withdraw;
const withdrawFeeString = this.safeString(chain, 'withdrawalFee');
if (withdrawFeeString !== undefined) {
minWithdrawFeeString = (minWithdrawFeeString === undefined) ? withdrawFeeString : Precise.stringMin(withdrawFeeString, minWithdrawFeeString);
}
const minNetworkWithdrawString = this.safeString(chain, 'withdrawalMinSize');
if (minNetworkWithdrawString !== undefined) {
minWithdrawString = (minWithdrawString === undefined) ? minNetworkWithdrawString : Precise.stringMin(minNetworkWithdrawString, minWithdrawString);
}
const minNetworkDepositString = this.safeString(chain, 'depositMinSize');
if (minNetworkDepositString !== undefined) {
minDepositString = (minDepositString === undefined) ? minNetworkDepositString : Precise.stringMin(minNetworkDepositString, minDepositString);
}
networks[networkCode] = {
'info': chain,
'id': networkId,
'network': networkCode,
'active': depositAllowed && withdrawAllowed,
'deposit': depositAllowed,
'withdraw': withdrawAllowed,
'fee': this.parseNumber(withdrawFeeString),
'precision': precision,
'limits': {
'withdraw': {
'min': this.parseNumber(minNetworkWithdrawString),
'max': undefined,
},
'deposit': {
'min': this.parseNumber(minNetworkDepositString),
'max': undefined,
},
},
};
}
result[code] = this.safeCurrencyStructure({
'info': currency,
'code': code,
'id': currencyId,
'name': name,
'active': deposit && withdraw,
'deposit': deposit,
'withdraw': withdraw,
'fee': this.parseNumber(minWithdrawFeeString),
'precision': precision,
'limits': {
'amount': {
'min': undefined,
'max': undefined,
},
'withdraw': {
'min': this.parseNumber(minWithdrawString),
'max': undefined,
},
'deposit': {
'min': this.parseNumber(minDepositString),
'max': undefined,
},
},
'networks': networks,
});
}
return result;
}
/**
* @method
* @name zebpay#fetchTradingFee
* @description fetch the trading fees for a market
* @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/private-endpoints.md#get-exchange-fee
* @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/exchange.md#get-trade-fee-single-symbol
* @param {string} symbol unified symbol of the market to fetch the order book for
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {object} [params.side] side to fetch trading fee
* @returns {object} a [status structure]{@link https://docs.ccxt.com/?id=exchange-status-structure}
*/
async fetchTradingFee(symbol, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
let response = undefined;
let data;
const request = {
'symbol': market['id'],
};
if (market['spot']) {
response = await this.privateSpotGetV2ExTradefee(this.extend(request, params));
//
// {
// "statusDescription": "Success",
// "data":
// {
// "symbol": "BTCINR",
// "takerFeeRate": "0.01",
// "makerFeeRate": "0.05",
// "percentage": true
// } ,
// "statusCode": 200,
// }
data = this.safeDict(response, 'data', {});
}
else {
response = await this.publicSwapGetV1ExchangeTradefee(this.extend(request, params));
//
// {
// "statusDescription": "OK",
// "data":
// [
// {
// "symbol": "BTCINR",
// "takerFee": "0.01",
// "makerFee": "0.05"
// }
// ] ,
// "statusCode": 200,
// "customMessage": ["OK"]
// }
//
const responseData = this.safeList(response, 'data', []);
data = this.safeDict(responseData, 0);
}
return this.parseTradingFee(data, market);
}
/**
* @method
* @name zebpay(futures)#fetchTradingFees
* @description fetch the trading fees for multiple markets
* @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/exchange.md#get-trade-fees-all-symbols
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [status structure]{@link https://docs.ccxt.com/?id=exchange-status-structure}
*/
async fetchTradingFees(params = {}) {
let type = undefined;
[type, params] = this.handleMarketTypeAndParams('fetchTradingFees', undefined, params);
let response = undefined;
if (type === 'spot') {
response = await this.publicSpotGetV2ExTradefees(params);
}
else {
response = await this.publicSwapGetV1ExchangeTradefees(params);
}
//
// {
// "statusDescription": "OK",
// "data": [
// {
// "symbol": "BTCINR",
// "takerFee": "0.01",
// "makerFee": "0.05"
// }
// ],
// "statusCode": 200,
// "customMessage": ["OK"]
// }
//
const fees = this.safeList(response, 'data', []);
const result = {};
for (let i = 0; i < fees.length; i++) {
const fee = this.parseTradingFee(fees[i]);
const symbol = fee['symbol'];
result[symbol] = fee;
}
return result;
}
/**
* @method
* @name zebpay#fetchOrderBook
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
* @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-order-book
* @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/market.md#get-order-book
* @param {string} symbol unified symbol of the market to fetch the order book for
* @param {int} [limit] the maximum amount of order book entries to return
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/?id=order-book-structure} indexed by market symbols
*/
async fetchOrderBook(symbol, limit = undefined, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const request = {
'symbol': market['id'],
};
let response = undefined;
if (market['spot']) {
if (limit !== undefined) {
request['limit'] = limit;
}
//
// {
// "asks": [
// [5000, 1000], //Price, quantity
// [6000, 1983] //Price, quantity
// ],
// "bids": [
// [3200, 800], //Price, quantity
// [3100, 100] //Price, quantity
// ],
// }
// }
response = await this.publicSpotGetV2MarketOrderbook(this.extend(request, params));
}
else {
response = await this.publicSwapGetV1MarketOrderBook(this.extend(request, params));
}
const bookData = this.safeDict(response, 'data', {});
const orderbook = this.parseOrderBook(bookData, market['symbol'], undefined, 'bids', 'asks', 0, 1);
orderbook['nonce'] = this.safeInteger(bookData, 'nonce');
return orderbook;
}
/**
* @method
* @name zebpay#fetchTicker
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
* @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-ticker
* @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/market.md#get-24hr-ticker
* @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 = {
'symbol': market['id'],
};
let response = undefined;
if (market['spot']) {
response = await this.publicSpotGetV2MarketTicker(this.extend(request, params));
//
// [
// {
// "symbol": "BTC-INR",
// "bestBid": "4900000",
// "bestBidQty": "0.00014938",
// "bestAsk": "",
// "bestAskQty": "0",
// "priceChange": "-98134.56",
// "priceChangePercent": "-1.84",
// "high": "5433400",
// "low": "5333400",
// "vol": "0.0002",
// "volValue": "1066.68",
// "last": "5333400"
// }
// ]
//
}
else {
response = await this.publicSwapGetV1MarketTicker24Hr(this.extend(request, params));
}
const data = this.safeDict(response, 'data', {});
return this.parseTicker(data, market);
}
/**
* @method
* @name zebpay#fetchTickers
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
* @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-all-tickers
* @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}
*/
async fetchTickers(symbols = undefined, params = {}) {
let type = undefined;
[type, params] = this.handleMarketTypeAndParams('fetchTickers', undefined, params);
if (type !== 'spot') {
throw new NotSupported(this.id + ' fetchTickers() does not support ' + type + ' markets');
}
await this.loadMarkets();
symbols = this.marketSymbols(symbols);
const response = await this.publicSpotGetV2MarketAllTickers(params);
//
// [
// {
// "symbol": "BTC-INR",
// "bestBid": "4900000",
// "bestBidQty": "0.00014938",
// "bestAsk": "",
// "bestAskQty": "0",
// "priceChange": "-98134.56",
// "priceChangePercent": "-1.84",
// "high": "5433400",
// "low": "5333400",
// "vol": "0.0002",
// "volValue": "1066.68",
// "last": "5333400"
// }
// ]
//
const tickerList = this.safeList(response, 'data', []);
return this.parseTickers(tickerList, symbols);
}
/**
* @method
* @name zebpay#fetchOHLCV
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
* @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-klinescandlesticks
* @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/market.md#-get-k-lines-ohlcv-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} [since] timestamp in ms of the earliest candle to fetch
* @param {int} [limit] the maximum amount of candles to fetch
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {int} [params.endtime] the latest time in ms to fetch orders for
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
*/
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
if (limit === undefined) {
limit = 100; // default is 200
}
const request = {
'symbol': market['id'],
};
if (market['spot']) {
request['interval'] = this.safeString(this.timeframes, timeframe, timeframe);
}
else {
request['interval'] = timeframe;
}
if (market['contract'] && (limit !== undefined)) {
request['limit'] = limit;
}
if (since !== undefined) {
if (market['spot']) {
request['startTime'] = since;
}
else {
request['since'] = since;
}
}
const until = this.safeInteger2(params, 'until', 'endtime');
if (until !== undefined) {
request['endTime'] = until;
params = this.omit(params, ['endtime', 'until']);
}
let response = undefined;
if (market['spot']) {
if (until === undefined || since === undefined) {
throw new ArgumentsRequired(this.id + ' fetchOHLCV() requires a both a since and until/endtime parameter for spot markets');
}
response = await this.publicSpotGetV2MarketKlines(this.extend(request, params));
}
else {
response = await this.publicSwapPostV1MarketKlines(this.extend(request, params));
}
//
// [
// [
// "1670608800000",
// "17071",
// "17073",
// "17027",
// "17055.5",
// "268611",
// "15.74462667"
// ],
// [
// "1670605200000",
// "17071.5",
// "17071.5",
// "17061",
// "17071",
// "4177",
// "0.24469757"
// ],
// [
// "1670601600000",
// "17086.5",
// "17088",
// "16978",
// "17071.5",
// "6356",
// "0.37288112"
// ]
// ]
//
const data = this.safeList(response, 'data', []);
return this.parseOHLCVs(data, market, timeframe, since, limit);
}
/**
* @method
* @name zebpay#fetchTrades
* @description get the list of most recent trades for a particular symbol
* @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-recent-trades
* @see https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/market.md#get-aggregate-trades
* @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}
*/
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const request = {
'symbol': market['id'],
};
if (market['spot'] && limit !== undefined) {
request['limit'] = limit;
}
let response = undefined;
if (market['spot']) {
response = await this.publicSpotGetV2MarketTrades(this.extend(request, params));
}
else {
response = await this.publicSwapGetV1MarketAggTrade(this.extend(request, params));
}
//
// [
// {
// "id" : "60014521",
// "price" : "23162.94",
// "qty" : "0.00009",
// "side" : "SELL",
// "time" : 1659684602042,
// "isBuyerMaker" : 1659684602036
// }
// ]
//
const data = this.safeList(response, 'data', []);
return this.parseTrades(data, market, since, limit);
}
/**
* @method
* @name zebpay#fetchMyTrades
* @description get the list of most recent trades for a particular symbol
* @see https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/trade.md#-get-trade-history
* @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}
*/
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
await this.loadMarkets();
let market = undefined;
if (symbol !== undefined) {
market = this.market(symbol);
}
let type = undefined;
[type, params] = this.handleMarketTypeAndParams('fetchMyTrades', market, params);
let response = undefined;
if (type === 'spot') {
throw new NotSupported(this.id + ' fetchMyTrades() does not support spot markets');
}
else {
response = await this.privateSwapGetV1TradeHistory(params);
}
const data = this.safeDict(response, 'data', {});
const items = this.safeList(data, 'items', []);
return this.parseTrades(items, market, since, limit);
}
/**
* @method
* @name zebpatspot#fetchOrderTrades
* @description fetch all the trades made from a single order
* @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/private-endpoints.md#get-order-fills
* @param {string} id order id
* @param {string} symbol unified market symbol
* @param {int} [since] the earliest time in ms to fetch trades for
* @param {int} [limit] the maximum number of trades to retrieve
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=trade-structure}
*/
async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
let type = undefined;
[type, params] = this.handleMarketTypeAndParams('fetchOrderTrades', undefined, params);
if (type !== 'spot') {
throw new NotSupported(this.id + ' fetchOrderTrades() does not support ' + type + ' markets');
}
await this.loadMarkets();
const request = {
'orderId': id,
};
const response = await this.privateSpotGetV2ExOrderFills(this.extend(request, params));
//
// {
// "orderId": "456789",
// "symbol": "LINK_USDT",
// "origQty": "1.5",
// "orderId": "30249408733945856",
// "side": "BUY",
// "type": "LIMIT",
// "matchRole": "MAKER",
// "createTime": 1648200366864,
// "price": "3.1",
// "avgExecutedPrice": "2.3456"
// "openQty": "1",
// "filledQty": "0",
// "fees": "0.00145",
// }
//
const data = this.safeDict(response, 'data', {});
const trades = [data];
return this.parseTrades(trades);
}
parseTrade(trade, market = undefined) {
//
// fetchMyTrades
//
// {
// "id": "32164924331503616",
// "symbol": "LINK_USDT",
// "accountType": "SPOT",
// "orderId": "32164923987566592",
// "side": "SELL",
// "type": "MARKET",
// "matchRole": "TAKER",
// "createTime": 1648635115525,
// "price": "11",
// "quantity": "0.5",
// "amount": "5.5",
// "feeCurrency": "USDT",
// "feeAmount": "0.007975",
// "pageId": "32164924331503616",
// "clientOrderId": "myOwnId-321"
// }
// {
// aggregateTradeId: '2659115835',
// symbol: 'ETHINR',
// price: '292848',
// quantity: '0.147',
// firstTradeId: '7018766077',
// lastTradeId: '7018766081',
// tradeTime: '1765381971447',
// isBuyerMarketMaker: true
// }
//
//
const id = this.safeString2(trade, 'id', 'aggregateTradeId');
const orderId = this.safeString2(trade, 'id', 'order');
const timestamp = this.safeInteger2(trade, 'timestamp', 'tradeTime');
const marketId = this.safeString(trade, 'symbol');
market = this.safeMarket(marketId, market, '_');
const symbol = market['symbol'];
const side = this.safeStringLower(trade, 'side');
const priceString = this.safeString(trade, 'price');
const amountString = this.safeString2(trade, 'amount', 'quantity');
return this.safeTrade({
'id': id,
'info': trade,
'timestamp': timestamp,
'datetime': this.iso8601(timestamp),
'symbol': symbol,
'order': orderId,
'type': this.safeStringLower(trade, 'type'),
'side': side,
'takerOrMaker': undefined,
'price': priceString,
'amount': amountString,
'cost': this.safeString(trade, 'cost'),
'fee': this.safeDict(trade, 'fee'),
}, market);
}
/**
* @method
* @name zebpay#fetchBalance
* @description query for balance and get the amount of funds available for trading or funds locked in orders
* @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/private-endpoints.md#get-account-balance
* @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/wallet.md#get-wallet-balance
* @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();
let type = undefined;
[type, params] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
const isSpot = (type === 'spot');
let response = undefined;
if (isSpot) {
response = await this.privateSpotGetV2AccountBalance(params);
}
else {
response = await this.privateSwapGetV1WalletBalance(params);
}
//
// {
// "data": [
// {
// "free": 200,
// "used": 100,
// "total": 300,
// "currency": "INR"
// },
// {
// "free": 0,
// "used": 0,
// "total": 0,
// "currency": "USDT"
// }
// ]
// }
//
return this.parseBalance(response);
}
/**
* @method
* @name zebpay#createOrder
* @description Create an order on the exchange
* @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/private-endpoints.md#place-new-order
* @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/trade.md#--create-order
* @param {string} symbol Unified CCXT market symbol
* @param {string} type 'limit' or 'market'
* @param {string} side 'buy' or 'sell'
* @param {float} amount the amount of currency to trade
* @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 {string} [params.formType] The price at which a trigger order is triggered at
* @param {string} [params.marginAsset] The asset the order creates, default is INR.
* @param {boolean} [params.takeProfit] Takeprofit flag for the order.
* @param {boolean} [params.stopLoss] Stop loss flag for the order.
* @param {string} [params.positionId] PositionId of the order.
* @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 upperCaseType = type.toUpperCase();
const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
const stopLossPrice = this.safeString(params, 'stopLossPrice');
params = this.omit(params, ['marginAsset', 'takeProfitPrice', 'takeProfitPrice']);
let request = {
'symbol': market['id'],
'side': side.toUpperCase(),
};
let response = undefined;
if (market['spot']) {
[request, params] = this.orderRequest(symbol, type, amount, request, price, params);
response = await this.privateSpotPostV2ExOrders(this.extend(request, params));
}
else {
const marginAsset = this.safeString(params, 'marginAsset', 'INR');
const formType = this.safeStringUpper(params, 'formType', 'ORDER_FORM');
request['formType'] = formType;
request['amount'] = this.parseToNumeric(this.amountToPrecision(market['id'], amount));
request['marginAsset'] = marginAsset;
const hasTP = takeProfitPrice !== undefined;
const hasSL = stopLossPrice !== undefined;
if (hasTP || hasSL) {
if (hasTP) {
request['takeProfitPrice'] = this.parseToNumeric(this.priceToPrecision(symbol, takeProfitPrice));
}
if (hasSL) {
request['stopLossPrice'] = this.parseToNumeric(this.priceToPrecision(symbol, stopLossPrice));
}
response = await this.privateSwapPostV1TradeOrderAddTPSL(this.extend(request, params));
}
else {
request['type'] = upperCaseType;
if (type === 'limit') {
if (price === undefined) {
throw new ArgumentsRequired(this.id + ' createOrder() requires a price argument for limit orders');
}
request['price'] = this.parseToNumeric(this.priceToPrecision(symbol, price));
}
response = await this.privateSwapPostV1TradeOrder(this.extend(request, params));
}
}
//
// {
// "data": {
// "clientOrderId": "619717484f1d010001510cde",
// },
// }
//
const data = this.safeDict(response, 'data', {});
return this.parseOrder(data, market);
}
orderRequest(symbol, type, amount, request, price = undefined, params = {}) {
const upperCaseType = type.toUpperCase();
const triggerPrice = this.safeString(params, 'stopLossPrice', undefined);
const quoteOrderQty = this.safeString2(params, 'quoteOrderQty', 'cost', undefined);
const timeInForce = this.safeString(params, 'timeInForce', 'GTC');
const clientOrderId = this.safeString(params, 'clientOrderId', this.uuid());
params = this.omit(params, ['stopLossPrice', 'cost', 'timeInForce', 'clientOrderId']);
request['type'] = upperCaseType;
request['clientOrderId'] = clientOrderId;
request['timeInForce'] = timeInForce;
if (upperCaseType === 'MARKET') {
if (quoteOrderQty === undefined) {
throw new ExchangeError(this.id + ' spot market orders require cost in params');
}
request['quoteOrderAmount'] = this.costToPrecision(symbol, quoteOrderQty);
}
else {
if (triggerPrice !== undefined) {
request['stopLossPrice'] = this.priceToPrecision(symbol, triggerPrice);
}
request['amount'] = this.amountToPrecision(symbol, amount);
request['price'] = this.priceToPrecision(symbol, price);
}
return [request, params];
}
/**
* @method
* @name zebpay#cancelOrder
* @description cancels an open order
* @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/private-endpoints.md#cancel-order
* @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/trade.md#-cancel-order
* @param {string} id order id
* @param {string} symbol unified symbol of the market the order was made in
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {object} [params.timestamp] 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 market = this.market(symbol);
let response = undefined;
const request = {};
if (market['spot']) {
request['orderId'] = id;
response = await this.privateSpotDeleteV2ExOrder(this.extend(request, params));
}
else {
const clientOrderId = this.safeString(params, 'clientOrderId');
if (clientOrderId === undefined) {
throw new ArgumentsRequire